1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073730747307573076730777307873079730807308173082730837308473085730867308773088730897309073091730927309373094730957309673097730987309973100731017310273103731047310573106731077310873109731107311173112731137311473115731167311773118731197312073121731227312373124731257312673127731287312973130731317313273133731347313573136731377313873139731407314173142731437314473145731467314773148731497315073151731527315373154731557315673157731587315973160731617316273163731647316573166731677316873169731707317173172731737317473175731767317773178731797318073181731827318373184731857318673187731887318973190731917319273193731947319573196731977319873199732007320173202732037320473205732067320773208732097321073211732127321373214732157321673217732187321973220732217322273223732247322573226732277322873229732307323173232732337323473235732367323773238732397324073241732427324373244732457324673247732487324973250732517325273253732547325573256732577325873259732607326173262732637326473265732667326773268732697327073271732727327373274732757327673277732787327973280732817328273283732847328573286732877328873289732907329173292732937329473295732967329773298732997330073301733027330373304733057330673307733087330973310733117331273313733147331573316733177331873319733207332173322733237332473325733267332773328733297333073331733327333373334733357333673337733387333973340733417334273343733447334573346733477334873349733507335173352733537335473355733567335773358733597336073361733627336373364733657336673367733687336973370733717337273373733747337573376733777337873379733807338173382733837338473385733867338773388733897339073391733927339373394733957339673397733987339973400734017340273403734047340573406734077340873409734107341173412734137341473415734167341773418734197342073421734227342373424734257342673427734287342973430734317343273433734347343573436734377343873439734407344173442734437344473445734467344773448734497345073451734527345373454734557345673457734587345973460734617346273463734647346573466734677346873469734707347173472734737347473475734767347773478734797348073481734827348373484734857348673487734887348973490734917349273493734947349573496734977349873499735007350173502735037350473505735067350773508735097351073511735127351373514735157351673517735187351973520735217352273523735247352573526735277352873529735307353173532735337353473535735367353773538735397354073541735427354373544735457354673547735487354973550735517355273553735547355573556735577355873559735607356173562735637356473565735667356773568735697357073571735727357373574735757357673577735787357973580735817358273583735847358573586735877358873589735907359173592735937359473595735967359773598735997360073601736027360373604736057360673607736087360973610736117361273613736147361573616736177361873619736207362173622736237362473625736267362773628736297363073631736327363373634736357363673637736387363973640736417364273643736447364573646736477364873649736507365173652736537365473655736567365773658736597366073661736627366373664736657366673667736687366973670736717367273673736747367573676736777367873679736807368173682736837368473685736867368773688736897369073691736927369373694736957369673697736987369973700737017370273703737047370573706737077370873709737107371173712737137371473715737167371773718737197372073721737227372373724737257372673727737287372973730737317373273733737347373573736737377373873739737407374173742737437374473745737467374773748737497375073751737527375373754737557375673757737587375973760737617376273763737647376573766737677376873769737707377173772737737377473775737767377773778737797378073781737827378373784737857378673787737887378973790737917379273793737947379573796737977379873799738007380173802738037380473805738067380773808738097381073811738127381373814738157381673817738187381973820738217382273823738247382573826738277382873829738307383173832738337383473835738367383773838738397384073841738427384373844738457384673847738487384973850738517385273853738547385573856738577385873859738607386173862738637386473865738667386773868738697387073871738727387373874738757387673877738787387973880738817388273883738847388573886738877388873889738907389173892738937389473895738967389773898738997390073901739027390373904739057390673907739087390973910739117391273913739147391573916739177391873919739207392173922739237392473925739267392773928739297393073931739327393373934739357393673937739387393973940739417394273943739447394573946739477394873949739507395173952739537395473955739567395773958739597396073961739627396373964739657396673967739687396973970739717397273973739747397573976739777397873979739807398173982739837398473985739867398773988739897399073991739927399373994739957399673997739987399974000740017400274003740047400574006740077400874009740107401174012740137401474015740167401774018740197402074021740227402374024740257402674027740287402974030740317403274033740347403574036740377403874039740407404174042740437404474045740467404774048740497405074051740527405374054740557405674057740587405974060740617406274063740647406574066740677406874069740707407174072740737407474075740767407774078740797408074081740827408374084740857408674087740887408974090740917409274093740947409574096740977409874099741007410174102741037410474105741067410774108741097411074111741127411374114741157411674117741187411974120741217412274123741247412574126741277412874129741307413174132741337413474135741367413774138741397414074141741427414374144741457414674147741487414974150741517415274153741547415574156741577415874159741607416174162741637416474165741667416774168741697417074171741727417374174741757417674177741787417974180741817418274183741847418574186741877418874189741907419174192741937419474195741967419774198741997420074201742027420374204742057420674207742087420974210742117421274213742147421574216742177421874219742207422174222742237422474225742267422774228742297423074231742327423374234742357423674237742387423974240742417424274243742447424574246742477424874249742507425174252742537425474255742567425774258742597426074261742627426374264742657426674267742687426974270742717427274273742747427574276742777427874279742807428174282742837428474285742867428774288742897429074291742927429374294742957429674297742987429974300743017430274303743047430574306743077430874309743107431174312743137431474315743167431774318743197432074321743227432374324743257432674327743287432974330743317433274333743347433574336743377433874339743407434174342743437434474345743467434774348743497435074351743527435374354743557435674357743587435974360743617436274363743647436574366743677436874369743707437174372743737437474375743767437774378743797438074381743827438374384743857438674387743887438974390743917439274393743947439574396743977439874399744007440174402744037440474405744067440774408744097441074411744127441374414744157441674417744187441974420744217442274423744247442574426744277442874429744307443174432744337443474435744367443774438744397444074441744427444374444744457444674447744487444974450744517445274453744547445574456744577445874459744607446174462744637446474465744667446774468744697447074471744727447374474744757447674477744787447974480744817448274483744847448574486744877448874489744907449174492744937449474495744967449774498744997450074501745027450374504745057450674507745087450974510745117451274513745147451574516745177451874519745207452174522745237452474525745267452774528745297453074531745327453374534745357453674537745387453974540745417454274543745447454574546745477454874549745507455174552745537455474555745567455774558745597456074561745627456374564745657456674567745687456974570745717457274573745747457574576745777457874579745807458174582745837458474585745867458774588745897459074591745927459374594745957459674597745987459974600746017460274603746047460574606746077460874609746107461174612746137461474615746167461774618746197462074621746227462374624746257462674627746287462974630746317463274633746347463574636746377463874639746407464174642746437464474645746467464774648746497465074651746527465374654746557465674657746587465974660746617466274663746647466574666746677466874669746707467174672746737467474675746767467774678746797468074681746827468374684746857468674687746887468974690746917469274693746947469574696746977469874699747007470174702747037470474705747067470774708747097471074711747127471374714747157471674717747187471974720747217472274723747247472574726747277472874729747307473174732747337473474735747367473774738747397474074741747427474374744747457474674747747487474974750747517475274753747547475574756747577475874759747607476174762747637476474765747667476774768747697477074771747727477374774747757477674777747787477974780747817478274783747847478574786747877478874789747907479174792747937479474795747967479774798747997480074801748027480374804748057480674807748087480974810748117481274813748147481574816748177481874819748207482174822748237482474825748267482774828748297483074831748327483374834748357483674837748387483974840748417484274843748447484574846748477484874849748507485174852748537485474855748567485774858748597486074861748627486374864748657486674867748687486974870748717487274873748747487574876748777487874879748807488174882748837488474885748867488774888748897489074891748927489374894748957489674897748987489974900749017490274903749047490574906749077490874909749107491174912749137491474915749167491774918749197492074921749227492374924749257492674927749287492974930749317493274933749347493574936749377493874939749407494174942749437494474945749467494774948749497495074951749527495374954749557495674957749587495974960749617496274963749647496574966749677496874969749707497174972749737497474975749767497774978749797498074981749827498374984749857498674987749887498974990749917499274993749947499574996749977499874999750007500175002750037500475005750067500775008750097501075011750127501375014750157501675017750187501975020750217502275023750247502575026750277502875029750307503175032750337503475035750367503775038750397504075041750427504375044750457504675047750487504975050750517505275053750547505575056750577505875059750607506175062750637506475065750667506775068750697507075071750727507375074750757507675077750787507975080750817508275083750847508575086750877508875089750907509175092750937509475095750967509775098750997510075101751027510375104751057510675107751087510975110751117511275113751147511575116751177511875119751207512175122751237512475125751267512775128751297513075131751327513375134751357513675137751387513975140751417514275143751447514575146751477514875149751507515175152751537515475155751567515775158751597516075161751627516375164751657516675167751687516975170751717517275173751747517575176751777517875179751807518175182751837518475185751867518775188751897519075191751927519375194751957519675197751987519975200752017520275203752047520575206752077520875209752107521175212752137521475215752167521775218752197522075221752227522375224752257522675227752287522975230752317523275233752347523575236752377523875239752407524175242752437524475245752467524775248752497525075251752527525375254752557525675257752587525975260752617526275263752647526575266752677526875269752707527175272752737527475275752767527775278752797528075281752827528375284752857528675287752887528975290752917529275293752947529575296752977529875299753007530175302753037530475305753067530775308753097531075311753127531375314753157531675317753187531975320753217532275323753247532575326753277532875329753307533175332753337533475335753367533775338753397534075341753427534375344753457534675347753487534975350753517535275353753547535575356753577535875359753607536175362753637536475365753667536775368753697537075371753727537375374753757537675377753787537975380753817538275383753847538575386753877538875389753907539175392753937539475395753967539775398753997540075401754027540375404754057540675407754087540975410754117541275413754147541575416754177541875419754207542175422754237542475425754267542775428754297543075431754327543375434754357543675437754387543975440754417544275443754447544575446754477544875449754507545175452754537545475455754567545775458754597546075461754627546375464754657546675467754687546975470754717547275473754747547575476754777547875479754807548175482754837548475485754867548775488754897549075491754927549375494754957549675497754987549975500755017550275503755047550575506755077550875509755107551175512755137551475515755167551775518755197552075521755227552375524755257552675527755287552975530755317553275533755347553575536755377553875539755407554175542755437554475545755467554775548755497555075551755527555375554755557555675557755587555975560755617556275563755647556575566755677556875569755707557175572755737557475575755767557775578755797558075581755827558375584755857558675587755887558975590755917559275593755947559575596755977559875599756007560175602756037560475605756067560775608756097561075611756127561375614756157561675617756187561975620756217562275623756247562575626756277562875629756307563175632756337563475635756367563775638756397564075641756427564375644756457564675647756487564975650756517565275653756547565575656756577565875659756607566175662756637566475665756667566775668756697567075671756727567375674756757567675677756787567975680756817568275683756847568575686756877568875689756907569175692756937569475695756967569775698756997570075701757027570375704757057570675707757087570975710757117571275713757147571575716757177571875719757207572175722757237572475725757267572775728757297573075731757327573375734757357573675737757387573975740757417574275743757447574575746757477574875749757507575175752757537575475755757567575775758757597576075761757627576375764757657576675767757687576975770757717577275773757747577575776757777577875779757807578175782757837578475785757867578775788757897579075791757927579375794757957579675797757987579975800758017580275803758047580575806758077580875809758107581175812758137581475815758167581775818758197582075821758227582375824758257582675827758287582975830758317583275833758347583575836758377583875839758407584175842758437584475845758467584775848758497585075851758527585375854758557585675857758587585975860758617586275863758647586575866758677586875869758707587175872758737587475875758767587775878758797588075881758827588375884758857588675887758887588975890758917589275893758947589575896758977589875899759007590175902759037590475905759067590775908759097591075911759127591375914759157591675917759187591975920759217592275923759247592575926759277592875929759307593175932759337593475935759367593775938759397594075941759427594375944759457594675947759487594975950759517595275953759547595575956759577595875959759607596175962759637596475965759667596775968759697597075971759727597375974759757597675977759787597975980759817598275983759847598575986759877598875989759907599175992759937599475995759967599775998759997600076001760027600376004760057600676007760087600976010760117601276013760147601576016760177601876019760207602176022760237602476025760267602776028760297603076031760327603376034760357603676037760387603976040760417604276043760447604576046760477604876049760507605176052760537605476055760567605776058760597606076061760627606376064760657606676067760687606976070760717607276073760747607576076760777607876079760807608176082760837608476085760867608776088760897609076091760927609376094760957609676097760987609976100761017610276103761047610576106761077610876109761107611176112761137611476115761167611776118761197612076121761227612376124761257612676127761287612976130761317613276133761347613576136761377613876139761407614176142761437614476145761467614776148761497615076151761527615376154761557615676157761587615976160761617616276163761647616576166761677616876169761707617176172761737617476175761767617776178761797618076181761827618376184761857618676187761887618976190761917619276193761947619576196761977619876199762007620176202762037620476205762067620776208762097621076211762127621376214762157621676217762187621976220762217622276223762247622576226762277622876229762307623176232762337623476235762367623776238762397624076241762427624376244762457624676247762487624976250762517625276253762547625576256762577625876259762607626176262762637626476265762667626776268762697627076271762727627376274762757627676277762787627976280762817628276283762847628576286762877628876289762907629176292762937629476295762967629776298762997630076301763027630376304763057630676307763087630976310763117631276313763147631576316763177631876319763207632176322763237632476325763267632776328763297633076331763327633376334763357633676337763387633976340763417634276343763447634576346763477634876349763507635176352763537635476355763567635776358763597636076361763627636376364763657636676367763687636976370763717637276373763747637576376763777637876379763807638176382763837638476385763867638776388763897639076391763927639376394763957639676397763987639976400764017640276403764047640576406764077640876409764107641176412764137641476415764167641776418764197642076421764227642376424764257642676427764287642976430764317643276433764347643576436764377643876439764407644176442764437644476445764467644776448764497645076451764527645376454764557645676457764587645976460764617646276463764647646576466764677646876469764707647176472764737647476475764767647776478764797648076481764827648376484764857648676487764887648976490764917649276493764947649576496764977649876499765007650176502765037650476505765067650776508765097651076511765127651376514765157651676517765187651976520765217652276523765247652576526765277652876529765307653176532765337653476535765367653776538765397654076541765427654376544765457654676547765487654976550765517655276553765547655576556765577655876559765607656176562765637656476565765667656776568765697657076571765727657376574765757657676577765787657976580765817658276583765847658576586765877658876589765907659176592765937659476595765967659776598765997660076601766027660376604766057660676607766087660976610766117661276613766147661576616766177661876619766207662176622766237662476625766267662776628766297663076631766327663376634766357663676637766387663976640766417664276643766447664576646766477664876649766507665176652766537665476655766567665776658766597666076661766627666376664766657666676667766687666976670766717667276673766747667576676766777667876679766807668176682766837668476685766867668776688766897669076691766927669376694766957669676697766987669976700767017670276703767047670576706767077670876709767107671176712767137671476715767167671776718767197672076721767227672376724767257672676727767287672976730767317673276733767347673576736767377673876739767407674176742767437674476745767467674776748767497675076751767527675376754767557675676757767587675976760767617676276763767647676576766767677676876769767707677176772767737677476775767767677776778767797678076781767827678376784767857678676787767887678976790767917679276793767947679576796767977679876799768007680176802768037680476805768067680776808768097681076811768127681376814768157681676817768187681976820768217682276823768247682576826768277682876829768307683176832768337683476835768367683776838768397684076841768427684376844768457684676847768487684976850768517685276853768547685576856768577685876859768607686176862768637686476865768667686776868768697687076871768727687376874768757687676877768787687976880768817688276883768847688576886768877688876889768907689176892768937689476895768967689776898768997690076901769027690376904769057690676907769087690976910769117691276913769147691576916769177691876919769207692176922769237692476925769267692776928769297693076931769327693376934769357693676937769387693976940769417694276943769447694576946769477694876949769507695176952769537695476955769567695776958769597696076961769627696376964769657696676967769687696976970769717697276973769747697576976769777697876979769807698176982769837698476985769867698776988769897699076991769927699376994769957699676997769987699977000770017700277003770047700577006770077700877009770107701177012770137701477015770167701777018770197702077021770227702377024770257702677027770287702977030770317703277033770347703577036770377703877039770407704177042770437704477045770467704777048770497705077051770527705377054770557705677057770587705977060770617706277063770647706577066770677706877069770707707177072770737707477075770767707777078770797708077081770827708377084770857708677087770887708977090770917709277093770947709577096770977709877099771007710177102771037710477105771067710777108771097711077111771127711377114771157711677117771187711977120771217712277123771247712577126771277712877129771307713177132771337713477135771367713777138771397714077141771427714377144771457714677147771487714977150771517715277153771547715577156771577715877159771607716177162771637716477165771667716777168771697717077171771727717377174771757717677177771787717977180771817718277183771847718577186771877718877189771907719177192771937719477195771967719777198771997720077201772027720377204772057720677207772087720977210772117721277213772147721577216772177721877219772207722177222772237722477225772267722777228772297723077231772327723377234772357723677237772387723977240772417724277243772447724577246772477724877249772507725177252772537725477255772567725777258772597726077261772627726377264772657726677267772687726977270772717727277273772747727577276772777727877279772807728177282772837728477285772867728777288772897729077291772927729377294772957729677297772987729977300773017730277303773047730577306773077730877309773107731177312773137731477315773167731777318773197732077321773227732377324773257732677327773287732977330773317733277333773347733577336773377733877339773407734177342773437734477345773467734777348773497735077351773527735377354773557735677357773587735977360773617736277363773647736577366773677736877369773707737177372773737737477375773767737777378773797738077381773827738377384773857738677387773887738977390773917739277393773947739577396773977739877399774007740177402774037740477405774067740777408774097741077411774127741377414774157741677417774187741977420774217742277423774247742577426774277742877429774307743177432774337743477435774367743777438774397744077441774427744377444774457744677447774487744977450774517745277453774547745577456774577745877459774607746177462774637746477465774667746777468774697747077471774727747377474774757747677477774787747977480774817748277483774847748577486774877748877489774907749177492774937749477495774967749777498774997750077501775027750377504775057750677507775087750977510775117751277513775147751577516775177751877519775207752177522775237752477525775267752777528775297753077531775327753377534775357753677537775387753977540775417754277543775447754577546775477754877549775507755177552775537755477555775567755777558775597756077561775627756377564775657756677567775687756977570775717757277573775747757577576775777757877579775807758177582775837758477585775867758777588775897759077591775927759377594775957759677597775987759977600776017760277603776047760577606776077760877609776107761177612776137761477615776167761777618776197762077621776227762377624776257762677627776287762977630776317763277633776347763577636776377763877639776407764177642776437764477645776467764777648776497765077651776527765377654776557765677657776587765977660776617766277663776647766577666776677766877669776707767177672776737767477675776767767777678776797768077681776827768377684776857768677687776887768977690776917769277693776947769577696776977769877699777007770177702777037770477705777067770777708777097771077711777127771377714777157771677717777187771977720777217772277723777247772577726777277772877729777307773177732777337773477735777367773777738777397774077741777427774377744777457774677747777487774977750777517775277753777547775577756777577775877759777607776177762777637776477765777667776777768777697777077771777727777377774777757777677777777787777977780777817778277783777847778577786777877778877789777907779177792777937779477795777967779777798777997780077801778027780377804778057780677807778087780977810778117781277813778147781577816778177781877819778207782177822778237782477825778267782777828778297783077831778327783377834778357783677837778387783977840778417784277843778447784577846778477784877849778507785177852778537785477855778567785777858778597786077861778627786377864778657786677867778687786977870778717787277873778747787577876778777787877879778807788177882778837788477885778867788777888778897789077891778927789377894778957789677897778987789977900779017790277903779047790577906779077790877909779107791177912779137791477915779167791777918779197792077921779227792377924779257792677927779287792977930779317793277933779347793577936779377793877939779407794177942779437794477945779467794777948779497795077951779527795377954779557795677957779587795977960779617796277963779647796577966779677796877969779707797177972779737797477975779767797777978779797798077981779827798377984779857798677987779887798977990779917799277993779947799577996779977799877999780007800178002780037800478005780067800778008780097801078011780127801378014780157801678017780187801978020780217802278023780247802578026780277802878029780307803178032780337803478035780367803778038780397804078041780427804378044780457804678047780487804978050780517805278053780547805578056780577805878059780607806178062780637806478065780667806778068780697807078071780727807378074780757807678077780787807978080780817808278083780847808578086780877808878089780907809178092780937809478095780967809778098780997810078101781027810378104781057810678107781087810978110781117811278113781147811578116781177811878119781207812178122781237812478125781267812778128781297813078131781327813378134781357813678137781387813978140781417814278143781447814578146781477814878149781507815178152781537815478155781567815778158781597816078161781627816378164781657816678167781687816978170781717817278173781747817578176781777817878179781807818178182781837818478185781867818778188781897819078191781927819378194781957819678197781987819978200782017820278203782047820578206782077820878209782107821178212782137821478215782167821778218782197822078221782227822378224782257822678227782287822978230782317823278233782347823578236782377823878239782407824178242782437824478245782467824778248782497825078251782527825378254782557825678257782587825978260782617826278263782647826578266782677826878269782707827178272782737827478275782767827778278782797828078281782827828378284782857828678287782887828978290782917829278293782947829578296782977829878299783007830178302783037830478305783067830778308783097831078311783127831378314783157831678317783187831978320783217832278323783247832578326783277832878329783307833178332783337833478335783367833778338783397834078341783427834378344783457834678347783487834978350783517835278353783547835578356783577835878359783607836178362783637836478365783667836778368783697837078371783727837378374783757837678377783787837978380783817838278383783847838578386783877838878389783907839178392783937839478395783967839778398783997840078401784027840378404784057840678407784087840978410784117841278413784147841578416784177841878419784207842178422784237842478425784267842778428784297843078431784327843378434784357843678437784387843978440784417844278443784447844578446784477844878449784507845178452784537845478455784567845778458784597846078461784627846378464784657846678467784687846978470784717847278473784747847578476784777847878479784807848178482784837848478485784867848778488784897849078491784927849378494784957849678497784987849978500785017850278503785047850578506785077850878509785107851178512785137851478515785167851778518785197852078521785227852378524785257852678527785287852978530785317853278533785347853578536785377853878539785407854178542785437854478545785467854778548785497855078551785527855378554785557855678557785587855978560785617856278563785647856578566785677856878569785707857178572785737857478575785767857778578785797858078581785827858378584785857858678587785887858978590785917859278593785947859578596785977859878599786007860178602786037860478605786067860778608786097861078611786127861378614786157861678617786187861978620786217862278623786247862578626786277862878629786307863178632786337863478635786367863778638786397864078641786427864378644786457864678647786487864978650786517865278653786547865578656786577865878659786607866178662786637866478665786667866778668786697867078671786727867378674786757867678677786787867978680786817868278683786847868578686786877868878689786907869178692786937869478695786967869778698786997870078701787027870378704787057870678707787087870978710787117871278713787147871578716787177871878719787207872178722787237872478725787267872778728787297873078731787327873378734787357873678737787387873978740787417874278743787447874578746787477874878749787507875178752787537875478755787567875778758787597876078761787627876378764787657876678767787687876978770787717877278773787747877578776787777877878779787807878178782787837878478785787867878778788787897879078791787927879378794787957879678797787987879978800788017880278803788047880578806788077880878809788107881178812788137881478815788167881778818788197882078821788227882378824788257882678827788287882978830788317883278833788347883578836788377883878839788407884178842788437884478845788467884778848788497885078851788527885378854788557885678857788587885978860788617886278863788647886578866788677886878869788707887178872788737887478875788767887778878788797888078881788827888378884788857888678887788887888978890788917889278893788947889578896788977889878899789007890178902789037890478905789067890778908789097891078911789127891378914789157891678917789187891978920789217892278923789247892578926789277892878929789307893178932789337893478935789367893778938789397894078941789427894378944789457894678947789487894978950789517895278953789547895578956789577895878959789607896178962789637896478965789667896778968789697897078971789727897378974789757897678977789787897978980789817898278983789847898578986789877898878989789907899178992789937899478995789967899778998789997900079001790027900379004790057900679007790087900979010790117901279013790147901579016790177901879019790207902179022790237902479025790267902779028790297903079031790327903379034790357903679037790387903979040790417904279043790447904579046790477904879049790507905179052790537905479055790567905779058790597906079061790627906379064790657906679067790687906979070790717907279073790747907579076790777907879079790807908179082790837908479085790867908779088790897909079091790927909379094790957909679097790987909979100791017910279103791047910579106791077910879109791107911179112791137911479115791167911779118791197912079121791227912379124791257912679127791287912979130791317913279133791347913579136791377913879139791407914179142791437914479145791467914779148791497915079151791527915379154791557915679157791587915979160791617916279163791647916579166791677916879169791707917179172791737917479175791767917779178791797918079181791827918379184791857918679187791887918979190791917919279193791947919579196791977919879199792007920179202792037920479205792067920779208792097921079211792127921379214792157921679217792187921979220792217922279223792247922579226792277922879229792307923179232792337923479235792367923779238792397924079241792427924379244792457924679247792487924979250792517925279253792547925579256792577925879259792607926179262792637926479265792667926779268792697927079271792727927379274792757927679277792787927979280792817928279283792847928579286792877928879289792907929179292792937929479295792967929779298792997930079301793027930379304793057930679307793087930979310793117931279313793147931579316793177931879319793207932179322793237932479325793267932779328793297933079331793327933379334793357933679337793387933979340793417934279343793447934579346793477934879349793507935179352793537935479355793567935779358793597936079361793627936379364793657936679367793687936979370793717937279373793747937579376793777937879379793807938179382793837938479385793867938779388793897939079391793927939379394793957939679397793987939979400794017940279403794047940579406794077940879409794107941179412794137941479415794167941779418794197942079421794227942379424794257942679427794287942979430794317943279433794347943579436794377943879439794407944179442794437944479445794467944779448794497945079451794527945379454794557945679457794587945979460794617946279463794647946579466794677946879469794707947179472794737947479475794767947779478794797948079481794827948379484794857948679487794887948979490794917949279493794947949579496794977949879499795007950179502795037950479505795067950779508795097951079511795127951379514795157951679517795187951979520795217952279523795247952579526795277952879529795307953179532795337953479535795367953779538795397954079541795427954379544795457954679547795487954979550795517955279553795547955579556795577955879559795607956179562795637956479565795667956779568795697957079571795727957379574795757957679577795787957979580795817958279583795847958579586795877958879589795907959179592795937959479595795967959779598795997960079601796027960379604796057960679607796087960979610796117961279613796147961579616796177961879619796207962179622796237962479625796267962779628796297963079631796327963379634796357963679637796387963979640796417964279643796447964579646796477964879649796507965179652796537965479655796567965779658796597966079661796627966379664796657966679667796687966979670796717967279673796747967579676796777967879679796807968179682796837968479685796867968779688796897969079691796927969379694796957969679697796987969979700797017970279703797047970579706797077970879709797107971179712797137971479715797167971779718797197972079721797227972379724797257972679727797287972979730797317973279733797347973579736797377973879739797407974179742797437974479745797467974779748797497975079751797527975379754797557975679757797587975979760797617976279763797647976579766797677976879769797707977179772797737977479775797767977779778797797978079781797827978379784797857978679787797887978979790797917979279793797947979579796797977979879799798007980179802798037980479805798067980779808798097981079811798127981379814798157981679817798187981979820798217982279823798247982579826798277982879829798307983179832798337983479835798367983779838798397984079841798427984379844798457984679847798487984979850798517985279853798547985579856798577985879859798607986179862798637986479865798667986779868798697987079871798727987379874798757987679877798787987979880798817988279883798847988579886798877988879889798907989179892798937989479895798967989779898798997990079901799027990379904799057990679907799087990979910799117991279913799147991579916799177991879919799207992179922799237992479925799267992779928799297993079931799327993379934799357993679937799387993979940799417994279943799447994579946799477994879949799507995179952799537995479955799567995779958799597996079961799627996379964799657996679967799687996979970799717997279973799747997579976799777997879979799807998179982799837998479985799867998779988799897999079991799927999379994799957999679997799987999980000800018000280003800048000580006800078000880009800108001180012800138001480015800168001780018800198002080021800228002380024800258002680027800288002980030800318003280033800348003580036800378003880039800408004180042800438004480045800468004780048800498005080051800528005380054800558005680057800588005980060800618006280063800648006580066800678006880069800708007180072800738007480075800768007780078800798008080081800828008380084800858008680087800888008980090800918009280093800948009580096800978009880099801008010180102801038010480105801068010780108801098011080111801128011380114801158011680117801188011980120801218012280123801248012580126801278012880129801308013180132801338013480135801368013780138801398014080141801428014380144801458014680147801488014980150801518015280153801548015580156801578015880159801608016180162801638016480165801668016780168801698017080171801728017380174801758017680177801788017980180801818018280183801848018580186801878018880189801908019180192801938019480195801968019780198801998020080201802028020380204802058020680207802088020980210802118021280213802148021580216802178021880219802208022180222802238022480225802268022780228802298023080231802328023380234802358023680237802388023980240802418024280243802448024580246802478024880249802508025180252802538025480255802568025780258802598026080261802628026380264802658026680267802688026980270802718027280273802748027580276802778027880279802808028180282802838028480285802868028780288802898029080291802928029380294802958029680297802988029980300803018030280303803048030580306803078030880309803108031180312803138031480315803168031780318803198032080321803228032380324803258032680327803288032980330803318033280333803348033580336803378033880339803408034180342803438034480345803468034780348803498035080351803528035380354803558035680357803588035980360803618036280363803648036580366803678036880369803708037180372803738037480375803768037780378803798038080381803828038380384803858038680387803888038980390803918039280393803948039580396803978039880399804008040180402804038040480405804068040780408804098041080411804128041380414804158041680417804188041980420804218042280423804248042580426804278042880429804308043180432804338043480435804368043780438804398044080441804428044380444804458044680447804488044980450804518045280453804548045580456804578045880459804608046180462804638046480465804668046780468804698047080471804728047380474804758047680477804788047980480804818048280483804848048580486804878048880489804908049180492804938049480495804968049780498804998050080501805028050380504805058050680507805088050980510805118051280513805148051580516805178051880519805208052180522805238052480525805268052780528805298053080531805328053380534805358053680537805388053980540805418054280543805448054580546805478054880549805508055180552805538055480555805568055780558805598056080561805628056380564805658056680567805688056980570805718057280573805748057580576805778057880579805808058180582805838058480585805868058780588805898059080591805928059380594805958059680597805988059980600806018060280603806048060580606806078060880609806108061180612806138061480615806168061780618806198062080621806228062380624806258062680627806288062980630806318063280633806348063580636806378063880639806408064180642806438064480645806468064780648806498065080651806528065380654806558065680657806588065980660806618066280663806648066580666806678066880669806708067180672806738067480675806768067780678806798068080681806828068380684806858068680687806888068980690806918069280693806948069580696806978069880699807008070180702807038070480705807068070780708807098071080711807128071380714807158071680717807188071980720807218072280723807248072580726807278072880729807308073180732807338073480735807368073780738807398074080741807428074380744807458074680747807488074980750807518075280753807548075580756807578075880759807608076180762807638076480765807668076780768807698077080771807728077380774807758077680777807788077980780807818078280783807848078580786807878078880789807908079180792807938079480795807968079780798807998080080801808028080380804808058080680807808088080980810808118081280813808148081580816808178081880819808208082180822808238082480825808268082780828808298083080831808328083380834808358083680837808388083980840808418084280843808448084580846808478084880849808508085180852808538085480855808568085780858808598086080861808628086380864808658086680867808688086980870808718087280873808748087580876808778087880879808808088180882808838088480885808868088780888808898089080891808928089380894808958089680897808988089980900809018090280903809048090580906809078090880909809108091180912809138091480915809168091780918809198092080921809228092380924809258092680927809288092980930809318093280933809348093580936809378093880939809408094180942809438094480945809468094780948809498095080951809528095380954809558095680957809588095980960809618096280963809648096580966809678096880969809708097180972809738097480975809768097780978809798098080981809828098380984809858098680987809888098980990809918099280993809948099580996809978099880999810008100181002810038100481005810068100781008810098101081011810128101381014810158101681017810188101981020810218102281023810248102581026810278102881029810308103181032810338103481035810368103781038810398104081041810428104381044810458104681047810488104981050810518105281053810548105581056810578105881059810608106181062810638106481065810668106781068810698107081071810728107381074810758107681077810788107981080810818108281083810848108581086810878108881089810908109181092810938109481095810968109781098810998110081101811028110381104811058110681107811088110981110811118111281113811148111581116811178111881119811208112181122811238112481125811268112781128811298113081131811328113381134811358113681137811388113981140811418114281143811448114581146811478114881149811508115181152811538115481155811568115781158811598116081161811628116381164811658116681167811688116981170811718117281173811748117581176811778117881179811808118181182811838118481185811868118781188811898119081191811928119381194811958119681197811988119981200812018120281203812048120581206812078120881209812108121181212812138121481215812168121781218812198122081221812228122381224812258122681227812288122981230812318123281233812348123581236812378123881239812408124181242812438124481245812468124781248812498125081251812528125381254812558125681257812588125981260812618126281263812648126581266812678126881269812708127181272812738127481275812768127781278812798128081281812828128381284812858128681287812888128981290812918129281293812948129581296812978129881299813008130181302813038130481305813068130781308813098131081311813128131381314813158131681317813188131981320813218132281323813248132581326813278132881329813308133181332813338133481335813368133781338813398134081341813428134381344813458134681347813488134981350813518135281353813548135581356813578135881359813608136181362813638136481365813668136781368813698137081371813728137381374813758137681377813788137981380813818138281383813848138581386813878138881389813908139181392813938139481395813968139781398813998140081401814028140381404814058140681407814088140981410814118141281413814148141581416814178141881419814208142181422814238142481425814268142781428814298143081431814328143381434814358143681437814388143981440814418144281443814448144581446814478144881449814508145181452814538145481455814568145781458814598146081461814628146381464814658146681467814688146981470814718147281473814748147581476814778147881479814808148181482814838148481485814868148781488814898149081491814928149381494814958149681497814988149981500815018150281503815048150581506815078150881509815108151181512815138151481515815168151781518815198152081521815228152381524815258152681527815288152981530815318153281533815348153581536815378153881539815408154181542815438154481545815468154781548815498155081551815528155381554815558155681557815588155981560815618156281563815648156581566815678156881569815708157181572815738157481575815768157781578815798158081581815828158381584815858158681587815888158981590815918159281593815948159581596815978159881599816008160181602816038160481605816068160781608816098161081611816128161381614816158161681617816188161981620816218162281623816248162581626816278162881629816308163181632816338163481635816368163781638816398164081641816428164381644816458164681647816488164981650816518165281653816548165581656816578165881659816608166181662816638166481665816668166781668816698167081671816728167381674816758167681677816788167981680816818168281683816848168581686816878168881689816908169181692816938169481695816968169781698816998170081701817028170381704817058170681707817088170981710817118171281713817148171581716817178171881719817208172181722817238172481725817268172781728817298173081731817328173381734817358173681737817388173981740817418174281743817448174581746817478174881749817508175181752817538175481755817568175781758817598176081761817628176381764817658176681767817688176981770817718177281773817748177581776817778177881779817808178181782817838178481785817868178781788817898179081791817928179381794817958179681797817988179981800818018180281803818048180581806818078180881809818108181181812818138181481815818168181781818818198182081821818228182381824818258182681827818288182981830818318183281833818348183581836818378183881839818408184181842818438184481845818468184781848818498185081851818528185381854818558185681857818588185981860818618186281863818648186581866818678186881869818708187181872818738187481875818768187781878818798188081881818828188381884818858188681887818888188981890818918189281893818948189581896818978189881899819008190181902819038190481905819068190781908819098191081911819128191381914819158191681917819188191981920819218192281923819248192581926819278192881929819308193181932819338193481935819368193781938819398194081941819428194381944819458194681947819488194981950819518195281953819548195581956819578195881959819608196181962819638196481965819668196781968819698197081971819728197381974819758197681977819788197981980819818198281983819848198581986819878198881989819908199181992819938199481995819968199781998819998200082001820028200382004820058200682007820088200982010820118201282013820148201582016820178201882019820208202182022820238202482025820268202782028820298203082031820328203382034820358203682037820388203982040820418204282043820448204582046820478204882049820508205182052820538205482055820568205782058820598206082061820628206382064820658206682067820688206982070820718207282073820748207582076820778207882079820808208182082820838208482085820868208782088820898209082091820928209382094820958209682097820988209982100821018210282103821048210582106821078210882109821108211182112821138211482115821168211782118821198212082121821228212382124821258212682127821288212982130821318213282133821348213582136821378213882139821408214182142821438214482145821468214782148821498215082151821528215382154821558215682157821588215982160821618216282163821648216582166821678216882169821708217182172821738217482175821768217782178821798218082181821828218382184821858218682187821888218982190821918219282193821948219582196821978219882199822008220182202822038220482205822068220782208822098221082211822128221382214822158221682217822188221982220822218222282223822248222582226822278222882229822308223182232822338223482235822368223782238822398224082241822428224382244822458224682247822488224982250822518225282253822548225582256822578225882259822608226182262822638226482265822668226782268822698227082271822728227382274822758227682277822788227982280822818228282283822848228582286822878228882289822908229182292822938229482295822968229782298822998230082301823028230382304823058230682307823088230982310823118231282313823148231582316823178231882319823208232182322823238232482325823268232782328823298233082331823328233382334823358233682337823388233982340823418234282343823448234582346823478234882349823508235182352823538235482355823568235782358823598236082361823628236382364823658236682367823688236982370823718237282373823748237582376823778237882379823808238182382823838238482385823868238782388823898239082391823928239382394823958239682397823988239982400824018240282403824048240582406824078240882409824108241182412824138241482415824168241782418824198242082421824228242382424824258242682427824288242982430824318243282433824348243582436824378243882439824408244182442824438244482445824468244782448824498245082451824528245382454824558245682457824588245982460824618246282463824648246582466824678246882469824708247182472824738247482475824768247782478824798248082481824828248382484824858248682487824888248982490824918249282493824948249582496824978249882499825008250182502825038250482505825068250782508825098251082511825128251382514825158251682517825188251982520825218252282523825248252582526825278252882529825308253182532825338253482535825368253782538825398254082541825428254382544825458254682547825488254982550825518255282553825548255582556825578255882559825608256182562825638256482565825668256782568825698257082571825728257382574825758257682577825788257982580825818258282583825848258582586825878258882589825908259182592825938259482595825968259782598825998260082601826028260382604826058260682607826088260982610826118261282613826148261582616826178261882619826208262182622826238262482625826268262782628826298263082631826328263382634826358263682637826388263982640826418264282643826448264582646826478264882649826508265182652826538265482655826568265782658826598266082661826628266382664826658266682667826688266982670826718267282673826748267582676826778267882679826808268182682826838268482685826868268782688826898269082691826928269382694826958269682697826988269982700827018270282703827048270582706827078270882709827108271182712827138271482715827168271782718827198272082721827228272382724827258272682727827288272982730827318273282733827348273582736827378273882739827408274182742827438274482745827468274782748827498275082751827528275382754827558275682757827588275982760827618276282763827648276582766827678276882769827708277182772827738277482775827768277782778827798278082781827828278382784827858278682787827888278982790827918279282793827948279582796827978279882799828008280182802828038280482805828068280782808828098281082811828128281382814828158281682817828188281982820828218282282823828248282582826828278282882829828308283182832828338283482835828368283782838828398284082841828428284382844828458284682847828488284982850828518285282853828548285582856828578285882859828608286182862828638286482865828668286782868828698287082871828728287382874828758287682877828788287982880828818288282883828848288582886828878288882889828908289182892828938289482895828968289782898828998290082901829028290382904829058290682907829088290982910829118291282913829148291582916829178291882919829208292182922829238292482925829268292782928829298293082931829328293382934829358293682937829388293982940829418294282943829448294582946829478294882949829508295182952829538295482955829568295782958829598296082961829628296382964829658296682967829688296982970829718297282973829748297582976829778297882979829808298182982829838298482985829868298782988829898299082991829928299382994829958299682997829988299983000830018300283003830048300583006830078300883009830108301183012830138301483015830168301783018830198302083021830228302383024830258302683027830288302983030830318303283033830348303583036830378303883039830408304183042830438304483045830468304783048830498305083051830528305383054830558305683057830588305983060830618306283063830648306583066830678306883069830708307183072830738307483075830768307783078830798308083081830828308383084830858308683087830888308983090830918309283093830948309583096830978309883099831008310183102831038310483105831068310783108831098311083111831128311383114831158311683117831188311983120831218312283123831248312583126831278312883129831308313183132831338313483135831368313783138831398314083141831428314383144831458314683147831488314983150831518315283153831548315583156831578315883159831608316183162831638316483165831668316783168831698317083171831728317383174831758317683177831788317983180831818318283183831848318583186831878318883189831908319183192831938319483195831968319783198831998320083201832028320383204832058320683207832088320983210832118321283213832148321583216832178321883219832208322183222832238322483225832268322783228832298323083231832328323383234832358323683237832388323983240832418324283243832448324583246832478324883249832508325183252832538325483255832568325783258832598326083261832628326383264832658326683267832688326983270832718327283273832748327583276832778327883279832808328183282832838328483285832868328783288832898329083291832928329383294832958329683297832988329983300833018330283303833048330583306833078330883309833108331183312833138331483315833168331783318833198332083321833228332383324833258332683327833288332983330833318333283333833348333583336833378333883339833408334183342833438334483345833468334783348833498335083351833528335383354833558335683357833588335983360833618336283363833648336583366833678336883369833708337183372833738337483375833768337783378833798338083381833828338383384833858338683387833888338983390833918339283393833948339583396833978339883399834008340183402834038340483405834068340783408834098341083411834128341383414834158341683417834188341983420834218342283423834248342583426834278342883429834308343183432834338343483435834368343783438834398344083441834428344383444834458344683447834488344983450834518345283453834548345583456834578345883459834608346183462834638346483465834668346783468834698347083471834728347383474834758347683477834788347983480834818348283483834848348583486834878348883489834908349183492834938349483495834968349783498834998350083501835028350383504835058350683507835088350983510835118351283513835148351583516835178351883519835208352183522835238352483525835268352783528835298353083531835328353383534835358353683537835388353983540835418354283543835448354583546835478354883549835508355183552835538355483555835568355783558835598356083561835628356383564835658356683567835688356983570835718357283573835748357583576835778357883579835808358183582835838358483585835868358783588835898359083591835928359383594835958359683597835988359983600836018360283603836048360583606836078360883609836108361183612836138361483615836168361783618836198362083621836228362383624836258362683627836288362983630836318363283633836348363583636836378363883639836408364183642836438364483645836468364783648836498365083651836528365383654836558365683657836588365983660836618366283663836648366583666836678366883669836708367183672836738367483675836768367783678836798368083681836828368383684836858368683687836888368983690836918369283693836948369583696836978369883699837008370183702837038370483705837068370783708837098371083711837128371383714837158371683717837188371983720837218372283723837248372583726837278372883729837308373183732837338373483735837368373783738837398374083741837428374383744837458374683747837488374983750837518375283753837548375583756837578375883759837608376183762837638376483765837668376783768837698377083771837728377383774837758377683777837788377983780837818378283783837848378583786837878378883789837908379183792837938379483795837968379783798837998380083801838028380383804838058380683807838088380983810838118381283813838148381583816838178381883819838208382183822838238382483825838268382783828838298383083831838328383383834838358383683837838388383983840838418384283843838448384583846838478384883849838508385183852838538385483855838568385783858838598386083861838628386383864838658386683867838688386983870838718387283873838748387583876838778387883879838808388183882838838388483885838868388783888838898389083891838928389383894838958389683897838988389983900839018390283903839048390583906839078390883909839108391183912839138391483915839168391783918839198392083921839228392383924839258392683927839288392983930839318393283933839348393583936839378393883939839408394183942839438394483945839468394783948839498395083951839528395383954839558395683957839588395983960839618396283963839648396583966839678396883969839708397183972839738397483975839768397783978839798398083981839828398383984839858398683987839888398983990839918399283993839948399583996839978399883999840008400184002840038400484005840068400784008840098401084011840128401384014840158401684017840188401984020840218402284023840248402584026840278402884029840308403184032840338403484035840368403784038840398404084041840428404384044840458404684047840488404984050840518405284053840548405584056840578405884059840608406184062840638406484065840668406784068840698407084071840728407384074840758407684077840788407984080840818408284083840848408584086840878408884089840908409184092840938409484095840968409784098840998410084101841028410384104841058410684107841088410984110841118411284113841148411584116841178411884119841208412184122841238412484125841268412784128841298413084131841328413384134841358413684137841388413984140841418414284143841448414584146841478414884149841508415184152841538415484155841568415784158841598416084161841628416384164841658416684167841688416984170841718417284173841748417584176841778417884179841808418184182841838418484185841868418784188841898419084191841928419384194841958419684197841988419984200842018420284203842048420584206842078420884209842108421184212842138421484215842168421784218842198422084221842228422384224842258422684227842288422984230842318423284233842348423584236842378423884239842408424184242842438424484245842468424784248842498425084251842528425384254842558425684257842588425984260842618426284263842648426584266842678426884269842708427184272842738427484275842768427784278842798428084281842828428384284842858428684287842888428984290842918429284293842948429584296842978429884299843008430184302843038430484305843068430784308843098431084311843128431384314843158431684317843188431984320843218432284323843248432584326843278432884329843308433184332843338433484335843368433784338843398434084341843428434384344843458434684347843488434984350843518435284353843548435584356843578435884359843608436184362843638436484365843668436784368843698437084371843728437384374843758437684377843788437984380843818438284383843848438584386843878438884389843908439184392843938439484395843968439784398843998440084401844028440384404844058440684407844088440984410844118441284413844148441584416844178441884419844208442184422844238442484425844268442784428844298443084431844328443384434844358443684437844388443984440844418444284443844448444584446844478444884449844508445184452844538445484455844568445784458844598446084461844628446384464844658446684467844688446984470844718447284473844748447584476844778447884479844808448184482844838448484485844868448784488844898449084491844928449384494844958449684497844988449984500845018450284503845048450584506845078450884509845108451184512845138451484515845168451784518845198452084521845228452384524845258452684527845288452984530845318453284533845348453584536845378453884539845408454184542845438454484545845468454784548845498455084551845528455384554845558455684557845588455984560845618456284563845648456584566845678456884569845708457184572845738457484575845768457784578845798458084581845828458384584845858458684587845888458984590845918459284593845948459584596845978459884599846008460184602846038460484605846068460784608846098461084611846128461384614846158461684617846188461984620846218462284623846248462584626846278462884629846308463184632846338463484635846368463784638846398464084641846428464384644846458464684647846488464984650846518465284653846548465584656846578465884659846608466184662846638466484665846668466784668846698467084671846728467384674846758467684677846788467984680846818468284683846848468584686846878468884689846908469184692846938469484695846968469784698846998470084701847028470384704847058470684707847088470984710847118471284713847148471584716847178471884719847208472184722847238472484725847268472784728847298473084731847328473384734847358473684737847388473984740847418474284743847448474584746847478474884749847508475184752847538475484755847568475784758847598476084761847628476384764847658476684767847688476984770847718477284773847748477584776847778477884779847808478184782847838478484785847868478784788847898479084791847928479384794847958479684797847988479984800848018480284803848048480584806848078480884809848108481184812848138481484815848168481784818848198482084821848228482384824848258482684827848288482984830848318483284833848348483584836848378483884839848408484184842848438484484845848468484784848848498485084851848528485384854848558485684857848588485984860848618486284863848648486584866848678486884869848708487184872848738487484875848768487784878848798488084881848828488384884848858488684887848888488984890848918489284893848948489584896848978489884899849008490184902849038490484905849068490784908849098491084911849128491384914849158491684917849188491984920849218492284923849248492584926849278492884929849308493184932849338493484935849368493784938849398494084941849428494384944849458494684947849488494984950849518495284953849548495584956849578495884959849608496184962849638496484965849668496784968849698497084971849728497384974849758497684977849788497984980849818498284983849848498584986849878498884989849908499184992849938499484995849968499784998849998500085001850028500385004850058500685007850088500985010850118501285013850148501585016850178501885019850208502185022850238502485025850268502785028850298503085031850328503385034850358503685037850388503985040850418504285043850448504585046850478504885049850508505185052850538505485055850568505785058850598506085061850628506385064850658506685067850688506985070850718507285073850748507585076850778507885079850808508185082850838508485085850868508785088850898509085091850928509385094850958509685097850988509985100851018510285103851048510585106851078510885109851108511185112851138511485115851168511785118851198512085121851228512385124851258512685127851288512985130851318513285133851348513585136851378513885139851408514185142851438514485145851468514785148851498515085151851528515385154851558515685157851588515985160851618516285163851648516585166851678516885169851708517185172851738517485175851768517785178851798518085181851828518385184851858518685187851888518985190851918519285193851948519585196851978519885199852008520185202852038520485205852068520785208852098521085211852128521385214852158521685217852188521985220852218522285223852248522585226852278522885229852308523185232852338523485235852368523785238852398524085241852428524385244852458524685247852488524985250852518525285253852548525585256852578525885259852608526185262852638526485265852668526785268852698527085271852728527385274852758527685277852788527985280852818528285283852848528585286852878528885289852908529185292852938529485295852968529785298852998530085301853028530385304853058530685307853088530985310853118531285313853148531585316853178531885319853208532185322853238532485325853268532785328853298533085331853328533385334853358533685337853388533985340853418534285343853448534585346853478534885349853508535185352853538535485355853568535785358853598536085361853628536385364853658536685367853688536985370853718537285373853748537585376853778537885379853808538185382853838538485385853868538785388853898539085391853928539385394853958539685397853988539985400854018540285403854048540585406854078540885409854108541185412854138541485415854168541785418854198542085421854228542385424854258542685427854288542985430854318543285433854348543585436854378543885439854408544185442854438544485445854468544785448854498545085451854528545385454854558545685457854588545985460854618546285463854648546585466854678546885469854708547185472854738547485475854768547785478854798548085481854828548385484854858548685487854888548985490854918549285493854948549585496854978549885499855008550185502855038550485505855068550785508855098551085511855128551385514855158551685517855188551985520855218552285523855248552585526855278552885529855308553185532855338553485535855368553785538855398554085541855428554385544855458554685547855488554985550855518555285553855548555585556855578555885559855608556185562855638556485565855668556785568855698557085571855728557385574855758557685577855788557985580855818558285583855848558585586855878558885589855908559185592855938559485595855968559785598855998560085601856028560385604856058560685607856088560985610856118561285613856148561585616856178561885619856208562185622856238562485625856268562785628856298563085631856328563385634856358563685637856388563985640856418564285643856448564585646856478564885649856508565185652856538565485655856568565785658856598566085661856628566385664856658566685667856688566985670856718567285673856748567585676856778567885679856808568185682856838568485685856868568785688856898569085691856928569385694856958569685697856988569985700857018570285703857048570585706857078570885709857108571185712857138571485715857168571785718857198572085721857228572385724857258572685727857288572985730857318573285733857348573585736857378573885739857408574185742857438574485745857468574785748857498575085751857528575385754857558575685757857588575985760857618576285763857648576585766857678576885769857708577185772857738577485775857768577785778857798578085781857828578385784857858578685787857888578985790857918579285793857948579585796857978579885799858008580185802858038580485805858068580785808858098581085811858128581385814858158581685817858188581985820858218582285823858248582585826858278582885829858308583185832858338583485835858368583785838858398584085841858428584385844858458584685847858488584985850858518585285853858548585585856858578585885859858608586185862858638586485865858668586785868858698587085871858728587385874858758587685877858788587985880858818588285883858848588585886858878588885889858908589185892858938589485895858968589785898858998590085901859028590385904859058590685907859088590985910859118591285913859148591585916859178591885919859208592185922859238592485925859268592785928859298593085931859328593385934859358593685937859388593985940859418594285943859448594585946859478594885949859508595185952859538595485955859568595785958859598596085961859628596385964859658596685967859688596985970859718597285973859748597585976859778597885979859808598185982859838598485985859868598785988859898599085991859928599385994859958599685997859988599986000860018600286003860048600586006860078600886009860108601186012860138601486015860168601786018860198602086021860228602386024860258602686027860288602986030860318603286033860348603586036860378603886039860408604186042860438604486045860468604786048860498605086051860528605386054860558605686057860588605986060860618606286063860648606586066860678606886069860708607186072860738607486075860768607786078860798608086081860828608386084860858608686087860888608986090860918609286093860948609586096860978609886099861008610186102861038610486105861068610786108861098611086111861128611386114861158611686117861188611986120861218612286123861248612586126861278612886129861308613186132861338613486135861368613786138861398614086141861428614386144861458614686147861488614986150861518615286153861548615586156861578615886159861608616186162861638616486165861668616786168861698617086171861728617386174861758617686177861788617986180861818618286183861848618586186861878618886189861908619186192861938619486195861968619786198861998620086201862028620386204862058620686207862088620986210862118621286213862148621586216862178621886219862208622186222862238622486225862268622786228862298623086231862328623386234862358623686237862388623986240862418624286243862448624586246862478624886249862508625186252862538625486255862568625786258862598626086261862628626386264862658626686267862688626986270862718627286273862748627586276862778627886279862808628186282862838628486285862868628786288862898629086291862928629386294862958629686297862988629986300863018630286303863048630586306863078630886309863108631186312863138631486315863168631786318863198632086321863228632386324863258632686327863288632986330863318633286333863348633586336863378633886339863408634186342863438634486345863468634786348863498635086351863528635386354863558635686357863588635986360863618636286363863648636586366863678636886369863708637186372863738637486375863768637786378863798638086381863828638386384863858638686387863888638986390863918639286393863948639586396863978639886399864008640186402864038640486405864068640786408864098641086411864128641386414864158641686417864188641986420864218642286423864248642586426864278642886429864308643186432864338643486435864368643786438864398644086441864428644386444864458644686447864488644986450864518645286453864548645586456864578645886459864608646186462864638646486465864668646786468864698647086471864728647386474864758647686477864788647986480864818648286483864848648586486864878648886489864908649186492864938649486495864968649786498864998650086501865028650386504865058650686507865088650986510865118651286513865148651586516865178651886519865208652186522865238652486525865268652786528865298653086531865328653386534865358653686537865388653986540865418654286543865448654586546865478654886549865508655186552865538655486555865568655786558865598656086561865628656386564865658656686567865688656986570865718657286573865748657586576865778657886579865808658186582865838658486585865868658786588865898659086591865928659386594865958659686597865988659986600866018660286603866048660586606866078660886609866108661186612866138661486615866168661786618866198662086621866228662386624866258662686627866288662986630866318663286633866348663586636866378663886639866408664186642866438664486645866468664786648866498665086651866528665386654866558665686657866588665986660866618666286663866648666586666866678666886669866708667186672866738667486675866768667786678866798668086681866828668386684866858668686687866888668986690866918669286693866948669586696866978669886699867008670186702867038670486705867068670786708867098671086711867128671386714867158671686717867188671986720867218672286723867248672586726867278672886729867308673186732867338673486735867368673786738867398674086741867428674386744867458674686747867488674986750867518675286753867548675586756867578675886759867608676186762867638676486765867668676786768867698677086771867728677386774867758677686777867788677986780867818678286783867848678586786867878678886789867908679186792867938679486795867968679786798867998680086801868028680386804868058680686807868088680986810868118681286813868148681586816868178681886819868208682186822868238682486825868268682786828868298683086831868328683386834868358683686837868388683986840868418684286843868448684586846868478684886849868508685186852868538685486855868568685786858868598686086861868628686386864868658686686867868688686986870868718687286873868748687586876868778687886879868808688186882868838688486885868868688786888868898689086891868928689386894868958689686897868988689986900869018690286903869048690586906869078690886909869108691186912869138691486915869168691786918869198692086921869228692386924869258692686927869288692986930869318693286933869348693586936869378693886939869408694186942869438694486945869468694786948869498695086951869528695386954869558695686957869588695986960869618696286963869648696586966869678696886969869708697186972869738697486975869768697786978869798698086981869828698386984869858698686987869888698986990869918699286993869948699586996869978699886999870008700187002870038700487005870068700787008870098701087011870128701387014870158701687017870188701987020870218702287023870248702587026870278702887029870308703187032870338703487035870368703787038870398704087041870428704387044870458704687047870488704987050870518705287053870548705587056870578705887059870608706187062870638706487065870668706787068870698707087071870728707387074870758707687077870788707987080870818708287083870848708587086870878708887089870908709187092870938709487095870968709787098870998710087101871028710387104871058710687107871088710987110871118711287113871148711587116871178711887119871208712187122871238712487125871268712787128871298713087131871328713387134871358713687137871388713987140871418714287143871448714587146871478714887149871508715187152871538715487155871568715787158871598716087161871628716387164871658716687167871688716987170871718717287173871748717587176871778717887179871808718187182871838718487185871868718787188871898719087191871928719387194871958719687197871988719987200872018720287203872048720587206872078720887209872108721187212872138721487215872168721787218872198722087221872228722387224872258722687227872288722987230872318723287233872348723587236872378723887239872408724187242872438724487245872468724787248872498725087251872528725387254872558725687257872588725987260872618726287263872648726587266872678726887269872708727187272872738727487275872768727787278872798728087281872828728387284872858728687287872888728987290872918729287293872948729587296872978729887299873008730187302873038730487305873068730787308873098731087311873128731387314873158731687317873188731987320873218732287323873248732587326873278732887329873308733187332873338733487335873368733787338873398734087341873428734387344873458734687347873488734987350873518735287353873548735587356873578735887359873608736187362873638736487365873668736787368873698737087371873728737387374873758737687377873788737987380873818738287383873848738587386873878738887389873908739187392873938739487395873968739787398873998740087401874028740387404874058740687407874088740987410874118741287413874148741587416874178741887419874208742187422874238742487425874268742787428874298743087431874328743387434874358743687437874388743987440874418744287443874448744587446874478744887449874508745187452874538745487455874568745787458874598746087461874628746387464874658746687467874688746987470874718747287473874748747587476874778747887479874808748187482874838748487485874868748787488874898749087491874928749387494874958749687497874988749987500875018750287503875048750587506875078750887509875108751187512875138751487515875168751787518875198752087521875228752387524875258752687527875288752987530875318753287533875348753587536875378753887539875408754187542875438754487545 |
- diff -Nur linux-2.6.36.orig/crypto/Kconfig linux-2.6.36/crypto/Kconfig
- --- linux-2.6.36.orig/crypto/Kconfig 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/crypto/Kconfig 2010-11-09 20:28:04.004996902 +0100
- @@ -845,3 +845,6 @@
- source "drivers/crypto/Kconfig"
-
- endif # if CRYPTO
- +
- +source "crypto/ocf/Kconfig"
- +
- diff -Nur linux-2.6.36.orig/crypto/Makefile linux-2.6.36/crypto/Makefile
- --- linux-2.6.36.orig/crypto/Makefile 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/crypto/Makefile 2010-11-09 20:28:04.014995662 +0100
- @@ -86,6 +86,8 @@
- obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
- obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
-
- +obj-$(CONFIG_OCF_OCF) += ocf/
- +
- #
- # generic algorithms and the async_tx api
- #
- diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.c linux-2.6.36/crypto/ocf/c7108/aes-7108.c
- --- linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/c7108/aes-7108.c 2010-11-09 20:28:04.061247304 +0100
- @@ -0,0 +1,839 @@
- +/*
- + * Copyright (C) 2006 Micronas USA
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored in part by the Defense Advanced Research Projects
- + * Agency (DARPA) and Air Force Research Laboratory, Air Force
- + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- + *
- + */
- +
- +//#include <linux/config.h>
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/sched.h>
- +#include <linux/wait.h>
- +#include <linux/crypto.h>
- +#include <linux/mm.h>
- +#include <linux/skbuff.h>
- +#include <linux/random.h>
- +#include <asm/io.h>
- +#include <asm/delay.h>
- +//#include <asm/scatterlist.h>
- +#include <linux/scatterlist.h>
- +#include <linux/dma-mapping.h>
- +#include <linux/highmem.h>
- +#include <cryptodev.h>
- +#include <uio.h>
- +#include <aes-7108.h>
- +
- +/* Runtime mode */
- +static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
- +//static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
- +
- +static int32_t c7108_id = -1;
- +static struct cipher_7108 **c7108_sessions = NULL;
- +static u_int32_t c7108_sesnum = 0;
- +static unsigned long iobar;
- +
- +/* Crypto entry points */
- +static int c7108_process(void *, struct cryptop *, int);
- +static int c7108_newsession(void *, u_int32_t *, struct cryptoini *);
- +static int c7108_freesession(void *, u_int64_t);
- +
- +/* Globals */
- +static int debug = 0;
- +static spinlock_t csr_mutex;
- +
- +/* Generic controller-based lock */
- +#define AES_LOCK()\
- + spin_lock(&csr_mutex)
- +#define AES_UNLOCK()\
- + spin_unlock(&csr_mutex)
- +
- +/* 7108 AES register access */
- +#define c7108_reg_wr8(a,d) iowrite8(d, (void*)(iobar+(a)))
- +#define c7108_reg_wr16(a,d) iowrite16(d, (void*)(iobar+(a)))
- +#define c7108_reg_wr32(a,d) iowrite32(d, (void*)(iobar+(a)))
- +#define c7108_reg_rd8(a) ioread8((void*)(iobar+(a)))
- +#define c7108_reg_rd16(a) ioread16((void*)(iobar+(a)))
- +#define c7108_reg_rd32(a) ioread32((void*)(iobar+(a)))
- +
- +static int
- +c7108_xlate_key(int klen, u8* k8ptr, u32* k32ptr)
- +{
- + int i, nw=0;
- + nw = ((klen >= 256) ? 8 : (klen >= 192) ? 6 : 4);
- + for ( i = 0; i < nw; i++) {
- + k32ptr[i] = (k8ptr[i+3] << 24) | (k8ptr[i+2] << 16) |
- + (k8ptr[i+1] << 8) | k8ptr[i];
- +
- + }
- + return 0;
- +}
- +
- +static int
- +c7108_cache_key(int klen, u32* k32ptr, u8* k8ptr)
- +{
- + int i, nb=0;
- + u8* ptr = (u8*)k32ptr;
- + nb = ((klen >= 256) ? 32 : (klen >= 192) ? 24 : 16);
- + for ( i = 0; i < nb; i++)
- + k8ptr[i] = ptr[i];
- + return 0;
- +}
- +
- +static int
- +c7108_aes_setup_dma(u32 src, u32 dst, u32 len)
- +{
- + if (len < 16) {
- + printk("len < 16\n");
- + return -10;
- + }
- + if (len % 16) {
- + printk("len not multiple of 16\n");
- + return -11;
- + }
- + c7108_reg_wr16(C7108_AES_DMA_SRC0_LO, (u16) src);
- + c7108_reg_wr16(C7108_AES_DMA_SRC0_HI, (u16)((src & 0xffff0000) >> 16));
- + c7108_reg_wr16(C7108_AES_DMA_DST0_LO, (u16) dst);
- + c7108_reg_wr16(C7108_AES_DMA_DST0_HI, (u16)((dst & 0xffff0000) >> 16));
- + c7108_reg_wr16(C7108_AES_DMA_LEN, (u16) ((len / 16) - 1));
- +
- + return 0;
- +}
- +
- +static int
- +c7108_aes_set_hw_iv(u8 iv[16])
- +{
- + c7108_reg_wr16(C7108_AES_IV0_LO, (u16) ((iv[1] << 8) | iv[0]));
- + c7108_reg_wr16(C7108_AES_IV0_HI, (u16) ((iv[3] << 8) | iv[2]));
- + c7108_reg_wr16(C7108_AES_IV1_LO, (u16) ((iv[5] << 8) | iv[4]));
- + c7108_reg_wr16(C7108_AES_IV1_HI, (u16) ((iv[7] << 8) | iv[6]));
- + c7108_reg_wr16(C7108_AES_IV2_LO, (u16) ((iv[9] << 8) | iv[8]));
- + c7108_reg_wr16(C7108_AES_IV2_HI, (u16) ((iv[11] << 8) | iv[10]));
- + c7108_reg_wr16(C7108_AES_IV3_LO, (u16) ((iv[13] << 8) | iv[12]));
- + c7108_reg_wr16(C7108_AES_IV3_HI, (u16) ((iv[15] << 8) | iv[14]));
- +
- + return 0;
- +}
- +
- +static void
- +c7108_aes_read_dkey(u32 * dkey)
- +{
- + dkey[0] = (c7108_reg_rd16(C7108_AES_EKEY0_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY0_LO);
- + dkey[1] = (c7108_reg_rd16(C7108_AES_EKEY1_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY1_LO);
- + dkey[2] = (c7108_reg_rd16(C7108_AES_EKEY2_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY2_LO);
- + dkey[3] = (c7108_reg_rd16(C7108_AES_EKEY3_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY3_LO);
- + dkey[4] = (c7108_reg_rd16(C7108_AES_EKEY4_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY4_LO);
- + dkey[5] = (c7108_reg_rd16(C7108_AES_EKEY5_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY5_LO);
- + dkey[6] = (c7108_reg_rd16(C7108_AES_EKEY6_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY6_LO);
- + dkey[7] = (c7108_reg_rd16(C7108_AES_EKEY7_HI) << 16) |
- + c7108_reg_rd16(C7108_AES_EKEY7_LO);
- +}
- +
- +static int
- +c7108_aes_cipher(int op,
- + u32 dst,
- + u32 src,
- + u32 len,
- + int klen,
- + u16 mode,
- + u32 key[8],
- + u8 iv[16])
- +{
- + int rv = 0, cnt=0;
- + u16 ctrl = 0, stat = 0;
- +
- + AES_LOCK();
- +
- + /* Setup key length */
- + if (klen == 128) {
- + ctrl |= C7108_AES_KEY_LEN_128;
- + } else if (klen == 192) {
- + ctrl |= C7108_AES_KEY_LEN_192;
- + } else if (klen == 256) {
- + ctrl |= C7108_AES_KEY_LEN_256;
- + } else {
- + AES_UNLOCK();
- + return -3;
- + }
- +
- + /* Check opcode */
- + if (C7108_AES_ENCRYPT == op) {
- + ctrl |= C7108_AES_ENCRYPT;
- + } else if (C7108_AES_DECRYPT == op) {
- + ctrl |= C7108_AES_DECRYPT;
- + } else {
- + AES_UNLOCK();
- + return -4;
- + }
- +
- + /* check mode */
- + if ( (mode != C7108_AES_CTRL_MODE_CBC) &&
- + (mode != C7108_AES_CTRL_MODE_CFB) &&
- + (mode != C7108_AES_CTRL_MODE_OFB) &&
- + (mode != C7108_AES_CTRL_MODE_CTR) &&
- + (mode != C7108_AES_CTRL_MODE_ECB) ) {
- + AES_UNLOCK();
- + return -5;
- + }
- +
- + /* Now set mode */
- + ctrl |= mode;
- +
- + /* For CFB, OFB, and CTR, neither backward key
- + * expansion nor key inversion is required.
- + */
- + if ( (C7108_AES_DECRYPT == op) &&
- + (C7108_AES_CTRL_MODE_CBC == mode ||
- + C7108_AES_CTRL_MODE_ECB == mode ) ){
- +
- + /* Program Key */
- + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[4]);
- + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[4] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[5]);
- + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[5] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[6]);
- + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[6] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[7]);
- + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[7] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[2]);
- + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[2] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[3]);
- + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[3] >> 16));
- +
- +
- + if (192 == klen) {
- + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[7]);
- + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[7] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[7]);
- + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[7] >> 16));
- +
- + } else if (256 == klen) {
- + /* 256 */
- + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[0]);
- + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[0] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[1]);
- + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[1] >> 16));
- +
- + }
- +
- + } else {
- + /* Program Key */
- + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[0]);
- + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[0] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[1]);
- + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[1] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[2]);
- + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[2] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[3]);
- + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[3] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[4]);
- + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[4] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[5]);
- + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[5] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[6]);
- + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[6] >> 16));
- + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[7]);
- + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[7] >> 16));
- +
- + }
- +
- + /* Set IV always */
- + c7108_aes_set_hw_iv(iv);
- +
- + /* Program DMA addresses */
- + if ((rv = c7108_aes_setup_dma(src, dst, len)) < 0) {
- + AES_UNLOCK();
- + return rv;
- + }
- +
- +
- + /* Start AES cipher */
- + c7108_reg_wr16(C7108_AES_CTRL, ctrl | C7108_AES_GO);
- +
- + //printk("Ctrl: 0x%x\n", ctrl | C7108_AES_GO);
- + do {
- + /* TODO: interrupt mode */
- + // printk("aes_stat=0x%x\n", stat);
- + //udelay(100);
- + } while ((cnt++ < 1000000) &&
- + !((stat=c7108_reg_rd16(C7108_AES_CTRL))&C7108_AES_OP_DONE));
- +
- +
- + if ((mode == C7108_AES_CTRL_MODE_ECB)||
- + (mode == C7108_AES_CTRL_MODE_CBC)) {
- + /* Save out key when the lock is held ... */
- + c7108_aes_read_dkey(key);
- + }
- +
- + AES_UNLOCK();
- + return 0;
- +
- +}
- +
- +/*
- + * Generate a new crypto device session.
- + */
- +static int
- +c7108_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
- +{
- + struct cipher_7108 **swd;
- + u_int32_t i;
- + char *algo;
- + int mode, xfm_type;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid == NULL || cri == NULL) {
- + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + if (c7108_sessions) {
- + for (i = 1; i < c7108_sesnum; i++)
- + if (c7108_sessions[i] == NULL)
- + break;
- + } else
- + i = 1; /* NB: to silence compiler warning */
- +
- + if (c7108_sessions == NULL || i == c7108_sesnum) {
- + if (c7108_sessions == NULL) {
- + i = 1; /* We leave c7108_sessions[0] empty */
- + c7108_sesnum = CRYPTO_SW_SESSIONS;
- + } else
- + c7108_sesnum *= 2;
- +
- + swd = kmalloc(c7108_sesnum * sizeof(struct cipher_7108 *),
- + GFP_ATOMIC);
- + if (swd == NULL) {
- + /* Reset session number */
- + if (c7108_sesnum == CRYPTO_SW_SESSIONS)
- + c7108_sesnum = 0;
- + else
- + c7108_sesnum /= 2;
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memset(swd, 0, c7108_sesnum * sizeof(struct cipher_7108 *));
- +
- + /* Copy existing sessions */
- + if (c7108_sessions) {
- + memcpy(swd, c7108_sessions,
- + (c7108_sesnum / 2) * sizeof(struct cipher_7108 *));
- + kfree(c7108_sessions);
- + }
- +
- + c7108_sessions = swd;
- +
- + }
- +
- + swd = &c7108_sessions[i];
- + *sid = i;
- +
- + while (cri) {
- + *swd = (struct cipher_7108 *)
- + kmalloc(sizeof(struct cipher_7108), GFP_ATOMIC);
- + if (*swd == NULL) {
- + c7108_freesession(NULL, i);
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memset(*swd, 0, sizeof(struct cipher_7108));
- +
- + algo = NULL;
- + mode = 0;
- + xfm_type = HW_TYPE_CIPHER;
- +
- + switch (cri->cri_alg) {
- +
- + case CRYPTO_AES_CBC:
- + algo = "aes";
- + mode = CRYPTO_TFM_MODE_CBC;
- + c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
- + break;
- +#if 0
- + case CRYPTO_AES_CTR:
- + algo = "aes_ctr";
- + mode = CRYPTO_TFM_MODE_CBC;
- + c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
- + break;
- + case CRYPTO_AES_ECB:
- + algo = "aes_ecb";
- + mode = CRYPTO_TFM_MODE_CBC;
- + c7108_crypto_mode = C7108_AES_CTRL_MODE_ECB;
- + break;
- + case CRYPTO_AES_OFB:
- + algo = "aes_ofb";
- + mode = CRYPTO_TFM_MODE_CBC;
- + c7108_crypto_mode = C7108_AES_CTRL_MODE_OFB;
- + break;
- + case CRYPTO_AES_CFB:
- + algo = "aes_cfb";
- + mode = CRYPTO_TFM_MODE_CBC;
- + c7108_crypto_mode = C7108_AES_CTRL_MODE_CFB;
- + break;
- +#endif
- + default:
- + printk("unsupported crypto algorithm: %d\n",
- + cri->cri_alg);
- + return -EINVAL;
- + break;
- + }
- +
- +
- + if (!algo || !*algo) {
- + printk("cypher_7108_crypto: Unknown algo 0x%x\n",
- + cri->cri_alg);
- + c7108_freesession(NULL, i);
- + return EINVAL;
- + }
- +
- + if (xfm_type == HW_TYPE_CIPHER) {
- + if (debug) {
- + dprintk("%s key:", __FUNCTION__);
- + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
- + dprintk("%s0x%02x", (i % 8) ? " " : "\n ",
- + cri->cri_key[i]);
- + dprintk("\n");
- + }
- +
- + } else if (xfm_type == SW_TYPE_HMAC ||
- + xfm_type == SW_TYPE_HASH) {
- + printk("cypher_7108_crypto: HMAC unsupported!\n");
- + return -EINVAL;
- + c7108_freesession(NULL, i);
- + } else {
- + printk("cypher_7108_crypto: "
- + "Unhandled xfm_type %d\n", xfm_type);
- + c7108_freesession(NULL, i);
- + return EINVAL;
- + }
- +
- + (*swd)->cri_alg = cri->cri_alg;
- + (*swd)->xfm_type = xfm_type;
- +
- + cri = cri->cri_next;
- + swd = &((*swd)->next);
- + }
- + return 0;
- +}
- +
- +/*
- + * Free a session.
- + */
- +static int
- +c7108_freesession(void *arg, u_int64_t tid)
- +{
- + struct cipher_7108 *swd;
- + u_int32_t sid = CRYPTO_SESID2LID(tid);
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid > c7108_sesnum || c7108_sessions == NULL ||
- + c7108_sessions[sid] == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return(EINVAL);
- + }
- +
- + /* Silently accept and return */
- + if (sid == 0)
- + return(0);
- +
- + while ((swd = c7108_sessions[sid]) != NULL) {
- + c7108_sessions[sid] = swd->next;
- + kfree(swd);
- + }
- + return 0;
- +}
- +
- +/*
- + * Process a hardware request.
- + */
- +static int
- +c7108_process(void *arg, struct cryptop *crp, int hint)
- +{
- + struct cryptodesc *crd;
- + struct cipher_7108 *sw;
- + u_int32_t lid;
- + int type;
- + u32 hwkey[8];
- +
- +#define SCATTERLIST_MAX 16
- + struct scatterlist sg[SCATTERLIST_MAX];
- + int sg_num, sg_len, skip;
- + struct sk_buff *skb = NULL;
- + struct uio *uiop = NULL;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + /* Sanity check */
- + if (crp == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + crp->crp_etype = 0;
- +
- + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + lid = crp->crp_sid & 0xffffffff;
- + if (lid >= c7108_sesnum || lid == 0 || c7108_sessions == NULL ||
- + c7108_sessions[lid] == NULL) {
- + crp->crp_etype = ENOENT;
- + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + /*
- + * do some error checking outside of the loop for SKB and IOV
- + * processing this leaves us with valid skb or uiop pointers
- + * for later
- + */
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + skb = (struct sk_buff *) crp->crp_buf;
- + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
- + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX",
- + __FILE__, __LINE__,
- + skb_shinfo(skb)->nr_frags);
- + goto done;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + uiop = (struct uio *) crp->crp_buf;
- + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
- + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX",
- + __FILE__, __LINE__,
- + uiop->uio_iovcnt);
- + goto done;
- + }
- + }
- +
- + /* Go through crypto descriptors, processing as we go */
- + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
- + /*
- + * Find the crypto context.
- + *
- + * XXX Note that the logic here prevents us from having
- + * XXX the same algorithm multiple times in a session
- + * XXX (or rather, we can but it won't give us the right
- + * XXX results). To do that, we'd need some way of differentiating
- + * XXX between the various instances of an algorithm (so we can
- + * XXX locate the correct crypto context).
- + */
- + for (sw = c7108_sessions[lid];
- + sw && sw->cri_alg != crd->crd_alg;
- + sw = sw->next)
- + ;
- +
- + /* No such context ? */
- + if (sw == NULL) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + skip = crd->crd_skip;
- +
- + /*
- + * setup the SG list skip from the start of the buffer
- + */
- + memset(sg, 0, sizeof(sg));
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + int i, len;
- + type = CRYPTO_BUF_SKBUF;
- +
- + sg_num = 0;
- + sg_len = 0;
- +
- + if (skip < skb_headlen(skb)) {
- + //sg[sg_num].page = virt_to_page(skb->data + skip);
- + //sg[sg_num].offset = offset_in_page(skb->data + skip);
- + len = skb_headlen(skb) - skip;
- + if (len + sg_len > crd->crd_len)
- + len = crd->crd_len - sg_len;
- + //sg[sg_num].length = len;
- + sg_set_page(&sg[sg_num], virt_to_page(skb->data + skip), len, offset_in_page(skb->data + skip));
- + sg_len += sg[sg_num].length;
- + sg_num++;
- + skip = 0;
- + } else
- + skip -= skb_headlen(skb);
- +
- + for (i = 0; sg_len < crd->crd_len &&
- + i < skb_shinfo(skb)->nr_frags &&
- + sg_num < SCATTERLIST_MAX; i++) {
- + if (skip < skb_shinfo(skb)->frags[i].size) {
- + //sg[sg_num].page = skb_shinfo(skb)->frags[i].page;
- + //sg[sg_num].offset = skb_shinfo(skb)->frags[i].page_offset + skip;
- + len = skb_shinfo(skb)->frags[i].size - skip;
- + if (len + sg_len > crd->crd_len)
- + len = crd->crd_len - sg_len;
- + //sg[sg_num].length = len;
- + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, len, skb_shinfo(skb)->frags[i].page_offset + skip);
- + sg_len += sg[sg_num].length;
- + sg_num++;
- + skip = 0;
- + } else
- + skip -= skb_shinfo(skb)->frags[i].size;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + int len;
- + type = CRYPTO_BUF_IOV;
- + sg_len = 0;
- + for (sg_num = 0; sg_len < crd->crd_len &&
- + sg_num < uiop->uio_iovcnt &&
- + sg_num < SCATTERLIST_MAX; sg_num++) {
- + if (skip < uiop->uio_iov[sg_num].iov_len) {
- + //sg[sg_num].page = virt_to_page(uiop->uio_iov[sg_num].iov_base+skip);
- + //sg[sg_num].offset = offset_in_page(uiop->uio_iov[sg_num].iov_base+skip);
- + len = uiop->uio_iov[sg_num].iov_len - skip;
- + if (len + sg_len > crd->crd_len)
- + len = crd->crd_len - sg_len;
- + //sg[sg_num].length = len;
- + sg_set_page(&sg[sg_num], virt_to_page(uiop->uio_iov[sg_num].iov_base+skip), len, offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
- + sg_len += sg[sg_num].length;
- + skip = 0;
- + } else
- + skip -= uiop->uio_iov[sg_num].iov_len;
- + }
- + } else {
- + type = CRYPTO_BUF_CONTIG;
- + //sg[0].page = virt_to_page(crp->crp_buf + skip);
- + //sg[0].offset = offset_in_page(crp->crp_buf + skip);
- + sg_len = (crp->crp_ilen - skip);
- + if (sg_len > crd->crd_len)
- + sg_len = crd->crd_len;
- + //sg[0].length = sg_len;
- + sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip), sg_len, offset_in_page(crp->crp_buf + skip));
- + sg_num = 1;
- + }
- +
- +
- + switch (sw->xfm_type) {
- +
- + case HW_TYPE_CIPHER: {
- +
- + unsigned char iv[64];
- + unsigned char *ivp = iv;
- + int i;
- + int ivsize = 16; /* fixed for AES */
- + int blocksize = 16; /* fixed for AES */
- +
- + if (sg_len < blocksize) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL len %d < %d\n",
- + __FILE__, __LINE__,
- + sg_len,
- + blocksize);
- + goto done;
- + }
- +
- + if (ivsize > sizeof(iv)) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
- +
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
- + ivp = crd->crd_iv;
- + } else {
- + get_random_bytes(ivp, ivsize);
- + }
- + /*
- + * do we have to copy the IV back to the buffer ?
- + */
- + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- + crypto_copyback(crp->crp_buf,
- + crd->crd_inject,
- + ivsize,
- + (caddr_t)ivp);
- + }
- +
- + c7108_xlate_key(crd->crd_klen,
- + (u8*)crd->crd_key, (u32*)hwkey);
- +
- + /* Encrypt SG list */
- + for (i = 0; i < sg_num; i++) {
- + sg[i].dma_address =
- + dma_map_single(NULL,
- + kmap(sg_page(&sg[i])) + sg[i].offset, sg_len, DMA_BIDIRECTIONAL);
- +#if 0
- + printk("sg[%d]:0x%08x, off 0x%08x "
- + "kmap 0x%08x phys 0x%08x\n",
- + i, sg[i].page, sg[i].offset,
- + kmap(sg[i].page) + sg[i].offset,
- + sg[i].dma_address);
- +#endif
- + c7108_aes_cipher(C7108_AES_ENCRYPT,
- + sg[i].dma_address,
- + sg[i].dma_address,
- + sg_len,
- + crd->crd_klen,
- + c7108_crypto_mode,
- + hwkey,
- + ivp);
- +
- + if ((c7108_crypto_mode == C7108_AES_CTRL_MODE_CBC)||
- + (c7108_crypto_mode == C7108_AES_CTRL_MODE_ECB)) {
- + /* Read back expanded key and cache it in key
- + * context.
- + * NOTE: for ECB/CBC modes only (not CTR, CFB, OFB)
- + * where you set the key once.
- + */
- + c7108_cache_key(crd->crd_klen,
- + (u32*)hwkey, (u8*)crd->crd_key);
- +#if 0
- + printk("%s expanded key:", __FUNCTION__);
- + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
- + printk("%s0x%02x", (i % 8) ? " " : "\n ",
- + crd->crd_key[i]);
- + printk("\n");
- +#endif
- + }
- + }
- + }
- + else { /*decrypt */
- +
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
- + ivp = crd->crd_iv;
- + } else {
- + crypto_copydata(crp->crp_buf, crd->crd_inject,
- + ivsize, (caddr_t)ivp);
- + }
- +
- + c7108_xlate_key(crd->crd_klen,
- + (u8*)crd->crd_key, (u32*)hwkey);
- +
- + /* Decrypt SG list */
- + for (i = 0; i < sg_num; i++) {
- + sg[i].dma_address =
- + dma_map_single(NULL,
- + kmap(sg_page(&sg[i])) + sg[i].offset,
- + sg_len, DMA_BIDIRECTIONAL);
- +
- +#if 0
- + printk("sg[%d]:0x%08x, off 0x%08x "
- + "kmap 0x%08x phys 0x%08x\n",
- + i, sg[i].page, sg[i].offset,
- + kmap(sg[i].page) + sg[i].offset,
- + sg[i].dma_address);
- +#endif
- + c7108_aes_cipher(C7108_AES_DECRYPT,
- + sg[i].dma_address,
- + sg[i].dma_address,
- + sg_len,
- + crd->crd_klen,
- + c7108_crypto_mode,
- + hwkey,
- + ivp);
- + }
- + }
- + } break;
- + case SW_TYPE_HMAC:
- + case SW_TYPE_HASH:
- + crp->crp_etype = EINVAL;
- + goto done;
- + break;
- +
- + case SW_TYPE_COMP:
- + crp->crp_etype = EINVAL;
- + goto done;
- + break;
- +
- + default:
- + /* Unknown/unsupported algorithm */
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- + }
- +
- +done:
- + crypto_done(crp);
- + return 0;
- +}
- +
- +static struct {
- + softc_device_decl sc_dev;
- +} a7108dev;
- +
- +static device_method_t a7108_methods = {
- +/* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, c7108_newsession),
- + DEVMETHOD(cryptodev_freesession, c7108_freesession),
- + DEVMETHOD(cryptodev_process, c7108_process),
- + DEVMETHOD(cryptodev_kprocess, NULL)
- +};
- +
- +static int
- +cypher_7108_crypto_init(void)
- +{
- + dprintk("%s(%p)\n", __FUNCTION__, cypher_7108_crypto_init);
- +
- + iobar = (unsigned long)ioremap(CCU_AES_REG_BASE, 0x4000);
- + printk("7108: AES @ 0x%08x (0x%08x phys) %s mode\n",
- + iobar, CCU_AES_REG_BASE,
- + c7108_crypto_mode & C7108_AES_CTRL_MODE_CBC ? "CBC" :
- + c7108_crypto_mode & C7108_AES_CTRL_MODE_ECB ? "ECB" :
- + c7108_crypto_mode & C7108_AES_CTRL_MODE_CTR ? "CTR" :
- + c7108_crypto_mode & C7108_AES_CTRL_MODE_CFB ? "CFB" :
- + c7108_crypto_mode & C7108_AES_CTRL_MODE_OFB ? "OFB" : "???");
- + csr_mutex = SPIN_LOCK_UNLOCKED;
- +
- + memset(&a7108dev, 0, sizeof(a7108dev));
- + softc_device_init(&a7108dev, "aes7108", 0, a7108_methods);
- +
- + c7108_id = crypto_get_driverid(softc_get_device(&a7108dev), CRYPTOCAP_F_HARDWARE);
- + if (c7108_id < 0)
- + panic("7108: crypto device cannot initialize!");
- +
- +// crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0, c7108_newsession, c7108_freesession, c7108_process, NULL);
- + crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0);
- +
- + return(0);
- +}
- +
- +static void
- +cypher_7108_crypto_exit(void)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + crypto_unregister_all(c7108_id);
- + c7108_id = -1;
- +}
- +
- +module_init(cypher_7108_crypto_init);
- +module_exit(cypher_7108_crypto_exit);
- +
- +MODULE_LICENSE("Dual BSD/GPL");
- +MODULE_DESCRIPTION("Cypher 7108 Crypto (OCF module for kernel crypto)");
- diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.h linux-2.6.36/crypto/ocf/c7108/aes-7108.h
- --- linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/c7108/aes-7108.h 2010-11-09 20:28:04.102495305 +0100
- @@ -0,0 +1,134 @@
- +/*
- + * Copyright (C) 2006 Micronas USA
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored in part by the Defense Advanced Research Projects
- + * Agency (DARPA) and Air Force Research Laboratory, Air Force
- + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- + *
- + */
- +
- +#ifndef __AES_7108_H__
- +#define __AES_7108_H__
- +
- +/* Cypher 7108 AES Controller Hardware */
- +#define CCU_REG_BASE 0x1b500000
- +#define CCU_AES_REG_BASE (CCU_REG_BASE + 0x100)
- +#define C7108_AES_KEY0_LO (0x0000)
- +#define C7108_AES_KEY0_HI (0x0004)
- +#define C7108_AES_KEY1_LO (0x0008)
- +#define C7108_AES_KEY1_HI (0x000c)
- +#define C7108_AES_KEY2_LO (0x0010)
- +#define C7108_AES_KEY2_HI (0x0014)
- +#define C7108_AES_KEY3_LO (0x0018)
- +#define C7108_AES_KEY3_HI (0x001c)
- +#define C7108_AES_KEY4_LO (0x0020)
- +#define C7108_AES_KEY4_HI (0x0024)
- +#define C7108_AES_KEY5_LO (0x0028)
- +#define C7108_AES_KEY5_HI (0x002c)
- +#define C7108_AES_KEY6_LO (0x0030)
- +#define C7108_AES_KEY6_HI (0x0034)
- +#define C7108_AES_KEY7_LO (0x0038)
- +#define C7108_AES_KEY7_HI (0x003c)
- +#define C7108_AES_IV0_LO (0x0040)
- +#define C7108_AES_IV0_HI (0x0044)
- +#define C7108_AES_IV1_LO (0x0048)
- +#define C7108_AES_IV1_HI (0x004c)
- +#define C7108_AES_IV2_LO (0x0050)
- +#define C7108_AES_IV2_HI (0x0054)
- +#define C7108_AES_IV3_LO (0x0058)
- +#define C7108_AES_IV3_HI (0x005c)
- +
- +#define C7108_AES_DMA_SRC0_LO (0x0068) /* Bits 0:15 */
- +#define C7108_AES_DMA_SRC0_HI (0x006c) /* Bits 27:16 */
- +#define C7108_AES_DMA_DST0_LO (0x0070) /* Bits 0:15 */
- +#define C7108_AES_DMA_DST0_HI (0x0074) /* Bits 27:16 */
- +#define C7108_AES_DMA_LEN (0x0078) /*Bytes:(Count+1)x16 */
- +
- +/* AES/Copy engine control register */
- +#define C7108_AES_CTRL (0x007c) /* AES control */
- +#define C7108_AES_CTRL_RS (1<<0) /* Which set of src/dst to use */
- +
- +/* AES Cipher mode, controlled by setting Bits 2:0 */
- +#define C7108_AES_CTRL_MODE_CBC 0
- +#define C7108_AES_CTRL_MODE_CFB (1<<0)
- +#define C7108_AES_CTRL_MODE_OFB (1<<1)
- +#define C7108_AES_CTRL_MODE_CTR ((1<<0)|(1<<1))
- +#define C7108_AES_CTRL_MODE_ECB (1<<2)
- +
- +/* AES Key length , Bits 5:4 */
- +#define C7108_AES_KEY_LEN_128 0 /* 00 */
- +#define C7108_AES_KEY_LEN_192 (1<<4) /* 01 */
- +#define C7108_AES_KEY_LEN_256 (1<<5) /* 10 */
- +
- +/* AES Operation (crypt/decrypt), Bit 3 */
- +#define C7108_AES_DECRYPT (1<<3) /* Clear for encrypt */
- +#define C7108_AES_ENCRYPT 0
- +#define C7108_AES_INTR (1<<13) /* Set on done trans from 0->1*/
- +#define C7108_AES_GO (1<<14) /* Run */
- +#define C7108_AES_OP_DONE (1<<15) /* Set when complete */
- +
- +
- +/* Expanded key registers */
- +#define C7108_AES_EKEY0_LO (0x0080)
- +#define C7108_AES_EKEY0_HI (0x0084)
- +#define C7108_AES_EKEY1_LO (0x0088)
- +#define C7108_AES_EKEY1_HI (0x008c)
- +#define C7108_AES_EKEY2_LO (0x0090)
- +#define C7108_AES_EKEY2_HI (0x0094)
- +#define C7108_AES_EKEY3_LO (0x0098)
- +#define C7108_AES_EKEY3_HI (0x009c)
- +#define C7108_AES_EKEY4_LO (0x00a0)
- +#define C7108_AES_EKEY4_HI (0x00a4)
- +#define C7108_AES_EKEY5_LO (0x00a8)
- +#define C7108_AES_EKEY5_HI (0x00ac)
- +#define C7108_AES_EKEY6_LO (0x00b0)
- +#define C7108_AES_EKEY6_HI (0x00b4)
- +#define C7108_AES_EKEY7_LO (0x00b8)
- +#define C7108_AES_EKEY7_HI (0x00bc)
- +#define C7108_AES_OK (0x00fc) /* Reset: "OK" */
- +
- +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
- +
- +/* Software session entry */
- +
- +#define HW_TYPE_CIPHER 0
- +#define SW_TYPE_HMAC 1
- +#define SW_TYPE_AUTH2 2
- +#define SW_TYPE_HASH 3
- +#define SW_TYPE_COMP 4
- +
- +struct cipher_7108 {
- + int xfm_type;
- + int cri_alg;
- + union {
- + struct {
- + char sw_key[HMAC_BLOCK_LEN];
- + int sw_klen;
- + int sw_authlen;
- + } hmac;
- + } u;
- + struct cipher_7108 *next;
- +};
- +
- +
- +
- +#endif /* __C7108_AES_7108_H__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/Makefile linux-2.6.36/crypto/ocf/c7108/Makefile
- --- linux-2.6.36.orig/crypto/ocf/c7108/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/c7108/Makefile 2010-11-09 20:28:04.152495478 +0100
- @@ -0,0 +1,12 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_C7108) += aes-7108.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/Config.in linux-2.6.36/crypto/ocf/Config.in
- --- linux-2.6.36.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/Config.in 2010-11-09 20:28:04.191247583 +0100
- @@ -0,0 +1,36 @@
- +#############################################################################
- +
- +mainmenu_option next_comment
- +comment 'OCF Configuration'
- +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
- +dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
- + CONFIG_OCF_FIPS $CONFIG_OCF_OCF
- +dep_mbool ' enable harvesting entropy for /dev/random' \
- + CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
- +dep_tristate ' cryptodev (user space support)' \
- + CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
- +dep_tristate ' cryptosoft (software crypto engine)' \
- + CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
- +dep_tristate ' safenet (HW crypto engine)' \
- + CONFIG_OCF_SAFE $CONFIG_OCF_OCF
- +dep_tristate ' IXP4xx (HW crypto engine)' \
- + CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
- +dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
- + CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
- +dep_tristate ' hifn (HW crypto engine)' \
- + CONFIG_OCF_HIFN $CONFIG_OCF_OCF
- +dep_tristate ' talitos (HW crypto engine)' \
- + CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
- +dep_tristate ' pasemi (HW crypto engine)' \
- + CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
- +dep_tristate ' ep80579 (HW crypto engine)' \
- + CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
- +dep_tristate ' Micronas c7108 (HW crypto engine)' \
- + CONFIG_OCF_C7108 $CONFIG_OCF_OCF
- +dep_tristate ' ocfnull (does no crypto)' \
- + CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
- +dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
- + CONFIG_OCF_BENCH $CONFIG_OCF_OCF
- +endmenu
- +
- +#############################################################################
- diff -Nur linux-2.6.36.orig/crypto/ocf/criov.c linux-2.6.36/crypto/ocf/criov.c
- --- linux-2.6.36.orig/crypto/ocf/criov.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/criov.c 2010-11-09 20:28:04.232050075 +0100
- @@ -0,0 +1,215 @@
- +/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
- +
- +/*
- + * Linux port done by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + * The license and original author are listed below.
- + *
- + * Copyright (c) 1999 Theo de Raadt
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- +__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/slab.h>
- +#include <linux/uio.h>
- +#include <linux/skbuff.h>
- +#include <linux/kernel.h>
- +#include <linux/mm.h>
- +#include <asm/io.h>
- +
- +#include <uio.h>
- +#include <cryptodev.h>
- +
- +/*
- + * This macro is only for avoiding code duplication, as we need to skip
- + * given number of bytes in the same way in three functions below.
- + */
- +#define CUIO_SKIP() do { \
- + KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
- + KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
- + while (off > 0) { \
- + KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
- + if (off < iov->iov_len) \
- + break; \
- + off -= iov->iov_len; \
- + iol--; \
- + iov++; \
- + } \
- +} while (0)
- +
- +void
- +cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
- +{
- + struct iovec *iov = uio->uio_iov;
- + int iol = uio->uio_iovcnt;
- + unsigned count;
- +
- + CUIO_SKIP();
- + while (len > 0) {
- + KASSERT(iol >= 0, ("%s: empty", __func__));
- + count = min((int)(iov->iov_len - off), len);
- + memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
- + len -= count;
- + cp += count;
- + off = 0;
- + iol--;
- + iov++;
- + }
- +}
- +
- +void
- +cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
- +{
- + struct iovec *iov = uio->uio_iov;
- + int iol = uio->uio_iovcnt;
- + unsigned count;
- +
- + CUIO_SKIP();
- + while (len > 0) {
- + KASSERT(iol >= 0, ("%s: empty", __func__));
- + count = min((int)(iov->iov_len - off), len);
- + memcpy(((caddr_t)iov->iov_base) + off, cp, count);
- + len -= count;
- + cp += count;
- + off = 0;
- + iol--;
- + iov++;
- + }
- +}
- +
- +/*
- + * Return a pointer to iov/offset of location in iovec list.
- + */
- +struct iovec *
- +cuio_getptr(struct uio *uio, int loc, int *off)
- +{
- + struct iovec *iov = uio->uio_iov;
- + int iol = uio->uio_iovcnt;
- +
- + while (loc >= 0) {
- + /* Normal end of search */
- + if (loc < iov->iov_len) {
- + *off = loc;
- + return (iov);
- + }
- +
- + loc -= iov->iov_len;
- + if (iol == 0) {
- + if (loc == 0) {
- + /* Point at the end of valid data */
- + *off = iov->iov_len;
- + return (iov);
- + } else
- + return (NULL);
- + } else {
- + iov++, iol--;
- + }
- + }
- +
- + return (NULL);
- +}
- +
- +EXPORT_SYMBOL(cuio_copyback);
- +EXPORT_SYMBOL(cuio_copydata);
- +EXPORT_SYMBOL(cuio_getptr);
- +
- +
- +static void
- +skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
- +{
- + int i;
- + if (offset < skb_headlen(skb)) {
- + memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
- + len -= skb_headlen(skb);
- + cp += skb_headlen(skb);
- + }
- + offset -= skb_headlen(skb);
- + for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
- + if (offset < skb_shinfo(skb)->frags[i].size) {
- + memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
- + skb_shinfo(skb)->frags[i].page_offset,
- + cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
- + len -= skb_shinfo(skb)->frags[i].size;
- + cp += skb_shinfo(skb)->frags[i].size;
- + }
- + offset -= skb_shinfo(skb)->frags[i].size;
- + }
- +}
- +
- +void
- +crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
- +{
- +
- + if ((flags & CRYPTO_F_SKBUF) != 0)
- + skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
- + else if ((flags & CRYPTO_F_IOV) != 0)
- + cuio_copyback((struct uio *)buf, off, size, in);
- + else
- + bcopy(in, buf + off, size);
- +}
- +
- +void
- +crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
- +{
- +
- + if ((flags & CRYPTO_F_SKBUF) != 0)
- + skb_copy_bits((struct sk_buff *)buf, off, out, size);
- + else if ((flags & CRYPTO_F_IOV) != 0)
- + cuio_copydata((struct uio *)buf, off, size, out);
- + else
- + bcopy(buf + off, out, size);
- +}
- +
- +int
- +crypto_apply(int flags, caddr_t buf, int off, int len,
- + int (*f)(void *, void *, u_int), void *arg)
- +{
- +#if 0
- + int error;
- +
- + if ((flags & CRYPTO_F_SKBUF) != 0)
- + error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
- + else if ((flags & CRYPTO_F_IOV) != 0)
- + error = cuio_apply((struct uio *)buf, off, len, f, arg);
- + else
- + error = (*f)(arg, buf + off, len);
- + return (error);
- +#else
- + KASSERT(0, ("crypto_apply not implemented!\n"));
- +#endif
- + return 0;
- +}
- +
- +EXPORT_SYMBOL(crypto_copyback);
- +EXPORT_SYMBOL(crypto_copydata);
- +EXPORT_SYMBOL(crypto_apply);
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/crypto.c linux-2.6.36/crypto/ocf/crypto.c
- --- linux-2.6.36.orig/crypto/ocf/crypto.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/crypto.c 2010-11-09 20:28:04.272495385 +0100
- @@ -0,0 +1,1784 @@
- +/*-
- + * Linux port done by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + * The license and original author are listed below.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
- + *
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +#if 0
- +#include <sys/cdefs.h>
- +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
- +#endif
- +
- +/*
- + * Cryptographic Subsystem.
- + *
- + * This code is derived from the Openbsd Cryptographic Framework (OCF)
- + * that has the copyright shown below. Very little of the original
- + * code remains.
- + */
- +/*-
- + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
- + *
- + * This code was written by Angelos D. Keromytis in Athens, Greece, in
- + * February 2000. Network Security Technologies Inc. (NSTI) kindly
- + * supported the development of this code.
- + *
- + * Copyright (c) 2000, 2001 Angelos D. Keromytis
- + *
- + * Permission to use, copy, and modify this software with or without fee
- + * is hereby granted, provided that this entire notice is included in
- + * all source code copies of any software which is or includes a copy or
- + * modification of this software.
- + *
- + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
- + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
- + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
- + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
- + * PURPOSE.
- + *
- +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
- + */
- +
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/wait.h>
- +#include <linux/sched.h>
- +#include <linux/spinlock.h>
- +#include <linux/version.h>
- +#include <cryptodev.h>
- +
- +/*
- + * keep track of whether or not we have been initialised, a big
- + * issue if we are linked into the kernel and a driver gets started before
- + * us
- + */
- +static int crypto_initted = 0;
- +
- +/*
- + * Crypto drivers register themselves by allocating a slot in the
- + * crypto_drivers table with crypto_get_driverid() and then registering
- + * each algorithm they support with crypto_register() and crypto_kregister().
- + */
- +
- +/*
- + * lock on driver table
- + * we track its state as spin_is_locked does not do anything on non-SMP boxes
- + */
- +static spinlock_t crypto_drivers_lock;
- +static int crypto_drivers_locked; /* for non-SMP boxes */
- +
- +#define CRYPTO_DRIVER_LOCK() \
- + ({ \
- + spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
- + crypto_drivers_locked = 1; \
- + dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
- + })
- +#define CRYPTO_DRIVER_UNLOCK() \
- + ({ \
- + dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
- + crypto_drivers_locked = 0; \
- + spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
- + })
- +#define CRYPTO_DRIVER_ASSERT() \
- + ({ \
- + if (!crypto_drivers_locked) { \
- + dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
- + } \
- + })
- +
- +/*
- + * Crypto device/driver capabilities structure.
- + *
- + * Synchronization:
- + * (d) - protected by CRYPTO_DRIVER_LOCK()
- + * (q) - protected by CRYPTO_Q_LOCK()
- + * Not tagged fields are read-only.
- + */
- +struct cryptocap {
- + device_t cc_dev; /* (d) device/driver */
- + u_int32_t cc_sessions; /* (d) # of sessions */
- + u_int32_t cc_koperations; /* (d) # os asym operations */
- + /*
- + * Largest possible operator length (in bits) for each type of
- + * encryption algorithm. XXX not used
- + */
- + u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
- + u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
- + u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
- +
- + int cc_flags; /* (d) flags */
- +#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
- + int cc_qblocked; /* (q) symmetric q blocked */
- + int cc_kqblocked; /* (q) asymmetric q blocked */
- +
- + int cc_unqblocked; /* (q) symmetric q blocked */
- + int cc_unkqblocked; /* (q) asymmetric q blocked */
- +};
- +static struct cryptocap *crypto_drivers = NULL;
- +static int crypto_drivers_num = 0;
- +
- +/*
- + * There are two queues for crypto requests; one for symmetric (e.g.
- + * cipher) operations and one for asymmetric (e.g. MOD)operations.
- + * A single mutex is used to lock access to both queues. We could
- + * have one per-queue but having one simplifies handling of block/unblock
- + * operations.
- + */
- +static int crp_sleep = 0;
- +static LIST_HEAD(crp_q); /* request queues */
- +static LIST_HEAD(crp_kq);
- +
- +static spinlock_t crypto_q_lock;
- +
- +int crypto_all_qblocked = 0; /* protect with Q_LOCK */
- +module_param(crypto_all_qblocked, int, 0444);
- +MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
- +
- +int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
- +module_param(crypto_all_kqblocked, int, 0444);
- +MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
- +
- +#define CRYPTO_Q_LOCK() \
- + ({ \
- + spin_lock_irqsave(&crypto_q_lock, q_flags); \
- + dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
- + })
- +#define CRYPTO_Q_UNLOCK() \
- + ({ \
- + dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
- + spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
- + })
- +
- +/*
- + * There are two queues for processing completed crypto requests; one
- + * for the symmetric and one for the asymmetric ops. We only need one
- + * but have two to avoid type futzing (cryptop vs. cryptkop). A single
- + * mutex is used to lock access to both queues. Note that this lock
- + * must be separate from the lock on request queues to insure driver
- + * callbacks don't generate lock order reversals.
- + */
- +static LIST_HEAD(crp_ret_q); /* callback queues */
- +static LIST_HEAD(crp_ret_kq);
- +
- +static spinlock_t crypto_ret_q_lock;
- +#define CRYPTO_RETQ_LOCK() \
- + ({ \
- + spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
- + dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
- + })
- +#define CRYPTO_RETQ_UNLOCK() \
- + ({ \
- + dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
- + spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
- + })
- +#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +static kmem_cache_t *cryptop_zone;
- +static kmem_cache_t *cryptodesc_zone;
- +#else
- +static struct kmem_cache *cryptop_zone;
- +static struct kmem_cache *cryptodesc_zone;
- +#endif
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
- +#include <linux/sched.h>
- +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
- +#endif
- +
- +#define debug crypto_debug
- +int crypto_debug = 0;
- +module_param(crypto_debug, int, 0644);
- +MODULE_PARM_DESC(crypto_debug, "Enable debug");
- +EXPORT_SYMBOL(crypto_debug);
- +
- +/*
- + * Maximum number of outstanding crypto requests before we start
- + * failing requests. We need this to prevent DOS when too many
- + * requests are arriving for us to keep up. Otherwise we will
- + * run the system out of memory. Since crypto is slow, we are
- + * usually the bottleneck that needs to say, enough is enough.
- + *
- + * We cannot print errors when this condition occurs, we are already too
- + * slow, printing anything will just kill us
- + */
- +
- +static int crypto_q_cnt = 0;
- +module_param(crypto_q_cnt, int, 0444);
- +MODULE_PARM_DESC(crypto_q_cnt,
- + "Current number of outstanding crypto requests");
- +
- +static int crypto_q_max = 1000;
- +module_param(crypto_q_max, int, 0644);
- +MODULE_PARM_DESC(crypto_q_max,
- + "Maximum number of outstanding crypto requests");
- +
- +#define bootverbose crypto_verbose
- +static int crypto_verbose = 0;
- +module_param(crypto_verbose, int, 0644);
- +MODULE_PARM_DESC(crypto_verbose,
- + "Enable verbose crypto startup");
- +
- +int crypto_usercrypto = 1; /* userland may do crypto reqs */
- +module_param(crypto_usercrypto, int, 0644);
- +MODULE_PARM_DESC(crypto_usercrypto,
- + "Enable/disable user-mode access to crypto support");
- +
- +int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
- +module_param(crypto_userasymcrypto, int, 0644);
- +MODULE_PARM_DESC(crypto_userasymcrypto,
- + "Enable/disable user-mode access to asymmetric crypto support");
- +
- +int crypto_devallowsoft = 0; /* only use hardware crypto */
- +module_param(crypto_devallowsoft, int, 0644);
- +MODULE_PARM_DESC(crypto_devallowsoft,
- + "Enable/disable use of software crypto support");
- +
- +/*
- + * This parameter controls the maximum number of crypto operations to
- + * do consecutively in the crypto kernel thread before scheduling to allow
- + * other processes to run. Without it, it is possible to get into a
- + * situation where the crypto thread never allows any other processes to run.
- + * Default to 1000 which should be less than one second.
- + */
- +static int crypto_max_loopcount = 1000;
- +module_param(crypto_max_loopcount, int, 0644);
- +MODULE_PARM_DESC(crypto_max_loopcount,
- + "Maximum number of crypto ops to do before yielding to other processes");
- +
- +static pid_t cryptoproc = (pid_t) -1;
- +static struct completion cryptoproc_exited;
- +static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
- +static pid_t cryptoretproc = (pid_t) -1;
- +static struct completion cryptoretproc_exited;
- +static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
- +
- +static int crypto_proc(void *arg);
- +static int crypto_ret_proc(void *arg);
- +static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
- +static int crypto_kinvoke(struct cryptkop *krp, int flags);
- +static void crypto_exit(void);
- +static int crypto_init(void);
- +
- +static struct cryptostats cryptostats;
- +
- +static struct cryptocap *
- +crypto_checkdriver(u_int32_t hid)
- +{
- + if (crypto_drivers == NULL)
- + return NULL;
- + return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
- +}
- +
- +/*
- + * Compare a driver's list of supported algorithms against another
- + * list; return non-zero if all algorithms are supported.
- + */
- +static int
- +driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
- +{
- + const struct cryptoini *cr;
- +
- + /* See if all the algorithms are supported. */
- + for (cr = cri; cr; cr = cr->cri_next)
- + if (cap->cc_alg[cr->cri_alg] == 0)
- + return 0;
- + return 1;
- +}
- +
- +/*
- + * Select a driver for a new session that supports the specified
- + * algorithms and, optionally, is constrained according to the flags.
- + * The algorithm we use here is pretty stupid; just use the
- + * first driver that supports all the algorithms we need. If there
- + * are multiple drivers we choose the driver with the fewest active
- + * sessions. We prefer hardware-backed drivers to software ones.
- + *
- + * XXX We need more smarts here (in real life too, but that's
- + * XXX another story altogether).
- + */
- +static struct cryptocap *
- +crypto_select_driver(const struct cryptoini *cri, int flags)
- +{
- + struct cryptocap *cap, *best;
- + int match, hid;
- +
- + CRYPTO_DRIVER_ASSERT();
- +
- + /*
- + * Look first for hardware crypto devices if permitted.
- + */
- + if (flags & CRYPTOCAP_F_HARDWARE)
- + match = CRYPTOCAP_F_HARDWARE;
- + else
- + match = CRYPTOCAP_F_SOFTWARE;
- + best = NULL;
- +again:
- + for (hid = 0; hid < crypto_drivers_num; hid++) {
- + cap = &crypto_drivers[hid];
- + /*
- + * If it's not initialized, is in the process of
- + * going away, or is not appropriate (hardware
- + * or software based on match), then skip.
- + */
- + if (cap->cc_dev == NULL ||
- + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
- + (cap->cc_flags & match) == 0)
- + continue;
- +
- + /* verify all the algorithms are supported. */
- + if (driver_suitable(cap, cri)) {
- + if (best == NULL ||
- + cap->cc_sessions < best->cc_sessions)
- + best = cap;
- + }
- + }
- + if (best != NULL)
- + return best;
- + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
- + /* sort of an Algol 68-style for loop */
- + match = CRYPTOCAP_F_SOFTWARE;
- + goto again;
- + }
- + return best;
- +}
- +
- +/*
- + * Create a new session. The crid argument specifies a crypto
- + * driver to use or constraints on a driver to select (hardware
- + * only, software only, either). Whatever driver is selected
- + * must be capable of the requested crypto algorithms.
- + */
- +int
- +crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
- +{
- + struct cryptocap *cap;
- + u_int32_t hid, lid;
- + int err;
- + unsigned long d_flags;
- +
- + CRYPTO_DRIVER_LOCK();
- + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
- + /*
- + * Use specified driver; verify it is capable.
- + */
- + cap = crypto_checkdriver(crid);
- + if (cap != NULL && !driver_suitable(cap, cri))
- + cap = NULL;
- + } else {
- + /*
- + * No requested driver; select based on crid flags.
- + */
- + cap = crypto_select_driver(cri, crid);
- + /*
- + * if NULL then can't do everything in one session.
- + * XXX Fix this. We need to inject a "virtual" session
- + * XXX layer right about here.
- + */
- + }
- + if (cap != NULL) {
- + /* Call the driver initialization routine. */
- + hid = cap - crypto_drivers;
- + lid = hid; /* Pass the driver ID. */
- + cap->cc_sessions++;
- + CRYPTO_DRIVER_UNLOCK();
- + err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
- + CRYPTO_DRIVER_LOCK();
- + if (err == 0) {
- + (*sid) = (cap->cc_flags & 0xff000000)
- + | (hid & 0x00ffffff);
- + (*sid) <<= 32;
- + (*sid) |= (lid & 0xffffffff);
- + } else
- + cap->cc_sessions--;
- + } else
- + err = EINVAL;
- + CRYPTO_DRIVER_UNLOCK();
- + return err;
- +}
- +
- +static void
- +crypto_remove(struct cryptocap *cap)
- +{
- + CRYPTO_DRIVER_ASSERT();
- + if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
- + bzero(cap, sizeof(*cap));
- +}
- +
- +/*
- + * Delete an existing session (or a reserved session on an unregistered
- + * driver).
- + */
- +int
- +crypto_freesession(u_int64_t sid)
- +{
- + struct cryptocap *cap;
- + u_int32_t hid;
- + int err = 0;
- + unsigned long d_flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + CRYPTO_DRIVER_LOCK();
- +
- + if (crypto_drivers == NULL) {
- + err = EINVAL;
- + goto done;
- + }
- +
- + /* Determine two IDs. */
- + hid = CRYPTO_SESID2HID(sid);
- +
- + if (hid >= crypto_drivers_num) {
- + dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
- + err = ENOENT;
- + goto done;
- + }
- + cap = &crypto_drivers[hid];
- +
- + if (cap->cc_dev) {
- + CRYPTO_DRIVER_UNLOCK();
- + /* Call the driver cleanup routine, if available, unlocked. */
- + err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
- + CRYPTO_DRIVER_LOCK();
- + }
- +
- + if (cap->cc_sessions)
- + cap->cc_sessions--;
- +
- + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
- + crypto_remove(cap);
- +
- +done:
- + CRYPTO_DRIVER_UNLOCK();
- + return err;
- +}
- +
- +/*
- + * Return an unused driver id. Used by drivers prior to registering
- + * support for the algorithms they handle.
- + */
- +int32_t
- +crypto_get_driverid(device_t dev, int flags)
- +{
- + struct cryptocap *newdrv;
- + int i;
- + unsigned long d_flags;
- +
- + if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
- + printf("%s: no flags specified when registering driver\n",
- + device_get_nameunit(dev));
- + return -1;
- + }
- +
- + CRYPTO_DRIVER_LOCK();
- +
- + for (i = 0; i < crypto_drivers_num; i++) {
- + if (crypto_drivers[i].cc_dev == NULL &&
- + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
- + break;
- + }
- + }
- +
- + /* Out of entries, allocate some more. */
- + if (i == crypto_drivers_num) {
- + /* Be careful about wrap-around. */
- + if (2 * crypto_drivers_num <= crypto_drivers_num) {
- + CRYPTO_DRIVER_UNLOCK();
- + printk("crypto: driver count wraparound!\n");
- + return -1;
- + }
- +
- + newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
- + GFP_KERNEL);
- + if (newdrv == NULL) {
- + CRYPTO_DRIVER_UNLOCK();
- + printk("crypto: no space to expand driver table!\n");
- + return -1;
- + }
- +
- + memcpy(newdrv, crypto_drivers,
- + crypto_drivers_num * sizeof(struct cryptocap));
- + memset(&newdrv[crypto_drivers_num], 0,
- + crypto_drivers_num * sizeof(struct cryptocap));
- +
- + crypto_drivers_num *= 2;
- +
- + kfree(crypto_drivers);
- + crypto_drivers = newdrv;
- + }
- +
- + /* NB: state is zero'd on free */
- + crypto_drivers[i].cc_sessions = 1; /* Mark */
- + crypto_drivers[i].cc_dev = dev;
- + crypto_drivers[i].cc_flags = flags;
- + if (bootverbose)
- + printf("crypto: assign %s driver id %u, flags %u\n",
- + device_get_nameunit(dev), i, flags);
- +
- + CRYPTO_DRIVER_UNLOCK();
- +
- + return i;
- +}
- +
- +/*
- + * Lookup a driver by name. We match against the full device
- + * name and unit, and against just the name. The latter gives
- + * us a simple widlcarding by device name. On success return the
- + * driver/hardware identifier; otherwise return -1.
- + */
- +int
- +crypto_find_driver(const char *match)
- +{
- + int i, len = strlen(match);
- + unsigned long d_flags;
- +
- + CRYPTO_DRIVER_LOCK();
- + for (i = 0; i < crypto_drivers_num; i++) {
- + device_t dev = crypto_drivers[i].cc_dev;
- + if (dev == NULL ||
- + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
- + continue;
- + if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
- + strncmp(match, device_get_name(dev), len) == 0)
- + break;
- + }
- + CRYPTO_DRIVER_UNLOCK();
- + return i < crypto_drivers_num ? i : -1;
- +}
- +
- +/*
- + * Return the device_t for the specified driver or NULL
- + * if the driver identifier is invalid.
- + */
- +device_t
- +crypto_find_device_byhid(int hid)
- +{
- + struct cryptocap *cap = crypto_checkdriver(hid);
- + return cap != NULL ? cap->cc_dev : NULL;
- +}
- +
- +/*
- + * Return the device/driver capabilities.
- + */
- +int
- +crypto_getcaps(int hid)
- +{
- + struct cryptocap *cap = crypto_checkdriver(hid);
- + return cap != NULL ? cap->cc_flags : 0;
- +}
- +
- +/*
- + * Register support for a key-related algorithm. This routine
- + * is called once for each algorithm supported a driver.
- + */
- +int
- +crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
- +{
- + struct cryptocap *cap;
- + int err;
- + unsigned long d_flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + CRYPTO_DRIVER_LOCK();
- +
- + cap = crypto_checkdriver(driverid);
- + if (cap != NULL &&
- + (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
- + /*
- + * XXX Do some performance testing to determine placing.
- + * XXX We probably need an auxiliary data structure that
- + * XXX describes relative performances.
- + */
- +
- + cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
- + if (bootverbose)
- + printf("crypto: %s registers key alg %u flags %u\n"
- + , device_get_nameunit(cap->cc_dev)
- + , kalg
- + , flags
- + );
- + err = 0;
- + } else
- + err = EINVAL;
- +
- + CRYPTO_DRIVER_UNLOCK();
- + return err;
- +}
- +
- +/*
- + * Register support for a non-key-related algorithm. This routine
- + * is called once for each such algorithm supported by a driver.
- + */
- +int
- +crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
- + u_int32_t flags)
- +{
- + struct cryptocap *cap;
- + int err;
- + unsigned long d_flags;
- +
- + dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
- + driverid, alg, maxoplen, flags);
- +
- + CRYPTO_DRIVER_LOCK();
- +
- + cap = crypto_checkdriver(driverid);
- + /* NB: algorithms are in the range [1..max] */
- + if (cap != NULL &&
- + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
- + /*
- + * XXX Do some performance testing to determine placing.
- + * XXX We probably need an auxiliary data structure that
- + * XXX describes relative performances.
- + */
- +
- + cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
- + cap->cc_max_op_len[alg] = maxoplen;
- + if (bootverbose)
- + printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
- + , device_get_nameunit(cap->cc_dev)
- + , alg
- + , flags
- + , maxoplen
- + );
- + cap->cc_sessions = 0; /* Unmark */
- + err = 0;
- + } else
- + err = EINVAL;
- +
- + CRYPTO_DRIVER_UNLOCK();
- + return err;
- +}
- +
- +static void
- +driver_finis(struct cryptocap *cap)
- +{
- + u_int32_t ses, kops;
- +
- + CRYPTO_DRIVER_ASSERT();
- +
- + ses = cap->cc_sessions;
- + kops = cap->cc_koperations;
- + bzero(cap, sizeof(*cap));
- + if (ses != 0 || kops != 0) {
- + /*
- + * If there are pending sessions,
- + * just mark as invalid.
- + */
- + cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
- + cap->cc_sessions = ses;
- + cap->cc_koperations = kops;
- + }
- +}
- +
- +/*
- + * Unregister a crypto driver. If there are pending sessions using it,
- + * leave enough information around so that subsequent calls using those
- + * sessions will correctly detect the driver has been unregistered and
- + * reroute requests.
- + */
- +int
- +crypto_unregister(u_int32_t driverid, int alg)
- +{
- + struct cryptocap *cap;
- + int i, err;
- + unsigned long d_flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + CRYPTO_DRIVER_LOCK();
- +
- + cap = crypto_checkdriver(driverid);
- + if (cap != NULL &&
- + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
- + cap->cc_alg[alg] != 0) {
- + cap->cc_alg[alg] = 0;
- + cap->cc_max_op_len[alg] = 0;
- +
- + /* Was this the last algorithm ? */
- + for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
- + if (cap->cc_alg[i] != 0)
- + break;
- +
- + if (i == CRYPTO_ALGORITHM_MAX + 1)
- + driver_finis(cap);
- + err = 0;
- + } else
- + err = EINVAL;
- + CRYPTO_DRIVER_UNLOCK();
- + return err;
- +}
- +
- +/*
- + * Unregister all algorithms associated with a crypto driver.
- + * If there are pending sessions using it, leave enough information
- + * around so that subsequent calls using those sessions will
- + * correctly detect the driver has been unregistered and reroute
- + * requests.
- + */
- +int
- +crypto_unregister_all(u_int32_t driverid)
- +{
- + struct cryptocap *cap;
- + int err;
- + unsigned long d_flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + CRYPTO_DRIVER_LOCK();
- + cap = crypto_checkdriver(driverid);
- + if (cap != NULL) {
- + driver_finis(cap);
- + err = 0;
- + } else
- + err = EINVAL;
- + CRYPTO_DRIVER_UNLOCK();
- +
- + return err;
- +}
- +
- +/*
- + * Clear blockage on a driver. The what parameter indicates whether
- + * the driver is now ready for cryptop's and/or cryptokop's.
- + */
- +int
- +crypto_unblock(u_int32_t driverid, int what)
- +{
- + struct cryptocap *cap;
- + int err;
- + unsigned long q_flags;
- +
- + CRYPTO_Q_LOCK();
- + cap = crypto_checkdriver(driverid);
- + if (cap != NULL) {
- + if (what & CRYPTO_SYMQ) {
- + cap->cc_qblocked = 0;
- + cap->cc_unqblocked = 0;
- + crypto_all_qblocked = 0;
- + }
- + if (what & CRYPTO_ASYMQ) {
- + cap->cc_kqblocked = 0;
- + cap->cc_unkqblocked = 0;
- + crypto_all_kqblocked = 0;
- + }
- + if (crp_sleep)
- + wake_up_interruptible(&cryptoproc_wait);
- + err = 0;
- + } else
- + err = EINVAL;
- + CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
- +
- + return err;
- +}
- +
- +/*
- + * Add a crypto request to a queue, to be processed by the kernel thread.
- + */
- +int
- +crypto_dispatch(struct cryptop *crp)
- +{
- + struct cryptocap *cap;
- + int result = -1;
- + unsigned long q_flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + cryptostats.cs_ops++;
- +
- + CRYPTO_Q_LOCK();
- + if (crypto_q_cnt >= crypto_q_max) {
- + CRYPTO_Q_UNLOCK();
- + cryptostats.cs_drops++;
- + return ENOMEM;
- + }
- + crypto_q_cnt++;
- +
- + /* make sure we are starting a fresh run on this crp. */
- + crp->crp_flags &= ~CRYPTO_F_DONE;
- + crp->crp_etype = 0;
- +
- + /*
- + * Caller marked the request to be processed immediately; dispatch
- + * it directly to the driver unless the driver is currently blocked.
- + */
- + if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
- + int hid = CRYPTO_SESID2HID(crp->crp_sid);
- + cap = crypto_checkdriver(hid);
- + /* Driver cannot disappear when there is an active session. */
- + KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
- + if (!cap->cc_qblocked) {
- + crypto_all_qblocked = 0;
- + crypto_drivers[hid].cc_unqblocked = 1;
- + CRYPTO_Q_UNLOCK();
- + result = crypto_invoke(cap, crp, 0);
- + CRYPTO_Q_LOCK();
- + if (result == ERESTART)
- + if (crypto_drivers[hid].cc_unqblocked)
- + crypto_drivers[hid].cc_qblocked = 1;
- + crypto_drivers[hid].cc_unqblocked = 0;
- + }
- + }
- + if (result == ERESTART) {
- + /*
- + * The driver ran out of resources, mark the
- + * driver ``blocked'' for cryptop's and put
- + * the request back in the queue. It would
- + * best to put the request back where we got
- + * it but that's hard so for now we put it
- + * at the front. This should be ok; putting
- + * it at the end does not work.
- + */
- + list_add(&crp->crp_next, &crp_q);
- + cryptostats.cs_blocks++;
- + result = 0;
- + } else if (result == -1) {
- + TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
- + result = 0;
- + }
- + if (crp_sleep)
- + wake_up_interruptible(&cryptoproc_wait);
- + CRYPTO_Q_UNLOCK();
- + return result;
- +}
- +
- +/*
- + * Add an asymetric crypto request to a queue,
- + * to be processed by the kernel thread.
- + */
- +int
- +crypto_kdispatch(struct cryptkop *krp)
- +{
- + int error;
- + unsigned long q_flags;
- +
- + cryptostats.cs_kops++;
- +
- + error = crypto_kinvoke(krp, krp->krp_crid);
- + if (error == ERESTART) {
- + CRYPTO_Q_LOCK();
- + TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
- + if (crp_sleep)
- + wake_up_interruptible(&cryptoproc_wait);
- + CRYPTO_Q_UNLOCK();
- + error = 0;
- + }
- + return error;
- +}
- +
- +/*
- + * Verify a driver is suitable for the specified operation.
- + */
- +static __inline int
- +kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
- +{
- + return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
- +}
- +
- +/*
- + * Select a driver for an asym operation. The driver must
- + * support the necessary algorithm. The caller can constrain
- + * which device is selected with the flags parameter. The
- + * algorithm we use here is pretty stupid; just use the first
- + * driver that supports the algorithms we need. If there are
- + * multiple suitable drivers we choose the driver with the
- + * fewest active operations. We prefer hardware-backed
- + * drivers to software ones when either may be used.
- + */
- +static struct cryptocap *
- +crypto_select_kdriver(const struct cryptkop *krp, int flags)
- +{
- + struct cryptocap *cap, *best, *blocked;
- + int match, hid;
- +
- + CRYPTO_DRIVER_ASSERT();
- +
- + /*
- + * Look first for hardware crypto devices if permitted.
- + */
- + if (flags & CRYPTOCAP_F_HARDWARE)
- + match = CRYPTOCAP_F_HARDWARE;
- + else
- + match = CRYPTOCAP_F_SOFTWARE;
- + best = NULL;
- + blocked = NULL;
- +again:
- + for (hid = 0; hid < crypto_drivers_num; hid++) {
- + cap = &crypto_drivers[hid];
- + /*
- + * If it's not initialized, is in the process of
- + * going away, or is not appropriate (hardware
- + * or software based on match), then skip.
- + */
- + if (cap->cc_dev == NULL ||
- + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
- + (cap->cc_flags & match) == 0)
- + continue;
- +
- + /* verify all the algorithms are supported. */
- + if (kdriver_suitable(cap, krp)) {
- + if (best == NULL ||
- + cap->cc_koperations < best->cc_koperations)
- + best = cap;
- + }
- + }
- + if (best != NULL)
- + return best;
- + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
- + /* sort of an Algol 68-style for loop */
- + match = CRYPTOCAP_F_SOFTWARE;
- + goto again;
- + }
- + return best;
- +}
- +
- +/*
- + * Dispatch an assymetric crypto request.
- + */
- +static int
- +crypto_kinvoke(struct cryptkop *krp, int crid)
- +{
- + struct cryptocap *cap = NULL;
- + int error;
- + unsigned long d_flags;
- +
- + KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
- + KASSERT(krp->krp_callback != NULL,
- + ("%s: krp->crp_callback == NULL", __func__));
- +
- + CRYPTO_DRIVER_LOCK();
- + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
- + cap = crypto_checkdriver(crid);
- + if (cap != NULL) {
- + /*
- + * Driver present, it must support the necessary
- + * algorithm and, if s/w drivers are excluded,
- + * it must be registered as hardware-backed.
- + */
- + if (!kdriver_suitable(cap, krp) ||
- + (!crypto_devallowsoft &&
- + (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
- + cap = NULL;
- + }
- + } else {
- + /*
- + * No requested driver; select based on crid flags.
- + */
- + if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
- + crid &= ~CRYPTOCAP_F_SOFTWARE;
- + cap = crypto_select_kdriver(krp, crid);
- + }
- + if (cap != NULL && !cap->cc_kqblocked) {
- + krp->krp_hid = cap - crypto_drivers;
- + cap->cc_koperations++;
- + CRYPTO_DRIVER_UNLOCK();
- + error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
- + CRYPTO_DRIVER_LOCK();
- + if (error == ERESTART) {
- + cap->cc_koperations--;
- + CRYPTO_DRIVER_UNLOCK();
- + return (error);
- + }
- + /* return the actual device used */
- + krp->krp_crid = krp->krp_hid;
- + } else {
- + /*
- + * NB: cap is !NULL if device is blocked; in
- + * that case return ERESTART so the operation
- + * is resubmitted if possible.
- + */
- + error = (cap == NULL) ? ENODEV : ERESTART;
- + }
- + CRYPTO_DRIVER_UNLOCK();
- +
- + if (error) {
- + krp->krp_status = error;
- + crypto_kdone(krp);
- + }
- + return 0;
- +}
- +
- +
- +/*
- + * Dispatch a crypto request to the appropriate crypto devices.
- + */
- +static int
- +crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
- +{
- + KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
- + KASSERT(crp->crp_callback != NULL,
- + ("%s: crp->crp_callback == NULL", __func__));
- + KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- +#ifdef CRYPTO_TIMING
- + if (crypto_timing)
- + crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
- +#endif
- + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
- + struct cryptodesc *crd;
- + u_int64_t nid;
- +
- + /*
- + * Driver has unregistered; migrate the session and return
- + * an error to the caller so they'll resubmit the op.
- + *
- + * XXX: What if there are more already queued requests for this
- + * session?
- + */
- + crypto_freesession(crp->crp_sid);
- +
- + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
- + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
- +
- + /* XXX propagate flags from initial session? */
- + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
- + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
- + crp->crp_sid = nid;
- +
- + crp->crp_etype = EAGAIN;
- + crypto_done(crp);
- + return 0;
- + } else {
- + /*
- + * Invoke the driver to process the request.
- + */
- + return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
- + }
- +}
- +
- +/*
- + * Release a set of crypto descriptors.
- + */
- +void
- +crypto_freereq(struct cryptop *crp)
- +{
- + struct cryptodesc *crd;
- +
- + if (crp == NULL)
- + return;
- +
- +#ifdef DIAGNOSTIC
- + {
- + struct cryptop *crp2;
- + unsigned long q_flags;
- +
- + CRYPTO_Q_LOCK();
- + TAILQ_FOREACH(crp2, &crp_q, crp_next) {
- + KASSERT(crp2 != crp,
- + ("Freeing cryptop from the crypto queue (%p).",
- + crp));
- + }
- + CRYPTO_Q_UNLOCK();
- + CRYPTO_RETQ_LOCK();
- + TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
- + KASSERT(crp2 != crp,
- + ("Freeing cryptop from the return queue (%p).",
- + crp));
- + }
- + CRYPTO_RETQ_UNLOCK();
- + }
- +#endif
- +
- + while ((crd = crp->crp_desc) != NULL) {
- + crp->crp_desc = crd->crd_next;
- + kmem_cache_free(cryptodesc_zone, crd);
- + }
- + kmem_cache_free(cryptop_zone, crp);
- +}
- +
- +/*
- + * Acquire a set of crypto descriptors.
- + */
- +struct cryptop *
- +crypto_getreq(int num)
- +{
- + struct cryptodesc *crd;
- + struct cryptop *crp;
- +
- + crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
- + if (crp != NULL) {
- + memset(crp, 0, sizeof(*crp));
- + INIT_LIST_HEAD(&crp->crp_next);
- + init_waitqueue_head(&crp->crp_waitq);
- + while (num--) {
- + crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
- + if (crd == NULL) {
- + crypto_freereq(crp);
- + return NULL;
- + }
- + memset(crd, 0, sizeof(*crd));
- + crd->crd_next = crp->crp_desc;
- + crp->crp_desc = crd;
- + }
- + }
- + return crp;
- +}
- +
- +/*
- + * Invoke the callback on behalf of the driver.
- + */
- +void
- +crypto_done(struct cryptop *crp)
- +{
- + unsigned long q_flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
- + crp->crp_flags |= CRYPTO_F_DONE;
- + CRYPTO_Q_LOCK();
- + crypto_q_cnt--;
- + CRYPTO_Q_UNLOCK();
- + } else
- + printk("crypto: crypto_done op already done, flags 0x%x",
- + crp->crp_flags);
- + if (crp->crp_etype != 0)
- + cryptostats.cs_errs++;
- + /*
- + * CBIMM means unconditionally do the callback immediately;
- + * CBIFSYNC means do the callback immediately only if the
- + * operation was done synchronously. Both are used to avoid
- + * doing extraneous context switches; the latter is mostly
- + * used with the software crypto driver.
- + */
- + if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
- + ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
- + (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
- + /*
- + * Do the callback directly. This is ok when the
- + * callback routine does very little (e.g. the
- + * /dev/crypto callback method just does a wakeup).
- + */
- + crp->crp_callback(crp);
- + } else {
- + unsigned long r_flags;
- + /*
- + * Normal case; queue the callback for the thread.
- + */
- + CRYPTO_RETQ_LOCK();
- + if (CRYPTO_RETQ_EMPTY())
- + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
- + TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
- + CRYPTO_RETQ_UNLOCK();
- + }
- +}
- +
- +/*
- + * Invoke the callback on behalf of the driver.
- + */
- +void
- +crypto_kdone(struct cryptkop *krp)
- +{
- + struct cryptocap *cap;
- + unsigned long d_flags;
- +
- + if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
- + printk("crypto: crypto_kdone op already done, flags 0x%x",
- + krp->krp_flags);
- + krp->krp_flags |= CRYPTO_KF_DONE;
- + if (krp->krp_status != 0)
- + cryptostats.cs_kerrs++;
- +
- + CRYPTO_DRIVER_LOCK();
- + /* XXX: What if driver is loaded in the meantime? */
- + if (krp->krp_hid < crypto_drivers_num) {
- + cap = &crypto_drivers[krp->krp_hid];
- + cap->cc_koperations--;
- + KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
- + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
- + crypto_remove(cap);
- + }
- + CRYPTO_DRIVER_UNLOCK();
- +
- + /*
- + * CBIMM means unconditionally do the callback immediately;
- + * This is used to avoid doing extraneous context switches
- + */
- + if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
- + /*
- + * Do the callback directly. This is ok when the
- + * callback routine does very little (e.g. the
- + * /dev/crypto callback method just does a wakeup).
- + */
- + krp->krp_callback(krp);
- + } else {
- + unsigned long r_flags;
- + /*
- + * Normal case; queue the callback for the thread.
- + */
- + CRYPTO_RETQ_LOCK();
- + if (CRYPTO_RETQ_EMPTY())
- + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
- + TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
- + CRYPTO_RETQ_UNLOCK();
- + }
- +}
- +
- +int
- +crypto_getfeat(int *featp)
- +{
- + int hid, kalg, feat = 0;
- + unsigned long d_flags;
- +
- + CRYPTO_DRIVER_LOCK();
- + for (hid = 0; hid < crypto_drivers_num; hid++) {
- + const struct cryptocap *cap = &crypto_drivers[hid];
- +
- + if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
- + !crypto_devallowsoft) {
- + continue;
- + }
- + for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
- + if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
- + feat |= 1 << kalg;
- + }
- + CRYPTO_DRIVER_UNLOCK();
- + *featp = feat;
- + return (0);
- +}
- +
- +/*
- + * Crypto thread, dispatches crypto requests.
- + */
- +static int
- +crypto_proc(void *arg)
- +{
- + struct cryptop *crp, *submit;
- + struct cryptkop *krp, *krpp;
- + struct cryptocap *cap;
- + u_int32_t hid;
- + int result, hint;
- + unsigned long q_flags;
- + int loopcount = 0;
- +
- + ocf_daemonize("crypto");
- +
- + CRYPTO_Q_LOCK();
- + for (;;) {
- + /*
- + * we need to make sure we don't get into a busy loop with nothing
- + * to do, the two crypto_all_*blocked vars help us find out when
- + * we are all full and can do nothing on any driver or Q. If so we
- + * wait for an unblock.
- + */
- + crypto_all_qblocked = !list_empty(&crp_q);
- +
- + /*
- + * Find the first element in the queue that can be
- + * processed and look-ahead to see if multiple ops
- + * are ready for the same driver.
- + */
- + submit = NULL;
- + hint = 0;
- + list_for_each_entry(crp, &crp_q, crp_next) {
- + hid = CRYPTO_SESID2HID(crp->crp_sid);
- + cap = crypto_checkdriver(hid);
- + /*
- + * Driver cannot disappear when there is an active
- + * session.
- + */
- + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
- + __func__, __LINE__));
- + if (cap == NULL || cap->cc_dev == NULL) {
- + /* Op needs to be migrated, process it. */
- + if (submit == NULL)
- + submit = crp;
- + break;
- + }
- + if (!cap->cc_qblocked) {
- + if (submit != NULL) {
- + /*
- + * We stop on finding another op,
- + * regardless whether its for the same
- + * driver or not. We could keep
- + * searching the queue but it might be
- + * better to just use a per-driver
- + * queue instead.
- + */
- + if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
- + hint = CRYPTO_HINT_MORE;
- + break;
- + } else {
- + submit = crp;
- + if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
- + break;
- + /* keep scanning for more are q'd */
- + }
- + }
- + }
- + if (submit != NULL) {
- + hid = CRYPTO_SESID2HID(submit->crp_sid);
- + crypto_all_qblocked = 0;
- + list_del(&submit->crp_next);
- + crypto_drivers[hid].cc_unqblocked = 1;
- + cap = crypto_checkdriver(hid);
- + CRYPTO_Q_UNLOCK();
- + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
- + __func__, __LINE__));
- + result = crypto_invoke(cap, submit, hint);
- + CRYPTO_Q_LOCK();
- + if (result == ERESTART) {
- + /*
- + * The driver ran out of resources, mark the
- + * driver ``blocked'' for cryptop's and put
- + * the request back in the queue. It would
- + * best to put the request back where we got
- + * it but that's hard so for now we put it
- + * at the front. This should be ok; putting
- + * it at the end does not work.
- + */
- + /* XXX validate sid again? */
- + list_add(&submit->crp_next, &crp_q);
- + cryptostats.cs_blocks++;
- + if (crypto_drivers[hid].cc_unqblocked)
- + crypto_drivers[hid].cc_qblocked=0;
- + crypto_drivers[hid].cc_unqblocked=0;
- + }
- + crypto_drivers[hid].cc_unqblocked = 0;
- + }
- +
- + crypto_all_kqblocked = !list_empty(&crp_kq);
- +
- + /* As above, but for key ops */
- + krp = NULL;
- + list_for_each_entry(krpp, &crp_kq, krp_next) {
- + cap = crypto_checkdriver(krpp->krp_hid);
- + if (cap == NULL || cap->cc_dev == NULL) {
- + /*
- + * Operation needs to be migrated, invalidate
- + * the assigned device so it will reselect a
- + * new one below. Propagate the original
- + * crid selection flags if supplied.
- + */
- + krp->krp_hid = krp->krp_crid &
- + (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
- + if (krp->krp_hid == 0)
- + krp->krp_hid =
- + CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
- + break;
- + }
- + if (!cap->cc_kqblocked) {
- + krp = krpp;
- + break;
- + }
- + }
- + if (krp != NULL) {
- + crypto_all_kqblocked = 0;
- + list_del(&krp->krp_next);
- + crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
- + CRYPTO_Q_UNLOCK();
- + result = crypto_kinvoke(krp, krp->krp_hid);
- + CRYPTO_Q_LOCK();
- + if (result == ERESTART) {
- + /*
- + * The driver ran out of resources, mark the
- + * driver ``blocked'' for cryptkop's and put
- + * the request back in the queue. It would
- + * best to put the request back where we got
- + * it but that's hard so for now we put it
- + * at the front. This should be ok; putting
- + * it at the end does not work.
- + */
- + /* XXX validate sid again? */
- + list_add(&krp->krp_next, &crp_kq);
- + cryptostats.cs_kblocks++;
- + } else
- + crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
- + }
- +
- + if (submit == NULL && krp == NULL) {
- + /*
- + * Nothing more to be processed. Sleep until we're
- + * woken because there are more ops to process.
- + * This happens either by submission or by a driver
- + * becoming unblocked and notifying us through
- + * crypto_unblock. Note that when we wakeup we
- + * start processing each queue again from the
- + * front. It's not clear that it's important to
- + * preserve this ordering since ops may finish
- + * out of order if dispatched to different devices
- + * and some become blocked while others do not.
- + */
- + dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
- + __FUNCTION__,
- + list_empty(&crp_q), crypto_all_qblocked,
- + list_empty(&crp_kq), crypto_all_kqblocked);
- + loopcount = 0;
- + CRYPTO_Q_UNLOCK();
- + crp_sleep = 1;
- + wait_event_interruptible(cryptoproc_wait,
- + !(list_empty(&crp_q) || crypto_all_qblocked) ||
- + !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
- + cryptoproc == (pid_t) -1);
- + crp_sleep = 0;
- + if (signal_pending (current)) {
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- + spin_lock_irq(¤t->sigmask_lock);
- +#endif
- + flush_signals(current);
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- + spin_unlock_irq(¤t->sigmask_lock);
- +#endif
- + }
- + CRYPTO_Q_LOCK();
- + dprintk("%s - awake\n", __FUNCTION__);
- + if (cryptoproc == (pid_t) -1)
- + break;
- + cryptostats.cs_intrs++;
- + } else if (loopcount > crypto_max_loopcount) {
- + /*
- + * Give other processes a chance to run if we've
- + * been using the CPU exclusively for a while.
- + */
- + loopcount = 0;
- + schedule();
- + }
- + loopcount++;
- + }
- + CRYPTO_Q_UNLOCK();
- + complete_and_exit(&cryptoproc_exited, 0);
- +}
- +
- +/*
- + * Crypto returns thread, does callbacks for processed crypto requests.
- + * Callbacks are done here, rather than in the crypto drivers, because
- + * callbacks typically are expensive and would slow interrupt handling.
- + */
- +static int
- +crypto_ret_proc(void *arg)
- +{
- + struct cryptop *crpt;
- + struct cryptkop *krpt;
- + unsigned long r_flags;
- +
- + ocf_daemonize("crypto_ret");
- +
- + CRYPTO_RETQ_LOCK();
- + for (;;) {
- + /* Harvest return q's for completed ops */
- + crpt = NULL;
- + if (!list_empty(&crp_ret_q))
- + crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
- + if (crpt != NULL)
- + list_del(&crpt->crp_next);
- +
- + krpt = NULL;
- + if (!list_empty(&crp_ret_kq))
- + krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
- + if (krpt != NULL)
- + list_del(&krpt->krp_next);
- +
- + if (crpt != NULL || krpt != NULL) {
- + CRYPTO_RETQ_UNLOCK();
- + /*
- + * Run callbacks unlocked.
- + */
- + if (crpt != NULL)
- + crpt->crp_callback(crpt);
- + if (krpt != NULL)
- + krpt->krp_callback(krpt);
- + CRYPTO_RETQ_LOCK();
- + } else {
- + /*
- + * Nothing more to be processed. Sleep until we're
- + * woken because there are more returns to process.
- + */
- + dprintk("%s - sleeping\n", __FUNCTION__);
- + CRYPTO_RETQ_UNLOCK();
- + wait_event_interruptible(cryptoretproc_wait,
- + cryptoretproc == (pid_t) -1 ||
- + !list_empty(&crp_ret_q) ||
- + !list_empty(&crp_ret_kq));
- + if (signal_pending (current)) {
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- + spin_lock_irq(¤t->sigmask_lock);
- +#endif
- + flush_signals(current);
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- + spin_unlock_irq(¤t->sigmask_lock);
- +#endif
- + }
- + CRYPTO_RETQ_LOCK();
- + dprintk("%s - awake\n", __FUNCTION__);
- + if (cryptoretproc == (pid_t) -1) {
- + dprintk("%s - EXITING!\n", __FUNCTION__);
- + break;
- + }
- + cryptostats.cs_rets++;
- + }
- + }
- + CRYPTO_RETQ_UNLOCK();
- + complete_and_exit(&cryptoretproc_exited, 0);
- +}
- +
- +
- +#if 0 /* should put this into /proc or something */
- +static void
- +db_show_drivers(void)
- +{
- + int hid;
- +
- + db_printf("%12s %4s %4s %8s %2s %2s\n"
- + , "Device"
- + , "Ses"
- + , "Kops"
- + , "Flags"
- + , "QB"
- + , "KB"
- + );
- + for (hid = 0; hid < crypto_drivers_num; hid++) {
- + const struct cryptocap *cap = &crypto_drivers[hid];
- + if (cap->cc_dev == NULL)
- + continue;
- + db_printf("%-12s %4u %4u %08x %2u %2u\n"
- + , device_get_nameunit(cap->cc_dev)
- + , cap->cc_sessions
- + , cap->cc_koperations
- + , cap->cc_flags
- + , cap->cc_qblocked
- + , cap->cc_kqblocked
- + );
- + }
- +}
- +
- +DB_SHOW_COMMAND(crypto, db_show_crypto)
- +{
- + struct cryptop *crp;
- +
- + db_show_drivers();
- + db_printf("\n");
- +
- + db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
- + "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
- + "Desc", "Callback");
- + TAILQ_FOREACH(crp, &crp_q, crp_next) {
- + db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
- + , (int) CRYPTO_SESID2HID(crp->crp_sid)
- + , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
- + , crp->crp_ilen, crp->crp_olen
- + , crp->crp_etype
- + , crp->crp_flags
- + , crp->crp_desc
- + , crp->crp_callback
- + );
- + }
- + if (!TAILQ_EMPTY(&crp_ret_q)) {
- + db_printf("\n%4s %4s %4s %8s\n",
- + "HID", "Etype", "Flags", "Callback");
- + TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
- + db_printf("%4u %4u %04x %8p\n"
- + , (int) CRYPTO_SESID2HID(crp->crp_sid)
- + , crp->crp_etype
- + , crp->crp_flags
- + , crp->crp_callback
- + );
- + }
- + }
- +}
- +
- +DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
- +{
- + struct cryptkop *krp;
- +
- + db_show_drivers();
- + db_printf("\n");
- +
- + db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
- + "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
- + TAILQ_FOREACH(krp, &crp_kq, krp_next) {
- + db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
- + , krp->krp_op
- + , krp->krp_status
- + , krp->krp_iparams, krp->krp_oparams
- + , krp->krp_crid, krp->krp_hid
- + , krp->krp_callback
- + );
- + }
- + if (!TAILQ_EMPTY(&crp_ret_q)) {
- + db_printf("%4s %5s %8s %4s %8s\n",
- + "Op", "Status", "CRID", "HID", "Callback");
- + TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
- + db_printf("%4u %5u %08x %4u %8p\n"
- + , krp->krp_op
- + , krp->krp_status
- + , krp->krp_crid, krp->krp_hid
- + , krp->krp_callback
- + );
- + }
- + }
- +}
- +#endif
- +
- +
- +static int
- +crypto_init(void)
- +{
- + int error;
- +
- + dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
- +
- + if (crypto_initted)
- + return 0;
- + crypto_initted = 1;
- +
- + spin_lock_init(&crypto_drivers_lock);
- + spin_lock_init(&crypto_q_lock);
- + spin_lock_init(&crypto_ret_q_lock);
- +
- + cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
- + 0, SLAB_HWCACHE_ALIGN, NULL
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
- + , NULL
- +#endif
- + );
- +
- + cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
- + 0, SLAB_HWCACHE_ALIGN, NULL
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
- + , NULL
- +#endif
- + );
- +
- + if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
- + printk("crypto: crypto_init cannot setup crypto zones\n");
- + error = ENOMEM;
- + goto bad;
- + }
- +
- + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
- + crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
- + GFP_KERNEL);
- + if (crypto_drivers == NULL) {
- + printk("crypto: crypto_init cannot setup crypto drivers\n");
- + error = ENOMEM;
- + goto bad;
- + }
- +
- + memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
- +
- + init_completion(&cryptoproc_exited);
- + init_completion(&cryptoretproc_exited);
- +
- + cryptoproc = 0; /* to avoid race condition where proc runs first */
- + cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
- + if (cryptoproc < 0) {
- + error = cryptoproc;
- + printk("crypto: crypto_init cannot start crypto thread; error %d",
- + error);
- + goto bad;
- + }
- +
- + cryptoretproc = 0; /* to avoid race condition where proc runs first */
- + cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
- + if (cryptoretproc < 0) {
- + error = cryptoretproc;
- + printk("crypto: crypto_init cannot start cryptoret thread; error %d",
- + error);
- + goto bad;
- + }
- +
- + return 0;
- +bad:
- + crypto_exit();
- + return error;
- +}
- +
- +
- +static void
- +crypto_exit(void)
- +{
- + pid_t p;
- + unsigned long d_flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + /*
- + * Terminate any crypto threads.
- + */
- +
- + CRYPTO_DRIVER_LOCK();
- + p = cryptoproc;
- + cryptoproc = (pid_t) -1;
- + kill_proc(p, SIGTERM, 1);
- + wake_up_interruptible(&cryptoproc_wait);
- + CRYPTO_DRIVER_UNLOCK();
- +
- + wait_for_completion(&cryptoproc_exited);
- +
- + CRYPTO_DRIVER_LOCK();
- + p = cryptoretproc;
- + cryptoretproc = (pid_t) -1;
- + kill_proc(p, SIGTERM, 1);
- + wake_up_interruptible(&cryptoretproc_wait);
- + CRYPTO_DRIVER_UNLOCK();
- +
- + wait_for_completion(&cryptoretproc_exited);
- +
- + /* XXX flush queues??? */
- +
- + /*
- + * Reclaim dynamically allocated resources.
- + */
- + if (crypto_drivers != NULL)
- + kfree(crypto_drivers);
- +
- + if (cryptodesc_zone != NULL)
- + kmem_cache_destroy(cryptodesc_zone);
- + if (cryptop_zone != NULL)
- + kmem_cache_destroy(cryptop_zone);
- +}
- +
- +
- +EXPORT_SYMBOL(crypto_newsession);
- +EXPORT_SYMBOL(crypto_freesession);
- +EXPORT_SYMBOL(crypto_get_driverid);
- +EXPORT_SYMBOL(crypto_kregister);
- +EXPORT_SYMBOL(crypto_register);
- +EXPORT_SYMBOL(crypto_unregister);
- +EXPORT_SYMBOL(crypto_unregister_all);
- +EXPORT_SYMBOL(crypto_unblock);
- +EXPORT_SYMBOL(crypto_dispatch);
- +EXPORT_SYMBOL(crypto_kdispatch);
- +EXPORT_SYMBOL(crypto_freereq);
- +EXPORT_SYMBOL(crypto_getreq);
- +EXPORT_SYMBOL(crypto_done);
- +EXPORT_SYMBOL(crypto_kdone);
- +EXPORT_SYMBOL(crypto_getfeat);
- +EXPORT_SYMBOL(crypto_userasymcrypto);
- +EXPORT_SYMBOL(crypto_getcaps);
- +EXPORT_SYMBOL(crypto_find_driver);
- +EXPORT_SYMBOL(crypto_find_device_byhid);
- +
- +module_init(crypto_init);
- +module_exit(crypto_exit);
- +
- +MODULE_LICENSE("BSD");
- +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
- +MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
- diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/cavium_crypto.c linux-2.6.36/crypto/ocf/cryptocteon/cavium_crypto.c
- --- linux-2.6.36.orig/crypto/ocf/cryptocteon/cavium_crypto.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/cryptocteon/cavium_crypto.c 2010-11-09 20:28:04.311245450 +0100
- @@ -0,0 +1,2283 @@
- +/*
- + * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com>
- + *
- + * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights
- + * reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * 1. Redistributions of source code must retain the above copyright notice,
- + * this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright notice,
- + * this list of conditions and the following disclaimer in the documentation
- + * and/or other materials provided with the distribution.
- + * 3. All advertising materials mentioning features or use of this software
- + * must display the following acknowledgement:
- + * This product includes software developed by Cavium Networks
- + * 4. Cavium Networks' name may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * This Software, including technical data, may be subject to U.S. export
- + * control laws, including the U.S. Export Administration Act and its
- + * associated regulations, and may be subject to export or import regulations
- + * in other countries. You warrant that You will comply strictly in all
- + * respects with all such regulations and acknowledge that you have the
- + * responsibility to obtain licenses to export, re-export or import the
- + * Software.
- + *
- + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
- + * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES,
- + * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE
- + * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
- + * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
- + * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
- + * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
- + * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
- + * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
- + * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- +*/
- +/****************************************************************************/
- +
- +#include <linux/scatterlist.h>
- +#include <asm/octeon/octeon.h>
- +#include "octeon-asm.h"
- +
- +/****************************************************************************/
- +
- +extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *);
- +extern void octeon_crypto_disable(struct octeon_cop2_state *, unsigned long);
- +
- +#define SG_INIT(s, p, i, l) \
- + { \
- + (i) = 0; \
- + (l) = (s)[0].length; \
- + (p) = (typeof(p)) sg_virt((s)); \
- + CVMX_PREFETCH0((p)); \
- + }
- +
- +#define SG_CONSUME(s, p, i, l) \
- + { \
- + (p)++; \
- + (l) -= sizeof(*(p)); \
- + if ((l) < 0) { \
- + dprintk("%s, %d: l = %d\n", __FILE__, __LINE__, l); \
- + } else if ((l) == 0) { \
- + (i)++; \
- + (l) = (s)[0].length; \
- + (p) = (typeof(p)) sg_virt(s); \
- + CVMX_PREFETCH0((p)); \
- + } \
- + }
- +
- +#define ESP_HEADER_LENGTH 8
- +#define DES_CBC_IV_LENGTH 8
- +#define AES_CBC_IV_LENGTH 16
- +#define ESP_HMAC_LEN 12
- +
- +#define ESP_HEADER_LENGTH 8
- +#define DES_CBC_IV_LENGTH 8
- +
- +/****************************************************************************/
- +
- +#define CVM_LOAD_SHA_UNIT(dat, next) { \
- + if (next == 0) { \
- + next = 1; \
- + CVMX_MT_HSH_DAT (dat, 0); \
- + } else if (next == 1) { \
- + next = 2; \
- + CVMX_MT_HSH_DAT (dat, 1); \
- + } else if (next == 2) { \
- + next = 3; \
- + CVMX_MT_HSH_DAT (dat, 2); \
- + } else if (next == 3) { \
- + next = 4; \
- + CVMX_MT_HSH_DAT (dat, 3); \
- + } else if (next == 4) { \
- + next = 5; \
- + CVMX_MT_HSH_DAT (dat, 4); \
- + } else if (next == 5) { \
- + next = 6; \
- + CVMX_MT_HSH_DAT (dat, 5); \
- + } else if (next == 6) { \
- + next = 7; \
- + CVMX_MT_HSH_DAT (dat, 6); \
- + } else { \
- + CVMX_MT_HSH_STARTSHA (dat); \
- + next = 0; \
- + } \
- +}
- +
- +#define CVM_LOAD2_SHA_UNIT(dat1, dat2, next) { \
- + if (next == 0) { \
- + CVMX_MT_HSH_DAT (dat1, 0); \
- + CVMX_MT_HSH_DAT (dat2, 1); \
- + next = 2; \
- + } else if (next == 1) { \
- + CVMX_MT_HSH_DAT (dat1, 1); \
- + CVMX_MT_HSH_DAT (dat2, 2); \
- + next = 3; \
- + } else if (next == 2) { \
- + CVMX_MT_HSH_DAT (dat1, 2); \
- + CVMX_MT_HSH_DAT (dat2, 3); \
- + next = 4; \
- + } else if (next == 3) { \
- + CVMX_MT_HSH_DAT (dat1, 3); \
- + CVMX_MT_HSH_DAT (dat2, 4); \
- + next = 5; \
- + } else if (next == 4) { \
- + CVMX_MT_HSH_DAT (dat1, 4); \
- + CVMX_MT_HSH_DAT (dat2, 5); \
- + next = 6; \
- + } else if (next == 5) { \
- + CVMX_MT_HSH_DAT (dat1, 5); \
- + CVMX_MT_HSH_DAT (dat2, 6); \
- + next = 7; \
- + } else if (next == 6) { \
- + CVMX_MT_HSH_DAT (dat1, 6); \
- + CVMX_MT_HSH_STARTSHA (dat2); \
- + next = 0; \
- + } else { \
- + CVMX_MT_HSH_STARTSHA (dat1); \
- + CVMX_MT_HSH_DAT (dat2, 0); \
- + next = 1; \
- + } \
- +}
- +
- +/****************************************************************************/
- +
- +#define CVM_LOAD_MD5_UNIT(dat, next) { \
- + if (next == 0) { \
- + next = 1; \
- + CVMX_MT_HSH_DAT (dat, 0); \
- + } else if (next == 1) { \
- + next = 2; \
- + CVMX_MT_HSH_DAT (dat, 1); \
- + } else if (next == 2) { \
- + next = 3; \
- + CVMX_MT_HSH_DAT (dat, 2); \
- + } else if (next == 3) { \
- + next = 4; \
- + CVMX_MT_HSH_DAT (dat, 3); \
- + } else if (next == 4) { \
- + next = 5; \
- + CVMX_MT_HSH_DAT (dat, 4); \
- + } else if (next == 5) { \
- + next = 6; \
- + CVMX_MT_HSH_DAT (dat, 5); \
- + } else if (next == 6) { \
- + next = 7; \
- + CVMX_MT_HSH_DAT (dat, 6); \
- + } else { \
- + CVMX_MT_HSH_STARTMD5 (dat); \
- + next = 0; \
- + } \
- +}
- +
- +#define CVM_LOAD2_MD5_UNIT(dat1, dat2, next) { \
- + if (next == 0) { \
- + CVMX_MT_HSH_DAT (dat1, 0); \
- + CVMX_MT_HSH_DAT (dat2, 1); \
- + next = 2; \
- + } else if (next == 1) { \
- + CVMX_MT_HSH_DAT (dat1, 1); \
- + CVMX_MT_HSH_DAT (dat2, 2); \
- + next = 3; \
- + } else if (next == 2) { \
- + CVMX_MT_HSH_DAT (dat1, 2); \
- + CVMX_MT_HSH_DAT (dat2, 3); \
- + next = 4; \
- + } else if (next == 3) { \
- + CVMX_MT_HSH_DAT (dat1, 3); \
- + CVMX_MT_HSH_DAT (dat2, 4); \
- + next = 5; \
- + } else if (next == 4) { \
- + CVMX_MT_HSH_DAT (dat1, 4); \
- + CVMX_MT_HSH_DAT (dat2, 5); \
- + next = 6; \
- + } else if (next == 5) { \
- + CVMX_MT_HSH_DAT (dat1, 5); \
- + CVMX_MT_HSH_DAT (dat2, 6); \
- + next = 7; \
- + } else if (next == 6) { \
- + CVMX_MT_HSH_DAT (dat1, 6); \
- + CVMX_MT_HSH_STARTMD5 (dat2); \
- + next = 0; \
- + } else { \
- + CVMX_MT_HSH_STARTMD5 (dat1); \
- + CVMX_MT_HSH_DAT (dat2, 0); \
- + next = 1; \
- + } \
- +}
- +
- +/****************************************************************************/
- +
- +static inline uint64_t
- +swap64(uint64_t a)
- +{
- + return ((a >> 56) |
- + (((a >> 48) & 0xfful) << 8) |
- + (((a >> 40) & 0xfful) << 16) |
- + (((a >> 32) & 0xfful) << 24) |
- + (((a >> 24) & 0xfful) << 32) |
- + (((a >> 16) & 0xfful) << 40) |
- + (((a >> 8) & 0xfful) << 48) | (((a >> 0) & 0xfful) << 56));
- +}
- +
- +/****************************************************************************/
- +
- +void
- +octo_calc_hash(__u8 auth, unsigned char *key, uint64_t *inner, uint64_t *outer)
- +{
- + uint8_t hash_key[64];
- + uint64_t *key1;
- + register uint64_t xor1 = 0x3636363636363636ULL;
- + register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + memset(hash_key, 0, sizeof(hash_key));
- + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
- + key1 = (uint64_t *) hash_key;
- + flags = octeon_crypto_enable(&state);
- + if (auth) {
- + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
- + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
- + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
- + } else {
- + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
- + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
- + }
- +
- + CVMX_MT_HSH_DAT((*key1 ^ xor1), 0);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor1), 1);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor1), 2);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor1), 3);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor1), 4);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor1), 5);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor1), 6);
- + key1++;
- + if (auth)
- + CVMX_MT_HSH_STARTSHA((*key1 ^ xor1));
- + else
- + CVMX_MT_HSH_STARTMD5((*key1 ^ xor1));
- +
- + CVMX_MF_HSH_IV(inner[0], 0);
- + CVMX_MF_HSH_IV(inner[1], 1);
- + if (auth) {
- + inner[2] = 0;
- + CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2);
- + }
- +
- + memset(hash_key, 0, sizeof(hash_key));
- + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
- + key1 = (uint64_t *) hash_key;
- + if (auth) {
- + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
- + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
- + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
- + } else {
- + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
- + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
- + }
- +
- + CVMX_MT_HSH_DAT((*key1 ^ xor2), 0);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor2), 1);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor2), 2);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor2), 3);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor2), 4);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor2), 5);
- + key1++;
- + CVMX_MT_HSH_DAT((*key1 ^ xor2), 6);
- + key1++;
- + if (auth)
- + CVMX_MT_HSH_STARTSHA((*key1 ^ xor2));
- + else
- + CVMX_MT_HSH_STARTMD5((*key1 ^ xor2));
- +
- + CVMX_MF_HSH_IV(outer[0], 0);
- + CVMX_MF_HSH_IV(outer[1], 1);
- + if (auth) {
- + outer[2] = 0;
- + CVMX_MF_HSH_IV(outer[2], 2);
- + }
- + octeon_crypto_disable(&state, flags);
- + return;
- +}
- +
- +/****************************************************************************/
- +/* DES functions */
- +
- +int
- +octo_des_cbc_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + uint64_t *data;
- + int data_i, data_l;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load 3DES Key */
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + if (od->octo_encklen == 24) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + } else if (od->octo_encklen == 8) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- +
- + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
- +
- + while (crypt_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_off -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + CVMX_MT_3DES_ENC_CBC(*data);
- + CVMX_MF_3DES_RESULT(*data);
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_len -= 8;
- + }
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +
- +int
- +octo_des_cbc_decrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + uint64_t *data;
- + int data_i, data_l;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load 3DES Key */
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + if (od->octo_encklen == 24) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + } else if (od->octo_encklen == 8) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- +
- + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
- +
- + while (crypt_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_off -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + CVMX_MT_3DES_DEC_CBC(*data);
- + CVMX_MF_3DES_RESULT(*data);
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_len -= 8;
- + }
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- +/* AES functions */
- +
- +int
- +octo_aes_cbc_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + uint64_t *data, *pdata;
- + int data_i, data_l;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load AES Key */
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- +
- + if (od->octo_encklen == 16) {
- + CVMX_MT_AES_KEY(0x0, 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 24) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 32) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
- +
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
- +
- + while (crypt_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_off -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + pdata = data;
- + CVMX_MT_AES_ENC_CBC0(*data);
- + SG_CONSUME(sg, data, data_i, data_l);
- + CVMX_MT_AES_ENC_CBC1(*data);
- + CVMX_MF_AES_RESULT(*pdata, 0);
- + CVMX_MF_AES_RESULT(*data, 1);
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_len -= 16;
- + }
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +
- +int
- +octo_aes_cbc_decrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + uint64_t *data, *pdata;
- + int data_i, data_l;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load AES Key */
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- +
- + if (od->octo_encklen == 16) {
- + CVMX_MT_AES_KEY(0x0, 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 24) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 32) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
- +
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
- +
- + while (crypt_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_off -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + pdata = data;
- + CVMX_MT_AES_DEC_CBC0(*data);
- + SG_CONSUME(sg, data, data_i, data_l);
- + CVMX_MT_AES_DEC_CBC1(*data);
- + CVMX_MF_AES_RESULT(*pdata, 0);
- + CVMX_MF_AES_RESULT(*data, 1);
- + SG_CONSUME(sg, data, data_i, data_l);
- + crypt_len -= 16;
- + }
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- +/* MD5 */
- +
- +int
- +octo_null_md5_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + uint64_t *data;
- + uint64_t tmp1, tmp2;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
- + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data, data_i, data_l);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* Load MD5 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- +
- + while (auth_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + auth_off -= 8;
- + }
- +
- + while (auth_len > 0) {
- + CVM_LOAD_MD5_UNIT(*data, next);
- + auth_len -= 8;
- + SG_CONSUME(sg, data, data_i, data_l);
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVMX_ES64(tmp1, ((alen + 64) << 3));
- + CVM_LOAD_MD5_UNIT(tmp1, next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_ES64(tmp1, ((64 + 16) << 3));
- + CVMX_MT_HSH_STARTMD5(tmp1);
- +
- + /* save the HMAC */
- + SG_INIT(sg, data, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + icv_off -= 8;
- + }
- + CVMX_MF_HSH_IV(*data, 0);
- + SG_CONSUME(sg, data, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- +/* SHA1 */
- +
- +int
- +octo_null_sha1_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + uint64_t *data;
- + uint64_t tmp1, tmp2, tmp3;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
- + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data, data_i, data_l);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* Load SHA1 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
- +
- + while (auth_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + auth_off -= 8;
- + }
- +
- + while (auth_len > 0) {
- + CVM_LOAD_SHA_UNIT(*data, next);
- + auth_len -= 8;
- + SG_CONSUME(sg, data, data_i, data_l);
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- + tmp3 = 0;
- + CVMX_MF_HSH_IV(tmp3, 2);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + tmp3 |= 0x0000000080000000;
- + CVMX_MT_HSH_DAT(tmp3, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
- +
- + /* save the HMAC */
- + SG_INIT(sg, data, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data, data_i, data_l);
- + icv_off -= 8;
- + }
- + CVMX_MF_HSH_IV(*data, 0);
- + SG_CONSUME(sg, data, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- +/* DES MD5 */
- +
- +int
- +octo_des_cbc_md5_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata;
- + uint64_t *data = &mydata.data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load 3DES Key */
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + if (od->octo_encklen == 24) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + } else if (od->octo_encklen == 8) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- +
- + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
- +
- + /* Load MD5 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + while (crypt_len > 0 || auth_len > 0) {
- + uint32_t *first = data32;
- + mydata.data32[0] = *first;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata.data32[1] = *data32;
- + if (crypt_off <= 0) {
- + if (crypt_len > 0) {
- + CVMX_MT_3DES_ENC_CBC(*data);
- + CVMX_MF_3DES_RESULT(*data);
- + crypt_len -= 8;
- + }
- + } else
- + crypt_off -= 8;
- + if (auth_off <= 0) {
- + if (auth_len > 0) {
- + CVM_LOAD_MD5_UNIT(*data, next);
- + auth_len -= 8;
- + }
- + } else
- + auth_off -= 8;
- + *first = mydata.data32[0];
- + *data32 = mydata.data32[1];
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVMX_ES64(tmp1, ((alen + 64) << 3));
- + CVM_LOAD_MD5_UNIT(tmp1, next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_ES64(tmp1, ((64 + 16) << 3));
- + CVMX_MT_HSH_STARTMD5(tmp1);
- +
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +int
- +octo_des_cbc_md5_decrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata;
- + uint64_t *data = &mydata.data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load 3DES Key */
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + if (od->octo_encklen == 24) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + } else if (od->octo_encklen == 8) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- +
- + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
- +
- + /* Load MD5 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + while (crypt_len > 0 || auth_len > 0) {
- + uint32_t *first = data32;
- + mydata.data32[0] = *first;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata.data32[1] = *data32;
- + if (auth_off <= 0) {
- + if (auth_len > 0) {
- + CVM_LOAD_MD5_UNIT(*data, next);
- + auth_len -= 8;
- + }
- + } else
- + auth_off -= 8;
- + if (crypt_off <= 0) {
- + if (crypt_len > 0) {
- + CVMX_MT_3DES_DEC_CBC(*data);
- + CVMX_MF_3DES_RESULT(*data);
- + crypt_len -= 8;
- + }
- + } else
- + crypt_off -= 8;
- + *first = mydata.data32[0];
- + *data32 = mydata.data32[1];
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVMX_ES64(tmp1, ((alen + 64) << 3));
- + CVM_LOAD_MD5_UNIT(tmp1, next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_ES64(tmp1, ((64 + 16) << 3));
- + CVMX_MT_HSH_STARTMD5(tmp1);
- +
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- +/* DES SHA */
- +
- +int
- +octo_des_cbc_sha1_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata;
- + uint64_t *data = &mydata.data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2, tmp3;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load 3DES Key */
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + if (od->octo_encklen == 24) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + } else if (od->octo_encklen == 8) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- +
- + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
- +
- + /* Load SHA1 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + while (crypt_len > 0 || auth_len > 0) {
- + uint32_t *first = data32;
- + mydata.data32[0] = *first;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata.data32[1] = *data32;
- + if (crypt_off <= 0) {
- + if (crypt_len > 0) {
- + CVMX_MT_3DES_ENC_CBC(*data);
- + CVMX_MF_3DES_RESULT(*data);
- + crypt_len -= 8;
- + }
- + } else
- + crypt_off -= 8;
- + if (auth_off <= 0) {
- + if (auth_len > 0) {
- + CVM_LOAD_SHA_UNIT(*data, next);
- + auth_len -= 8;
- + }
- + } else
- + auth_off -= 8;
- + *first = mydata.data32[0];
- + *data32 = mydata.data32[1];
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_SHA_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- + tmp3 = 0;
- + CVMX_MF_HSH_IV(tmp3, 2);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + tmp3 |= 0x0000000080000000;
- + CVMX_MT_HSH_DAT(tmp3, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
- +
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +int
- +octo_des_cbc_sha1_decrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata;
- + uint64_t *data = &mydata.data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2, tmp3;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load 3DES Key */
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + if (od->octo_encklen == 24) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + } else if (od->octo_encklen == 8) {
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
- + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- +
- + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
- +
- + /* Load SHA1 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + while (crypt_len > 0 || auth_len > 0) {
- + uint32_t *first = data32;
- + mydata.data32[0] = *first;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata.data32[1] = *data32;
- + if (auth_off <= 0) {
- + if (auth_len > 0) {
- + CVM_LOAD_SHA_UNIT(*data, next);
- + auth_len -= 8;
- + }
- + } else
- + auth_off -= 8;
- + if (crypt_off <= 0) {
- + if (crypt_len > 0) {
- + CVMX_MT_3DES_DEC_CBC(*data);
- + CVMX_MF_3DES_RESULT(*data);
- + crypt_len -= 8;
- + }
- + } else
- + crypt_off -= 8;
- + *first = mydata.data32[0];
- + *data32 = mydata.data32[1];
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_SHA_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- + tmp3 = 0;
- + CVMX_MF_HSH_IV(tmp3, 2);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + tmp3 |= 0x0000000080000000;
- + CVMX_MT_HSH_DAT(tmp3, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- +/* AES MD5 */
- +
- +int
- +octo_aes_cbc_md5_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata[2];
- + uint64_t *pdata = &mydata[0].data64[0];
- + uint64_t *data = &mydata[1].data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load AES Key */
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- +
- + if (od->octo_encklen == 16) {
- + CVMX_MT_AES_KEY(0x0, 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 24) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 32) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
- +
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
- +
- + /* Load MD5 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + /* align auth and crypt */
- + while (crypt_off > 0 && auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_MD5_UNIT(*pdata, next);
- + crypt_off -= 8;
- + auth_len -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + uint32_t *pdata32[3];
- +
- + pdata32[0] = data32;
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- +
- + pdata32[1] = data32;
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- +
- + pdata32[2] = data32;
- + mydata[1].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- +
- + mydata[1].data32[1] = *data32;
- +
- + CVMX_MT_AES_ENC_CBC0(*pdata);
- + CVMX_MT_AES_ENC_CBC1(*data);
- + CVMX_MF_AES_RESULT(*pdata, 0);
- + CVMX_MF_AES_RESULT(*data, 1);
- + crypt_len -= 16;
- +
- + if (auth_len > 0) {
- + CVM_LOAD_MD5_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- + if (auth_len > 0) {
- + CVM_LOAD_MD5_UNIT(*data, next);
- + auth_len -= 8;
- + }
- +
- + *pdata32[0] = mydata[0].data32[0];
- + *pdata32[1] = mydata[0].data32[1];
- + *pdata32[2] = mydata[1].data32[0];
- + *data32 = mydata[1].data32[1];
- +
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish any left over hashing */
- + while (auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_MD5_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVMX_ES64(tmp1, ((alen + 64) << 3));
- + CVM_LOAD_MD5_UNIT(tmp1, next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_ES64(tmp1, ((64 + 16) << 3));
- + CVMX_MT_HSH_STARTMD5(tmp1);
- +
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +int
- +octo_aes_cbc_md5_decrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata[2];
- + uint64_t *pdata = &mydata[0].data64[0];
- + uint64_t *data = &mydata[1].data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load AES Key */
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- +
- + if (od->octo_encklen == 16) {
- + CVMX_MT_AES_KEY(0x0, 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 24) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 32) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
- +
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
- +
- + /* Load MD5 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + /* align auth and crypt */
- + while (crypt_off > 0 && auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_MD5_UNIT(*pdata, next);
- + crypt_off -= 8;
- + auth_len -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + uint32_t *pdata32[3];
- +
- + pdata32[0] = data32;
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + pdata32[1] = data32;
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + pdata32[2] = data32;
- + mydata[1].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[1].data32[1] = *data32;
- +
- + if (auth_len > 0) {
- + CVM_LOAD_MD5_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- +
- + if (auth_len > 0) {
- + CVM_LOAD_MD5_UNIT(*data, next);
- + auth_len -= 8;
- + }
- +
- + CVMX_MT_AES_DEC_CBC0(*pdata);
- + CVMX_MT_AES_DEC_CBC1(*data);
- + CVMX_MF_AES_RESULT(*pdata, 0);
- + CVMX_MF_AES_RESULT(*data, 1);
- + crypt_len -= 16;
- +
- + *pdata32[0] = mydata[0].data32[0];
- + *pdata32[1] = mydata[0].data32[1];
- + *pdata32[2] = mydata[1].data32[0];
- + *data32 = mydata[1].data32[1];
- +
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish left over hash if any */
- + while (auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_MD5_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- +
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVMX_ES64(tmp1, ((alen + 64) << 3));
- + CVM_LOAD_MD5_UNIT(tmp1, next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_ES64(tmp1, ((64 + 16) << 3));
- + CVMX_MT_HSH_STARTMD5(tmp1);
- +
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- +/* AES SHA1 */
- +
- +int
- +octo_aes_cbc_sha1_encrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata[2];
- + uint64_t *pdata = &mydata[0].data64[0];
- + uint64_t *data = &mydata[1].data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2, tmp3;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
- + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load AES Key */
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- +
- + if (od->octo_encklen == 16) {
- + CVMX_MT_AES_KEY(0x0, 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 24) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 32) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
- +
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
- +
- + /* Load SHA IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + /* align auth and crypt */
- + while (crypt_off > 0 && auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_SHA_UNIT(*pdata, next);
- + crypt_off -= 8;
- + auth_len -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + uint32_t *pdata32[3];
- +
- + pdata32[0] = data32;
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + pdata32[1] = data32;
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + pdata32[2] = data32;
- + mydata[1].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[1].data32[1] = *data32;
- +
- + CVMX_MT_AES_ENC_CBC0(*pdata);
- + CVMX_MT_AES_ENC_CBC1(*data);
- + CVMX_MF_AES_RESULT(*pdata, 0);
- + CVMX_MF_AES_RESULT(*data, 1);
- + crypt_len -= 16;
- +
- + if (auth_len > 0) {
- + CVM_LOAD_SHA_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- + if (auth_len > 0) {
- + CVM_LOAD_SHA_UNIT(*data, next);
- + auth_len -= 8;
- + }
- +
- + *pdata32[0] = mydata[0].data32[0];
- + *pdata32[1] = mydata[0].data32[1];
- + *pdata32[2] = mydata[1].data32[0];
- + *data32 = mydata[1].data32[1];
- +
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish and hashing */
- + while (auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_SHA_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_SHA_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- + tmp3 = 0;
- + CVMX_MF_HSH_IV(tmp3, 2);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + tmp3 |= 0x0000000080000000;
- + CVMX_MT_HSH_DAT(tmp3, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +int
- +octo_aes_cbc_sha1_decrypt(
- + struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp)
- +{
- + register int next = 0;
- + union {
- + uint32_t data32[2];
- + uint64_t data64[1];
- + } mydata[2];
- + uint64_t *pdata = &mydata[0].data64[0];
- + uint64_t *data = &mydata[1].data64[0];
- + uint32_t *data32;
- + uint64_t tmp1, tmp2, tmp3;
- + int data_i, data_l, alen = auth_len;
- + struct octeon_cop2_state state;
- + unsigned long flags;
- +
- + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
- + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
- +
- + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
- + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
- + (crypt_len & 0x7) ||
- + (auth_len & 0x7) ||
- + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
- + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
- + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
- + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + return -EINVAL;
- + }
- +
- + SG_INIT(sg, data32, data_i, data_l);
- +
- + CVMX_PREFETCH0(ivp);
- + CVMX_PREFETCH0(od->octo_enckey);
- +
- + flags = octeon_crypto_enable(&state);
- +
- + /* load AES Key */
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
- +
- + if (od->octo_encklen == 16) {
- + CVMX_MT_AES_KEY(0x0, 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 24) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(0x0, 3);
- + } else if (od->octo_encklen == 32) {
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
- + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
- + } else {
- + octeon_crypto_disable(&state, flags);
- + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
- + return -EINVAL;
- + }
- + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
- +
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
- + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
- +
- + /* Load SHA1 IV */
- + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
- +
- + while (crypt_off > 0 && auth_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + crypt_off -= 4;
- + auth_off -= 4;
- + }
- +
- + /* align auth and crypt */
- + while (crypt_off > 0 && auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_SHA_UNIT(*pdata, next);
- + crypt_off -= 8;
- + auth_len -= 8;
- + }
- +
- + while (crypt_len > 0) {
- + uint32_t *pdata32[3];
- +
- + pdata32[0] = data32;
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + pdata32[1] = data32;
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + pdata32[2] = data32;
- + mydata[1].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[1].data32[1] = *data32;
- +
- + if (auth_len > 0) {
- + CVM_LOAD_SHA_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- + if (auth_len > 0) {
- + CVM_LOAD_SHA_UNIT(*data, next);
- + auth_len -= 8;
- + }
- +
- + CVMX_MT_AES_DEC_CBC0(*pdata);
- + CVMX_MT_AES_DEC_CBC1(*data);
- + CVMX_MF_AES_RESULT(*pdata, 0);
- + CVMX_MF_AES_RESULT(*data, 1);
- + crypt_len -= 16;
- +
- + *pdata32[0] = mydata[0].data32[0];
- + *pdata32[1] = mydata[0].data32[1];
- + *pdata32[2] = mydata[1].data32[0];
- + *data32 = mydata[1].data32[1];
- +
- + SG_CONSUME(sg, data32, data_i, data_l);
- + }
- +
- + /* finish and leftover hashing */
- + while (auth_len > 0) {
- + mydata[0].data32[0] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + mydata[0].data32[1] = *data32;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVM_LOAD_SHA_UNIT(*pdata, next);
- + auth_len -= 8;
- + }
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_SHA_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* Finish Inner hash */
- + while (next != 7) {
- + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
- + }
- + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
- +
- + /* Get the inner hash of HMAC */
- + CVMX_MF_HSH_IV(tmp1, 0);
- + CVMX_MF_HSH_IV(tmp2, 1);
- + tmp3 = 0;
- + CVMX_MF_HSH_IV(tmp3, 2);
- +
- + /* Initialize hash unit */
- + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
- + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
- + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
- +
- + CVMX_MT_HSH_DAT(tmp1, 0);
- + CVMX_MT_HSH_DAT(tmp2, 1);
- + tmp3 |= 0x0000000080000000;
- + CVMX_MT_HSH_DAT(tmp3, 2);
- + CVMX_MT_HSH_DATZ(3);
- + CVMX_MT_HSH_DATZ(4);
- + CVMX_MT_HSH_DATZ(5);
- + CVMX_MT_HSH_DATZ(6);
- + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
- +
- + /* finish the hash */
- + CVMX_PREFETCH0(od->octo_hmouter);
- +#if 0
- + if (unlikely(inplen)) {
- + uint64_t tmp = 0;
- + uint8_t *p = (uint8_t *) & tmp;
- + p[inplen] = 0x80;
- + do {
- + inplen--;
- + p[inplen] = ((uint8_t *) data)[inplen];
- + } while (inplen);
- + CVM_LOAD_MD5_UNIT(tmp, next);
- + } else {
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- + }
- +#else
- + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
- +#endif
- +
- + /* save the HMAC */
- + SG_INIT(sg, data32, data_i, data_l);
- + while (icv_off > 0) {
- + SG_CONSUME(sg, data32, data_i, data_l);
- + icv_off -= 4;
- + }
- + CVMX_MF_HSH_IV(tmp1, 0);
- + *data32 = (uint32_t) (tmp1 >> 32);
- + SG_CONSUME(sg, data32, data_i, data_l);
- + *data32 = (uint32_t) tmp1;
- + SG_CONSUME(sg, data32, data_i, data_l);
- + CVMX_MF_HSH_IV(tmp1, 1);
- + *data32 = (uint32_t) (tmp1 >> 32);
- +
- + octeon_crypto_disable(&state, flags);
- + return 0;
- +}
- +
- +/****************************************************************************/
- diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/cryptocteon.c linux-2.6.36/crypto/ocf/cryptocteon/cryptocteon.c
- --- linux-2.6.36.orig/crypto/ocf/cryptocteon/cryptocteon.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/cryptocteon/cryptocteon.c 2010-11-09 20:28:04.371247488 +0100
- @@ -0,0 +1,574 @@
- +/*
- + * Octeon Crypto for OCF
- + *
- + * Written by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2009-2010 David McCullough
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + * ---------------------------------------------------------------------------
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/sched.h>
- +#include <linux/wait.h>
- +#include <linux/crypto.h>
- +#include <linux/mm.h>
- +#include <linux/skbuff.h>
- +#include <linux/random.h>
- +#include <linux/scatterlist.h>
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +
- +struct {
- + softc_device_decl sc_dev;
- +} octo_softc;
- +
- +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
- +
- +struct octo_sess {
- + int octo_encalg;
- + #define MAX_CIPHER_KEYLEN 64
- + char octo_enckey[MAX_CIPHER_KEYLEN];
- + int octo_encklen;
- +
- + int octo_macalg;
- + #define MAX_HASH_KEYLEN 64
- + char octo_mackey[MAX_HASH_KEYLEN];
- + int octo_macklen;
- + int octo_mackey_set;
- +
- + int octo_mlen;
- + int octo_ivsize;
- +
- +#if 0
- + int (*octo_decrypt)(struct scatterlist *sg, int sg_len,
- + uint8_t *key, int key_len, uint8_t * iv,
- + uint64_t *hminner, uint64_t *hmouter);
- +
- + int (*octo_encrypt)(struct scatterlist *sg, int sg_len,
- + uint8_t *key, int key_len, uint8_t * iv,
- + uint64_t *hminner, uint64_t *hmouter);
- +#else
- + int (*octo_encrypt)(struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp);
- + int (*octo_decrypt)(struct octo_sess *od,
- + struct scatterlist *sg, int sg_len,
- + int auth_off, int auth_len,
- + int crypt_off, int crypt_len,
- + int icv_off, uint8_t *ivp);
- +#endif
- +
- + uint64_t octo_hminner[3];
- + uint64_t octo_hmouter[3];
- +};
- +
- +int32_t octo_id = -1;
- +module_param(octo_id, int, 0444);
- +MODULE_PARM_DESC(octo_id, "Read-Only OCF ID for cryptocteon driver");
- +
- +static struct octo_sess **octo_sessions = NULL;
- +static u_int32_t octo_sesnum = 0;
- +
- +static int octo_process(device_t, struct cryptop *, int);
- +static int octo_newsession(device_t, u_int32_t *, struct cryptoini *);
- +static int octo_freesession(device_t, u_int64_t);
- +
- +static device_method_t octo_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, octo_newsession),
- + DEVMETHOD(cryptodev_freesession,octo_freesession),
- + DEVMETHOD(cryptodev_process, octo_process),
- +};
- +
- +#define debug octo_debug
- +int octo_debug = 0;
- +module_param(octo_debug, int, 0644);
- +MODULE_PARM_DESC(octo_debug, "Enable debug");
- +
- +
- +#include "cavium_crypto.c"
- +
- +
- +/*
- + * Generate a new octo session. We artifically limit it to a single
- + * hash/cipher or hash-cipher combo just to make it easier, most callers
- + * do not expect more than this anyway.
- + */
- +static int
- +octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
- +{
- + struct cryptoini *c, *encini = NULL, *macini = NULL;
- + struct octo_sess **ocd;
- + int i;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid == NULL || cri == NULL) {
- + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + /*
- + * To keep it simple, we only handle hash, cipher or hash/cipher in a
- + * session, you cannot currently do multiple ciphers/hashes in one
- + * session even though it would be possibel to code this driver to
- + * handle it.
- + */
- + for (i = 0, c = cri; c && i < 2; i++) {
- + if (c->cri_alg == CRYPTO_MD5_HMAC ||
- + c->cri_alg == CRYPTO_SHA1_HMAC ||
- + c->cri_alg == CRYPTO_NULL_HMAC) {
- + if (macini) {
- + break;
- + }
- + macini = c;
- + }
- + if (c->cri_alg == CRYPTO_DES_CBC ||
- + c->cri_alg == CRYPTO_3DES_CBC ||
- + c->cri_alg == CRYPTO_AES_CBC ||
- + c->cri_alg == CRYPTO_NULL_CBC) {
- + if (encini) {
- + break;
- + }
- + encini = c;
- + }
- + c = c->cri_next;
- + }
- + if (!macini && !encini) {
- + dprintk("%s,%d - EINVAL bad cipher/hash or combination\n",
- + __FILE__, __LINE__);
- + return EINVAL;
- + }
- + if (c) {
- + dprintk("%s,%d - EINVAL cannot handle chained cipher/hash combos\n",
- + __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + /*
- + * So we have something we can do, lets setup the session
- + */
- +
- + if (octo_sessions) {
- + for (i = 1; i < octo_sesnum; i++)
- + if (octo_sessions[i] == NULL)
- + break;
- + } else
- + i = 1; /* NB: to silence compiler warning */
- +
- + if (octo_sessions == NULL || i == octo_sesnum) {
- + if (octo_sessions == NULL) {
- + i = 1; /* We leave octo_sessions[0] empty */
- + octo_sesnum = CRYPTO_SW_SESSIONS;
- + } else
- + octo_sesnum *= 2;
- +
- + ocd = kmalloc(octo_sesnum * sizeof(struct octo_sess *), SLAB_ATOMIC);
- + if (ocd == NULL) {
- + /* Reset session number */
- + if (octo_sesnum == CRYPTO_SW_SESSIONS)
- + octo_sesnum = 0;
- + else
- + octo_sesnum /= 2;
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memset(ocd, 0, octo_sesnum * sizeof(struct octo_sess *));
- +
- + /* Copy existing sessions */
- + if (octo_sessions) {
- + memcpy(ocd, octo_sessions,
- + (octo_sesnum / 2) * sizeof(struct octo_sess *));
- + kfree(octo_sessions);
- + }
- +
- + octo_sessions = ocd;
- + }
- +
- + ocd = &octo_sessions[i];
- + *sid = i;
- +
- +
- + *ocd = (struct octo_sess *) kmalloc(sizeof(struct octo_sess), SLAB_ATOMIC);
- + if (*ocd == NULL) {
- + octo_freesession(NULL, i);
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memset(*ocd, 0, sizeof(struct octo_sess));
- +
- + if (encini && encini->cri_key) {
- + (*ocd)->octo_encklen = (encini->cri_klen + 7) / 8;
- + memcpy((*ocd)->octo_enckey, encini->cri_key, (*ocd)->octo_encklen);
- + }
- +
- + if (macini && macini->cri_key) {
- + (*ocd)->octo_macklen = (macini->cri_klen + 7) / 8;
- + memcpy((*ocd)->octo_mackey, macini->cri_key, (*ocd)->octo_macklen);
- + }
- +
- + (*ocd)->octo_mlen = 0;
- + if (encini && encini->cri_mlen)
- + (*ocd)->octo_mlen = encini->cri_mlen;
- + else if (macini && macini->cri_mlen)
- + (*ocd)->octo_mlen = macini->cri_mlen;
- + else
- + (*ocd)->octo_mlen = 12;
- +
- + /*
- + * point c at the enc if it exists, otherwise the mac
- + */
- + c = encini ? encini : macini;
- +
- + switch (c->cri_alg) {
- + case CRYPTO_DES_CBC:
- + case CRYPTO_3DES_CBC:
- + (*ocd)->octo_ivsize = 8;
- + switch (macini ? macini->cri_alg : -1) {
- + case CRYPTO_MD5_HMAC:
- + (*ocd)->octo_encrypt = octo_des_cbc_md5_encrypt;
- + (*ocd)->octo_decrypt = octo_des_cbc_md5_decrypt;
- + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
- + (*ocd)->octo_hmouter);
- + break;
- + case CRYPTO_SHA1_HMAC:
- + (*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt;
- + (*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt;
- + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
- + (*ocd)->octo_hmouter);
- + break;
- + case -1:
- + (*ocd)->octo_encrypt = octo_des_cbc_encrypt;
- + (*ocd)->octo_decrypt = octo_des_cbc_decrypt;
- + break;
- + default:
- + octo_freesession(NULL, i);
- + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
- + return EINVAL;
- + }
- + break;
- + case CRYPTO_AES_CBC:
- + (*ocd)->octo_ivsize = 16;
- + switch (macini ? macini->cri_alg : -1) {
- + case CRYPTO_MD5_HMAC:
- + (*ocd)->octo_encrypt = octo_aes_cbc_md5_encrypt;
- + (*ocd)->octo_decrypt = octo_aes_cbc_md5_decrypt;
- + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
- + (*ocd)->octo_hmouter);
- + break;
- + case CRYPTO_SHA1_HMAC:
- + (*ocd)->octo_encrypt = octo_aes_cbc_sha1_encrypt;
- + (*ocd)->octo_decrypt = octo_aes_cbc_sha1_decrypt;
- + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
- + (*ocd)->octo_hmouter);
- + break;
- + case -1:
- + (*ocd)->octo_encrypt = octo_aes_cbc_encrypt;
- + (*ocd)->octo_decrypt = octo_aes_cbc_decrypt;
- + break;
- + default:
- + octo_freesession(NULL, i);
- + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
- + return EINVAL;
- + }
- + break;
- + case CRYPTO_MD5_HMAC:
- + (*ocd)->octo_encrypt = octo_null_md5_encrypt;
- + (*ocd)->octo_decrypt = octo_null_md5_encrypt;
- + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
- + (*ocd)->octo_hmouter);
- + break;
- + case CRYPTO_SHA1_HMAC:
- + (*ocd)->octo_encrypt = octo_null_sha1_encrypt;
- + (*ocd)->octo_decrypt = octo_null_sha1_encrypt;
- + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
- + (*ocd)->octo_hmouter);
- + break;
- + default:
- + octo_freesession(NULL, i);
- + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + (*ocd)->octo_encalg = encini ? encini->cri_alg : -1;
- + (*ocd)->octo_macalg = macini ? macini->cri_alg : -1;
- +
- + return 0;
- +}
- +
- +/*
- + * Free a session.
- + */
- +static int
- +octo_freesession(device_t dev, u_int64_t tid)
- +{
- + u_int32_t sid = CRYPTO_SESID2LID(tid);
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid > octo_sesnum || octo_sessions == NULL ||
- + octo_sessions[sid] == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return(EINVAL);
- + }
- +
- + /* Silently accept and return */
- + if (sid == 0)
- + return(0);
- +
- + if (octo_sessions[sid])
- + kfree(octo_sessions[sid]);
- + octo_sessions[sid] = NULL;
- + return 0;
- +}
- +
- +/*
- + * Process a request.
- + */
- +static int
- +octo_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + struct cryptodesc *crd;
- + struct octo_sess *od;
- + u_int32_t lid;
- +#define SCATTERLIST_MAX 16
- + struct scatterlist sg[SCATTERLIST_MAX];
- + int sg_num, sg_len;
- + struct sk_buff *skb = NULL;
- + struct uio *uiop = NULL;
- + struct cryptodesc *enccrd = NULL, *maccrd = NULL;
- + unsigned char *ivp = NULL;
- + unsigned char iv_data[HASH_MAX_LEN];
- + int auth_off = 0, auth_len = 0, crypt_off = 0, crypt_len = 0, icv_off = 0;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + /* Sanity check */
- + if (crp == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + crp->crp_etype = 0;
- +
- + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + lid = crp->crp_sid & 0xffffffff;
- + if (lid >= octo_sesnum || lid == 0 || octo_sessions == NULL ||
- + octo_sessions[lid] == NULL) {
- + crp->crp_etype = ENOENT;
- + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
- + goto done;
- + }
- + od = octo_sessions[lid];
- +
- + /*
- + * do some error checking outside of the loop for SKB and IOV processing
- + * this leaves us with valid skb or uiop pointers for later
- + */
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + skb = (struct sk_buff *) crp->crp_buf;
- + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
- + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
- + skb_shinfo(skb)->nr_frags);
- + goto done;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + uiop = (struct uio *) crp->crp_buf;
- + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
- + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
- + uiop->uio_iovcnt);
- + goto done;
- + }
- + }
- +
- + /* point our enccrd and maccrd appropriately */
- + crd = crp->crp_desc;
- + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
- + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
- + crd = crd->crd_next;
- + if (crd) {
- + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
- + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
- + crd = crd->crd_next;
- + }
- + if (crd) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: ENOENT - descriptors do not match session\n",
- + __FILE__, __LINE__);
- + goto done;
- + }
- +
- + if (enccrd) {
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
- + ivp = enccrd->crd_iv;
- + } else {
- + ivp = iv_data;
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);
- + }
- +
- + if (maccrd) {
- + auth_off = maccrd->crd_skip;
- + auth_len = maccrd->crd_len;
- + icv_off = maccrd->crd_inject;
- + }
- +
- + crypt_off = enccrd->crd_skip;
- + crypt_len = enccrd->crd_len;
- + } else { /* if (maccrd) */
- + auth_off = maccrd->crd_skip;
- + auth_len = maccrd->crd_len;
- + icv_off = maccrd->crd_inject;
- + }
- +
- +
- + /*
- + * setup the SG list to cover the buffer
- + */
- + memset(sg, 0, sizeof(sg));
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + int i, len;
- +
- + sg_num = 0;
- + sg_len = 0;
- +
- + len = skb_headlen(skb);
- + sg_set_page(&sg[sg_num], virt_to_page(skb->data), len,
- + offset_in_page(skb->data));
- + sg_len += len;
- + sg_num++;
- +
- + for (i = 0; i < skb_shinfo(skb)->nr_frags && sg_num < SCATTERLIST_MAX;
- + i++) {
- + len = skb_shinfo(skb)->frags[i].size;
- + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page,
- + len, skb_shinfo(skb)->frags[i].page_offset);
- + sg_len += len;
- + sg_num++;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + int len;
- +
- + sg_len = 0;
- + for (sg_num = 0; sg_len < crp->crp_ilen &&
- + sg_num < uiop->uio_iovcnt &&
- + sg_num < SCATTERLIST_MAX; sg_num++) {
- + len = uiop->uio_iov[sg_num].iov_len;
- + sg_set_page(&sg[sg_num],
- + virt_to_page(uiop->uio_iov[sg_num].iov_base), len,
- + offset_in_page(uiop->uio_iov[sg_num].iov_base));
- + sg_len += len;
- + }
- + } else {
- + sg_len = crp->crp_ilen;
- + sg_set_page(&sg[0], virt_to_page(crp->crp_buf), sg_len,
- + offset_in_page(crp->crp_buf));
- + sg_num = 1;
- + }
- +
- +
- + /*
- + * setup a new explicit key
- + */
- + if (enccrd) {
- + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
- + od->octo_encklen = (enccrd->crd_klen + 7) / 8;
- + memcpy(od->octo_enckey, enccrd->crd_key, od->octo_encklen);
- + }
- + }
- + if (maccrd) {
- + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
- + od->octo_macklen = (maccrd->crd_klen + 7) / 8;
- + memcpy(od->octo_mackey, maccrd->crd_key, od->octo_macklen);
- + od->octo_mackey_set = 0;
- + }
- + if (!od->octo_mackey_set) {
- + octo_calc_hash(maccrd->crd_alg == CRYPTO_MD5_HMAC ? 0 : 1,
- + maccrd->crd_key, od->octo_hminner, od->octo_hmouter);
- + od->octo_mackey_set = 1;
- + }
- + }
- +
- +
- + if (!enccrd || (enccrd->crd_flags & CRD_F_ENCRYPT))
- + (*od->octo_encrypt)(od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- + else
- + (*od->octo_decrypt)(od, sg, sg_len,
- + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
- +
- +done:
- + crypto_done(crp);
- + return 0;
- +}
- +
- +static int
- +cryptocteon_init(void)
- +{
- + dprintk("%s(%p)\n", __FUNCTION__, cryptocteon_init);
- +
- + softc_device_init(&octo_softc, "cryptocteon", 0, octo_methods);
- +
- + octo_id = crypto_get_driverid(softc_get_device(&octo_softc),
- + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SYNC);
- + if (octo_id < 0) {
- + printk("Cryptocteon device cannot initialize!");
- + return -ENODEV;
- + }
- +
- + crypto_register(octo_id, CRYPTO_MD5_HMAC, 0,0);
- + crypto_register(octo_id, CRYPTO_SHA1_HMAC, 0,0);
- + //crypto_register(octo_id, CRYPTO_MD5, 0,0);
- + //crypto_register(octo_id, CRYPTO_SHA1, 0,0);
- + crypto_register(octo_id, CRYPTO_DES_CBC, 0,0);
- + crypto_register(octo_id, CRYPTO_3DES_CBC, 0,0);
- + crypto_register(octo_id, CRYPTO_AES_CBC, 0,0);
- +
- + return(0);
- +}
- +
- +static void
- +cryptocteon_exit(void)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + crypto_unregister_all(octo_id);
- + octo_id = -1;
- +}
- +
- +module_init(cryptocteon_init);
- +module_exit(cryptocteon_exit);
- +
- +MODULE_LICENSE("BSD");
- +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
- +MODULE_DESCRIPTION("Cryptocteon (OCF module for Cavium OCTEON crypto)");
- diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/Makefile linux-2.6.36/crypto/ocf/cryptocteon/Makefile
- --- linux-2.6.36.orig/crypto/ocf/cryptocteon/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/cryptocteon/Makefile 2010-11-09 20:28:04.411246358 +0100
- @@ -0,0 +1,17 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
- +
- +ifdef CONFIG_OCF_CRYPTOCTEON
- +# you need the cavium crypto component installed
- +EXTRA_CFLAGS += -I$(ROOTDIR)/prop/include
- +endif
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/cryptodev.c linux-2.6.36/crypto/ocf/cryptodev.c
- --- linux-2.6.36.orig/crypto/ocf/cryptodev.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/cryptodev.c 2010-11-09 20:29:09.284996310 +0100
- @@ -0,0 +1,1060 @@
- +/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
- +
- +/*-
- + * Linux port done by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + * The license and original author are listed below.
- + *
- + * Copyright (c) 2001 Theo de Raadt
- + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored in part by the Defense Advanced Research Projects
- + * Agency (DARPA) and Air Force Research Laboratory, Air Force
- + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- + *
- +__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/types.h>
- +#include <linux/time.h>
- +#include <linux/delay.h>
- +#include <linux/list.h>
- +#include <linux/init.h>
- +#include <linux/sched.h>
- +#include <linux/unistd.h>
- +#include <linux/module.h>
- +#include <linux/wait.h>
- +#include <linux/slab.h>
- +#include <linux/fs.h>
- +#include <linux/dcache.h>
- +#include <linux/file.h>
- +#include <linux/mount.h>
- +#include <linux/miscdevice.h>
- +#include <linux/version.h>
- +#include <asm/uaccess.h>
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +
- +extern asmlinkage long sys_dup(unsigned int fildes);
- +
- +#define debug cryptodev_debug
- +int cryptodev_debug = 0;
- +module_param(cryptodev_debug, int, 0644);
- +MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
- +
- +struct csession_info {
- + u_int16_t blocksize;
- + u_int16_t minkey, maxkey;
- +
- + u_int16_t keysize;
- + /* u_int16_t hashsize; */
- + u_int16_t authsize;
- + u_int16_t authkey;
- + /* u_int16_t ctxsize; */
- +};
- +
- +struct csession {
- + struct list_head list;
- + u_int64_t sid;
- + u_int32_t ses;
- +
- + wait_queue_head_t waitq;
- +
- + u_int32_t cipher;
- +
- + u_int32_t mac;
- +
- + caddr_t key;
- + int keylen;
- + u_char tmp_iv[EALG_MAX_BLOCK_LEN];
- +
- + caddr_t mackey;
- + int mackeylen;
- +
- + struct csession_info info;
- +
- + struct iovec iovec;
- + struct uio uio;
- + int error;
- +};
- +
- +struct fcrypt {
- + struct list_head csessions;
- + int sesn;
- +};
- +
- +static struct csession *csefind(struct fcrypt *, u_int);
- +static int csedelete(struct fcrypt *, struct csession *);
- +static struct csession *cseadd(struct fcrypt *, struct csession *);
- +static struct csession *csecreate(struct fcrypt *, u_int64_t,
- + struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
- +static int csefree(struct csession *);
- +
- +static int cryptodev_op(struct csession *, struct crypt_op *);
- +static int cryptodev_key(struct crypt_kop *);
- +static int cryptodev_find(struct crypt_find_op *);
- +
- +static int cryptodev_cb(void *);
- +static int cryptodev_open(struct inode *inode, struct file *filp);
- +
- +/*
- + * Check a crypto identifier to see if it requested
- + * a valid crid and it's capabilities match.
- + */
- +static int
- +checkcrid(int crid)
- +{
- + int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
- + int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
- + int caps = 0;
- +
- + /* if the user hasn't selected a driver, then just call newsession */
- + if (hid == 0 && typ != 0)
- + return 0;
- +
- + caps = crypto_getcaps(hid);
- +
- + /* didn't find anything with capabilities */
- + if (caps == 0) {
- + dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
- + return EINVAL;
- + }
- +
- + /* the user didn't specify SW or HW, so the driver is ok */
- + if (typ == 0)
- + return 0;
- +
- + /* if the type specified didn't match */
- + if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
- + dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
- + hid, typ, caps);
- + return EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +static int
- +cryptodev_op(struct csession *cse, struct crypt_op *cop)
- +{
- + struct cryptop *crp = NULL;
- + struct cryptodesc *crde = NULL, *crda = NULL;
- + int error = 0;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (cop->len > CRYPTO_MAX_DATA_LEN) {
- + dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
- + return (E2BIG);
- + }
- +
- + if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
- + dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
- + cop->len);
- + return (EINVAL);
- + }
- +
- + cse->uio.uio_iov = &cse->iovec;
- + cse->uio.uio_iovcnt = 1;
- + cse->uio.uio_offset = 0;
- +#if 0
- + cse->uio.uio_resid = cop->len;
- + cse->uio.uio_segflg = UIO_SYSSPACE;
- + cse->uio.uio_rw = UIO_WRITE;
- + cse->uio.uio_td = td;
- +#endif
- + cse->uio.uio_iov[0].iov_len = cop->len;
- + if (cse->info.authsize)
- + cse->uio.uio_iov[0].iov_len += cse->info.authsize;
- + cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
- + GFP_KERNEL);
- +
- + if (cse->uio.uio_iov[0].iov_base == NULL) {
- + dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
- + (int)cse->uio.uio_iov[0].iov_len);
- + return (ENOMEM);
- + }
- +
- + crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
- + if (crp == NULL) {
- + dprintk("%s: ENOMEM\n", __FUNCTION__);
- + error = ENOMEM;
- + goto bail;
- + }
- +
- + if (cse->info.authsize && cse->info.blocksize) {
- + if (cop->op == COP_ENCRYPT) {
- + crde = crp->crp_desc;
- + crda = crde->crd_next;
- + } else {
- + crda = crp->crp_desc;
- + crde = crda->crd_next;
- + }
- + } else if (cse->info.authsize) {
- + crda = crp->crp_desc;
- + } else if (cse->info.blocksize) {
- + crde = crp->crp_desc;
- + } else {
- + dprintk("%s: bad request\n", __FUNCTION__);
- + error = EINVAL;
- + goto bail;
- + }
- +
- + if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
- + cop->len))) {
- + dprintk("%s: bad copy\n", __FUNCTION__);
- + goto bail;
- + }
- +
- + if (crda) {
- + crda->crd_skip = 0;
- + crda->crd_len = cop->len;
- + crda->crd_inject = cop->len;
- +
- + crda->crd_alg = cse->mac;
- + crda->crd_key = cse->mackey;
- + crda->crd_klen = cse->mackeylen * 8;
- + }
- +
- + if (crde) {
- + if (cop->op == COP_ENCRYPT)
- + crde->crd_flags |= CRD_F_ENCRYPT;
- + else
- + crde->crd_flags &= ~CRD_F_ENCRYPT;
- + crde->crd_len = cop->len;
- + crde->crd_inject = 0;
- +
- + crde->crd_alg = cse->cipher;
- + crde->crd_key = cse->key;
- + crde->crd_klen = cse->keylen * 8;
- + }
- +
- + crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
- + crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
- + | (cop->flags & COP_F_BATCH);
- + crp->crp_buf = (caddr_t)&cse->uio;
- + crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
- + crp->crp_sid = cse->sid;
- + crp->crp_opaque = (void *)cse;
- +
- + if (cop->iv) {
- + if (crde == NULL) {
- + error = EINVAL;
- + dprintk("%s no crde\n", __FUNCTION__);
- + goto bail;
- + }
- + if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
- + error = EINVAL;
- + dprintk("%s arc4 with IV\n", __FUNCTION__);
- + goto bail;
- + }
- + if ((error = copy_from_user(cse->tmp_iv, cop->iv,
- + cse->info.blocksize))) {
- + dprintk("%s bad iv copy\n", __FUNCTION__);
- + goto bail;
- + }
- + memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
- + crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
- + crde->crd_skip = 0;
- + } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
- + crde->crd_skip = 0;
- + } else if (crde) {
- + crde->crd_flags |= CRD_F_IV_PRESENT;
- + crde->crd_skip = cse->info.blocksize;
- + crde->crd_len -= cse->info.blocksize;
- + }
- +
- + if (cop->mac && crda == NULL) {
- + error = EINVAL;
- + dprintk("%s no crda\n", __FUNCTION__);
- + goto bail;
- + }
- +
- + /*
- + * Let the dispatch run unlocked, then, interlock against the
- + * callback before checking if the operation completed and going
- + * to sleep. This insures drivers don't inherit our lock which
- + * results in a lock order reversal between crypto_dispatch forced
- + * entry and the crypto_done callback into us.
- + */
- + error = crypto_dispatch(crp);
- + if (error) {
- + dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
- + goto bail;
- + }
- +
- + dprintk("%s about to WAIT\n", __FUNCTION__);
- + /*
- + * we really need to wait for driver to complete to maintain
- + * state, luckily interrupts will be remembered
- + */
- + do {
- + error = wait_event_interruptible(crp->crp_waitq,
- + ((crp->crp_flags & CRYPTO_F_DONE) != 0));
- + /*
- + * we can't break out of this loop or we will leave behind
- + * a huge mess, however, staying here means if your driver
- + * is broken user applications can hang and not be killed.
- + * The solution, fix your driver :-)
- + */
- + if (error) {
- + schedule();
- + error = 0;
- + }
- + } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
- + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
- +
- + if (crp->crp_etype != 0) {
- + error = crp->crp_etype;
- + dprintk("%s error in crp processing\n", __FUNCTION__);
- + goto bail;
- + }
- +
- + if (cse->error) {
- + error = cse->error;
- + dprintk("%s error in cse processing\n", __FUNCTION__);
- + goto bail;
- + }
- +
- + if (cop->dst && (error = copy_to_user(cop->dst,
- + cse->uio.uio_iov[0].iov_base, cop->len))) {
- + dprintk("%s bad dst copy\n", __FUNCTION__);
- + goto bail;
- + }
- +
- + if (cop->mac &&
- + (error=copy_to_user(cop->mac,
- + (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
- + cse->info.authsize))) {
- + dprintk("%s bad mac copy\n", __FUNCTION__);
- + goto bail;
- + }
- +
- +bail:
- + if (crp)
- + crypto_freereq(crp);
- + if (cse->uio.uio_iov[0].iov_base)
- + kfree(cse->uio.uio_iov[0].iov_base);
- +
- + return (error);
- +}
- +
- +static int
- +cryptodev_cb(void *op)
- +{
- + struct cryptop *crp = (struct cryptop *) op;
- + struct csession *cse = (struct csession *)crp->crp_opaque;
- + int error;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + error = crp->crp_etype;
- + if (error == EAGAIN) {
- + crp->crp_flags &= ~CRYPTO_F_DONE;
- +#ifdef NOTYET
- + /*
- + * DAVIDM I am fairly sure that we should turn this into a batch
- + * request to stop bad karma/lockup, revisit
- + */
- + crp->crp_flags |= CRYPTO_F_BATCH;
- +#endif
- + return crypto_dispatch(crp);
- + }
- + if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
- + cse->error = error;
- + wake_up_interruptible(&crp->crp_waitq);
- + }
- + return (0);
- +}
- +
- +static int
- +cryptodevkey_cb(void *op)
- +{
- + struct cryptkop *krp = (struct cryptkop *) op;
- + dprintk("%s()\n", __FUNCTION__);
- + wake_up_interruptible(&krp->krp_waitq);
- + return (0);
- +}
- +
- +static int
- +cryptodev_key(struct crypt_kop *kop)
- +{
- + struct cryptkop *krp = NULL;
- + int error = EINVAL;
- + int in, out, size, i;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
- + dprintk("%s params too big\n", __FUNCTION__);
- + return (EFBIG);
- + }
- +
- + in = kop->crk_iparams;
- + out = kop->crk_oparams;
- + switch (kop->crk_op) {
- + case CRK_MOD_EXP:
- + if (in == 3 && out == 1)
- + break;
- + return (EINVAL);
- + case CRK_MOD_EXP_CRT:
- + if (in == 6 && out == 1)
- + break;
- + return (EINVAL);
- + case CRK_DSA_SIGN:
- + if (in == 5 && out == 2)
- + break;
- + return (EINVAL);
- + case CRK_DSA_VERIFY:
- + if (in == 7 && out == 0)
- + break;
- + return (EINVAL);
- + case CRK_DH_COMPUTE_KEY:
- + if (in == 3 && out == 1)
- + break;
- + return (EINVAL);
- + default:
- + return (EINVAL);
- + }
- +
- + krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
- + if (!krp)
- + return (ENOMEM);
- + bzero(krp, sizeof *krp);
- + krp->krp_op = kop->crk_op;
- + krp->krp_status = kop->crk_status;
- + krp->krp_iparams = kop->crk_iparams;
- + krp->krp_oparams = kop->crk_oparams;
- + krp->krp_crid = kop->crk_crid;
- + krp->krp_status = 0;
- + krp->krp_flags = CRYPTO_KF_CBIMM;
- + krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
- + init_waitqueue_head(&krp->krp_waitq);
- +
- + for (i = 0; i < CRK_MAXPARAM; i++)
- + krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
- + for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
- + size = (krp->krp_param[i].crp_nbits + 7) / 8;
- + if (size == 0)
- + continue;
- + krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
- + if (i >= krp->krp_iparams)
- + continue;
- + error = copy_from_user(krp->krp_param[i].crp_p,
- + kop->crk_param[i].crp_p, size);
- + if (error)
- + goto fail;
- + }
- +
- + error = crypto_kdispatch(krp);
- + if (error)
- + goto fail;
- +
- + do {
- + error = wait_event_interruptible(krp->krp_waitq,
- + ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
- + /*
- + * we can't break out of this loop or we will leave behind
- + * a huge mess, however, staying here means if your driver
- + * is broken user applications can hang and not be killed.
- + * The solution, fix your driver :-)
- + */
- + if (error) {
- + schedule();
- + error = 0;
- + }
- + } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
- +
- + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
- +
- + kop->crk_crid = krp->krp_crid; /* device that did the work */
- + if (krp->krp_status != 0) {
- + error = krp->krp_status;
- + goto fail;
- + }
- +
- + for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
- + size = (krp->krp_param[i].crp_nbits + 7) / 8;
- + if (size == 0)
- + continue;
- + error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
- + size);
- + if (error)
- + goto fail;
- + }
- +
- +fail:
- + if (krp) {
- + kop->crk_status = krp->krp_status;
- + for (i = 0; i < CRK_MAXPARAM; i++) {
- + if (krp->krp_param[i].crp_p)
- + kfree(krp->krp_param[i].crp_p);
- + }
- + kfree(krp);
- + }
- + return (error);
- +}
- +
- +static int
- +cryptodev_find(struct crypt_find_op *find)
- +{
- + device_t dev;
- +
- + if (find->crid != -1) {
- + dev = crypto_find_device_byhid(find->crid);
- + if (dev == NULL)
- + return (ENOENT);
- + strlcpy(find->name, device_get_nameunit(dev),
- + sizeof(find->name));
- + } else {
- + find->crid = crypto_find_driver(find->name);
- + if (find->crid == -1)
- + return (ENOENT);
- + }
- + return (0);
- +}
- +
- +static struct csession *
- +csefind(struct fcrypt *fcr, u_int ses)
- +{
- + struct csession *cse;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + list_for_each_entry(cse, &fcr->csessions, list)
- + if (cse->ses == ses)
- + return (cse);
- + return (NULL);
- +}
- +
- +static int
- +csedelete(struct fcrypt *fcr, struct csession *cse_del)
- +{
- + struct csession *cse;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + list_for_each_entry(cse, &fcr->csessions, list) {
- + if (cse == cse_del) {
- + list_del(&cse->list);
- + return (1);
- + }
- + }
- + return (0);
- +}
- +
- +static struct csession *
- +cseadd(struct fcrypt *fcr, struct csession *cse)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + list_add_tail(&cse->list, &fcr->csessions);
- + cse->ses = fcr->sesn++;
- + return (cse);
- +}
- +
- +static struct csession *
- +csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
- + struct cryptoini *cria, struct csession_info *info)
- +{
- + struct csession *cse;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
- + if (cse == NULL)
- + return NULL;
- + memset(cse, 0, sizeof(struct csession));
- +
- + INIT_LIST_HEAD(&cse->list);
- + init_waitqueue_head(&cse->waitq);
- +
- + cse->key = crie->cri_key;
- + cse->keylen = crie->cri_klen/8;
- + cse->mackey = cria->cri_key;
- + cse->mackeylen = cria->cri_klen/8;
- + cse->sid = sid;
- + cse->cipher = crie->cri_alg;
- + cse->mac = cria->cri_alg;
- + cse->info = *info;
- + cseadd(fcr, cse);
- + return (cse);
- +}
- +
- +static int
- +csefree(struct csession *cse)
- +{
- + int error;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + error = crypto_freesession(cse->sid);
- + if (cse->key)
- + kfree(cse->key);
- + if (cse->mackey)
- + kfree(cse->mackey);
- + kfree(cse);
- + return(error);
- +}
- +
- +static int
- +cryptodev_ioctl(
- + struct inode *inode,
- + struct file *filp,
- + unsigned int cmd,
- + unsigned long arg)
- +{
- + struct cryptoini cria, crie;
- + struct fcrypt *fcr = filp->private_data;
- + struct csession *cse;
- + struct csession_info info;
- + struct session2_op sop;
- + struct crypt_op cop;
- + struct crypt_kop kop;
- + struct crypt_find_op fop;
- + u_int64_t sid;
- + u_int32_t ses = 0;
- + int feat, fd, error = 0, crid;
- + mm_segment_t fs;
- +
- + dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
- +
- + switch (cmd) {
- +
- + case CRIOGET: {
- + dprintk("%s(CRIOGET)\n", __FUNCTION__);
- + fs = get_fs();
- + set_fs(get_ds());
- + for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
- + if (files_fdtable(current->files)->fd[fd] == filp)
- + break;
- + fd = sys_dup(fd);
- + set_fs(fs);
- + put_user(fd, (int *) arg);
- + return IS_ERR_VALUE(fd) ? fd : 0;
- + }
- +
- +#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
- + case CIOCGSESSION:
- + case CIOCGSESSION2:
- + dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
- + memset(&crie, 0, sizeof(crie));
- + memset(&cria, 0, sizeof(cria));
- + memset(&info, 0, sizeof(info));
- + memset(&sop, 0, sizeof(sop));
- +
- + if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
- + sizeof(struct session_op) : sizeof(sop))) {
- + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
- + error = EFAULT;
- + goto bail;
- + }
- +
- + switch (sop.cipher) {
- + case 0:
- + dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
- + break;
- + case CRYPTO_NULL_CBC:
- + info.blocksize = NULL_BLOCK_LEN;
- + info.minkey = NULL_MIN_KEY_LEN;
- + info.maxkey = NULL_MAX_KEY_LEN;
- + break;
- + case CRYPTO_DES_CBC:
- + info.blocksize = DES_BLOCK_LEN;
- + info.minkey = DES_MIN_KEY_LEN;
- + info.maxkey = DES_MAX_KEY_LEN;
- + break;
- + case CRYPTO_3DES_CBC:
- + info.blocksize = DES3_BLOCK_LEN;
- + info.minkey = DES3_MIN_KEY_LEN;
- + info.maxkey = DES3_MAX_KEY_LEN;
- + break;
- + case CRYPTO_BLF_CBC:
- + info.blocksize = BLOWFISH_BLOCK_LEN;
- + info.minkey = BLOWFISH_MIN_KEY_LEN;
- + info.maxkey = BLOWFISH_MAX_KEY_LEN;
- + break;
- + case CRYPTO_CAST_CBC:
- + info.blocksize = CAST128_BLOCK_LEN;
- + info.minkey = CAST128_MIN_KEY_LEN;
- + info.maxkey = CAST128_MAX_KEY_LEN;
- + break;
- + case CRYPTO_SKIPJACK_CBC:
- + info.blocksize = SKIPJACK_BLOCK_LEN;
- + info.minkey = SKIPJACK_MIN_KEY_LEN;
- + info.maxkey = SKIPJACK_MAX_KEY_LEN;
- + break;
- + case CRYPTO_AES_CBC:
- + info.blocksize = AES_BLOCK_LEN;
- + info.minkey = AES_MIN_KEY_LEN;
- + info.maxkey = AES_MAX_KEY_LEN;
- + break;
- + case CRYPTO_ARC4:
- + info.blocksize = ARC4_BLOCK_LEN;
- + info.minkey = ARC4_MIN_KEY_LEN;
- + info.maxkey = ARC4_MAX_KEY_LEN;
- + break;
- + case CRYPTO_CAMELLIA_CBC:
- + info.blocksize = CAMELLIA_BLOCK_LEN;
- + info.minkey = CAMELLIA_MIN_KEY_LEN;
- + info.maxkey = CAMELLIA_MAX_KEY_LEN;
- + break;
- + default:
- + dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
- + error = EINVAL;
- + goto bail;
- + }
- +
- + switch (sop.mac) {
- + case 0:
- + dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
- + break;
- + case CRYPTO_NULL_HMAC:
- + info.authsize = NULL_HASH_LEN;
- + break;
- + case CRYPTO_MD5:
- + info.authsize = MD5_HASH_LEN;
- + break;
- + case CRYPTO_SHA1:
- + info.authsize = SHA1_HASH_LEN;
- + break;
- + case CRYPTO_SHA2_256:
- + info.authsize = SHA2_256_HASH_LEN;
- + break;
- + case CRYPTO_SHA2_384:
- + info.authsize = SHA2_384_HASH_LEN;
- + break;
- + case CRYPTO_SHA2_512:
- + info.authsize = SHA2_512_HASH_LEN;
- + break;
- + case CRYPTO_RIPEMD160:
- + info.authsize = RIPEMD160_HASH_LEN;
- + break;
- + case CRYPTO_MD5_HMAC:
- + info.authsize = MD5_HASH_LEN;
- + info.authkey = 16;
- + break;
- + case CRYPTO_SHA1_HMAC:
- + info.authsize = SHA1_HASH_LEN;
- + info.authkey = 20;
- + break;
- + case CRYPTO_SHA2_256_HMAC:
- + info.authsize = SHA2_256_HASH_LEN;
- + info.authkey = 32;
- + break;
- + case CRYPTO_SHA2_384_HMAC:
- + info.authsize = SHA2_384_HASH_LEN;
- + info.authkey = 48;
- + break;
- + case CRYPTO_SHA2_512_HMAC:
- + info.authsize = SHA2_512_HASH_LEN;
- + info.authkey = 64;
- + break;
- + case CRYPTO_RIPEMD160_HMAC:
- + info.authsize = RIPEMD160_HASH_LEN;
- + info.authkey = 20;
- + break;
- + default:
- + dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
- + error = EINVAL;
- + goto bail;
- + }
- +
- + if (info.blocksize) {
- + crie.cri_alg = sop.cipher;
- + crie.cri_klen = sop.keylen * 8;
- + if ((info.maxkey && sop.keylen > info.maxkey) ||
- + sop.keylen < info.minkey) {
- + dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
- + error = EINVAL;
- + goto bail;
- + }
- +
- + crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
- + if (copy_from_user(crie.cri_key, sop.key,
- + crie.cri_klen/8)) {
- + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
- + error = EFAULT;
- + goto bail;
- + }
- + if (info.authsize)
- + crie.cri_next = &cria;
- + }
- +
- + if (info.authsize) {
- + cria.cri_alg = sop.mac;
- + cria.cri_klen = sop.mackeylen * 8;
- + if (info.authkey && sop.mackeylen != info.authkey) {
- + dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
- + CIOCGSESSSTR, sop.mackeylen, info.authkey);
- + error = EINVAL;
- + goto bail;
- + }
- +
- + if (cria.cri_klen) {
- + cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
- + if (copy_from_user(cria.cri_key, sop.mackey,
- + cria.cri_klen / 8)) {
- + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
- + error = EFAULT;
- + goto bail;
- + }
- + }
- + }
- +
- + /* NB: CIOGSESSION2 has the crid */
- + if (cmd == CIOCGSESSION2) {
- + crid = sop.crid;
- + error = checkcrid(crid);
- + if (error) {
- + dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
- + CIOCGSESSSTR, error);
- + goto bail;
- + }
- + } else {
- + /* allow either HW or SW to be used */
- + crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
- + }
- + error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
- + if (error) {
- + dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
- + goto bail;
- + }
- +
- + cse = csecreate(fcr, sid, &crie, &cria, &info);
- + if (cse == NULL) {
- + crypto_freesession(sid);
- + error = EINVAL;
- + dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
- + goto bail;
- + }
- + sop.ses = cse->ses;
- +
- + if (cmd == CIOCGSESSION2) {
- + /* return hardware/driver id */
- + sop.crid = CRYPTO_SESID2HID(cse->sid);
- + }
- +
- + if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
- + sizeof(struct session_op) : sizeof(sop))) {
- + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
- + error = EFAULT;
- + }
- +bail:
- + if (error) {
- + dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
- + if (crie.cri_key)
- + kfree(crie.cri_key);
- + if (cria.cri_key)
- + kfree(cria.cri_key);
- + }
- + break;
- + case CIOCFSESSION:
- + dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
- + get_user(ses, (uint32_t*)arg);
- + cse = csefind(fcr, ses);
- + if (cse == NULL) {
- + error = EINVAL;
- + dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
- + break;
- + }
- + csedelete(fcr, cse);
- + error = csefree(cse);
- + break;
- + case CIOCCRYPT:
- + dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
- + if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
- + dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
- + error = EFAULT;
- + goto bail;
- + }
- + cse = csefind(fcr, cop.ses);
- + if (cse == NULL) {
- + error = EINVAL;
- + dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
- + break;
- + }
- + error = cryptodev_op(cse, &cop);
- + if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
- + dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
- + error = EFAULT;
- + goto bail;
- + }
- + break;
- + case CIOCKEY:
- + case CIOCKEY2:
- + dprintk("%s(CIOCKEY)\n", __FUNCTION__);
- + if (!crypto_userasymcrypto)
- + return (EPERM); /* XXX compat? */
- + if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
- + dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
- + error = EFAULT;
- + goto bail;
- + }
- + if (cmd == CIOCKEY) {
- + /* NB: crypto core enforces s/w driver use */
- + kop.crk_crid =
- + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
- + }
- + error = cryptodev_key(&kop);
- + if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
- + dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
- + error = EFAULT;
- + goto bail;
- + }
- + break;
- + case CIOCASYMFEAT:
- + dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
- + if (!crypto_userasymcrypto) {
- + /*
- + * NB: if user asym crypto operations are
- + * not permitted return "no algorithms"
- + * so well-behaved applications will just
- + * fallback to doing them in software.
- + */
- + feat = 0;
- + } else
- + error = crypto_getfeat(&feat);
- + if (!error) {
- + error = copy_to_user((void*)arg, &feat, sizeof(feat));
- + }
- + break;
- + case CIOCFINDDEV:
- + if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
- + dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
- + error = EFAULT;
- + goto bail;
- + }
- + error = cryptodev_find(&fop);
- + if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
- + dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
- + error = EFAULT;
- + goto bail;
- + }
- + break;
- + default:
- + dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
- + error = EINVAL;
- + break;
- + }
- + return(-error);
- +}
- +
- +#ifdef HAVE_UNLOCKED_IOCTL
- +static long
- +cryptodev_unlocked_ioctl(
- + struct file *filp,
- + unsigned int cmd,
- + unsigned long arg)
- +{
- + return cryptodev_ioctl(NULL, filp, cmd, arg);
- +}
- +#endif
- +
- +static int
- +cryptodev_open(struct inode *inode, struct file *filp)
- +{
- + struct fcrypt *fcr;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (filp->private_data) {
- + printk("cryptodev: Private data already exists !\n");
- + return(0);
- + }
- +
- + fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
- + if (!fcr) {
- + dprintk("%s() - malloc failed\n", __FUNCTION__);
- + return(-ENOMEM);
- + }
- + memset(fcr, 0, sizeof(*fcr));
- +
- + INIT_LIST_HEAD(&fcr->csessions);
- + filp->private_data = fcr;
- + return(0);
- +}
- +
- +static int
- +cryptodev_release(struct inode *inode, struct file *filp)
- +{
- + struct fcrypt *fcr = filp->private_data;
- + struct csession *cse, *tmp;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (!filp) {
- + printk("cryptodev: No private data on release\n");
- + return(0);
- + }
- +
- + list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
- + list_del(&cse->list);
- + (void)csefree(cse);
- + }
- + filp->private_data = NULL;
- + kfree(fcr);
- + return(0);
- +}
- +
- +static struct file_operations cryptodev_fops = {
- + .owner = THIS_MODULE,
- + .open = cryptodev_open,
- + .release = cryptodev_release,
- +#ifdef HAVE_UNLOCKED_IOCTL
- + .unlocked_ioctl = cryptodev_unlocked_ioctl,
- +#endif
- +};
- +
- +static struct miscdevice cryptodev = {
- + .minor = CRYPTODEV_MINOR,
- + .name = "crypto",
- + .fops = &cryptodev_fops,
- +};
- +
- +static int __init
- +cryptodev_init(void)
- +{
- + int rc;
- +
- + dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
- + rc = misc_register(&cryptodev);
- + if (rc) {
- + printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
- + return(rc);
- + }
- +
- + return(0);
- +}
- +
- +static void __exit
- +cryptodev_exit(void)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + misc_deregister(&cryptodev);
- +}
- +
- +module_init(cryptodev_init);
- +module_exit(cryptodev_exit);
- +
- +MODULE_LICENSE("BSD");
- +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
- +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
- diff -Nur linux-2.6.36.orig/crypto/ocf/cryptodev.h linux-2.6.36/crypto/ocf/cryptodev.h
- --- linux-2.6.36.orig/crypto/ocf/cryptodev.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/cryptodev.h 2010-11-09 20:28:04.492495480 +0100
- @@ -0,0 +1,479 @@
- +/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
- +/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
- +
- +/*-
- + * Linux port done by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + * The license and original author are listed below.
- + *
- + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
- + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
- + *
- + * This code was written by Angelos D. Keromytis in Athens, Greece, in
- + * February 2000. Network Security Technologies Inc. (NSTI) kindly
- + * supported the development of this code.
- + *
- + * Copyright (c) 2000 Angelos D. Keromytis
- + *
- + * Permission to use, copy, and modify this software with or without fee
- + * is hereby granted, provided that this entire notice is included in
- + * all source code copies of any software which is or includes a copy or
- + * modification of this software.
- + *
- + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
- + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
- + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
- + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
- + * PURPOSE.
- + *
- + * Copyright (c) 2001 Theo de Raadt
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored in part by the Defense Advanced Research Projects
- + * Agency (DARPA) and Air Force Research Laboratory, Air Force
- + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- + *
- + */
- +
- +#ifndef _CRYPTO_CRYPTO_H_
- +#define _CRYPTO_CRYPTO_H_
- +
- +/* Some initial values */
- +#define CRYPTO_DRIVERS_INITIAL 4
- +#define CRYPTO_SW_SESSIONS 32
- +
- +/* Hash values */
- +#define NULL_HASH_LEN 0
- +#define MD5_HASH_LEN 16
- +#define SHA1_HASH_LEN 20
- +#define RIPEMD160_HASH_LEN 20
- +#define SHA2_256_HASH_LEN 32
- +#define SHA2_384_HASH_LEN 48
- +#define SHA2_512_HASH_LEN 64
- +#define MD5_KPDK_HASH_LEN 16
- +#define SHA1_KPDK_HASH_LEN 20
- +/* Maximum hash algorithm result length */
- +#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
- +
- +/* HMAC values */
- +#define NULL_HMAC_BLOCK_LEN 1
- +#define MD5_HMAC_BLOCK_LEN 64
- +#define SHA1_HMAC_BLOCK_LEN 64
- +#define RIPEMD160_HMAC_BLOCK_LEN 64
- +#define SHA2_256_HMAC_BLOCK_LEN 64
- +#define SHA2_384_HMAC_BLOCK_LEN 128
- +#define SHA2_512_HMAC_BLOCK_LEN 128
- +/* Maximum HMAC block length */
- +#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
- +#define HMAC_IPAD_VAL 0x36
- +#define HMAC_OPAD_VAL 0x5C
- +
- +/* Encryption algorithm block sizes */
- +#define NULL_BLOCK_LEN 1
- +#define DES_BLOCK_LEN 8
- +#define DES3_BLOCK_LEN 8
- +#define BLOWFISH_BLOCK_LEN 8
- +#define SKIPJACK_BLOCK_LEN 8
- +#define CAST128_BLOCK_LEN 8
- +#define RIJNDAEL128_BLOCK_LEN 16
- +#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
- +#define CAMELLIA_BLOCK_LEN 16
- +#define ARC4_BLOCK_LEN 1
- +#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
- +
- +/* Encryption algorithm min and max key sizes */
- +#define NULL_MIN_KEY_LEN 0
- +#define NULL_MAX_KEY_LEN 0
- +#define DES_MIN_KEY_LEN 8
- +#define DES_MAX_KEY_LEN 8
- +#define DES3_MIN_KEY_LEN 24
- +#define DES3_MAX_KEY_LEN 24
- +#define BLOWFISH_MIN_KEY_LEN 4
- +#define BLOWFISH_MAX_KEY_LEN 56
- +#define SKIPJACK_MIN_KEY_LEN 10
- +#define SKIPJACK_MAX_KEY_LEN 10
- +#define CAST128_MIN_KEY_LEN 5
- +#define CAST128_MAX_KEY_LEN 16
- +#define RIJNDAEL128_MIN_KEY_LEN 16
- +#define RIJNDAEL128_MAX_KEY_LEN 32
- +#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
- +#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
- +#define CAMELLIA_MIN_KEY_LEN 16
- +#define CAMELLIA_MAX_KEY_LEN 32
- +#define ARC4_MIN_KEY_LEN 1
- +#define ARC4_MAX_KEY_LEN 256
- +
- +/* Max size of data that can be processed */
- +#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
- +
- +#define CRYPTO_ALGORITHM_MIN 1
- +#define CRYPTO_DES_CBC 1
- +#define CRYPTO_3DES_CBC 2
- +#define CRYPTO_BLF_CBC 3
- +#define CRYPTO_CAST_CBC 4
- +#define CRYPTO_SKIPJACK_CBC 5
- +#define CRYPTO_MD5_HMAC 6
- +#define CRYPTO_SHA1_HMAC 7
- +#define CRYPTO_RIPEMD160_HMAC 8
- +#define CRYPTO_MD5_KPDK 9
- +#define CRYPTO_SHA1_KPDK 10
- +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
- +#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
- +#define CRYPTO_ARC4 12
- +#define CRYPTO_MD5 13
- +#define CRYPTO_SHA1 14
- +#define CRYPTO_NULL_HMAC 15
- +#define CRYPTO_NULL_CBC 16
- +#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
- +#define CRYPTO_SHA2_256_HMAC 18
- +#define CRYPTO_SHA2_384_HMAC 19
- +#define CRYPTO_SHA2_512_HMAC 20
- +#define CRYPTO_CAMELLIA_CBC 21
- +#define CRYPTO_SHA2_256 22
- +#define CRYPTO_SHA2_384 23
- +#define CRYPTO_SHA2_512 24
- +#define CRYPTO_RIPEMD160 25
- +#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
- +
- +/* Algorithm flags */
- +#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
- +#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
- +#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
- +
- +/*
- + * Crypto driver/device flags. They can set in the crid
- + * parameter when creating a session or submitting a key
- + * op to affect the device/driver assigned. If neither
- + * of these are specified then the crid is assumed to hold
- + * the driver id of an existing (and suitable) device that
- + * must be used to satisfy the request.
- + */
- +#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
- +#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
- +
- +/* NB: deprecated */
- +struct session_op {
- + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
- + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
- +
- + u_int32_t keylen; /* cipher key */
- + caddr_t key;
- + int mackeylen; /* mac key */
- + caddr_t mackey;
- +
- + u_int32_t ses; /* returns: session # */
- +};
- +
- +struct session2_op {
- + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
- + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
- +
- + u_int32_t keylen; /* cipher key */
- + caddr_t key;
- + int mackeylen; /* mac key */
- + caddr_t mackey;
- +
- + u_int32_t ses; /* returns: session # */
- + int crid; /* driver id + flags (rw) */
- + int pad[4]; /* for future expansion */
- +};
- +
- +struct crypt_op {
- + u_int32_t ses;
- + u_int16_t op; /* i.e. COP_ENCRYPT */
- +#define COP_NONE 0
- +#define COP_ENCRYPT 1
- +#define COP_DECRYPT 2
- + u_int16_t flags;
- +#define COP_F_BATCH 0x0008 /* Batch op if possible */
- + u_int len;
- + caddr_t src, dst; /* become iov[] inside kernel */
- + caddr_t mac; /* must be big enough for chosen MAC */
- + caddr_t iv;
- +};
- +
- +/*
- + * Parameters for looking up a crypto driver/device by
- + * device name or by id. The latter are returned for
- + * created sessions (crid) and completed key operations.
- + */
- +struct crypt_find_op {
- + int crid; /* driver id + flags */
- + char name[32]; /* device/driver name */
- +};
- +
- +/* bignum parameter, in packed bytes, ... */
- +struct crparam {
- + caddr_t crp_p;
- + u_int crp_nbits;
- +};
- +
- +#define CRK_MAXPARAM 8
- +
- +struct crypt_kop {
- + u_int crk_op; /* ie. CRK_MOD_EXP or other */
- + u_int crk_status; /* return status */
- + u_short crk_iparams; /* # of input parameters */
- + u_short crk_oparams; /* # of output parameters */
- + u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
- + struct crparam crk_param[CRK_MAXPARAM];
- +};
- +#define CRK_ALGORITM_MIN 0
- +#define CRK_MOD_EXP 0
- +#define CRK_MOD_EXP_CRT 1
- +#define CRK_DSA_SIGN 2
- +#define CRK_DSA_VERIFY 3
- +#define CRK_DH_COMPUTE_KEY 4
- +#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
- +
- +#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
- +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
- +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
- +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
- +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
- +
- +/*
- + * done against open of /dev/crypto, to get a cloned descriptor.
- + * Please use F_SETFD against the cloned descriptor.
- + */
- +#define CRIOGET _IOWR('c', 100, u_int32_t)
- +#define CRIOASYMFEAT CIOCASYMFEAT
- +#define CRIOFINDDEV CIOCFINDDEV
- +
- +/* the following are done against the cloned descriptor */
- +#define CIOCGSESSION _IOWR('c', 101, struct session_op)
- +#define CIOCFSESSION _IOW('c', 102, u_int32_t)
- +#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
- +#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
- +#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
- +#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
- +#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
- +#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
- +
- +struct cryptotstat {
- + struct timespec acc; /* total accumulated time */
- + struct timespec min; /* min time */
- + struct timespec max; /* max time */
- + u_int32_t count; /* number of observations */
- +};
- +
- +struct cryptostats {
- + u_int32_t cs_ops; /* symmetric crypto ops submitted */
- + u_int32_t cs_errs; /* symmetric crypto ops that failed */
- + u_int32_t cs_kops; /* asymetric/key ops submitted */
- + u_int32_t cs_kerrs; /* asymetric/key ops that failed */
- + u_int32_t cs_intrs; /* crypto swi thread activations */
- + u_int32_t cs_rets; /* crypto return thread activations */
- + u_int32_t cs_blocks; /* symmetric op driver block */
- + u_int32_t cs_kblocks; /* symmetric op driver block */
- + /*
- + * When CRYPTO_TIMING is defined at compile time and the
- + * sysctl debug.crypto is set to 1, the crypto system will
- + * accumulate statistics about how long it takes to process
- + * crypto requests at various points during processing.
- + */
- + struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
- + struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
- + struct cryptotstat cs_cb; /* crypto_done -> callback */
- + struct cryptotstat cs_finis; /* callback -> callback return */
- +
- + u_int32_t cs_drops; /* crypto ops dropped due to congestion */
- +};
- +
- +#ifdef __KERNEL__
- +
- +/* Standard initialization structure beginning */
- +struct cryptoini {
- + int cri_alg; /* Algorithm to use */
- + int cri_klen; /* Key length, in bits */
- + int cri_mlen; /* Number of bytes we want from the
- + entire hash. 0 means all. */
- + caddr_t cri_key; /* key to use */
- + u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
- + struct cryptoini *cri_next;
- +};
- +
- +/* Describe boundaries of a single crypto operation */
- +struct cryptodesc {
- + int crd_skip; /* How many bytes to ignore from start */
- + int crd_len; /* How many bytes to process */
- + int crd_inject; /* Where to inject results, if applicable */
- + int crd_flags;
- +
- +#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
- +#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
- + place, so don't copy. */
- +#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
- +#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
- +#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
- +#define CRD_F_COMP 0x0f /* Set when doing compression */
- +
- + struct cryptoini CRD_INI; /* Initialization/context data */
- +#define crd_iv CRD_INI.cri_iv
- +#define crd_key CRD_INI.cri_key
- +#define crd_alg CRD_INI.cri_alg
- +#define crd_klen CRD_INI.cri_klen
- +#define crd_mlen CRD_INI.cri_mlen
- +
- + struct cryptodesc *crd_next;
- +};
- +
- +/* Structure describing complete operation */
- +struct cryptop {
- + struct list_head crp_next;
- + wait_queue_head_t crp_waitq;
- +
- + u_int64_t crp_sid; /* Session ID */
- + int crp_ilen; /* Input data total length */
- + int crp_olen; /* Result total length */
- +
- + int crp_etype; /*
- + * Error type (zero means no error).
- + * All error codes except EAGAIN
- + * indicate possible data corruption (as in,
- + * the data have been touched). On all
- + * errors, the crp_sid may have changed
- + * (reset to a new one), so the caller
- + * should always check and use the new
- + * value on future requests.
- + */
- + int crp_flags;
- +
- +#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
- +#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
- +#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
- +#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
- +#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
- +#define CRYPTO_F_DONE 0x0020 /* Operation completed */
- +#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
- +
- + caddr_t crp_buf; /* Data to be processed */
- + caddr_t crp_opaque; /* Opaque pointer, passed along */
- + struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
- +
- + int (*crp_callback)(struct cryptop *); /* Callback function */
- +};
- +
- +#define CRYPTO_BUF_CONTIG 0x0
- +#define CRYPTO_BUF_IOV 0x1
- +#define CRYPTO_BUF_SKBUF 0x2
- +
- +#define CRYPTO_OP_DECRYPT 0x0
- +#define CRYPTO_OP_ENCRYPT 0x1
- +
- +/*
- + * Hints passed to process methods.
- + */
- +#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
- +
- +struct cryptkop {
- + struct list_head krp_next;
- + wait_queue_head_t krp_waitq;
- +
- + int krp_flags;
- +#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
- +#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
- +
- + u_int krp_op; /* ie. CRK_MOD_EXP or other */
- + u_int krp_status; /* return status */
- + u_short krp_iparams; /* # of input parameters */
- + u_short krp_oparams; /* # of output parameters */
- + u_int krp_crid; /* desired device, etc. */
- + u_int32_t krp_hid;
- + struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
- + int (*krp_callback)(struct cryptkop *);
- +};
- +
- +#include <ocf-compat.h>
- +
- +/*
- + * Session ids are 64 bits. The lower 32 bits contain a "local id" which
- + * is a driver-private session identifier. The upper 32 bits contain a
- + * "hardware id" used by the core crypto code to identify the driver and
- + * a copy of the driver's capabilities that can be used by client code to
- + * optimize operation.
- + */
- +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
- +#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
- +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
- +
- +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
- +extern int crypto_freesession(u_int64_t sid);
- +#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
- +#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
- +#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
- +extern int32_t crypto_get_driverid(device_t dev, int flags);
- +extern int crypto_find_driver(const char *);
- +extern device_t crypto_find_device_byhid(int hid);
- +extern int crypto_getcaps(int hid);
- +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
- + u_int32_t flags);
- +extern int crypto_kregister(u_int32_t, int, u_int32_t);
- +extern int crypto_unregister(u_int32_t driverid, int alg);
- +extern int crypto_unregister_all(u_int32_t driverid);
- +extern int crypto_dispatch(struct cryptop *crp);
- +extern int crypto_kdispatch(struct cryptkop *);
- +#define CRYPTO_SYMQ 0x1
- +#define CRYPTO_ASYMQ 0x2
- +extern int crypto_unblock(u_int32_t, int);
- +extern void crypto_done(struct cryptop *crp);
- +extern void crypto_kdone(struct cryptkop *);
- +extern int crypto_getfeat(int *);
- +
- +extern void crypto_freereq(struct cryptop *crp);
- +extern struct cryptop *crypto_getreq(int num);
- +
- +extern int crypto_usercrypto; /* userland may do crypto requests */
- +extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
- +extern int crypto_devallowsoft; /* only use hardware crypto */
- +
- +/*
- + * random number support, crypto_unregister_all will unregister
- + */
- +extern int crypto_rregister(u_int32_t driverid,
- + int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
- +extern int crypto_runregister_all(u_int32_t driverid);
- +
- +/*
- + * Crypto-related utility routines used mainly by drivers.
- + *
- + * XXX these don't really belong here; but for now they're
- + * kept apart from the rest of the system.
- + */
- +struct uio;
- +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
- +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
- +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
- +
- +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
- + caddr_t in);
- +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
- + caddr_t out);
- +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
- + int (*f)(void *, void *, u_int), void *arg);
- +
- +#endif /* __KERNEL__ */
- +#endif /* _CRYPTO_CRYPTO_H_ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/cryptosoft.c linux-2.6.36/crypto/ocf/cryptosoft.c
- --- linux-2.6.36.orig/crypto/ocf/cryptosoft.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/cryptosoft.c 2010-11-09 20:28:04.532495450 +0100
- @@ -0,0 +1,1210 @@
- +/*
- + * An OCF module that uses the linux kernel cryptoapi, based on the
- + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
- + * but is mostly unrecognisable,
- + *
- + * Written by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2004-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * ALTERNATIVELY, provided that this notice is retained in full, this product
- + * may be distributed under the terms of the GNU General Public License (GPL),
- + * in which case the provisions of the GPL apply INSTEAD OF those given above.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + * ---------------------------------------------------------------------------
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/sched.h>
- +#include <linux/wait.h>
- +#include <linux/crypto.h>
- +#include <linux/mm.h>
- +#include <linux/skbuff.h>
- +#include <linux/random.h>
- +#include <linux/version.h>
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
- +#include <linux/scatterlist.h>
- +#endif
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
- +#include <crypto/hash.h>
- +#endif
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +
- +struct {
- + softc_device_decl sc_dev;
- +} swcr_softc;
- +
- +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
- +
- +#define SW_TYPE_CIPHER 0x01
- +#define SW_TYPE_HMAC 0x02
- +#define SW_TYPE_HASH 0x04
- +#define SW_TYPE_COMP 0x08
- +#define SW_TYPE_BLKCIPHER 0x10
- +#define SW_TYPE_ALG_MASK 0x1f
- +
- +#define SW_TYPE_ASYNC 0x8000
- +
- +/* We change some of the above if we have an async interface */
- +
- +#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
- +
- +#define SW_TYPE_ABLKCIPHER (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
- +#define SW_TYPE_AHASH (SW_TYPE_HASH | SW_TYPE_ASYNC)
- +#define SW_TYPE_AHMAC (SW_TYPE_HMAC | SW_TYPE_ASYNC)
- +
- +#define SCATTERLIST_MAX 16
- +
- +struct swcr_data {
- + int sw_type;
- + int sw_alg;
- + struct crypto_tfm *sw_tfm;
- + union {
- + struct {
- + char *sw_key;
- + int sw_klen;
- + int sw_mlen;
- + } hmac;
- + void *sw_comp_buf;
- + } u;
- + struct swcr_data *sw_next;
- +};
- +
- +struct swcr_req {
- + struct swcr_data *sw_head;
- + struct swcr_data *sw;
- + struct cryptop *crp;
- + struct cryptodesc *crd;
- + struct scatterlist sg[SCATTERLIST_MAX];
- + unsigned char iv[EALG_MAX_BLOCK_LEN];
- + char result[HASH_MAX_LEN];
- + void *crypto_req;
- +};
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +static kmem_cache_t *swcr_req_cache;
- +#else
- +static struct kmem_cache *swcr_req_cache;
- +#endif
- +
- +#ifndef CRYPTO_TFM_MODE_CBC
- +/*
- + * As of linux-2.6.21 this is no longer defined, and presumably no longer
- + * needed to be passed into the crypto core code.
- + */
- +#define CRYPTO_TFM_MODE_CBC 0
- +#define CRYPTO_TFM_MODE_ECB 0
- +#endif
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
- + /*
- + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
- + * API into old API.
- + */
- +
- + /* Symmetric/Block Cipher */
- + struct blkcipher_desc
- + {
- + struct crypto_tfm *tfm;
- + void *info;
- + };
- + #define ecb(X) #X , CRYPTO_TFM_MODE_ECB
- + #define cbc(X) #X , CRYPTO_TFM_MODE_CBC
- + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
- + #define crypto_blkcipher_cast(X) X
- + #define crypto_blkcipher_tfm(X) X
- + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
- + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
- + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
- + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
- + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
- + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
- + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
- + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
- + #define crypto_blkcipher_set_flags(x, y) /* nop */
- +
- + /* Hash/HMAC/Digest */
- + struct hash_desc
- + {
- + struct crypto_tfm *tfm;
- + };
- + #define hmac(X) #X , 0
- + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
- + #define crypto_hash_cast(X) X
- + #define crypto_hash_tfm(X) X
- + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
- + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
- + #define crypto_hash_digest(W, X, Y, Z) \
- + crypto_digest_digest((W)->tfm, X, sg_num, Z)
- +
- + /* Asymmetric Cipher */
- + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
- +
- + /* Compression */
- + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
- + #define crypto_comp_tfm(X) X
- + #define crypto_comp_cast(X) X
- + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
- + #define plain(X) #X , 0
- +#else
- + #define ecb(X) "ecb(" #X ")" , 0
- + #define cbc(X) "cbc(" #X ")" , 0
- + #define hmac(X) "hmac(" #X ")" , 0
- + #define plain(X) #X , 0
- +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- +/* no ablkcipher in older kernels */
- +#define crypto_alloc_ablkcipher(a,b,c) (NULL)
- +#define crypto_ablkcipher_tfm(x) ((struct crypto_tfm *)(x))
- +#define crypto_ablkcipher_set_flags(a, b) /* nop */
- +#define crypto_ablkcipher_setkey(x, y, z) (-EINVAL)
- +#define crypto_has_ablkcipher(a,b,c) (0)
- +#else
- +#define HAVE_ABLKCIPHER
- +#endif
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
- +/* no ahash in older kernels */
- +#define crypto_ahash_tfm(x) ((struct crypto_tfm *)(x))
- +#define crypto_alloc_ahash(a,b,c) (NULL)
- +#define crypto_ahash_digestsize(x) 0
- +#else
- +#define HAVE_AHASH
- +#endif
- +
- +struct crypto_details {
- + char *alg_name;
- + int mode;
- + int sw_type;
- +};
- +
- +static struct crypto_details crypto_details[] = {
- + [CRYPTO_DES_CBC] = { cbc(des), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_3DES_CBC] = { cbc(des3_ede), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_BLF_CBC] = { cbc(blowfish), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_CAST_CBC] = { cbc(cast5), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_SKIPJACK_CBC] = { cbc(skipjack), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_MD5_HMAC] = { hmac(md5), SW_TYPE_HMAC, },
- + [CRYPTO_SHA1_HMAC] = { hmac(sha1), SW_TYPE_HMAC, },
- + [CRYPTO_RIPEMD160_HMAC] = { hmac(ripemd160), SW_TYPE_HMAC, },
- + [CRYPTO_MD5_KPDK] = { plain(md5-kpdk), SW_TYPE_HASH, },
- + [CRYPTO_SHA1_KPDK] = { plain(sha1-kpdk), SW_TYPE_HASH, },
- + [CRYPTO_AES_CBC] = { cbc(aes), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_ARC4] = { ecb(arc4), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_MD5] = { plain(md5), SW_TYPE_HASH, },
- + [CRYPTO_SHA1] = { plain(sha1), SW_TYPE_HASH, },
- + [CRYPTO_NULL_HMAC] = { hmac(digest_null), SW_TYPE_HMAC, },
- + [CRYPTO_NULL_CBC] = { cbc(cipher_null), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_DEFLATE_COMP] = { plain(deflate), SW_TYPE_COMP, },
- + [CRYPTO_SHA2_256_HMAC] = { hmac(sha256), SW_TYPE_HMAC, },
- + [CRYPTO_SHA2_384_HMAC] = { hmac(sha384), SW_TYPE_HMAC, },
- + [CRYPTO_SHA2_512_HMAC] = { hmac(sha512), SW_TYPE_HMAC, },
- + [CRYPTO_CAMELLIA_CBC] = { cbc(camellia), SW_TYPE_BLKCIPHER, },
- + [CRYPTO_SHA2_256] = { plain(sha256), SW_TYPE_HASH, },
- + [CRYPTO_SHA2_384] = { plain(sha384), SW_TYPE_HASH, },
- + [CRYPTO_SHA2_512] = { plain(sha512), SW_TYPE_HASH, },
- + [CRYPTO_RIPEMD160] = { plain(ripemd160), SW_TYPE_HASH, },
- +};
- +
- +int32_t swcr_id = -1;
- +module_param(swcr_id, int, 0444);
- +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
- +
- +int swcr_fail_if_compression_grows = 1;
- +module_param(swcr_fail_if_compression_grows, int, 0644);
- +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
- + "Treat compression that results in more data as a failure");
- +
- +int swcr_no_ahash = 0;
- +module_param(swcr_no_ahash, int, 0644);
- +MODULE_PARM_DESC(swcr_no_ahash,
- + "Do not use async hash/hmac even if available");
- +
- +int swcr_no_ablk = 0;
- +module_param(swcr_no_ablk, int, 0644);
- +MODULE_PARM_DESC(swcr_no_ablk,
- + "Do not use async blk ciphers even if available");
- +
- +static struct swcr_data **swcr_sessions = NULL;
- +static u_int32_t swcr_sesnum = 0;
- +
- +static int swcr_process(device_t, struct cryptop *, int);
- +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
- +static int swcr_freesession(device_t, u_int64_t);
- +
- +static device_method_t swcr_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, swcr_newsession),
- + DEVMETHOD(cryptodev_freesession,swcr_freesession),
- + DEVMETHOD(cryptodev_process, swcr_process),
- +};
- +
- +#define debug swcr_debug
- +int swcr_debug = 0;
- +module_param(swcr_debug, int, 0644);
- +MODULE_PARM_DESC(swcr_debug, "Enable debug");
- +
- +static void swcr_process_req(struct swcr_req *req);
- +
- +/*
- + * Generate a new software session.
- + */
- +static int
- +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
- +{
- + struct swcr_data **swd;
- + u_int32_t i;
- + int error;
- + char *algo;
- + int mode;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid == NULL || cri == NULL) {
- + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + if (swcr_sessions) {
- + for (i = 1; i < swcr_sesnum; i++)
- + if (swcr_sessions[i] == NULL)
- + break;
- + } else
- + i = 1; /* NB: to silence compiler warning */
- +
- + if (swcr_sessions == NULL || i == swcr_sesnum) {
- + if (swcr_sessions == NULL) {
- + i = 1; /* We leave swcr_sessions[0] empty */
- + swcr_sesnum = CRYPTO_SW_SESSIONS;
- + } else
- + swcr_sesnum *= 2;
- +
- + swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
- + if (swd == NULL) {
- + /* Reset session number */
- + if (swcr_sesnum == CRYPTO_SW_SESSIONS)
- + swcr_sesnum = 0;
- + else
- + swcr_sesnum /= 2;
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
- +
- + /* Copy existing sessions */
- + if (swcr_sessions) {
- + memcpy(swd, swcr_sessions,
- + (swcr_sesnum / 2) * sizeof(struct swcr_data *));
- + kfree(swcr_sessions);
- + }
- +
- + swcr_sessions = swd;
- + }
- +
- + swd = &swcr_sessions[i];
- + *sid = i;
- +
- + while (cri) {
- + *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
- + SLAB_ATOMIC);
- + if (*swd == NULL) {
- + swcr_freesession(NULL, i);
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memset(*swd, 0, sizeof(struct swcr_data));
- +
- + if (cri->cri_alg < 0 ||
- + cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
- + printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
- + swcr_freesession(NULL, i);
- + return EINVAL;
- + }
- +
- + algo = crypto_details[cri->cri_alg].alg_name;
- + if (!algo || !*algo) {
- + printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
- + swcr_freesession(NULL, i);
- + return EINVAL;
- + }
- +
- + mode = crypto_details[cri->cri_alg].mode;
- + (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
- + (*swd)->sw_alg = cri->cri_alg;
- +
- + /* Algorithm specific configuration */
- + switch (cri->cri_alg) {
- + case CRYPTO_NULL_CBC:
- + cri->cri_klen = 0; /* make it work with crypto API */
- + break;
- + default:
- + break;
- + }
- +
- + if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
- + dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
- + algo, mode);
- +
- + /* try async first */
- + (*swd)->sw_tfm = swcr_no_ablk ? NULL :
- + crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
- + if ((*swd)->sw_tfm) {
- + dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
- + (*swd)->sw_type |= SW_TYPE_ASYNC;
- + } else {
- + dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
- + (*swd)->sw_tfm = crypto_blkcipher_tfm(
- + crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
- + }
- + if (!(*swd)->sw_tfm) {
- + dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
- + algo,mode);
- + swcr_freesession(NULL, i);
- + return EINVAL;
- + }
- +
- + if (debug) {
- + dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
- + __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
- + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
- + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
- + cri->cri_key[i] & 0xff);
- + dprintk("\n");
- + }
- + if ((*swd)->sw_type & SW_TYPE_ASYNC) {
- + /* OCF doesn't enforce keys */
- + crypto_ablkcipher_set_flags(
- + __crypto_ablkcipher_cast((*swd)->sw_tfm),
- + CRYPTO_TFM_REQ_WEAK_KEY);
- + error = crypto_ablkcipher_setkey(
- + __crypto_ablkcipher_cast((*swd)->sw_tfm),
- + cri->cri_key, (cri->cri_klen + 7) / 8);
- + } else {
- + /* OCF doesn't enforce keys */
- + crypto_blkcipher_set_flags(
- + crypto_blkcipher_cast((*swd)->sw_tfm),
- + CRYPTO_TFM_REQ_WEAK_KEY);
- + error = crypto_blkcipher_setkey(
- + crypto_blkcipher_cast((*swd)->sw_tfm),
- + cri->cri_key, (cri->cri_klen + 7) / 8);
- + }
- + if (error) {
- + printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
- + (*swd)->sw_tfm->crt_flags);
- + swcr_freesession(NULL, i);
- + return error;
- + }
- + } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
- + dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
- + algo, mode);
- +
- + /* try async first */
- + (*swd)->sw_tfm = swcr_no_ahash ? NULL :
- + crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
- + if ((*swd)->sw_tfm) {
- + dprintk("%s %s hash is async\n", __FUNCTION__, algo);
- + (*swd)->sw_type |= SW_TYPE_ASYNC;
- + } else {
- + dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
- + (*swd)->sw_tfm = crypto_hash_tfm(
- + crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
- + }
- +
- + if (!(*swd)->sw_tfm) {
- + dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
- + algo, mode);
- + swcr_freesession(NULL, i);
- + return EINVAL;
- + }
- +
- + (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
- + (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
- + SLAB_ATOMIC);
- + if ((*swd)->u.hmac.sw_key == NULL) {
- + swcr_freesession(NULL, i);
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
- + if (cri->cri_mlen) {
- + (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
- + } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
- + (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
- + __crypto_ahash_cast((*swd)->sw_tfm));
- + } else {
- + (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
- + crypto_hash_cast((*swd)->sw_tfm));
- + }
- + } else if ((*swd)->sw_type & SW_TYPE_COMP) {
- + (*swd)->sw_tfm = crypto_comp_tfm(
- + crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
- + if (!(*swd)->sw_tfm) {
- + dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
- + algo, mode);
- + swcr_freesession(NULL, i);
- + return EINVAL;
- + }
- + (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
- + if ((*swd)->u.sw_comp_buf == NULL) {
- + swcr_freesession(NULL, i);
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + } else {
- + printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
- + swcr_freesession(NULL, i);
- + return EINVAL;
- + }
- +
- + cri = cri->cri_next;
- + swd = &((*swd)->sw_next);
- + }
- + return 0;
- +}
- +
- +/*
- + * Free a session.
- + */
- +static int
- +swcr_freesession(device_t dev, u_int64_t tid)
- +{
- + struct swcr_data *swd;
- + u_int32_t sid = CRYPTO_SESID2LID(tid);
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid > swcr_sesnum || swcr_sessions == NULL ||
- + swcr_sessions[sid] == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return(EINVAL);
- + }
- +
- + /* Silently accept and return */
- + if (sid == 0)
- + return(0);
- +
- + while ((swd = swcr_sessions[sid]) != NULL) {
- + swcr_sessions[sid] = swd->sw_next;
- + if (swd->sw_tfm) {
- + switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
- +#ifdef HAVE_AHASH
- + case SW_TYPE_AHMAC:
- + case SW_TYPE_AHASH:
- + crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
- + break;
- +#endif
- +#ifdef HAVE_ABLKCIPHER
- + case SW_TYPE_ABLKCIPHER:
- + crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
- + break;
- +#endif
- + case SW_TYPE_BLKCIPHER:
- + crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
- + break;
- + case SW_TYPE_HMAC:
- + case SW_TYPE_HASH:
- + crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
- + break;
- + case SW_TYPE_COMP:
- + crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
- + default:
- + crypto_free_tfm(swd->sw_tfm);
- + break;
- + }
- + swd->sw_tfm = NULL;
- + }
- + if (swd->sw_type & SW_TYPE_COMP) {
- + if (swd->u.sw_comp_buf)
- + kfree(swd->u.sw_comp_buf);
- + } else {
- + if (swd->u.hmac.sw_key)
- + kfree(swd->u.hmac.sw_key);
- + }
- + kfree(swd);
- + }
- + return 0;
- +}
- +
- +#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
- +/* older kernels had no async interface */
- +
- +static void swcr_process_callback(struct crypto_async_request *creq, int err)
- +{
- + struct swcr_req *req = creq->data;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (err) {
- + if (err == -EINPROGRESS)
- + return;
- + dprintk("%s() fail %d\n", __FUNCTION__, -err);
- + req->crp->crp_etype = -err;
- + goto done;
- + }
- +
- + switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
- + case SW_TYPE_AHMAC:
- + case SW_TYPE_AHASH:
- + crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
- + req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
- + ahash_request_free(req->crypto_req);
- + break;
- + case SW_TYPE_ABLKCIPHER:
- + ablkcipher_request_free(req->crypto_req);
- + break;
- + default:
- + req->crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + req->crd = req->crd->crd_next;
- + if (req->crd) {
- + swcr_process_req(req);
- + return;
- + }
- +
- +done:
- + dprintk("%s crypto_done %p\n", __FUNCTION__, req);
- + crypto_done(req->crp);
- + kmem_cache_free(swcr_req_cache, req);
- +}
- +#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
- +
- +
- +static void swcr_process_req(struct swcr_req *req)
- +{
- + struct swcr_data *sw;
- + struct cryptop *crp = req->crp;
- + struct cryptodesc *crd = req->crd;
- + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
- + struct uio *uiop = (struct uio *) crp->crp_buf;
- + int sg_num, sg_len, skip;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + /*
- + * Find the crypto context.
- + *
- + * XXX Note that the logic here prevents us from having
- + * XXX the same algorithm multiple times in a session
- + * XXX (or rather, we can but it won't give us the right
- + * XXX results). To do that, we'd need some way of differentiating
- + * XXX between the various instances of an algorithm (so we can
- + * XXX locate the correct crypto context).
- + */
- + for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
- + ;
- +
- + /* No such context ? */
- + if (sw == NULL) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + req->sw = sw;
- + skip = crd->crd_skip;
- +
- + /*
- + * setup the SG list skip from the start of the buffer
- + */
- + memset(req->sg, 0, sizeof(req->sg));
- + sg_init_table(req->sg, SCATTERLIST_MAX);
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + int i, len;
- +
- + sg_num = 0;
- + sg_len = 0;
- +
- + if (skip < skb_headlen(skb)) {
- + len = skb_headlen(skb) - skip;
- + if (len + sg_len > crd->crd_len)
- + len = crd->crd_len - sg_len;
- + sg_set_page(&req->sg[sg_num],
- + virt_to_page(skb->data + skip), len,
- + offset_in_page(skb->data + skip));
- + sg_len += len;
- + sg_num++;
- + skip = 0;
- + } else
- + skip -= skb_headlen(skb);
- +
- + for (i = 0; sg_len < crd->crd_len &&
- + i < skb_shinfo(skb)->nr_frags &&
- + sg_num < SCATTERLIST_MAX; i++) {
- + if (skip < skb_shinfo(skb)->frags[i].size) {
- + len = skb_shinfo(skb)->frags[i].size - skip;
- + if (len + sg_len > crd->crd_len)
- + len = crd->crd_len - sg_len;
- + sg_set_page(&req->sg[sg_num],
- + skb_shinfo(skb)->frags[i].page,
- + len,
- + skb_shinfo(skb)->frags[i].page_offset + skip);
- + sg_len += len;
- + sg_num++;
- + skip = 0;
- + } else
- + skip -= skb_shinfo(skb)->frags[i].size;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + int len;
- +
- + sg_len = 0;
- + for (sg_num = 0; sg_len < crd->crd_len &&
- + sg_num < uiop->uio_iovcnt &&
- + sg_num < SCATTERLIST_MAX; sg_num++) {
- + if (skip <= uiop->uio_iov[sg_num].iov_len) {
- + len = uiop->uio_iov[sg_num].iov_len - skip;
- + if (len + sg_len > crd->crd_len)
- + len = crd->crd_len - sg_len;
- + sg_set_page(&req->sg[sg_num],
- + virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
- + len,
- + offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
- + sg_len += len;
- + skip = 0;
- + } else
- + skip -= uiop->uio_iov[sg_num].iov_len;
- + }
- + } else {
- + sg_len = (crp->crp_ilen - skip);
- + if (sg_len > crd->crd_len)
- + sg_len = crd->crd_len;
- + sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
- + sg_len, offset_in_page(crp->crp_buf + skip));
- + sg_num = 1;
- + }
- +
- + switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
- +
- +#ifdef HAVE_AHASH
- + case SW_TYPE_AHMAC:
- + case SW_TYPE_AHASH:
- + {
- + int ret;
- +
- + /* check we have room for the result */
- + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
- + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
- + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
- + crd->crd_inject, sw->u.hmac.sw_mlen);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + req->crypto_req =
- + ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
- + if (!req->crypto_req) {
- + crp->crp_etype = ENOMEM;
- + dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + ahash_request_set_callback(req->crypto_req,
- + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
- +
- + memset(req->result, 0, sizeof(req->result));
- +
- + if (sw->sw_type & SW_TYPE_AHMAC)
- + crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
- + sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
- + ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
- + ret = crypto_ahash_digest(req->crypto_req);
- + switch (ret) {
- + case -EINPROGRESS:
- + case -EBUSY:
- + return;
- + default:
- + case 0:
- + dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
- + crp->crp_etype = ret;
- + ahash_request_free(req->crypto_req);
- + goto done;
- + }
- + } break;
- +#endif /* HAVE_AHASH */
- +
- +#ifdef HAVE_ABLKCIPHER
- + case SW_TYPE_ABLKCIPHER: {
- + int ret;
- + unsigned char *ivp = req->iv;
- + int ivsize =
- + crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
- +
- + if (sg_len < crypto_ablkcipher_blocksize(
- + __crypto_ablkcipher_cast(sw->sw_tfm))) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
- + sg_len, crypto_ablkcipher_blocksize(
- + __crypto_ablkcipher_cast(sw->sw_tfm)));
- + goto done;
- + }
- +
- + if (ivsize > sizeof(req->iv)) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + req->crypto_req = ablkcipher_request_alloc(
- + __crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
- + if (!req->crypto_req) {
- + crp->crp_etype = ENOMEM;
- + dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
- + __FILE__, __LINE__);
- + goto done;
- + }
- +
- + ablkcipher_request_set_callback(req->crypto_req,
- + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
- +
- + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
- + int i, error;
- +
- + if (debug) {
- + dprintk("%s key:", __FUNCTION__);
- + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
- + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
- + crd->crd_key[i] & 0xff);
- + dprintk("\n");
- + }
- + /* OCF doesn't enforce keys */
- + crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
- + CRYPTO_TFM_REQ_WEAK_KEY);
- + error = crypto_ablkcipher_setkey(
- + __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
- + (crd->crd_klen + 7) / 8);
- + if (error) {
- + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
- + error, sw->sw_tfm->crt_flags);
- + crp->crp_etype = -error;
- + }
- + }
- +
- + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
- +
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
- + ivp = crd->crd_iv;
- + else
- + get_random_bytes(ivp, ivsize);
- + /*
- + * do we have to copy the IV back to the buffer ?
- + */
- + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject, ivsize, (caddr_t)ivp);
- + }
- + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
- + sg_len, ivp);
- + ret = crypto_ablkcipher_encrypt(req->crypto_req);
- +
- + } else { /*decrypt */
- +
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
- + ivp = crd->crd_iv;
- + else
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject, ivsize, (caddr_t)ivp);
- + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
- + sg_len, ivp);
- + ret = crypto_ablkcipher_decrypt(req->crypto_req);
- + }
- +
- + switch (ret) {
- + case -EINPROGRESS:
- + case -EBUSY:
- + return;
- + default:
- + case 0:
- + dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
- + crp->crp_etype = ret;
- + goto done;
- + }
- + } break;
- +#endif /* HAVE_ABLKCIPHER */
- +
- + case SW_TYPE_BLKCIPHER: {
- + unsigned char iv[EALG_MAX_BLOCK_LEN];
- + unsigned char *ivp = iv;
- + struct blkcipher_desc desc;
- + int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
- +
- + if (sg_len < crypto_blkcipher_blocksize(
- + crypto_blkcipher_cast(sw->sw_tfm))) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
- + sg_len, crypto_blkcipher_blocksize(
- + crypto_blkcipher_cast(sw->sw_tfm)));
- + goto done;
- + }
- +
- + if (ivsize > sizeof(iv)) {
- + crp->crp_etype = EINVAL;
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
- + int i, error;
- +
- + if (debug) {
- + dprintk("%s key:", __FUNCTION__);
- + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
- + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
- + crd->crd_key[i] & 0xff);
- + dprintk("\n");
- + }
- + /* OCF doesn't enforce keys */
- + crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
- + CRYPTO_TFM_REQ_WEAK_KEY);
- + error = crypto_blkcipher_setkey(
- + crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
- + (crd->crd_klen + 7) / 8);
- + if (error) {
- + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
- + error, sw->sw_tfm->crt_flags);
- + crp->crp_etype = -error;
- + }
- + }
- +
- + memset(&desc, 0, sizeof(desc));
- + desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
- +
- + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
- +
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
- + ivp = crd->crd_iv;
- + } else {
- + get_random_bytes(ivp, ivsize);
- + }
- + /*
- + * do we have to copy the IV back to the buffer ?
- + */
- + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject, ivsize, (caddr_t)ivp);
- + }
- + desc.info = ivp;
- + crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
- +
- + } else { /*decrypt */
- +
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
- + ivp = crd->crd_iv;
- + } else {
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject, ivsize, (caddr_t)ivp);
- + }
- + desc.info = ivp;
- + crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
- + }
- + } break;
- +
- + case SW_TYPE_HMAC:
- + case SW_TYPE_HASH:
- + {
- + char result[HASH_MAX_LEN];
- + struct hash_desc desc;
- +
- + /* check we have room for the result */
- + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
- + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
- + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
- + crd->crd_inject, sw->u.hmac.sw_mlen);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + memset(&desc, 0, sizeof(desc));
- + desc.tfm = crypto_hash_cast(sw->sw_tfm);
- +
- + memset(result, 0, sizeof(result));
- +
- + if (sw->sw_type & SW_TYPE_HMAC) {
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
- + crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
- + req->sg, sg_num, result);
- +#else
- + crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
- + sw->u.hmac.sw_klen);
- + crypto_hash_digest(&desc, req->sg, sg_len, result);
- +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
- +
- + } else { /* SW_TYPE_HASH */
- + crypto_hash_digest(&desc, req->sg, sg_len, result);
- + }
- +
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject, sw->u.hmac.sw_mlen, result);
- + }
- + break;
- +
- + case SW_TYPE_COMP: {
- + void *ibuf = NULL;
- + void *obuf = sw->u.sw_comp_buf;
- + int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
- + int ret = 0;
- +
- + /*
- + * we need to use an additional copy if there is more than one
- + * input chunk since the kernel comp routines do not handle
- + * SG yet. Otherwise we just use the input buffer as is.
- + * Rather than allocate another buffer we just split the tmp
- + * buffer we already have.
- + * Perhaps we should just use zlib directly ?
- + */
- + if (sg_num > 1) {
- + int blk;
- +
- + ibuf = obuf;
- + for (blk = 0; blk < sg_num; blk++) {
- + memcpy(obuf, sg_virt(&req->sg[blk]),
- + req->sg[blk].length);
- + obuf += req->sg[blk].length;
- + }
- + olen -= sg_len;
- + } else
- + ibuf = sg_virt(&req->sg[0]);
- +
- + if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
- + ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
- + ibuf, ilen, obuf, &olen);
- + if (!ret && olen > crd->crd_len) {
- + dprintk("cryptosoft: ERANGE compress %d into %d\n",
- + crd->crd_len, olen);
- + if (swcr_fail_if_compression_grows)
- + ret = ERANGE;
- + }
- + } else { /* decompress */
- + ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
- + ibuf, ilen, obuf, &olen);
- + if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
- + dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
- + "space for %d,at offset %d\n",
- + crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
- + ret = ETOOSMALL;
- + }
- + }
- + if (ret)
- + dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
- +
- + /*
- + * on success copy result back,
- + * linux crpyto API returns -errno, we need to fix that
- + */
- + crp->crp_etype = ret < 0 ? -ret : ret;
- + if (ret == 0) {
- + /* copy back the result and return it's size */
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject, olen, obuf);
- + crp->crp_olen = olen;
- + }
- +
- +
- + } break;
- +
- + default:
- + /* Unknown/unsupported algorithm */
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- +done:
- + crypto_done(crp);
- + kmem_cache_free(swcr_req_cache, req);
- +}
- +
- +
- +/*
- + * Process a crypto request.
- + */
- +static int
- +swcr_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + struct swcr_req *req = NULL;
- + u_int32_t lid;
- +
- + dprintk("%s()\n", __FUNCTION__);
- + /* Sanity check */
- + if (crp == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + crp->crp_etype = 0;
- +
- + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + lid = crp->crp_sid & 0xffffffff;
- + if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
- + swcr_sessions[lid] == NULL) {
- + crp->crp_etype = ENOENT;
- + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- + /*
- + * do some error checking outside of the loop for SKB and IOV processing
- + * this leaves us with valid skb or uiop pointers for later
- + */
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
- + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
- + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
- + skb_shinfo(skb)->nr_frags);
- + goto done;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + struct uio *uiop = (struct uio *) crp->crp_buf;
- + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
- + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
- + uiop->uio_iovcnt);
- + goto done;
- + }
- + }
- +
- + /*
- + * setup a new request ready for queuing
- + */
- + req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
- + if (req == NULL) {
- + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
- + crp->crp_etype = ENOMEM;
- + goto done;
- + }
- + memset(req, 0, sizeof(*req));
- +
- + req->sw_head = swcr_sessions[lid];
- + req->crp = crp;
- + req->crd = crp->crp_desc;
- +
- + swcr_process_req(req);
- + return 0;
- +
- +done:
- + crypto_done(crp);
- + if (req)
- + kmem_cache_free(swcr_req_cache, req);
- + return 0;
- +}
- +
- +
- +static int
- +cryptosoft_init(void)
- +{
- + int i, sw_type, mode;
- + char *algo;
- +
- + dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
- +
- + swcr_req_cache = kmem_cache_create("cryptosoft_req",
- + sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
- + , NULL
- +#endif
- + );
- + if (!swcr_req_cache) {
- + printk("cryptosoft: failed to create request cache\n");
- + return -ENOENT;
- + }
- +
- + softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
- +
- + swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
- + CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
- + if (swcr_id < 0) {
- + printk("cryptosoft: Software crypto device cannot initialize!");
- + return -ENODEV;
- + }
- +
- +#define REGISTER(alg) \
- + crypto_register(swcr_id, alg, 0,0)
- +
- + for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
- + int found;
- +
- + algo = crypto_details[i].alg_name;
- + if (!algo || !*algo) {
- + dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
- + continue;
- + }
- +
- + mode = crypto_details[i].mode;
- + sw_type = crypto_details[i].sw_type;
- +
- + found = 0;
- + switch (sw_type & SW_TYPE_ALG_MASK) {
- + case SW_TYPE_CIPHER:
- + found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
- + break;
- + case SW_TYPE_HMAC:
- + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
- + break;
- + case SW_TYPE_HASH:
- + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
- + break;
- + case SW_TYPE_COMP:
- + found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
- + break;
- + case SW_TYPE_BLKCIPHER:
- + found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
- + if (!found && !swcr_no_ablk)
- + found = crypto_has_ablkcipher(algo, 0, 0);
- + break;
- + }
- + if (found) {
- + REGISTER(i);
- + } else {
- + dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
- + __FUNCTION__, sw_type, i, algo);
- + }
- + }
- + return 0;
- +}
- +
- +static void
- +cryptosoft_exit(void)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + crypto_unregister_all(swcr_id);
- + swcr_id = -1;
- + kmem_cache_destroy(swcr_req_cache);
- +}
- +
- +late_initcall(cryptosoft_init);
- +module_exit(cryptosoft_exit);
- +
- +MODULE_LICENSE("Dual BSD/GPL");
- +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
- +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
- diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.36/crypto/ocf/ep80579/icp_asym.c
- --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_asym.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ep80579/icp_asym.c 2010-11-09 20:28:04.572486503 +0100
- @@ -0,0 +1,1334 @@
- +/***************************************************************************
- + *
- + * This file is provided under a dual BSD/GPLv2 license. When using or
- + * redistributing this file, you may do so under either license.
- + *
- + * GPL LICENSE SUMMARY
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of version 2 of the GNU General Public License as
- + * published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful, but
- + * WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- + * The full GNU General Public License is included in this distribution
- + * in the file called LICENSE.GPL.
- + *
- + * Contact Information:
- + * Intel Corporation
- + *
- + * BSD LICENSE
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in
- + * the documentation and/or other materials provided with the
- + * distribution.
- + * * Neither the name of Intel Corporation nor the names of its
- + * contributors may be used to endorse or promote products derived
- + * from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + *
- + * version: Security.L.1.0.2-229
- + *
- + ***************************************************************************/
- +
- +#include "icp_ocf.h"
- +
- +/*The following define values (containing the word 'INDEX') are used to find
- +the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
- +These values were found through analysis of the OCF OpenSSL patch. If the
- +calling program uses different input buffer positions, these defines will have
- +to be changed.*/
- +
- +/*DIFFIE HELLMAN buffer index values*/
- +#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
- +#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
- +#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
- +#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
- +
- +/*MOD EXP buffer index values*/
- +#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
- +#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
- +#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
- +#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
- +
- +/*MOD EXP CRT buffer index values*/
- +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
- +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
- +#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
- +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
- +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
- +#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
- +#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
- +
- +/*DSA sign buffer index values*/
- +#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
- +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
- +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
- +#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
- +#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
- +#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
- +#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
- +
- +/*DSA verify buffer index values*/
- +#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
- +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
- +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
- +#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
- +#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
- +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
- +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
- +
- +/*DSA sign prime Q vs random number K size check values*/
- +#define DONT_RUN_LESS_THAN_CHECK (0)
- +#define FAIL_A_IS_GREATER_THAN_B (1)
- +#define FAIL_A_IS_EQUAL_TO_B (1)
- +#define SUCCESS_A_IS_LESS_THAN_B (0)
- +#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
- +
- +/* We need to set a cryptokp success value just in case it is set or allocated
- + and not set to zero outside of this module */
- +#define CRYPTO_OP_SUCCESS (0)
- +
- +/*Function to compute Diffie Hellman (DH) phase 1 or phase 2 key values*/
- +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
- +
- +/*Function to compute a Modular Exponentiation (Mod Exp)*/
- +static int icp_ocfDrvModExp(struct cryptkop *krp);
- +
- +/*Function to compute a Mod Exp using the Chinease Remainder Theorem*/
- +static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
- +
- +/*Helper function to compute whether the first big number argument is less than
- + the second big number argument */
- +static int
- +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
- +
- +/*Function to sign an input with DSA R and S keys*/
- +static int icp_ocfDrvDsaSign(struct cryptkop *krp);
- +
- +/*Function to Verify a DSA buffer signature*/
- +static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
- +
- +/*Callback function for DH operation*/
- +static void
- +icp_ocfDrvDhP1CallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
- +
- +/*Callback function for ME operation*/
- +static void
- +icp_ocfDrvModExpCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData, CpaFlatBuffer * pResult);
- +
- +/*Callback function for ME CRT operation*/
- +static void
- +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData, CpaFlatBuffer * pOutputData);
- +
- +/*Callback function for DSA sign operation*/
- +static void
- +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData,
- + CpaBoolean protocolStatus,
- + CpaFlatBuffer * pR, CpaFlatBuffer * pS);
- +
- +/*Callback function for DSA Verify operation*/
- +static void
- +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData, CpaBoolean verifyStatus);
- +
- +/* Name : icp_ocfDrvPkeProcess
- + *
- + * Description : This function will choose which PKE process to follow
- + * based on the input arguments
- + */
- +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint)
- +{
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- +
- + if (NULL == krp) {
- + DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
- + __FUNCTION__, krp);
- + return EINVAL;
- + }
- +
- + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
- + krp->krp_status = ECANCELED;
- + return ECANCELED;
- + }
- +
- + switch (krp->krp_op) {
- + case CRK_DH_COMPUTE_KEY:
- + DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
- + lacStatus = icp_ocfDrvDHComputeKey(krp);
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
- + "(%d).\n", __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + return ECANCELED;
- + }
- +
- + break;
- +
- + case CRK_MOD_EXP:
- + DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
- + lacStatus = icp_ocfDrvModExp(krp);
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
- + __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + return ECANCELED;
- + }
- +
- + break;
- +
- + case CRK_MOD_EXP_CRT:
- + DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
- + lacStatus = icp_ocfDrvModExpCRT(krp);
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): icp_ocfDrvModExpCRT "
- + "failed (%d).\n", __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + return ECANCELED;
- + }
- +
- + break;
- +
- + case CRK_DSA_SIGN:
- + DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
- + lacStatus = icp_ocfDrvDsaSign(krp);
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): icp_ocfDrvDsaSign "
- + "failed (%d).\n", __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + return ECANCELED;
- + }
- +
- + break;
- +
- + case CRK_DSA_VERIFY:
- + DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
- + lacStatus = icp_ocfDrvDsaVerify(krp);
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): icp_ocfDrvDsaVerify "
- + "failed (%d).\n", __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + return ECANCELED;
- + }
- +
- + break;
- +
- + default:
- + EPRINTK("%s(): Asymettric function not "
- + "supported (%d).\n", __FUNCTION__, krp->krp_op);
- + krp->krp_status = EOPNOTSUPP;
- + return EOPNOTSUPP;
- + }
- +
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- +}
- +
- +/* Name : icp_ocfDrvSwapBytes
- + *
- + * Description : This function is used to swap the byte order of a buffer.
- + * It has been seen that in general we are passed little endian byte order
- + * buffers, but LAC only accepts big endian byte order buffers.
- + */
- +static void inline icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
- +{
- +
- + int i;
- + u_int8_t *end_ptr;
- + u_int8_t hold_val;
- +
- + end_ptr = num + (buff_len_bytes - 1);
- + buff_len_bytes = buff_len_bytes >> 1;
- + for (i = 0; i < buff_len_bytes; i++) {
- + hold_val = *num;
- + *num = *end_ptr;
- + num++;
- + *end_ptr = hold_val;
- + end_ptr--;
- + }
- +}
- +
- +/* Name : icp_ocfDrvDHComputeKey
- + *
- + * Description : This function will map Diffie Hellman calls from OCF
- + * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
- + * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
- + * break down to a modular exponentiation.
- + */
- +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
- +{
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + void *callbackTag = NULL;
- + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
- + CpaFlatBuffer *pLocalOctetStringPV = NULL;
- + uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
- +
- + /* Input checks - check prime is a multiple of 8 bits to allow for
- + allocation later */
- + dh_prime_len_bits =
- + (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
- +
- + /* LAC can reject prime lengths based on prime key sizes, we just
- + need to make sure we can allocate space for the base and
- + exponent buffers correctly */
- + if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
- + APRINTK("%s(): Warning Prime number buffer size is not a "
- + "multiple of 8 bits\n", __FUNCTION__);
- + }
- +
- + /* Result storage space should be the same size as the prime as this
- + value can take up the same amount of storage space */
- + if (dh_prime_len_bits !=
- + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
- + DPRINTK("%s(): Return Buffer must be the same size "
- + "as the Prime buffer\n", __FUNCTION__);
- + krp->krp_status = EINVAL;
- + return EINVAL;
- + }
- + /* Switch to size in bytes */
- + BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
- +
- + callbackTag = krp;
- +
- +/*All allocations are set to ICP_M_NOWAIT due to the possibility of getting
- +called in interrupt context*/
- + pPhase1OpData = icp_kmem_cache_zalloc(drvDH_zone, ICP_M_NOWAIT);
- + if (NULL == pPhase1OpData) {
- + APRINTK("%s():Failed to get memory for key gen data\n",
- + __FUNCTION__);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + pLocalOctetStringPV =
- + icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
- + if (NULL == pLocalOctetStringPV) {
- + APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
- + __FUNCTION__);
- + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + /* Link parameters */
- + pPhase1OpData->primeP.pData =
- + krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
- +
- + pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
- +
- + icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
- +
- + pPhase1OpData->baseG.pData =
- + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
- +
- + BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
- + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
- +
- + icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
- + pPhase1OpData->baseG.dataLenInBytes);
- +
- + pPhase1OpData->privateValueX.pData =
- + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
- +
- + BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
- + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
- + pPhase1OpData->privateValueX.dataLenInBytes);
- +
- + /* Output parameters */
- + pLocalOctetStringPV->pData =
- + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
- +
- + BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
- + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
- +
- + lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
- + icp_ocfDrvDhP1CallBack,
- + callbackTag, pPhase1OpData,
- + pLocalOctetStringPV);
- +
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
- + __FUNCTION__, lacStatus);
- + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
- + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
- + }
- +
- + return lacStatus;
- +}
- +
- +/* Name : icp_ocfDrvModExp
- + *
- + * Description : This function will map ordinary Modular Exponentiation calls
- + * from OCF to the LAC API.
- + *
- + */
- +static int icp_ocfDrvModExp(struct cryptkop *krp)
- +{
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + void *callbackTag = NULL;
- + CpaCyLnModExpOpData *pModExpOpData = NULL;
- + CpaFlatBuffer *pResult = NULL;
- +
- + if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
- + NUM_BITS_IN_BYTE) != 0) {
- + DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
- + "multiple of 8 bits\n", __FUNCTION__,
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
- + crp_nbits);
- + }
- +
- + /* Result storage space should be the same size as the prime as this
- + value can take up the same amount of storage space */
- + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
- + APRINTK("%s(): Return Buffer size must be the same or"
- + " greater than the Modulus buffer\n", __FUNCTION__);
- + krp->krp_status = EINVAL;
- + return EINVAL;
- + }
- +
- + callbackTag = krp;
- +
- + pModExpOpData = icp_kmem_cache_zalloc(drvLnModExp_zone, ICP_M_NOWAIT);
- + if (NULL == pModExpOpData) {
- + APRINTK("%s():Failed to get memory for key gen data\n",
- + __FUNCTION__);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + pResult = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
- + if (NULL == pResult) {
- + APRINTK("%s():Failed to get memory for ModExp result\n",
- + __FUNCTION__);
- + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + /* Link parameters */
- + pModExpOpData->modulus.pData =
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
- + BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
- + pModExpOpData->modulus.dataLenInBytes);
- +
- + DPRINTK("%s : base (%d)\n", __FUNCTION__, krp->
- + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
- + pModExpOpData->base.pData =
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
- + BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
- + crp_nbits);
- + icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
- + pModExpOpData->base.dataLenInBytes);
- +
- + pModExpOpData->exponent.pData =
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
- + BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
- + pModExpOpData->exponent.dataLenInBytes);
- + /* Output parameters */
- + pResult->pData =
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
- + BITS_TO_BYTES(pResult->dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
- + crp_nbits);
- +
- + lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
- + icp_ocfDrvModExpCallBack,
- + callbackTag, pModExpOpData, pResult);
- +
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
- + __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + icp_ocfDrvFreeFlatBuffer(pResult);
- + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
- + }
- +
- + return lacStatus;
- +}
- +
- +/* Name : icp_ocfDrvModExpCRT
- + *
- + * Description : This function will map ordinary Modular Exponentiation Chinese
- + * Remainder Theorem implementaion calls from OCF to the LAC API.
- + *
- + * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
- + * decrypt operation. Therefore P and Q input values must always be prime
- + * numbers. Although basic primality checks are done in LAC, it is up to the
- + * user to do any correct prime number checking before passing the inputs.
- + */
- +static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
- +{
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
- + void *callbackTag = NULL;
- + CpaFlatBuffer *pOutputData = NULL;
- +
- + /*Parameter input checks are all done by LAC, no need to repeat
- + them here. */
- + callbackTag = krp;
- +
- + rsaDecryptOpData =
- + icp_kmem_cache_zalloc(drvRSADecrypt_zone, ICP_M_NOWAIT);
- + if (NULL == rsaDecryptOpData) {
- + APRINTK("%s():Failed to get memory"
- + " for MOD EXP CRT Op data struct\n", __FUNCTION__);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + rsaDecryptOpData->pRecipientPrivateKey
- + = icp_kmem_cache_zalloc(drvRSAPrivateKey_zone, ICP_M_NOWAIT);
- + if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
- + APRINTK("%s():Failed to get memory for MOD EXP CRT"
- + " private key values struct\n", __FUNCTION__);
- + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + rsaDecryptOpData->pRecipientPrivateKey->
- + version = CPA_CY_RSA_VERSION_TWO_PRIME;
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
- +
- + pOutputData = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
- + if (NULL == pOutputData) {
- + APRINTK("%s():Failed to get memory"
- + " for MOD EXP CRT output data\n", __FUNCTION__);
- + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
- + rsaDecryptOpData->pRecipientPrivateKey);
- + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + rsaDecryptOpData->pRecipientPrivateKey->
- + version = CPA_CY_RSA_VERSION_TWO_PRIME;
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
- +
- + /* Link parameters */
- + rsaDecryptOpData->inputData.pData =
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
- + BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
- + rsaDecryptOpData->inputData.dataLenInBytes);
- +
- + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
- + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
- + prime1P.dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.prime1P.pData,
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.prime1P.dataLenInBytes);
- +
- + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
- + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
- + prime2Q.dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.prime2Q.pData,
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.prime2Q.dataLenInBytes);
- +
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.exponent1Dp.pData =
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
- + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
- + exponent1Dp.dataLenInBytes,
- + krp->
- + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.exponent1Dp.pData,
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.exponent1Dp.dataLenInBytes);
- +
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.exponent2Dq.pData =
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
- + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.exponent2Dq.dataLenInBytes,
- + krp->
- + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.exponent2Dq.pData,
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.exponent2Dq.dataLenInBytes);
- +
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.coefficientQInv.pData =
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
- + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.coefficientQInv.dataLenInBytes,
- + krp->
- + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.coefficientQInv.pData,
- + rsaDecryptOpData->pRecipientPrivateKey->
- + privateKeyRep2.coefficientQInv.dataLenInBytes);
- +
- + /* Output Parameter */
- + pOutputData->pData =
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
- + BITS_TO_BYTES(pOutputData->dataLenInBytes,
- + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
- + crp_nbits);
- +
- + lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
- + icp_ocfDrvModExpCRTCallBack,
- + callbackTag, rsaDecryptOpData, pOutputData);
- +
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
- + __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + icp_ocfDrvFreeFlatBuffer(pOutputData);
- + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
- + rsaDecryptOpData->pRecipientPrivateKey);
- + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
- + }
- +
- + return lacStatus;
- +}
- +
- +/* Name : icp_ocfDrvCheckALessThanB
- + *
- + * Description : This function will check whether the first argument is less
- + * than the second. It is used to check whether the DSA RS sign Random K
- + * value is less than the Prime Q value (as defined in the specification)
- + *
- + */
- +static int
- +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
- +{
- +
- + uint8_t *MSB_K = pK->pData;
- + uint8_t *MSB_Q = pQ->pData;
- + uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
- +
- + if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
- + return FAIL_A_IS_GREATER_THAN_B;
- + }
- +
- +/*Check MSBs
- +if A == B, check next MSB
- +if A > B, return A_IS_GREATER_THAN_B
- +if A < B, return A_IS_LESS_THAN_B (success)
- +*/
- + while (*MSB_K == *MSB_Q) {
- + MSB_K++;
- + MSB_Q++;
- +
- + buffer_lengths_in_bytes--;
- + if (0 == buffer_lengths_in_bytes) {
- + DPRINTK("%s() Buffers have equal value!!\n",
- + __FUNCTION__);
- + return FAIL_A_IS_EQUAL_TO_B;
- + }
- +
- + }
- +
- + if (*MSB_K < *MSB_Q) {
- + return SUCCESS_A_IS_LESS_THAN_B;
- + } else {
- + return FAIL_A_IS_GREATER_THAN_B;
- + }
- +
- +}
- +
- +/* Name : icp_ocfDrvDsaSign
- + *
- + * Description : This function will map DSA RS Sign from OCF to the LAC API.
- + *
- + * NOTE: From looking at OCF patch to OpenSSL and even the number of input
- + * parameters, OCF expects us to generate the random seed value. This value
- + * is generated and passed to LAC, however the number is discared in the
- + * callback and not returned to the user.
- + */
- +static int icp_ocfDrvDsaSign(struct cryptkop *krp)
- +{
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
- + void *callbackTag = NULL;
- + CpaCyRandGenOpData randGenOpData;
- + int primeQSizeInBytes = 0;
- + int doCheck = 0;
- + CpaFlatBuffer randData;
- + CpaBoolean protocolStatus = CPA_FALSE;
- + CpaFlatBuffer *pR = NULL;
- + CpaFlatBuffer *pS = NULL;
- +
- + callbackTag = krp;
- +
- + BITS_TO_BYTES(primeQSizeInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
- + crp_nbits);
- +
- + if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
- + APRINTK("%s(): DSA PRIME Q size not equal to the "
- + "FIPS defined 20bytes, = %d\n",
- + __FUNCTION__, primeQSizeInBytes);
- + krp->krp_status = EDOM;
- + return EDOM;
- + }
- +
- + dsaRsSignOpData =
- + icp_kmem_cache_zalloc(drvDSARSSign_zone, ICP_M_NOWAIT);
- + if (NULL == dsaRsSignOpData) {
- + APRINTK("%s():Failed to get memory"
- + " for DSA RS Sign Op data struct\n", __FUNCTION__);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + dsaRsSignOpData->K.pData =
- + icp_kmem_cache_alloc(drvDSARSSignKValue_zone, ICP_M_NOWAIT);
- +
- + if (NULL == dsaRsSignOpData->K.pData) {
- + APRINTK("%s():Failed to get memory"
- + " for DSA RS Sign Op Random value\n", __FUNCTION__);
- + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + pR = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
- + if (NULL == pR) {
- + APRINTK("%s():Failed to get memory"
- + " for DSA signature R\n", __FUNCTION__);
- + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
- + dsaRsSignOpData->K.pData);
- + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + pS = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
- + if (NULL == pS) {
- + APRINTK("%s():Failed to get memory"
- + " for DSA signature S\n", __FUNCTION__);
- + icp_ocfDrvFreeFlatBuffer(pR);
- + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
- + dsaRsSignOpData->K.pData);
- + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + /*link prime number parameter for ease of processing */
- + dsaRsSignOpData->P.pData =
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
- + BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
- + dsaRsSignOpData->P.dataLenInBytes);
- +
- + dsaRsSignOpData->Q.pData =
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
- + BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
- + crp_nbits);
- +
- + icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
- + dsaRsSignOpData->Q.dataLenInBytes);
- +
- + /*generate random number with equal buffer size to Prime value Q,
- + but value less than Q */
- + dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
- +
- + randGenOpData.generateBits = CPA_TRUE;
- + randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
- +
- + icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
- + dsaRsSignOpData->K.dataLenInBytes,
- + &randData);
- +
- + doCheck = 0;
- + while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
- + &(dsaRsSignOpData->Q), &doCheck)) {
- +
- + if (CPA_STATUS_SUCCESS
- + != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
- + NULL, NULL, &randGenOpData, &randData)) {
- + APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
- + "value\n", __FUNCTION__);
- + icp_ocfDrvFreeFlatBuffer(pS);
- + icp_ocfDrvFreeFlatBuffer(pR);
- + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
- + dsaRsSignOpData->K.pData);
- + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
- + krp->krp_status = EAGAIN;
- + return EAGAIN;
- + }
- +
- + doCheck++;
- + if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
- + APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
- + "value less than Q value\n", __FUNCTION__);
- + icp_ocfDrvFreeFlatBuffer(pS);
- + icp_ocfDrvFreeFlatBuffer(pR);
- + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
- + dsaRsSignOpData->K.pData);
- + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
- + krp->krp_status = EAGAIN;
- + return EAGAIN;
- + }
- +
- + }
- + /*Rand Data - no need to swap bytes for pK */
- +
- + /* Link parameters */
- + dsaRsSignOpData->G.pData =
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
- + BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
- +
- + icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
- + dsaRsSignOpData->G.dataLenInBytes);
- +
- + dsaRsSignOpData->X.pData =
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
- + BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
- + icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
- + dsaRsSignOpData->X.dataLenInBytes);
- +
- + /*OpenSSL dgst parameter is left in big endian byte order,
- + therefore no byte swap is required */
- + dsaRsSignOpData->M.pData =
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
- + BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
- + crp_nbits);
- +
- + /* Output Parameters */
- + pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
- + BITS_TO_BYTES(pS->dataLenInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
- + crp_nbits);
- +
- + pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
- + BITS_TO_BYTES(pR->dataLenInBytes,
- + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
- + crp_nbits);
- +
- + lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
- + icp_ocfDrvDsaRSSignCallBack,
- + callbackTag, dsaRsSignOpData,
- + &protocolStatus, pR, pS);
- +
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
- + __FUNCTION__, lacStatus);
- + krp->krp_status = ECANCELED;
- + icp_ocfDrvFreeFlatBuffer(pS);
- + icp_ocfDrvFreeFlatBuffer(pR);
- + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
- + dsaRsSignOpData->K.pData);
- + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
- + }
- +
- + return lacStatus;
- +}
- +
- +/* Name : icp_ocfDrvDsaVerify
- + *
- + * Description : This function will map DSA RS Verify from OCF to the LAC API.
- + *
- + */
- +static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
- +{
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
- + void *callbackTag = NULL;
- + CpaBoolean verifyStatus = CPA_FALSE;
- +
- + callbackTag = krp;
- +
- + dsaVerifyOpData =
- + icp_kmem_cache_zalloc(drvDSAVerify_zone, ICP_M_NOWAIT);
- + if (NULL == dsaVerifyOpData) {
- + APRINTK("%s():Failed to get memory"
- + " for DSA Verify Op data struct\n", __FUNCTION__);
- + krp->krp_status = ENOMEM;
- + return ENOMEM;
- + }
- +
- + /* Link parameters */
- + dsaVerifyOpData->P.pData =
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
- + BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
- + crp_nbits);
- + icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
- + dsaVerifyOpData->P.dataLenInBytes);
- +
- + dsaVerifyOpData->Q.pData =
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
- + BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
- + crp_nbits);
- + icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
- + dsaVerifyOpData->Q.dataLenInBytes);
- +
- + dsaVerifyOpData->G.pData =
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
- + BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
- + crp_nbits);
- + icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
- + dsaVerifyOpData->G.dataLenInBytes);
- +
- + dsaVerifyOpData->Y.pData =
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
- + BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
- + crp_nbits);
- + icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
- + dsaVerifyOpData->Y.dataLenInBytes);
- +
- + /*OpenSSL dgst parameter is left in big endian byte order,
- + therefore no byte swap is required */
- + dsaVerifyOpData->M.pData =
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
- + BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
- + crp_nbits);
- +
- + dsaVerifyOpData->R.pData =
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
- + BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
- + crp_nbits);
- + icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
- + dsaVerifyOpData->R.dataLenInBytes);
- +
- + dsaVerifyOpData->S.pData =
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
- + BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
- + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
- + crp_nbits);
- + icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
- + dsaVerifyOpData->S.dataLenInBytes);
- +
- + lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
- + icp_ocfDrvDsaVerifyCallBack,
- + callbackTag, dsaVerifyOpData, &verifyStatus);
- +
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
- + __FUNCTION__, lacStatus);
- + ICP_CACHE_FREE(drvDSAVerify_zone, dsaVerifyOpData);
- + krp->krp_status = ECANCELED;
- + }
- +
- + return lacStatus;
- +}
- +
- +/* Name : icp_ocfDrvDhP1Callback
- + *
- + * Description : When this function returns it signifies that the LAC
- + * component has completed the DH operation.
- + */
- +static void
- +icp_ocfDrvDhP1CallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
- +{
- + struct cryptkop *krp = NULL;
- + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
- +
- + if (NULL == callbackTag) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "callbackTag data is NULL\n", __FUNCTION__);
- + return;
- + }
- + krp = (struct cryptkop *)callbackTag;
- +
- + if (NULL == pOpData) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "Operation Data is NULL\n", __FUNCTION__);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- + pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
- +
- + if (NULL == pLocalOctetStringPV) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
- + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
- + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- +
- + if (CPA_STATUS_SUCCESS == status) {
- + krp->krp_status = CRYPTO_OP_SUCCESS;
- + } else {
- + APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
- + "Operation Status = %d\n", __FUNCTION__, status);
- + krp->krp_status = ECANCELED;
- + }
- +
- + icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
- + pLocalOctetStringPV->dataLenInBytes);
- +
- + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
- + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
- + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
- +
- + crypto_kdone(krp);
- +
- + return;
- +}
- +
- +/* Name : icp_ocfDrvModExpCallBack
- + *
- + * Description : When this function returns it signifies that the LAC
- + * component has completed the Mod Exp operation.
- + */
- +static void
- +icp_ocfDrvModExpCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpdata, CpaFlatBuffer * pResult)
- +{
- + struct cryptkop *krp = NULL;
- + CpaCyLnModExpOpData *pLnModExpOpData = NULL;
- +
- + if (NULL == callbackTag) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "callbackTag data is NULL\n", __FUNCTION__);
- + return;
- + }
- + krp = (struct cryptkop *)callbackTag;
- +
- + if (NULL == pOpdata) {
- + DPRINTK("%s(): Invalid Mod Exp input parameters - "
- + "Operation Data is NULL\n", __FUNCTION__);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- + pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
- +
- + if (NULL == pResult) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "pResult data is NULL\n", __FUNCTION__);
- + krp->krp_status = ECANCELED;
- + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
- + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
- + crypto_kdone(krp);
- + return;
- + }
- +
- + if (CPA_STATUS_SUCCESS == status) {
- + krp->krp_status = CRYPTO_OP_SUCCESS;
- + } else {
- + APRINTK("%s(): LAC Mod Exp Operation failed - "
- + "Operation Status = %d\n", __FUNCTION__, status);
- + krp->krp_status = ECANCELED;
- + }
- +
- + icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
- +
- + /*switch base size value back to original */
- + if (pLnModExpOpData->base.pData ==
- + (uint8_t *) & (krp->
- + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
- + crp_nbits)) {
- + *((uint32_t *) pLnModExpOpData->base.pData) =
- + ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
- + }
- + icp_ocfDrvFreeFlatBuffer(pResult);
- + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
- + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
- +
- + crypto_kdone(krp);
- +
- + return;
- +
- +}
- +
- +/* Name : icp_ocfDrvModExpCRTCallBack
- + *
- + * Description : When this function returns it signifies that the LAC
- + * component has completed the Mod Exp CRT operation.
- + */
- +static void
- +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData, CpaFlatBuffer * pOutputData)
- +{
- + struct cryptkop *krp = NULL;
- + CpaCyRsaDecryptOpData *pDecryptData = NULL;
- +
- + if (NULL == callbackTag) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "callbackTag data is NULL\n", __FUNCTION__);
- + return;
- + }
- +
- + krp = (struct cryptkop *)callbackTag;
- +
- + if (NULL == pOpData) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "Operation Data is NULL\n", __FUNCTION__);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- + pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
- +
- + if (NULL == pOutputData) {
- + DPRINTK("%s(): Invalid input parameter - "
- + "pOutputData is NULL\n", __FUNCTION__);
- + memset(pDecryptData->pRecipientPrivateKey, 0,
- + sizeof(CpaCyRsaPrivateKey));
- + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
- + pDecryptData->pRecipientPrivateKey);
- + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
- + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- +
- + if (CPA_STATUS_SUCCESS == status) {
- + krp->krp_status = CRYPTO_OP_SUCCESS;
- + } else {
- + APRINTK("%s(): LAC Mod Exp CRT operation failed - "
- + "Operation Status = %d\n", __FUNCTION__, status);
- + krp->krp_status = ECANCELED;
- + }
- +
- + icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
- +
- + icp_ocfDrvFreeFlatBuffer(pOutputData);
- + memset(pDecryptData->pRecipientPrivateKey, 0,
- + sizeof(CpaCyRsaPrivateKey));
- + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
- + pDecryptData->pRecipientPrivateKey);
- + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
- + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
- +
- + crypto_kdone(krp);
- +
- + return;
- +}
- +
- +/* Name : icp_ocfDrvDsaRSSignCallBack
- + *
- + * Description : When this function returns it signifies that the LAC
- + * component has completed the DSA RS sign operation.
- + */
- +static void
- +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData,
- + CpaBoolean protocolStatus,
- + CpaFlatBuffer * pR, CpaFlatBuffer * pS)
- +{
- + struct cryptkop *krp = NULL;
- + CpaCyDsaRSSignOpData *pSignData = NULL;
- +
- + if (NULL == callbackTag) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "callbackTag data is NULL\n", __FUNCTION__);
- + return;
- + }
- +
- + krp = (struct cryptkop *)callbackTag;
- +
- + if (NULL == pOpData) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "Operation Data is NULL\n", __FUNCTION__);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- + pSignData = (CpaCyDsaRSSignOpData *) pOpData;
- +
- + if (NULL == pR) {
- + DPRINTK("%s(): Invalid input parameter - "
- + "pR sign is NULL\n", __FUNCTION__);
- + icp_ocfDrvFreeFlatBuffer(pS);
- + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- +
- + if (NULL == pS) {
- + DPRINTK("%s(): Invalid input parameter - "
- + "pS sign is NULL\n", __FUNCTION__);
- + icp_ocfDrvFreeFlatBuffer(pR);
- + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- +
- + if (CPA_STATUS_SUCCESS != status) {
- + APRINTK("%s(): LAC DSA RS Sign operation failed - "
- + "Operation Status = %d\n", __FUNCTION__, status);
- + krp->krp_status = ECANCELED;
- + } else {
- + krp->krp_status = CRYPTO_OP_SUCCESS;
- +
- + if (CPA_TRUE != protocolStatus) {
- + DPRINTK("%s(): LAC DSA RS Sign operation failed due "
- + "to protocol error\n", __FUNCTION__);
- + krp->krp_status = EIO;
- + }
- + }
- +
- + /* Swap bytes only when the callback status is successful and
- + protocolStatus is set to true */
- + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
- + icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
- + icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
- + }
- +
- + icp_ocfDrvFreeFlatBuffer(pR);
- + icp_ocfDrvFreeFlatBuffer(pS);
- + memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
- + ICP_CACHE_FREE(drvDSARSSignKValue_zone, pSignData->K.pData);
- + memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
- + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
- + crypto_kdone(krp);
- +
- + return;
- +}
- +
- +/* Name : icp_ocfDrvDsaVerifyCallback
- + *
- + * Description : When this function returns it signifies that the LAC
- + * component has completed the DSA Verify operation.
- + */
- +static void
- +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
- + CpaStatus status,
- + void *pOpData, CpaBoolean verifyStatus)
- +{
- +
- + struct cryptkop *krp = NULL;
- + CpaCyDsaVerifyOpData *pVerData = NULL;
- +
- + if (NULL == callbackTag) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "callbackTag data is NULL\n", __FUNCTION__);
- + return;
- + }
- +
- + krp = (struct cryptkop *)callbackTag;
- +
- + if (NULL == pOpData) {
- + DPRINTK("%s(): Invalid input parameters - "
- + "Operation Data is NULL\n", __FUNCTION__);
- + krp->krp_status = ECANCELED;
- + crypto_kdone(krp);
- + return;
- + }
- + pVerData = (CpaCyDsaVerifyOpData *) pOpData;
- +
- + if (CPA_STATUS_SUCCESS != status) {
- + APRINTK("%s(): LAC DSA Verify operation failed - "
- + "Operation Status = %d\n", __FUNCTION__, status);
- + krp->krp_status = ECANCELED;
- + } else {
- + krp->krp_status = CRYPTO_OP_SUCCESS;
- +
- + if (CPA_TRUE != verifyStatus) {
- + DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
- + krp->krp_status = EIO;
- + }
- + }
- +
- + /* Swap bytes only when the callback status is successful and
- + verifyStatus is set to true */
- + /*Just swapping back the key values for now. Possibly all
- + swapped buffers need to be reverted */
- + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
- + icp_ocfDrvSwapBytes(pVerData->R.pData,
- + pVerData->R.dataLenInBytes);
- + icp_ocfDrvSwapBytes(pVerData->S.pData,
- + pVerData->S.dataLenInBytes);
- + }
- +
- + memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
- + ICP_CACHE_FREE(drvDSAVerify_zone, pVerData);
- + crypto_kdone(krp);
- +
- + return;
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.36/crypto/ocf/ep80579/icp_common.c
- --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_common.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ep80579/icp_common.c 2010-11-09 20:28:04.612495446 +0100
- @@ -0,0 +1,773 @@
- +/*************************************************************************
- + *
- + * This file is provided under a dual BSD/GPLv2 license. When using or
- + * redistributing this file, you may do so under either license.
- + *
- + * GPL LICENSE SUMMARY
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of version 2 of the GNU General Public License as
- + * published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful, but
- + * WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- + * The full GNU General Public License is included in this distribution
- + * in the file called LICENSE.GPL.
- + *
- + * Contact Information:
- + * Intel Corporation
- + *
- + * BSD LICENSE
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in
- + * the documentation and/or other materials provided with the
- + * distribution.
- + * * Neither the name of Intel Corporation nor the names of its
- + * contributors may be used to endorse or promote products derived
- + * from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + *
- + * version: Security.L.1.0.2-229
- + *
- + ***************************************************************************/
- +
- +/*
- + * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
- + * crypto.
- + *
- + * This driver requires the ICP Access Library that is available from Intel in
- + * order to operate.
- + */
- +
- +#include "icp_ocf.h"
- +
- +#define ICP_OCF_COMP_NAME "ICP_OCF"
- +#define ICP_OCF_VER_MAIN (2)
- +#define ICP_OCF_VER_MJR (1)
- +#define ICP_OCF_VER_MNR (0)
- +
- +#define MAX_DEREG_RETRIES (100)
- +#define DEFAULT_DEREG_RETRIES (10)
- +#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
- +
- +/* This defines the maximum number of sessions possible between OCF
- + and the OCF EP80579 Driver. If set to zero, there is no limit. */
- +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
- +#define NUM_SUPPORTED_CAPABILITIES (21)
- +
- +/*Slab zone names*/
- +#define ICP_SESSION_DATA_NAME "icp_ocf.SesDat"
- +#define ICP_OP_DATA_NAME "icp_ocf.OpDat"
- +#define ICP_DH_NAME "icp_ocf.DH"
- +#define ICP_MODEXP_NAME "icp_ocf.ModExp"
- +#define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec"
- +#define ICP_RSA_PKEY_NAME "icp_ocf.RSApk"
- +#define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg"
- +#define ICP_DSA_VER_NAME "icp_ocf.DSAver"
- +#define ICP_RAND_VAL_NAME "icp_ocf.DSArnd"
- +#define ICP_FLAT_BUFF_NAME "icp_ocf.FB"
- +
- +/*Slabs zones*/
- +icp_kmem_cache drvSessionData_zone = NULL;
- +icp_kmem_cache drvOpData_zone = NULL;
- +icp_kmem_cache drvDH_zone = NULL;
- +icp_kmem_cache drvLnModExp_zone = NULL;
- +icp_kmem_cache drvRSADecrypt_zone = NULL;
- +icp_kmem_cache drvRSAPrivateKey_zone = NULL;
- +icp_kmem_cache drvDSARSSign_zone = NULL;
- +icp_kmem_cache drvDSARSSignKValue_zone = NULL;
- +icp_kmem_cache drvDSAVerify_zone = NULL;
- +
- +/*Slab zones for flatbuffers and bufferlist*/
- +icp_kmem_cache drvFlatBuffer_zone = NULL;
- +
- +static inline int icp_cache_null_check(void)
- +{
- + return (drvSessionData_zone && drvOpData_zone
- + && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
- + && drvRSAPrivateKey_zone && drvDSARSSign_zone
- + && drvDSARSSign_zone && drvDSARSSignKValue_zone
- + && drvDSAVerify_zone && drvFlatBuffer_zone);
- +}
- +
- +/*Function to free all allocated slab caches before exiting the module*/
- +static void icp_ocfDrvFreeCaches(void);
- +
- +int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
- +
- +/* Module parameter - gives the number of times LAC deregistration shall be
- + re-tried */
- +int num_dereg_retries = DEFAULT_DEREG_RETRIES;
- +
- +/* Module parameter - gives the delay time in jiffies before a LAC session
- + shall be attempted to be deregistered again */
- +int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
- +
- +/* Module parameter - gives the maximum number of sessions possible between
- + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
- +int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
- +
- +/* This is set when the module is removed from the system, no further
- + processing can take place if this is set */
- +icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
- +
- +/* This is used to show how many lac sessions were not deregistered*/
- +icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
- +
- +/* This is used to track the number of registered sessions between OCF and
- + * and the OCF EP80579 driver, when max_session is set to value other than
- + * zero. This ensures that the max_session set for the OCF and the driver
- + * is equal to the LAC registered sessions */
- +icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
- +
- +/* Head of linked list used to store session data */
- +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
- +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
- +
- +icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
- +
- +/*Below pointer is only used in linux, FreeBSD uses the name to
- +create its own variable name*/
- +icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
- +ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
- +
- +struct icp_drvBuffListInfo defBuffListInfo;
- +
- +/* Name : icp_ocfDrvInit
- + *
- + * Description : This function will register all the symmetric and asymmetric
- + * functionality that will be accelerated by the hardware. It will also
- + * get a unique driver ID from the OCF and initialise all slab caches
- + */
- +ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
- +{
- + int ocfStatus = 0;
- +
- + IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
- + ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
- +
- + if (MAX_DEREG_RETRIES < num_dereg_retries) {
- + EPRINTK("Session deregistration retry count set to greater "
- + "than %d", MAX_DEREG_RETRIES);
- + icp_module_return_code(EINVAL);
- + }
- +
- + /* Initialize and Start the Cryptographic component */
- + if (CPA_STATUS_SUCCESS !=
- + cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
- + EPRINTK("Failed to initialize and start the instance "
- + "of the Cryptographic component.\n");
- + return icp_module_return_code(EINVAL);
- + }
- +
- + icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
- +
- + /* Set the default size of BufferList to allocate */
- + memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
- + &defBuffListInfo)) {
- + EPRINTK("Failed to get bufferlist memory info.\n");
- + return icp_module_return_code(ENOMEM);
- + }
- +
- + /*Register OCF EP80579 Driver with OCF */
- + icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
- +
- + if (icp_ocfDrvDriverId < 0) {
- + EPRINTK("%s : ICP driver failed to register with OCF!\n",
- + __FUNCTION__);
- + return icp_module_return_code(ENODEV);
- + }
- +
- + /*Create all the slab caches used by the OCF EP80579 Driver */
- + drvSessionData_zone =
- + ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
- +
- + /*
- + * Allocation of the OpData includes the allocation space for meta data.
- + * The memory after the opData structure is reserved for this meta data.
- + */
- + drvOpData_zone =
- + icp_kmem_cache_create(ICP_OP_DATA_NAME,
- + sizeof(struct icp_drvOpData) +
- + defBuffListInfo.metaSize,
- + ICP_KERNEL_CACHE_ALIGN,
- + ICP_KERNEL_CACHE_NOINIT);
- +
- + drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
- +
- + drvLnModExp_zone =
- + ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
- +
- + drvRSADecrypt_zone =
- + ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
- +
- + drvRSAPrivateKey_zone =
- + ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
- +
- + drvDSARSSign_zone =
- + ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
- +
- + /*too awkward to use a macro here */
- + drvDSARSSignKValue_zone =
- + ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
- + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
- +
- + drvDSAVerify_zone =
- + ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
- +
- + drvFlatBuffer_zone =
- + ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
- +
- + if (0 == icp_cache_null_check()) {
- + icp_ocfDrvFreeCaches();
- + EPRINTK("%s() line %d: Not enough memory!\n",
- + __FUNCTION__, __LINE__);
- + return ENOMEM;
- + }
- +
- + /* Register the ICP symmetric crypto support. */
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
- + ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
- + ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
- + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
- + ocfStatus);
- +
- + /* Register the ICP asymmetric algorithm support */
- + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
- + ocfStatus);
- + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
- + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
- + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
- + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
- +
- + /* Register the ICP random number generator support */
- + ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
- + icp_ocfDrvReadRandom, NULL, ocfStatus);
- +
- + if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
- + DPRINTK("%s: Failed to register any device capabilities\n",
- + __FUNCTION__);
- + icp_ocfDrvFreeCaches();
- + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
- + return icp_module_return_code(ECANCELED);
- + }
- +
- + DPRINTK("%s: Registered %d of %d device capabilities\n",
- + __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
- +
- + /*Session data linked list used during module exit */
- + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
- + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
- +
- + ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
- + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
- + EPRINTK("%s: Failed to create single "
- + "thread workqueue\n", __FUNCTION__);
- + icp_ocfDrvFreeCaches();
- + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
- + return icp_module_return_code(ENOMEM);
- + }
- +
- + return icp_module_return_code(0);
- +}
- +
- +/* Name : icp_ocfDrvExit
- + *
- + * Description : This function will deregister all the symmetric sessions
- + * registered with the LAC component. It will also deregister all symmetric
- + * and asymmetric functionality that can be accelerated by the hardware via OCF
- + * and random number generation if it is enabled.
- + */
- +ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
- +{
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + struct icp_drvSessionData *sessionData = NULL;
- + struct icp_drvSessionData *tempSessionData = NULL;
- + int i, remaining_delay_time_in_jiffies = 0;
- +
- + /* For FreeBSD the invariant macro below makes function to return */
- + /* with EBUSY value in the case of any session which has been regi- */
- + /* stered with LAC not being deregistered. */
- + /* The Linux implementation is empty since it is purely to compensate */
- + /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */
- +
- + ICP_MODULE_EXIT_INV();
- +
- + /* There is a possibility of a process or new session command being */
- + /* sent before this variable is incremented. The aim of this variable */
- + /* is to stop a loop of calls creating a deadlock situation which */
- + /* would prevent the driver from exiting. */
- + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
- +
- + /*Existing sessions will be routed to another driver after these calls */
- + crypto_unregister_all(icp_ocfDrvDriverId);
- + crypto_runregister_all(icp_ocfDrvDriverId);
- +
- + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
- + DPRINTK("%s: workqueue already "
- + "destroyed, therefore module exit "
- + " function already called. Exiting.\n", __FUNCTION__);
- + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
- + }
- + /*If any sessions are waiting to be deregistered, do that. This also
- + flushes the work queue */
- + ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
- +
- + /*ENTER CRITICAL SECTION */
- + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
- +
- + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
- + &icp_ocfDrvGlobalSymListHead, listNode) {
- + for (i = 0; i < num_dereg_retries; i++) {
- + /*No harm if bad input - LAC will handle error cases */
- + if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
- + lacStatus =
- + cpaCySymRemoveSession
- + (CPA_INSTANCE_HANDLE_SINGLE,
- + tempSessionData->sessHandle);
- + if (CPA_STATUS_SUCCESS == lacStatus) {
- + /* Succesfully deregistered */
- + break;
- + } else if (CPA_STATUS_RETRY != lacStatus) {
- + icp_atomic_inc
- + (&lac_session_failed_dereg_count);
- + break;
- + }
- +
- + /*schedule_timout returns the time left for completion if
- + * this task is set to TASK_INTERRUPTIBLE */
- + remaining_delay_time_in_jiffies =
- + dereg_retry_delay_in_jiffies;
- + while (0 > remaining_delay_time_in_jiffies) {
- + remaining_delay_time_in_jiffies =
- + icp_schedule_timeout
- + (&icp_ocfDrvSymSessInfoListSpinlock,
- + remaining_delay_time_in_jiffies);
- + }
- +
- + DPRINTK
- + ("%s(): Retry %d to deregistrate the session\n",
- + __FUNCTION__, i);
- + }
- + }
- +
- + /*remove from current list */
- + ICP_LIST_DEL(tempSessionData, listNode);
- + /*add to free mem linked list */
- + ICP_LIST_ADD(tempSessionData,
- + &icp_ocfDrvGlobalSymListHead_FreeMemList,
- + listNode);
- +
- + }
- +
- + /*EXIT CRITICAL SECTION */
- + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
- +
- + /*set back to initial values */
- + sessionData = NULL;
- + /*still have a reference in our list! */
- + tempSessionData = NULL;
- + /*free memory */
- +
- + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
- + &icp_ocfDrvGlobalSymListHead_FreeMemList,
- + listNode) {
- +
- + ICP_LIST_DEL(tempSessionData, listNode);
- + /* Free allocated CpaCySymSessionCtx */
- + if (NULL != tempSessionData->sessHandle) {
- + icp_kfree(tempSessionData->sessHandle);
- + }
- + memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
- + ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
- + }
- +
- + if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
- + DPRINTK("%s(): %d LAC sessions were not deregistered "
- + "correctly. This is not a clean exit! \n",
- + __FUNCTION__,
- + icp_atomic_read(&lac_session_failed_dereg_count));
- + }
- +
- + icp_ocfDrvFreeCaches();
- + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
- +
- + icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
- +
- + /* Shutdown the Cryptographic component */
- + lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + DPRINTK("%s(): Failed to stop instance of the "
- + "Cryptographic component.(status == %d)\n",
- + __FUNCTION__, lacStatus);
- + }
- +
- + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
- +}
- +
- +/* Name : icp_ocfDrvFreeCaches
- + *
- + * Description : This function deregisters all slab caches
- + */
- +static void icp_ocfDrvFreeCaches(void)
- +{
- + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
- +
- + /*Sym Zones */
- + ICP_CACHE_DESTROY(drvSessionData_zone);
- + ICP_CACHE_DESTROY(drvOpData_zone);
- +
- + /*Asym zones */
- + ICP_CACHE_DESTROY(drvDH_zone);
- + ICP_CACHE_DESTROY(drvLnModExp_zone);
- + ICP_CACHE_DESTROY(drvRSADecrypt_zone);
- + ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
- + ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
- + ICP_CACHE_DESTROY(drvDSARSSign_zone);
- + ICP_CACHE_DESTROY(drvDSAVerify_zone);
- +
- + /*FlatBuffer and BufferList Zones */
- + ICP_CACHE_DESTROY(drvFlatBuffer_zone);
- +
- +}
- +
- +/* Name : icp_ocfDrvDeregRetry
- + *
- + * Description : This function will try to farm the session deregistration
- + * off to a work queue. If it fails, nothing more can be done and it
- + * returns an error
- + */
- +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
- +{
- + struct icp_ocfDrvFreeLacSession *workstore = NULL;
- +
- + DPRINTK("%s(): Retry - Deregistering session (%p)\n",
- + __FUNCTION__, sessionToDeregister);
- +
- + /*make sure the session is not available to be allocated during this
- + process */
- + icp_atomic_inc(&lac_session_failed_dereg_count);
- +
- + /*Farm off to work queue */
- + workstore =
- + icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
- + if (NULL == workstore) {
- + DPRINTK("%s(): unable to free session - no memory available "
- + "for work queue\n", __FUNCTION__);
- + return ENOMEM;
- + }
- +
- + workstore->sessionToDeregister = sessionToDeregister;
- +
- + icp_init_work(&(workstore->work),
- + icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
- +
- + ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
- + &(workstore->work));
- +
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- +
- +}
- +
- +/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
- + *
- + * Description : This function will retry (module input parameter)
- + * 'num_dereg_retries' times to deregister any symmetric session that recieves a
- + * CPA_STATUS_RETRY message from the LAC component. This function is run in
- + * Thread context because it is called from a worker thread
- + */
- +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
- +{
- + struct icp_ocfDrvFreeLacSession *workstore = NULL;
- + CpaCySymSessionCtx sessionToDeregister = NULL;
- + int i = 0;
- + int remaining_delay_time_in_jiffies = 0;
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- +
- + workstore = (struct icp_ocfDrvFreeLacSession *)arg;
- + if (NULL == workstore) {
- + DPRINTK("%s() function called with null parameter \n",
- + __FUNCTION__);
- + return;
- + }
- +
- + sessionToDeregister = workstore->sessionToDeregister;
- + icp_kfree(workstore);
- +
- + /*if exiting, give deregistration one more blast only */
- + if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
- + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
- + sessionToDeregister);
- +
- + if (lacStatus != CPA_STATUS_SUCCESS) {
- + DPRINTK("%s() Failed to Dereg LAC session %p "
- + "during module exit\n", __FUNCTION__,
- + sessionToDeregister);
- + return;
- + }
- +
- + icp_atomic_dec(&lac_session_failed_dereg_count);
- + return;
- + }
- +
- + for (i = 0; i <= num_dereg_retries; i++) {
- + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
- + sessionToDeregister);
- +
- + if (lacStatus == CPA_STATUS_SUCCESS) {
- + icp_atomic_dec(&lac_session_failed_dereg_count);
- + return;
- + }
- + if (lacStatus != CPA_STATUS_RETRY) {
- + DPRINTK("%s() Failed to deregister session - lacStatus "
- + " = %d", __FUNCTION__, lacStatus);
- + break;
- + }
- +
- + /*schedule_timout returns the time left for completion if this
- + task is set to TASK_INTERRUPTIBLE */
- + remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
- + while (0 < remaining_delay_time_in_jiffies) {
- + remaining_delay_time_in_jiffies =
- + icp_schedule_timeout(NULL,
- + remaining_delay_time_in_jiffies);
- + }
- +
- + }
- +
- + DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
- + DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
- + icp_atomic_read(&lac_session_failed_dereg_count));
- +}
- +
- +/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
- + *
- + * Description : This function converts a "pointer and length" buffer
- + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
- + *
- + * This function assumes that the data passed in are valid.
- + */
- +inline void
- +icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
- + CpaFlatBuffer * pFlatBuffer)
- +{
- + pFlatBuffer->pData = pData;
- + pFlatBuffer->dataLenInBytes = len;
- +}
- +
- +/* Name : icp_ocfDrvPtrAndLenToBufferList
- + *
- + * Description : This function converts a "pointer and length" buffer
- + * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
- + *
- + * This function assumes that the data passed in are valid.
- + */
- +inline void
- +icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
- + CpaBufferList * pBufferList)
- +{
- + pBufferList->numBuffers = 1;
- + pBufferList->pBuffers->pData = pDataIn;
- + pBufferList->pBuffers->dataLenInBytes = length;
- +}
- +
- +/* Name : icp_ocfDrvBufferListToPtrAndLen
- + *
- + * Description : This function converts Fredericksburg Scatter/Gather Buffer
- + * (CpaBufferList) format to a "pointer and length" buffer structure.
- + *
- + * This function assumes that the data passed in are valid.
- + */
- +inline void
- +icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
- + void **ppDataOut, uint32_t * pLength)
- +{
- + *ppDataOut = pBufferList->pBuffers->pData;
- + *pLength = pBufferList->pBuffers->dataLenInBytes;
- +}
- +
- +/* Name : icp_ocfDrvBufferListMemInfo
- + *
- + * Description : This function will set the number of flat buffers in
- + * bufferlist, the size of memory to allocate for the pPrivateMetaData
- + * member of the CpaBufferList.
- + */
- +int
- +icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
- + struct icp_drvBuffListInfo *buffListInfo)
- +{
- + buffListInfo->numBuffers = numBuffers;
- +
- + if (CPA_STATUS_SUCCESS !=
- + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
- + buffListInfo->numBuffers,
- + &(buffListInfo->metaSize))) {
- + EPRINTK("%s() Failed to get buffer list meta size.\n",
- + __FUNCTION__);
- + return ICP_OCF_DRV_STATUS_FAIL;
- + }
- +
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- +}
- +
- +/* Name : icp_ocfDrvFreeFlatBuffer
- + *
- + * Description : This function will deallocate flat buffer.
- + */
- +inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
- +{
- + if (pFlatBuffer != NULL) {
- + memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
- + ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
- + }
- +}
- +
- +/* Name : icp_ocfDrvAllocMetaData
- + *
- + * Description : This function will allocate memory for the
- + * pPrivateMetaData member of CpaBufferList.
- + */
- +inline int
- +icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
- + struct icp_drvOpData *pOpData)
- +{
- + Cpa32U metaSize = 0;
- +
- + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
- + uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
- +
- + if (0 == defBuffListInfo.metaSize) {
- + pBufferList->pPrivateMetaData = NULL;
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- + }
- + /*
- + * The meta data allocation has been included as part of the
- + * op data. It has been pre-allocated in memory just after the
- + * icp_drvOpData structure.
- + */
- + pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
- + sizeof(struct
- + icp_drvOpData));
- + } else {
- + if (CPA_STATUS_SUCCESS !=
- + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
- + pBufferList->numBuffers,
- + &metaSize)) {
- + EPRINTK("%s() Failed to get buffer list meta size.\n",
- + __FUNCTION__);
- + return ICP_OCF_DRV_STATUS_FAIL;
- + }
- +
- + if (0 == metaSize) {
- + pBufferList->pPrivateMetaData = NULL;
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- + }
- +
- + pBufferList->pPrivateMetaData =
- + icp_kmalloc(metaSize, ICP_M_NOWAIT);
- + }
- + if (NULL == pBufferList->pPrivateMetaData) {
- + EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
- + __FUNCTION__);
- + return ICP_OCF_DRV_STATUS_FAIL;
- + }
- +
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- +}
- +
- +/* Name : icp_ocfDrvFreeMetaData
- + *
- + * Description : This function will deallocate pPrivateMetaData memory.
- + */
- +inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
- +{
- + if (NULL == pBufferList->pPrivateMetaData) {
- + return;
- + }
- +
- + /*
- + * Only free the meta data if the BufferList has more than
- + * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
- + * Otherwise, the meta data shall be freed when the icp_drvOpData is
- + * freed.
- + */
- + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
- + icp_kfree(pBufferList->pPrivateMetaData);
- + }
- +}
- +
- +/* Module declaration, init and exit functions */
- +ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
- +ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
- +ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
- +ICP_MODULE_LICENSE("Dual BSD/GPL");
- +ICP_MODULE_AUTHOR("Intel");
- +
- +/* Module parameters */
- +ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
- + "Number of times to retry LAC Sym Session Deregistration. "
- + "Default 10, Max 100");
- +ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
- + "(added to a schedule() function call) before a LAC Sym "
- + "Session Dereg is retried. Default 10");
- +ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
- + "This sets the maximum number of sessions "
- + "between OCF and this driver. If this value is set to zero,"
- + "max session count checking is disabled. Default is zero(0)");
- +
- +/* Module dependencies */
- +#define MODULE_MIN_VER 1
- +#define CRYPTO_MAX_VER 3
- +#define LAC_MAX_VER 2
- +
- +ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
- + CRYPTO_MAX_VER);
- +ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
- + CRYPTO_MAX_VER);
- +ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
- + LAC_MAX_VER);
- diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.36/crypto/ocf/ep80579/icp_ocf.h
- --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_ocf.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ep80579/icp_ocf.h 2010-11-09 20:28:04.662495462 +0100
- @@ -0,0 +1,376 @@
- +/***************************************************************************
- + *
- + * This file is provided under a dual BSD/GPLv2 license. When using or
- + * redistributing this file, you may do so under either license.
- + *
- + * GPL LICENSE SUMMARY
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of version 2 of the GNU General Public License as
- + * published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful, but
- + * WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- + * The full GNU General Public License is included in this distribution
- + * in the file called LICENSE.GPL.
- + *
- + * Contact Information:
- + * Intel Corporation
- + *
- + * BSD LICENSE
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in
- + * the documentation and/or other materials provided with the
- + * distribution.
- + * * Neither the name of Intel Corporation nor the names of its
- + * contributors may be used to endorse or promote products derived
- + * from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + *
- + * version: Security.L.1.0.2-229
- + *
- + ***************************************************************************/
- +
- +/*
- + * OCF driver header file for the Intel ICP processor.
- + */
- +
- +#ifndef ICP_OCF_H_
- +#define ICP_OCF_H_
- +
- +#include <cpa.h>
- +#include <cpa_cy_im.h>
- +#include <cpa_cy_sym.h>
- +#include <cpa_cy_rand.h>
- +#include <cpa_cy_dh.h>
- +#include <cpa_cy_rsa.h>
- +#include <cpa_cy_ln.h>
- +#include <cpa_cy_common.h>
- +#include <cpa_cy_dsa.h>
- +
- +#include "icp_os.h"
- +
- +#define NUM_BITS_IN_BYTE (8)
- +#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
- +#define INVALID_DRIVER_ID (-1)
- +#define RETURN_RAND_NUM_GEN_FAILED (-1)
- +
- +/*This is the max block cipher initialisation vector*/
- +#define MAX_IV_LEN_IN_BYTES (20)
- +/*This is used to check whether the OCF to this driver session limit has
- + been disabled*/
- +#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
- +
- +/*OCF values mapped here*/
- +#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
- +#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
- +#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
- +#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
- +#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
- +#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
- +
- +#define OCF_REGISTRATION_STATUS_SUCCESS (0)
- +#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
- +#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
- +#define ICP_OCF_DRV_STATUS_SUCCESS (0)
- +#define ICP_OCF_DRV_STATUS_FAIL (1)
- +
- +/*Turn on/off debug options*/
- +#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
- +#define ICP_OCF_PRINT_KERN_ALERT (1)
- +#define ICP_OCF_PRINT_KERN_ERRS (1)
- +
- +#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
- +#define DPRINTK(args...) \
- +{ \
- + ICP_IPRINTK(args); \
- +}
- +
- +#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
- +
- +#define DPRINTK(args...)
- +
- +#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
- +
- +#if ICP_OCF_PRINT_KERN_ALERT == 1
- +#define APRINTK(args...) \
- +{ \
- + ICP_APRINTK(args); \
- +}
- +
- +#else //ICP_OCF_PRINT_KERN_ALERT == 1
- +
- +#define APRINTK(args...)
- +
- +#endif //ICP_OCF_PRINT_KERN_ALERT == 1
- +
- +#if ICP_OCF_PRINT_KERN_ERRS == 1
- +#define EPRINTK(args...) \
- +{ \
- + ICP_EPRINTK(args); \
- +}
- +
- +#else //ICP_OCF_PRINT_KERN_ERRS == 1
- +
- +#define EPRINTK(args...)
- +
- +#endif //ICP_OCF_PRINT_KERN_ERRS == 1
- +
- +#define IPRINTK(args...) \
- +{ \
- + ICP_IPRINTK(args); \
- +}
- +
- +/*DSA Prime Q size in bytes (as defined in the standard) */
- +#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
- +
- +#define BITS_TO_BYTES(bytes, bits) \
- + bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
- +
- +typedef enum {
- + ICP_OCF_DRV_ALG_CIPHER = 0,
- + ICP_OCF_DRV_ALG_HASH
- +} icp_ocf_drv_alg_type_t;
- +
- +typedef ICP_LIST_HEAD(icp_drvSessionListHead_s,
- + icp_drvSessionData) icp_drvSessionListHead_t;
- +
- +/*Values used to derisk chances of performs being called against
- +deregistered sessions (for which the slab page has been reclaimed)
- +This is not a fix - since page frames are reclaimed from a slab, one cannot
- +rely on that memory not being re-used by another app.*/
- +typedef enum {
- + ICP_SESSION_INITIALISED = 0x5C5C5C,
- + ICP_SESSION_RUNNING = 0x005C00,
- + ICP_SESSION_DEREGISTERED = 0xC5C5C5
- +} usage_derisk;
- +
- +/* This struct is required for deferred session
- + deregistration as a work queue function can
- + only have one argument*/
- +struct icp_ocfDrvFreeLacSession {
- + CpaCySymSessionCtx sessionToDeregister;
- + icp_workstruct work;
- +};
- +
- +/*
- +This is the OCF<->OCF_DRV session object:
- +
- +1.listNode
- + The first member is a listNode. These session objects are added to a linked
- + list in order to make it easier to remove them all at session exit time.
- +
- +2.inUse
- + The second member is used to give the session object state and derisk the
- + possibility of OCF batch calls executing against a deregistered session (as
- + described above).
- +
- +3.sessHandle
- + The third member is a LAC<->OCF_DRV session handle (initialised with the first
- + perform request for that session).
- +
- +4.lacSessCtx
- + The fourth is the LAC session context. All the parameters for this structure
- + are only known when the first perform request for this session occurs. That is
- + why the OCF EP80579 Driver only registers a new LAC session at perform time
- +*/
- +struct icp_drvSessionData {
- + ICP_LIST_ENTRY(icp_drvSessionData) listNode;
- + usage_derisk inUse;
- + CpaCySymSessionCtx sessHandle;
- + CpaCySymSessionSetupData lacSessCtx;
- +};
- +
- +/* These are all defined in icp_common.c */
- +extern icp_atomic_t lac_session_failed_dereg_count;
- +extern icp_atomic_t icp_ocfDrvIsExiting;
- +extern icp_atomic_t num_ocf_to_drv_registered_sessions;
- +
- +extern int32_t icp_ocfDrvDriverId;
- +
- +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
- +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
- +extern icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ;
- +extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
- +
- +/*Slab zones for symettric functionality, instantiated in icp_common.c*/
- +extern icp_kmem_cache drvSessionData_zone;
- +extern icp_kmem_cache drvOpData_zone;
- +
- +/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
- +extern icp_kmem_cache drvDH_zone;
- +extern icp_kmem_cache drvLnModExp_zone;
- +extern icp_kmem_cache drvRSADecrypt_zone;
- +extern icp_kmem_cache drvRSAPrivateKey_zone;
- +extern icp_kmem_cache drvDSARSSign_zone;
- +extern icp_kmem_cache drvDSARSSignKValue_zone;
- +extern icp_kmem_cache drvDSAVerify_zone;
- +
- +/* Module parameters defined in icp_cpmmon.c*/
- +
- +/* Module parameters - gives the number of times LAC deregistration shall be
- + re-tried */
- +extern int num_dereg_retries;
- +
- +/* Module parameter - gives the delay time in jiffies before a LAC session
- + shall be attempted to be deregistered again */
- +extern int dereg_retry_delay_in_jiffies;
- +
- +/* Module parameter - gives the maximum number of sessions possible between
- + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
- +extern int max_sessions;
- +
- +/*Slab zones for flatbuffers and bufferlist*/
- +extern icp_kmem_cache drvFlatBuffer_zone;
- +
- +#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
- +
- +struct icp_drvBuffListInfo {
- + Cpa16U numBuffers;
- + Cpa32U metaSize;
- + Cpa32U metaOffset;
- + Cpa32U buffListSize;
- +};
- +
- +extern struct icp_drvBuffListInfo defBuffListInfo;
- +
- +/* This struct is used to keep a reference to the relevant node in the list
- + of sessionData structs, to the buffer type required by OCF and to the OCF
- + provided crp struct that needs to be returned. All this info is needed in
- + the callback function.*/
- +struct icp_drvOpData {
- + CpaCySymOpData lacOpData;
- + uint32_t digestSizeInBytes;
- + struct cryptop *crp;
- + uint8_t bufferType;
- + uint8_t ivData[MAX_IV_LEN_IN_BYTES];
- + uint16_t numBufferListArray;
- + CpaBufferList srcBuffer;
- + CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
- + CpaBoolean verifyResult;
- +};
- +
- +/* Create a new session between OCF and this driver*/
- +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sild,
- + struct cryptoini *cri);
- +
- +/* Free a session between this driver and the Quick Assist Framework*/
- +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid);
- +
- +/* Defer freeing a Quick Assist session*/
- +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
- +
- +/* Process OCF cryptographic request for a symmetric algorithm*/
- +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint);
- +
- +/* Process OCF cryptographic request for an asymmetric algorithm*/
- +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint);
- +
- +/* Populate a buffer with random data*/
- +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
- +
- +/* Retry Quick Assist session deregistration*/
- +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
- +
- +/* Convert an OS scatter gather list to a CPA buffer list*/
- +int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t * pPacketBuffer,
- + CpaBufferList * bufferList);
- +
- +/* Convert a CPA buffer list to an OS scatter gather list*/
- +int icp_ocfDrvBufferListToPacketBuff(CpaBufferList * bufferList,
- + icp_packet_buffer_t ** pPacketBuffer);
- +
- +/* Get the number of buffers in an OS scatter gather list*/
- +uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t * pPacketBuffer);
- +
- +/* Convert a single OS buffer to a CPA Flat Buffer*/
- +void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t * pPacketBuffer,
- + CpaFlatBuffer * pFlatBuffer);
- +
- +/* Add pointer and length to a CPA Flat Buffer structure*/
- +void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
- + CpaFlatBuffer * pFlatBuffer);
- +
- +/* Convert pointer and length values to a CPA buffer list*/
- +void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
- + CpaBufferList * pBufferList);
- +
- +/* Convert a CPA buffer list to pointer and length values*/
- +void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
- + void **ppDataOut, uint32_t * pLength);
- +
- +/* Set the number of flat buffers in bufferlist and the size of memory
- + to allocate for the pPrivateMetaData member of the CpaBufferList.*/
- +int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
- + struct icp_drvBuffListInfo *buffListInfo);
- +
- +/* Find pointer position of the digest within an OS scatter gather list*/
- +uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData
- + *drvOpData,
- + int offsetInBytes,
- + uint32_t digestSizeInBytes);
- +
- +/*This top level function is used to find a pointer to where a digest is
- + stored/needs to be inserted. */
- +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
- + struct cryptodesc *crp_desc);
- +
- +/* Free a CPA flat buffer*/
- +void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
- +
- +/* This function will allocate memory for the pPrivateMetaData
- + member of CpaBufferList. */
- +int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
- + struct icp_drvOpData *pOpData);
- +
- +/* Free data allocated for the pPrivateMetaData
- + member of CpaBufferList.*/
- +void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
- +
- +#define ICP_CACHE_CREATE(cache_ID, cache_name) \
- + icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\
- + ICP_KERNEL_CACHE_NOINIT)
- +
- +#define ICP_CACHE_FREE(args...) \
- + icp_kmem_cache_free (args)
- +
- +#define ICP_CACHE_DESTROY(slab_zone)\
- +{\
- + if(NULL != slab_zone){\
- + icp_kmem_cache_destroy(slab_zone);\
- + slab_zone = NULL;\
- + }\
- +}
- +
- +#endif
- +/* ICP_OCF_H_ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.36/crypto/ocf/ep80579/icp_sym.c
- --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_sym.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ep80579/icp_sym.c 2010-11-09 20:28:04.702495471 +0100
- @@ -0,0 +1,1153 @@
- +/***************************************************************************
- + *
- + * This file is provided under a dual BSD/GPLv2 license. When using or
- + * redistributing this file, you may do so under either license.
- + *
- + * GPL LICENSE SUMMARY
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of version 2 of the GNU General Public License as
- + * published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful, but
- + * WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- + * The full GNU General Public License is included in this distribution
- + * in the file called LICENSE.GPL.
- + *
- + * Contact Information:
- + * Intel Corporation
- + *
- + * BSD LICENSE
- + *
- + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in
- + * the documentation and/or other materials provided with the
- + * distribution.
- + * * Neither the name of Intel Corporation nor the names of its
- + * contributors may be used to endorse or promote products derived
- + * from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + *
- + * version: Security.L.1.0.2-229
- + *
- + ***************************************************************************/
- +/*
- + * An OCF module that uses the API for Intel® QuickAssist Technology to do the
- + * cryptography.
- + *
- + * This driver requires the ICP Access Library that is available from Intel in
- + * order to operate.
- + */
- +
- +#include "icp_ocf.h"
- +
- +/*This is the call back function for all symmetric cryptographic processes.
- + Its main functionality is to free driver crypto operation structure and to
- + call back to OCF*/
- +static void
- +icp_ocfDrvSymCallBack(void *callbackTag,
- + CpaStatus status,
- + const CpaCySymOp operationType,
- + void *pOpData,
- + CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
- +
- +/*This function is used to extract crypto processing information from the OCF
- + inputs, so as that it may be passed onto LAC*/
- +static int
- +icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
- + struct cryptodesc *crp_desc);
- +
- +/*This function checks whether the crp_desc argument pertains to a digest or a
- + cipher operation*/
- +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
- +
- +/*This function copies all the passed in session context information and stores
- + it in a LAC context structure*/
- +static int
- +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
- + CpaCySymSessionSetupData * lacSessCtx);
- +
- +/*This function is used to free an OCF->OCF_DRV session object*/
- +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
- +
- +/*max IOV buffs supported in a UIO structure*/
- +#define NUM_IOV_SUPPORTED (1)
- +
- +/* Name : icp_ocfDrvSymCallBack
- + *
- + * Description : When this function returns it signifies that the LAC
- + * component has completed the relevant symmetric operation.
- + *
- + * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
- + * object was passed to LAC for the cryptographic processing and contains all
- + * the relevant information for cleaning up buffer handles etc. so that the
- + * OCF EP80579 Driver portion of this crypto operation can be fully completed.
- + */
- +static void
- +icp_ocfDrvSymCallBack(void *callbackTag,
- + CpaStatus status,
- + const CpaCySymOp operationType,
- + void *pOpData,
- + CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
- +{
- + struct cryptop *crp = NULL;
- + struct icp_drvOpData *temp_drvOpData =
- + (struct icp_drvOpData *)callbackTag;
- + uint64_t *tempBasePtr = NULL;
- + uint32_t tempLen = 0;
- +
- + if (NULL == temp_drvOpData) {
- + DPRINTK("%s(): The callback from the LAC component"
- + " has failed due to Null userOpaque data"
- + "(status == %d).\n", __FUNCTION__, status);
- + DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
- + return;
- + }
- +
- + crp = temp_drvOpData->crp;
- + crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
- +
- + if (NULL == pOpData) {
- + DPRINTK("%s(): The callback from the LAC component"
- + " has failed due to Null Symmetric Op data"
- + "(status == %d).\n", __FUNCTION__, status);
- + crp->crp_etype = ECANCELED;
- + crypto_done(crp);
- + return;
- + }
- +
- + if (NULL == pDstBuffer) {
- + DPRINTK("%s(): The callback from the LAC component"
- + " has failed due to Null Dst Bufferlist data"
- + "(status == %d).\n", __FUNCTION__, status);
- + crp->crp_etype = ECANCELED;
- + crypto_done(crp);
- + return;
- + }
- +
- + if (CPA_STATUS_SUCCESS == status) {
- +
- + if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
- + (icp_packet_buffer_t
- + **)
- + & (crp->crp_buf))) {
- + EPRINTK("%s(): BufferList to SkBuff "
- + "conversion error.\n", __FUNCTION__);
- + crp->crp_etype = EPERM;
- + }
- + } else {
- + icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
- + (void **)&tempBasePtr,
- + &tempLen);
- + crp->crp_olen = (int)tempLen;
- + }
- +
- + } else {
- + DPRINTK("%s(): The callback from the LAC component has failed"
- + "(status == %d).\n", __FUNCTION__, status);
- +
- + crp->crp_etype = ECANCELED;
- + }
- +
- + if (temp_drvOpData->numBufferListArray >
- + ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
- + icp_kfree(pDstBuffer->pBuffers);
- + }
- + icp_ocfDrvFreeMetaData(pDstBuffer);
- + ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
- +
- + /* Invoke the OCF callback function */
- + crypto_done(crp);
- +
- + return;
- +}
- +
- +/* Name : icp_ocfDrvNewSession
- + *
- + * Description : This function will create a new Driver<->OCF session
- + *
- + * Notes : LAC session registration happens during the first perform call.
- + * That is the first time we know all information about a given session.
- + */
- +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
- + struct cryptoini *cri)
- +{
- + struct icp_drvSessionData *sessionData = NULL;
- + uint32_t delete_session = 0;
- +
- + /* The SID passed in should be our driver ID. We can return the */
- + /* local ID (LID) which is a unique identifier which we can use */
- + /* to differentiate between the encrypt/decrypt LAC session handles */
- + if (NULL == sid) {
- + EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
- + __FUNCTION__);
- + return EINVAL;
- + }
- +
- + if (NULL == cri) {
- + EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
- + __FUNCTION__);
- + return EINVAL;
- + }
- +
- + if (icp_ocfDrvDriverId != *sid) {
- + EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
- + __FUNCTION__);
- + EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
- + return EINVAL;
- + }
- +
- + sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);
- + if (NULL == sessionData) {
- + DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
- + return ENOMEM;
- + }
- +
- + /*ENTER CRITICAL SECTION */
- + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
- + /*put this check in the spinlock so no new sessions can be added to the
- + linked list when we are exiting */
- + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
- + delete_session++;
- +
- + } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
- + if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
- + (max_sessions -
- + icp_atomic_read(&lac_session_failed_dereg_count))) {
- + delete_session++;
- + } else {
- + icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
- + /* Add to session data linked list */
- + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
- + listNode);
- + }
- +
- + } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
- + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
- + listNode);
- + }
- +
- + sessionData->inUse = ICP_SESSION_INITIALISED;
- +
- + /*EXIT CRITICAL SECTION */
- + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
- +
- + if (delete_session) {
- + DPRINTK("%s():No Session handles available\n", __FUNCTION__);
- + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
- + return EPERM;
- + }
- +
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
- + DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
- + icp_ocfDrvFreeOCFSession(sessionData);
- + return EINVAL;
- + }
- +
- + if (cri->cri_next) {
- + if (cri->cri_next->cri_next != NULL) {
- + DPRINTK("%s():only two chained algorithms supported\n",
- + __FUNCTION__);
- + icp_ocfDrvFreeOCFSession(sessionData);
- + return EPERM;
- + }
- +
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvAlgorithmSetup(cri->cri_next,
- + &(sessionData->lacSessCtx))) {
- + DPRINTK("%s():second algorithm not supported\n",
- + __FUNCTION__);
- + icp_ocfDrvFreeOCFSession(sessionData);
- + return EINVAL;
- + }
- +
- + sessionData->lacSessCtx.symOperation =
- + CPA_CY_SYM_OP_ALGORITHM_CHAINING;
- + }
- +
- + *sid = (uint32_t) sessionData;
- +
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- +}
- +
- +/* Name : icp_ocfDrvAlgorithmSetup
- + *
- + * Description : This function builds the session context data from the
- + * information supplied through OCF. Algorithm chain order and whether the
- + * session is Encrypt/Decrypt can only be found out at perform time however, so
- + * the session is registered with LAC at that time.
- + */
- +static int
- +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
- + CpaCySymSessionSetupData * lacSessCtx)
- +{
- +
- + lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
- +
- + switch (cri->cri_alg) {
- +
- + case CRYPTO_NULL_CBC:
- + DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
- + lacSessCtx->cipherSetupData.cipherAlgorithm =
- + CPA_CY_SYM_CIPHER_NULL;
- + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
- + break;
- +
- + case CRYPTO_DES_CBC:
- + DPRINTK("%s(): DES CBC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
- + lacSessCtx->cipherSetupData.cipherAlgorithm =
- + CPA_CY_SYM_CIPHER_DES_CBC;
- + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
- + break;
- +
- + case CRYPTO_3DES_CBC:
- + DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
- + lacSessCtx->cipherSetupData.cipherAlgorithm =
- + CPA_CY_SYM_CIPHER_3DES_CBC;
- + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
- + break;
- +
- + case CRYPTO_AES_CBC:
- + DPRINTK("%s(): AES CBC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
- + lacSessCtx->cipherSetupData.cipherAlgorithm =
- + CPA_CY_SYM_CIPHER_AES_CBC;
- + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
- + break;
- +
- + case CRYPTO_ARC4:
- + DPRINTK("%s(): ARC4\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
- + lacSessCtx->cipherSetupData.cipherAlgorithm =
- + CPA_CY_SYM_CIPHER_ARC4;
- + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
- + break;
- +
- + case CRYPTO_SHA1:
- + DPRINTK("%s(): SHA1\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
- +
- + break;
- +
- + case CRYPTO_SHA1_HMAC:
- + DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
- + lacSessCtx->hashSetupData.authModeSetupData.authKey =
- + cri->cri_key;
- + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
- +
- + break;
- +
- + case CRYPTO_SHA2_256:
- + DPRINTK("%s(): SHA256\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm =
- + CPA_CY_SYM_HASH_SHA256;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
- +
- + break;
- +
- + case CRYPTO_SHA2_256_HMAC:
- + DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm =
- + CPA_CY_SYM_HASH_SHA256;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
- + lacSessCtx->hashSetupData.authModeSetupData.authKey =
- + cri->cri_key;
- + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
- +
- + break;
- +
- + case CRYPTO_SHA2_384:
- + DPRINTK("%s(): SHA384\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm =
- + CPA_CY_SYM_HASH_SHA384;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
- +
- + break;
- +
- + case CRYPTO_SHA2_384_HMAC:
- + DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm =
- + CPA_CY_SYM_HASH_SHA384;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
- + lacSessCtx->hashSetupData.authModeSetupData.authKey =
- + cri->cri_key;
- + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
- +
- + break;
- +
- + case CRYPTO_SHA2_512:
- + DPRINTK("%s(): SHA512\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm =
- + CPA_CY_SYM_HASH_SHA512;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
- +
- + break;
- +
- + case CRYPTO_SHA2_512_HMAC:
- + DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm =
- + CPA_CY_SYM_HASH_SHA512;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
- + lacSessCtx->hashSetupData.authModeSetupData.authKey =
- + cri->cri_key;
- + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
- +
- + break;
- +
- + case CRYPTO_MD5:
- + DPRINTK("%s(): MD5\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
- +
- + break;
- +
- + case CRYPTO_MD5_HMAC:
- + DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
- + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
- + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
- + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
- + lacSessCtx->hashSetupData.digestResultLenInBytes =
- + (cri->cri_mlen ?
- + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
- + lacSessCtx->hashSetupData.authModeSetupData.authKey =
- + cri->cri_key;
- + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
- + cri->cri_klen / NUM_BITS_IN_BYTE;
- + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
- +
- + break;
- +
- + default:
- + DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
- + return ICP_OCF_DRV_STATUS_FAIL;
- + }
- +
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- +}
- +
- +/* Name : icp_ocfDrvFreeOCFSession
- + *
- + * Description : This function deletes all existing Session data representing
- + * the Cryptographic session established between OCF and this driver. This
- + * also includes freeing the memory allocated for the session context. The
- + * session object is also removed from the session linked list.
- + */
- +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
- +{
- +
- + sessionData->inUse = ICP_SESSION_DEREGISTERED;
- +
- + /*ENTER CRITICAL SECTION */
- + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
- +
- + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
- + /*If the Driver is exiting, allow that process to
- + handle any deletions */
- + /*EXIT CRITICAL SECTION */
- + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
- + return;
- + }
- +
- + icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
- +
- + ICP_LIST_DEL(sessionData, listNode);
- +
- + /*EXIT CRITICAL SECTION */
- + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
- +
- + if (NULL != sessionData->sessHandle) {
- + icp_kfree(sessionData->sessHandle);
- + }
- + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
- +}
- +
- +/* Name : icp_ocfDrvFreeLACSession
- + *
- + * Description : This attempts to deregister a LAC session. If it fails, the
- + * deregistation retry function is called.
- + */
- +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
- +{
- + CpaCySymSessionCtx sessionToDeregister = NULL;
- + struct icp_drvSessionData *sessionData = NULL;
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + int retval = 0;
- +
- + sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
- + if (NULL == sessionData) {
- + EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
- + __FUNCTION__);
- + return EINVAL;
- + }
- +
- + sessionToDeregister = sessionData->sessHandle;
- +
- + if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&
- + (ICP_SESSION_RUNNING != sessionData->inUse) &&
- + (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {
- + DPRINTK("%s() Session not initialised.\n", __FUNCTION__);
- + return EINVAL;
- + }
- +
- + if (ICP_SESSION_RUNNING == sessionData->inUse) {
- + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
- + sessionToDeregister);
- + if (CPA_STATUS_RETRY == lacStatus) {
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvDeregRetry(&sessionToDeregister)) {
- + /* the retry function increments the
- + dereg failed count */
- + DPRINTK("%s(): LAC failed to deregister the "
- + "session. (localSessionId= %p)\n",
- + __FUNCTION__, sessionToDeregister);
- + retval = EPERM;
- + }
- +
- + } else if (CPA_STATUS_SUCCESS != lacStatus) {
- + DPRINTK("%s(): LAC failed to deregister the session. "
- + "localSessionId= %p, lacStatus = %d\n",
- + __FUNCTION__, sessionToDeregister, lacStatus);
- + icp_atomic_inc(&lac_session_failed_dereg_count);
- + retval = EPERM;
- + }
- + } else {
- + DPRINTK("%s() Session not registered with LAC.\n",
- + __FUNCTION__);
- + }
- +
- + icp_ocfDrvFreeOCFSession(sessionData);
- + return retval;
- +
- +}
- +
- +/* Name : icp_ocfDrvAlgCheck
- + *
- + * Description : This function checks whether the cryptodesc argument pertains
- + * to a sym or hash function
- + */
- +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
- +{
- +
- + if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
- + crp_desc->crd_alg == CRYPTO_AES_CBC ||
- + crp_desc->crd_alg == CRYPTO_DES_CBC ||
- + crp_desc->crd_alg == CRYPTO_NULL_CBC ||
- + crp_desc->crd_alg == CRYPTO_ARC4) {
- + return ICP_OCF_DRV_ALG_CIPHER;
- + }
- +
- + return ICP_OCF_DRV_ALG_HASH;
- +}
- +
- +/* Name : icp_ocfDrvSymProcess
- + *
- + * Description : This function will map symmetric functionality calls from OCF
- + * to the LAC API. It will also allocate memory to store the session context.
- + *
- + * Notes: If it is the first perform call for a given session, then a LAC
- + * session is registered. After the session is registered, no checks as
- + * to whether session paramaters have changed (e.g. alg chain order) are
- + * done.
- + */
- +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
- +{
- + struct icp_drvSessionData *sessionData = NULL;
- + struct icp_drvOpData *drvOpData = NULL;
- + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
- + Cpa32U sessionCtxSizeInBytes = 0;
- +
- + if (NULL == crp) {
- + DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
- + __FUNCTION__);
- + return EINVAL;
- + }
- +
- + if (NULL == crp->crp_desc) {
- + DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
- + "to crp\n", __FUNCTION__);
- + crp->crp_etype = EINVAL;
- + return EINVAL;
- + }
- +
- + if (NULL == crp->crp_buf) {
- + DPRINTK("%s(): Invalid input parameters, no buffer attached "
- + "to crp\n", __FUNCTION__);
- + crp->crp_etype = EINVAL;
- + return EINVAL;
- + }
- +
- + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
- + crp->crp_etype = EFAULT;
- + return EFAULT;
- + }
- +
- + sessionData = (struct icp_drvSessionData *)
- + (CRYPTO_SESID2LID(crp->crp_sid));
- + if (NULL == sessionData) {
- + DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
- + __FUNCTION__);
- + crp->crp_etype = EINVAL;
- + return EINVAL;
- + }
- +
- +/*If we get a request against a deregisted session, cancel operation*/
- + if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
- + DPRINTK("%s(): Session ID %d was deregistered \n",
- + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
- + crp->crp_etype = EFAULT;
- + return EFAULT;
- + }
- +
- +/*If none of the session states are set, then the session structure was either
- + not initialised properly or we are reading from a freed memory area (possible
- + due to OCF batch mode not removing queued requests against deregistered
- + sessions*/
- + if (ICP_SESSION_INITIALISED != sessionData->inUse &&
- + ICP_SESSION_RUNNING != sessionData->inUse) {
- + DPRINTK("%s(): Session - ID %d - not properly initialised or "
- + "memory freed back to the kernel \n",
- + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
- + crp->crp_etype = EINVAL;
- + return EINVAL;
- + }
- +
- + /*For the below checks, remember error checking is already done in LAC.
- + We're not validating inputs subsequent to registration */
- + if (sessionData->inUse == ICP_SESSION_INITIALISED) {
- + DPRINTK("%s(): Initialising session\n", __FUNCTION__);
- +
- + if (NULL != crp->crp_desc->crd_next) {
- + if (ICP_OCF_DRV_ALG_CIPHER ==
- + icp_ocfDrvAlgCheck(crp->crp_desc)) {
- +
- + sessionData->lacSessCtx.algChainOrder =
- + CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
- +
- + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
- + sessionData->lacSessCtx.cipherSetupData.
- + cipherDirection =
- + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
- + } else {
- + sessionData->lacSessCtx.cipherSetupData.
- + cipherDirection =
- + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
- + }
- + } else {
- + sessionData->lacSessCtx.algChainOrder =
- + CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
- +
- + if (crp->crp_desc->crd_next->crd_flags &
- + CRD_F_ENCRYPT) {
- + sessionData->lacSessCtx.cipherSetupData.
- + cipherDirection =
- + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
- + } else {
- + sessionData->lacSessCtx.cipherSetupData.
- + cipherDirection =
- + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
- + }
- +
- + }
- +
- + } else if (ICP_OCF_DRV_ALG_CIPHER ==
- + icp_ocfDrvAlgCheck(crp->crp_desc)) {
- + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
- + sessionData->lacSessCtx.cipherSetupData.
- + cipherDirection =
- + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
- + } else {
- + sessionData->lacSessCtx.cipherSetupData.
- + cipherDirection =
- + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
- + }
- +
- + }
- +
- + /*No action required for standalone Auth here */
- +
- + /* Allocate memory for SymSessionCtx before the Session Registration */
- + lacStatus =
- + cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
- + &(sessionData->lacSessCtx),
- + &sessionCtxSizeInBytes);
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
- + __FUNCTION__, lacStatus);
- + crp->crp_etype = EINVAL;
- + return EINVAL;
- + }
- + sessionData->sessHandle =
- + icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
- + if (NULL == sessionData->sessHandle) {
- + EPRINTK
- + ("%s(): Failed to get memory for SymSessionCtx\n",
- + __FUNCTION__);
- + crp->crp_etype = ENOMEM;
- + return ENOMEM;
- + }
- +
- + lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
- + icp_ocfDrvSymCallBack,
- + &(sessionData->lacSessCtx),
- + sessionData->sessHandle);
- +
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
- + __FUNCTION__, lacStatus);
- + crp->crp_etype = EFAULT;
- + return EFAULT;
- + }
- +
- + sessionData->inUse = ICP_SESSION_RUNNING;
- + }
- +
- + drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);
- + if (NULL == drvOpData) {
- + EPRINTK("%s():Failed to get memory for drvOpData\n",
- + __FUNCTION__);
- + crp->crp_etype = ENOMEM;
- + return ENOMEM;
- + }
- +
- + drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
- + drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
- + digestResultLenInBytes;
- + drvOpData->crp = crp;
- +
- + /* Set the default buffer list array memory allocation */
- + drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
- + drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
- +
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
- + crp->crp_etype = EINVAL;
- + goto err;
- + }
- +
- + if (drvOpData->crp->crp_desc->crd_next != NULL) {
- + if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
- + crp_desc->crd_next)) {
- + crp->crp_etype = EINVAL;
- + goto err;
- + }
- +
- + }
- +
- + /*
- + * Allocate buffer list array memory if the data fragment is more than
- + * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
- + * calculated already
- + */
- + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
- + if (NULL == drvOpData->lacOpData.pDigestResult) {
- + drvOpData->numBufferListArray =
- + icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)
- + crp->crp_buf);
- + }
- +
- + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
- + drvOpData->numBufferListArray) {
- + DPRINTK("%s() numBufferListArray more than default\n",
- + __FUNCTION__);
- + drvOpData->srcBuffer.pBuffers = NULL;
- + drvOpData->srcBuffer.pBuffers =
- + icp_kmalloc(drvOpData->numBufferListArray *
- + sizeof(CpaFlatBuffer), ICP_M_NOWAIT);
- + if (NULL == drvOpData->srcBuffer.pBuffers) {
- + EPRINTK("%s() Failed to get memory for "
- + "pBuffers\n", __FUNCTION__);
- + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
- + crp->crp_etype = ENOMEM;
- + return ENOMEM;
- + }
- + }
- + }
- +
- + /*
- + * Check the type of buffer structure we got and convert it into
- + * CpaBufferList format.
- + */
- + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
- + crp->crp_buf,
- + &(drvOpData->srcBuffer))) {
- + EPRINTK("%s():Failed to translate from packet buffer "
- + "to bufferlist\n", __FUNCTION__);
- + crp->crp_etype = EINVAL;
- + goto err;
- + }
- +
- + drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + /* OCF only supports IOV of one entry. */
- + if (NUM_IOV_SUPPORTED ==
- + ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
- +
- + icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
- + crp_buf))->
- + uio_iov[0].iov_base,
- + ((struct uio *)(crp->
- + crp_buf))->
- + uio_iov[0].iov_len,
- + &(drvOpData->
- + srcBuffer));
- +
- + drvOpData->bufferType = CRYPTO_F_IOV;
- +
- + } else {
- + DPRINTK("%s():Unable to handle IOVs with lengths of "
- + "greater than one!\n", __FUNCTION__);
- + crp->crp_etype = EINVAL;
- + goto err;
- + }
- +
- + } else {
- + icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
- + crp->crp_ilen,
- + &(drvOpData->srcBuffer));
- +
- + drvOpData->bufferType = CRYPTO_BUF_CONTIG;
- + }
- +
- + /* Allocate srcBuffer's private meta data */
- + if (ICP_OCF_DRV_STATUS_SUCCESS !=
- + icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
- + EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
- + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
- + crp->crp_etype = EINVAL;
- + goto err;
- + }
- +
- + /* Perform "in-place" crypto operation */
- + lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
- + (void *)drvOpData,
- + &(drvOpData->lacOpData),
- + &(drvOpData->srcBuffer),
- + &(drvOpData->srcBuffer),
- + &(drvOpData->verifyResult));
- + if (CPA_STATUS_RETRY == lacStatus) {
- + DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
- + __FUNCTION__, lacStatus);
- + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
- + crp->crp_etype = ERESTART;
- + goto err;
- + }
- + if (CPA_STATUS_SUCCESS != lacStatus) {
- + EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
- + __FUNCTION__, lacStatus);
- + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
- + crp->crp_etype = EINVAL;
- + goto err;
- + }
- +
- + return 0; //OCF success status value
- +
- + err:
- + if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
- + icp_kfree(drvOpData->srcBuffer.pBuffers);
- + }
- + icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
- + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
- +
- + return crp->crp_etype;
- +}
- +
- +/* Name : icp_ocfDrvProcessDataSetup
- + *
- + * Description : This function will setup all the cryptographic operation data
- + * that is required by LAC to execute the operation.
- + */
- +static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
- + struct cryptodesc *crp_desc)
- +{
- + CpaCyRandGenOpData randGenOpData;
- + CpaFlatBuffer randData;
- +
- + drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
- +
- + /* Convert from the cryptop to the ICP LAC crypto parameters */
- + switch (crp_desc->crd_alg) {
- + case CRYPTO_NULL_CBC:
- + drvOpData->lacOpData.
- + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
- + drvOpData->lacOpData.
- + messageLenToCipherInBytes = crp_desc->crd_len;
- + drvOpData->verifyResult = CPA_FALSE;
- + drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
- + break;
- + case CRYPTO_DES_CBC:
- + drvOpData->lacOpData.
- + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
- + drvOpData->lacOpData.
- + messageLenToCipherInBytes = crp_desc->crd_len;
- + drvOpData->verifyResult = CPA_FALSE;
- + drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
- + break;
- + case CRYPTO_3DES_CBC:
- + drvOpData->lacOpData.
- + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
- + drvOpData->lacOpData.
- + messageLenToCipherInBytes = crp_desc->crd_len;
- + drvOpData->verifyResult = CPA_FALSE;
- + drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
- + break;
- + case CRYPTO_ARC4:
- + drvOpData->lacOpData.
- + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
- + drvOpData->lacOpData.
- + messageLenToCipherInBytes = crp_desc->crd_len;
- + drvOpData->verifyResult = CPA_FALSE;
- + drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
- + break;
- + case CRYPTO_AES_CBC:
- + drvOpData->lacOpData.
- + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
- + drvOpData->lacOpData.
- + messageLenToCipherInBytes = crp_desc->crd_len;
- + drvOpData->verifyResult = CPA_FALSE;
- + drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
- + break;
- + case CRYPTO_SHA1:
- + case CRYPTO_SHA1_HMAC:
- + case CRYPTO_SHA2_256:
- + case CRYPTO_SHA2_256_HMAC:
- + case CRYPTO_SHA2_384:
- + case CRYPTO_SHA2_384_HMAC:
- + case CRYPTO_SHA2_512:
- + case CRYPTO_SHA2_512_HMAC:
- + case CRYPTO_MD5:
- + case CRYPTO_MD5_HMAC:
- + drvOpData->lacOpData.
- + hashStartSrcOffsetInBytes = crp_desc->crd_skip;
- + drvOpData->lacOpData.
- + messageLenToHashInBytes = crp_desc->crd_len;
- + drvOpData->lacOpData.
- + pDigestResult =
- + icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
- +
- + if (NULL == drvOpData->lacOpData.pDigestResult) {
- + DPRINTK("%s(): ERROR - could not calculate "
- + "Digest Result memory address\n", __FUNCTION__);
- + return ICP_OCF_DRV_STATUS_FAIL;
- + }
- +
- + drvOpData->lacOpData.digestVerify = CPA_FALSE;
- + break;
- + default:
- + DPRINTK("%s(): Crypto process error - algorithm not "
- + "found \n", __FUNCTION__);
- + return ICP_OCF_DRV_STATUS_FAIL;
- + }
- +
- + /* Figure out what the IV is supposed to be */
- + if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
- + (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
- + (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
- + /*ARC4 doesn't use an IV */
- + if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
- + /* Explicit IV provided to OCF */
- + drvOpData->lacOpData.pIv = crp_desc->crd_iv;
- + } else {
- + /* IV is not explicitly provided to OCF */
- +
- + /* Point the LAC OP Data IV pointer to our allocated
- + storage location for this session. */
- + drvOpData->lacOpData.pIv = drvOpData->ivData;
- +
- + if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
- + ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
- +
- + /* Encrypting - need to create IV */
- + randGenOpData.generateBits = CPA_TRUE;
- + randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
- +
- + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
- + drvOpData->
- + ivData,
- + MAX_IV_LEN_IN_BYTES,
- + &randData);
- +
- + if (CPA_STATUS_SUCCESS !=
- + cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
- + NULL, NULL,
- + &randGenOpData, &randData)) {
- + DPRINTK("%s(): ERROR - Failed to"
- + " generate"
- + " Initialisation Vector\n",
- + __FUNCTION__);
- + return ICP_OCF_DRV_STATUS_FAIL;
- + }
- +
- + crypto_copyback(drvOpData->crp->
- + crp_flags,
- + drvOpData->crp->crp_buf,
- + crp_desc->crd_inject,
- + drvOpData->lacOpData.
- + ivLenInBytes,
- + (caddr_t) (drvOpData->lacOpData.
- + pIv));
- + } else {
- + /* Reading IV from buffer */
- + crypto_copydata(drvOpData->crp->
- + crp_flags,
- + drvOpData->crp->crp_buf,
- + crp_desc->crd_inject,
- + drvOpData->lacOpData.
- + ivLenInBytes,
- + (caddr_t) (drvOpData->lacOpData.
- + pIv));
- + }
- +
- + }
- +
- + }
- +
- + return ICP_OCF_DRV_STATUS_SUCCESS;
- +}
- +
- +/* Name : icp_ocfDrvDigestPointerFind
- + *
- + * Description : This function is used to find the memory address of where the
- + * digest information shall be stored in. Input buffer types are an skbuff, iov
- + * or flat buffer. The address is found using the buffer data start address and
- + * an offset.
- + *
- + * Note: In the case of a linux skbuff, the digest address may exist within
- + * a memory space linked to from the start buffer. These linked memory spaces
- + * must be traversed by the data length offset in order to find the digest start
- + * address. Whether there is enough space for the digest must also be checked.
- + */
- +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
- + struct cryptodesc * crp_desc)
- +{
- +
- + int offsetInBytes = crp_desc->crd_inject;
- + uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
- + uint8_t *flat_buffer_base = NULL;
- + int flat_buffer_length = 0;
- +
- + if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
- +
- + return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
- + offsetInBytes,
- + digestSizeInBytes);
- +
- + } else {
- + /* IOV or flat buffer */
- + if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
- + /*single IOV check has already been done */
- + flat_buffer_base = ((struct uio *)
- + (drvOpData->crp->crp_buf))->
- + uio_iov[0].iov_base;
- + flat_buffer_length = ((struct uio *)
- + (drvOpData->crp->crp_buf))->
- + uio_iov[0].iov_len;
- + } else {
- + flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
- + flat_buffer_length = drvOpData->crp->crp_ilen;
- + }
- +
- + if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
- + DPRINTK("%s() Not enough space for Digest "
- + "(IOV/Flat Buffer) \n", __FUNCTION__);
- + return NULL;
- + } else {
- + return (uint8_t *) (flat_buffer_base + offsetInBytes);
- + }
- + }
- + DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
- + return NULL;
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/Makefile linux-2.6.36/crypto/ocf/ep80579/Makefile
- --- linux-2.6.36.orig/crypto/ocf/ep80579/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ep80579/Makefile 2010-11-09 20:28:04.742495461 +0100
- @@ -0,0 +1,119 @@
- +#########################################################################
- +#
- +# Targets supported
- +# all - builds everything and installs
- +# install - identical to all
- +# depend - build dependencies
- +# clean - clears derived objects except the .depend files
- +# distclean- clears all derived objects and the .depend file
- +#
- +# @par
- +# This file is provided under a dual BSD/GPLv2 license. When using or
- +# redistributing this file, you may do so under either license.
- +#
- +# GPL LICENSE SUMMARY
- +#
- +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- +#
- +# This program is free software; you can redistribute it and/or modify
- +# it under the terms of version 2 of the GNU General Public License as
- +# published by the Free Software Foundation.
- +#
- +# This program is distributed in the hope that it will be useful, but
- +# WITHOUT ANY WARRANTY; without even the implied warranty of
- +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- +# General Public License for more details.
- +#
- +# You should have received a copy of the GNU General Public License
- +# along with this program; if not, write to the Free Software
- +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- +# The full GNU General Public License is included in this distribution
- +# in the file called LICENSE.GPL.
- +#
- +# Contact Information:
- +# Intel Corporation
- +#
- +# BSD LICENSE
- +#
- +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
- +# All rights reserved.
- +#
- +# Redistribution and use in source and binary forms, with or without
- +# modification, are permitted provided that the following conditions
- +# are met:
- +#
- +# * Redistributions of source code must retain the above copyright
- +# notice, this list of conditions and the following disclaimer.
- +# * Redistributions in binary form must reproduce the above copyright
- +# notice, this list of conditions and the following disclaimer in
- +# the documentation and/or other materials provided with the
- +# distribution.
- +# * Neither the name of Intel Corporation nor the names of its
- +# contributors may be used to endorse or promote products derived
- +# from this software without specific prior written permission.
- +#
- +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +#
- +#
- +# version: Security.L.1.0.2-229
- +############################################################################
- +
- +
- +####################Common variables and definitions########################
- +
- +ifndef ICP_ROOT
- +$(warning ICP_ROOT is undefined. Please set the path to EP80579 release package directory \
- + "-> setenv ICP_ROOT <path>")
- +all fastdep:
- + :
- +else
- +
- +ifndef KERNEL_SOURCE_ROOT
- +$(error KERNEL_SOURCE_ROOT is undefined. Please set the path to the kernel source directory \
- + "-> setenv KERNEL_SOURCE_ROOT <path>")
- +endif
- +
- +# Ensure The ENV_DIR environmental var is defined.
- +ifndef ICP_ENV_DIR
- +$(error ICP_ENV_DIR is undefined. Please set the path to EP80579 driver environment.mk file \
- + "-> setenv ICP_ENV_DIR <path>")
- +endif
- +
- +#Add your project environment Makefile
- +include ${ICP_ENV_DIR}/environment.mk
- +
- +#include the makefile with all the default and common Make variable definitions
- +include ${ICP_BUILDSYSTEM_PATH}/build_files/common.mk
- +
- +#Add the name for the executable, Library or Module output definitions
- +OUTPUT_NAME= icp_ocf
- +
- +# List of Source Files to be compiled
- +SOURCES= icp_common.c icp_sym.c icp_asym.c icp_ocf_linux.c
- +
- +#common includes between all supported OSes
- +INCLUDES= -I ${ICP_API_DIR} -I${ICP_LAC_API} \
- +-I${ICP_OCF_SRC_DIR}
- +
- +# The location of the os level makefile needs to be changed.
- +include ${ICP_ENV_DIR}/${ICP_OS}_${ICP_OS_LEVEL}.mk
- +
- +# On the line directly below list the outputs you wish to build for,
- +# e.g "lib_static lib_shared exe module" as shown below
- +install: module
- +
- +###################Include rules makefiles########################
- +include ${ICP_BUILDSYSTEM_PATH}/build_files/rules.mk
- +###################End of Rules inclusion#########################
- +
- +endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.36/crypto/ocf/hifn/hifn7751.c
- --- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/hifn/hifn7751.c 2010-11-09 20:28:04.752495537 +0100
- @@ -0,0 +1,2976 @@
- +/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
- +
- +/*-
- + * Invertex AEON / Hifn 7751 driver
- + * Copyright (c) 1999 Invertex Inc. All rights reserved.
- + * Copyright (c) 1999 Theo de Raadt
- + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
- + * http://www.netsec.net
- + * Copyright (c) 2003 Hifn Inc.
- + *
- + * This driver is based on a previous driver by Invertex, for which they
- + * requested: Please send any comments, feedback, bug-fixes, or feature
- + * requests to software@invertex.com.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored in part by the Defense Advanced Research Projects
- + * Agency (DARPA) and Air Force Research Laboratory, Air Force
- + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- + *
- + *
- +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
- + */
- +
- +/*
- + * Driver for various Hifn encryption processors.
- + */
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/wait.h>
- +#include <linux/sched.h>
- +#include <linux/pci.h>
- +#include <linux/delay.h>
- +#include <linux/interrupt.h>
- +#include <linux/spinlock.h>
- +#include <linux/random.h>
- +#include <linux/version.h>
- +#include <linux/skbuff.h>
- +#include <asm/io.h>
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +#include <hifn/hifn7751reg.h>
- +#include <hifn/hifn7751var.h>
- +
- +#if 1
- +#define DPRINTF(a...) if (hifn_debug) { \
- + printk("%s: ", sc ? \
- + device_get_nameunit(sc->sc_dev) : "hifn"); \
- + printk(a); \
- + } else
- +#else
- +#define DPRINTF(a...)
- +#endif
- +
- +static inline int
- +pci_get_revid(struct pci_dev *dev)
- +{
- + u8 rid = 0;
- + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
- + return rid;
- +}
- +
- +static struct hifn_stats hifnstats;
- +
- +#define debug hifn_debug
- +int hifn_debug = 0;
- +module_param(hifn_debug, int, 0644);
- +MODULE_PARM_DESC(hifn_debug, "Enable debug");
- +
- +int hifn_maxbatch = 1;
- +module_param(hifn_maxbatch, int, 0644);
- +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
- +
- +int hifn_cache_linesize = 0x10;
- +module_param(hifn_cache_linesize, int, 0444);
- +MODULE_PARM_DESC(hifn_cache_linesize, "PCI config cache line size");
- +
- +#ifdef MODULE_PARM
- +char *hifn_pllconfig = NULL;
- +MODULE_PARM(hifn_pllconfig, "s");
- +#else
- +char hifn_pllconfig[32]; /* This setting is RO after loading */
- +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
- +#endif
- +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
- +
- +#ifdef HIFN_VULCANDEV
- +#include <sys/conf.h>
- +#include <sys/uio.h>
- +
- +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
- +#endif
- +
- +/*
- + * Prototypes and count for the pci_device structure
- + */
- +static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
- +static void hifn_remove(struct pci_dev *dev);
- +
- +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
- +static int hifn_freesession(device_t, u_int64_t);
- +static int hifn_process(device_t, struct cryptop *, int);
- +
- +static device_method_t hifn_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, hifn_newsession),
- + DEVMETHOD(cryptodev_freesession,hifn_freesession),
- + DEVMETHOD(cryptodev_process, hifn_process),
- +};
- +
- +static void hifn_reset_board(struct hifn_softc *, int);
- +static void hifn_reset_puc(struct hifn_softc *);
- +static void hifn_puc_wait(struct hifn_softc *);
- +static int hifn_enable_crypto(struct hifn_softc *);
- +static void hifn_set_retry(struct hifn_softc *sc);
- +static void hifn_init_dma(struct hifn_softc *);
- +static void hifn_init_pci_registers(struct hifn_softc *);
- +static int hifn_sramsize(struct hifn_softc *);
- +static int hifn_dramsize(struct hifn_softc *);
- +static int hifn_ramtype(struct hifn_softc *);
- +static void hifn_sessions(struct hifn_softc *);
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- +static irqreturn_t hifn_intr(int irq, void *arg);
- +#else
- +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
- +#endif
- +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
- +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
- +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
- +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
- +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
- +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
- +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
- +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
- +static int hifn_init_pubrng(struct hifn_softc *);
- +static void hifn_tick(unsigned long arg);
- +static void hifn_abort(struct hifn_softc *);
- +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
- +
- +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
- +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
- +
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
- +#endif
- +
- +#define HIFN_MAX_CHIPS 8
- +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
- +
- +static __inline u_int32_t
- +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
- +{
- + u_int32_t v = readl(sc->sc_bar0 + reg);
- + sc->sc_bar0_lastreg = (bus_size_t) -1;
- + return (v);
- +}
- +#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
- +
- +static __inline u_int32_t
- +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
- +{
- + u_int32_t v = readl(sc->sc_bar1 + reg);
- + sc->sc_bar1_lastreg = (bus_size_t) -1;
- + return (v);
- +}
- +#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
- +
- +/*
- + * map in a given buffer (great on some arches :-)
- + */
- +
- +static int
- +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
- +{
- + struct iovec *iov = uio->uio_iov;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + buf->mapsize = 0;
- + for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
- + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
- + iov->iov_base, iov->iov_len,
- + PCI_DMA_BIDIRECTIONAL);
- + buf->segs[buf->nsegs].ds_len = iov->iov_len;
- + buf->mapsize += iov->iov_len;
- + iov++;
- + buf->nsegs++;
- + }
- + /* identify this buffer by the first segment */
- + buf->map = (void *) buf->segs[0].ds_addr;
- + return(0);
- +}
- +
- +/*
- + * map in a given sk_buff
- + */
- +
- +static int
- +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
- +{
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + buf->mapsize = 0;
- +
- + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
- + skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
- + buf->segs[0].ds_len = skb_headlen(skb);
- + buf->mapsize += buf->segs[0].ds_len;
- +
- + buf->nsegs = 1;
- +
- + for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
- + buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
- + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
- + page_address(skb_shinfo(skb)->frags[i].page) +
- + skb_shinfo(skb)->frags[i].page_offset,
- + buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
- + buf->mapsize += buf->segs[buf->nsegs].ds_len;
- + buf->nsegs++;
- + }
- +
- + /* identify this buffer by the first segment */
- + buf->map = (void *) buf->segs[0].ds_addr;
- + return(0);
- +}
- +
- +/*
- + * map in a given contiguous buffer
- + */
- +
- +static int
- +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
- +{
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + buf->mapsize = 0;
- + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
- + b, len, PCI_DMA_BIDIRECTIONAL);
- + buf->segs[0].ds_len = len;
- + buf->mapsize += buf->segs[0].ds_len;
- + buf->nsegs = 1;
- +
- + /* identify this buffer by the first segment */
- + buf->map = (void *) buf->segs[0].ds_addr;
- + return(0);
- +}
- +
- +#if 0 /* not needed at this time */
- +static void
- +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
- +{
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- + for (i = 0; i < buf->nsegs; i++)
- + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
- + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
- +}
- +#endif
- +
- +static void
- +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
- +{
- + int i;
- + DPRINTF("%s()\n", __FUNCTION__);
- + for (i = 0; i < buf->nsegs; i++) {
- + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
- + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
- + buf->segs[i].ds_addr = 0;
- + buf->segs[i].ds_len = 0;
- + }
- + buf->nsegs = 0;
- + buf->mapsize = 0;
- + buf->map = 0;
- +}
- +
- +static const char*
- +hifn_partname(struct hifn_softc *sc)
- +{
- + /* XXX sprintf numbers when not decoded */
- + switch (pci_get_vendor(sc->sc_pcidev)) {
- + case PCI_VENDOR_HIFN:
- + switch (pci_get_device(sc->sc_pcidev)) {
- + case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
- + case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
- + case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
- + case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
- + case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
- + case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
- + }
- + return "Hifn unknown-part";
- + case PCI_VENDOR_INVERTEX:
- + switch (pci_get_device(sc->sc_pcidev)) {
- + case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
- + }
- + return "Invertex unknown-part";
- + case PCI_VENDOR_NETSEC:
- + switch (pci_get_device(sc->sc_pcidev)) {
- + case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
- + }
- + return "NetSec unknown-part";
- + }
- + return "Unknown-vendor unknown-part";
- +}
- +
- +static u_int
- +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
- +{
- + struct hifn_softc *sc = pci_get_drvdata(dev);
- + if (v > max) {
- + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
- + "using max %u\n", what, v, max);
- + v = max;
- + } else if (v < min) {
- + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
- + "using min %u\n", what, v, min);
- + v = min;
- + }
- + return v;
- +}
- +
- +/*
- + * Select PLL configuration for 795x parts. This is complicated in
- + * that we cannot determine the optimal parameters without user input.
- + * The reference clock is derived from an external clock through a
- + * multiplier. The external clock is either the host bus (i.e. PCI)
- + * or an external clock generator. When using the PCI bus we assume
- + * the clock is either 33 or 66 MHz; for an external source we cannot
- + * tell the speed.
- + *
- + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
- + * for an external source, followed by the frequency. We calculate
- + * the appropriate multiplier and PLL register contents accordingly.
- + * When no configuration is given we default to "pci66" since that
- + * always will allow the card to work. If a card is using the PCI
- + * bus clock and in a 33MHz slot then it will be operating at half
- + * speed until the correct information is provided.
- + *
- + * We use a default setting of "ext66" because according to Mike Ham
- + * of HiFn, almost every board in existence has an external crystal
- + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
- + * because PCI33 can have clocks from 0 to 33Mhz, and some have
- + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
- + */
- +static void
- +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
- +{
- + const char *pllspec = hifn_pllconfig;
- + u_int freq, mul, fl, fh;
- + u_int32_t pllconfig;
- + char *nxt;
- +
- + if (pllspec == NULL)
- + pllspec = "ext66";
- + fl = 33, fh = 66;
- + pllconfig = 0;
- + if (strncmp(pllspec, "ext", 3) == 0) {
- + pllspec += 3;
- + pllconfig |= HIFN_PLL_REF_SEL;
- + switch (pci_get_device(dev)) {
- + case PCI_PRODUCT_HIFN_7955:
- + case PCI_PRODUCT_HIFN_7956:
- + fl = 20, fh = 100;
- + break;
- +#ifdef notyet
- + case PCI_PRODUCT_HIFN_7954:
- + fl = 20, fh = 66;
- + break;
- +#endif
- + }
- + } else if (strncmp(pllspec, "pci", 3) == 0)
- + pllspec += 3;
- + freq = strtoul(pllspec, &nxt, 10);
- + if (nxt == pllspec)
- + freq = 66;
- + else
- + freq = checkmaxmin(dev, "frequency", freq, fl, fh);
- + /*
- + * Calculate multiplier. We target a Fck of 266 MHz,
- + * allowing only even values, possibly rounded down.
- + * Multipliers > 8 must set the charge pump current.
- + */
- + mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
- + pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
- + if (mul > 8)
- + pllconfig |= HIFN_PLL_IS;
- + *pll = pllconfig;
- +}
- +
- +/*
- + * Attach an interface that successfully probed.
- + */
- +static int
- +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
- +{
- + struct hifn_softc *sc = NULL;
- + char rbase;
- + u_int16_t ena, rev;
- + int rseg, rc;
- + unsigned long mem_start, mem_len;
- + static int num_chips = 0;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (pci_enable_device(dev) < 0)
- + return(-ENODEV);
- +
- + if (pci_set_mwi(dev))
- + return(-ENODEV);
- +
- + if (!dev->irq) {
- + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
- + pci_disable_device(dev);
- + return(-ENODEV);
- + }
- +
- + sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
- + if (!sc)
- + return(-ENOMEM);
- + memset(sc, 0, sizeof(*sc));
- +
- + softc_device_init(sc, "hifn", num_chips, hifn_methods);
- +
- + sc->sc_pcidev = dev;
- + sc->sc_irq = -1;
- + sc->sc_cid = -1;
- + sc->sc_num = num_chips++;
- + if (sc->sc_num < HIFN_MAX_CHIPS)
- + hifn_chip_idx[sc->sc_num] = sc;
- +
- + pci_set_drvdata(sc->sc_pcidev, sc);
- +
- + spin_lock_init(&sc->sc_mtx);
- +
- + /* XXX handle power management */
- +
- + /*
- + * The 7951 and 795x have a random number generator and
- + * public key support; note this.
- + */
- + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
- + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
- + pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
- + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
- + sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
- + /*
- + * The 7811 has a random number generator and
- + * we also note it's identity 'cuz of some quirks.
- + */
- + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
- + pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
- + sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
- +
- + /*
- + * The 795x parts support AES.
- + */
- + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
- + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
- + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
- + sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
- + /*
- + * Select PLL configuration. This depends on the
- + * bus and board design and must be manually configured
- + * if the default setting is unacceptable.
- + */
- + hifn_getpllconfig(dev, &sc->sc_pllconfig);
- + }
- +
- + /*
- + * Setup PCI resources. Note that we record the bus
- + * tag and handle for each register mapping, this is
- + * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
- + * and WRITE_REG_1 macros throughout the driver.
- + */
- + mem_start = pci_resource_start(sc->sc_pcidev, 0);
- + mem_len = pci_resource_len(sc->sc_pcidev, 0);
- + sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
- + if (!sc->sc_bar0) {
- + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
- + goto fail;
- + }
- + sc->sc_bar0_lastreg = (bus_size_t) -1;
- +
- + mem_start = pci_resource_start(sc->sc_pcidev, 1);
- + mem_len = pci_resource_len(sc->sc_pcidev, 1);
- + sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
- + if (!sc->sc_bar1) {
- + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
- + goto fail;
- + }
- + sc->sc_bar1_lastreg = (bus_size_t) -1;
- +
- + /* fix up the bus size */
- + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
- + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
- + goto fail;
- + }
- + if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
- + device_printf(sc->sc_dev,
- + "No usable consistent DMA configuration, aborting.\n");
- + goto fail;
- + }
- +
- + hifn_set_retry(sc);
- +
- + /*
- + * Setup the area where the Hifn DMA's descriptors
- + * and associated data structures.
- + */
- + sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
- + sizeof(*sc->sc_dma),
- + &sc->sc_dma_physaddr);
- + if (!sc->sc_dma) {
- + device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
- + goto fail;
- + }
- + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
- +
- + /*
- + * Reset the board and do the ``secret handshake''
- + * to enable the crypto support. Then complete the
- + * initialization procedure by setting up the interrupt
- + * and hooking in to the system crypto support so we'll
- + * get used for system services like the crypto device,
- + * IPsec, RNG device, etc.
- + */
- + hifn_reset_board(sc, 0);
- +
- + if (hifn_enable_crypto(sc) != 0) {
- + device_printf(sc->sc_dev, "crypto enabling failed\n");
- + goto fail;
- + }
- + hifn_reset_puc(sc);
- +
- + hifn_init_dma(sc);
- + hifn_init_pci_registers(sc);
- +
- + pci_set_master(sc->sc_pcidev);
- +
- + /* XXX can't dynamically determine ram type for 795x; force dram */
- + if (sc->sc_flags & HIFN_IS_7956)
- + sc->sc_drammodel = 1;
- + else if (hifn_ramtype(sc))
- + goto fail;
- +
- + if (sc->sc_drammodel == 0)
- + hifn_sramsize(sc);
- + else
- + hifn_dramsize(sc);
- +
- + /*
- + * Workaround for NetSec 7751 rev A: half ram size because two
- + * of the address lines were left floating
- + */
- + if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
- + pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
- + pci_get_revid(dev) == 0x61) /*XXX???*/
- + sc->sc_ramsize >>= 1;
- +
- + /*
- + * Arrange the interrupt line.
- + */
- + rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
- + if (rc) {
- + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
- + goto fail;
- + }
- + sc->sc_irq = dev->irq;
- +
- + hifn_sessions(sc);
- +
- + /*
- + * NB: Keep only the low 16 bits; this masks the chip id
- + * from the 7951.
- + */
- + rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
- +
- + rseg = sc->sc_ramsize / 1024;
- + rbase = 'K';
- + if (sc->sc_ramsize >= (1024 * 1024)) {
- + rbase = 'M';
- + rseg /= 1024;
- + }
- + device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
- + hifn_partname(sc), rev,
- + rseg, rbase, sc->sc_drammodel ? 'd' : 's');
- + if (sc->sc_flags & HIFN_IS_7956)
- + printf(", pll=0x%x<%s clk, %ux mult>",
- + sc->sc_pllconfig,
- + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
- + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
- + printf("\n");
- +
- + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
- + if (sc->sc_cid < 0) {
- + device_printf(sc->sc_dev, "could not get crypto driver id\n");
- + goto fail;
- + }
- +
- + WRITE_REG_0(sc, HIFN_0_PUCNFG,
- + READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
- + ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
- +
- + switch (ena) {
- + case HIFN_PUSTAT_ENA_2:
- + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
- + if (sc->sc_flags & HIFN_HAS_AES)
- + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
- + /*FALLTHROUGH*/
- + case HIFN_PUSTAT_ENA_1:
- + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
- + break;
- + }
- +
- + if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
- + hifn_init_pubrng(sc);
- +
- + init_timer(&sc->sc_tickto);
- + sc->sc_tickto.function = hifn_tick;
- + sc->sc_tickto.data = (unsigned long) sc->sc_num;
- + mod_timer(&sc->sc_tickto, jiffies + HZ);
- +
- + return (0);
- +
- +fail:
- + if (sc->sc_cid >= 0)
- + crypto_unregister_all(sc->sc_cid);
- + if (sc->sc_irq != -1)
- + free_irq(sc->sc_irq, sc);
- + if (sc->sc_dma) {
- + /* Turn off DMA polling */
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
- +
- + pci_free_consistent(sc->sc_pcidev,
- + sizeof(*sc->sc_dma),
- + sc->sc_dma, sc->sc_dma_physaddr);
- + }
- + kfree(sc);
- + return (-ENXIO);
- +}
- +
- +/*
- + * Detach an interface that successfully probed.
- + */
- +static void
- +hifn_remove(struct pci_dev *dev)
- +{
- + struct hifn_softc *sc = pci_get_drvdata(dev);
- + unsigned long l_flags;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
- +
- + /* disable interrupts */
- + HIFN_LOCK(sc);
- + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
- + HIFN_UNLOCK(sc);
- +
- + /*XXX other resources */
- + del_timer_sync(&sc->sc_tickto);
- +
- + /* Turn off DMA polling */
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
- +
- + crypto_unregister_all(sc->sc_cid);
- +
- + free_irq(sc->sc_irq, sc);
- +
- + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
- + sc->sc_dma, sc->sc_dma_physaddr);
- +}
- +
- +
- +static int
- +hifn_init_pubrng(struct hifn_softc *sc)
- +{
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if ((sc->sc_flags & HIFN_IS_7811) == 0) {
- + /* Reset 7951 public key/rng engine */
- + WRITE_REG_1(sc, HIFN_1_PUB_RESET,
- + READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
- +
- + for (i = 0; i < 100; i++) {
- + DELAY(1000);
- + if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
- + HIFN_PUBRST_RESET) == 0)
- + break;
- + }
- +
- + if (i == 100) {
- + device_printf(sc->sc_dev, "public key init failed\n");
- + return (1);
- + }
- + }
- +
- + /* Enable the rng, if available */
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- + if (sc->sc_flags & HIFN_HAS_RNG) {
- + if (sc->sc_flags & HIFN_IS_7811) {
- + u_int32_t r;
- + r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
- + if (r & HIFN_7811_RNGENA_ENA) {
- + r &= ~HIFN_7811_RNGENA_ENA;
- + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
- + }
- + WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
- + HIFN_7811_RNGCFG_DEFL);
- + r |= HIFN_7811_RNGENA_ENA;
- + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
- + } else
- + WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
- + READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
- + HIFN_RNGCFG_ENA);
- +
- + sc->sc_rngfirst = 1;
- + crypto_rregister(sc->sc_cid, hifn_read_random, sc);
- + }
- +#endif
- +
- + /* Enable public key engine, if available */
- + if (sc->sc_flags & HIFN_HAS_PUBLIC) {
- + WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
- + sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
- + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
- +#ifdef HIFN_VULCANDEV
- + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
- + UID_ROOT, GID_WHEEL, 0666,
- + "vulcanpk");
- + sc->sc_pkdev->si_drv1 = sc;
- +#endif
- + }
- +
- + return (0);
- +}
- +
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- +static int
- +hifn_read_random(void *arg, u_int32_t *buf, int len)
- +{
- + struct hifn_softc *sc = (struct hifn_softc *) arg;
- + u_int32_t sts;
- + int i, rc = 0;
- +
- + if (len <= 0)
- + return rc;
- +
- + if (sc->sc_flags & HIFN_IS_7811) {
- + /* ONLY VALID ON 7811!!!! */
- + for (i = 0; i < 5; i++) {
- + sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
- + if (sts & HIFN_7811_RNGSTS_UFL) {
- + device_printf(sc->sc_dev,
- + "RNG underflow: disabling\n");
- + /* DAVIDM perhaps return -1 */
- + break;
- + }
- + if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
- + break;
- +
- + /*
- + * There are at least two words in the RNG FIFO
- + * at this point.
- + */
- + if (rc < len)
- + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
- + if (rc < len)
- + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
- + }
- + } else
- + buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
- +
- + /* NB: discard first data read */
- + if (sc->sc_rngfirst) {
- + sc->sc_rngfirst = 0;
- + rc = 0;
- + }
- +
- + return(rc);
- +}
- +#endif /* CONFIG_OCF_RANDOMHARVEST */
- +
- +static void
- +hifn_puc_wait(struct hifn_softc *sc)
- +{
- + int i;
- + int reg = HIFN_0_PUCTRL;
- +
- + if (sc->sc_flags & HIFN_IS_7956) {
- + reg = HIFN_0_PUCTRL2;
- + }
- +
- + for (i = 5000; i > 0; i--) {
- + DELAY(1);
- + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
- + break;
- + }
- + if (!i)
- + device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
- + READ_REG_0(sc, HIFN_0_PUCTRL));
- +}
- +
- +/*
- + * Reset the processing unit.
- + */
- +static void
- +hifn_reset_puc(struct hifn_softc *sc)
- +{
- + /* Reset processing unit */
- + int reg = HIFN_0_PUCTRL;
- +
- + if (sc->sc_flags & HIFN_IS_7956) {
- + reg = HIFN_0_PUCTRL2;
- + }
- + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
- +
- + hifn_puc_wait(sc);
- +}
- +
- +/*
- + * Set the Retry and TRDY registers; note that we set them to
- + * zero because the 7811 locks up when forced to retry (section
- + * 3.6 of "Specification Update SU-0014-04". Not clear if we
- + * should do this for all Hifn parts, but it doesn't seem to hurt.
- + */
- +static void
- +hifn_set_retry(struct hifn_softc *sc)
- +{
- + DPRINTF("%s()\n", __FUNCTION__);
- + /* NB: RETRY only responds to 8-bit reads/writes */
- + pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
- + pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
- + /* piggy back the cache line setting here */
- + pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);
- +}
- +
- +/*
- + * Resets the board. Values in the regesters are left as is
- + * from the reset (i.e. initial values are assigned elsewhere).
- + */
- +static void
- +hifn_reset_board(struct hifn_softc *sc, int full)
- +{
- + u_int32_t reg;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- + /*
- + * Set polling in the DMA configuration register to zero. 0x7 avoids
- + * resetting the board and zeros out the other fields.
- + */
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
- +
- + /*
- + * Now that polling has been disabled, we have to wait 1 ms
- + * before resetting the board.
- + */
- + DELAY(1000);
- +
- + /* Reset the DMA unit */
- + if (full) {
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
- + DELAY(1000);
- + } else {
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
- + HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
- + hifn_reset_puc(sc);
- + }
- +
- + KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
- + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
- +
- + /* Bring dma unit out of reset */
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
- +
- + hifn_puc_wait(sc);
- + hifn_set_retry(sc);
- +
- + if (sc->sc_flags & HIFN_IS_7811) {
- + for (reg = 0; reg < 1000; reg++) {
- + if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
- + HIFN_MIPSRST_CRAMINIT)
- + break;
- + DELAY(1000);
- + }
- + if (reg == 1000)
- + device_printf(sc->sc_dev, ": cram init timeout\n");
- + } else {
- + /* set up DMA configuration register #2 */
- + /* turn off all PK and BAR0 swaps */
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
- + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
- + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
- + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
- + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
- + }
- +}
- +
- +static u_int32_t
- +hifn_next_signature(u_int32_t a, u_int cnt)
- +{
- + int i;
- + u_int32_t v;
- +
- + for (i = 0; i < cnt; i++) {
- +
- + /* get the parity */
- + v = a & 0x80080125;
- + v ^= v >> 16;
- + v ^= v >> 8;
- + v ^= v >> 4;
- + v ^= v >> 2;
- + v ^= v >> 1;
- +
- + a = (v & 1) ^ (a << 1);
- + }
- +
- + return a;
- +}
- +
- +
- +/*
- + * Checks to see if crypto is already enabled. If crypto isn't enable,
- + * "hifn_enable_crypto" is called to enable it. The check is important,
- + * as enabling crypto twice will lock the board.
- + */
- +static int
- +hifn_enable_crypto(struct hifn_softc *sc)
- +{
- + u_int32_t dmacfg, ramcfg, encl, addr, i;
- + char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00 };
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
- + dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
- +
- + /*
- + * The RAM config register's encrypt level bit needs to be set before
- + * every read performed on the encryption level register.
- + */
- + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
- +
- + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
- +
- + /*
- + * Make sure we don't re-unlock. Two unlocks kills chip until the
- + * next reboot.
- + */
- + if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
- +#ifdef HIFN_DEBUG
- + if (hifn_debug)
- + device_printf(sc->sc_dev,
- + "Strong crypto already enabled!\n");
- +#endif
- + goto report;
- + }
- +
- + if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
- +#ifdef HIFN_DEBUG
- + if (hifn_debug)
- + device_printf(sc->sc_dev,
- + "Unknown encryption level 0x%x\n", encl);
- +#endif
- + return 1;
- + }
- +
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
- + HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
- + DELAY(1000);
- + addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
- + DELAY(1000);
- + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
- + DELAY(1000);
- +
- + for (i = 0; i <= 12; i++) {
- + addr = hifn_next_signature(addr, offtbl[i] + 0x101);
- + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
- +
- + DELAY(1000);
- + }
- +
- + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
- + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
- +
- +#ifdef HIFN_DEBUG
- + if (hifn_debug) {
- + if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
- + device_printf(sc->sc_dev, "Engine is permanently "
- + "locked until next system reset!\n");
- + else
- + device_printf(sc->sc_dev, "Engine enabled "
- + "successfully!\n");
- + }
- +#endif
- +
- +report:
- + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
- +
- + switch (encl) {
- + case HIFN_PUSTAT_ENA_1:
- + case HIFN_PUSTAT_ENA_2:
- + break;
- + case HIFN_PUSTAT_ENA_0:
- + default:
- + device_printf(sc->sc_dev, "disabled\n");
- + break;
- + }
- +
- + return 0;
- +}
- +
- +/*
- + * Give initial values to the registers listed in the "Register Space"
- + * section of the HIFN Software Development reference manual.
- + */
- +static void
- +hifn_init_pci_registers(struct hifn_softc *sc)
- +{
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + /* write fixed values needed by the Initialization registers */
- + WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
- + WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
- + WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
- +
- + /* write all 4 ring address registers */
- + WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, cmdr[0]));
- + WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, srcr[0]));
- + WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, dstr[0]));
- + WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, resr[0]));
- +
- + DELAY(2000);
- +
- + /* write status register */
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
- + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
- + HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
- + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
- + HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
- + HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
- + HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
- + HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
- + HIFN_DMACSR_S_WAIT |
- + HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
- + HIFN_DMACSR_C_WAIT |
- + HIFN_DMACSR_ENGINE |
- + ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
- + HIFN_DMACSR_PUBDONE : 0) |
- + ((sc->sc_flags & HIFN_IS_7811) ?
- + HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
- +
- + sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
- + sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
- + HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
- + HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
- + ((sc->sc_flags & HIFN_IS_7811) ?
- + HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
- + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
- + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
- +
- +
- + if (sc->sc_flags & HIFN_IS_7956) {
- + u_int32_t pll;
- +
- + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
- + HIFN_PUCNFG_TCALLPHASES |
- + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
- +
- + /* turn off the clocks and insure bypass is set */
- + pll = READ_REG_1(sc, HIFN_1_PLL);
- + pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
- + | HIFN_PLL_BP | HIFN_PLL_MBSET;
- + WRITE_REG_1(sc, HIFN_1_PLL, pll);
- + DELAY(10*1000); /* 10ms */
- +
- + /* change configuration */
- + pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
- + WRITE_REG_1(sc, HIFN_1_PLL, pll);
- + DELAY(10*1000); /* 10ms */
- +
- + /* disable bypass */
- + pll &= ~HIFN_PLL_BP;
- + WRITE_REG_1(sc, HIFN_1_PLL, pll);
- + /* enable clocks with new configuration */
- + pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
- + WRITE_REG_1(sc, HIFN_1_PLL, pll);
- + } else {
- + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
- + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
- + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
- + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
- + }
- +
- + WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
- + ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
- + ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
- +}
- +
- +/*
- + * The maximum number of sessions supported by the card
- + * is dependent on the amount of context ram, which
- + * encryption algorithms are enabled, and how compression
- + * is configured. This should be configured before this
- + * routine is called.
- + */
- +static void
- +hifn_sessions(struct hifn_softc *sc)
- +{
- + u_int32_t pucnfg;
- + int ctxsize;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
- +
- + if (pucnfg & HIFN_PUCNFG_COMPSING) {
- + if (pucnfg & HIFN_PUCNFG_ENCCNFG)
- + ctxsize = 128;
- + else
- + ctxsize = 512;
- + /*
- + * 7955/7956 has internal context memory of 32K
- + */
- + if (sc->sc_flags & HIFN_IS_7956)
- + sc->sc_maxses = 32768 / ctxsize;
- + else
- + sc->sc_maxses = 1 +
- + ((sc->sc_ramsize - 32768) / ctxsize);
- + } else
- + sc->sc_maxses = sc->sc_ramsize / 16384;
- +
- + if (sc->sc_maxses > 2048)
- + sc->sc_maxses = 2048;
- +}
- +
- +/*
- + * Determine ram type (sram or dram). Board should be just out of a reset
- + * state when this is called.
- + */
- +static int
- +hifn_ramtype(struct hifn_softc *sc)
- +{
- + u_int8_t data[8], dataexpect[8];
- + int i;
- +
- + for (i = 0; i < sizeof(data); i++)
- + data[i] = dataexpect[i] = 0x55;
- + if (hifn_writeramaddr(sc, 0, data))
- + return (-1);
- + if (hifn_readramaddr(sc, 0, data))
- + return (-1);
- + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
- + sc->sc_drammodel = 1;
- + return (0);
- + }
- +
- + for (i = 0; i < sizeof(data); i++)
- + data[i] = dataexpect[i] = 0xaa;
- + if (hifn_writeramaddr(sc, 0, data))
- + return (-1);
- + if (hifn_readramaddr(sc, 0, data))
- + return (-1);
- + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
- + sc->sc_drammodel = 1;
- + return (0);
- + }
- +
- + return (0);
- +}
- +
- +#define HIFN_SRAM_MAX (32 << 20)
- +#define HIFN_SRAM_STEP_SIZE 16384
- +#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
- +
- +static int
- +hifn_sramsize(struct hifn_softc *sc)
- +{
- + u_int32_t a;
- + u_int8_t data[8];
- + u_int8_t dataexpect[sizeof(data)];
- + int32_t i;
- +
- + for (i = 0; i < sizeof(data); i++)
- + data[i] = dataexpect[i] = i ^ 0x5a;
- +
- + for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
- + a = i * HIFN_SRAM_STEP_SIZE;
- + bcopy(&i, data, sizeof(i));
- + hifn_writeramaddr(sc, a, data);
- + }
- +
- + for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
- + a = i * HIFN_SRAM_STEP_SIZE;
- + bcopy(&i, dataexpect, sizeof(i));
- + if (hifn_readramaddr(sc, a, data) < 0)
- + return (0);
- + if (bcmp(data, dataexpect, sizeof(data)) != 0)
- + return (0);
- + sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
- + }
- +
- + return (0);
- +}
- +
- +/*
- + * XXX For dram boards, one should really try all of the
- + * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
- + * is already set up correctly.
- + */
- +static int
- +hifn_dramsize(struct hifn_softc *sc)
- +{
- + u_int32_t cnfg;
- +
- + if (sc->sc_flags & HIFN_IS_7956) {
- + /*
- + * 7955/7956 have a fixed internal ram of only 32K.
- + */
- + sc->sc_ramsize = 32768;
- + } else {
- + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
- + HIFN_PUCNFG_DRAMMASK;
- + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
- + }
- + return (0);
- +}
- +
- +static void
- +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
- + dma->cmdi = 0;
- + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
- + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- + }
- + *cmdp = dma->cmdi++;
- + dma->cmdk = dma->cmdi;
- +
- + if (dma->srci == HIFN_D_SRC_RSIZE) {
- + dma->srci = 0;
- + dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
- + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- + }
- + *srcp = dma->srci++;
- + dma->srck = dma->srci;
- +
- + if (dma->dsti == HIFN_D_DST_RSIZE) {
- + dma->dsti = 0;
- + dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
- + HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- + }
- + *dstp = dma->dsti++;
- + dma->dstk = dma->dsti;
- +
- + if (dma->resi == HIFN_D_RES_RSIZE) {
- + dma->resi = 0;
- + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
- + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- + }
- + *resp = dma->resi++;
- + dma->resk = dma->resi;
- +}
- +
- +static int
- +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + hifn_base_command_t wc;
- + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
- + int r, cmdi, resi, srci, dsti;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + wc.masks = htole16(3 << 13);
- + wc.session_num = htole16(addr >> 14);
- + wc.total_source_count = htole16(8);
- + wc.total_dest_count = htole16(addr & 0x3fff);
- +
- + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
- +
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
- + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
- + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
- +
- + /* build write command */
- + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
- + *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
- + bcopy(data, &dma->test_src, sizeof(dma->test_src));
- +
- + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
- + + offsetof(struct hifn_dma, test_src));
- + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
- + + offsetof(struct hifn_dma, test_dst));
- +
- + dma->cmdr[cmdi].l = htole32(16 | masks);
- + dma->srcr[srci].l = htole32(8 | masks);
- + dma->dstr[dsti].l = htole32(4 | masks);
- + dma->resr[resi].l = htole32(4 | masks);
- +
- + for (r = 10000; r >= 0; r--) {
- + DELAY(10);
- + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
- + break;
- + }
- + if (r == 0) {
- + device_printf(sc->sc_dev, "writeramaddr -- "
- + "result[%d](addr %d) still valid\n", resi, addr);
- + r = -1;
- + return (-1);
- + } else
- + r = 0;
- +
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
- + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
- + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
- +
- + return (r);
- +}
- +
- +static int
- +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + hifn_base_command_t rc;
- + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
- + int r, cmdi, srci, dsti, resi;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + rc.masks = htole16(2 << 13);
- + rc.session_num = htole16(addr >> 14);
- + rc.total_source_count = htole16(addr & 0x3fff);
- + rc.total_dest_count = htole16(8);
- +
- + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
- +
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
- + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
- + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
- +
- + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
- + *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
- +
- + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, test_src));
- + dma->test_src = 0;
- + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, test_dst));
- + dma->test_dst = 0;
- + dma->cmdr[cmdi].l = htole32(8 | masks);
- + dma->srcr[srci].l = htole32(8 | masks);
- + dma->dstr[dsti].l = htole32(8 | masks);
- + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
- +
- + for (r = 10000; r >= 0; r--) {
- + DELAY(10);
- + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
- + break;
- + }
- + if (r == 0) {
- + device_printf(sc->sc_dev, "readramaddr -- "
- + "result[%d](addr %d) still valid\n", resi, addr);
- + r = -1;
- + } else {
- + r = 0;
- + bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
- + }
- +
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
- + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
- + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
- +
- + return (r);
- +}
- +
- +/*
- + * Initialize the descriptor rings.
- + */
- +static void
- +hifn_init_dma(struct hifn_softc *sc)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + hifn_set_retry(sc);
- +
- + /* initialize static pointer values */
- + for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
- + dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, command_bufs[i][0]));
- + for (i = 0; i < HIFN_D_RES_RSIZE; i++)
- + dma->resr[i].p = htole32(sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, result_bufs[i][0]));
- +
- + dma->cmdr[HIFN_D_CMD_RSIZE].p =
- + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
- + dma->srcr[HIFN_D_SRC_RSIZE].p =
- + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
- + dma->dstr[HIFN_D_DST_RSIZE].p =
- + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
- + dma->resr[HIFN_D_RES_RSIZE].p =
- + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
- +
- + dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
- + dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
- + dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
- +}
- +
- +/*
- + * Writes out the raw command buffer space. Returns the
- + * command buffer size.
- + */
- +static u_int
- +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
- +{
- + struct hifn_softc *sc = NULL;
- + u_int8_t *buf_pos;
- + hifn_base_command_t *base_cmd;
- + hifn_mac_command_t *mac_cmd;
- + hifn_crypt_command_t *cry_cmd;
- + int using_mac, using_crypt, len, ivlen;
- + u_int32_t dlen, slen;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + buf_pos = buf;
- + using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
- + using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
- +
- + base_cmd = (hifn_base_command_t *)buf_pos;
- + base_cmd->masks = htole16(cmd->base_masks);
- + slen = cmd->src_mapsize;
- + if (cmd->sloplen)
- + dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
- + else
- + dlen = cmd->dst_mapsize;
- + base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
- + base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
- + dlen >>= 16;
- + slen >>= 16;
- + base_cmd->session_num = htole16(
- + ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
- + ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
- + buf_pos += sizeof(hifn_base_command_t);
- +
- + if (using_mac) {
- + mac_cmd = (hifn_mac_command_t *)buf_pos;
- + dlen = cmd->maccrd->crd_len;
- + mac_cmd->source_count = htole16(dlen & 0xffff);
- + dlen >>= 16;
- + mac_cmd->masks = htole16(cmd->mac_masks |
- + ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
- + mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
- + mac_cmd->reserved = 0;
- + buf_pos += sizeof(hifn_mac_command_t);
- + }
- +
- + if (using_crypt) {
- + cry_cmd = (hifn_crypt_command_t *)buf_pos;
- + dlen = cmd->enccrd->crd_len;
- + cry_cmd->source_count = htole16(dlen & 0xffff);
- + dlen >>= 16;
- + cry_cmd->masks = htole16(cmd->cry_masks |
- + ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
- + cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
- + cry_cmd->reserved = 0;
- + buf_pos += sizeof(hifn_crypt_command_t);
- + }
- +
- + if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
- + bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
- + buf_pos += HIFN_MAC_KEY_LENGTH;
- + }
- +
- + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
- + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
- + case HIFN_CRYPT_CMD_ALG_3DES:
- + bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
- + buf_pos += HIFN_3DES_KEY_LENGTH;
- + break;
- + case HIFN_CRYPT_CMD_ALG_DES:
- + bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
- + buf_pos += HIFN_DES_KEY_LENGTH;
- + break;
- + case HIFN_CRYPT_CMD_ALG_RC4:
- + len = 256;
- + do {
- + int clen;
- +
- + clen = MIN(cmd->cklen, len);
- + bcopy(cmd->ck, buf_pos, clen);
- + len -= clen;
- + buf_pos += clen;
- + } while (len > 0);
- + bzero(buf_pos, 4);
- + buf_pos += 4;
- + break;
- + case HIFN_CRYPT_CMD_ALG_AES:
- + /*
- + * AES keys are variable 128, 192 and
- + * 256 bits (16, 24 and 32 bytes).
- + */
- + bcopy(cmd->ck, buf_pos, cmd->cklen);
- + buf_pos += cmd->cklen;
- + break;
- + }
- + }
- +
- + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
- + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
- + case HIFN_CRYPT_CMD_ALG_AES:
- + ivlen = HIFN_AES_IV_LENGTH;
- + break;
- + default:
- + ivlen = HIFN_IV_LENGTH;
- + break;
- + }
- + bcopy(cmd->iv, buf_pos, ivlen);
- + buf_pos += ivlen;
- + }
- +
- + if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
- + bzero(buf_pos, 8);
- + buf_pos += 8;
- + }
- +
- + return (buf_pos - buf);
- +}
- +
- +static int
- +hifn_dmamap_aligned(struct hifn_operand *op)
- +{
- + struct hifn_softc *sc = NULL;
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + for (i = 0; i < op->nsegs; i++) {
- + if (op->segs[i].ds_addr & 3)
- + return (0);
- + if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
- + return (0);
- + }
- + return (1);
- +}
- +
- +static __inline int
- +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- +
- + if (++idx == HIFN_D_DST_RSIZE) {
- + dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
- + HIFN_D_MASKDONEIRQ);
- + HIFN_DSTR_SYNC(sc, idx,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + idx = 0;
- + }
- + return (idx);
- +}
- +
- +static int
- +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + struct hifn_operand *dst = &cmd->dst;
- + u_int32_t p, l;
- + int idx, used = 0, i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + idx = dma->dsti;
- + for (i = 0; i < dst->nsegs - 1; i++) {
- + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
- + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
- + wmb();
- + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
- + HIFN_DSTR_SYNC(sc, idx,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + used++;
- +
- + idx = hifn_dmamap_dstwrap(sc, idx);
- + }
- +
- + if (cmd->sloplen == 0) {
- + p = dst->segs[i].ds_addr;
- + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
- + dst->segs[i].ds_len;
- + } else {
- + p = sc->sc_dma_physaddr +
- + offsetof(struct hifn_dma, slop[cmd->slopidx]);
- + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
- + sizeof(u_int32_t);
- +
- + if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
- + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
- + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
- + (dst->segs[i].ds_len - cmd->sloplen));
- + wmb();
- + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
- + HIFN_DSTR_SYNC(sc, idx,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + used++;
- +
- + idx = hifn_dmamap_dstwrap(sc, idx);
- + }
- + }
- + dma->dstr[idx].p = htole32(p);
- + dma->dstr[idx].l = htole32(l);
- + wmb();
- + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
- + HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + used++;
- +
- + idx = hifn_dmamap_dstwrap(sc, idx);
- +
- + dma->dsti = idx;
- + dma->dstu += used;
- + return (idx);
- +}
- +
- +static __inline int
- +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- +
- + if (++idx == HIFN_D_SRC_RSIZE) {
- + dma->srcr[idx].l = htole32(HIFN_D_VALID |
- + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
- + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- + idx = 0;
- + }
- + return (idx);
- +}
- +
- +static int
- +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + struct hifn_operand *src = &cmd->src;
- + int idx, i;
- + u_int32_t last = 0;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + idx = dma->srci;
- + for (i = 0; i < src->nsegs; i++) {
- + if (i == src->nsegs - 1)
- + last = HIFN_D_LAST;
- +
- + dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
- + dma->srcr[idx].l = htole32(src->segs[i].ds_len |
- + HIFN_D_MASKDONEIRQ | last);
- + wmb();
- + dma->srcr[idx].l |= htole32(HIFN_D_VALID);
- + HIFN_SRCR_SYNC(sc, idx,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- +
- + idx = hifn_dmamap_srcwrap(sc, idx);
- + }
- + dma->srci = idx;
- + dma->srcu += src->nsegs;
- + return (idx);
- +}
- +
- +
- +static int
- +hifn_crypto(
- + struct hifn_softc *sc,
- + struct hifn_command *cmd,
- + struct cryptop *crp,
- + int hint)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + u_int32_t cmdlen, csr;
- + int cmdi, resi, err = 0;
- + unsigned long l_flags;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + /*
- + * need 1 cmd, and 1 res
- + *
- + * NB: check this first since it's easy.
- + */
- + HIFN_LOCK(sc);
- + if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
- + (dma->resu + 1) > HIFN_D_RES_RSIZE) {
- +#ifdef HIFN_DEBUG
- + if (hifn_debug) {
- + device_printf(sc->sc_dev,
- + "cmd/result exhaustion, cmdu %u resu %u\n",
- + dma->cmdu, dma->resu);
- + }
- +#endif
- + hifnstats.hst_nomem_cr++;
- + sc->sc_needwakeup |= CRYPTO_SYMQ;
- + HIFN_UNLOCK(sc);
- + return (ERESTART);
- + }
- +
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
- + hifnstats.hst_nomem_load++;
- + err = ENOMEM;
- + goto err_srcmap1;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
- + hifnstats.hst_nomem_load++;
- + err = ENOMEM;
- + goto err_srcmap1;
- + }
- + } else {
- + if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
- + hifnstats.hst_nomem_load++;
- + err = ENOMEM;
- + goto err_srcmap1;
- + }
- + }
- +
- + if (hifn_dmamap_aligned(&cmd->src)) {
- + cmd->sloplen = cmd->src_mapsize & 3;
- + cmd->dst = cmd->src;
- + } else {
- + if (crp->crp_flags & CRYPTO_F_IOV) {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + err = EINVAL;
- + goto err_srcmap;
- + } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
- +#ifdef NOTYET
- + int totlen, len;
- + struct mbuf *m, *m0, *mlast;
- +
- + KASSERT(cmd->dst_m == cmd->src_m,
- + ("hifn_crypto: dst_m initialized improperly"));
- + hifnstats.hst_unaligned++;
- + /*
- + * Source is not aligned on a longword boundary.
- + * Copy the data to insure alignment. If we fail
- + * to allocate mbufs or clusters while doing this
- + * we return ERESTART so the operation is requeued
- + * at the crypto later, but only if there are
- + * ops already posted to the hardware; otherwise we
- + * have no guarantee that we'll be re-entered.
- + */
- + totlen = cmd->src_mapsize;
- + if (cmd->src_m->m_flags & M_PKTHDR) {
- + len = MHLEN;
- + MGETHDR(m0, M_DONTWAIT, MT_DATA);
- + if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
- + m_free(m0);
- + m0 = NULL;
- + }
- + } else {
- + len = MLEN;
- + MGET(m0, M_DONTWAIT, MT_DATA);
- + }
- + if (m0 == NULL) {
- + hifnstats.hst_nomem_mbuf++;
- + err = dma->cmdu ? ERESTART : ENOMEM;
- + goto err_srcmap;
- + }
- + if (totlen >= MINCLSIZE) {
- + MCLGET(m0, M_DONTWAIT);
- + if ((m0->m_flags & M_EXT) == 0) {
- + hifnstats.hst_nomem_mcl++;
- + err = dma->cmdu ? ERESTART : ENOMEM;
- + m_freem(m0);
- + goto err_srcmap;
- + }
- + len = MCLBYTES;
- + }
- + totlen -= len;
- + m0->m_pkthdr.len = m0->m_len = len;
- + mlast = m0;
- +
- + while (totlen > 0) {
- + MGET(m, M_DONTWAIT, MT_DATA);
- + if (m == NULL) {
- + hifnstats.hst_nomem_mbuf++;
- + err = dma->cmdu ? ERESTART : ENOMEM;
- + m_freem(m0);
- + goto err_srcmap;
- + }
- + len = MLEN;
- + if (totlen >= MINCLSIZE) {
- + MCLGET(m, M_DONTWAIT);
- + if ((m->m_flags & M_EXT) == 0) {
- + hifnstats.hst_nomem_mcl++;
- + err = dma->cmdu ? ERESTART : ENOMEM;
- + mlast->m_next = m;
- + m_freem(m0);
- + goto err_srcmap;
- + }
- + len = MCLBYTES;
- + }
- +
- + m->m_len = len;
- + m0->m_pkthdr.len += len;
- + totlen -= len;
- +
- + mlast->m_next = m;
- + mlast = m;
- + }
- + cmd->dst_m = m0;
- +#else
- + device_printf(sc->sc_dev,
- + "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
- + __FILE__, __LINE__);
- + err = EINVAL;
- + goto err_srcmap;
- +#endif
- + } else {
- + device_printf(sc->sc_dev,
- + "%s,%d: unaligned contig buffers not implemented\n",
- + __FILE__, __LINE__);
- + err = EINVAL;
- + goto err_srcmap;
- + }
- + }
- +
- + if (cmd->dst_map == NULL) {
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
- + hifnstats.hst_nomem_map++;
- + err = ENOMEM;
- + goto err_dstmap1;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
- + hifnstats.hst_nomem_load++;
- + err = ENOMEM;
- + goto err_dstmap1;
- + }
- + } else {
- + if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
- + hifnstats.hst_nomem_load++;
- + err = ENOMEM;
- + goto err_dstmap1;
- + }
- + }
- + }
- +
- +#ifdef HIFN_DEBUG
- + if (hifn_debug) {
- + device_printf(sc->sc_dev,
- + "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
- + READ_REG_1(sc, HIFN_1_DMA_CSR),
- + READ_REG_1(sc, HIFN_1_DMA_IER),
- + dma->cmdu, dma->srcu, dma->dstu, dma->resu,
- + cmd->src_nsegs, cmd->dst_nsegs);
- + }
- +#endif
- +
- +#if 0
- + if (cmd->src_map == cmd->dst_map) {
- + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
- + BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
- + } else {
- + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
- + BUS_DMASYNC_PREWRITE);
- + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
- + BUS_DMASYNC_PREREAD);
- + }
- +#endif
- +
- + /*
- + * need N src, and N dst
- + */
- + if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
- + (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
- +#ifdef HIFN_DEBUG
- + if (hifn_debug) {
- + device_printf(sc->sc_dev,
- + "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
- + dma->srcu, cmd->src_nsegs,
- + dma->dstu, cmd->dst_nsegs);
- + }
- +#endif
- + hifnstats.hst_nomem_sd++;
- + err = ERESTART;
- + goto err_dstmap;
- + }
- +
- + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
- + dma->cmdi = 0;
- + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
- + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- + }
- + cmdi = dma->cmdi++;
- + cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
- + HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
- +
- + /* .p for command/result already set */
- + dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
- + HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
- + HIFN_CMDR_SYNC(sc, cmdi,
- + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- + dma->cmdu++;
- +
- + /*
- + * We don't worry about missing an interrupt (which a "command wait"
- + * interrupt salvages us from), unless there is more than one command
- + * in the queue.
- + */
- + if (dma->cmdu > 1) {
- + sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
- + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
- + }
- +
- + hifnstats.hst_ipackets++;
- + hifnstats.hst_ibytes += cmd->src_mapsize;
- +
- + hifn_dmamap_load_src(sc, cmd);
- +
- + /*
- + * Unlike other descriptors, we don't mask done interrupt from
- + * result descriptor.
- + */
- +#ifdef HIFN_DEBUG
- + if (hifn_debug)
- + device_printf(sc->sc_dev, "load res\n");
- +#endif
- + if (dma->resi == HIFN_D_RES_RSIZE) {
- + dma->resi = 0;
- + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
- + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + }
- + resi = dma->resi++;
- + KASSERT(dma->hifn_commands[resi] == NULL,
- + ("hifn_crypto: command slot %u busy", resi));
- + dma->hifn_commands[resi] = cmd;
- + HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
- + if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
- + dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
- + HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
- + wmb();
- + dma->resr[resi].l |= htole32(HIFN_D_VALID);
- + sc->sc_curbatch++;
- + if (sc->sc_curbatch > hifnstats.hst_maxbatch)
- + hifnstats.hst_maxbatch = sc->sc_curbatch;
- + hifnstats.hst_totbatch++;
- + } else {
- + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
- + wmb();
- + dma->resr[resi].l |= htole32(HIFN_D_VALID);
- + sc->sc_curbatch = 0;
- + }
- + HIFN_RESR_SYNC(sc, resi,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + dma->resu++;
- +
- + if (cmd->sloplen)
- + cmd->slopidx = resi;
- +
- + hifn_dmamap_load_dst(sc, cmd);
- +
- + csr = 0;
- + if (sc->sc_c_busy == 0) {
- + csr |= HIFN_DMACSR_C_CTRL_ENA;
- + sc->sc_c_busy = 1;
- + }
- + if (sc->sc_s_busy == 0) {
- + csr |= HIFN_DMACSR_S_CTRL_ENA;
- + sc->sc_s_busy = 1;
- + }
- + if (sc->sc_r_busy == 0) {
- + csr |= HIFN_DMACSR_R_CTRL_ENA;
- + sc->sc_r_busy = 1;
- + }
- + if (sc->sc_d_busy == 0) {
- + csr |= HIFN_DMACSR_D_CTRL_ENA;
- + sc->sc_d_busy = 1;
- + }
- + if (csr)
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
- +
- +#ifdef HIFN_DEBUG
- + if (hifn_debug) {
- + device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
- + READ_REG_1(sc, HIFN_1_DMA_CSR),
- + READ_REG_1(sc, HIFN_1_DMA_IER));
- + }
- +#endif
- +
- + sc->sc_active = 5;
- + HIFN_UNLOCK(sc);
- + KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
- + return (err); /* success */
- +
- +err_dstmap:
- + if (cmd->src_map != cmd->dst_map)
- + pci_unmap_buf(sc, &cmd->dst);
- +err_dstmap1:
- +err_srcmap:
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + if (cmd->src_skb != cmd->dst_skb)
- +#ifdef NOTYET
- + m_freem(cmd->dst_m);
- +#else
- + device_printf(sc->sc_dev,
- + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
- + __FILE__, __LINE__);
- +#endif
- + }
- + pci_unmap_buf(sc, &cmd->src);
- +err_srcmap1:
- + HIFN_UNLOCK(sc);
- + return (err);
- +}
- +
- +static void
- +hifn_tick(unsigned long arg)
- +{
- + struct hifn_softc *sc;
- + unsigned long l_flags;
- +
- + if (arg >= HIFN_MAX_CHIPS)
- + return;
- + sc = hifn_chip_idx[arg];
- + if (!sc)
- + return;
- +
- + HIFN_LOCK(sc);
- + if (sc->sc_active == 0) {
- + struct hifn_dma *dma = sc->sc_dma;
- + u_int32_t r = 0;
- +
- + if (dma->cmdu == 0 && sc->sc_c_busy) {
- + sc->sc_c_busy = 0;
- + r |= HIFN_DMACSR_C_CTRL_DIS;
- + }
- + if (dma->srcu == 0 && sc->sc_s_busy) {
- + sc->sc_s_busy = 0;
- + r |= HIFN_DMACSR_S_CTRL_DIS;
- + }
- + if (dma->dstu == 0 && sc->sc_d_busy) {
- + sc->sc_d_busy = 0;
- + r |= HIFN_DMACSR_D_CTRL_DIS;
- + }
- + if (dma->resu == 0 && sc->sc_r_busy) {
- + sc->sc_r_busy = 0;
- + r |= HIFN_DMACSR_R_CTRL_DIS;
- + }
- + if (r)
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
- + } else
- + sc->sc_active--;
- + HIFN_UNLOCK(sc);
- + mod_timer(&sc->sc_tickto, jiffies + HZ);
- +}
- +
- +static irqreturn_t
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- +hifn_intr(int irq, void *arg)
- +#else
- +hifn_intr(int irq, void *arg, struct pt_regs *regs)
- +#endif
- +{
- + struct hifn_softc *sc = arg;
- + struct hifn_dma *dma;
- + u_int32_t dmacsr, restart;
- + int i, u;
- + unsigned long l_flags;
- +
- + dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
- +
- + /* Nothing in the DMA unit interrupted */
- + if ((dmacsr & sc->sc_dmaier) == 0)
- + return IRQ_NONE;
- +
- + HIFN_LOCK(sc);
- +
- + dma = sc->sc_dma;
- +
- +#ifdef HIFN_DEBUG
- + if (hifn_debug) {
- + device_printf(sc->sc_dev,
- + "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
- + dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
- + dma->cmdi, dma->srci, dma->dsti, dma->resi,
- + dma->cmdk, dma->srck, dma->dstk, dma->resk,
- + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
- + }
- +#endif
- +
- + WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
- +
- + if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
- + (dmacsr & HIFN_DMACSR_PUBDONE))
- + WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
- + READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
- +
- + restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
- + if (restart)
- + device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
- +
- + if (sc->sc_flags & HIFN_IS_7811) {
- + if (dmacsr & HIFN_DMACSR_ILLR)
- + device_printf(sc->sc_dev, "illegal read\n");
- + if (dmacsr & HIFN_DMACSR_ILLW)
- + device_printf(sc->sc_dev, "illegal write\n");
- + }
- +
- + restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
- + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
- + if (restart) {
- + device_printf(sc->sc_dev, "abort, resetting.\n");
- + hifnstats.hst_abort++;
- + hifn_abort(sc);
- + HIFN_UNLOCK(sc);
- + return IRQ_HANDLED;
- + }
- +
- + if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
- + /*
- + * If no slots to process and we receive a "waiting on
- + * command" interrupt, we disable the "waiting on command"
- + * (by clearing it).
- + */
- + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
- + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
- + }
- +
- + /* clear the rings */
- + i = dma->resk; u = dma->resu;
- + while (u != 0) {
- + HIFN_RESR_SYNC(sc, i,
- + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- + if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
- + HIFN_RESR_SYNC(sc, i,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + break;
- + }
- +
- + if (i != HIFN_D_RES_RSIZE) {
- + struct hifn_command *cmd;
- + u_int8_t *macbuf = NULL;
- +
- + HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
- + cmd = dma->hifn_commands[i];
- + KASSERT(cmd != NULL,
- + ("hifn_intr: null command slot %u", i));
- + dma->hifn_commands[i] = NULL;
- +
- + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
- + macbuf = dma->result_bufs[i];
- + macbuf += 12;
- + }
- +
- + hifn_callback(sc, cmd, macbuf);
- + hifnstats.hst_opackets++;
- + u--;
- + }
- +
- + if (++i == (HIFN_D_RES_RSIZE + 1))
- + i = 0;
- + }
- + dma->resk = i; dma->resu = u;
- +
- + i = dma->srck; u = dma->srcu;
- + while (u != 0) {
- + if (i == HIFN_D_SRC_RSIZE)
- + i = 0;
- + HIFN_SRCR_SYNC(sc, i,
- + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- + if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
- + HIFN_SRCR_SYNC(sc, i,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + break;
- + }
- + i++, u--;
- + }
- + dma->srck = i; dma->srcu = u;
- +
- + i = dma->cmdk; u = dma->cmdu;
- + while (u != 0) {
- + HIFN_CMDR_SYNC(sc, i,
- + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- + if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
- + HIFN_CMDR_SYNC(sc, i,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- + break;
- + }
- + if (i != HIFN_D_CMD_RSIZE) {
- + u--;
- + HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
- + }
- + if (++i == (HIFN_D_CMD_RSIZE + 1))
- + i = 0;
- + }
- + dma->cmdk = i; dma->cmdu = u;
- +
- + HIFN_UNLOCK(sc);
- +
- + if (sc->sc_needwakeup) { /* XXX check high watermark */
- + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
- +#ifdef HIFN_DEBUG
- + if (hifn_debug)
- + device_printf(sc->sc_dev,
- + "wakeup crypto (%x) u %d/%d/%d/%d\n",
- + sc->sc_needwakeup,
- + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
- +#endif
- + sc->sc_needwakeup &= ~wakeup;
- + crypto_unblock(sc->sc_cid, wakeup);
- + }
- +
- + return IRQ_HANDLED;
- +}
- +
- +/*
- + * Allocate a new 'session' and return an encoded session id. 'sidp'
- + * contains our registration id, and should contain an encoded session
- + * id on successful allocation.
- + */
- +static int
- +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
- +{
- + struct hifn_softc *sc = device_get_softc(dev);
- + struct cryptoini *c;
- + int mac = 0, cry = 0, sesn;
- + struct hifn_session *ses = NULL;
- + unsigned long l_flags;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + KASSERT(sc != NULL, ("hifn_newsession: null softc"));
- + if (sidp == NULL || cri == NULL || sc == NULL) {
- + DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
- + return (EINVAL);
- + }
- +
- + HIFN_LOCK(sc);
- + if (sc->sc_sessions == NULL) {
- + ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
- + SLAB_ATOMIC);
- + if (ses == NULL) {
- + HIFN_UNLOCK(sc);
- + return (ENOMEM);
- + }
- + sesn = 0;
- + sc->sc_nsessions = 1;
- + } else {
- + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
- + if (!sc->sc_sessions[sesn].hs_used) {
- + ses = &sc->sc_sessions[sesn];
- + break;
- + }
- + }
- +
- + if (ses == NULL) {
- + sesn = sc->sc_nsessions;
- + ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
- + SLAB_ATOMIC);
- + if (ses == NULL) {
- + HIFN_UNLOCK(sc);
- + return (ENOMEM);
- + }
- + bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
- + bzero(sc->sc_sessions, sesn * sizeof(*ses));
- + kfree(sc->sc_sessions);
- + sc->sc_sessions = ses;
- + ses = &sc->sc_sessions[sesn];
- + sc->sc_nsessions++;
- + }
- + }
- + HIFN_UNLOCK(sc);
- +
- + bzero(ses, sizeof(*ses));
- + ses->hs_used = 1;
- +
- + for (c = cri; c != NULL; c = c->cri_next) {
- + switch (c->cri_alg) {
- + case CRYPTO_MD5:
- + case CRYPTO_SHA1:
- + case CRYPTO_MD5_HMAC:
- + case CRYPTO_SHA1_HMAC:
- + if (mac) {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + return (EINVAL);
- + }
- + mac = 1;
- + ses->hs_mlen = c->cri_mlen;
- + if (ses->hs_mlen == 0) {
- + switch (c->cri_alg) {
- + case CRYPTO_MD5:
- + case CRYPTO_MD5_HMAC:
- + ses->hs_mlen = 16;
- + break;
- + case CRYPTO_SHA1:
- + case CRYPTO_SHA1_HMAC:
- + ses->hs_mlen = 20;
- + break;
- + }
- + }
- + break;
- + case CRYPTO_DES_CBC:
- + case CRYPTO_3DES_CBC:
- + case CRYPTO_AES_CBC:
- + /* XXX this may read fewer, does it matter? */
- + read_random(ses->hs_iv,
- + c->cri_alg == CRYPTO_AES_CBC ?
- + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
- + /*FALLTHROUGH*/
- + case CRYPTO_ARC4:
- + if (cry) {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + return (EINVAL);
- + }
- + cry = 1;
- + break;
- + default:
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + return (EINVAL);
- + }
- + }
- + if (mac == 0 && cry == 0) {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + return (EINVAL);
- + }
- +
- + *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
- +
- + return (0);
- +}
- +
- +/*
- + * Deallocate a session.
- + * XXX this routine should run a zero'd mac/encrypt key into context ram.
- + * XXX to blow away any keys already stored there.
- + */
- +static int
- +hifn_freesession(device_t dev, u_int64_t tid)
- +{
- + struct hifn_softc *sc = device_get_softc(dev);
- + int session, error;
- + u_int32_t sid = CRYPTO_SESID2LID(tid);
- + unsigned long l_flags;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + KASSERT(sc != NULL, ("hifn_freesession: null softc"));
- + if (sc == NULL) {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + return (EINVAL);
- + }
- +
- + HIFN_LOCK(sc);
- + session = HIFN_SESSION(sid);
- + if (session < sc->sc_nsessions) {
- + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
- + error = 0;
- + } else {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + error = EINVAL;
- + }
- + HIFN_UNLOCK(sc);
- +
- + return (error);
- +}
- +
- +static int
- +hifn_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + struct hifn_softc *sc = device_get_softc(dev);
- + struct hifn_command *cmd = NULL;
- + int session, err, ivlen;
- + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (crp == NULL || crp->crp_callback == NULL) {
- + hifnstats.hst_invalid++;
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + return (EINVAL);
- + }
- + session = HIFN_SESSION(crp->crp_sid);
- +
- + if (sc == NULL || session >= sc->sc_nsessions) {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + err = EINVAL;
- + goto errout;
- + }
- +
- + cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
- + if (cmd == NULL) {
- + hifnstats.hst_nomem++;
- + err = ENOMEM;
- + goto errout;
- + }
- + memset(cmd, 0, sizeof(*cmd));
- +
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + cmd->src_skb = (struct sk_buff *)crp->crp_buf;
- + cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + cmd->src_io = (struct uio *)crp->crp_buf;
- + cmd->dst_io = (struct uio *)crp->crp_buf;
- + } else {
- + cmd->src_buf = crp->crp_buf;
- + cmd->dst_buf = crp->crp_buf;
- + }
- +
- + crd1 = crp->crp_desc;
- + if (crd1 == NULL) {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + err = EINVAL;
- + goto errout;
- + }
- + crd2 = crd1->crd_next;
- +
- + if (crd2 == NULL) {
- + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1 ||
- + crd1->crd_alg == CRYPTO_MD5) {
- + maccrd = crd1;
- + enccrd = NULL;
- + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
- + crd1->crd_alg == CRYPTO_3DES_CBC ||
- + crd1->crd_alg == CRYPTO_AES_CBC ||
- + crd1->crd_alg == CRYPTO_ARC4) {
- + if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
- + cmd->base_masks |= HIFN_BASE_CMD_DECODE;
- + maccrd = NULL;
- + enccrd = crd1;
- + } else {
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + err = EINVAL;
- + goto errout;
- + }
- + } else {
- + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd1->crd_alg == CRYPTO_MD5 ||
- + crd1->crd_alg == CRYPTO_SHA1) &&
- + (crd2->crd_alg == CRYPTO_DES_CBC ||
- + crd2->crd_alg == CRYPTO_3DES_CBC ||
- + crd2->crd_alg == CRYPTO_AES_CBC ||
- + crd2->crd_alg == CRYPTO_ARC4) &&
- + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
- + cmd->base_masks = HIFN_BASE_CMD_DECODE;
- + maccrd = crd1;
- + enccrd = crd2;
- + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
- + crd1->crd_alg == CRYPTO_ARC4 ||
- + crd1->crd_alg == CRYPTO_3DES_CBC ||
- + crd1->crd_alg == CRYPTO_AES_CBC) &&
- + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
- + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd2->crd_alg == CRYPTO_MD5 ||
- + crd2->crd_alg == CRYPTO_SHA1) &&
- + (crd1->crd_flags & CRD_F_ENCRYPT)) {
- + enccrd = crd1;
- + maccrd = crd2;
- + } else {
- + /*
- + * We cannot order the 7751 as requested
- + */
- + DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
- + err = EINVAL;
- + goto errout;
- + }
- + }
- +
- + if (enccrd) {
- + cmd->enccrd = enccrd;
- + cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
- + switch (enccrd->crd_alg) {
- + case CRYPTO_ARC4:
- + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
- + break;
- + case CRYPTO_DES_CBC:
- + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
- + HIFN_CRYPT_CMD_MODE_CBC |
- + HIFN_CRYPT_CMD_NEW_IV;
- + break;
- + case CRYPTO_3DES_CBC:
- + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
- + HIFN_CRYPT_CMD_MODE_CBC |
- + HIFN_CRYPT_CMD_NEW_IV;
- + break;
- + case CRYPTO_AES_CBC:
- + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
- + HIFN_CRYPT_CMD_MODE_CBC |
- + HIFN_CRYPT_CMD_NEW_IV;
- + break;
- + default:
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + err = EINVAL;
- + goto errout;
- + }
- + if (enccrd->crd_alg != CRYPTO_ARC4) {
- + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
- + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
- + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
- + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
- + else
- + bcopy(sc->sc_sessions[session].hs_iv,
- + cmd->iv, ivlen);
- +
- + if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
- + == 0) {
- + crypto_copyback(crp->crp_flags,
- + crp->crp_buf, enccrd->crd_inject,
- + ivlen, cmd->iv);
- + }
- + } else {
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
- + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
- + else {
- + crypto_copydata(crp->crp_flags,
- + crp->crp_buf, enccrd->crd_inject,
- + ivlen, cmd->iv);
- + }
- + }
- + }
- +
- + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
- + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
- + cmd->ck = enccrd->crd_key;
- + cmd->cklen = enccrd->crd_klen >> 3;
- + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
- +
- + /*
- + * Need to specify the size for the AES key in the masks.
- + */
- + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
- + HIFN_CRYPT_CMD_ALG_AES) {
- + switch (cmd->cklen) {
- + case 16:
- + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
- + break;
- + case 24:
- + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
- + break;
- + case 32:
- + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
- + break;
- + default:
- + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
- + err = EINVAL;
- + goto errout;
- + }
- + }
- + }
- +
- + if (maccrd) {
- + cmd->maccrd = maccrd;
- + cmd->base_masks |= HIFN_BASE_CMD_MAC;
- +
- + switch (maccrd->crd_alg) {
- + case CRYPTO_MD5:
- + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
- + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
- + HIFN_MAC_CMD_POS_IPSEC;
- + break;
- + case CRYPTO_MD5_HMAC:
- + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
- + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
- + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
- + break;
- + case CRYPTO_SHA1:
- + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
- + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
- + HIFN_MAC_CMD_POS_IPSEC;
- + break;
- + case CRYPTO_SHA1_HMAC:
- + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
- + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
- + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
- + break;
- + }
- +
- + if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
- + maccrd->crd_alg == CRYPTO_MD5_HMAC) {
- + cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
- + bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
- + bzero(cmd->mac + (maccrd->crd_klen >> 3),
- + HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
- + }
- + }
- +
- + cmd->crp = crp;
- + cmd->session_num = session;
- + cmd->softc = sc;
- +
- + err = hifn_crypto(sc, cmd, crp, hint);
- + if (!err) {
- + return 0;
- + } else if (err == ERESTART) {
- + /*
- + * There weren't enough resources to dispatch the request
- + * to the part. Notify the caller so they'll requeue this
- + * request and resubmit it again soon.
- + */
- +#ifdef HIFN_DEBUG
- + if (hifn_debug)
- + device_printf(sc->sc_dev, "requeue request\n");
- +#endif
- + kfree(cmd);
- + sc->sc_needwakeup |= CRYPTO_SYMQ;
- + return (err);
- + }
- +
- +errout:
- + if (cmd != NULL)
- + kfree(cmd);
- + if (err == EINVAL)
- + hifnstats.hst_invalid++;
- + else
- + hifnstats.hst_nomem++;
- + crp->crp_etype = err;
- + crypto_done(crp);
- + return (err);
- +}
- +
- +static void
- +hifn_abort(struct hifn_softc *sc)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + struct hifn_command *cmd;
- + struct cryptop *crp;
- + int i, u;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + i = dma->resk; u = dma->resu;
- + while (u != 0) {
- + cmd = dma->hifn_commands[i];
- + KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
- + dma->hifn_commands[i] = NULL;
- + crp = cmd->crp;
- +
- + if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
- + /* Salvage what we can. */
- + u_int8_t *macbuf;
- +
- + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
- + macbuf = dma->result_bufs[i];
- + macbuf += 12;
- + } else
- + macbuf = NULL;
- + hifnstats.hst_opackets++;
- + hifn_callback(sc, cmd, macbuf);
- + } else {
- +#if 0
- + if (cmd->src_map == cmd->dst_map) {
- + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
- + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
- + } else {
- + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
- + BUS_DMASYNC_POSTREAD);
- + }
- +#endif
- +
- + if (cmd->src_skb != cmd->dst_skb) {
- +#ifdef NOTYET
- + m_freem(cmd->src_m);
- + crp->crp_buf = (caddr_t)cmd->dst_m;
- +#else
- + device_printf(sc->sc_dev,
- + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
- + __FILE__, __LINE__);
- +#endif
- + }
- +
- + /* non-shared buffers cannot be restarted */
- + if (cmd->src_map != cmd->dst_map) {
- + /*
- + * XXX should be EAGAIN, delayed until
- + * after the reset.
- + */
- + crp->crp_etype = ENOMEM;
- + pci_unmap_buf(sc, &cmd->dst);
- + } else
- + crp->crp_etype = ENOMEM;
- +
- + pci_unmap_buf(sc, &cmd->src);
- +
- + kfree(cmd);
- + if (crp->crp_etype != EAGAIN)
- + crypto_done(crp);
- + }
- +
- + if (++i == HIFN_D_RES_RSIZE)
- + i = 0;
- + u--;
- + }
- + dma->resk = i; dma->resu = u;
- +
- + hifn_reset_board(sc, 1);
- + hifn_init_dma(sc);
- + hifn_init_pci_registers(sc);
- +}
- +
- +static void
- +hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
- +{
- + struct hifn_dma *dma = sc->sc_dma;
- + struct cryptop *crp = cmd->crp;
- + struct cryptodesc *crd;
- + int i, u, ivlen;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- +#if 0
- + if (cmd->src_map == cmd->dst_map) {
- + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
- + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
- + } else {
- + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
- + BUS_DMASYNC_POSTREAD);
- + }
- +#endif
- +
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + if (cmd->src_skb != cmd->dst_skb) {
- +#ifdef NOTYET
- + crp->crp_buf = (caddr_t)cmd->dst_m;
- + totlen = cmd->src_mapsize;
- + for (m = cmd->dst_m; m != NULL; m = m->m_next) {
- + if (totlen < m->m_len) {
- + m->m_len = totlen;
- + totlen = 0;
- + } else
- + totlen -= m->m_len;
- + }
- + cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
- + m_freem(cmd->src_m);
- +#else
- + device_printf(sc->sc_dev,
- + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
- + __FILE__, __LINE__);
- +#endif
- + }
- + }
- +
- + if (cmd->sloplen != 0) {
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
- + (caddr_t)&dma->slop[cmd->slopidx]);
- + }
- +
- + i = dma->dstk; u = dma->dstu;
- + while (u != 0) {
- + if (i == HIFN_D_DST_RSIZE)
- + i = 0;
- +#if 0
- + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
- + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- +#endif
- + if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
- +#if 0
- + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- +#endif
- + break;
- + }
- + i++, u--;
- + }
- + dma->dstk = i; dma->dstu = u;
- +
- + hifnstats.hst_obytes += cmd->dst_mapsize;
- +
- + if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
- + HIFN_BASE_CMD_CRYPT) {
- + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
- + if (crd->crd_alg != CRYPTO_DES_CBC &&
- + crd->crd_alg != CRYPTO_3DES_CBC &&
- + crd->crd_alg != CRYPTO_AES_CBC)
- + continue;
- + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
- + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + crd->crd_skip + crd->crd_len - ivlen, ivlen,
- + cmd->softc->sc_sessions[cmd->session_num].hs_iv);
- + break;
- + }
- + }
- +
- + if (macbuf != NULL) {
- + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
- + int len;
- +
- + if (crd->crd_alg != CRYPTO_MD5 &&
- + crd->crd_alg != CRYPTO_SHA1 &&
- + crd->crd_alg != CRYPTO_MD5_HMAC &&
- + crd->crd_alg != CRYPTO_SHA1_HMAC) {
- + continue;
- + }
- + len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject, len, macbuf);
- + break;
- + }
- + }
- +
- + if (cmd->src_map != cmd->dst_map)
- + pci_unmap_buf(sc, &cmd->dst);
- + pci_unmap_buf(sc, &cmd->src);
- + kfree(cmd);
- + crypto_done(crp);
- +}
- +
- +/*
- + * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
- + * and Group 1 registers; avoid conditions that could create
- + * burst writes by doing a read in between the writes.
- + *
- + * NB: The read we interpose is always to the same register;
- + * we do this because reading from an arbitrary (e.g. last)
- + * register may not always work.
- + */
- +static void
- +hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
- +{
- + if (sc->sc_flags & HIFN_IS_7811) {
- + if (sc->sc_bar0_lastreg == reg - 4)
- + readl(sc->sc_bar0 + HIFN_0_PUCNFG);
- + sc->sc_bar0_lastreg = reg;
- + }
- + writel(val, sc->sc_bar0 + reg);
- +}
- +
- +static void
- +hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
- +{
- + if (sc->sc_flags & HIFN_IS_7811) {
- + if (sc->sc_bar1_lastreg == reg - 4)
- + readl(sc->sc_bar1 + HIFN_1_REVID);
- + sc->sc_bar1_lastreg = reg;
- + }
- + writel(val, sc->sc_bar1 + reg);
- +}
- +
- +
- +static struct pci_device_id hifn_pci_tbl[] = {
- + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + /*
- + * Other vendors share this PCI ID as well, such as
- + * http://www.powercrypt.com, and obviously they also
- + * use the same key.
- + */
- + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { 0, 0, 0, 0, 0, 0, }
- +};
- +MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
- +
- +static struct pci_driver hifn_driver = {
- + .name = "hifn",
- + .id_table = hifn_pci_tbl,
- + .probe = hifn_probe,
- + .remove = hifn_remove,
- + /* add PM stuff here one day */
- +};
- +
- +static int __init hifn_init (void)
- +{
- + struct hifn_softc *sc = NULL;
- + int rc;
- +
- + DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
- +
- + rc = pci_register_driver(&hifn_driver);
- + pci_register_driver_compat(&hifn_driver, rc);
- +
- + return rc;
- +}
- +
- +static void __exit hifn_exit (void)
- +{
- + pci_unregister_driver(&hifn_driver);
- +}
- +
- +module_init(hifn_init);
- +module_exit(hifn_exit);
- +
- +MODULE_LICENSE("BSD");
- +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
- +MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
- diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.36/crypto/ocf/hifn/hifn7751reg.h
- --- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751reg.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/hifn/hifn7751reg.h 2010-11-09 20:28:04.792495416 +0100
- @@ -0,0 +1,540 @@
- +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
- +/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
- +
- +/*-
- + * Invertex AEON / Hifn 7751 driver
- + * Copyright (c) 1999 Invertex Inc. All rights reserved.
- + * Copyright (c) 1999 Theo de Raadt
- + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
- + * http://www.netsec.net
- + *
- + * Please send any comments, feedback, bug-fixes, or feature requests to
- + * software@invertex.com.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored in part by the Defense Advanced Research Projects
- + * Agency (DARPA) and Air Force Research Laboratory, Air Force
- + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- + *
- + */
- +#ifndef __HIFN_H__
- +#define __HIFN_H__
- +
- +/*
- + * Some PCI configuration space offset defines. The names were made
- + * identical to the names used by the Linux kernel.
- + */
- +#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
- +#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
- +#define HIFN_TRDY_TIMEOUT 0x40
- +#define HIFN_RETRY_TIMEOUT 0x41
- +
- +/*
- + * PCI vendor and device identifiers
- + * (the names are preserved from their OpenBSD source).
- + */
- +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
- +#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
- +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
- +#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
- +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
- +#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
- +#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
- +#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
- +
- +#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
- +#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
- +
- +#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
- +#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
- +
- +/*
- + * The values below should multiple of 4 -- and be large enough to handle
- + * any command the driver implements.
- + *
- + * MAX_COMMAND = base command + mac command + encrypt command +
- + * mac-key + rc4-key
- + * MAX_RESULT = base result + mac result + mac + encrypt result
- + *
- + *
- + */
- +#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
- +#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
- +
- +/*
- + * hifn_desc_t
- + *
- + * Holds an individual descriptor for any of the rings.
- + */
- +typedef struct hifn_desc {
- + volatile u_int32_t l; /* length and status bits */
- + volatile u_int32_t p;
- +} hifn_desc_t;
- +
- +/*
- + * Masks for the "length" field of struct hifn_desc.
- + */
- +#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
- +#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
- +#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
- +#define HIFN_D_OVER 0x08000000 /* overflow */
- +#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
- +#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
- +#define HIFN_D_VALID 0x80000000 /* valid bit */
- +
- +
- +/*
- + * Processing Unit Registers (offset from BASEREG0)
- + */
- +#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
- +#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
- +#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
- +#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
- +#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
- +#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
- +#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
- +#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
- +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
- +#define HIFN_0_MUTE1 0x80
- +#define HIFN_0_MUTE2 0x90
- +#define HIFN_0_SPACESIZE 0x100 /* Register space size */
- +
- +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
- +#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
- +#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
- +#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
- +#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
- +#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
- +
- +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
- +#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
- +#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
- +#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
- +#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
- +#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
- +#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
- +#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
- +#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
- +#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
- +#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
- +
- +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
- +#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
- +#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
- +#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
- +#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
- +#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
- +#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
- +#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
- +#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
- +#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
- +#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
- +#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
- +#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
- +#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
- +#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
- +#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
- +#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
- +#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
- +#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
- +#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
- +#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
- +#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
- +#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
- +#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
- +
- +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
- +#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
- +#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
- +#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
- +#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
- +#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
- +#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
- +#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
- +#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
- +#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
- +#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
- +
- +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
- +#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
- +#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
- +#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
- +#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
- +#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
- +#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
- +#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
- +#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
- +#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
- +#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
- +#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
- +#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
- +#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
- +#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
- +#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
- +#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
- +#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
- +
- +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
- +#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
- +#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
- +
- +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
- +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
- +
- +/*
- + * DMA Interface Registers (offset from BASEREG1)
- + */
- +#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
- +#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
- +#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
- +#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
- +#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
- +#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
- +#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
- +#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
- +#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
- +#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
- +#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
- +#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
- +#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
- +#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
- +#define HIFN_1_REVID 0x98 /* Revision ID */
- +
- +#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
- +#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
- +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
- +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
- +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
- +#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
- +#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
- +#define HIFN_1_RNG_DATA 0x318 /* RNG data */
- +#define HIFN_1_PUB_MODE 0x320 /* PK mode */
- +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
- +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
- +#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
- +#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
- +
- +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
- +#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
- +#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
- +#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
- +#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
- +#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
- +#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
- +#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
- +#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
- +#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
- +#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
- +#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
- +#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
- +#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
- +#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
- +#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
- +#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
- +#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
- +#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
- +#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
- +#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
- +#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
- +#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
- +#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
- +#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
- +#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
- +#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
- +#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
- +#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
- +#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
- +#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
- +#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
- +#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
- +#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
- +#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
- +#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
- +#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
- +#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
- +#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
- +
- +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
- +#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
- +#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
- +#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
- +#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
- +#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
- +#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
- +#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
- +#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
- +#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
- +#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
- +#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
- +#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
- +#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
- +#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
- +#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
- +#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
- +#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
- +#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
- +#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
- +#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
- +#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
- +#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
- +
- +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
- +#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
- +#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
- +#define HIFN_DMACNFG_UNLOCK 0x00000800
- +#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
- +#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
- +#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
- +#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
- +#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
- +
- +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
- +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
- +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
- +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
- +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
- +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
- +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
- +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
- +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
- +
- +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
- +#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
- +
- +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
- +#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
- +#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
- +#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
- +
- +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
- +#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
- +#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
- +
- +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
- +#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
- +#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
- +#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
- +#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
- +#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
- +#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
- +#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
- +#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
- +#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
- +
- +/* Public key reset register (HIFN_1_PUB_RESET) */
- +#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
- +
- +/* Public operation register (HIFN_1_PUB_OP) */
- +#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
- +#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
- +#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
- +#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
- +#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
- +#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
- +#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
- +#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
- +#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
- +#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
- +#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
- +#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
- +#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
- +#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
- +#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
- +#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
- +#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
- +
- +/* Public operand length register (HIFN_1_PUB_OPLEN) */
- +#define HIFN_PUBOPLEN_MODLEN 0x0000007f
- +#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
- +#define HIFN_PUBOPLEN_REDLEN 0x003c0000
- +
- +/* Public status register (HIFN_1_PUB_STATUS) */
- +#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
- +#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
- +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
- +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
- +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
- +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
- +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
- +
- +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
- +#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
- +
- +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
- +#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
- +
- +/*
- + * Register offsets in register set 1
- + */
- +
- +#define HIFN_UNLOCK_SECRET1 0xf4
- +#define HIFN_UNLOCK_SECRET2 0xfc
- +
- +/*
- + * PLL config register
- + *
- + * This register is present only on 7954/7955/7956 parts. It must be
- + * programmed according to the bus interface method used by the h/w.
- + * Note that the parts require a stable clock. Since the PCI clock
- + * may vary the reference clock must usually be used. To avoid
- + * overclocking the core logic, setup must be done carefully, refer
- + * to the driver for details. The exact multiplier required varies
- + * by part and system configuration; refer to the Hifn documentation.
- + */
- +#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
- +#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
- +/* bit 2 reserved */
- +#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
- +#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
- +/* bits 5-9 reserved */
- +#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
- +#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
- +#define HIFN_PLL_ND_SHIFT 11
- +#define HIFN_PLL_ND_2 0x00000000 /* 2x */
- +#define HIFN_PLL_ND_4 0x00000800 /* 4x */
- +#define HIFN_PLL_ND_6 0x00001000 /* 6x */
- +#define HIFN_PLL_ND_8 0x00001800 /* 8x */
- +#define HIFN_PLL_ND_10 0x00002000 /* 10x */
- +#define HIFN_PLL_ND_12 0x00002800 /* 12x */
- +/* bits 14-15 reserved */
- +#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
- +/* bits 17-31 reserved */
- +
- +/*
- + * Board configuration specifies only these bits.
- + */
- +#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
- +
- +/*
- + * Public Key Engine Mode Register
- + */
- +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
- +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
- +
- +
- +/*********************************************************************
- + * Structs for board commands
- + *
- + *********************************************************************/
- +
- +/*
- + * Structure to help build up the command data structure.
- + */
- +typedef struct hifn_base_command {
- + volatile u_int16_t masks;
- + volatile u_int16_t session_num;
- + volatile u_int16_t total_source_count;
- + volatile u_int16_t total_dest_count;
- +} hifn_base_command_t;
- +
- +#define HIFN_BASE_CMD_MAC 0x0400
- +#define HIFN_BASE_CMD_CRYPT 0x0800
- +#define HIFN_BASE_CMD_DECODE 0x2000
- +#define HIFN_BASE_CMD_SRCLEN_M 0xc000
- +#define HIFN_BASE_CMD_SRCLEN_S 14
- +#define HIFN_BASE_CMD_DSTLEN_M 0x3000
- +#define HIFN_BASE_CMD_DSTLEN_S 12
- +#define HIFN_BASE_CMD_LENMASK_HI 0x30000
- +#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
- +
- +/*
- + * Structure to help build up the command data structure.
- + */
- +typedef struct hifn_crypt_command {
- + volatile u_int16_t masks;
- + volatile u_int16_t header_skip;
- + volatile u_int16_t source_count;
- + volatile u_int16_t reserved;
- +} hifn_crypt_command_t;
- +
- +#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
- +#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
- +#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
- +#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
- +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
- +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
- +#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
- +#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
- +#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
- +#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
- +#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
- +#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
- +#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
- +
- +#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
- +#define HIFN_CRYPT_CMD_SRCLEN_S 14
- +
- +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
- +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
- +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
- +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
- +
- +/*
- + * Structure to help build up the command data structure.
- + */
- +typedef struct hifn_mac_command {
- + volatile u_int16_t masks;
- + volatile u_int16_t header_skip;
- + volatile u_int16_t source_count;
- + volatile u_int16_t reserved;
- +} hifn_mac_command_t;
- +
- +#define HIFN_MAC_CMD_ALG_MASK 0x0001
- +#define HIFN_MAC_CMD_ALG_SHA1 0x0000
- +#define HIFN_MAC_CMD_ALG_MD5 0x0001
- +#define HIFN_MAC_CMD_MODE_MASK 0x000c
- +#define HIFN_MAC_CMD_MODE_HMAC 0x0000
- +#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
- +#define HIFN_MAC_CMD_MODE_HASH 0x0008
- +#define HIFN_MAC_CMD_MODE_FULL 0x0004
- +#define HIFN_MAC_CMD_TRUNC 0x0010
- +#define HIFN_MAC_CMD_RESULT 0x0020
- +#define HIFN_MAC_CMD_APPEND 0x0040
- +#define HIFN_MAC_CMD_SRCLEN_M 0xc000
- +#define HIFN_MAC_CMD_SRCLEN_S 14
- +
- +/*
- + * MAC POS IPsec initiates authentication after encryption on encodes
- + * and before decryption on decodes.
- + */
- +#define HIFN_MAC_CMD_POS_IPSEC 0x0200
- +#define HIFN_MAC_CMD_NEW_KEY 0x0800
- +
- +/*
- + * The poll frequency and poll scalar defines are unshifted values used
- + * to set fields in the DMA Configuration Register.
- + */
- +#ifndef HIFN_POLL_FREQUENCY
- +#define HIFN_POLL_FREQUENCY 0x1
- +#endif
- +
- +#ifndef HIFN_POLL_SCALAR
- +#define HIFN_POLL_SCALAR 0x0
- +#endif
- +
- +#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
- +#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
- +#endif /* __HIFN_H__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.36/crypto/ocf/hifn/hifn7751var.h
- --- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751var.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/hifn/hifn7751var.h 2010-11-09 20:28:04.832495385 +0100
- @@ -0,0 +1,369 @@
- +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
- +/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
- +
- +/*-
- + * Invertex AEON / Hifn 7751 driver
- + * Copyright (c) 1999 Invertex Inc. All rights reserved.
- + * Copyright (c) 1999 Theo de Raadt
- + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
- + * http://www.netsec.net
- + *
- + * Please send any comments, feedback, bug-fixes, or feature requests to
- + * software@invertex.com.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored in part by the Defense Advanced Research Projects
- + * Agency (DARPA) and Air Force Research Laboratory, Air Force
- + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- + *
- + */
- +
- +#ifndef __HIFN7751VAR_H__
- +#define __HIFN7751VAR_H__
- +
- +#ifdef __KERNEL__
- +
- +/*
- + * Some configurable values for the driver. By default command+result
- + * descriptor rings are the same size. The src+dst descriptor rings
- + * are sized at 3.5x the number of potential commands. Slower parts
- + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
- + * src+cmd/result descriptors. It's not clear that increasing the size
- + * of the descriptor rings helps performance significantly as other
- + * factors tend to come into play (e.g. copying misaligned packets).
- + */
- +#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
- +#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
- +#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
- +#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
- +
- +/*
- + * Length values for cryptography
- + */
- +#define HIFN_DES_KEY_LENGTH 8
- +#define HIFN_3DES_KEY_LENGTH 24
- +#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
- +#define HIFN_IV_LENGTH 8
- +#define HIFN_AES_IV_LENGTH 16
- +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
- +
- +/*
- + * Length values for authentication
- + */
- +#define HIFN_MAC_KEY_LENGTH 64
- +#define HIFN_MD5_LENGTH 16
- +#define HIFN_SHA1_LENGTH 20
- +#define HIFN_MAC_TRUNC_LENGTH 12
- +
- +#define MAX_SCATTER 64
- +
- +/*
- + * Data structure to hold all 4 rings and any other ring related data.
- + */
- +struct hifn_dma {
- + /*
- + * Descriptor rings. We add +1 to the size to accomidate the
- + * jump descriptor.
- + */
- + struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
- + struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
- + struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
- + struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
- +
- + struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
- +
- + u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
- + u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
- + u_int32_t slop[HIFN_D_CMD_RSIZE];
- +
- + u_int64_t test_src, test_dst;
- +
- + /*
- + * Our current positions for insertion and removal from the desriptor
- + * rings.
- + */
- + int cmdi, srci, dsti, resi;
- + volatile int cmdu, srcu, dstu, resu;
- + int cmdk, srck, dstk, resk;
- +};
- +
- +struct hifn_session {
- + int hs_used;
- + int hs_mlen;
- + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
- +};
- +
- +#define HIFN_RING_SYNC(sc, r, i, f) \
- + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
- +
- +#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
- +#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
- +#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
- +#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
- +
- +#define HIFN_CMD_SYNC(sc, i, f) \
- + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
- +
- +#define HIFN_RES_SYNC(sc, i, f) \
- + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
- +
- +typedef int bus_size_t;
- +
- +/*
- + * Holds data specific to a single HIFN board.
- + */
- +struct hifn_softc {
- + softc_device_decl sc_dev;
- +
- + struct pci_dev *sc_pcidev; /* PCI device pointer */
- + spinlock_t sc_mtx; /* per-instance lock */
- +
- + int sc_num; /* for multiple devs */
- +
- + ocf_iomem_t sc_bar0;
- + bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
- + ocf_iomem_t sc_bar1;
- + bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
- +
- + int sc_irq;
- +
- + u_int32_t sc_dmaier;
- + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
- + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
- +
- + struct hifn_dma *sc_dma;
- + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
- +
- + int sc_dmansegs;
- + int32_t sc_cid;
- + int sc_maxses;
- + int sc_nsessions;
- + struct hifn_session *sc_sessions;
- + int sc_ramsize;
- + int sc_flags;
- +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
- +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
- +#define HIFN_HAS_AES 0x4 /* includes AES support */
- +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
- +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
- +
- + struct timer_list sc_tickto; /* for managing DMA */
- +
- + int sc_rngfirst;
- + int sc_rnghz; /* RNG polling frequency */
- +
- + int sc_c_busy; /* command ring busy */
- + int sc_s_busy; /* source data ring busy */
- + int sc_d_busy; /* destination data ring busy */
- + int sc_r_busy; /* result ring busy */
- + int sc_active; /* for initial countdown */
- + int sc_needwakeup; /* ops q'd wating on resources */
- + int sc_curbatch; /* # ops submitted w/o int */
- + int sc_suspended;
- +#ifdef HIFN_VULCANDEV
- + struct cdev *sc_pkdev;
- +#endif
- +};
- +
- +#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
- +#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
- +
- +/*
- + * hifn_command_t
- + *
- + * This is the control structure used to pass commands to hifn_encrypt().
- + *
- + * flags
- + * -----
- + * Flags is the bitwise "or" values for command configuration. A single
- + * encrypt direction needs to be set:
- + *
- + * HIFN_ENCODE or HIFN_DECODE
- + *
- + * To use cryptography, a single crypto algorithm must be included:
- + *
- + * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
- + *
- + * To use authentication is used, a single MAC algorithm must be included:
- + *
- + * HIFN_MAC_MD5 or HIFN_MAC_SHA1
- + *
- + * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
- + * If the value below is set, hash values are truncated or assumed
- + * truncated to 12 bytes:
- + *
- + * HIFN_MAC_TRUNC
- + *
- + * Keys for encryption and authentication can be sent as part of a command,
- + * or the last key value used with a particular session can be retrieved
- + * and used again if either of these flags are not specified.
- + *
- + * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
- + *
- + * session_num
- + * -----------
- + * A number between 0 and 2048 (for DRAM models) or a number between
- + * 0 and 768 (for SRAM models). Those who don't want to use session
- + * numbers should leave value at zero and send a new crypt key and/or
- + * new MAC key on every command. If you use session numbers and
- + * don't send a key with a command, the last key sent for that same
- + * session number will be used.
- + *
- + * Warning: Using session numbers and multiboard at the same time
- + * is currently broken.
- + *
- + * mbuf
- + * ----
- + * Either fill in the mbuf pointer and npa=0 or
- + * fill packp[] and packl[] and set npa to > 0
- + *
- + * mac_header_skip
- + * ---------------
- + * The number of bytes of the source_buf that are skipped over before
- + * authentication begins. This must be a number between 0 and 2^16-1
- + * and can be used by IPsec implementers to skip over IP headers.
- + * *** Value ignored if authentication not used ***
- + *
- + * crypt_header_skip
- + * -----------------
- + * The number of bytes of the source_buf that are skipped over before
- + * the cryptographic operation begins. This must be a number between 0
- + * and 2^16-1. For IPsec, this number will always be 8 bytes larger
- + * than the auth_header_skip (to skip over the ESP header).
- + * *** Value ignored if cryptography not used ***
- + *
- + */
- +struct hifn_operand {
- + union {
- + struct sk_buff *skb;
- + struct uio *io;
- + unsigned char *buf;
- + } u;
- + void *map;
- + bus_size_t mapsize;
- + int nsegs;
- + struct {
- + dma_addr_t ds_addr;
- + int ds_len;
- + } segs[MAX_SCATTER];
- +};
- +
- +struct hifn_command {
- + u_int16_t session_num;
- + u_int16_t base_masks, cry_masks, mac_masks;
- + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
- + int cklen;
- + int sloplen, slopidx;
- +
- + struct hifn_operand src;
- + struct hifn_operand dst;
- +
- + struct hifn_softc *softc;
- + struct cryptop *crp;
- + struct cryptodesc *enccrd, *maccrd;
- +};
- +
- +#define src_skb src.u.skb
- +#define src_io src.u.io
- +#define src_map src.map
- +#define src_mapsize src.mapsize
- +#define src_segs src.segs
- +#define src_nsegs src.nsegs
- +#define src_buf src.u.buf
- +
- +#define dst_skb dst.u.skb
- +#define dst_io dst.u.io
- +#define dst_map dst.map
- +#define dst_mapsize dst.mapsize
- +#define dst_segs dst.segs
- +#define dst_nsegs dst.nsegs
- +#define dst_buf dst.u.buf
- +
- +/*
- + * Return values for hifn_crypto()
- + */
- +#define HIFN_CRYPTO_SUCCESS 0
- +#define HIFN_CRYPTO_BAD_INPUT (-1)
- +#define HIFN_CRYPTO_RINGS_FULL (-2)
- +
- +/**************************************************************************
- + *
- + * Function: hifn_crypto
- + *
- + * Purpose: Called by external drivers to begin an encryption on the
- + * HIFN board.
- + *
- + * Blocking/Non-blocking Issues
- + * ============================
- + * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
- + * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
- + * room in any of the rings for the request to proceed.
- + *
- + * Return Values
- + * =============
- + * 0 for success, negative values on error
- + *
- + * Defines for negative error codes are:
- + *
- + * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
- + * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
- + * behaviour was requested.
- + *
- + *************************************************************************/
- +
- +/*
- + * Convert back and forth from 'sid' to 'card' and 'session'
- + */
- +#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
- +#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
- +#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
- +
- +#endif /* _KERNEL */
- +
- +struct hifn_stats {
- + u_int64_t hst_ibytes;
- + u_int64_t hst_obytes;
- + u_int32_t hst_ipackets;
- + u_int32_t hst_opackets;
- + u_int32_t hst_invalid;
- + u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
- + u_int32_t hst_abort;
- + u_int32_t hst_noirq; /* IRQ for no reason */
- + u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
- + u_int32_t hst_maxbatch; /* max ops submitted together */
- + u_int32_t hst_unaligned; /* unaligned src caused copy */
- + /*
- + * The following divides hst_nomem into more specific buckets.
- + */
- + u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
- + u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
- + u_int32_t hst_nomem_mbuf; /* MGET* failed */
- + u_int32_t hst_nomem_mcl; /* MCLGET* failed */
- + u_int32_t hst_nomem_cr; /* out of command/result descriptor */
- + u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
- +};
- +
- +#endif /* __HIFN7751VAR_H__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.36/crypto/ocf/hifn/hifnHIPP.c
- --- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPP.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/hifn/hifnHIPP.c 2010-11-09 20:28:04.881244876 +0100
- @@ -0,0 +1,420 @@
- +/*-
- + * Driver for Hifn HIPP-I/II chipset
- + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored by Hifn Inc.
- + *
- + */
- +
- +/*
- + * Driver for various Hifn encryption processors.
- + */
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/wait.h>
- +#include <linux/sched.h>
- +#include <linux/pci.h>
- +#include <linux/delay.h>
- +#include <linux/interrupt.h>
- +#include <linux/spinlock.h>
- +#include <linux/random.h>
- +#include <linux/version.h>
- +#include <linux/skbuff.h>
- +#include <linux/uio.h>
- +#include <linux/sysfs.h>
- +#include <linux/miscdevice.h>
- +#include <asm/io.h>
- +
- +#include <cryptodev.h>
- +
- +#include "hifnHIPPreg.h"
- +#include "hifnHIPPvar.h"
- +
- +#if 1
- +#define DPRINTF(a...) if (hipp_debug) { \
- + printk("%s: ", sc ? \
- + device_get_nameunit(sc->sc_dev) : "hifn"); \
- + printk(a); \
- + } else
- +#else
- +#define DPRINTF(a...)
- +#endif
- +
- +typedef int bus_size_t;
- +
- +static inline int
- +pci_get_revid(struct pci_dev *dev)
- +{
- + u8 rid = 0;
- + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
- + return rid;
- +}
- +
- +#define debug hipp_debug
- +int hipp_debug = 0;
- +module_param(hipp_debug, int, 0644);
- +MODULE_PARM_DESC(hipp_debug, "Enable debug");
- +
- +int hipp_maxbatch = 1;
- +module_param(hipp_maxbatch, int, 0644);
- +MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
- +
- +static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
- +static void hipp_remove(struct pci_dev *dev);
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- +static irqreturn_t hipp_intr(int irq, void *arg);
- +#else
- +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
- +#endif
- +
- +static int hipp_num_chips = 0;
- +static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
- +
- +static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
- +static int hipp_freesession(device_t, u_int64_t);
- +static int hipp_process(device_t, struct cryptop *, int);
- +
- +static device_method_t hipp_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, hipp_newsession),
- + DEVMETHOD(cryptodev_freesession,hipp_freesession),
- + DEVMETHOD(cryptodev_process, hipp_process),
- +};
- +
- +static __inline u_int32_t
- +READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
- +{
- + u_int32_t v = readl(sc->sc_bar[barno] + reg);
- + //sc->sc_bar0_lastreg = (bus_size_t) -1;
- + return (v);
- +}
- +static __inline void
- +WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
- +{
- + writel(val, sc->sc_bar[barno] + reg);
- +}
- +
- +#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
- +#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
- +#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
- +#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
- +
- +static int
- +hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
- +{
- + return EINVAL;
- +}
- +
- +static int
- +hipp_freesession(device_t dev, u_int64_t tid)
- +{
- + return EINVAL;
- +}
- +
- +static int
- +hipp_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + return EINVAL;
- +}
- +
- +static const char*
- +hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
- +{
- + char *n = NULL;
- +
- + switch (pci_get_vendor(sc->sc_pcidev)) {
- + case PCI_VENDOR_HIFN:
- + switch (pci_get_device(sc->sc_pcidev)) {
- + case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
- + case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
- + case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
- + }
- + }
- +
- + if(n==NULL) {
- + snprintf(buf, blen, "VID=%02x,PID=%02x",
- + pci_get_vendor(sc->sc_pcidev),
- + pci_get_device(sc->sc_pcidev));
- + } else {
- + buf[0]='\0';
- + strncat(buf, n, blen);
- + }
- + return buf;
- +}
- +
- +struct hipp_fs_entry {
- + struct attribute attr;
- + /* other stuff */
- +};
- +
- +
- +static ssize_t
- +cryptoid_show(struct device *dev,
- + struct device_attribute *attr,
- + char *buf)
- +{
- + struct hipp_softc *sc;
- +
- + sc = pci_get_drvdata(to_pci_dev (dev));
- + return sprintf (buf, "%d\n", sc->sc_cid);
- +}
- +
- +struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
- +
- +/*
- + * Attach an interface that successfully probed.
- + */
- +static int
- +hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
- +{
- + struct hipp_softc *sc = NULL;
- + int i;
- + //char rbase;
- + //u_int16_t ena;
- + int rev;
- + //int rseg;
- + int rc;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (pci_enable_device(dev) < 0)
- + return(-ENODEV);
- +
- + if (pci_set_mwi(dev))
- + return(-ENODEV);
- +
- + if (!dev->irq) {
- + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
- + pci_disable_device(dev);
- + return(-ENODEV);
- + }
- +
- + sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
- + if (!sc)
- + return(-ENOMEM);
- + memset(sc, 0, sizeof(*sc));
- +
- + softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
- +
- + sc->sc_pcidev = dev;
- + sc->sc_irq = -1;
- + sc->sc_cid = -1;
- + sc->sc_num = hipp_num_chips++;
- +
- + if (sc->sc_num < HIPP_MAX_CHIPS)
- + hipp_chip_idx[sc->sc_num] = sc;
- +
- + pci_set_drvdata(sc->sc_pcidev, sc);
- +
- + spin_lock_init(&sc->sc_mtx);
- +
- + /*
- + * Setup PCI resources.
- + * The READ_REG_0, WRITE_REG_0, READ_REG_1,
- + * and WRITE_REG_1 macros throughout the driver are used
- + * to permit better debugging.
- + */
- + for(i=0; i<4; i++) {
- + unsigned long mem_start, mem_len;
- + mem_start = pci_resource_start(sc->sc_pcidev, i);
- + mem_len = pci_resource_len(sc->sc_pcidev, i);
- + sc->sc_barphy[i] = (caddr_t)mem_start;
- + sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
- + if (!sc->sc_bar[i]) {
- + device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
- + goto fail;
- + }
- + }
- +
- + //hipp_reset_board(sc, 0);
- + pci_set_master(sc->sc_pcidev);
- +
- + /*
- + * Arrange the interrupt line.
- + */
- + rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
- + if (rc) {
- + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
- + goto fail;
- + }
- + sc->sc_irq = dev->irq;
- +
- + rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
- +
- + {
- + char b[32];
- + device_printf(sc->sc_dev, "%s, rev %u",
- + hipp_partname(sc, b, sizeof(b)), rev);
- + }
- +
- +#if 0
- + if (sc->sc_flags & HIFN_IS_7956)
- + printf(", pll=0x%x<%s clk, %ux mult>",
- + sc->sc_pllconfig,
- + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
- + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
- +#endif
- + printf("\n");
- +
- + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
- + if (sc->sc_cid < 0) {
- + device_printf(sc->sc_dev, "could not get crypto driver id\n");
- + goto fail;
- + }
- +
- +#if 0 /* cannot work with a non-GPL module */
- + /* make a sysfs entry to let the world know what entry we got */
- + sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
- +#endif
- +
- +#if 0
- + init_timer(&sc->sc_tickto);
- + sc->sc_tickto.function = hifn_tick;
- + sc->sc_tickto.data = (unsigned long) sc->sc_num;
- + mod_timer(&sc->sc_tickto, jiffies + HZ);
- +#endif
- +
- +#if 0 /* no code here yet ?? */
- + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
- +#endif
- +
- + return (0);
- +
- +fail:
- + if (sc->sc_cid >= 0)
- + crypto_unregister_all(sc->sc_cid);
- + if (sc->sc_irq != -1)
- + free_irq(sc->sc_irq, sc);
- +
- +#if 0
- + if (sc->sc_dma) {
- + /* Turn off DMA polling */
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
- +
- + pci_free_consistent(sc->sc_pcidev,
- + sizeof(*sc->sc_dma),
- + sc->sc_dma, sc->sc_dma_physaddr);
- + }
- +#endif
- + kfree(sc);
- + return (-ENXIO);
- +}
- +
- +/*
- + * Detach an interface that successfully probed.
- + */
- +static void
- +hipp_remove(struct pci_dev *dev)
- +{
- + struct hipp_softc *sc = pci_get_drvdata(dev);
- + unsigned long l_flags;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + /* disable interrupts */
- + HIPP_LOCK(sc);
- +
- +#if 0
- + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
- + HIFN_UNLOCK(sc);
- +
- + /*XXX other resources */
- + del_timer_sync(&sc->sc_tickto);
- +
- + /* Turn off DMA polling */
- + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
- +#endif
- +
- + crypto_unregister_all(sc->sc_cid);
- +
- + free_irq(sc->sc_irq, sc);
- +
- +#if 0
- + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
- + sc->sc_dma, sc->sc_dma_physaddr);
- +#endif
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- +static irqreturn_t hipp_intr(int irq, void *arg)
- +#else
- +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
- +#endif
- +{
- + struct hipp_softc *sc = arg;
- +
- + sc = sc; /* shut up compiler */
- +
- + return IRQ_HANDLED;
- +}
- +
- +static struct pci_device_id hipp_pci_tbl[] = {
- + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- +};
- +MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
- +
- +static struct pci_driver hipp_driver = {
- + .name = "hipp",
- + .id_table = hipp_pci_tbl,
- + .probe = hipp_probe,
- + .remove = hipp_remove,
- + /* add PM stuff here one day */
- +};
- +
- +static int __init hipp_init (void)
- +{
- + struct hipp_softc *sc = NULL;
- + int rc;
- +
- + DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
- +
- + rc = pci_register_driver(&hipp_driver);
- + pci_register_driver_compat(&hipp_driver, rc);
- +
- + return rc;
- +}
- +
- +static void __exit hipp_exit (void)
- +{
- + pci_unregister_driver(&hipp_driver);
- +}
- +
- +module_init(hipp_init);
- +module_exit(hipp_exit);
- +
- +MODULE_LICENSE("BSD");
- +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
- +MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
- diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.36/crypto/ocf/hifn/hifnHIPPreg.h
- --- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPreg.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/hifn/hifnHIPPreg.h 2010-11-09 20:28:04.922495399 +0100
- @@ -0,0 +1,46 @@
- +/*-
- + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
- + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored by Hifn inc.
- + *
- + */
- +
- +#ifndef __HIFNHIPP_H__
- +#define __HIFNHIPP_H__
- +
- +/*
- + * PCI vendor and device identifiers
- + */
- +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
- +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
- +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
- +#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
- +
- +#define HIPP_1_REVID 0x01 /* BOGUS */
- +
- +#endif /* __HIPP_H__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.36/crypto/ocf/hifn/hifnHIPPvar.h
- --- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPvar.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/hifn/hifnHIPPvar.h 2010-11-09 20:28:04.964807923 +0100
- @@ -0,0 +1,93 @@
- +/*
- + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
- + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * Effort sponsored by Hifn inc.
- + *
- + */
- +
- +#ifndef __HIFNHIPPVAR_H__
- +#define __HIFNHIPPVAR_H__
- +
- +#define HIPP_MAX_CHIPS 8
- +
- +/*
- + * Holds data specific to a single Hifn HIPP-I board.
- + */
- +struct hipp_softc {
- + softc_device_decl sc_dev;
- +
- + struct pci_dev *sc_pcidev; /* device backpointer */
- + ocf_iomem_t sc_bar[5];
- + caddr_t sc_barphy[5]; /* physical address */
- + int sc_num; /* for multiple devs */
- + spinlock_t sc_mtx; /* per-instance lock */
- + int32_t sc_cid;
- + int sc_irq;
- +
- +#if 0
- +
- + u_int32_t sc_dmaier;
- + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
- + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
- +
- + struct hifn_dma *sc_dma;
- + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
- +
- + int sc_dmansegs;
- + int sc_maxses;
- + int sc_nsessions;
- + struct hifn_session *sc_sessions;
- + int sc_ramsize;
- + int sc_flags;
- +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
- +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
- +#define HIFN_HAS_AES 0x4 /* includes AES support */
- +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
- +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
- +
- + struct timer_list sc_tickto; /* for managing DMA */
- +
- + int sc_rngfirst;
- + int sc_rnghz; /* RNG polling frequency */
- +
- + int sc_c_busy; /* command ring busy */
- + int sc_s_busy; /* source data ring busy */
- + int sc_d_busy; /* destination data ring busy */
- + int sc_r_busy; /* result ring busy */
- + int sc_active; /* for initial countdown */
- + int sc_needwakeup; /* ops q'd wating on resources */
- + int sc_curbatch; /* # ops submitted w/o int */
- + int sc_suspended;
- + struct miscdevice sc_miscdev;
- +#endif
- +};
- +
- +#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
- +#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
- +
- +#endif /* __HIFNHIPPVAR_H__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/Makefile linux-2.6.36/crypto/ocf/hifn/Makefile
- --- linux-2.6.36.orig/crypto/ocf/hifn/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/hifn/Makefile 2010-11-09 20:28:05.002825564 +0100
- @@ -0,0 +1,13 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_HIFN) += hifn7751.o
- +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.36/crypto/ocf/ixp4xx/ixp4xx.c
- --- linux-2.6.36.orig/crypto/ocf/ixp4xx/ixp4xx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ixp4xx/ixp4xx.c 2010-11-09 20:28:05.051258556 +0100
- @@ -0,0 +1,1324 @@
- +/*
- + * An OCF module that uses Intels IXP CryptACC API to do the crypto.
- + * This driver requires the IXP400 Access Library that is available
- + * from Intel in order to operate (or compile).
- + *
- + * Written by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * ALTERNATIVELY, provided that this notice is retained in full, this product
- + * may be distributed under the terms of the GNU General Public License (GPL),
- + * in which case the provisions of the GPL apply INSTEAD OF those given above.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/sched.h>
- +#include <linux/wait.h>
- +#include <linux/crypto.h>
- +#include <linux/interrupt.h>
- +#include <asm/scatterlist.h>
- +
- +#include <IxTypes.h>
- +#include <IxOsBuffMgt.h>
- +#include <IxNpeDl.h>
- +#include <IxCryptoAcc.h>
- +#include <IxQMgr.h>
- +#include <IxOsServices.h>
- +#include <IxOsCacheMMU.h>
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +
- +#ifndef IX_MBUF_PRIV
- +#define IX_MBUF_PRIV(x) ((x)->priv)
- +#endif
- +
- +struct ixp_data;
- +
- +struct ixp_q {
- + struct list_head ixp_q_list;
- + struct ixp_data *ixp_q_data;
- + struct cryptop *ixp_q_crp;
- + struct cryptodesc *ixp_q_ccrd;
- + struct cryptodesc *ixp_q_acrd;
- + IX_MBUF ixp_q_mbuf;
- + UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
- + UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
- + unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
- + unsigned char *ixp_q_iv;
- +};
- +
- +struct ixp_data {
- + int ixp_registered; /* is the context registered */
- + int ixp_crd_flags; /* detect direction changes */
- +
- + int ixp_cipher_alg;
- + int ixp_auth_alg;
- +
- + UINT32 ixp_ctx_id;
- + UINT32 ixp_hash_key_id; /* used when hashing */
- + IxCryptoAccCtx ixp_ctx;
- + IX_MBUF ixp_pri_mbuf;
- + IX_MBUF ixp_sec_mbuf;
- +
- + struct work_struct ixp_pending_work;
- + struct work_struct ixp_registration_work;
- + struct list_head ixp_q; /* unprocessed requests */
- +};
- +
- +#ifdef __ixp46X
- +
- +#define MAX_IOP_SIZE 64 /* words */
- +#define MAX_OOP_SIZE 128
- +
- +#define MAX_PARAMS 3
- +
- +struct ixp_pkq {
- + struct list_head pkq_list;
- + struct cryptkop *pkq_krp;
- +
- + IxCryptoAccPkeEauInOperands pkq_op;
- + IxCryptoAccPkeEauOpResult pkq_result;
- +
- + UINT32 pkq_ibuf0[MAX_IOP_SIZE];
- + UINT32 pkq_ibuf1[MAX_IOP_SIZE];
- + UINT32 pkq_ibuf2[MAX_IOP_SIZE];
- + UINT32 pkq_obuf[MAX_OOP_SIZE];
- +};
- +
- +static LIST_HEAD(ixp_pkq); /* current PK wait list */
- +static struct ixp_pkq *ixp_pk_cur;
- +static spinlock_t ixp_pkq_lock;
- +
- +#endif /* __ixp46X */
- +
- +static int ixp_blocked = 0;
- +
- +static int32_t ixp_id = -1;
- +static struct ixp_data **ixp_sessions = NULL;
- +static u_int32_t ixp_sesnum = 0;
- +
- +static int ixp_process(device_t, struct cryptop *, int);
- +static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
- +static int ixp_freesession(device_t, u_int64_t);
- +#ifdef __ixp46X
- +static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
- +#endif
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +static kmem_cache_t *qcache;
- +#else
- +static struct kmem_cache *qcache;
- +#endif
- +
- +#define debug ixp_debug
- +static int ixp_debug = 0;
- +module_param(ixp_debug, int, 0644);
- +MODULE_PARM_DESC(ixp_debug, "Enable debug");
- +
- +static int ixp_init_crypto = 1;
- +module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
- +MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
- +
- +static void ixp_process_pending(void *arg);
- +static void ixp_registration(void *arg);
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +static void ixp_process_pending_wq(struct work_struct *work);
- +static void ixp_registration_wq(struct work_struct *work);
- +#endif
- +
- +/*
- + * dummy device structure
- + */
- +
- +static struct {
- + softc_device_decl sc_dev;
- +} ixpdev;
- +
- +static device_method_t ixp_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, ixp_newsession),
- + DEVMETHOD(cryptodev_freesession,ixp_freesession),
- + DEVMETHOD(cryptodev_process, ixp_process),
- +#ifdef __ixp46X
- + DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
- +#endif
- +};
- +
- +/*
- + * Generate a new software session.
- + */
- +static int
- +ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
- +{
- + struct ixp_data *ixp;
- + u_int32_t i;
- +#define AUTH_LEN(cri, def) \
- + (cri->cri_mlen ? cri->cri_mlen : (def))
- +
- + dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
- + if (sid == NULL || cri == NULL) {
- + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + if (ixp_sessions) {
- + for (i = 1; i < ixp_sesnum; i++)
- + if (ixp_sessions[i] == NULL)
- + break;
- + } else
- + i = 1; /* NB: to silence compiler warning */
- +
- + if (ixp_sessions == NULL || i == ixp_sesnum) {
- + struct ixp_data **ixpd;
- +
- + if (ixp_sessions == NULL) {
- + i = 1; /* We leave ixp_sessions[0] empty */
- + ixp_sesnum = CRYPTO_SW_SESSIONS;
- + } else
- + ixp_sesnum *= 2;
- +
- + ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
- + if (ixpd == NULL) {
- + /* Reset session number */
- + if (ixp_sesnum == CRYPTO_SW_SESSIONS)
- + ixp_sesnum = 0;
- + else
- + ixp_sesnum /= 2;
- + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
- +
- + /* Copy existing sessions */
- + if (ixp_sessions) {
- + memcpy(ixpd, ixp_sessions,
- + (ixp_sesnum / 2) * sizeof(struct ixp_data *));
- + kfree(ixp_sessions);
- + }
- +
- + ixp_sessions = ixpd;
- + }
- +
- + ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
- + SLAB_ATOMIC);
- + if (ixp_sessions[i] == NULL) {
- + ixp_freesession(NULL, i);
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- +
- + *sid = i;
- +
- + ixp = ixp_sessions[i];
- + memset(ixp, 0, sizeof(*ixp));
- +
- + ixp->ixp_cipher_alg = -1;
- + ixp->ixp_auth_alg = -1;
- + ixp->ixp_ctx_id = -1;
- + INIT_LIST_HEAD(&ixp->ixp_q);
- +
- + ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
- +
- + while (cri) {
- + switch (cri->cri_alg) {
- + case CRYPTO_DES_CBC:
- + ixp->ixp_cipher_alg = cri->cri_alg;
- + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
- + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
- + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
- + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
- + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
- + IX_CRYPTO_ACC_DES_IV_64;
- + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
- + cri->cri_key, (cri->cri_klen + 7) / 8);
- + break;
- +
- + case CRYPTO_3DES_CBC:
- + ixp->ixp_cipher_alg = cri->cri_alg;
- + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
- + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
- + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
- + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
- + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
- + IX_CRYPTO_ACC_DES_IV_64;
- + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
- + cri->cri_key, (cri->cri_klen + 7) / 8);
- + break;
- +
- + case CRYPTO_RIJNDAEL128_CBC:
- + ixp->ixp_cipher_alg = cri->cri_alg;
- + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
- + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
- + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
- + ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
- + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
- + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
- + cri->cri_key, (cri->cri_klen + 7) / 8);
- + break;
- +
- + case CRYPTO_MD5:
- + case CRYPTO_MD5_HMAC:
- + ixp->ixp_auth_alg = cri->cri_alg;
- + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
- + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
- + ixp->ixp_ctx.authCtx.aadLen = 0;
- + /* Only MD5_HMAC needs a key */
- + if (cri->cri_alg == CRYPTO_MD5_HMAC) {
- + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
- + if (ixp->ixp_ctx.authCtx.authKeyLen >
- + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
- + printk(
- + "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
- + cri->cri_klen);
- + ixp_freesession(NULL, i);
- + return EINVAL;
- + }
- + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
- + cri->cri_key, (cri->cri_klen + 7) / 8);
- + }
- + break;
- +
- + case CRYPTO_SHA1:
- + case CRYPTO_SHA1_HMAC:
- + ixp->ixp_auth_alg = cri->cri_alg;
- + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
- + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
- + ixp->ixp_ctx.authCtx.aadLen = 0;
- + /* Only SHA1_HMAC needs a key */
- + if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
- + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
- + if (ixp->ixp_ctx.authCtx.authKeyLen >
- + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
- + printk(
- + "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
- + cri->cri_klen);
- + ixp_freesession(NULL, i);
- + return EINVAL;
- + }
- + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
- + cri->cri_key, (cri->cri_klen + 7) / 8);
- + }
- + break;
- +
- + default:
- + printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
- + ixp_freesession(NULL, i);
- + return EINVAL;
- + }
- + cri = cri->cri_next;
- + }
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
- + INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
- +#else
- + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
- + INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
- +#endif
- +
- + return 0;
- +}
- +
- +
- +/*
- + * Free a session.
- + */
- +static int
- +ixp_freesession(device_t dev, u_int64_t tid)
- +{
- + u_int32_t sid = CRYPTO_SESID2LID(tid);
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid > ixp_sesnum || ixp_sessions == NULL ||
- + ixp_sessions[sid] == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + /* Silently accept and return */
- + if (sid == 0)
- + return 0;
- +
- + if (ixp_sessions[sid]) {
- + if (ixp_sessions[sid]->ixp_ctx_id != -1) {
- + ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
- + ixp_sessions[sid]->ixp_ctx_id = -1;
- + }
- + kfree(ixp_sessions[sid]);
- + }
- + ixp_sessions[sid] = NULL;
- + if (ixp_blocked) {
- + ixp_blocked = 0;
- + crypto_unblock(ixp_id, CRYPTO_SYMQ);
- + }
- + return 0;
- +}
- +
- +
- +/*
- + * callback for when hash processing is complete
- + */
- +
- +static void
- +ixp_hash_perform_cb(
- + UINT32 hash_key_id,
- + IX_MBUF *bufp,
- + IxCryptoAccStatus status)
- +{
- + struct ixp_q *q;
- +
- + dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
- +
- + if (bufp == NULL) {
- + printk("ixp: NULL buf in %s\n", __FUNCTION__);
- + return;
- + }
- +
- + q = IX_MBUF_PRIV(bufp);
- + if (q == NULL) {
- + printk("ixp: NULL priv in %s\n", __FUNCTION__);
- + return;
- + }
- +
- + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
- + /* On success, need to copy hash back into original client buffer */
- + memcpy(q->ixp_hash_dest, q->ixp_hash_src,
- + (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
- + SHA1_HASH_LEN : MD5_HASH_LEN);
- + }
- + else {
- + printk("ixp: hash perform failed status=%d\n", status);
- + q->ixp_q_crp->crp_etype = EINVAL;
- + }
- +
- + /* Free internal buffer used for hashing */
- + kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
- +
- + crypto_done(q->ixp_q_crp);
- + kmem_cache_free(qcache, q);
- +}
- +
- +/*
- + * setup a request and perform it
- + */
- +static void
- +ixp_q_process(struct ixp_q *q)
- +{
- + IxCryptoAccStatus status;
- + struct ixp_data *ixp = q->ixp_q_data;
- + int auth_off = 0;
- + int auth_len = 0;
- + int crypt_off = 0;
- + int crypt_len = 0;
- + int icv_off = 0;
- + char *crypt_func;
- +
- + dprintk("%s(%p)\n", __FUNCTION__, q);
- +
- + if (q->ixp_q_ccrd) {
- + if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
- + q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
- + } else {
- + q->ixp_q_iv = q->ixp_q_iv_data;
- + crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
- + q->ixp_q_ccrd->crd_inject,
- + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
- + (caddr_t) q->ixp_q_iv);
- + }
- +
- + if (q->ixp_q_acrd) {
- + auth_off = q->ixp_q_acrd->crd_skip;
- + auth_len = q->ixp_q_acrd->crd_len;
- + icv_off = q->ixp_q_acrd->crd_inject;
- + }
- +
- + crypt_off = q->ixp_q_ccrd->crd_skip;
- + crypt_len = q->ixp_q_ccrd->crd_len;
- + } else { /* if (q->ixp_q_acrd) */
- + auth_off = q->ixp_q_acrd->crd_skip;
- + auth_len = q->ixp_q_acrd->crd_len;
- + icv_off = q->ixp_q_acrd->crd_inject;
- + }
- +
- + if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
- + struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
- + if (skb_shinfo(skb)->nr_frags) {
- + /*
- + * DAVIDM fix this limitation one day by using
- + * a buffer pool and chaining, it is not currently
- + * needed for current user/kernel space acceleration
- + */
- + printk("ixp: Cannot handle fragmented skb's yet !\n");
- + q->ixp_q_crp->crp_etype = ENOENT;
- + goto done;
- + }
- + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
- + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
- + IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
- + } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
- + struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
- + if (uiop->uio_iovcnt != 1) {
- + /*
- + * DAVIDM fix this limitation one day by using
- + * a buffer pool and chaining, it is not currently
- + * needed for current user/kernel space acceleration
- + */
- + printk("ixp: Cannot handle more than 1 iovec yet !\n");
- + q->ixp_q_crp->crp_etype = ENOENT;
- + goto done;
- + }
- + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
- + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
- + IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
- + } else /* contig buffer */ {
- + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
- + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
- + IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
- + }
- +
- + IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
- +
- + if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
- + /*
- + * For SHA1 and MD5 hash, need to create an internal buffer that is big
- + * enough to hold the original data + the appropriate padding for the
- + * hash algorithm.
- + */
- + UINT8 *tbuf = NULL;
- +
- + IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
- + ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
- + tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
- +
- + if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
- + printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
- + IX_MBUF_MLEN(&q->ixp_q_mbuf));
- + q->ixp_q_crp->crp_etype = ENOMEM;
- + goto done;
- + }
- + memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
- +
- + /* Set location in client buffer to copy hash into */
- + q->ixp_hash_dest =
- + &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
- +
- + IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
- +
- + /* Set location in internal buffer for where hash starts */
- + q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
- +
- + crypt_func = "ixCryptoAccHashPerform";
- + status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
- + &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
- + &ixp->ixp_hash_key_id);
- + }
- + else {
- + crypt_func = "ixCryptoAccAuthCryptPerform";
- + status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
- + NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
- + q->ixp_q_iv);
- + }
- +
- + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
- + return;
- +
- + if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
- + q->ixp_q_crp->crp_etype = ENOMEM;
- + goto done;
- + }
- +
- + printk("ixp: %s failed %u\n", crypt_func, status);
- + q->ixp_q_crp->crp_etype = EINVAL;
- +
- +done:
- + crypto_done(q->ixp_q_crp);
- + kmem_cache_free(qcache, q);
- +}
- +
- +
- +/*
- + * because we cannot process the Q from the Register callback
- + * we do it here on a task Q.
- + */
- +
- +static void
- +ixp_process_pending(void *arg)
- +{
- + struct ixp_data *ixp = arg;
- + struct ixp_q *q = NULL;
- +
- + dprintk("%s(%p)\n", __FUNCTION__, arg);
- +
- + if (!ixp)
- + return;
- +
- + while (!list_empty(&ixp->ixp_q)) {
- + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
- + list_del(&q->ixp_q_list);
- + ixp_q_process(q);
- + }
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +static void
- +ixp_process_pending_wq(struct work_struct *work)
- +{
- + struct ixp_data *ixp = container_of(work, struct ixp_data, ixp_pending_work);
- + ixp_process_pending(ixp);
- +}
- +#endif
- +
- +/*
- + * callback for when context registration is complete
- + */
- +
- +static void
- +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
- +{
- + int i;
- + struct ixp_data *ixp;
- + struct ixp_q *q;
- +
- + dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
- +
- + /*
- + * free any buffer passed in to this routine
- + */
- + if (bufp) {
- + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
- + kfree(IX_MBUF_MDATA(bufp));
- + IX_MBUF_MDATA(bufp) = NULL;
- + }
- +
- + for (i = 0; i < ixp_sesnum; i++) {
- + ixp = ixp_sessions[i];
- + if (ixp && ixp->ixp_ctx_id == ctx_id)
- + break;
- + }
- + if (i >= ixp_sesnum) {
- + printk("ixp: invalid context id %d\n", ctx_id);
- + return;
- + }
- +
- + if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
- + /* this is normal to free the first of two buffers */
- + dprintk("ixp: register not finished yet.\n");
- + return;
- + }
- +
- + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
- + printk("ixp: register failed 0x%x\n", status);
- + while (!list_empty(&ixp->ixp_q)) {
- + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
- + list_del(&q->ixp_q_list);
- + q->ixp_q_crp->crp_etype = EINVAL;
- + crypto_done(q->ixp_q_crp);
- + kmem_cache_free(qcache, q);
- + }
- + return;
- + }
- +
- + /*
- + * we are now registered, we cannot start processing the Q here
- + * or we get strange errors with AES (DES/3DES seem to be ok).
- + */
- + ixp->ixp_registered = 1;
- + schedule_work(&ixp->ixp_pending_work);
- +}
- +
- +
- +/*
- + * callback for when data processing is complete
- + */
- +
- +static void
- +ixp_perform_cb(
- + UINT32 ctx_id,
- + IX_MBUF *sbufp,
- + IX_MBUF *dbufp,
- + IxCryptoAccStatus status)
- +{
- + struct ixp_q *q;
- +
- + dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
- + dbufp, status);
- +
- + if (sbufp == NULL) {
- + printk("ixp: NULL sbuf in ixp_perform_cb\n");
- + return;
- + }
- +
- + q = IX_MBUF_PRIV(sbufp);
- + if (q == NULL) {
- + printk("ixp: NULL priv in ixp_perform_cb\n");
- + return;
- + }
- +
- + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
- + printk("ixp: perform failed status=%d\n", status);
- + q->ixp_q_crp->crp_etype = EINVAL;
- + }
- +
- + crypto_done(q->ixp_q_crp);
- + kmem_cache_free(qcache, q);
- +}
- +
- +
- +/*
- + * registration is not callable at IRQ time, so we defer
- + * to a task queue, this routines completes the registration for us
- + * when the task queue runs
- + *
- + * Unfortunately this means we cannot tell OCF that the driver is blocked,
- + * we do that on the next request.
- + */
- +
- +static void
- +ixp_registration(void *arg)
- +{
- + struct ixp_data *ixp = arg;
- + struct ixp_q *q = NULL;
- + IX_MBUF *pri = NULL, *sec = NULL;
- + int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
- +
- + if (!ixp) {
- + printk("ixp: ixp_registration with no arg\n");
- + return;
- + }
- +
- + if (ixp->ixp_ctx_id != -1) {
- + ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
- + ixp->ixp_ctx_id = -1;
- + }
- +
- + if (list_empty(&ixp->ixp_q)) {
- + printk("ixp: ixp_registration with no Q\n");
- + return;
- + }
- +
- + /*
- + * setup the primary and secondary buffers
- + */
- + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
- + if (q->ixp_q_acrd) {
- + pri = &ixp->ixp_pri_mbuf;
- + sec = &ixp->ixp_sec_mbuf;
- + IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
- + IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
- + IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
- + IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
- + }
- +
- + /* Only need to register if a crypt op or HMAC op */
- + if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
- + ixp->ixp_auth_alg == CRYPTO_MD5)) {
- + status = ixCryptoAccCtxRegister(
- + &ixp->ixp_ctx,
- + pri, sec,
- + ixp_register_cb,
- + ixp_perform_cb,
- + &ixp->ixp_ctx_id);
- + }
- + else {
- + /* Otherwise we start processing pending q */
- + schedule_work(&ixp->ixp_pending_work);
- + }
- +
- + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
- + return;
- +
- + if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
- + printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
- + ixp_blocked = 1;
- + /* perhaps we should return EGAIN on queued ops ? */
- + return;
- + }
- +
- + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
- + ixp->ixp_ctx_id = -1;
- +
- + /*
- + * everything waiting is toasted
- + */
- + while (!list_empty(&ixp->ixp_q)) {
- + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
- + list_del(&q->ixp_q_list);
- + q->ixp_q_crp->crp_etype = ENOENT;
- + crypto_done(q->ixp_q_crp);
- + kmem_cache_free(qcache, q);
- + }
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +static void
- +ixp_registration_wq(struct work_struct *work)
- +{
- + struct ixp_data *ixp = container_of(work, struct ixp_data,
- + ixp_registration_work);
- + ixp_registration(ixp);
- +}
- +#endif
- +
- +/*
- + * Process a request.
- + */
- +static int
- +ixp_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + struct ixp_data *ixp;
- + unsigned int lid;
- + struct ixp_q *q = NULL;
- + int status;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + /* Sanity check */
- + if (crp == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + crp->crp_etype = 0;
- +
- + if (ixp_blocked)
- + return ERESTART;
- +
- + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + /*
- + * find the session we are using
- + */
- +
- + lid = crp->crp_sid & 0xffffffff;
- + if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
- + ixp_sessions[lid] == NULL) {
- + crp->crp_etype = ENOENT;
- + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
- + goto done;
- + }
- + ixp = ixp_sessions[lid];
- +
- + /*
- + * setup a new request ready for queuing
- + */
- + q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
- + if (q == NULL) {
- + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
- + crp->crp_etype = ENOMEM;
- + goto done;
- + }
- + /*
- + * save some cycles by only zeroing the important bits
- + */
- + memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
- + q->ixp_q_ccrd = NULL;
- + q->ixp_q_acrd = NULL;
- + q->ixp_q_crp = crp;
- + q->ixp_q_data = ixp;
- +
- + /*
- + * point the cipher and auth descriptors appropriately
- + * check that we have something to do
- + */
- + if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
- + q->ixp_q_ccrd = crp->crp_desc;
- + else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
- + q->ixp_q_acrd = crp->crp_desc;
- + else {
- + crp->crp_etype = ENOENT;
- + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
- + goto done;
- + }
- + if (crp->crp_desc->crd_next) {
- + if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
- + q->ixp_q_ccrd = crp->crp_desc->crd_next;
- + else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
- + q->ixp_q_acrd = crp->crp_desc->crd_next;
- + else {
- + crp->crp_etype = ENOENT;
- + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
- + goto done;
- + }
- + }
- +
- + /*
- + * If there is a direction change for this context then we mark it as
- + * unregistered and re-register is for the new direction. This is not
- + * a very expensive operation and currently only tends to happen when
- + * user-space application are doing benchmarks
- + *
- + * DM - we should be checking for pending requests before unregistering.
- + */
- + if (q->ixp_q_ccrd && ixp->ixp_registered &&
- + ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
- + dprintk("%s - detected direction change on session\n", __FUNCTION__);
- + ixp->ixp_registered = 0;
- + }
- +
- + /*
- + * if we are registered, call straight into the perform code
- + */
- + if (ixp->ixp_registered) {
- + ixp_q_process(q);
- + return 0;
- + }
- +
- + /*
- + * the only part of the context not set in newsession is the direction
- + * dependent parts
- + */
- + if (q->ixp_q_ccrd) {
- + ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
- + if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
- + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
- + IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
- + } else {
- + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
- + IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
- + }
- + } else {
- + /* q->ixp_q_acrd must be set if we are here */
- + ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
- + }
- +
- + status = list_empty(&ixp->ixp_q);
- + list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
- + if (status)
- + schedule_work(&ixp->ixp_registration_work);
- + return 0;
- +
- +done:
- + if (q)
- + kmem_cache_free(qcache, q);
- + crypto_done(crp);
- + return 0;
- +}
- +
- +
- +#ifdef __ixp46X
- +/*
- + * key processing support for the ixp465
- + */
- +
- +
- +/*
- + * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
- + * assume zeroed and only copy bits that are significant
- + */
- +
- +static int
- +ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
- +{
- + unsigned char *src = (unsigned char *) p->crp_p;
- + unsigned char *dst;
- + int len, bits = p->crp_nbits;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
- + dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
- + bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
- + return -1;
- + }
- +
- + len = (bits + 31) / 32; /* the number UINT32's needed */
- +
- + dst = (unsigned char *) &buf[len];
- + dst--;
- +
- + while (bits > 0) {
- + *dst-- = *src++;
- + bits -= 8;
- + }
- +
- +#if 0 /* no need to zero remaining bits as it is done during request alloc */
- + while (dst > (unsigned char *) buf)
- + *dst-- = '\0';
- +#endif
- +
- + op->pData = buf;
- + op->dataLen = len;
- + return 0;
- +}
- +
- +/*
- + * copy out the result, be as forgiving as we can about small output buffers
- + */
- +
- +static int
- +ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
- +{
- + unsigned char *dst = (unsigned char *) p->crp_p;
- + unsigned char *src = (unsigned char *) buf;
- + int len, z, bits = p->crp_nbits;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + len = op->dataLen * sizeof(UINT32);
- +
- + /* skip leading zeroes to be small buffer friendly */
- + z = 0;
- + while (z < len && src[z] == '\0')
- + z++;
- +
- + src += len;
- + src--;
- + len -= z;
- +
- + while (len > 0 && bits > 0) {
- + *dst++ = *src--;
- + len--;
- + bits -= 8;
- + }
- +
- + while (bits > 0) {
- + *dst++ = '\0';
- + bits -= 8;
- + }
- +
- + if (len > 0) {
- + dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
- + __FUNCTION__, len, z, p->crp_nbits / 8);
- + return -1;
- + }
- +
- + return 0;
- +}
- +
- +
- +/*
- + * the parameter offsets for exp_mod
- + */
- +
- +#define IXP_PARAM_BASE 0
- +#define IXP_PARAM_EXP 1
- +#define IXP_PARAM_MOD 2
- +#define IXP_PARAM_RES 3
- +
- +/*
- + * key processing complete callback, is also used to start processing
- + * by passing a NULL for pResult
- + */
- +
- +static void
- +ixp_kperform_cb(
- + IxCryptoAccPkeEauOperation operation,
- + IxCryptoAccPkeEauOpResult *pResult,
- + BOOL carryOrBorrow,
- + IxCryptoAccStatus status)
- +{
- + struct ixp_pkq *q, *tmp;
- + unsigned long flags;
- +
- + dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
- + carryOrBorrow, status);
- +
- + /* handle a completed request */
- + if (pResult) {
- + if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
- + q = ixp_pk_cur;
- + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
- + dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
- + q->pkq_krp->krp_status = ERANGE; /* could do better */
- + } else {
- + /* copy out the result */
- + if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
- + &q->pkq_result, q->pkq_obuf))
- + q->pkq_krp->krp_status = ERANGE;
- + }
- + crypto_kdone(q->pkq_krp);
- + kfree(q);
- + ixp_pk_cur = NULL;
- + } else
- + printk("%s - callback with invalid result pointer\n", __FUNCTION__);
- + }
- +
- + spin_lock_irqsave(&ixp_pkq_lock, flags);
- + if (ixp_pk_cur || list_empty(&ixp_pkq)) {
- + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
- + return;
- + }
- +
- + list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
- +
- + list_del(&q->pkq_list);
- + ixp_pk_cur = q;
- +
- + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
- +
- + status = ixCryptoAccPkeEauPerform(
- + IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
- + &q->pkq_op,
- + ixp_kperform_cb,
- + &q->pkq_result);
- +
- + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
- + dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
- + return; /* callback will return here for callback */
- + } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
- + printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
- + } else {
- + printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
- + __FUNCTION__, status);
- + }
- + q->pkq_krp->krp_status = ERANGE; /* could do better */
- + crypto_kdone(q->pkq_krp);
- + kfree(q);
- + spin_lock_irqsave(&ixp_pkq_lock, flags);
- + }
- + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
- +}
- +
- +
- +static int
- +ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
- +{
- + struct ixp_pkq *q;
- + int rc = 0;
- + unsigned long flags;
- +
- + dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
- + krp->krp_param[IXP_PARAM_BASE].crp_nbits,
- + krp->krp_param[IXP_PARAM_EXP].crp_nbits,
- + krp->krp_param[IXP_PARAM_MOD].crp_nbits,
- + krp->krp_param[IXP_PARAM_RES].crp_nbits);
- +
- +
- + if (krp->krp_op != CRK_MOD_EXP) {
- + krp->krp_status = EOPNOTSUPP;
- + goto err;
- + }
- +
- + q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
- + if (q == NULL) {
- + krp->krp_status = ENOMEM;
- + goto err;
- + }
- +
- + /*
- + * The PKE engine does not appear to zero the output buffer
- + * appropriately, so we need to do it all here.
- + */
- + memset(q, 0, sizeof(*q));
- +
- + q->pkq_krp = krp;
- + INIT_LIST_HEAD(&q->pkq_list);
- +
- + if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
- + q->pkq_ibuf0))
- + rc = 1;
- + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
- + &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
- + rc = 2;
- + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
- + &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
- + rc = 3;
- +
- + if (rc) {
- + kfree(q);
- + krp->krp_status = ERANGE;
- + goto err;
- + }
- +
- + q->pkq_result.pData = q->pkq_obuf;
- + q->pkq_result.dataLen =
- + (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
- +
- + spin_lock_irqsave(&ixp_pkq_lock, flags);
- + list_add_tail(&q->pkq_list, &ixp_pkq);
- + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
- +
- + if (!ixp_pk_cur)
- + ixp_kperform_cb(0, NULL, 0, 0);
- + return (0);
- +
- +err:
- + crypto_kdone(krp);
- + return (0);
- +}
- +
- +
- +
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- +/*
- + * We run the random number generator output through SHA so that it
- + * is FIPS compliant.
- + */
- +
- +static volatile int sha_done = 0;
- +static unsigned char sha_digest[20];
- +
- +static void
- +ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
- +{
- + dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
- + if (sha_digest != digest)
- + printk("digest error\n");
- + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
- + sha_done = 1;
- + else
- + sha_done = -status;
- +}
- +
- +static int
- +ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
- +{
- + IxCryptoAccStatus status;
- + int i, n, rc;
- +
- + dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
- + memset(buf, 0, maxwords * sizeof(*buf));
- + status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
- + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
- + dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
- + __FUNCTION__, status);
- + return 0;
- + }
- +
- + /*
- + * run the random data through SHA to make it look more random
- + */
- +
- + n = sizeof(sha_digest); /* process digest bytes at a time */
- +
- + rc = 0;
- + for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
- + if ((maxwords - i) * sizeof(*buf) < n)
- + n = (maxwords - i) * sizeof(*buf);
- + sha_done = 0;
- + status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
- + (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
- + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
- + dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
- + return -EIO;
- + }
- + while (!sha_done)
- + schedule();
- + if (sha_done < 0) {
- + dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
- + return 0;
- + }
- + memcpy(&buf[i], sha_digest, n);
- + rc += n / sizeof(*buf);;
- + }
- +
- + return rc;
- +}
- +#endif /* CONFIG_OCF_RANDOMHARVEST */
- +
- +#endif /* __ixp46X */
- +
- +
- +
- +/*
- + * our driver startup and shutdown routines
- + */
- +
- +static int
- +ixp_init(void)
- +{
- + dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
- +
- + if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
- + printk("ixCryptoAccInit failed, assuming already initialised!\n");
- +
- + qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
- + SLAB_HWCACHE_ALIGN, NULL
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
- + , NULL
- +#endif
- + );
- + if (!qcache) {
- + printk("failed to create Qcache\n");
- + return -ENOENT;
- + }
- +
- + memset(&ixpdev, 0, sizeof(ixpdev));
- + softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
- +
- + ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
- + CRYPTOCAP_F_HARDWARE);
- + if (ixp_id < 0)
- + panic("IXP/OCF crypto device cannot initialize!");
- +
- +#define REGISTER(alg) \
- + crypto_register(ixp_id,alg,0,0)
- +
- + REGISTER(CRYPTO_DES_CBC);
- + REGISTER(CRYPTO_3DES_CBC);
- + REGISTER(CRYPTO_RIJNDAEL128_CBC);
- +#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
- + REGISTER(CRYPTO_MD5);
- + REGISTER(CRYPTO_SHA1);
- +#endif
- + REGISTER(CRYPTO_MD5_HMAC);
- + REGISTER(CRYPTO_SHA1_HMAC);
- +#undef REGISTER
- +
- +#ifdef __ixp46X
- + spin_lock_init(&ixp_pkq_lock);
- + /*
- + * we do not enable the go fast options here as they can potentially
- + * allow timing based attacks
- + *
- + * http://www.openssl.org/news/secadv_20030219.txt
- + */
- + ixCryptoAccPkeEauExpConfig(0, 0);
- + crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- + crypto_rregister(ixp_id, ixp_read_random, NULL);
- +#endif
- +#endif
- +
- + return 0;
- +}
- +
- +static void
- +ixp_exit(void)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + crypto_unregister_all(ixp_id);
- + ixp_id = -1;
- + kmem_cache_destroy(qcache);
- + qcache = NULL;
- +}
- +
- +module_init(ixp_init);
- +module_exit(ixp_exit);
- +
- +MODULE_LICENSE("Dual BSD/GPL");
- +MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
- +MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
- diff -Nur linux-2.6.36.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.36/crypto/ocf/ixp4xx/Makefile
- --- linux-2.6.36.orig/crypto/ocf/ixp4xx/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ixp4xx/Makefile 2010-11-09 20:28:05.113478850 +0100
- @@ -0,0 +1,104 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +#
- +# You will need to point this at your Intel ixp425 includes, this portion
- +# of the Makefile only really works under SGLinux with the appropriate libs
- +# installed. They can be downloaded from http://www.snapgear.org/
- +#
- +ifeq ($(CONFIG_CPU_IXP46X),y)
- +IXPLATFORM = ixp46X
- +else
- +ifeq ($(CONFIG_CPU_IXP43X),y)
- +IXPLATFORM = ixp43X
- +else
- +IXPLATFORM = ixp42X
- +endif
- +endif
- +
- +ifdef CONFIG_IXP400_LIB_2_4
- +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
- +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
- +endif
- +ifdef CONFIG_IXP400_LIB_2_1
- +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
- +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
- +endif
- +ifdef CONFIG_IXP400_LIB_2_0
- +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
- +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
- +endif
- +ifdef IX_XSCALE_SW
- +ifdef CONFIG_IXP400_LIB_2_4
- +IXP_CFLAGS = \
- + -I$(ROOTDIR)/. \
- + -I$(IX_XSCALE_SW)/src/include \
- + -I$(OSAL_DIR)/common/include/ \
- + -I$(OSAL_DIR)/common/include/modules/ \
- + -I$(OSAL_DIR)/common/include/modules/ddk/ \
- + -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
- + -I$(OSAL_DIR)/common/include/modules/ioMem/ \
- + -I$(OSAL_DIR)/common/os/linux/include/ \
- + -I$(OSAL_DIR)/common/os/linux/include/core/ \
- + -I$(OSAL_DIR)/common/os/linux/include/modules/ \
- + -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
- + -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
- + -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
- + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
- + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
- + -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
- + -DUSE_IXP4XX_CRYPTO
- +else
- +IXP_CFLAGS = \
- + -I$(ROOTDIR)/. \
- + -I$(IX_XSCALE_SW)/src/include \
- + -I$(OSAL_DIR)/ \
- + -I$(OSAL_DIR)/os/linux/include/ \
- + -I$(OSAL_DIR)/os/linux/include/modules/ \
- + -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
- + -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
- + -I$(OSAL_DIR)/os/linux/include/core/ \
- + -I$(OSAL_DIR)/os/linux/include/platforms/ \
- + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
- + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
- + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
- + -I$(OSAL_DIR)/os/linux/include/core/ \
- + -I$(OSAL_DIR)/include/ \
- + -I$(OSAL_DIR)/include/modules/ \
- + -I$(OSAL_DIR)/include/modules/bufferMgt/ \
- + -I$(OSAL_DIR)/include/modules/ioMem/ \
- + -I$(OSAL_DIR)/include/platforms/ \
- + -I$(OSAL_DIR)/include/platforms/ixp400/ \
- + -DUSE_IXP4XX_CRYPTO
- +endif
- +endif
- +ifdef CONFIG_IXP400_LIB_1_4
- +IXP_CFLAGS = \
- + -I$(ROOTDIR)/. \
- + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
- + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
- + -DUSE_IXP4XX_CRYPTO
- +endif
- +ifndef IXPDIR
- +IXPDIR = ixp-version-is-not-supported
- +endif
- +
- +ifeq ($(CONFIG_CPU_IXP46X),y)
- +IXP_CFLAGS += -D__ixp46X
- +else
- +ifeq ($(CONFIG_CPU_IXP43X),y)
- +IXP_CFLAGS += -D__ixp43X
- +else
- +IXP_CFLAGS += -D__ixp42X
- +endif
- +endif
- +
- +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/Kconfig linux-2.6.36/crypto/ocf/Kconfig
- --- linux-2.6.36.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/Kconfig 2010-11-09 20:28:05.141255099 +0100
- @@ -0,0 +1,119 @@
- +menu "OCF Configuration"
- +
- +config OCF_OCF
- + tristate "OCF (Open Cryptograhic Framework)"
- + help
- + A linux port of the OpenBSD/FreeBSD crypto framework.
- +
- +config OCF_RANDOMHARVEST
- + bool "crypto random --- harvest entropy for /dev/random"
- + depends on OCF_OCF
- + help
- + Includes code to harvest random numbers from devices that support it.
- +
- +config OCF_FIPS
- + bool "enable fips RNG checks"
- + depends on OCF_OCF && OCF_RANDOMHARVEST
- + help
- + Run all RNG provided data through a fips check before
- + adding it /dev/random's entropy pool.
- +
- +config OCF_CRYPTODEV
- + tristate "cryptodev (user space support)"
- + depends on OCF_OCF
- + help
- + The user space API to access crypto hardware.
- +
- +config OCF_CRYPTOSOFT
- + tristate "cryptosoft (software crypto engine)"
- + depends on OCF_OCF
- + help
- + A software driver for the OCF framework that uses
- + the kernel CryptoAPI.
- +
- +config OCF_SAFE
- + tristate "safenet (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + A driver for a number of the safenet Excel crypto accelerators.
- + Currently tested and working on the 1141 and 1741.
- +
- +config OCF_IXP4XX
- + tristate "IXP4xx (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + XScale IXP4xx crypto accelerator driver. Requires the
- + Intel Access library.
- +
- +config OCF_IXP4XX_SHA1_MD5
- + bool "IXP4xx SHA1 and MD5 Hashing"
- + depends on OCF_IXP4XX
- + help
- + Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
- + Note: this is MUCH slower than using cryptosoft (software crypto engine).
- +
- +config OCF_HIFN
- + tristate "hifn (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for various HIFN based crypto accelerators.
- + (7951, 7955, 7956, 7751, 7811)
- +
- +config OCF_HIFNHIPP
- + tristate "Hifn HIPP (HW packet crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for various HIFN (HIPP) based crypto accelerators
- + (7855)
- +
- +config OCF_TALITOS
- + tristate "talitos (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for Freescale's security engine (SEC/talitos).
- +
- +config OCF_PASEMI
- + tristate "pasemi (HW crypto engine)"
- + depends on OCF_OCF && PPC_PASEMI
- + help
- + OCF driver for the PA Semi PWRficient DMA Engine
- +
- +config OCF_EP80579
- + tristate "ep80579 (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for the Intel EP80579 Integrated Processor Product Line.
- +
- +config OCF_CRYPTOCTEON
- + tristate "cryptocteon (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for the Cavium OCTEON Processors.
- +
- +config OCF_KIRKWOOD
- + tristate "kirkwood (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
- +
- +config OCF_C7108
- + tristate "Micronas 7108 (HW crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for the Microna 7108 Cipher processors.
- +
- +config OCF_OCFNULL
- + tristate "ocfnull (fake crypto engine)"
- + depends on OCF_OCF
- + help
- + OCF driver for measuring ipsec overheads (does no crypto)
- +
- +config OCF_BENCH
- + tristate "ocf-bench (HW crypto in-kernel benchmark)"
- + depends on OCF_OCF
- + help
- + A very simple encryption test for the in-kernel interface
- + of OCF. Also includes code to benchmark the IXP Access library
- + for comparison.
- +
- +endmenu
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 2010-11-09 20:28:05.189557501 +0100
- @@ -0,0 +1,317 @@
- +/* rijndael-alg-ref.c v2.0 August '99
- + * Reference ANSI C code
- + * authors: Paulo Barreto
- + * Vincent Rijmen, K.U.Leuven
- + *
- + * This code is placed in the public domain.
- + */
- +
- +#include "mvOs.h"
- +
- +#include "mvAesAlg.h"
- +
- +#include "mvAesBoxes.dat"
- +
- +
- +MV_U8 mul1(MV_U8 aa, MV_U8 bb);
- +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
- +void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
- +void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
- +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
- +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
- +void InvMixColumn(MV_U8 a[4][MAXBC]);
- +
- +
- +#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
- +
- +MV_U8 mul1(MV_U8 aa, MV_U8 bb)
- +{
- + return mask[bb] & Alogtable[aa + Logtable[bb]];
- +}
- +
- +
- +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
- +{
- + /* Exor corresponding text input and round key input bytes
- + */
- + ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
- + ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
- + ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
- + ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
- +
- +}
- +
- +void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
- + /* Row 0 remains unchanged
- + * The other three rows are shifted a variable amount
- + */
- + MV_U8 tmp[MAXBC];
- +
- + tmp[0] = a[1][1];
- + tmp[1] = a[1][2];
- + tmp[2] = a[1][3];
- + tmp[3] = a[1][0];
- +
- + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
- + /*
- + a[1][0] = tmp[0];
- + a[1][1] = tmp[1];
- + a[1][2] = tmp[2];
- + a[1][3] = tmp[3];
- + */
- + tmp[0] = a[2][2];
- + tmp[1] = a[2][3];
- + tmp[2] = a[2][0];
- + tmp[3] = a[2][1];
- +
- + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
- + /*
- + a[2][0] = tmp[0];
- + a[2][1] = tmp[1];
- + a[2][2] = tmp[2];
- + a[2][3] = tmp[3];
- + */
- + tmp[0] = a[3][3];
- + tmp[1] = a[3][0];
- + tmp[2] = a[3][1];
- + tmp[3] = a[3][2];
- +
- + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
- + /*
- + a[3][0] = tmp[0];
- + a[3][1] = tmp[1];
- + a[3][2] = tmp[2];
- + a[3][3] = tmp[3];
- + */
- +}
- +
- +void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
- + /* Row 0 remains unchanged
- + * The other three rows are shifted a variable amount
- + */
- + MV_U8 tmp[MAXBC];
- +
- + tmp[0] = a[1][3];
- + tmp[1] = a[1][0];
- + tmp[2] = a[1][1];
- + tmp[3] = a[1][2];
- +
- + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
- + /*
- + a[1][0] = tmp[0];
- + a[1][1] = tmp[1];
- + a[1][2] = tmp[2];
- + a[1][3] = tmp[3];
- + */
- +
- + tmp[0] = a[2][2];
- + tmp[1] = a[2][3];
- + tmp[2] = a[2][0];
- + tmp[3] = a[2][1];
- +
- + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
- + /*
- + a[2][0] = tmp[0];
- + a[2][1] = tmp[1];
- + a[2][2] = tmp[2];
- + a[2][3] = tmp[3];
- + */
- +
- + tmp[0] = a[3][1];
- + tmp[1] = a[3][2];
- + tmp[2] = a[3][3];
- + tmp[3] = a[3][0];
- +
- + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
- + /*
- + a[3][0] = tmp[0];
- + a[3][1] = tmp[1];
- + a[3][2] = tmp[2];
- + a[3][3] = tmp[3];
- + */
- +}
- +
- +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
- + /* Replace every byte of the input by the byte at that place
- + * in the nonlinear S-box
- + */
- + int i, j;
- +
- + for(i = 0; i < 4; i++)
- + for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
- +}
- +
- +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
- + /* Mix the four bytes of every column in a linear way
- + */
- + MV_U8 b[4][MAXBC];
- + int i, j;
- +
- + for(j = 0; j < 4; j++){
- + b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
- + b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
- + b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
- + b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
- + }
- + for(i = 0; i < 4; i++)
- + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
- + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;
- +}
- +
- +void InvMixColumn(MV_U8 a[4][MAXBC]) {
- + /* Mix the four bytes of every column in a linear way
- + * This is the opposite operation of Mixcolumn
- + */
- + MV_U8 b[4][MAXBC];
- + int i, j;
- +
- + for(j = 0; j < 4; j++){
- + b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
- + b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
- + b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
- + b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
- + }
- + for(i = 0; i < 4; i++)
- + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
- + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
- +}
- +
- +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
- +{
- + /* Calculate the necessary round keys
- + * The number of calculations depends on keyBits and blockBits
- + */
- + int KC, BC, ROUNDS;
- + int i, j, t, rconpointer = 0;
- + MV_U8 tk[4][MAXKC];
- +
- + switch (keyBits) {
- + case 128: KC = 4; break;
- + case 192: KC = 6; break;
- + case 256: KC = 8; break;
- + default : return (-1);
- + }
- +
- + switch (blockBits) {
- + case 128: BC = 4; break;
- + case 192: BC = 6; break;
- + case 256: BC = 8; break;
- + default : return (-2);
- + }
- +
- + switch (keyBits >= blockBits ? keyBits : blockBits) {
- + case 128: ROUNDS = 10; break;
- + case 192: ROUNDS = 12; break;
- + case 256: ROUNDS = 14; break;
- + default : return (-3); /* this cannot happen */
- + }
- +
- +
- + for(j = 0; j < KC; j++)
- + for(i = 0; i < 4; i++)
- + tk[i][j] = k[i][j];
- + t = 0;
- + /* copy values into round key array */
- + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
- + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
- +
- + while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
- + /* calculate new values */
- + for(i = 0; i < 4; i++)
- + tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
- + tk[0][0] ^= rcon[rconpointer++];
- +
- + if (KC != 8)
- + for(j = 1; j < KC; j++)
- + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
- + else {
- + for(j = 1; j < KC/2; j++)
- + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
- + for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
- + for(j = KC/2 + 1; j < KC; j++)
- + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
- + }
- + /* copy values into round key array */
- + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
- + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
- + }
- +
- + return 0;
- +}
- +
- +
- +
- +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
- +{
- + /* Encryption of one block.
- + */
- + int r, BC, ROUNDS;
- +
- + BC = 4;
- + ROUNDS = rounds;
- +
- + /* begin with a key addition
- + */
- +
- + KeyAddition(a,rk[0],BC);
- +
- + /* ROUNDS-1 ordinary rounds
- + */
- + for(r = 1; r < ROUNDS; r++) {
- + Substitution(a,S);
- + ShiftRow128Enc(a);
- + MixColumn(a, rk[r]);
- + /*KeyAddition(a,rk[r],BC);*/
- + }
- +
- + /* Last round is special: there is no MixColumn
- + */
- + Substitution(a,S);
- + ShiftRow128Enc(a);
- + KeyAddition(a,rk[ROUNDS],BC);
- +
- + return 0;
- +}
- +
- +
- +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
- +{
- + int r, BC, ROUNDS;
- +
- + BC = 4;
- + ROUNDS = rounds;
- +
- + /* To decrypt: apply the inverse operations of the encrypt routine,
- + * in opposite order
- + *
- + * (KeyAddition is an involution: it 's equal to its inverse)
- + * (the inverse of Substitution with table S is Substitution with the inverse table of S)
- + * (the inverse of Shiftrow is Shiftrow over a suitable distance)
- + */
- +
- + /* First the special round:
- + * without InvMixColumn
- + * with extra KeyAddition
- + */
- + KeyAddition(a,rk[ROUNDS],BC);
- + ShiftRow128Dec(a);
- + Substitution(a,Si);
- +
- + /* ROUNDS-1 ordinary rounds
- + */
- + for(r = ROUNDS-1; r > 0; r--) {
- + KeyAddition(a,rk[r],BC);
- + InvMixColumn(a);
- + ShiftRow128Dec(a);
- + Substitution(a,Si);
- +
- + }
- +
- + /* End with the extra key addition
- + */
- +
- + KeyAddition(a,rk[0],BC);
- +
- + return 0;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 2010-11-09 20:28:05.222495460 +0100
- @@ -0,0 +1,19 @@
- +/* rijndael-alg-ref.h v2.0 August '99
- + * Reference ANSI C code
- + * authors: Paulo Barreto
- + * Vincent Rijmen, K.U.Leuven
- + */
- +#ifndef __RIJNDAEL_ALG_H
- +#define __RIJNDAEL_ALG_H
- +
- +#define MAXBC (128/32)
- +#define MAXKC (256/32)
- +#define MAXROUNDS 14
- +
- +
- +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]);
- +
- +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
- +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
- +
- +#endif /* __RIJNDAEL_ALG_H */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 2010-11-09 20:28:05.264499847 +0100
- @@ -0,0 +1,312 @@
- +/* rijndael-api-ref.c v2.1 April 2000
- + * Reference ANSI C code
- + * authors: v2.0 Paulo Barreto
- + * Vincent Rijmen, K.U.Leuven
- + * v2.1 Vincent Rijmen, K.U.Leuven
- + *
- + * This code is placed in the public domain.
- + */
- +#include "mvOs.h"
- +
- +#include "mvAes.h"
- +#include "mvAesAlg.h"
- +
- +
- +/* Defines:
- + Add any additional defines you need
- +*/
- +
- +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
- +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
- +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
- +
- +
- +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen)
- +{
- + MV_U8 W[MAXROUNDS+1][4][MAXBC];
- + MV_U8 k[4][MAXKC];
- + MV_U8 j;
- + int i, rounds, KC;
- +
- + if (expandedKey == NULL)
- + {
- + return AES_BAD_KEY_INSTANCE;
- + }
- +
- + if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256)))
- + {
- + return AES_BAD_KEY_MAT;
- + }
- +
- + if (keyMaterial == NULL)
- + {
- + return AES_BAD_KEY_MAT;
- + }
- +
- + /* initialize key schedule: */
- + for(i=0; i<keyLen/8; i++)
- + {
- + j = keyMaterial[i];
- + k[i % 4][i / 4] = j;
- + }
- +
- + rijndaelKeySched (k, keyLen, blockLen, W);
- +#ifdef MV_AES_DEBUG
- + {
- + MV_U8* pW = &W[0][0][0];
- + int x;
- +
- + mvOsPrintf("Expended Key: size = %d\n", sizeof(W));
- + for(i=0; i<sizeof(W); i++)
- + {
- + mvOsPrintf("%02x ", pW[i]);
- + }
- + for(i=0; i<MAXROUNDS+1; i++)
- + {
- + mvOsPrintf("\n Round #%02d: ", i);
- + for(x=0; x<MAXBC; x++)
- + {
- + mvOsPrintf("%02x%02x%02x%02x ",
- + W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]);
- + }
- + mvOsPrintf("\n");
- + }
- + }
- +#endif /* MV_AES_DEBUG */
- + switch (keyLen)
- + {
- + case 128:
- + rounds = 10;
- + KC = 4;
- + break;
- + case 192:
- + rounds = 12;
- + KC = 6;
- + break;
- + case 256:
- + rounds = 14;
- + KC = 8;
- + break;
- + default :
- + return (-1);
- + }
- +
- + for(i=0; i<MAXBC; i++)
- + {
- + for(j=0; j<4; j++)
- + {
- + expandedKey[i*4+j] = W[rounds][j][i];
- + }
- + }
- + for(; i<KC; i++)
- + {
- + for(j=0; j<4; j++)
- + {
- + expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];
- + }
- + }
- +
- +
- + return 0;
- +}
- +
- +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
- + MV_U32 *plain, int numBlocks, MV_U32 *cipher)
- +{
- + int i, j, t;
- + MV_U8 block[4][MAXBC];
- + int rounds;
- + char *input, *outBuffer;
- +
- + input = (char*)plain;
- + outBuffer = (char*)cipher;
- +
- + /* check parameter consistency: */
- + if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256)))
- + {
- + return AES_BAD_KEY_MAT;
- + }
- + if ((mode != MODE_ECB && mode != MODE_CBC))
- + {
- + return AES_BAD_CIPHER_STATE;
- + }
- +
- + switch (keyLen)
- + {
- + case 128: rounds = 10; break;
- + case 192: rounds = 12; break;
- + case 256: rounds = 14; break;
- + default : return (-3); /* this cannot happen */
- + }
- +
- +
- + switch (mode)
- + {
- + case MODE_ECB:
- + for (i = 0; i < numBlocks; i++)
- + {
- + for (j = 0; j < 4; j++)
- + {
- + for(t = 0; t < 4; t++)
- + /* parse input stream into rectangular array */
- + block[t][j] = input[16*i+4*j+t] & 0xFF;
- + }
- + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
- + for (j = 0; j < 4; j++)
- + {
- + /* parse rectangular array into output ciphertext bytes */
- + for(t = 0; t < 4; t++)
- + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
- +
- + }
- + }
- + break;
- +
- + case MODE_CBC:
- + for (j = 0; j < 4; j++)
- + {
- + for(t = 0; t < 4; t++)
- + /* parse initial value into rectangular array */
- + block[t][j] = IV[t+4*j] & 0xFF;
- + }
- + for (i = 0; i < numBlocks; i++)
- + {
- + for (j = 0; j < 4; j++)
- + {
- + for(t = 0; t < 4; t++)
- + /* parse input stream into rectangular array and exor with
- + IV or the previous ciphertext */
- + block[t][j] ^= input[16*i+4*j+t] & 0xFF;
- + }
- + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
- + for (j = 0; j < 4; j++)
- + {
- + /* parse rectangular array into output ciphertext bytes */
- + for(t = 0; t < 4; t++)
- + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
- + }
- + }
- + break;
- +
- + default: return AES_BAD_CIPHER_STATE;
- + }
- +
- + return 0;
- +}
- +
- +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
- + MV_U32 *srcData, int numBlocks, MV_U32 *dstData)
- +{
- + int i, j, t;
- + MV_U8 block[4][MAXBC];
- + MV_U8 iv[4][MAXBC];
- + int rounds;
- + char *input, *outBuffer;
- +
- + input = (char*)srcData;
- + outBuffer = (char*)dstData;
- +
- + if (expandedKey == NULL)
- + {
- + return AES_BAD_KEY_MAT;
- + }
- +
- + /* check parameter consistency: */
- + if (keyLen != 128 && keyLen != 192 && keyLen != 256)
- + {
- + return AES_BAD_KEY_MAT;
- + }
- + if ((mode != MODE_ECB && mode != MODE_CBC))
- + {
- + return AES_BAD_CIPHER_STATE;
- + }
- +
- + switch (keyLen)
- + {
- + case 128: rounds = 10; break;
- + case 192: rounds = 12; break;
- + case 256: rounds = 14; break;
- + default : return (-3); /* this cannot happen */
- + }
- +
- +
- + switch (mode)
- + {
- + case MODE_ECB:
- + for (i = 0; i < numBlocks; i++)
- + {
- + for (j = 0; j < 4; j++)
- + {
- + for(t = 0; t < 4; t++)
- + {
- + /* parse input stream into rectangular array */
- + block[t][j] = input[16*i+4*j+t] & 0xFF;
- + }
- + }
- + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
- + for (j = 0; j < 4; j++)
- + {
- + /* parse rectangular array into output ciphertext bytes */
- + for(t = 0; t < 4; t++)
- + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
- + }
- + }
- + break;
- +
- + case MODE_CBC:
- + /* first block */
- + for (j = 0; j < 4; j++)
- + {
- + for(t = 0; t < 4; t++)
- + {
- + /* parse input stream into rectangular array */
- + block[t][j] = input[4*j+t] & 0xFF;
- + iv[t][j] = block[t][j];
- + }
- + }
- + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
- +
- + for (j = 0; j < 4; j++)
- + {
- + /* exor the IV and parse rectangular array into output ciphertext bytes */
- + for(t = 0; t < 4; t++)
- + {
- + outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
- + IV[t+4*j] = iv[t][j];
- + }
- + }
- +
- + /* next blocks */
- + for (i = 1; i < numBlocks; i++)
- + {
- + for (j = 0; j < 4; j++)
- + {
- + for(t = 0; t < 4; t++)
- + {
- + /* parse input stream into rectangular array */
- + iv[t][j] = input[16*i+4*j+t] & 0xFF;
- + block[t][j] = iv[t][j];
- + }
- + }
- + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
- +
- + for (j = 0; j < 4; j++)
- + {
- + /* exor previous ciphertext block and parse rectangular array
- + into output ciphertext bytes */
- + for(t = 0; t < 4; t++)
- + {
- + outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
- + IV[t+4*j] = iv[t][j];
- + }
- + }
- + }
- + break;
- +
- + default: return AES_BAD_CIPHER_STATE;
- + }
- +
- + return 0;
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAes.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAes.h 2010-11-09 20:28:05.292495461 +0100
- @@ -0,0 +1,62 @@
- +/* mvAes.h v2.0 August '99
- + * Reference ANSI C code
- + */
- +
- +/* AES Cipher header file for ANSI C Submissions
- + Lawrence E. Bassham III
- + Computer Security Division
- + National Institute of Standards and Technology
- +
- + April 15, 1998
- +
- + This sample is to assist implementers developing to the Cryptographic
- +API Profile for AES Candidate Algorithm Submissions. Please consult this
- +document as a cross-reference.
- +
- + ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
- +MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
- +THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT
- +BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE
- +IMPLEMENTATION SPECIFIC INFORMATION.
- +*/
- +
- +/* Includes:
- + Standard include files
- +*/
- +
- +#include "mvOs.h"
- +
- +
- +/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
- +
- +/* Key direction is invalid, e.g., unknown value */
- +#define AES_BAD_KEY_DIR -1
- +
- +/* Key material not of correct length */
- +#define AES_BAD_KEY_MAT -2
- +
- +/* Key passed is not valid */
- +#define AES_BAD_KEY_INSTANCE -3
- +
- +/* Params struct passed to cipherInit invalid */
- +#define AES_BAD_CIPHER_MODE -4
- +
- +/* Cipher in wrong state (e.g., not initialized) */
- +#define AES_BAD_CIPHER_STATE -5
- +
- +#define AES_BAD_CIPHER_INSTANCE -7
- +
- +
- +/* Function protoypes */
- +/* CHANGED: makeKey(): parameter blockLen added
- + this parameter is absolutely necessary if you want to
- + setup the round keys in a variable block length setting
- + cipherInit(): parameter blockLen added (for obvious reasons)
- + */
- +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen);
- +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
- + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
- +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
- + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.c 2010-11-09 20:28:05.302495516 +0100
- @@ -0,0 +1,3126 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "cesa/mvCesa.h"
- +
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#undef CESA_DEBUG
- +
- +
- +/********** Global variables **********/
- +
- +/* If request size is more than MV_CESA_MAX_BUF_SIZE the
- + * request is processed as fragmented request.
- + */
- +
- +MV_CESA_STATS cesaStats;
- +
- +MV_BUF_INFO cesaSramSaBuf;
- +short cesaLastSid = -1;
- +MV_CESA_SA* pCesaSAD = NULL;
- +MV_U16 cesaMaxSA = 0;
- +
- +MV_CESA_REQ* pCesaReqFirst = NULL;
- +MV_CESA_REQ* pCesaReqLast = NULL;
- +MV_CESA_REQ* pCesaReqEmpty = NULL;
- +MV_CESA_REQ* pCesaReqProcess = NULL;
- +int cesaQueueDepth = 0;
- +int cesaReqResources = 0;
- +
- +MV_CESA_SRAM_MAP* cesaSramVirtPtr = NULL;
- +MV_U32 cesaCryptEngBase = 0;
- +void *cesaOsHandle = NULL;
- +#if (MV_CESA_VERSION >= 3)
- +MV_U32 cesaChainLength = 0;
- +int chainReqNum = 0;
- +MV_U32 chainIndex = 0;
- +MV_CESA_REQ* pNextActiveChain = 0;
- +MV_CESA_REQ* pEndCurrChain = 0;
- +MV_BOOL isFirstReq = MV_TRUE;
- +#endif
- +
- +static INLINE MV_U8* mvCesaSramAddrGet(void)
- +{
- +#ifdef MV_CESA_NO_SRAM
- + return (MV_U8*)cesaSramVirtPtr;
- +#else
- + return (MV_U8*)cesaCryptEngBase;
- +#endif /* MV_CESA_NO_SRAM */
- +}
- +
- +static INLINE MV_ULONG mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt)
- +{
- +#ifdef MV_CESA_NO_SRAM
- + return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt);
- +#else
- + return (MV_ULONG)pSramVirt;
- +#endif /* MV_CESA_NO_SRAM */
- +}
- +
- +/* Internal Function prototypes */
- +
- +static INLINE void mvCesaSramDescrBuild(MV_U32 config, int frag,
- + int cryptoOffset, int ivOffset, int cryptoLength,
- + int macOffset, int digestOffset, int macLength, int macTotalLen,
- + MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc);
- +
- +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc);
- +
- +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
- + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
- + int offset, int copySize, MV_BOOL skipFlush);
- +
- +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
- + unsigned char innerIV[], unsigned char outerIV[]);
- +
- +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
- + int macDataSize);
- +
- +static MV_CESA_COMMAND* mvCesaCtrModeInit(void);
- +
- +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd);
- +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd);
- +static void mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd);
- +
- +static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq);
- +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag);
- +
- +static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset);
- +static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd);
- +
- +static INLINE void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
- + int cryptoOffset, int macOffset,
- + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize);
- +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size);
- +
- +
- +/* Go to the next request in the request queue */
- +static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq)
- +{
- + if(pReq == pCesaReqLast)
- + return pCesaReqFirst;
- +
- + return pReq+1;
- +}
- +
- +#if (MV_CESA_VERSION >= 3)
- +/* Go to the previous request in the request queue */
- +static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq)
- +{
- + if(pReq == pCesaReqFirst)
- + return pCesaReqLast;
- +
- + return pReq-1;
- +}
- +
- +#endif
- +
- +
- +static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq)
- +{
- + int frag;
- +
- +#if (MV_CESA_VERSION >= 3)
- + pReq->state = MV_CESA_CHAIN;
- +#else
- + pReq->state = MV_CESA_PROCESS;
- +#endif
- + cesaStats.startCount++;
- +
- + if(pReq->fragMode == MV_CESA_FRAG_NONE)
- + {
- + frag = 0;
- + }
- + else
- + {
- + frag = pReq->frags.nextFrag;
- + pReq->frags.nextFrag++;
- + }
- +#if (MV_CESA_VERSION >= 2)
- + /* Enable TDMA engine */
- + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
- + MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG,
- + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
- +#else
- + /* Enable IDMA engine */
- + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
- + MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0),
- + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
- +#endif /* MV_CESA_VERSION >= 2 */
- +
- +#if defined(MV_BRIDGE_SYNC_REORDER)
- + mvOsBridgeReorderWA();
- +#endif
- +
- + /* Start Accelerator */
- + MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK);
- +}
- +
- +
- +/*******************************************************************************
- +* mvCesaHalInit - Initialize the CESA driver
- +*
- +* DESCRIPTION:
- +* This function initialize the CESA driver.
- +* 1) Session database
- +* 2) Request queue
- +* 4) DMA descriptor lists - one list per request. Each list
- +* has MV_CESA_MAX_DMA_DESC descriptors.
- +*
- +* INPUT:
- +* numOfSession - maximum number of supported sessions
- +* queueDepth - number of elements in the request queue.
- +* pSramBase - virtual address of Sram
- +* osHandle - A handle used by the OS to allocate memory for the
- +* module (Passed to the OS Services layer)
- +*
- +* RETURN:
- +* MV_OK - Success
- +* MV_NO_RESOURCE - Fail, can't allocate resources:
- +* Session database, request queue,
- +* DMA descriptors list, LRU cache database.
- +* MV_NOT_ALIGNED - Sram base address is not 8 byte aligned.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase,
- + void *osHandle)
- +{
- + int i, req;
- + MV_U32 descOffsetReg, configReg;
- + MV_CESA_SRAM_SA *pSramSA;
- +
- +
- + mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",
- + numOfSession, queueDepth, pSramBase);
- +
- + cesaOsHandle = osHandle;
- + /* Create Session database */
- + pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession);
- + if(pCesaSAD == NULL)
- + {
- + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",
- + sizeof(MV_CESA_SA)*numOfSession, numOfSession);
- + mvCesaFinish();
- + return MV_NO_RESOURCE;
- + }
- + memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession);
- + cesaMaxSA = numOfSession;
- +
- + /* Allocate imag of sramSA in the DRAM */
- + cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession +
- + CPU_D_CACHE_LINE_SIZE;
- +
- + cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize,
- + &cesaSramSaBuf.bufPhysAddr,
- + &cesaSramSaBuf.memHandle);
- +
- + if(cesaSramSaBuf.bufVirtPtr == NULL)
- + {
- + mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n",
- + cesaSramSaBuf.bufSize);
- + mvCesaFinish();
- + return MV_NO_RESOURCE;
- + }
- + memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize);
- + pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr,
- + CPU_D_CACHE_LINE_SIZE);
- + for(i=0; i<numOfSession; i++)
- + {
- + pCesaSAD[i].pSramSA = &pSramSA[i];
- + }
- +
- + /* Create request queue */
- + pCesaReqFirst = mvOsMalloc(sizeof(MV_CESA_REQ)*queueDepth);
- + if(pCesaReqFirst == NULL)
- + {
- + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",
- + sizeof(MV_CESA_REQ)*queueDepth, queueDepth);
- + mvCesaFinish();
- + return MV_NO_RESOURCE;
- + }
- + memset(pCesaReqFirst, 0, sizeof(MV_CESA_REQ)*queueDepth);
- + pCesaReqEmpty = pCesaReqFirst;
- + pCesaReqLast = pCesaReqFirst + (queueDepth-1);
- + pCesaReqProcess = pCesaReqEmpty;
- + cesaQueueDepth = queueDepth;
- + cesaReqResources = queueDepth;
- +#if (MV_CESA_VERSION >= 3)
- + cesaChainLength = MAX_CESA_CHAIN_LENGTH;
- +#endif
- + /* pSramBase must be 8 byte aligned */
- + if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) )
- + {
- + mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",
- + pSramBase);
- + mvCesaFinish();
- + return MV_NOT_ALIGNED;
- + }
- + cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase;
- +
- + cesaCryptEngBase = cryptEngBase;
- +
- + /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/
- +
- + /* Clear registers */
- + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
- + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
- + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
- +
- + /* Initialize DMA descriptor lists for all requests in Request queue */
- + descOffsetReg = configReg = 0;
- + for(req=0; req<queueDepth; req++)
- + {
- + int frag;
- + MV_CESA_REQ* pReq;
- + MV_DMA_DESC* pDmaDesc;
- +
- + pReq = &pCesaReqFirst[req];
- +
- + pReq->cesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS +
- + CPU_D_CACHE_LINE_SIZE;
- +
- + pReq->cesaDescBuf.bufVirtPtr =
- + mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize,
- + &pReq->cesaDescBuf.bufPhysAddr,
- + &pReq->cesaDescBuf.memHandle);
- +
- + if(pReq->cesaDescBuf.bufVirtPtr == NULL)
- + {
- + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n",
- + req, pReq->cesaDescBuf.bufSize);
- + mvCesaFinish();
- + return MV_NO_RESOURCE;
- + }
- + memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize);
- + pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr,
- + CPU_D_CACHE_LINE_SIZE);
- +
- + pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS +
- + CPU_D_CACHE_LINE_SIZE;
- +
- + pReq->dmaDescBuf.bufVirtPtr =
- + mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize,
- + &pReq->dmaDescBuf.bufPhysAddr,
- + &pReq->dmaDescBuf.memHandle);
- +
- + if(pReq->dmaDescBuf.bufVirtPtr == NULL)
- + {
- + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n",
- + req, pReq->dmaDescBuf.bufSize);
- + mvCesaFinish();
- + return MV_NO_RESOURCE;
- + }
- + memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize);
- + pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr,
- + CPU_D_CACHE_LINE_SIZE);
- +
- + for(frag=0; frag<MV_CESA_MAX_REQ_FRAGS; frag++)
- + {
- + MV_CESA_DMA* pDma = &pReq->dma[frag];
- +
- + pDma->pDmaFirst = pDmaDesc;
- + pDma->pDmaLast = NULL;
- +
- + for(i=0; i<MV_CESA_MAX_DMA_DESC-1; i++)
- + {
- + /* link all DMA descriptors together */
- + pDma->pDmaFirst[i].phyNextDescPtr =
- + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1]));
- + }
- + pDma->pDmaFirst[i].phyNextDescPtr = 0;
- + mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC));
- +
- + pDmaDesc += MV_CESA_MAX_DMA_DESC;
- + }
- + }
- + /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/
- + descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet());
- + MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg);
- +
- + configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK);
- +#if (MV_CESA_VERSION >= 3)
- + configReg |= MV_CESA_CFG_CHAIN_MODE_MASK;
- +#endif
- +
- +#if (MV_CESA_VERSION >= 2)
- + /* Initialize TDMA engine */
- + MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE);
- + MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0);
- + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
- +#else
- + /* Initialize IDMA #0 engine */
- + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
- + MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);
- + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
- + MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE
- +#ifdef MV_CPU_LE
- + | ICCHR_DESC_BYTE_SWAP_EN
- +#endif
- + );
- + /* Clear Cause Byte of IDMA channel to be used */
- + MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0));
- + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE);
- +#endif /* (MV_CESA_VERSION >= 2) */
- +
- + /* Set CESA configuration registers */
- + MV_REG_WRITE( MV_CESA_CFG_REG, configReg);
- + mvCesaDebugStatsClear();
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaFinish - Shutdown the CESA driver
- +*
- +* DESCRIPTION:
- +* This function shutdown the CESA driver and free all allocted resources.
- +*
- +* INPUT: None
- +*
- +* RETURN:
- +* MV_OK - Success
- +* Other - Fail
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaFinish (void)
- +{
- + int req;
- + MV_CESA_REQ* pReq;
- +
- + mvOsPrintf("mvCesaFinish: \n");
- +
- + cesaSramVirtPtr = NULL;
- +
- + /* Free all resources: DMA list, etc. */
- + for(req=0; req<cesaQueueDepth; req++)
- + {
- + pReq = &pCesaReqFirst[req];
- + if(pReq->dmaDescBuf.bufVirtPtr != NULL)
- + {
- + mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize,
- + pReq->dmaDescBuf.bufPhysAddr,
- + pReq->dmaDescBuf.bufVirtPtr,
- + pReq->dmaDescBuf.memHandle);
- + }
- + if(pReq->cesaDescBuf.bufVirtPtr != NULL)
- + {
- + mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize,
- + pReq->cesaDescBuf.bufPhysAddr,
- + pReq->cesaDescBuf.bufVirtPtr,
- + pReq->cesaDescBuf.memHandle);
- + }
- + }
- +#if (MV_CESA_VERSION < 2)
- + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
- +#endif /* (MV_CESA_VERSION < 2) */
- +
- + /* Free request queue */
- + if(pCesaReqFirst != NULL)
- + {
- + mvOsFree(pCesaReqFirst);
- + pCesaReqFirst = pCesaReqLast = NULL;
- + pCesaReqEmpty = pCesaReqProcess = NULL;
- + cesaQueueDepth = cesaReqResources = 0;
- + }
- + /* Free SA database */
- + if(pCesaSAD != NULL)
- + {
- + mvOsFree(pCesaSAD);
- + pCesaSAD = NULL;
- + cesaMaxSA = 0;
- + }
- + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
- + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
- + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode
- +*
- +* DESCRIPTION:
- +* This function set IV value using by Crypto algorithms in CBC mode.
- +* Each channel has its own IV value.
- +* This function gets IV value from the caller. If no IV value passed from
- +* the caller or only part of IV passed, the function will init the rest part
- +* of IV value (or the whole IV) by random value.
- +*
- +* INPUT:
- +* MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL
- +* the function will generate random IV value.
- +* int ivSize - size (in bytes) of IV provided by user. If ivSize is
- +* smaller than maximum IV size, the function will complete
- +* IV by random value.
- +*
- +* RETURN:
- +* MV_OK - Success
- +* Other - Fail
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize)
- +{
- + MV_U8* pSramIV;
- +#if defined(MV646xx)
- + mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");
- +#endif
- + pSramIV = cesaSramVirtPtr->cryptoIV;
- + if(ivSize > MV_CESA_MAX_IV_LENGTH)
- + {
- + mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize);
- + ivSize = MV_CESA_MAX_IV_LENGTH;
- + }
- + if(pIV != NULL)
- + {
- + memcpy(pSramIV, pIV, ivSize);
- + ivSize = MV_CESA_MAX_IV_LENGTH - ivSize;
- + pSramIV += ivSize;
- + }
- +
- + while(ivSize > 0)
- + {
- + int size, mv_random = mvOsRand();
- +
- + size = MV_MIN(ivSize, sizeof(mv_random));
- + memcpy(pSramIV, (void*)&mv_random, size);
- +
- + pSramIV += size;
- + ivSize -= size;
- + }
- +/*
- + mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,
- + MV_CESA_MAX_IV_LENGTH);
- + mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,
- + MV_CESA_MAX_IV_LENGTH);
- +*/
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaSessionOpen - Open new uni-directional crypto session
- +*
- +* DESCRIPTION:
- +* This function open new session.
- +*
- +* INPUT:
- +* MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters
- +*
- +* OUTPUT:
- +* short *pSid - session ID, should be used for all future
- +* requests over this session.
- +*
- +* RETURN:
- +* MV_OK - Session opend successfully.
- +* MV_FULL - All sessions are in use, no free place in
- +* SA database.
- +* MV_BAD_PARAM - One of session input parameters is invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid)
- +{
- + short sid;
- + MV_U32 config = 0;
- + int digestSize;
- +
- + cesaStats.openedCount++;
- +
- + /* Find free entry in SAD */
- + for(sid=0; sid<cesaMaxSA; sid++)
- + {
- + if(pCesaSAD[sid].valid == 0)
- + {
- + break;
- + }
- + }
- + if(sid == cesaMaxSA)
- + {
- + mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");
- + return MV_FULL;
- + }
- +
- + /* Check Input parameters for Open session */
- + if (pSession->operation >= MV_CESA_MAX_OPERATION)
- + {
- + mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",
- + pSession->operation);
- + return MV_BAD_PARAM;
- + }
- + config |= (pSession->operation << MV_CESA_OPERATION_OFFSET);
- +
- + if( (pSession->direction != MV_CESA_DIR_ENCODE) &&
- + (pSession->direction != MV_CESA_DIR_DECODE) )
- + {
- + mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",
- + pSession->direction);
- + return MV_BAD_PARAM;
- + }
- + config |= (pSession->direction << MV_CESA_DIRECTION_BIT);
- + /* Clear SA entry */
- + /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */
- +
- + /* Check AUTH parameters and update SA entry */
- + if(pSession->operation != MV_CESA_CRYPTO_ONLY)
- + {
- + /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */
- + if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) ||
- + (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) )
- + {
- + if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH)
- + {
- + mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",
- + pSession->macKeyLength);
- + return MV_BAD_PARAM;
- + }
- + mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength,
- + pCesaSAD[sid].pSramSA->macInnerIV,
- + pCesaSAD[sid].pSramSA->macOuterIV);
- + pCesaSAD[sid].macKeyLength = pSession->macKeyLength;
- + }
- + switch(pSession->macMode)
- + {
- + case MV_CESA_MAC_MD5:
- + case MV_CESA_MAC_HMAC_MD5:
- + digestSize = MV_CESA_MD5_DIGEST_SIZE;
- + break;
- +
- + case MV_CESA_MAC_SHA1:
- + case MV_CESA_MAC_HMAC_SHA1:
- + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
- + break;
- +
- + default:
- + mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",
- + pSession->macMode);
- + return MV_BAD_PARAM;
- + }
- + config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET);
- +
- + /* Supported digest sizes: MD5 - 16 bytes (128 bits), */
- + /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */
- + if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12))
- + {
- + mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",
- + pSession->digestSize);
- + mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");
- + return MV_BAD_PARAM;
- + }
- + pCesaSAD[sid].digestSize = pSession->digestSize;
- +
- + if(pCesaSAD[sid].digestSize == 12)
- + {
- + /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */
- + config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT);
- + }
- + }
- +
- + /* Check CRYPTO parameters and update SA entry */
- + if(pSession->operation != MV_CESA_MAC_ONLY)
- + {
- + switch(pSession->cryptoAlgorithm)
- + {
- + case MV_CESA_CRYPTO_DES:
- + pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH;
- + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
- + break;
- +
- + case MV_CESA_CRYPTO_3DES:
- + pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH;
- + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
- + /* Only EDE mode is supported */
- + config |= (MV_CESA_CRYPTO_3DES_EDE <<
- + MV_CESA_CRYPTO_3DES_MODE_BIT);
- + break;
- +
- + case MV_CESA_CRYPTO_AES:
- + switch(pSession->cryptoKeyLength)
- + {
- + case 16:
- + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH;
- + config |= (MV_CESA_CRYPTO_AES_KEY_128 <<
- + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
- + break;
- +
- + case 24:
- + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH;
- + config |= (MV_CESA_CRYPTO_AES_KEY_192 <<
- + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
- + break;
- +
- + case 32:
- + default:
- + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH;
- + config |= (MV_CESA_CRYPTO_AES_KEY_256 <<
- + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
- + break;
- + }
- + pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE;
- + break;
- +
- + default:
- + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",
- + pSession->cryptoAlgorithm);
- + return MV_BAD_PARAM;
- + }
- + config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET);
- +
- + if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength)
- + {
- + mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",
- + pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Copy Crypto key */
- + if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) &&
- + (pSession->direction == MV_CESA_DIR_DECODE))
- + {
- + /* Crypto Key for AES decode is computed from original key material */
- + /* and depend on cryptoKeyLength (128/192/256 bits) */
- + aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
- + pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8);
- + }
- + else
- + {
- + /*panic("mvCesaSessionOpen2");*/
- + memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
- + pCesaSAD[sid].cryptoKeyLength);
- +
- + }
- +
- + switch(pSession->cryptoMode)
- + {
- + case MV_CESA_CRYPTO_ECB:
- + pCesaSAD[sid].cryptoIvSize = 0;
- + break;
- +
- + case MV_CESA_CRYPTO_CBC:
- + pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize;
- + break;
- +
- + case MV_CESA_CRYPTO_CTR:
- + /* Supported only for AES algorithm */
- + if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES)
- + {
- + mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");
- + return MV_BAD_PARAM;
- + }
- + pCesaSAD[sid].cryptoIvSize = 0;
- + pCesaSAD[sid].ctrMode = 1;
- + /* Replace to ECB mode for HW */
- + pSession->cryptoMode = MV_CESA_CRYPTO_ECB;
- + break;
- +
- + default:
- + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",
- + pSession->cryptoMode);
- + return MV_BAD_PARAM;
- + }
- +
- + config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT);
- + }
- + pCesaSAD[sid].config = config;
- +
- + mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA));
- + if(pSid != NULL)
- + *pSid = sid;
- +
- + pCesaSAD[sid].valid = 1;
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaSessionClose - Close active crypto session
- +*
- +* DESCRIPTION:
- +* This function closes existing session
- +*
- +* INPUT:
- +* short sid - Unique identifier of the session to be closed
- +*
- +* RETURN:
- +* MV_OK - Session closed successfully.
- +* MV_BAD_PARAM - Session identifier is out of valid range.
- +* MV_NOT_FOUND - There is no active session with such ID.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaSessionClose(short sid)
- +{
- + cesaStats.closedCount++;
- +
- + if(sid >= cesaMaxSA)
- + {
- + mvOsPrintf("CESA Error: sid (%d) is too big\n", sid);
- + return MV_BAD_PARAM;
- + }
- + if(pCesaSAD[sid].valid == 0)
- + {
- + mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid);
- + return MV_NOT_FOUND;
- + }
- + if(cesaLastSid == sid)
- + cesaLastSid = -1;
- +
- + pCesaSAD[sid].valid = 0;
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaAction - Perform crypto operation
- +*
- +* DESCRIPTION:
- +* This function set new CESA request FIFO queue for further HW processing.
- +* The function checks request parameters before set new request to the queue.
- +* If one of the CESA channels is ready for processing the request will be
- +* passed to HW. When request processing is finished the CESA interrupt will
- +* be generated by HW. The caller should call mvCesaReadyGet() function to
- +* complete request processing and get result.
- +*
- +* INPUT:
- +* MV_CESA_COMMAND *pCmd - pointer to new CESA request.
- +* It includes pointers to Source and Destination
- +* buffers, session identifier get from
- +* mvCesaSessionOpen() function, pointer to caller
- +* private data and all needed crypto parameters.
- +*
- +* RETURN:
- +* MV_OK - request successfully added to request queue
- +* and will be processed.
- +* MV_NO_MORE - request successfully added to request queue and will
- +* be processed, but request queue became Full and next
- +* request will not be accepted.
- +* MV_NO_RESOURCE - request queue is FULL and the request can not
- +* be processed.
- +* MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is
- +* failed. Request can not be processed.
- +* MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed
- +* as one request and should be splitted for two requests:
- +* CRYPTO_ONLY and MAC_ONLY.
- +* MV_BAD_PARAM - One of the request parameters is out of valid range.
- +* The request can not be processed.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaAction (MV_CESA_COMMAND *pCmd)
- +{
- + MV_STATUS status;
- + MV_CESA_REQ* pReq = pCesaReqEmpty;
- + int sid = pCmd->sessionId;
- + MV_CESA_SA* pSA = &pCesaSAD[sid];
- +#if (MV_CESA_VERSION >= 3)
- + MV_CESA_REQ* pFromReq;
- + MV_CESA_REQ* pToReq;
- +#endif
- + cesaStats.reqCount++;
- +
- + /* Check that the request queue is not FULL */
- + if(cesaReqResources == 0)
- + return MV_NO_RESOURCE;
- +
- + if( (sid >= cesaMaxSA) || (!pSA->valid) )
- + {
- + mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid);
- + return MV_BAD_PARAM;
- + }
- + pSA->count++;
- +
- + if(pSA->ctrMode)
- + {
- + /* AES in CTR mode can't be mixed with Authentication */
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");
- + return MV_NOT_ALLOWED;
- + }
- + /* All other request parameters should not be checked because key stream */
- + /* (not user data) processed by AES HW engine */
- + pReq->pOrgCmd = pCmd;
- + /* Allocate temporary pCmd structure for Key stream */
- + pCmd = mvCesaCtrModeInit();
- + if(pCmd == NULL)
- + return MV_OUT_OF_CPU_MEM;
- +
- + /* Prepare Key stream */
- + mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd);
- + pReq->fixOffset = 0;
- + }
- + else
- + {
- + /* Check request parameters and calculae fixOffset */
- + status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset);
- + if(status != MV_OK)
- + {
- + return status;
- + }
- + }
- + pReq->pCmd = pCmd;
- +
- + /* Check if the packet need fragmentation */
- + if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) )
- + {
- + /* request size is smaller than single buffer size */
- + pReq->fragMode = MV_CESA_FRAG_NONE;
- +
- + /* Prepare NOT fragmented packets */
- + status = mvCesaReqProcess(pReq);
- + if(status != MV_OK)
- + {
- + mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",
- + pReq, status);
- + }
- +#if (MV_CESA_VERSION >= 3)
- + pReq->frags.numFrag = 1;
- +#endif
- + }
- + else
- + {
- + MV_U8 frag = 0;
- +
- + /* request size is larger than buffer size - needs fragmentation */
- +
- + /* Check restrictions for processing fragmented packets */
- + status = mvCesaFragParamCheck(pSA, pCmd);
- + if(status != MV_OK)
- + return status;
- +
- + pReq->fragMode = MV_CESA_FRAG_FIRST;
- + pReq->frags.nextFrag = 0;
- +
- + /* Prepare Process Fragmented packets */
- + while(pReq->fragMode != MV_CESA_FRAG_LAST)
- + {
- + if(frag >= MV_CESA_MAX_REQ_FRAGS)
- + {
- + mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag);
- + return MV_OUT_OF_CPU_MEM;
- + }
- + status = mvCesaFragReqProcess(pReq, frag);
- + if(status == MV_OK) {
- +#if (MV_CESA_VERSION >= 3)
- + if(frag) {
- + pReq->dma[frag-1].pDmaLast->phyNextDescPtr =
- + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
- + mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC));
- + }
- +#endif
- + frag++;
- + }
- + }
- + pReq->frags.numFrag = frag;
- +#if (MV_CESA_VERSION >= 3)
- + if(chainReqNum) {
- + chainReqNum += pReq->frags.numFrag;
- + if(chainReqNum >= MAX_CESA_CHAIN_LENGTH)
- + chainReqNum = MAX_CESA_CHAIN_LENGTH;
- + }
- +#endif
- + }
- +
- + pReq->state = MV_CESA_PENDING;
- +
- + pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq);
- + cesaReqResources -= 1;
- +
- +/* #ifdef CESA_DEBUG */
- + if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount)
- + cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources);
- +/* #endif CESA_DEBUG */
- +
- + cesaLastSid = sid;
- +
- +#if (MV_CESA_VERSION >= 3)
- + /* Are we within chain bounderies and follows the first request ? */
- + if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) {
- + if(chainIndex) {
- + pFromReq = MV_CESA_REQ_PREV_PTR(pReq);
- + pToReq = pReq;
- + pReq->state = MV_CESA_CHAIN;
- + /* assume concatenating is possible */
- + pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr =
- + MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst));
- + mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC));
- +
- + /* align active & next pointers */
- + if(pNextActiveChain->state != MV_CESA_PENDING)
- + pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq);
- + }
- + else { /* we have only one chain, start new one */
- + chainReqNum = 0;
- + chainIndex++;
- + /* align active & next pointers */
- + if(pNextActiveChain->state != MV_CESA_PENDING)
- + pEndCurrChain = pNextActiveChain = pReq;
- + }
- + }
- + else {
- + /* In case we concatenate full chain */
- + if(chainReqNum == MAX_CESA_CHAIN_LENGTH) {
- + chainIndex++;
- + if(pNextActiveChain->state != MV_CESA_PENDING)
- + pEndCurrChain = pNextActiveChain = pReq;
- + chainReqNum = 0;
- + }
- +
- + pReq = pCesaReqProcess;
- + if(pReq->state == MV_CESA_PENDING) {
- + pNextActiveChain = pReq;
- + pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq);
- + /* Start Process new request */
- + mvCesaReqProcessStart(pReq);
- + }
- + }
- +
- + chainReqNum++;
- +
- + if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage))
- + cesaStats.maxChainUsage = chainReqNum;
- +
- +#else
- +
- + /* Check status of CESA channels and process requests if possible */
- + pReq = pCesaReqProcess;
- + if(pReq->state == MV_CESA_PENDING)
- + {
- + /* Start Process new request */
- + mvCesaReqProcessStart(pReq);
- + }
- +#endif
- + /* If request queue became FULL - return MV_NO_MORE */
- + if(cesaReqResources == 0)
- + return MV_NO_MORE;
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvCesaReadyGet - Get crypto request that processing is finished
- +*
- +* DESCRIPTION:
- +* This function complete request processing and return ready request to
- +* caller. To don't miss interrupts the caller must call this function
- +* while MV_OK or MV_TERMINATE values returned.
- +*
- +* INPUT:
- +* MV_U32 chanMap - map of CESA channels finished thier job
- +* accordingly with CESA Cause register.
- +* MV_CESA_RESULT* pResult - pointer to structure contains information
- +* about ready request. It includes pointer to
- +* user private structure "pReqPrv", session identifier
- +* for this request "sessionId" and return code.
- +* Return code set to MV_FAIL if calculated digest value
- +* on decode direction is different than digest value
- +* in the packet.
- +*
- +* RETURN:
- +* MV_OK - Success, ready request is returned.
- +* MV_NOT_READY - Next request is not ready yet. New interrupt will
- +* be generated for futher request processing.
- +* MV_EMPTY - There is no more request for processing.
- +* MV_BUSY - Fragmented request is not ready yet.
- +* MV_TERMINATE - Call this function once more to complete processing
- +* of fragmented request.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult)
- +{
- + MV_STATUS status, readyStatus = MV_NOT_READY;
- + MV_U32 statusReg;
- + MV_CESA_REQ* pReq;
- + MV_CESA_SA* pSA;
- +
- +#if (MV_CESA_VERSION >= 3)
- + if(isFirstReq == MV_TRUE) {
- + if(chainIndex == 0)
- + chainReqNum = 0;
- +
- + isFirstReq = MV_FALSE;
- +
- + if(pNextActiveChain->state == MV_CESA_PENDING) {
- + /* Start request Process */
- + mvCesaReqProcessStart(pNextActiveChain);
- + pEndCurrChain = pNextActiveChain;
- + if(chainIndex > 0)
- + chainIndex--;
- + /* Update pNextActiveChain to next chain head */
- + while(pNextActiveChain->state == MV_CESA_CHAIN)
- + pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain);
- + }
- + }
- +
- + /* Check if there are more processed requests - can we remove pEndCurrChain ??? */
- + if(pCesaReqProcess == pEndCurrChain) {
- + isFirstReq = MV_TRUE;
- + pEndCurrChain = pNextActiveChain;
- +#else
- + if(pCesaReqProcess->state != MV_CESA_PROCESS) {
- +#endif
- + return MV_EMPTY;
- + }
- +
- +#ifdef CESA_DEBUG
- + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
- + if( statusReg & MV_CESA_STATUS_ACTIVE_MASK )
- + {
- + mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg);
- + cesaStats.notReadyCount++;
- + return MV_NOT_READY;
- + }
- +#endif /* CESA_DEBUG */
- +
- + cesaStats.readyCount++;
- +
- + pReq = pCesaReqProcess;
- + pSA = &pCesaSAD[pReq->pCmd->sessionId];
- +
- + pResult->retCode = MV_OK;
- + if(pReq->fragMode != MV_CESA_FRAG_NONE)
- + {
- + MV_U8* pNewDigest;
- + int frag;
- +#if (MV_CESA_VERSION >= 3)
- + pReq->frags.nextFrag = 1;
- + while(pReq->frags.nextFrag <= pReq->frags.numFrag) {
- +#endif
- + frag = (pReq->frags.nextFrag - 1);
- +
- + /* Restore DMA descriptor list */
- + pReq->dma[frag].pDmaLast->phyNextDescPtr =
- + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1]));
- + pReq->dma[frag].pDmaLast = NULL;
- +
- + /* Special processing for finished fragmented request */
- + if(pReq->frags.nextFrag >= pReq->frags.numFrag)
- + {
- + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
- +
- + /* Fragmented packet is ready */
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + int macDataSize = pReq->pCmd->macLength - pReq->frags.macSize;
- +
- + if(macDataSize != 0)
- + {
- + /* Calculate all other blocks by SW */
- + mvCesaFragAuthComplete(pReq, pSA, macDataSize);
- + }
- +
- + /* Copy new digest from SRAM to the Destination buffer */
- + pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset;
- + status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst,
- + pReq->pCmd->digestOffset, pSA->digestSize);
- +
- + /* For decryption: Compare new digest value with original one */
- + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
- + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
- + {
- + if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0)
- + {
- +/*
- + mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",
- + chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));
- +*/
- + /* Signiture verification is failed */
- + pResult->retCode = MV_FAIL;
- + }
- + }
- + }
- + readyStatus = MV_OK;
- + }
- +#if (MV_CESA_VERSION >= 3)
- + pReq->frags.nextFrag++;
- + }
- +#endif
- + }
- + else
- + {
- + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
- +
- + /* Restore DMA descriptor list */
- + pReq->dma[0].pDmaLast->phyNextDescPtr =
- + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1]));
- + pReq->dma[0].pDmaLast = NULL;
- + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) &&
- + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
- + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) )
- + {
- + /* For AUTH on decode : Check Digest result in Status register */
- + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
- + if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK)
- + {
- +/*
- + mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",
- + chan, statusReg);
- +*/
- + /* Signiture verification is failed */
- + pResult->retCode = MV_FAIL;
- + }
- + }
- + readyStatus = MV_OK;
- + }
- +
- + if(readyStatus == MV_OK)
- + {
- + /* If Request is ready - Prepare pResult structure */
- + pResult->pReqPrv = pReq->pCmd->pReqPrv;
- + pResult->sessionId = pReq->pCmd->sessionId;
- +
- + pReq->state = MV_CESA_IDLE;
- + pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq);
- + cesaReqResources++;
- +
- + if(pSA->ctrMode)
- + {
- + /* For AES CTR mode - complete processing and free allocated resources */
- + mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd);
- + mvCesaCtrModeFinish(pReq->pCmd);
- + pReq->pOrgCmd = NULL;
- + }
- + }
- +
- +#if (MV_CESA_VERSION < 3)
- + if(pCesaReqProcess->state == MV_CESA_PROCESS)
- + {
- + /* Start request Process */
- + mvCesaReqProcessStart(pCesaReqProcess);
- + if(readyStatus == MV_NOT_READY)
- + readyStatus = MV_BUSY;
- + }
- + else if(pCesaReqProcess != pCesaReqEmpty)
- + {
- + /* Start process new request from the queue */
- + mvCesaReqProcessStart(pCesaReqProcess);
- + }
- +#endif
- + return readyStatus;
- +}
- +
- +/***************** Functions to work with CESA_MBUF structure ******************/
- +
- +/*******************************************************************************
- +* mvCesaMbufOffset - Locate offset in the Mbuf structure
- +*
- +* DESCRIPTION:
- +* This function locates offset inside Multi-Bufeer structure.
- +* It get fragment number and place in the fragment where the offset
- +* is located.
- +*
- +*
- +* INPUT:
- +* MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure
- +* int offset - Offset from the beginning of the data presented by
- +* the Mbuf structure.
- +*
- +* OUTPUT:
- +* int* pBufOffset - Offset from the beginning of the fragment where
- +* the offset is located.
- +*
- +* RETURN:
- +* int - Number of fragment, where the offset is located\
- +*
- +*******************************************************************************/
- +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset)
- +{
- + int frag = 0;
- +
- + while(offset > 0)
- + {
- + if(frag >= pMbuf->numFrags)
- + {
- + mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",
- + frag, pMbuf->numFrags);
- + return MV_INVALID;
- + }
- + if(offset < pMbuf->pFrags[frag].bufSize)
- + {
- + break;
- + }
- + offset -= pMbuf->pFrags[frag].bufSize;
- + frag++;
- + }
- + if(pBufOffset != NULL)
- + *pBufOffset = offset;
- +
- + return frag;
- +}
- +
- +/*******************************************************************************
- +* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_U8* pDstBuf - Pointer to continuous buffer, where data is
- +* copied to.
- +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
- +* copied from.
- +* int offset - Offset in the Mbuf structure where located first
- +* byte of data should be copied.
- +* int size - Size of data should be copied
- +*
- +* RETURN:
- +* MV_OK - Success, all data is copied successfully.
- +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
- +* No data is copied.
- +* MV_EMPTY - Multi-buffer structure has not enough data to copy
- +* Data from the offset to end of Mbuf data is copied.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf,
- + int offset, int size)
- +{
- + int frag, fragOffset, bufSize;
- + MV_U8* pBuf;
- +
- + if(size == 0)
- + return MV_OK;
- +
- + frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset);
- + if(frag == MV_INVALID)
- + {
- + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
- + return MV_OUT_OF_RANGE;
- + }
- +
- + bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset;
- + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset;
- + while(MV_TRUE)
- + {
- + if(size <= bufSize)
- + {
- + memcpy(pDstBuf, pBuf, size);
- + return MV_OK;
- + }
- + memcpy(pDstBuf, pBuf, bufSize);
- + size -= bufSize;
- + frag++;
- + pDstBuf += bufSize;
- + if(frag >= pSrcMbuf->numFrags)
- + break;
- +
- + bufSize = pSrcMbuf->pFrags[frag].bufSize;
- + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr;
- + }
- + mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",
- + size);
- + return MV_EMPTY;
- +}
- +
- +/*******************************************************************************
- +* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_U8* pSrcBuf - Pointer to continuous buffer, where data is
- +* copied from.
- +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
- +* copied to.
- +* int offset - Offset in the Mbuf structure where located first
- +* byte of data should be copied.
- +* int size - Size of data should be copied
- +*
- +* RETURN:
- +* MV_OK - Success, all data is copied successfully.
- +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
- +* No data is copied.
- +* MV_FULL - Multi-buffer structure has not enough place to copy
- +* all data. Data from the offset to end of Mbuf data
- +* is copied.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf,
- + int offset, int size)
- +{
- + int frag, fragOffset, bufSize;
- + MV_U8* pBuf;
- +
- + if(size == 0)
- + return MV_OK;
- +
- + frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset);
- + if(frag == MV_INVALID)
- + {
- + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
- + return MV_OUT_OF_RANGE;
- + }
- +
- + bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset;
- + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset;
- + while(MV_TRUE)
- + {
- + if(size <= bufSize)
- + {
- + memcpy(pBuf, pSrcBuf, size);
- + return MV_OK;
- + }
- + memcpy(pBuf, pSrcBuf, bufSize);
- + size -= bufSize;
- + frag++;
- + pSrcBuf += bufSize;
- + if(frag >= pDstMbuf->numFrags)
- + break;
- +
- + bufSize = pDstMbuf->pFrags[frag].bufSize;
- + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr;
- + }
- + mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",
- + size);
- + return MV_FULL;
- +}
- +
- +/*******************************************************************************
- +* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +*
- +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
- +* copied to.
- +* int dstMbufOffset - Offset in the dstMbuf structure where first byte
- +* of data should be copied to.
- +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
- +* copied from.
- +* int srcMbufOffset - Offset in the srcMbuf structure where first byte
- +* of data should be copied from.
- +* int size - Size of data should be copied
- +*
- +* RETURN:
- +* MV_OK - Success, all data is copied successfully.
- +* MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of
- +* srcMbuf or dstMbuf structure correspondently.
- +* No data is copied.
- +* MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy
- +* all data. Partial data is copied
- +*
- +*******************************************************************************/
- +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
- + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size)
- +{
- + int srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset;
- + int copySize;
- + MV_U8 *pSrc, *pDst;
- +
- + if(size == 0)
- + return MV_OK;
- +
- + srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset);
- + if(srcFrag == MV_INVALID)
- + {
- + mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset);
- + return MV_OUT_OF_RANGE;
- + }
- + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset;
- + srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset;
- +
- + dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset);
- + if(dstFrag == MV_INVALID)
- + {
- + mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset);
- + return MV_OUT_OF_RANGE;
- + }
- + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset;
- + dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset;
- +
- + while(size > 0)
- + {
- + copySize = MV_MIN(srcSize, dstSize);
- + if(size <= copySize)
- + {
- + memcpy(pDst, pSrc, size);
- + return MV_OK;
- + }
- + memcpy(pDst, pSrc, copySize);
- + size -= copySize;
- + srcSize -= copySize;
- + dstSize -= copySize;
- +
- + if(srcSize == 0)
- + {
- + srcFrag++;
- + if(srcFrag >= pMbufSrc->numFrags)
- + break;
- +
- + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr;
- + srcSize = pMbufSrc->pFrags[srcFrag].bufSize;
- + }
- +
- + if(dstSize == 0)
- + {
- + dstFrag++;
- + if(dstFrag >= pMbufDst->numFrags)
- + break;
- +
- + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr;
- + dstSize = pMbufDst->pFrags[dstFrag].bufSize;
- + }
- + }
- + mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",
- + size);
- +
- + return MV_BAD_SIZE;
- +}
- +
- +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size)
- +{
- + int frag, fragOffset, bufSize;
- + MV_U8* pBuf;
- +
- + if(size == 0)
- + return MV_OK;
- +
- + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
- + if(frag == MV_INVALID)
- + {
- + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
- + return MV_OUT_OF_RANGE;
- + }
- +
- + bufSize = pMbuf->pFrags[frag].bufSize - fragOffset;
- + pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
- + while(MV_TRUE)
- + {
- + if(size <= bufSize)
- + {
- + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size);
- + return MV_OK;
- + }
- +
- + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize);
- + size -= bufSize;
- + frag++;
- + if(frag >= pMbuf->numFrags)
- + break;
- +
- + bufSize = pMbuf->pFrags[frag].bufSize;
- + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
- + }
- + mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",
- + __FUNCTION__, size);
- + return MV_FULL;
- +}
- +
- +
- +/*************************************** Local Functions ******************************/
- +
- +/*******************************************************************************
- +* mvCesaFragReqProcess - Process fragmented request
- +*
- +* DESCRIPTION:
- +* This function processes a fragment of fragmented request (First, Middle or Last)
- +*
- +*
- +* INPUT:
- +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
- +*
- +* RETURN:
- +* MV_OK - The fragment is successfully passed to HW for processing.
- +* MV_TERMINATE - Means, that HW finished its work on this packet and no more
- +* interrupts will be generated for this request.
- +* Function mvCesaReadyGet() must be called to complete request
- +* processing and get request result.
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag)
- +{
- + int i, copySize, cryptoDataSize, macDataSize, sid;
- + int cryptoIvOffset, digestOffset;
- + MV_U32 config;
- + MV_CESA_COMMAND* pCmd = pReq->pCmd;
- + MV_CESA_SA* pSA;
- + MV_CESA_MBUF* pMbuf;
- + MV_DMA_DESC* pDmaDesc = pReq->dma[frag].pDmaFirst;
- + MV_U8* pSramBuf = cesaSramVirtPtr->buf;
- + int macTotalLen = 0;
- + int fixOffset, cryptoOffset, macOffset;
- +
- + cesaStats.fragCount++;
- +
- + sid = pReq->pCmd->sessionId;
- +
- + pSA = &pCesaSAD[sid];
- +
- + cryptoIvOffset = digestOffset = 0;
- + i = macDataSize = 0;
- + cryptoDataSize = 0;
- +
- + /* First fragment processing */
- + if(pReq->fragMode == MV_CESA_FRAG_FIRST)
- + {
- + /* pReq->frags monitors processing of fragmented request between fragments */
- + pReq->frags.bufOffset = 0;
- + pReq->frags.cryptoSize = 0;
- + pReq->frags.macSize = 0;
- +
- + config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET);
- +
- + /* fixOffset can be not equal to zero only for FIRST fragment */
- + fixOffset = pReq->fixOffset;
- + /* For FIRST fragment crypto and mac offsets are taken from pCmd */
- + cryptoOffset = pCmd->cryptoOffset;
- + macOffset = pCmd->macOffset;
- +
- + copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset;
- +
- + /* Find fragment size: Must meet all requirements for CRYPTO and MAC
- + * cryptoDataSize - size of data will be encrypted/decrypted in this fragment
- + * macDataSize - size of data will be signed/verified in this fragment
- + * copySize - size of data will be copied from srcMbuf to SRAM and
- + * back to dstMbuf for this fragment
- + */
- + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
- + ©Size, &cryptoDataSize, &macDataSize);
- +
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET))
- + {
- + /* CryptoIV special processing */
- + if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) ==
- + (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) )
- + {
- + /* In CBC mode for encode direction when IV from user */
- + if( (pCmd->ivFromUser) &&
- + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
- + (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) )
- + {
- +
- + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
- + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
- + * in the buffer to SRAM IVPointer
- + */
- + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
- + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
- + }
- +
- + /* Special processing when IV is not located in the first fragment */
- + if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize))
- + {
- + /* Prepare dummy place for cryptoIV in SRAM */
- + cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet();
- +
- + /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */
- + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
- + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
- + {
- + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i],
- + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
- + }
- + else
- + {
- + /* For Encryption when IV is NOT from User: */
- + /* Copy IV from SRAM to buffer (pCmd->ivOffset) */
- + if(pCmd->ivFromUser == 0)
- + {
- + /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */
- + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
- + MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
- + }
- + }
- + }
- + else
- + {
- + cryptoIvOffset = pCmd->ivOffset;
- + }
- + }
- + }
- +
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + /* MAC digest special processing on Decode direction */
- + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
- + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
- + {
- + /* Save digest from pCmd->digestOffset */
- + mvCesaCopyFromMbuf(pReq->frags.orgDigest,
- + pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
- +
- + /* If pCmd->digestOffset is not located on the first */
- + if(pCmd->digestOffset > (copySize - pSA->digestSize))
- + {
- + MV_U8 digestZero[MV_CESA_MAX_DIGEST_SIZE];
- +
- + /* Set zeros to pCmd->digestOffset (DRAM) */
- + memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE);
- + mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
- +
- + /* Prepare dummy place for digest in SRAM */
- + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
- + }
- + else
- + {
- + digestOffset = pCmd->digestOffset;
- + }
- + }
- + }
- + /* Update SA in SRAM */
- + if(cesaLastSid != sid)
- + {
- + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
- + i++;
- + }
- +
- + pReq->fragMode = MV_CESA_FRAG_MIDDLE;
- + }
- + else
- + {
- + /* Continue fragment */
- + fixOffset = 0;
- + cryptoOffset = 0;
- + macOffset = 0;
- + if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf))
- + {
- + /* Last fragment */
- + config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET);
- + pReq->fragMode = MV_CESA_FRAG_LAST;
- + copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset;
- +
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + macDataSize = pCmd->macLength - pReq->frags.macSize;
- +
- + /* If pCmd->digestOffset is not located on last fragment */
- + if(pCmd->digestOffset < pReq->frags.bufOffset)
- + {
- + /* Prepare dummy place for digest in SRAM */
- + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
- + }
- + else
- + {
- + digestOffset = pCmd->digestOffset - pReq->frags.bufOffset;
- + }
- + pReq->frags.newDigestOffset = digestOffset;
- + macTotalLen = pCmd->macLength;
- +
- + /* HW can't calculate the Digest correctly for fragmented packets
- + * in the following cases:
- + * - MV88F5182 ||
- + * - MV88F5181L when total macLength more that 16 Kbytes ||
- + * - total macLength more that 64 Kbytes
- + */
- + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
- + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
- + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
- + (pCmd->macLength >= (1 << 14)) ) )
- + {
- + return MV_TERMINATE;
- + }
- + }
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize;
- + }
- +
- + /* cryptoIvOffset - don't care */
- + }
- + else
- + {
- + /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */
- + if( (mvCtrlModelGet() == MV_5182_DEV_ID) &&
- + (((pSA->config & MV_CESA_MAC_MODE_MASK) ==
- + (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) ||
- + ((pSA->config & MV_CESA_MAC_MODE_MASK) ==
- + (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) )
- + {
- + pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
- + pReq->fragMode = MV_CESA_FRAG_LAST;
- +
- + return MV_TERMINATE;
- + }
- + /* Middle fragment */
- + config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET);
- + copySize = sizeof(cesaSramVirtPtr->buf);
- + /* digestOffset and cryptoIvOffset - don't care */
- +
- + /* Find fragment size */
- + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
- + ©Size, &cryptoDataSize, &macDataSize);
- + }
- + }
- + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
- + pMbuf = pCmd->pSrc;
- + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
- + MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
- +
- + /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */
- + mvCesaSramDescrBuild(config, frag,
- + cryptoOffset + fixOffset, cryptoIvOffset + fixOffset,
- + cryptoDataSize, macOffset + fixOffset,
- + digestOffset + fixOffset, macDataSize, macTotalLen,
- + pReq, &pDmaDesc[i]);
- + i++;
- +
- + /* Add special descriptor Ownership for CPU */
- + pDmaDesc[i].byteCnt = 0;
- + pDmaDesc[i].phySrcAdd = 0;
- + pDmaDesc[i].phyDestAdd = 0;
- + i++;
- +
- + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
- + pMbuf = pCmd->pDst;
- + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
- + MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
- +
- + /* Next field of Last DMA descriptor must be NULL */
- + pDmaDesc[i-1].phyNextDescPtr = 0;
- + pReq->dma[frag].pDmaLast = &pDmaDesc[i-1];
- + mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst,
- + i*sizeof(MV_DMA_DESC));
- +
- + /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/
- +
- + pReq->frags.bufOffset += copySize;
- + pReq->frags.cryptoSize += cryptoDataSize;
- + pReq->frags.macSize += macDataSize;
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvCesaReqProcess - Process regular (Non-fragmented) request
- +*
- +* DESCRIPTION:
- +* This function processes the whole (not fragmented) request
- +*
- +* INPUT:
- +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
- +*
- +* RETURN:
- +* MV_OK - The request is successfully passed to HW for processing.
- +* Other - Failure. The request will not be processed
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq)
- +{
- + MV_CESA_MBUF *pMbuf;
- + MV_DMA_DESC *pDmaDesc;
- + MV_U8 *pSramBuf;
- + int sid, i, fixOffset;
- + MV_CESA_SA *pSA;
- + MV_CESA_COMMAND *pCmd = pReq->pCmd;
- +
- + cesaStats.procCount++;
- +
- + sid = pCmd->sessionId;
- + pSA = &pCesaSAD[sid];
- + pDmaDesc = pReq->dma[0].pDmaFirst;
- + pSramBuf = cesaSramVirtPtr->buf;
- + fixOffset = pReq->fixOffset;
- +
- +/*
- + mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",
- + sid, pSA, pDmaDesc, pSramBuf);
- +*/
- + i = 0;
- +
- + /* Crypto IV Special processing in CBC mode for Encryption direction */
- + if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) &&
- + ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) &&
- + ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) &&
- + (pCmd->ivFromUser) )
- + {
- + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
- + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
- + * in the buffer to SRAM IVPointer
- + */
- + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
- + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
- + }
- +
- + /* Update SA in SRAM */
- + if(cesaLastSid != sid)
- + {
- + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
- + i++;
- + }
- +
- + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
- + pMbuf = pCmd->pSrc;
- + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
- + MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush);
- +
- + /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */
- + mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset,
- + pCmd->ivOffset + fixOffset, pCmd->cryptoLength,
- + pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset,
- + pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]);
- + i++;
- +
- + /* Add special descriptor Ownership for CPU */
- + pDmaDesc[i].byteCnt = 0;
- + pDmaDesc[i].phySrcAdd = 0;
- + pDmaDesc[i].phyDestAdd = 0;
- + i++;
- +
- + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
- + pMbuf = pCmd->pDst;
- + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
- + MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush);
- +
- + /* Next field of Last DMA descriptor must be NULL */
- + pDmaDesc[i-1].phyNextDescPtr = 0;
- + pReq->dma[0].pDmaLast = &pDmaDesc[i-1];
- + mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC));
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvCesaSramDescrBuild - Set CESA descriptor in SRAM
- +*
- +* DESCRIPTION:
- +* This function builds CESA descriptor in SRAM from all Command parameters
- +*
- +*
- +* INPUT:
- +* int chan - CESA channel uses the descriptor
- +* MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure
- +* int cryptoOffset - Offset from the beginning of SRAM buffer where
- +* data for encryption/decription is started.
- +* int ivOffset - Offset of crypto IV from the SRAM base. Valid only
- +* for first fragment.
- +* int cryptoLength - Size (in bytes) of data for encryption/descryption
- +* operation on this fragment.
- +* int macOffset - Offset from the beginning of SRAM buffer where
- +* data for Authentication is started
- +* int digestOffset - Offset from the beginning of SRAM buffer where
- +* digest is located. Valid for first and last fragments.
- +* int macLength - Size (in bytes) of data for Authentication
- +* operation on this fragment.
- +* int macTotalLen - Toatl size (in bytes) of data for Authentication
- +* operation on the whole request (packet). Valid for
- +* last fragment only.
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +static void mvCesaSramDescrBuild(MV_U32 config, int frag,
- + int cryptoOffset, int ivOffset, int cryptoLength,
- + int macOffset, int digestOffset, int macLength,
- + int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc)
- +{
- + MV_CESA_DESC* pCesaDesc = &pReq->pCesaDesc[frag];
- + MV_CESA_DESC* pSramDesc = pSramDesc = &cesaSramVirtPtr->desc;
- + MV_U16 sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet());
- +
- + pCesaDesc->config = MV_32BIT_LE(config);
- +
- + if( (config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + /* word 1 */
- + pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
- + pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
- + /* word 2 */
- + pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength);
- + /* word 3 */
- + pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey -
- + mvCesaSramAddrGet()));
- + /* word 4 */
- + pCesaDesc->cryptoIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV -
- + mvCesaSramAddrGet()));
- + pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset);
- + }
- +
- + if( (config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + /* word 5 */
- + pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset);
- + pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen);
- +
- + /* word 6 */
- + pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset);
- + pCesaDesc->macDataLen = MV_16BIT_LE(macLength);
- +
- + /* word 7 */
- + pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV -
- + mvCesaSramAddrGet()));
- + pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV -
- + mvCesaSramAddrGet()));
- + }
- + /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */
- + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc));
- + pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc));
- + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31);
- +
- + /* flush Source buffer */
- + mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC));
- +}
- +
- +/*******************************************************************************
- +* mvCesaSramSaUpdate - Move required SA information to SRAM if needed.
- +*
- +* DESCRIPTION:
- +* Copy to SRAM values of the required SA.
- +*
- +*
- +* INPUT:
- +* short sid - Session ID needs SRAM Cache update
- +* MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to
- +* copy SA values from DRAM to SRAM.
- +*
- +* RETURN:
- +* MV_OK - Cache entry for this SA copied to SRAM.
- +* MV_NO_CHANGE - Cache entry for this SA already exist in SRAM
- +*
- +*******************************************************************************/
- +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc)
- +{
- + MV_CESA_SA *pSA = &pCesaSAD[sid];
- +
- + /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */
- + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31);
- + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA));
- + pDmaDesc->phyDestAdd =
- + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA));
- +
- + /* Source buffer is already flushed during OpenSession*/
- + /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/
- +}
- +
- +/*******************************************************************************
- +* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by
- +* Mbuf structure from DRAM to SRAM
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request
- +* data in DRAM
- +* MV_U8* pSramBuf - pointer to buffer in SRAM where data should
- +* be copied to.
- +* MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy.
- +* The function set number of DMA descriptors needed
- +* to copy the copySize bytes from Mbuf.
- +* MV_BOOL isToMbuf - Copy direction.
- +* MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.
- +* MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.
- +* int offset - Offset in the Mbuf structure that copy should be
- +* started from.
- +* int copySize - Size of data should be copied.
- +*
- +* RETURN:
- +* int - number of DMA descriptors used for the copy.
- +*
- +*******************************************************************************/
- +#ifndef MV_NETBSD
- +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
- + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
- + int offset, int copySize, MV_BOOL skipFlush)
- +{
- + int bufOffset, bufSize, size, frag, i;
- + MV_U8* pBuf;
- +
- + i = 0;
- +
- + /* Calculate start place for copy: fragment number and offset in the fragment */
- + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
- + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
- + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
- +
- + /* Size accumulate total copy size */
- + size = 0;
- +
- + /* Create DMA lists to copy mBuf from pSrc to SRAM */
- + while(size < copySize)
- + {
- + /* Find copy size for each DMA descriptor */
- + bufSize = MV_MIN(bufSize, (copySize - size));
- + pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31);
- + if(isToMbuf)
- + {
- + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
- + pDmaDesc[i].phySrcAdd =
- + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
- + /* invalidate the buffer */
- + if(skipFlush == MV_FALSE)
- + mvOsCacheInvalidate(NULL, pBuf, bufSize);
- + }
- + else
- + {
- + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
- + pDmaDesc[i].phyDestAdd =
- + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
- + /* flush the buffer */
- + if(skipFlush == MV_FALSE)
- + mvOsCacheFlush(NULL, pBuf, bufSize);
- + }
- +
- + /* Count number of used DMA descriptors */
- + i++;
- + size += bufSize;
- +
- + /* go to next fragment in the Mbuf */
- + frag++;
- + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
- + bufSize = pMbuf->pFrags[frag].bufSize;
- + }
- + return i;
- +}
- +#else /* MV_NETBSD */
- +static int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
- + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
- + int offset, int copySize, MV_BOOL skipFlush)
- +{
- + int bufOffset, bufSize, thisSize, size, frag, i;
- + MV_ULONG bufPhys, sramPhys;
- + MV_U8* pBuf;
- +
- + /*
- + * Calculate start place for copy: fragment number and offset in
- + * the fragment
- + */
- + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
- +
- + /*
- + * Get SRAM physical address only once. We can update it in-place
- + * as we build the descriptor chain.
- + */
- + sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf);
- +
- + /*
- + * 'size' accumulates total copy size, 'i' counts desccriptors.
- + */
- + size = i = 0;
- +
- + /* Create DMA lists to copy mBuf from pSrc to SRAM */
- + while (size < copySize) {
- + /*
- + * Calculate # of bytes to copy from the current fragment,
- + * and the pointer to the start of data
- + */
- + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
- + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
- + bufOffset = 0; /* First frag may be non-zero */
- + frag++;
- +
- + /*
- + * As long as there is data in the current fragment...
- + */
- + while (bufSize > 0) {
- + /*
- + * Ensure we don't cross an MMU page boundary.
- + * XXX: This is NetBSD-specific, but it is a
- + * quick and dirty way to fix the problem.
- + * A true HAL would rely on the OS-specific
- + * driver to do this...
- + */
- + thisSize = PAGE_SIZE -
- + (((MV_ULONG)pBuf) & (PAGE_SIZE - 1));
- + thisSize = MV_MIN(bufSize, thisSize);
- + /*
- + * Make sure we don't copy more than requested
- + */
- + if (thisSize > (copySize - size)) {
- + thisSize = copySize - size;
- + bufSize = 0;
- + }
- +
- + /*
- + * Physicall address of this fragment
- + */
- + bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
- +
- + /*
- + * Set up the descriptor
- + */
- + pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31);
- + if(isToMbuf) {
- + pDmaDesc[i].phyDestAdd = bufPhys;
- + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(sramPhys);
- + /* invalidate the buffer */
- + if(skipFlush == MV_FALSE)
- + mvOsCacheInvalidate(NULL, pBuf, thisSize);
- + } else {
- + pDmaDesc[i].phySrcAdd = bufPhys;
- + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys);
- + /* flush the buffer */
- + if(skipFlush == MV_FALSE)
- + mvOsCacheFlush(NULL, pBuf, thisSize);
- + }
- +
- + pDmaDesc[i].phyNextDescPtr =
- + MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1])));
- +
- + /* flush the DMA desc */
- + mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC));
- +
- + /* Update state */
- + bufSize -= thisSize;
- + sramPhys += thisSize;
- + pBuf += thisSize;
- + size += thisSize;
- + i++;
- + }
- + }
- +
- + return i;
- +}
- +#endif /* MV_NETBSD */
- +/*******************************************************************************
- +* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key
- +*
- +* DESCRIPTION:
- +* This function calculate Inner and Outer values used for HMAC algorithm.
- +* This operation allows improve performance fro the whole HMAC processing.
- +*
- +* INPUT:
- +* MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1.
- +* unsigned char key[] - Pointer to HMAC key.
- +* int keyLength - Size of HMAC key (maximum 64 bytes)
- +*
- +* OUTPUT:
- +* unsigned char innerIV[] - HASH(key^inner)
- +* unsigned char outerIV[] - HASH(key^outter)
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
- + unsigned char innerIV[], unsigned char outerIV[])
- +{
- + unsigned char inner[MV_CESA_MAX_MAC_KEY_LENGTH];
- + unsigned char outer[MV_CESA_MAX_MAC_KEY_LENGTH];
- + int i, digestSize = 0;
- +#if defined(MV_CPU_LE) || defined(MV_PPC)
- + MV_U32 swapped32, val32, *pVal32;
- +#endif
- + for(i=0; i<keyLength; i++)
- + {
- + inner[i] = 0x36 ^ key[i];
- + outer[i] = 0x5c ^ key[i];
- + }
- +
- + for(i=keyLength; i<MV_CESA_MAX_MAC_KEY_LENGTH; i++)
- + {
- + inner[i] = 0x36;
- + outer[i] = 0x5c;
- + }
- + if(macMode == MV_CESA_MAC_HMAC_MD5)
- + {
- + MV_MD5_CONTEXT ctx;
- +
- + mvMD5Init(&ctx);
- + mvMD5Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
- +
- + memcpy(innerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
- + memset(&ctx, 0, sizeof(ctx));
- +
- + mvMD5Init(&ctx);
- + mvMD5Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
- + memcpy(outerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
- + memset(&ctx, 0, sizeof(ctx));
- + digestSize = MV_CESA_MD5_DIGEST_SIZE;
- + }
- + else if(macMode == MV_CESA_MAC_HMAC_SHA1)
- + {
- + MV_SHA1_CTX ctx;
- +
- + mvSHA1Init(&ctx);
- + mvSHA1Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
- + memcpy(innerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
- + memset(&ctx, 0, sizeof(ctx));
- +
- + mvSHA1Init(&ctx);
- + mvSHA1Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
- + memcpy(outerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
- + memset(&ctx, 0, sizeof(ctx));
- + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
- + }
- + else
- + {
- + mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode);
- + }
- +#if defined(MV_CPU_LE) || defined(MV_PPC)
- + /* 32 bits Swap of Inner and Outer values */
- + pVal32 = (MV_U32*)innerIV;
- + for(i=0; i<digestSize/4; i++)
- + {
- + val32 = *pVal32;
- + swapped32 = MV_BYTE_SWAP_32BIT(val32);
- + *pVal32 = swapped32;
- + pVal32++;
- + }
- + pVal32 = (MV_U32*)outerIV;
- + for(i=0; i<digestSize/4; i++)
- + {
- + val32 = *pVal32;
- + swapped32 = MV_BYTE_SWAP_32BIT(val32);
- + *pVal32 = swapped32;
- + pVal32++;
- + }
- +#endif /* defined(MV_CPU_LE) || defined(MV_PPC) */
- +}
- +
- +
- +/*******************************************************************************
- +* mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
- +* for SHA1 is placed.
- +* int offset - Offset in the Mbuf structure where
- +* unprocessed data for SHA1 is started.
- +* MV_U8* pOuterIV - Pointer to OUTER for this session.
- +* If pOuterIV==NULL - MAC mode is HASH_SHA1
- +* If pOuterIV!=NULL - MAC mode is HMAC_SHA1
- +* int macLeftSize - Size of unprocessed data for SHA1.
- +* int macTotalSize - Total size of data for SHA1 in the
- +* request (processed + unprocessed)
- +*
- +* OUTPUT:
- +* MV_U8* pDigest - Pointer to place where calculated Digest will
- +* be stored.
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +static void mvCesaFragSha1Complete(MV_CESA_MBUF* pMbuf, int offset,
- + MV_U8* pOuterIV, int macLeftSize,
- + int macTotalSize, MV_U8* pDigest)
- +{
- + MV_SHA1_CTX ctx;
- + MV_U8 *pData;
- + int i, frag, fragOffset, size;
- +
- + /* Read temporary Digest from HW */
- + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
- + {
- + ctx.state[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
- + }
- + /* Initialize MV_SHA1_CTX structure */
- + memset(ctx.buffer, 0, 64);
- + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
- + /* so count[1] is always 0 */
- + ctx.count[0] = ((macTotalSize - macLeftSize) * 8);
- + ctx.count[1] = 0;
- +
- + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
- + if(pOuterIV != NULL)
- + ctx.count[0] += (64 * 8);
- +
- + /* Get place of unprocessed data in the Mbuf structure */
- + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
- + if(frag == MV_INVALID)
- + {
- + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
- + return;
- + }
- +
- + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
- + size = pMbuf->pFrags[frag].bufSize - fragOffset;
- +
- + /* Complete Inner part */
- + while(macLeftSize > 0)
- + {
- + if(macLeftSize <= size)
- + {
- + mvSHA1Update(&ctx, pData, macLeftSize);
- + break;
- + }
- + mvSHA1Update(&ctx, pData, size);
- + macLeftSize -= size;
- + frag++;
- + pData = pMbuf->pFrags[frag].bufVirtPtr;
- + size = pMbuf->pFrags[frag].bufSize;
- + }
- + mvSHA1Final(pDigest, &ctx);
- +/*
- + mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
- + pOuterIV, macLeftSize, macTotalSize);
- + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
- +*/
- +
- + if(pOuterIV != NULL)
- + {
- + /* If HMAC - Complete Outer part */
- + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
- + {
- +#if defined(MV_CPU_LE) || defined(MV_ARM)
- + ctx.state[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
- +#else
- + ctx.state[i] = ((MV_U32*)pOuterIV)[i];
- +#endif
- + }
- + memset(ctx.buffer, 0, 64);
- +
- + ctx.count[0] = 64*8;
- + ctx.count[1] = 0;
- + mvSHA1Update(&ctx, pDigest, MV_CESA_SHA1_DIGEST_SIZE);
- + mvSHA1Final(pDigest, &ctx);
- + }
- +}
- +
- +/*******************************************************************************
- +* mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
- +* for SHA1 is placed.
- +* int offset - Offset in the Mbuf structure where
- +* unprocessed data for MD5 is started.
- +* MV_U8* pOuterIV - Pointer to OUTER for this session.
- +* If pOuterIV==NULL - MAC mode is HASH_MD5
- +* If pOuterIV!=NULL - MAC mode is HMAC_MD5
- +* int macLeftSize - Size of unprocessed data for MD5.
- +* int macTotalSize - Total size of data for MD5 in the
- +* request (processed + unprocessed)
- +*
- +* OUTPUT:
- +* MV_U8* pDigest - Pointer to place where calculated Digest will
- +* be stored.
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +static void mvCesaFragMd5Complete(MV_CESA_MBUF* pMbuf, int offset,
- + MV_U8* pOuterIV, int macLeftSize,
- + int macTotalSize, MV_U8* pDigest)
- +{
- + MV_MD5_CONTEXT ctx;
- + MV_U8 *pData;
- + int i, frag, fragOffset, size;
- +
- + /* Read temporary Digest from HW */
- + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
- + {
- + ctx.buf[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
- + }
- + memset(ctx.in, 0, 64);
- +
- + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
- + /* so count[1] is always 0 */
- + ctx.bits[0] = ((macTotalSize - macLeftSize) * 8);
- + ctx.bits[1] = 0;
- +
- + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
- + if(pOuterIV != NULL)
- + ctx.bits[0] += (64 * 8);
- +
- + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
- + if(frag == MV_INVALID)
- + {
- + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
- + return;
- + }
- +
- + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
- + size = pMbuf->pFrags[frag].bufSize - fragOffset;
- +
- + /* Complete Inner part */
- + while(macLeftSize > 0)
- + {
- + if(macLeftSize <= size)
- + {
- + mvMD5Update(&ctx, pData, macLeftSize);
- + break;
- + }
- + mvMD5Update(&ctx, pData, size);
- + macLeftSize -= size;
- + frag++;
- + pData = pMbuf->pFrags[frag].bufVirtPtr;
- + size = pMbuf->pFrags[frag].bufSize;
- + }
- + mvMD5Final(pDigest, &ctx);
- +
- +/*
- + mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
- + pOuterIV, macLeftSize, macTotalSize);
- + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
- +*/
- + if(pOuterIV != NULL)
- + {
- + /* Complete Outer part */
- + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
- + {
- +#if defined(MV_CPU_LE) || defined(MV_ARM)
- + ctx.buf[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
- +#else
- + ctx.buf[i] = ((MV_U32*)pOuterIV)[i];
- +#endif
- + }
- + memset(ctx.in, 0, 64);
- +
- + ctx.bits[0] = 64*8;
- + ctx.bits[1] = 0;
- + mvMD5Update(&ctx, pDigest, MV_CESA_MD5_DIGEST_SIZE);
- + mvMD5Final(pDigest, &ctx);
- + }
- +}
- +
- +/*******************************************************************************
- +* mvCesaFragAuthComplete -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_REQ* pReq,
- +* MV_CESA_SA* pSA,
- +* int macDataSize
- +*
- +* RETURN:
- +* MV_STATUS
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
- + int macDataSize)
- +{
- + MV_CESA_COMMAND* pCmd = pReq->pCmd;
- + MV_U8* pDigest;
- + MV_CESA_MAC_MODE macMode;
- + MV_U8* pOuterIV = NULL;
- +
- + /* Copy data from Source fragment to Destination */
- + if(pCmd->pSrc != pCmd->pDst)
- + {
- + mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset,
- + pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
- + }
- +
- +/*
- + mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
- + mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);
- +*/
- + pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset);
- +
- + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
- +/*
- + mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",
- + macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);
- +*/
- + switch(macMode)
- + {
- + case MV_CESA_MAC_HMAC_MD5:
- + pOuterIV = pSA->pSramSA->macOuterIV;
- +
- + case MV_CESA_MAC_MD5:
- + mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
- + macDataSize, pCmd->macLength, pDigest);
- + break;
- +
- + case MV_CESA_MAC_HMAC_SHA1:
- + pOuterIV = pSA->pSramSA->macOuterIV;
- +
- + case MV_CESA_MAC_SHA1:
- + mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
- + macDataSize, pCmd->macLength, pDigest);
- + break;
- +
- + default:
- + mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode);
- + return MV_BAD_PARAM;
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaCtrModeInit -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT: NONE
- +*
- +*
- +* RETURN:
- +* MV_CESA_COMMAND*
- +*
- +*******************************************************************************/
- +static MV_CESA_COMMAND* mvCesaCtrModeInit(void)
- +{
- + MV_CESA_MBUF *pMbuf;
- + MV_U8 *pBuf;
- + MV_CESA_COMMAND *pCmd;
- +
- + pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) +
- + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100);
- + if(pBuf == NULL)
- + {
- + mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",
- + sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) );
- + return NULL;
- + }
- + pCmd = (MV_CESA_COMMAND*)pBuf;
- + pBuf += sizeof(MV_CESA_COMMAND);
- +
- + pMbuf = (MV_CESA_MBUF*)pBuf;
- + pBuf += sizeof(MV_CESA_MBUF);
- +
- + pMbuf->pFrags = (MV_BUF_INFO*)pBuf;
- +
- + pMbuf->numFrags = 1;
- + pCmd->pSrc = pMbuf;
- + pCmd->pDst = pMbuf;
- +/*
- + mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",
- + pCmd, pCmd->pSrc, pCmd->pDst,
- + pMbuf->pFrags);
- +*/
- + return pCmd;
- +}
- +
- +/*******************************************************************************
- +* mvCesaCtrModePrepare -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd
- +*
- +* RETURN:
- +* MV_STATUS
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd)
- +{
- + MV_CESA_MBUF *pMbuf;
- + MV_U8 *pBuf, *pIV;
- + MV_U32 counter, *pCounter;
- + int cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE);
- +/*
- + mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
- + pCmd, pCmd->pSrc, pCmd->pDst,
- + pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);
- +*/
- + pMbuf = pCtrModeCmd->pSrc;
- +
- + /* Allocate buffer for Key stream */
- + pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize,
- + &pMbuf->pFrags[0].bufPhysAddr,
- + &pMbuf->pFrags[0].memHandle);
- + if(pBuf == NULL)
- + {
- + mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize);
- + return MV_OUT_OF_CPU_MEM;
- + }
- + memset(pBuf, 0, cryptoSize);
- + mvOsCacheFlush(NULL, pBuf, cryptoSize);
- +
- + pMbuf->pFrags[0].bufVirtPtr = pBuf;
- + pMbuf->mbufSize = cryptoSize;
- + pMbuf->pFrags[0].bufSize = cryptoSize;
- +
- + pCtrModeCmd->pReqPrv = pCmd->pReqPrv;
- + pCtrModeCmd->sessionId = pCmd->sessionId;
- +
- + /* ivFromUser and ivOffset are don't care */
- + pCtrModeCmd->cryptoOffset = 0;
- + pCtrModeCmd->cryptoLength = cryptoSize;
- +
- + /* digestOffset, macOffset and macLength are don't care */
- +
- + mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE);
- + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
- + counter = *pCounter;
- + counter = MV_32BIT_BE(counter);
- + pIV = pBuf;
- + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
- +
- + /* fill key stream */
- + while(cryptoSize > 0)
- + {
- + pBuf += MV_CESA_AES_BLOCK_SIZE;
- + memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter));
- + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
- + counter++;
- + *pCounter = MV_32BIT_BE(counter);
- + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaCtrModeComplete -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd
- +*
- +* RETURN:
- +* MV_STATUS
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd)
- +{
- + int srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize;
- + int cryptoSize = pCmd->cryptoLength;
- + MV_U8 *pSrc, *pDst, *pKey;
- + MV_STATUS status = MV_OK;
- +/*
- + mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
- + pCmd, pCmd->pSrc, pCmd->pDst,
- + pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);
- +*/
- + /* XOR source data with key stream to destination data */
- + pKey = pCmd->pDst->pFrags[0].bufVirtPtr;
- + keyOffset = 0;
- +
- + if( (pOrgCmd->pSrc != pOrgCmd->pDst) &&
- + (pOrgCmd->cryptoOffset > 0) )
- + {
- + /* Copy Prefix from source buffer to destination buffer */
- +
- + status = mvCesaMbufCopy(pOrgCmd->pDst, 0,
- + pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset);
- +/*
- + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
- + 0, pOrgCmd->cryptoOffset);
- + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
- + 0, pOrgCmd->cryptoOffset);
- +*/
- + }
- +
- + srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset);
- + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
- + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
- +
- + dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset);
- + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
- + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
- +
- + while(cryptoSize > 0)
- + {
- + pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]);
- +
- + cryptoSize--;
- + dstOffset++;
- + srcOffset++;
- + keyOffset++;
- +
- + if(srcOffset >= srcSize)
- + {
- + srcFrag++;
- + srcOffset = 0;
- + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
- + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
- + }
- +
- + if(dstOffset >= dstSize)
- + {
- + dstFrag++;
- + dstOffset = 0;
- + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
- + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
- + }
- + }
- +
- + if(pOrgCmd->pSrc != pOrgCmd->pDst)
- + {
- + /* Copy Suffix from source buffer to destination buffer */
- + srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength;
- +
- + if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0)
- + {
- + status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset,
- + pOrgCmd->pSrc, srcOffset,
- + pOrgCmd->pDst->mbufSize - srcOffset);
- + }
- +
- +/*
- + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
- + srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);
- + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
- + srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);
- +*/
- + }
- +
- + /* Free buffer used for Key stream */
- + mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize,
- + pCmd->pDst->pFrags[0].bufPhysAddr,
- + pCmd->pDst->pFrags[0].bufVirtPtr,
- + pCmd->pDst->pFrags[0].memHandle);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaCtrModeFinish -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_COMMAND* pCmd
- +*
- +* RETURN:
- +* MV_STATUS
- +*
- +*******************************************************************************/
- +static void mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd)
- +{
- + mvOsFree(pCmd);
- +}
- +
- +/*******************************************************************************
- +* mvCesaParamCheck -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset
- +*
- +* RETURN:
- +* MV_STATUS
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
- + MV_U8* pFixOffset)
- +{
- + MV_U8 fixOffset = 0xFF;
- +
- + /* Check AUTH operation parameters */
- + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
- + {
- + /* MAC offset should be at least 4 byte aligned */
- + if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) )
- + {
- + mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",
- + pCmd->macOffset);
- + return MV_BAD_PARAM;
- + }
- + /* Digest offset must be 4 byte aligned */
- + if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) )
- + {
- + mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",
- + pCmd->digestOffset);
- + return MV_BAD_PARAM;
- + }
- + /* In addition all offsets should be the same alignment: 8 or 4 */
- + if(fixOffset == 0xFF)
- + {
- + fixOffset = (pCmd->macOffset % 8);
- + }
- + else
- + {
- + if( (pCmd->macOffset % 8) != fixOffset)
- + {
- + mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",
- + pCmd->macOffset, fixOffset);
- + return MV_BAD_PARAM;
- + }
- + }
- + if( (pCmd->digestOffset % 8) != fixOffset)
- + {
- + mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",
- + pCmd->digestOffset, fixOffset);
- + return MV_BAD_PARAM;
- + }
- + }
- + /* Check CRYPTO operation parameters */
- + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
- + {
- + /* CryptoOffset should be at least 4 byte aligned */
- + if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4) )
- + {
- + mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",
- + pCmd->cryptoOffset);
- + return MV_BAD_PARAM;
- + }
- + /* cryptoLength should be the whole number of blocks */
- + if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) )
- + {
- + mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",
- + pCmd->cryptoLength, pSA->cryptoBlockSize);
- + return MV_BAD_PARAM;
- + }
- + if(fixOffset == 0xFF)
- + {
- + fixOffset = (pCmd->cryptoOffset % 8);
- + }
- + else
- + {
- + /* In addition all offsets should be the same alignment: 8 or 4 */
- + if( (pCmd->cryptoOffset % 8) != fixOffset)
- + {
- + mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",
- + pCmd->cryptoOffset, fixOffset);
- + return MV_BAD_PARAM;
- + }
- + }
- +
- + /* check for CBC mode */
- + if(pSA->cryptoIvSize > 0)
- + {
- + /* cryptoIV must not be part of CryptoLength */
- + if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) &&
- + (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
- + {
- + mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",
- + pCmd->ivOffset, pCmd->macOffset, pCmd->macLength);
- + return MV_BAD_PARAM;
- + }
- +
- + /* ivOffset must be 4 byte aligned */
- + if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) )
- + {
- + mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",
- + pCmd->ivOffset);
- + return MV_BAD_PARAM;
- + }
- + /* In addition all offsets should be the same alignment: 8 or 4 */
- + if( (pCmd->ivOffset % 8) != fixOffset)
- + {
- + mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",
- + pCmd->ivOffset, fixOffset);
- + return MV_BAD_PARAM;
- + }
- + }
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaFragParamCheck -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd
- +*
- +* RETURN:
- +* MV_STATUS
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd)
- +{
- + int offset;
- +
- + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
- + {
- + /* macOffset must be less that SRAM buffer size */
- + if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE))
- + {
- + mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",
- + pCmd->macOffset);
- + return MV_BAD_PARAM;
- + }
- + /* macOffset+macSize must be more than mbufSize - SRAM buffer size */
- + if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) ||
- + ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >=
- + sizeof(cesaSramVirtPtr->buf)) )
- + {
- + mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",
- + pCmd->macLength, pCmd->pSrc->mbufSize);
- + return MV_BAD_PARAM;
- + }
- + }
- +
- + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
- + {
- + /* cryptoOffset must be less that SRAM buffer size */
- + /* 4 for possible fixOffset */
- + if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize))
- + {
- + mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",
- + pCmd->cryptoOffset);
- + return MV_BAD_PARAM;
- + }
- +
- + /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */
- + if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) ||
- + ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >=
- + (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) )
- + {
- + mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",
- + pCmd->cryptoLength, pCmd->pSrc->mbufSize);
- + return MV_BAD_PARAM;
- + }
- + }
- +
- + /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */
- + if( ((pSA->config & MV_CESA_OPERATION_MASK) ==
- + (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) ||
- + ((pSA->config & MV_CESA_OPERATION_MASK) ==
- + (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) )
- + {
- + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
- + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
- + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
- + (pCmd->macLength >= (1 << 14)) ) )
- + {
- + return MV_NOT_ALLOWED;
- + }
- +
- + /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */
- + if(pCmd->cryptoOffset > pCmd->macOffset)
- + {
- + offset = pCmd->cryptoOffset - pCmd->macOffset;
- + }
- + else
- + {
- + offset = pCmd->macOffset - pCmd->cryptoOffset;
- + }
- +
- + if( MV_IS_NOT_ALIGN(offset, pSA->cryptoBlockSize) )
- + {
- +/*
- + mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",
- + pSA->cryptoBlockSize);
- +*/
- + return MV_NOT_ALLOWED;
- + }
- + /* Digest must not be part of CryptoLength */
- + if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) &&
- + (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
- + {
- +/*
- + mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",
- + pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);
- +*/
- + return MV_NOT_ALLOWED;
- + }
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCesaFragSizeFind -
- +*
- +* DESCRIPTION:
- +*
- +*
- +* INPUT:
- +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
- +* int cryptoOffset, int macOffset,
- +*
- +* OUTPUT:
- +* int* pCopySize, int* pCryptoDataSize, int* pMacDataSize
- +*
- +* RETURN:
- +* MV_STATUS
- +*
- +*******************************************************************************/
- +static void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
- + int cryptoOffset, int macOffset,
- + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize)
- +{
- + MV_CESA_COMMAND *pCmd = pReq->pCmd;
- + int cryptoDataSize, macDataSize, copySize;
- +
- + cryptoDataSize = macDataSize = 0;
- + copySize = *pCopySize;
- +
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + cryptoDataSize = MV_MIN( (copySize - cryptoOffset),
- + (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) );
- +
- + /* cryptoSize for each fragment must be the whole number of blocksSize */
- + if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) )
- + {
- + cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize);
- + copySize = cryptoOffset + cryptoDataSize;
- + }
- + }
- + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
- + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
- + {
- + macDataSize = MV_MIN( (copySize - macOffset),
- + (pCmd->macLength - (pReq->frags.macSize + 1)));
- +
- + /* macSize for each fragment (except last) must be the whole number of blocksSize */
- + if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) )
- + {
- + macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE);
- + copySize = macOffset + macDataSize;
- + }
- + cryptoDataSize = copySize - cryptoOffset;
- + }
- + *pCopySize = copySize;
- +
- + if(pCryptoDataSize != NULL)
- + *pCryptoDataSize = cryptoDataSize;
- +
- + if(pMacDataSize != NULL)
- + *pMacDataSize = macDataSize;
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaDebug.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 2010-11-09 20:28:05.342495385 +0100
- @@ -0,0 +1,484 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvOs.h"
- +#include "mvDebug.h"
- +
- +#include "cesa/mvMD5.h"
- +#include "cesa/mvSHA1.h"
- +
- +#include "cesa/mvCesa.h"
- +#include "cesa/mvCesaRegs.h"
- +#include "cesa/AES/mvAes.h"
- +
- +static const char* mvCesaDebugStateStr(MV_CESA_STATE state)
- +{
- + switch(state)
- + {
- + case MV_CESA_IDLE:
- + return "Idle";
- +
- + case MV_CESA_PENDING:
- + return "Pend";
- +
- + case MV_CESA_PROCESS:
- + return "Proc";
- +
- + case MV_CESA_READY:
- + return "Ready";
- +
- + default:
- + break;
- + }
- + return "Unknown";
- +}
- +
- +static const char* mvCesaDebugOperStr(MV_CESA_OPERATION oper)
- +{
- + switch(oper)
- + {
- + case MV_CESA_MAC_ONLY:
- + return "MacOnly";
- +
- + case MV_CESA_CRYPTO_ONLY:
- + return "CryptoOnly";
- +
- + case MV_CESA_MAC_THEN_CRYPTO:
- + return "MacCrypto";
- +
- + case MV_CESA_CRYPTO_THEN_MAC:
- + return "CryptoMac";
- +
- + default:
- + break;
- + }
- + return "Null";
- +}
- +
- +static const char* mvCesaDebugCryptoAlgStr(MV_CESA_CRYPTO_ALG cryptoAlg)
- +{
- + switch(cryptoAlg)
- + {
- + case MV_CESA_CRYPTO_DES:
- + return "DES";
- +
- + case MV_CESA_CRYPTO_3DES:
- + return "3DES";
- +
- + case MV_CESA_CRYPTO_AES:
- + return "AES";
- +
- + default:
- + break;
- + }
- + return "Null";
- +}
- +
- +static const char* mvCesaDebugMacModeStr(MV_CESA_MAC_MODE macMode)
- +{
- + switch(macMode)
- + {
- + case MV_CESA_MAC_MD5:
- + return "MD5";
- +
- + case MV_CESA_MAC_SHA1:
- + return "SHA1";
- +
- + case MV_CESA_MAC_HMAC_MD5:
- + return "HMAC-MD5";
- +
- + case MV_CESA_MAC_HMAC_SHA1:
- + return "HMAC_SHA1";
- +
- + default:
- + break;
- + }
- + return "Null";
- +}
- +
- +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode)
- +{
- + mvOsPrintf("pCmd=%p, pReqPrv=%p, pSrc=%p, pDst=%p, pCB=%p, sid=%d\n",
- + pCmd, pCmd->pReqPrv, pCmd->pSrc, pCmd->pDst,
- + pCmd->pFuncCB, pCmd->sessionId);
- + mvOsPrintf("isUser=%d, ivOffs=%d, crOffs=%d, crLen=%d, digest=%d, macOffs=%d, macLen=%d\n",
- + pCmd->ivFromUser, pCmd->ivOffset, pCmd->cryptoOffset, pCmd->cryptoLength,
- + pCmd->digestOffset, pCmd->macOffset, pCmd->macLength);
- +}
- +
- +/* no need to use in tool */
- +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size)
- +{
- + int frag, len, fragOffset;
- +
- + if(str != NULL)
- + mvOsPrintf("%s: pMbuf=%p, numFrags=%d, mbufSize=%d\n",
- + str, pMbuf, pMbuf->numFrags, pMbuf->mbufSize);
- +
- + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
- + if(frag == MV_INVALID)
- + {
- + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
- + return;
- + }
- +
- + for(; frag<pMbuf->numFrags; frag++)
- + {
- + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
- + frag, pMbuf->pFrags[frag].bufVirtPtr,
- + pMbuf->pFrags[frag].bufSize);
- + if(size > 0)
- + {
- + len = MV_MIN(pMbuf->pFrags[frag].bufSize, size);
- + mvDebugMemDump(pMbuf->pFrags[frag].bufVirtPtr+fragOffset, len, 1);
- + size -= len;
- + fragOffset = 0;
- + }
- + }
- +}
- +
- +void mvCesaDebugRegs(void)
- +{
- + mvOsPrintf("\t CESA Registers:\n");
- +
- + mvOsPrintf("MV_CESA_CMD_REG : 0x%X = 0x%08x\n",
- + MV_CESA_CMD_REG,
- + MV_REG_READ( MV_CESA_CMD_REG ) );
- +
- + mvOsPrintf("MV_CESA_CHAN_DESC_OFFSET_REG : 0x%X = 0x%08x\n",
- + MV_CESA_CHAN_DESC_OFFSET_REG,
- + MV_REG_READ(MV_CESA_CHAN_DESC_OFFSET_REG) );
- +
- + mvOsPrintf("MV_CESA_CFG_REG : 0x%X = 0x%08x\n",
- + MV_CESA_CFG_REG,
- + MV_REG_READ( MV_CESA_CFG_REG ) );
- +
- + mvOsPrintf("MV_CESA_STATUS_REG : 0x%X = 0x%08x\n",
- + MV_CESA_STATUS_REG,
- + MV_REG_READ( MV_CESA_STATUS_REG ) );
- +
- + mvOsPrintf("MV_CESA_ISR_CAUSE_REG : 0x%X = 0x%08x\n",
- + MV_CESA_ISR_CAUSE_REG,
- + MV_REG_READ( MV_CESA_ISR_CAUSE_REG ) );
- +
- + mvOsPrintf("MV_CESA_ISR_MASK_REG : 0x%X = 0x%08x\n",
- + MV_CESA_ISR_MASK_REG,
- + MV_REG_READ( MV_CESA_ISR_MASK_REG ) );
- +#if (MV_CESA_VERSION >= 2)
- + mvOsPrintf("MV_CESA_TDMA_CTRL_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_CTRL_REG,
- + MV_REG_READ( MV_CESA_TDMA_CTRL_REG ) );
- +
- + mvOsPrintf("MV_CESA_TDMA_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_BYTE_COUNT_REG,
- + MV_REG_READ( MV_CESA_TDMA_BYTE_COUNT_REG ) );
- +
- + mvOsPrintf("MV_CESA_TDMA_SRC_ADDR_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_SRC_ADDR_REG,
- + MV_REG_READ( MV_CESA_TDMA_SRC_ADDR_REG ) );
- +
- + mvOsPrintf("MV_CESA_TDMA_DST_ADDR_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_DST_ADDR_REG,
- + MV_REG_READ( MV_CESA_TDMA_DST_ADDR_REG ) );
- +
- + mvOsPrintf("MV_CESA_TDMA_NEXT_DESC_PTR_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_NEXT_DESC_PTR_REG,
- + MV_REG_READ( MV_CESA_TDMA_NEXT_DESC_PTR_REG ) );
- +
- + mvOsPrintf("MV_CESA_TDMA_CURR_DESC_PTR_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_CURR_DESC_PTR_REG,
- + MV_REG_READ( MV_CESA_TDMA_CURR_DESC_PTR_REG ) );
- +
- + mvOsPrintf("MV_CESA_TDMA_ERROR_CAUSE_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_ERROR_CAUSE_REG,
- + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
- +
- + mvOsPrintf("MV_CESA_TDMA_ERROR_MASK_REG : 0x%X = 0x%08x\n",
- + MV_CESA_TDMA_ERROR_MASK_REG,
- + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
- +
- +#endif
- +}
- +
- +void mvCesaDebugStatus(void)
- +{
- + mvOsPrintf("\n\t CESA Status\n\n");
- +
- + mvOsPrintf("pReqQ=%p, qDepth=%d, reqSize=%ld bytes, qRes=%d, ",
- + pCesaReqFirst, cesaQueueDepth, sizeof(MV_CESA_REQ),
- + cesaReqResources);
- +#if (MV_CESA_VERSION >= 3)
- + mvOsPrintf("chainLength=%u\n",cesaChainLength);
- +#else
- + mvOsPrintf("\n");
- +#endif
- +
- + mvOsPrintf("pSAD=%p, maxSA=%d, sizeSA=%ld bytes\n",
- + pCesaSAD, cesaMaxSA, sizeof(MV_CESA_SA));
- +
- + mvOsPrintf("\n");
- +
- + mvCesaDebugRegs();
- + mvCesaDebugStats();
- + mvCesaDebugStatsClear();
- +}
- +
- +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc)
- +{
- + mvOsPrintf("config=0x%08x, crSrcOffs=0x%04x, crDstOffs=0x%04x\n",
- + pDesc->config, pDesc->cryptoSrcOffset, pDesc->cryptoDstOffset);
- +
- + mvOsPrintf("crLen=0x%04x, crKeyOffs=0x%04x, ivOffs=0x%04x, ivBufOffs=0x%04x\n",
- + pDesc->cryptoDataLen, pDesc->cryptoKeyOffset,
- + pDesc->cryptoIvOffset, pDesc->cryptoIvBufOffset);
- +
- + mvOsPrintf("macSrc=0x%04x, digest=0x%04x, macLen=0x%04x, inIv=0x%04x, outIv=0x%04x\n",
- + pDesc->macSrcOffset, pDesc->macDigestOffset, pDesc->macDataLen,
- + pDesc->macInnerIvOffset, pDesc->macOuterIvOffset);
- +}
- +
- +void mvCesaDebugQueue(int mode)
- +{
- + mvOsPrintf("\n\t CESA Request Queue:\n\n");
- +
- + mvOsPrintf("pFirstReq=%p, pLastReq=%p, qDepth=%d, reqSize=%ld bytes\n",
- + pCesaReqFirst, pCesaReqLast, cesaQueueDepth, sizeof(MV_CESA_REQ));
- +
- + mvOsPrintf("pEmpty=%p, pProcess=%p, qResources=%d\n",
- + pCesaReqEmpty, pCesaReqProcess,
- + cesaReqResources);
- +
- + if(mode != 0)
- + {
- + int count = 0;
- + MV_CESA_REQ* pReq = pCesaReqFirst;
- +
- + for(count=0; count<cesaQueueDepth; count++)
- + {
- + /* Print out requsts */
- + mvOsPrintf("%02d. pReq=%p, state=%s, frag=0x%x, pCmd=%p, pDma=%p, pDesc=%p\n",
- + count, pReq, mvCesaDebugStateStr(pReq->state),
- + pReq->fragMode, pReq->pCmd, pReq->dma[0].pDmaFirst, &pReq->pCesaDesc[0]);
- + if(pReq->fragMode != MV_CESA_FRAG_NONE)
- + {
- + int frag;
- +
- + mvOsPrintf("pFrags=%p, num=%d, next=%d, bufOffset=%d, cryptoSize=%d, macSize=%d\n",
- + &pReq->frags, pReq->frags.numFrag, pReq->frags.nextFrag,
- + pReq->frags.bufOffset, pReq->frags.cryptoSize, pReq->frags.macSize);
- + for(frag=0; frag<pReq->frags.numFrag; frag++)
- + {
- + mvOsPrintf("#%d: pDmaFirst=%p, pDesc=%p\n", frag,
- + pReq->dma[frag].pDmaFirst, &pReq->pCesaDesc[frag]);
- + }
- + }
- + if(mode > 1)
- + {
- + /* Print out Command */
- + mvCesaDebugCmd(pReq->pCmd, mode);
- +
- + /* Print out Descriptor */
- + mvCesaDebugDescriptor(&pReq->pCesaDesc[0]);
- + }
- + pReq++;
- + }
- + }
- +}
- +
- +
- +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode)
- +{
- + if(pSramSA == NULL)
- + {
- + mvOsPrintf("cesaSramSA: Unexpected pSramSA=%p\n", pSramSA);
- + return;
- + }
- + mvOsPrintf("pSramSA=%p, sizeSramSA=%ld bytes\n",
- + pSramSA, sizeof(MV_CESA_SRAM_SA));
- +
- + if(mode != 0)
- + {
- + mvOsPrintf("cryptoKey=%p, maxCryptoKey=%d bytes\n",
- + pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH);
- + mvDebugMemDump(pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH, 1);
- +
- + mvOsPrintf("macInnerIV=%p, maxInnerIV=%d bytes\n",
- + pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE);
- + mvDebugMemDump(pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE, 1);
- +
- + mvOsPrintf("macOuterIV=%p, maxOuterIV=%d bytes\n",
- + pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE);
- + mvDebugMemDump(pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE, 1);
- + }
- +}
- +
- +void mvCesaDebugSA(short sid, int mode)
- +{
- + MV_CESA_OPERATION oper;
- + MV_CESA_DIRECTION dir;
- + MV_CESA_CRYPTO_ALG cryptoAlg;
- + MV_CESA_CRYPTO_MODE cryptoMode;
- + MV_CESA_MAC_MODE macMode;
- + MV_CESA_SA* pSA = &pCesaSAD[sid];
- +
- + if( (pSA->valid) || ((pSA->count != 0) && (mode > 0)) || (mode >= 2) )
- + {
- + mvOsPrintf("\n\nCESA SA Entry #%d (%p) - %s (count=%d)\n",
- + sid, pSA,
- + pSA->valid ? "Valid" : "Invalid", pSA->count);
- +
- + oper = (pSA->config & MV_CESA_OPERATION_MASK) >> MV_CESA_OPERATION_OFFSET;
- + dir = (pSA->config & MV_CESA_DIRECTION_MASK) >> MV_CESA_DIRECTION_BIT;
- + mvOsPrintf("%s - %s ", mvCesaDebugOperStr(oper),
- + (dir == MV_CESA_DIR_ENCODE) ? "Encode" : "Decode");
- + if(oper != MV_CESA_MAC_ONLY)
- + {
- + cryptoAlg = (pSA->config & MV_CESA_CRYPTO_ALG_MASK) >> MV_CESA_CRYPTO_ALG_OFFSET;
- + cryptoMode = (pSA->config & MV_CESA_CRYPTO_MODE_MASK) >> MV_CESA_CRYPTO_MODE_BIT;
- + mvOsPrintf("- %s - %s ", mvCesaDebugCryptoAlgStr(cryptoAlg),
- + (cryptoMode == MV_CESA_CRYPTO_ECB) ? "ECB" : "CBC");
- + }
- + if(oper != MV_CESA_CRYPTO_ONLY)
- + {
- + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
- + mvOsPrintf("- %s ", mvCesaDebugMacModeStr(macMode));
- + }
- + mvOsPrintf("\n");
- +
- + if(mode > 0)
- + {
- + mvOsPrintf("config=0x%08x, cryptoKeySize=%d, digestSize=%d\n",
- + pCesaSAD[sid].config, pCesaSAD[sid].cryptoKeyLength,
- + pCesaSAD[sid].digestSize);
- +
- + mvCesaDebugSramSA(pCesaSAD[sid].pSramSA, mode);
- + }
- + }
- +}
- +
- +
- +/**/
- +void mvCesaDebugSram(int mode)
- +{
- + mvOsPrintf("\n\t SRAM contents: size=%ld, pVirt=%p\n\n",
- + sizeof(MV_CESA_SRAM_MAP), cesaSramVirtPtr);
- +
- + mvOsPrintf("\n\t Sram buffer: size=%d, pVirt=%p\n",
- + MV_CESA_MAX_BUF_SIZE, cesaSramVirtPtr->buf);
- + if(mode != 0)
- + mvDebugMemDump(cesaSramVirtPtr->buf, 64, 1);
- +
- + mvOsPrintf("\n");
- + mvOsPrintf("\n\t Sram descriptor: size=%ld, pVirt=%p\n",
- + sizeof(MV_CESA_DESC), &cesaSramVirtPtr->desc);
- + if(mode != 0)
- + {
- + mvOsPrintf("\n");
- + mvCesaDebugDescriptor(&cesaSramVirtPtr->desc);
- + }
- + mvOsPrintf("\n\t Sram IV: size=%d, pVirt=%p\n",
- + MV_CESA_MAX_IV_LENGTH, &cesaSramVirtPtr->cryptoIV);
- + if(mode != 0)
- + {
- + mvOsPrintf("\n");
- + mvDebugMemDump(cesaSramVirtPtr->cryptoIV, MV_CESA_MAX_IV_LENGTH, 1);
- + }
- + mvOsPrintf("\n");
- + mvCesaDebugSramSA(&cesaSramVirtPtr->sramSA, 0);
- +}
- +
- +void mvCesaDebugSAD(int mode)
- +{
- + int sid;
- +
- + mvOsPrintf("\n\t Cesa SAD status: pSAD=%p, maxSA=%d\n",
- + pCesaSAD, cesaMaxSA);
- +
- + for(sid=0; sid<cesaMaxSA; sid++)
- + {
- + mvCesaDebugSA(sid, mode);
- + }
- +}
- +
- +void mvCesaDebugStats(void)
- +{
- + mvOsPrintf("\n\t Cesa Statistics\n");
- +
- + mvOsPrintf("Opened=%u, Closed=%u\n",
- + cesaStats.openedCount, cesaStats.closedCount);
- + mvOsPrintf("Req=%u, maxReq=%u, frags=%u, start=%u\n",
- + cesaStats.reqCount, cesaStats.maxReqCount,
- + cesaStats.fragCount, cesaStats.startCount);
- +#if (MV_CESA_VERSION >= 3)
- + mvOsPrintf("maxChainUsage=%u\n",cesaStats.maxChainUsage);
- +#endif
- + mvOsPrintf("\n");
- + mvOsPrintf("proc=%u, ready=%u, notReady=%u\n",
- + cesaStats.procCount, cesaStats.readyCount, cesaStats.notReadyCount);
- +}
- +
- +void mvCesaDebugStatsClear(void)
- +{
- + memset(&cesaStats, 0, sizeof(cesaStats));
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.h 2010-11-09 20:28:05.737859537 +0100
- @@ -0,0 +1,412 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +/*******************************************************************************
- +* mvCesa.h - Header File for Cryptographic Engines and Security Accelerator
- +*
- +* DESCRIPTION:
- +* This header file contains macros typedefs and function declaration for
- +* the Marvell Cryptographic Engines and Security Accelerator.
- +*
- +*******************************************************************************/
- +
- +#ifndef __mvCesa_h__
- +#define __mvCesa_h__
- +
- +#include "mvOs.h"
- +#include "mvCommon.h"
- +#include "mvDebug.h"
- +
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +
- +#include "cesa/mvMD5.h"
- +#include "cesa/mvSHA1.h"
- +
- +#include "cesa/mvCesa.h"
- +#include "cesa/AES/mvAes.h"
- +#include "mvSysHwConfig.h"
- +
- +#ifdef MV_INCLUDE_IDMA
- +#include "idma/mvIdma.h"
- +#include "idma/mvIdmaRegs.h"
- +#else
- +/* Redefine MV_DMA_DESC structure */
- +typedef struct _mvDmaDesc
- +{
- + MV_U32 byteCnt; /* The total number of bytes to transfer */
- + MV_U32 phySrcAdd; /* The physical source address */
- + MV_U32 phyDestAdd; /* The physical destination address */
- + MV_U32 phyNextDescPtr; /* If we are using chain mode DMA transfer, */
- + /* then this pointer should point to the */
- + /* physical address of the next descriptor, */
- + /* otherwise it should be NULL. */
- +}MV_DMA_DESC;
- +#endif /* MV_INCLUDE_IDMA */
- +
- +#include "cesa/mvCesaRegs.h"
- +
- +#define MV_CESA_AUTH_BLOCK_SIZE 64 /* bytes */
- +
- +#define MV_CESA_MD5_DIGEST_SIZE 16 /* bytes */
- +#define MV_CESA_SHA1_DIGEST_SIZE 20 /* bytes */
- +
- +#define MV_CESA_MAX_DIGEST_SIZE MV_CESA_SHA1_DIGEST_SIZE
- +
- +#define MV_CESA_DES_KEY_LENGTH 8 /* bytes = 64 bits */
- +#define MV_CESA_3DES_KEY_LENGTH 24 /* bytes = 192 bits */
- +#define MV_CESA_AES_128_KEY_LENGTH 16 /* bytes = 128 bits */
- +#define MV_CESA_AES_192_KEY_LENGTH 24 /* bytes = 192 bits */
- +#define MV_CESA_AES_256_KEY_LENGTH 32 /* bytes = 256 bits */
- +
- +#define MV_CESA_MAX_CRYPTO_KEY_LENGTH MV_CESA_AES_256_KEY_LENGTH
- +
- +#define MV_CESA_DES_BLOCK_SIZE 8 /* bytes = 64 bits */
- +#define MV_CESA_3DES_BLOCK_SIZE 8 /* bytes = 64 bits */
- +
- +#define MV_CESA_AES_BLOCK_SIZE 16 /* bytes = 128 bits */
- +
- +#define MV_CESA_MAX_IV_LENGTH MV_CESA_AES_BLOCK_SIZE
- +
- +#define MV_CESA_MAX_MAC_KEY_LENGTH 64 /* bytes */
- +
- +typedef struct
- +{
- + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
- + MV_U8 macKey[MV_CESA_MAX_MAC_KEY_LENGTH];
- + MV_CESA_OPERATION operation;
- + MV_CESA_DIRECTION direction;
- + MV_CESA_CRYPTO_ALG cryptoAlgorithm;
- + MV_CESA_CRYPTO_MODE cryptoMode;
- + MV_U8 cryptoKeyLength;
- + MV_CESA_MAC_MODE macMode;
- + MV_U8 macKeyLength;
- + MV_U8 digestSize;
- +
- +} MV_CESA_OPEN_SESSION;
- +
- +typedef struct
- +{
- + MV_BUF_INFO *pFrags;
- + MV_U16 numFrags;
- + MV_U16 mbufSize;
- +
- +} MV_CESA_MBUF;
- +
- +typedef struct
- +{
- + void* pReqPrv; /* instead of reqId */
- + MV_U32 retCode;
- + MV_16 sessionId;
- +
- +} MV_CESA_RESULT;
- +
- +typedef void (*MV_CESA_CALLBACK) (MV_CESA_RESULT* pResult);
- +
- +
- +typedef struct
- +{
- + void* pReqPrv; /* instead of reqId */
- + MV_CESA_MBUF* pSrc;
- + MV_CESA_MBUF* pDst;
- + MV_CESA_CALLBACK* pFuncCB;
- + MV_16 sessionId;
- + MV_U16 ivFromUser;
- + MV_U16 ivOffset;
- + MV_U16 cryptoOffset;
- + MV_U16 cryptoLength;
- + MV_U16 digestOffset;
- + MV_U16 macOffset;
- + MV_U16 macLength;
- + MV_BOOL skipFlush;
- +} MV_CESA_COMMAND;
- +
- +
- +
- +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, void *osHandle);
- +MV_STATUS mvCesaFinish (void);
- +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid);
- +MV_STATUS mvCesaSessionClose(short sid);
- +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize);
- +
- +MV_STATUS mvCesaAction (MV_CESA_COMMAND* pCmd);
- +
- +MV_U32 mvCesaInProcessGet(void);
- +MV_STATUS mvCesaReadyDispatch(void);
- +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult);
- +MV_BOOL mvCesaIsReady(void);
- +
- +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset);
- +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDst, MV_CESA_MBUF* pSrcMbuf,
- + int offset, int size);
- +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrc, MV_CESA_MBUF* pDstMbuf,
- + int offset, int size);
- +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
- + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size);
- +
- +/********** Debug functions ********/
- +
- +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size);
- +void mvCesaDebugSA(short sid, int mode);
- +void mvCesaDebugStats(void);
- +void mvCesaDebugStatsClear(void);
- +void mvCesaDebugRegs(void);
- +void mvCesaDebugStatus(void);
- +void mvCesaDebugQueue(int mode);
- +void mvCesaDebugSram(int mode);
- +void mvCesaDebugSAD(int mode);
- +
- +
- +/******** CESA Private definitions ********/
- +#if (MV_CESA_VERSION >= 2)
- +#if (MV_CACHE_COHERENCY == MV_CACHE_COHER_SW)
- +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
- + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
- + | MV_CESA_TDMA_OUTSTAND_READ_EN_MASK \
- + | MV_CESA_TDMA_NO_BYTE_SWAP_MASK \
- + | MV_CESA_TDMA_ENABLE_MASK
- +#else
- +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_32B) \
- + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
- + /*| MV_CESA_TDMA_OUTSTAND_READ_EN_MASK */\
- + | MV_CESA_TDMA_ENABLE_MASK
- +
- +#endif
- +#else
- +#define MV_CESA_IDMA_CTRL_LOW_VALUE ICCLR_DST_BURST_LIM_128BYTE \
- + | ICCLR_SRC_BURST_LIM_128BYTE \
- + | ICCLR_INT_MODE_MASK \
- + | ICCLR_BLOCK_MODE \
- + | ICCLR_CHAN_ENABLE \
- + | ICCLR_DESC_MODE_16M
- +#endif /* MV_CESA_VERSION >= 2 */
- +
- +#define MV_CESA_MAX_PKT_SIZE (64 * 1024)
- +#define MV_CESA_MAX_MBUF_FRAGS 20
- +
- +#define MV_CESA_MAX_REQ_FRAGS ( (MV_CESA_MAX_PKT_SIZE / MV_CESA_MAX_BUF_SIZE) + 1)
- +
- +#define MV_CESA_MAX_DMA_DESC (MV_CESA_MAX_MBUF_FRAGS*2 + 5)
- +
- +#define MAX_CESA_CHAIN_LENGTH 20
- +
- +typedef enum
- +{
- + MV_CESA_IDLE = 0,
- + MV_CESA_PENDING,
- + MV_CESA_PROCESS,
- + MV_CESA_READY,
- +#if (MV_CESA_VERSION >= 3)
- + MV_CESA_CHAIN,
- +#endif
- +} MV_CESA_STATE;
- +
- +
- +/* Session database */
- +
- +/* Map of Key materials of the session in SRAM.
- + * Each field must be 8 byte aligned
- + * Total size: 32 + 24 + 24 = 80 bytes
- + */
- +typedef struct
- +{
- + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
- + MV_U8 macInnerIV[MV_CESA_MAX_DIGEST_SIZE];
- + MV_U8 reservedInner[4];
- + MV_U8 macOuterIV[MV_CESA_MAX_DIGEST_SIZE];
- + MV_U8 reservedOuter[4];
- +
- +} MV_CESA_SRAM_SA;
- +
- +typedef struct
- +{
- + MV_CESA_SRAM_SA* pSramSA;
- + MV_U32 config;
- + MV_U8 cryptoKeyLength;
- + MV_U8 cryptoIvSize;
- + MV_U8 cryptoBlockSize;
- + MV_U8 digestSize;
- + MV_U8 macKeyLength;
- + MV_U8 valid;
- + MV_U8 ctrMode;
- + MV_U32 count;
- +
- +} MV_CESA_SA;
- +
- +/* DMA list management */
- +typedef struct
- +{
- + MV_DMA_DESC* pDmaFirst;
- + MV_DMA_DESC* pDmaLast;
- +
- +} MV_CESA_DMA;
- +
- +
- +typedef struct
- +{
- + MV_U8 numFrag;
- + MV_U8 nextFrag;
- + int bufOffset;
- + int cryptoSize;
- + int macSize;
- + int newDigestOffset;
- + MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
- +
- +} MV_CESA_FRAGS;
- +
- +/* Request queue */
- +typedef struct
- +{
- + MV_U8 state;
- + MV_U8 fragMode;
- + MV_U8 fixOffset;
- + MV_CESA_COMMAND* pCmd;
- + MV_CESA_COMMAND* pOrgCmd;
- + MV_BUF_INFO dmaDescBuf;
- + MV_CESA_DMA dma[MV_CESA_MAX_REQ_FRAGS];
- + MV_BUF_INFO cesaDescBuf;
- + MV_CESA_DESC* pCesaDesc;
- + MV_CESA_FRAGS frags;
- +
- +
- +} MV_CESA_REQ;
- +
- +
- +/* SRAM map */
- +/* Total SRAM size calculation */
- +/* SRAM size =
- + * MV_CESA_MAX_BUF_SIZE +
- + * sizeof(MV_CESA_DESC) +
- + * MV_CESA_MAX_IV_LENGTH +
- + * MV_CESA_MAX_IV_LENGTH +
- + * MV_CESA_MAX_DIGEST_SIZE +
- + * sizeof(MV_CESA_SRAM_SA)
- + * = 1600 + 32 + 16 + 16 + 24 + 80 + 280 (reserved) = 2048 bytes
- + * = 3200 + 32 + 16 + 16 + 24 + 80 + 728 (reserved) = 4096 bytes
- + */
- +typedef struct
- +{
- + MV_U8 buf[MV_CESA_MAX_BUF_SIZE];
- + MV_CESA_DESC desc;
- + MV_U8 cryptoIV[MV_CESA_MAX_IV_LENGTH];
- + MV_U8 tempCryptoIV[MV_CESA_MAX_IV_LENGTH];
- + MV_U8 tempDigest[MV_CESA_MAX_DIGEST_SIZE+4];
- + MV_CESA_SRAM_SA sramSA;
- +
- +} MV_CESA_SRAM_MAP;
- +
- +
- +typedef struct
- +{
- + MV_U32 openedCount;
- + MV_U32 closedCount;
- + MV_U32 fragCount;
- + MV_U32 reqCount;
- + MV_U32 maxReqCount;
- + MV_U32 procCount;
- + MV_U32 readyCount;
- + MV_U32 notReadyCount;
- + MV_U32 startCount;
- +#if (MV_CESA_VERSION >= 3)
- + MV_U32 maxChainUsage;
- +#endif
- +
- +} MV_CESA_STATS;
- +
- +
- +/* External variables */
- +
- +extern MV_CESA_STATS cesaStats;
- +extern MV_CESA_FRAGS cesaFrags;
- +
- +extern MV_BUF_INFO cesaSramSaBuf;
- +
- +extern MV_CESA_SA* pCesaSAD;
- +extern MV_U16 cesaMaxSA;
- +
- +extern MV_CESA_REQ* pCesaReqFirst;
- +extern MV_CESA_REQ* pCesaReqLast;
- +extern MV_CESA_REQ* pCesaReqEmpty;
- +extern MV_CESA_REQ* pCesaReqProcess;
- +extern int cesaQueueDepth;
- +extern int cesaReqResources;
- +#if (MV_CESA_VERSION>= 3)
- +extern MV_U32 cesaChainLength;
- +#endif
- +
- +extern MV_CESA_SRAM_MAP* cesaSramVirtPtr;
- +extern MV_U32 cesaSramPhysAddr;
- +
- +static INLINE MV_ULONG mvCesaVirtToPhys(MV_BUF_INFO* pBufInfo, void* pVirt)
- +{
- + return (pBufInfo->bufPhysAddr + ((MV_U8*)pVirt - pBufInfo->bufVirtPtr));
- +}
- +
- +/* Additional DEBUG functions */
- +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode);
- +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode);
- +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc);
- +
- +
- +
- +#endif /* __mvCesa_h__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 2010-11-09 20:28:05.772495441 +0100
- @@ -0,0 +1,357 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __mvCesaRegs_h__
- +#define __mvCesaRegs_h__
- +
- +#include "mvTypes.h"
- +
- +typedef struct
- +{
- + /* word 0 */
- + MV_U32 config;
- + /* word 1 */
- + MV_U16 cryptoSrcOffset;
- + MV_U16 cryptoDstOffset;
- + /* word 2 */
- + MV_U16 cryptoDataLen;
- + MV_U16 reserved1;
- + /* word 3 */
- + MV_U16 cryptoKeyOffset;
- + MV_U16 reserved2;
- + /* word 4 */
- + MV_U16 cryptoIvOffset;
- + MV_U16 cryptoIvBufOffset;
- + /* word 5 */
- + MV_U16 macSrcOffset;
- + MV_U16 macTotalLen;
- + /* word 6 */
- + MV_U16 macDigestOffset;
- + MV_U16 macDataLen;
- + /* word 7 */
- + MV_U16 macInnerIvOffset;
- + MV_U16 macOuterIvOffset;
- +
- +} MV_CESA_DESC;
- +
- +/* operation */
- +typedef enum
- +{
- + MV_CESA_MAC_ONLY = 0,
- + MV_CESA_CRYPTO_ONLY = 1,
- + MV_CESA_MAC_THEN_CRYPTO = 2,
- + MV_CESA_CRYPTO_THEN_MAC = 3,
- +
- + MV_CESA_MAX_OPERATION
- +
- +} MV_CESA_OPERATION;
- +
- +#define MV_CESA_OPERATION_OFFSET 0
- +#define MV_CESA_OPERATION_MASK (0x3 << MV_CESA_OPERATION_OFFSET)
- +
- +/* mac algorithm */
- +typedef enum
- +{
- + MV_CESA_MAC_NULL = 0,
- + MV_CESA_MAC_MD5 = 4,
- + MV_CESA_MAC_SHA1 = 5,
- + MV_CESA_MAC_HMAC_MD5 = 6,
- + MV_CESA_MAC_HMAC_SHA1 = 7,
- +
- +} MV_CESA_MAC_MODE;
- +
- +#define MV_CESA_MAC_MODE_OFFSET 4
- +#define MV_CESA_MAC_MODE_MASK (0x7 << MV_CESA_MAC_MODE_OFFSET)
- +
- +typedef enum
- +{
- + MV_CESA_MAC_DIGEST_FULL = 0,
- + MV_CESA_MAC_DIGEST_96B = 1,
- +
- +} MV_CESA_MAC_DIGEST_SIZE;
- +
- +#define MV_CESA_MAC_DIGEST_SIZE_BIT 7
- +#define MV_CESA_MAC_DIGEST_SIZE_MASK (1 << MV_CESA_MAC_DIGEST_SIZE_BIT)
- +
- +
- +typedef enum
- +{
- + MV_CESA_CRYPTO_NULL = 0,
- + MV_CESA_CRYPTO_DES = 1,
- + MV_CESA_CRYPTO_3DES = 2,
- + MV_CESA_CRYPTO_AES = 3,
- +
- +} MV_CESA_CRYPTO_ALG;
- +
- +#define MV_CESA_CRYPTO_ALG_OFFSET 8
- +#define MV_CESA_CRYPTO_ALG_MASK (0x3 << MV_CESA_CRYPTO_ALG_OFFSET)
- +
- +
- +/* direction */
- +typedef enum
- +{
- + MV_CESA_DIR_ENCODE = 0,
- + MV_CESA_DIR_DECODE = 1,
- +
- +} MV_CESA_DIRECTION;
- +
- +#define MV_CESA_DIRECTION_BIT 12
- +#define MV_CESA_DIRECTION_MASK (1 << MV_CESA_DIRECTION_BIT)
- +
- +/* crypto IV mode */
- +typedef enum
- +{
- + MV_CESA_CRYPTO_ECB = 0,
- + MV_CESA_CRYPTO_CBC = 1,
- +
- + /* NO HW Support */
- + MV_CESA_CRYPTO_CTR = 10,
- +
- +} MV_CESA_CRYPTO_MODE;
- +
- +#define MV_CESA_CRYPTO_MODE_BIT 16
- +#define MV_CESA_CRYPTO_MODE_MASK (1 << MV_CESA_CRYPTO_MODE_BIT)
- +
- +/* 3DES mode */
- +typedef enum
- +{
- + MV_CESA_CRYPTO_3DES_EEE = 0,
- + MV_CESA_CRYPTO_3DES_EDE = 1,
- +
- +} MV_CESA_CRYPTO_3DES_MODE;
- +
- +#define MV_CESA_CRYPTO_3DES_MODE_BIT 20
- +#define MV_CESA_CRYPTO_3DES_MODE_MASK (1 << MV_CESA_CRYPTO_3DES_MODE_BIT)
- +
- +
- +/* AES Key Length */
- +typedef enum
- +{
- + MV_CESA_CRYPTO_AES_KEY_128 = 0,
- + MV_CESA_CRYPTO_AES_KEY_192 = 1,
- + MV_CESA_CRYPTO_AES_KEY_256 = 2,
- +
- +} MV_CESA_CRYPTO_AES_KEY_LEN;
- +
- +#define MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET 24
- +#define MV_CESA_CRYPTO_AES_KEY_LEN_MASK (0x3 << MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET)
- +
- +/* Fragmentation mode */
- +typedef enum
- +{
- + MV_CESA_FRAG_NONE = 0,
- + MV_CESA_FRAG_FIRST = 1,
- + MV_CESA_FRAG_LAST = 2,
- + MV_CESA_FRAG_MIDDLE = 3,
- +
- +} MV_CESA_FRAG_MODE;
- +
- +#define MV_CESA_FRAG_MODE_OFFSET 30
- +#define MV_CESA_FRAG_MODE_MASK (0x3 << MV_CESA_FRAG_MODE_OFFSET)
- +/*---------------------------------------------------------------------------*/
- +
- +/********** Security Accelerator Command Register **************/
- +#define MV_CESA_CMD_REG (MV_CESA_REG_BASE + 0xE00)
- +
- +#define MV_CESA_CMD_CHAN_ENABLE_BIT 0
- +#define MV_CESA_CMD_CHAN_ENABLE_MASK (1 << MV_CESA_CMD_CHAN_ENABLE_BIT)
- +
- +#define MV_CESA_CMD_CHAN_DISABLE_BIT 2
- +#define MV_CESA_CMD_CHAN_DISABLE_MASK (1 << MV_CESA_CMD_CHAN_DISABLE_BIT)
- +
- +/********** Security Accelerator Descriptor Pointers Register **********/
- +#define MV_CESA_CHAN_DESC_OFFSET_REG (MV_CESA_REG_BASE + 0xE04)
- +
- +/********** Security Accelerator Configuration Register **********/
- +#define MV_CESA_CFG_REG (MV_CESA_REG_BASE + 0xE08)
- +
- +#define MV_CESA_CFG_STOP_DIGEST_ERR_BIT 0
- +#define MV_CESA_CFG_STOP_DIGEST_ERR_MASK (1 << MV_CESA_CFG_STOP_DIGEST_ERR_BIT)
- +
- +#define MV_CESA_CFG_WAIT_DMA_BIT 7
- +#define MV_CESA_CFG_WAIT_DMA_MASK (1 << MV_CESA_CFG_WAIT_DMA_BIT)
- +
- +#define MV_CESA_CFG_ACT_DMA_BIT 9
- +#define MV_CESA_CFG_ACT_DMA_MASK (1 << MV_CESA_CFG_ACT_DMA_BIT)
- +
- +#define MV_CESA_CFG_CHAIN_MODE_BIT 11
- +#define MV_CESA_CFG_CHAIN_MODE_MASK (1 << MV_CESA_CFG_CHAIN_MODE_BIT)
- +
- +/********** Security Accelerator Status Register ***********/
- +#define MV_CESA_STATUS_REG (MV_CESA_REG_BASE + 0xE0C)
- +
- +#define MV_CESA_STATUS_ACTIVE_BIT 0
- +#define MV_CESA_STATUS_ACTIVE_MASK (1 << MV_CESA_STATUS_ACTIVE_BIT)
- +
- +#define MV_CESA_STATUS_DIGEST_ERR_BIT 8
- +#define MV_CESA_STATUS_DIGEST_ERR_MASK (1 << MV_CESA_STATUS_DIGEST_ERR_BIT)
- +
- +
- +/* Cryptographic Engines and Security Accelerator Interrupt Cause Register */
- +#define MV_CESA_ISR_CAUSE_REG (MV_CESA_REG_BASE + 0xE20)
- +
- +/* Cryptographic Engines and Security Accelerator Interrupt Mask Register */
- +#define MV_CESA_ISR_MASK_REG (MV_CESA_REG_BASE + 0xE24)
- +
- +#define MV_CESA_CAUSE_AUTH_MASK (1 << 0)
- +#define MV_CESA_CAUSE_DES_MASK (1 << 1)
- +#define MV_CESA_CAUSE_AES_ENCR_MASK (1 << 2)
- +#define MV_CESA_CAUSE_AES_DECR_MASK (1 << 3)
- +#define MV_CESA_CAUSE_DES_ALL_MASK (1 << 4)
- +
- +#define MV_CESA_CAUSE_ACC_BIT 5
- +#define MV_CESA_CAUSE_ACC_MASK (1 << MV_CESA_CAUSE_ACC_BIT)
- +
- +#define MV_CESA_CAUSE_ACC_DMA_BIT 7
- +#define MV_CESA_CAUSE_ACC_DMA_MASK (1 << MV_CESA_CAUSE_ACC_DMA_BIT)
- +#define MV_CESA_CAUSE_ACC_DMA_ALL_MASK (3 << MV_CESA_CAUSE_ACC_DMA_BIT)
- +
- +#define MV_CESA_CAUSE_DMA_COMPL_BIT 9
- +#define MV_CESA_CAUSE_DMA_COMPL_MASK (1 << MV_CESA_CAUSE_DMA_COMPL_BIT)
- +
- +#define MV_CESA_CAUSE_DMA_OWN_ERR_BIT 10
- +#define MV_CESA_CAUSE_DMA_OWN_ERR_MASK (1 < MV_CESA_CAUSE_DMA_OWN_ERR_BIT)
- +
- +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT 11
- +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_MASK (1 < MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT)
- +
- +
- +#define MV_CESA_AUTH_DATA_IN_REG (MV_CESA_REG_BASE + 0xd38)
- +#define MV_CESA_AUTH_BIT_COUNT_LOW_REG (MV_CESA_REG_BASE + 0xd20)
- +#define MV_CESA_AUTH_BIT_COUNT_HIGH_REG (MV_CESA_REG_BASE + 0xd24)
- +
- +#define MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i) (MV_CESA_REG_BASE + 0xd00 + (i<<2))
- +
- +#define MV_CESA_AUTH_INIT_VAL_DIGEST_A_REG (MV_CESA_REG_BASE + 0xd00)
- +#define MV_CESA_AUTH_INIT_VAL_DIGEST_B_REG (MV_CESA_REG_BASE + 0xd04)
- +#define MV_CESA_AUTH_INIT_VAL_DIGEST_C_REG (MV_CESA_REG_BASE + 0xd08)
- +#define MV_CESA_AUTH_INIT_VAL_DIGEST_D_REG (MV_CESA_REG_BASE + 0xd0c)
- +#define MV_CESA_AUTH_INIT_VAL_DIGEST_E_REG (MV_CESA_REG_BASE + 0xd10)
- +#define MV_CESA_AUTH_COMMAND_REG (MV_CESA_REG_BASE + 0xd18)
- +
- +#define MV_CESA_AUTH_ALGORITHM_BIT 0
- +#define MV_CESA_AUTH_ALGORITHM_MD5 (0<<AUTH_ALGORITHM_BIT)
- +#define MV_CESA_AUTH_ALGORITHM_SHA1 (1<<AUTH_ALGORITHM_BIT)
- +
- +#define MV_CESA_AUTH_IV_MODE_BIT 1
- +#define MV_CESA_AUTH_IV_MODE_INIT (0<<AUTH_IV_MODE_BIT)
- +#define MV_CESA_AUTH_IV_MODE_CONTINUE (1<<AUTH_IV_MODE_BIT)
- +
- +#define MV_CESA_AUTH_DATA_BYTE_SWAP_BIT 2
- +#define MV_CESA_AUTH_DATA_BYTE_SWAP_MASK (1<<AUTH_DATA_BYTE_SWAP_BIT)
- +
- +
- +#define MV_CESA_AUTH_IV_BYTE_SWAP_BIT 4
- +#define MV_CESA_AUTH_IV_BYTE_SWAP_MASK (1<<AUTH_IV_BYTE_SWAP_BIT)
- +
- +#define MV_CESA_AUTH_TERMINATION_BIT 31
- +#define MV_CESA_AUTH_TERMINATION_MASK (1<<AUTH_TERMINATION_BIT)
- +
- +
- +/*************** TDMA Control Register ************************************************/
- +#define MV_CESA_TDMA_CTRL_REG (MV_CESA_TDMA_REG_BASE + 0x840)
- +
- +#define MV_CESA_TDMA_BURST_32B 3
- +#define MV_CESA_TDMA_BURST_128B 4
- +
- +#define MV_CESA_TDMA_DST_BURST_OFFSET 0
- +#define MV_CESA_TDMA_DST_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_DST_BURST_OFFSET)
- +#define MV_CESA_TDMA_DST_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_DST_BURST_OFFSET)
- +
- +#define MV_CESA_TDMA_OUTSTAND_READ_EN_BIT 4
- +#define MV_CESA_TDMA_OUTSTAND_READ_EN_MASK (1<<MV_CESA_TDMA_OUTSTAND_READ_EN_BIT)
- +
- +#define MV_CESA_TDMA_SRC_BURST_OFFSET 6
- +#define MV_CESA_TDMA_SRC_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_SRC_BURST_OFFSET)
- +#define MV_CESA_TDMA_SRC_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_SRC_BURST_OFFSET)
- +
- +#define MV_CESA_TDMA_CHAIN_MODE_BIT 9
- +#define MV_CESA_TDMA_NON_CHAIN_MODE_MASK (1<<MV_CESA_TDMA_CHAIN_MODE_BIT)
- +
- +#define MV_CESA_TDMA_BYTE_SWAP_BIT 11
- +#define MV_CESA_TDMA_BYTE_SWAP_MASK (0 << MV_CESA_TDMA_BYTE_SWAP_BIT)
- +#define MV_CESA_TDMA_NO_BYTE_SWAP_MASK (1 << MV_CESA_TDMA_BYTE_SWAP_BIT)
- +
- +#define MV_CESA_TDMA_ENABLE_BIT 12
- +#define MV_CESA_TDMA_ENABLE_MASK (1<<MV_CESA_TDMA_ENABLE_BIT)
- +
- +#define MV_CESA_TDMA_FETCH_NEXT_DESC_BIT 13
- +#define MV_CESA_TDMA_FETCH_NEXT_DESC_MASK (1<<MV_CESA_TDMA_FETCH_NEXT_DESC_BIT)
- +
- +#define MV_CESA_TDMA_CHAN_ACTIVE_BIT 14
- +#define MV_CESA_TDMA_CHAN_ACTIVE_MASK (1<<MV_CESA_TDMA_CHAN_ACTIVE_BIT)
- +/*------------------------------------------------------------------------------------*/
- +
- +#define MV_CESA_TDMA_BYTE_COUNT_REG (MV_CESA_TDMA_REG_BASE + 0x800)
- +#define MV_CESA_TDMA_SRC_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x810)
- +#define MV_CESA_TDMA_DST_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x820)
- +#define MV_CESA_TDMA_NEXT_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x830)
- +#define MV_CESA_TDMA_CURR_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x870)
- +
- +#define MV_CESA_TDMA_ERROR_CAUSE_REG (MV_CESA_TDMA_REG_BASE + 0x8C0)
- +#define MV_CESA_TDMA_ERROR_MASK_REG (MV_CESA_TDMA_REG_BASE + 0x8C4)
- +
- +
- +#endif /* __mvCesaRegs_h__ */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaTest.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaTest.c 2010-11-09 20:28:05.782495527 +0100
- @@ -0,0 +1,3096 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvOs.h"
- +
- +#if defined(MV_VXWORKS)
- +
- +#include "sysLib.h"
- +#include "logLib.h"
- +#include "tickLib.h"
- +#include "intLib.h"
- +#include "config.h"
- +
- +
- +SEM_ID cesaSemId = NULL;
- +SEM_ID cesaWaitSemId = NULL;
- +
- +#define CESA_TEST_LOCK(flags) flags = intLock()
- +#define CESA_TEST_UNLOCK(flags) intUnlock(flags)
- +
- +#define CESA_TEST_WAIT_INIT() cesaWaitSemId = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)
- +#define CESA_TEST_WAKE_UP() semGive(cesaWaitSemId)
- +#define CESA_TEST_WAIT(cond, ms) semTake(cesaWaitSemId, (sysClkRateGet()*ms)/1000)
- +
- +#define CESA_TEST_TICK_GET() tickGet()
- +#define CESA_TEST_TICK_TO_MS(tick) (((tick)*1000)/sysClkRateGet())
- +
- +#elif defined(MV_LINUX)
- +
- +#include <linux/wait.h>
- +wait_queue_head_t cesaTest_waitq;
- +spinlock_t cesaLock;
- +
- +#define CESA_TEST_LOCK(flags) spin_lock_irqsave( &cesaLock, flags)
- +#define CESA_TEST_UNLOCK(flags) spin_unlock_irqrestore( &cesaLock, flags);
- +
- +#define CESA_TEST_WAIT_INIT() init_waitqueue_head(&cesaTest_waitq)
- +#define CESA_TEST_WAKE_UP() wake_up(&cesaTest_waitq)
- +#define CESA_TEST_WAIT(cond, ms) wait_event_timeout(cesaTest_waitq, (cond), msecs_to_jiffies(ms))
- +
- +#define CESA_TEST_TICK_GET() jiffies
- +#define CESA_TEST_TICK_TO_MS(tick) jiffies_to_msecs(tick)
- +
- +#elif defined(MV_NETBSD)
- +
- +#include <sys/param.h>
- +#include <sys/kernel.h>
- +static int cesaLock;
- +
- +#define CESA_TEST_LOCK(flags) flags = splnet()
- +#define CESA_TEST_UNLOCK(flags) splx(flags)
- +
- +#define CESA_TEST_WAIT_INIT() /* nothing */
- +#define CESA_TEST_WAKE_UP() wakeup(&cesaLock)
- +#define CESA_TEST_WAIT(cond, ms) \
- +do { \
- + while (!(cond)) \
- + tsleep(&cesaLock, PWAIT, "cesatest",mstohz(ms)); \
- +} while (/*CONSTCOND*/0)
- +
- +#define CESA_TEST_TICK_GET() hardclock_ticks
- +#define CESA_TEST_TICK_TO_MS(tick) ((1000/hz)*(tick))
- +
- +#define request_irq(i,h,t,n,a) \
- + !mv_intr_establish((i),IPL_NET,(int(*)(void *))(h),(a))
- +
- +#else
- +#error "Only Linux, VxWorks, or NetBSD OS are supported"
- +#endif
- +
- +#include "mvDebug.h"
- +
- +#include "mvSysHwConfig.h"
- +#include "boardEnv/mvBoardEnvLib.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "cntmr/mvCntmr.h"
- +#include "cesa/mvCesa.h"
- +#include "cesa/mvCesaRegs.h"
- +#include "cesa/mvMD5.h"
- +#include "cesa/mvSHA1.h"
- +
- +#if defined(CONFIG_MV646xx)
- +#include "marvell_pic.h"
- +#endif
- +
- +#define MV_CESA_USE_TIMER_ID 0
- +#define CESA_DEF_BUF_SIZE 1500
- +#define CESA_DEF_BUF_NUM 1
- +#define CESA_DEF_SESSION_NUM 32
- +
- +#define CESA_DEF_ITER_NUM 100
- +
- +#define CESA_DEF_REQ_SIZE 256
- +
- +
- +/* CESA Tests Debug */
- +#undef CESA_TEST_DEBUG
- +
- +#ifdef CESA_TEST_DEBUG
- +
- +# define CESA_TEST_DEBUG_PRINT(msg) mvOsPrintf msg
- +# define CESA_TEST_DEBUG_CODE(code) code
- +
- +typedef struct
- +{
- + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
- + MV_U32 timeStamp;
- + MV_U32 cause;
- + MV_U32 realCause;
- + MV_U32 dmaCause;
- + int resources;
- + MV_CESA_REQ* pReqReady;
- + MV_CESA_REQ* pReqEmpty;
- + MV_CESA_REQ* pReqProcess;
- +} MV_CESA_TEST_TRACE;
- +
- +#define MV_CESA_TEST_TRACE_SIZE 25
- +
- +static int cesaTestTraceIdx = 0;
- +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
- +
- +static void cesaTestTraceAdd(int type, MV_U32 cause)
- +{
- + cesaTestTrace[cesaTestTraceIdx].type = type;
- + cesaTestTrace[cesaTestTraceIdx].cause = cause;
- + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
- + cesaTestTrace[cesaTestTraceIdx].dmaCause = MV_REG_READ(IDMA_CAUSE_REG);
- + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
- + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
- + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
- + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
- + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
- + cesaTestTraceIdx++;
- + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
- + cesaTestTraceIdx = 0;
- +}
- +
- +#else
- +
- +# define CESA_TEST_DEBUG_PRINT(msg)
- +# define CESA_TEST_DEBUG_CODE(code)
- +
- +#endif /* CESA_TEST_DEBUG */
- +
- +int cesaExpReqId=0;
- +int cesaCbIter=0;
- +
- +int cesaIdx;
- +int cesaIteration;
- +int cesaRateSize;
- +int cesaReqSize;
- +unsigned long cesaTaskId;
- +int cesaBufNum;
- +int cesaBufSize;
- +int cesaCheckOffset;
- +int cesaCheckSize;
- +int cesaCheckMode;
- +int cesaTestIdx;
- +int cesaCaseIdx;
- +
- +
- +MV_U32 cesaTestIsrCount = 0;
- +MV_U32 cesaTestIsrMissCount = 0;
- +
- +MV_U32 cesaCryptoError = 0;
- +MV_U32 cesaReqIdError = 0;
- +MV_U32 cesaError = 0;
- +
- +char* cesaHexBuffer = NULL;
- +
- +char* cesaBinBuffer = NULL;
- +char* cesaExpBinBuffer = NULL;
- +
- +char* cesaInputHexStr = NULL;
- +char* cesaOutputHexStr = NULL;
- +
- +MV_BUF_INFO cesaReqBufs[CESA_DEF_REQ_SIZE];
- +
- +MV_CESA_COMMAND* cesaCmdRing;
- +MV_CESA_RESULT cesaResult;
- +
- +int cesaTestFull = 0;
- +
- +MV_BOOL cesaIsReady = MV_FALSE;
- +MV_U32 cesaCycles = 0;
- +MV_U32 cesaBeginTicks = 0;
- +MV_U32 cesaEndTicks = 0;
- +MV_U32 cesaRate = 0;
- +MV_U32 cesaRateAfterDot = 0;
- +
- +void *cesaTestOSHandle = NULL;
- +
- +enum
- +{
- + CESA_FAST_CHECK_MODE = 0,
- + CESA_FULL_CHECK_MODE,
- + CESA_NULL_CHECK_MODE,
- + CESA_SHOW_CHECK_MODE,
- + CESA_SW_SHOW_CHECK_MODE,
- + CESA_SW_NULL_CHECK_MODE,
- +
- + CESA_MAX_CHECK_MODE
- +};
- +
- +enum
- +{
- + DES_TEST_TYPE = 0,
- + TRIPLE_DES_TEST_TYPE = 1,
- + AES_TEST_TYPE = 2,
- + MD5_TEST_TYPE = 3,
- + SHA_TEST_TYPE = 4,
- + COMBINED_TEST_TYPE = 5,
- +
- + MAX_TEST_TYPE
- +};
- +
- +/* Tests data base */
- +typedef struct
- +{
- + short sid;
- + char cryptoAlgorithm; /* DES/3DES/AES */
- + char cryptoMode; /* ECB or CBC */
- + char macAlgorithm; /* MD5 / SHA1 */
- + char operation; /* CRYPTO/HMAC/CRYPTO+HMAC/HMAC+CRYPTO */
- + char direction; /* ENCODE(SIGN)/DECODE(VERIFY) */
- + unsigned char* pCryptoKey;
- + int cryptoKeySize;
- + unsigned char* pMacKey;
- + int macKeySize;
- + const char* name;
- +
- +} MV_CESA_TEST_SESSION;
- +
- +typedef struct
- +{
- + MV_CESA_TEST_SESSION* pSessions;
- + int numSessions;
- +
- +} MV_CESA_TEST_DB_ENTRY;
- +
- +typedef struct
- +{
- + char* plainHexStr;
- + char* cipherHexStr;
- + unsigned char* pCryptoIV;
- + int cryptoLength;
- + int macLength;
- + int digestOffset;
- +
- +} MV_CESA_TEST_CASE;
- +
- +typedef struct
- +{
- + int size;
- + const char* outputHexStr;
- +
- +} MV_CESA_SIZE_TEST;
- +
- +static unsigned char cryptoKey1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
- + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
- + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
- +
- +static unsigned char cryptoKey7[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
- +static unsigned char iv1[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
- +
- +
- +static unsigned char cryptoKey2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
- +
- +static unsigned char cryptoKey3[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
- +
- +static unsigned char cryptoKey4[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
- +
- +static unsigned char cryptoKey5[] = {0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74,
- + 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49};
- +
- +
- +static unsigned char key3des1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
- + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
- + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23};
- +
- +/* Input ASCII string: The quick brown fox jump */
- +static char plain3des1[] = "54686520717566636B2062726F776E20666F78206A756D70";
- +static char cipher3des1[] = "A826FD8CE53B855FCCE21C8112256FE668D5C05DD9B6B900";
- +
- +static unsigned char key3des2[] = {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10,
- + 0x43, 0xcd, 0x26, 0x5d, 0x58, 0x40, 0xea, 0xf1,
- + 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c};
- +
- +static unsigned char iv3des2[] = {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75};
- +
- +static char plain3des2[] = "326a494cd33fe756";
- +
- +static char cipher3desCbc2[] = "8e29f75ea77e5475"
- + "b22b8d66de970692";
- +
- +static unsigned char key3des3[] = {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc,
- + 0x07, 0x54, 0xb9, 0x4f, 0x31, 0xcb, 0xb3, 0x85,
- + 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae};
- +
- +static unsigned char iv3des3[] = {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65};
- +
- +static char plain3des3[] = "84401f78fe6c10876d8ea23094ea5309";
- +
- +static char cipher3desCbc3[] = "3d1de3cc132e3b65"
- + "7b1f7c7e3b1c948ebd04a75ffba7d2f5";
- +
- +static unsigned char iv5[] = {0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c,
- + 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9};
- +
- +static unsigned char aesCtrKey[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
- + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
- +
- +static unsigned char mdKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
- +
- +static unsigned char mdKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
- +
- +static unsigned char shaKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- + 0x0b, 0x0b, 0x0b, 0x0b};
- +
- +static unsigned char shaKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- + 0xaa, 0xaa, 0xaa, 0xaa};
- +
- +static unsigned char mdKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
- +
- +static unsigned char shaKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- + 0x11, 0x12, 0x13, 0x14};
- +
- +
- +static MV_CESA_TEST_SESSION desTestSessions[] =
- +{
- +/*000*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
- + NULL, 0,
- + "DES ECB encode",
- + },
- +/*001*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
- + NULL, 0,
- + "DES ECB decode",
- + },
- +/*002*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
- + NULL, 0,
- + "DES CBC encode"
- + },
- +/*003*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
- + NULL, 0,
- + "DES CBC decode"
- + },
- +/*004*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0, NULL, 0,
- + "NULL Crypto Algorithm encode"
- + },
- +};
- +
- +
- +static MV_CESA_TEST_SESSION tripleDesTestSessions[] =
- +{
- +/*100*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + NULL, 0,
- + "3DES ECB encode",
- + },
- +/*101*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + NULL, 0,
- + "3DES ECB decode",
- + },
- +/*102*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + NULL, 0,
- + "3DES CBC encode"
- + },
- +/*103*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + NULL, 0,
- + "3DES CBC decode"
- + },
- +/*104*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + key3des1, sizeof(key3des1),
- + NULL, 0,
- + "3DES ECB encode"
- + },
- +/*105*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + key3des2, sizeof(key3des2),
- + NULL, 0,
- + "3DES ECB encode"
- + },
- +/*106*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + key3des3, sizeof(key3des3),
- + NULL, 0,
- + "3DES ECB encode"
- + },
- +};
- +
- +
- +static MV_CESA_TEST_SESSION aesTestSessions[] =
- +{
- +/*200*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
- + NULL, 0,
- + "AES-128 ECB encode"
- + },
- +/*201*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
- + NULL, 0,
- + "AES-128 ECB decode"
- + },
- +/*202*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
- + NULL, 0,
- + "AES-128 CBC encode"
- + },
- +/*203*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
- + NULL, 0,
- + "AES-128 CBC decode"
- + },
- +/*204*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
- + NULL, 0,
- + "AES-192 ECB encode"
- + },
- +/*205*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
- + NULL, 0,
- + "AES-192 ECB decode"
- + },
- +/*206*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
- + NULL, 0,
- + "AES-256 ECB encode"
- + },
- +/*207*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_DECODE,
- + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
- + NULL, 0,
- + "AES-256 ECB decode"
- + },
- +/*208*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CTR,
- + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
- + MV_CESA_DIR_ENCODE,
- + aesCtrKey, sizeof(aesCtrKey)/sizeof(aesCtrKey[0]),
- + NULL, 0,
- + "AES-128 CTR encode"
- + },
- +};
- +
- +
- +static MV_CESA_TEST_SESSION md5TestSessions[] =
- +{
- +/*300*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + mdKey1, sizeof(mdKey1),
- + "HMAC-MD5 Generate Signature"
- + },
- +/*301*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_DECODE,
- + NULL, 0,
- + mdKey1, sizeof(mdKey1),
- + "HMAC-MD5 Verify Signature"
- + },
- +/*302*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + mdKey2, sizeof(mdKey2),
- + "HMAC-MD5 Generate Signature"
- + },
- +/*303*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_DECODE,
- + NULL, 0,
- + mdKey2, sizeof(mdKey2),
- + "HMAC-MD5 Verify Signature"
- + },
- +/*304*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + mdKey4, sizeof(mdKey4),
- + "HMAC-MD5 Generate Signature"
- + },
- +/*305*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_MD5, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + NULL, 0,
- + "HASH-MD5 Generate Signature"
- + },
- +};
- +
- +
- +static MV_CESA_TEST_SESSION shaTestSessions[] =
- +{
- +/*400*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + shaKey1, sizeof(shaKey1),
- + "HMAC-SHA1 Generate Signature"
- + },
- +/*401*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_DECODE,
- + NULL, 0,
- + shaKey1, sizeof(shaKey1),
- + "HMAC-SHA1 Verify Signature"
- + },
- +/*402*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + shaKey2, sizeof(shaKey2),
- + "HMAC-SHA1 Generate Signature"
- + },
- +/*403*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_DECODE,
- + NULL, 0,
- + shaKey2, sizeof(shaKey2),
- + "HMAC-SHA1 Verify Signature"
- + },
- +/*404*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + shaKey4, sizeof(shaKey4),
- + "HMAC-SHA1 Generate Signature"
- + },
- +/*405*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_SHA1, MV_CESA_MAC_ONLY,
- + MV_CESA_DIR_ENCODE,
- + NULL, 0,
- + NULL, 0,
- + "HASH-SHA1 Generate Signature"
- + },
- +};
- +
- +static MV_CESA_TEST_SESSION combinedTestSessions[] =
- +{
- +/*500*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
- + mdKey4, sizeof(mdKey4),
- + "DES + MD5 encode"
- + },
- +/*501*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
- + shaKey4, sizeof(shaKey4),
- + "DES + SHA1 encode"
- + },
- +/*502*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + mdKey4, sizeof(mdKey4),
- + "3DES + MD5 encode"
- + },
- +/*503*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + shaKey4, sizeof(shaKey4),
- + "3DES + SHA1 encode"
- + },
- +/*504*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + mdKey4, sizeof(mdKey4),
- + "3DES CBC + MD5 encode"
- + },
- +/*505*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + shaKey4, sizeof(shaKey4),
- + "3DES CBC + SHA1 encode"
- + },
- +/*506*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
- + mdKey4, sizeof(mdKey4),
- + "AES-128 CBC + MD5 encode"
- + },
- +/*507*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
- + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
- + MV_CESA_DIR_ENCODE,
- + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
- + shaKey4, sizeof(shaKey4),
- + "AES-128 CBC + SHA1 encode"
- + },
- +/*508*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
- + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_THEN_CRYPTO,
- + MV_CESA_DIR_DECODE,
- + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
- + mdKey4, sizeof(mdKey4),
- + "HMAC-MD5 + 3DES decode"
- + },
- +};
- +
- +
- +static MV_CESA_TEST_DB_ENTRY cesaTestsDB[MAX_TEST_TYPE+1] =
- +{
- + { desTestSessions, sizeof(desTestSessions)/sizeof(desTestSessions[0]) },
- + { tripleDesTestSessions, sizeof(tripleDesTestSessions)/sizeof(tripleDesTestSessions[0]) },
- + { aesTestSessions, sizeof(aesTestSessions)/sizeof(aesTestSessions[0]) },
- + { md5TestSessions, sizeof(md5TestSessions)/sizeof(md5TestSessions[0]) },
- + { shaTestSessions, sizeof(shaTestSessions)/sizeof(shaTestSessions[0]) },
- + { combinedTestSessions, sizeof(combinedTestSessions)/sizeof(combinedTestSessions[0]) },
- + { NULL, 0 }
- +};
- +
- +
- +char cesaNullPlainHexText[] = "000000000000000000000000000000000000000000000000";
- +
- +char cesaPlainAsciiText[] = "Now is the time for all ";
- +char cesaPlainHexEbc[] = "4e6f77206973207468652074696d6520666f7220616c6c20";
- +char cesaCipherHexEcb[] = "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53";
- +char cesaPlainHexCbc[] = "1234567890abcdef4e6f77206973207468652074696d6520666f7220616c6c20";
- +char cesaCipherHexCbc[] = "1234567890abcdefe5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";
- +
- +char cesaAesPlainHexEcb[] = "000102030405060708090a0b0c0d0e0f";
- +char cesaAes128cipherHexEcb[] = "0a940bb5416ef045f1c39458c653ea5a";
- +char cesaAes192cipherHexEcb[] = "0060bffe46834bb8da5cf9a61ff220ae";
- +char cesaAes256cipherHexEcb[] = "5a6e045708fb7196f02e553d02c3a692";
- +
- +char cesaAsciiStr1[] = "Hi There";
- +char cesaDataHexStr1[] = "4869205468657265";
- +char cesaHmacMd5digestHex1[] = "9294727a3638bb1c13f48ef8158bfc9d";
- +char cesaHmacSha1digestHex1[] = "b617318655057264e28bc0b6fb378c8ef146be00";
- +char cesaDataAndMd5digest1[] = "48692054686572659294727a3638bb1c13f48ef8158bfc9d";
- +char cesaDataAndSha1digest1[] = "4869205468657265b617318655057264e28bc0b6fb378c8ef146be00";
- +
- +char cesaAesPlainText[] = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
- + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
- + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
- + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
- +
- +char cesaAes128CipherCbc[] = "c30e32ffedc0774e6aff6af0869f71aa"
- + "0f3af07a9a31a9c684db207eb0ef8e4e"
- + "35907aa632c3ffdf868bb7b29d3d46ad"
- + "83ce9f9a102ee99d49a53e87f4c3da55";
- +
- +char cesaAesIvPlainText[] = "8ce82eefbea0da3c44699ed7db51b7d9"
- + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
- + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
- + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
- + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
- +
- +char cesaAes128IvCipherCbc[] = "8ce82eefbea0da3c44699ed7db51b7d9"
- + "c30e32ffedc0774e6aff6af0869f71aa"
- + "0f3af07a9a31a9c684db207eb0ef8e4e"
- + "35907aa632c3ffdf868bb7b29d3d46ad"
- + "83ce9f9a102ee99d49a53e87f4c3da55";
- +
- +char cesaAesCtrPlain[] = "00E0017B27777F3F4A1786F000000001"
- + "000102030405060708090A0B0C0D0E0F"
- + "101112131415161718191A1B1C1D1E1F"
- + "20212223";
- +
- +char cesaAesCtrCipher[] = "00E0017B27777F3F4A1786F000000001"
- + "C1CF48A89F2FFDD9CF4652E9EFDB72D7"
- + "4540A42BDE6D7836D59A5CEAAEF31053"
- + "25B2072F";
- +
- +
- +
- +/* Input cesaHmacHex3 is '0xdd' repeated 50 times */
- +char cesaHmacMd5digestHex3[] = "56be34521d144c88dbb8c733f0e8b3f6";
- +char cesaHmacSha1digestHex3[] = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";
- +char cesaDataHexStr3[50*2+1] = "";
- +char cesaDataAndMd5digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacMd5digestHex3)+8*2+1] = "";
- +char cesaDataAndSha1digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacSha1digestHex3)+8*2+1] = "";
- +
- +/* Ascii string is "abc" */
- +char hashHexStr3[] = "616263";
- +char hashMd5digest3[] = "900150983cd24fb0d6963f7d28e17f72";
- +char hashSha1digest3[] = "a9993e364706816aba3e25717850c26c9cd0d89d";
- +
- +char hashHexStr80[] = "31323334353637383930"
- + "31323334353637383930"
- + "31323334353637383930"
- + "31323334353637383930"
- + "31323334353637383930"
- + "31323334353637383930"
- + "31323334353637383930"
- + "31323334353637383930";
- +
- +char hashMd5digest80[] = "57edf4a22be3c955ac49da2e2107b67a";
- +
- +char tripleDesThenMd5digest80[] = "b7726a03aad490bd6c5a452a89a1b271";
- +char tripleDesThenSha1digest80[] = "b2ddeaca91030eab5b95a234ef2c0f6e738ff883";
- +
- +char cbc3desThenMd5digest80[] = "6f463057e1a90e0e91ae505b527bcec0";
- +char cbc3desThenSha1digest80[] = "1b002ed050be743aa98860cf35659646bb8efcc0";
- +
- +char cbcAes128ThenMd5digest80[] = "6b6e863ac5a71d15e3e9b1c86c9ba05f";
- +char cbcAes128ThenSha1digest80[] = "13558472d1fc1c90dffec6e5136c7203452d509b";
- +
- +
- +static MV_CESA_TEST_CASE cesaTestCases[] =
- +{
- + /* plainHexStr cipherHexStr IV crypto mac digest */
- + /* Length Length Offset */
- + /*0*/ { NULL, NULL, NULL, 0, 0, -1 },
- + /*1*/ { cesaPlainHexEbc, cesaCipherHexEcb, NULL, 24, 0, -1 },
- + /*2*/ { cesaPlainHexCbc, cesaCipherHexCbc, NULL, 24, 0, -1 },
- + /*3*/ { cesaAesPlainHexEcb, cesaAes128cipherHexEcb, NULL, 16, 0, -1 },
- + /*4*/ { cesaAesPlainHexEcb, cesaAes192cipherHexEcb, NULL, 16, 0, -1 },
- + /*5*/ { cesaAesPlainHexEcb, cesaAes256cipherHexEcb, NULL, 16, 0, -1 },
- + /*6*/ { cesaDataHexStr1, cesaHmacMd5digestHex1, NULL, 0, 8, -1 },
- + /*7*/ { NULL, cesaDataAndMd5digest1, NULL, 0, 8, -1 },
- + /*8*/ { cesaDataHexStr3, cesaHmacMd5digestHex3, NULL, 0, 50, -1 },
- + /*9*/ { NULL, cesaDataAndMd5digest3, NULL, 0, 50, -1 },
- +/*10*/ { cesaAesPlainText, cesaAes128IvCipherCbc, iv5, 64, 0, -1 },
- +/*11*/ { cesaDataHexStr1, cesaHmacSha1digestHex1, NULL, 0, 8, -1 },
- +/*12*/ { NULL, cesaDataAndSha1digest1, NULL, 0, 8, -1 },
- +/*13*/ { cesaDataHexStr3, cesaHmacSha1digestHex3, NULL, 0, 50, -1 },
- +/*14*/ { NULL, cesaDataAndSha1digest3, NULL, 0, 50, -1 },
- +/*15*/ { hashHexStr3, hashMd5digest3, NULL, 0, 3, -1 },
- +/*16*/ { hashHexStr3, hashSha1digest3, NULL, 0, 3, -1 },
- +/*17*/ { hashHexStr80, tripleDesThenMd5digest80, NULL, 80, 80, -1 },
- +/*18*/ { hashHexStr80, tripleDesThenSha1digest80, NULL, 80, 80, -1 },
- +/*19*/ { hashHexStr80, cbc3desThenMd5digest80, iv1, 80, 80, -1 },
- +/*20*/ { hashHexStr80, cbc3desThenSha1digest80, iv1, 80, 80, -1 },
- +/*21*/ { hashHexStr80, cbcAes128ThenMd5digest80, iv5, 80, 80, -1 },
- +/*22*/ { hashHexStr80, cbcAes128ThenSha1digest80, iv5, 80, 80, -1 },
- +/*23*/ { cesaAesCtrPlain, cesaAesCtrCipher, NULL, 36, 0, -1 },
- +/*24*/ { cesaAesIvPlainText, cesaAes128IvCipherCbc, NULL, 64, 0, -1 },
- +/*25*/ { plain3des1, cipher3des1, NULL, 0, 0, -1 },
- +/*26*/ { plain3des2, cipher3desCbc2, iv3des2,0, 0, -1 },
- +/*27*/ { plain3des3, cipher3desCbc3, iv3des3,0, 0, -1 },
- +};
- +
- +
- +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
- + * Input 0xdd repeated "size" times
- + */
- +static MV_CESA_SIZE_TEST mdMultiSizeTest302[] =
- +{
- + { 80, "7a031a640c14a4872814930b1ef3a5b2" },
- + { 512, "5488e6c5a14dc72a79f28312ca5b939b" },
- + { 1000, "d00814f586a8b78a05724239d2531821" },
- + { 1001, "bf07df7b7f49d3f5b5ecacd4e9e63281" },
- + { 1002, "1ed4a1a802e87817a819d4e37bb4d0f7" },
- + { 1003, "5972ab64a4f265ee371dac2f2f137f90" },
- + { 1004, "71f95e7ec3aa7df2548e90898abdb28e" },
- + { 1005, "e082790b4857fcfc266e92e59e608814" },
- + { 1006, "9500f02fd8ac7fde8b10e4fece9a920d" },
- + { 1336, "e42edcce57d0b75b01aa09d71427948b" },
- + { 1344, "bb5454ada0deb49ba0a97ffd60f57071" },
- + { 1399, "0f44d793e744b24d53f44f295082ee8c" },
- + { 1400, "359de8a03a9b707928c6c60e0e8d79f1" },
- + { 1401, "e913858b484cbe2b384099ea88d8855b" },
- + { 1402, "d9848a164af53620e0540c1d7d87629e" },
- + { 1403, "0c9ee1c2c9ef45e9b625c26cbaf3e822" },
- + { 1404, "12edd4f609416e3c936170360561b064" },
- + { 1405, "7fc912718a05446395345009132bf562" },
- + { 1406, "882f17425e579ff0d85a91a59f308aa0" },
- + { 1407, "005cae408630a2fb5db82ad9db7e59da" },
- + { 1408, "64655f8b404b3fea7a3e3e609bc5088f" },
- + { 1409, "4a145284a7f74e01b6bb1a0ec6a0dd80" },
- + { 2048, "67caf64475650732def374ebb8bde3fd" },
- + { 2049, "6c84f11f472825f7e6cd125c2981884b" },
- + { 2050, "8999586754a73a99efbe4dbad2816d41" },
- + { 2051, "ba6946b610e098d286bc81091659dfff" },
- + { 2052, "d0afa01c92d4d13def2b024f36faed83" },
- + { 3072, "61d8beac61806afa2585d74a9a0e6974" },
- + { 3074, "f6501a28dcc24d1e4770505c51a87ed3" },
- + { 3075, "ea4a6929be67e33e61ff475369248b73" },
- + { 4048, "aa8c4d68f282a07e7385acdfa69f4bed" },
- + { 4052, "afb5ed2c0e1d430ea59e59ed5ed6b18a" },
- + { 4058, "9e8553f9bdd43aebe0bd729f0e600c99" },
- + { 6144, "f628f3e5d183fe5cdd3a5abee39cf872" },
- + { 6150, "89a3efcea9a2f25f919168ad4a1fd292" },
- + { 6400, "cdd176b7fb747873efa4da5e32bdf88f" },
- + { 6528, "b1d707b027354aca152c45ee559ccd3f" },
- + { 8192, "c600ea4429ac47f9941f09182166e51a" },
- + {16384, "16e8754bfbeb4c649218422792267a37" },
- + {18432, "0fd0607521b0aa8b52219cfbe215f63e" },
- + { 0, NULL },
- +};
- +
- +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + */
- +static MV_CESA_SIZE_TEST mdMultiSizeTest304[] =
- +{
- + { 80, "a456c4723fee6068530af5a2afa71627" },
- + { 512, "f85c2a2344f5de68b432208ad13e5794" },
- + { 1000, "35464d6821fd4a293a41eb84e274c8c5" },
- + { 1001, "c08eedbdce60cceb54bc2d732bb32c8b" },
- + { 1002, "5664f71800c011cc311cb6943339c1b8" },
- + { 1003, "779c723b044c585dc7802b13e8501bdc" },
- + { 1004, "55e500766a2c307bc5c5fdd15e4cacd4" },
- + { 1005, "d5f978954f5c38529d1679d2b714f068" },
- + { 1006, "cd3efc827ce628b7281b72172693abf9" },
- + { 1336, "6f04479910785878ae6335b8d1e87edf" },
- + { 1344, "b6d27b50c2bce1ba2a8e1b5cc4324368" },
- + { 1399, "65f70a1d4c86e5eaeb0704c8a7816795" },
- + { 1400, "3394b5adc4cb3ff98843ca260a44a88a" },
- + { 1401, "3a06f3582033a66a4e57e0603ce94e74" },
- + { 1402, "e4d97f5ed51edc48abfa46eeb5c31752" },
- + { 1403, "3d05e40b080ee3bedf293cb87b7140e7" },
- + { 1404, "8cf294fc3cd153ab18dccb2a52cbf244" },
- + { 1405, "d1487bd42f6edd9b4dab316631159221" },
- + { 1406, "0527123b6bf6936cf5d369dc18c6c70f" },
- + { 1407, "3224a06639db70212a0cd1ae1fcc570a" },
- + { 1408, "a9e13335612c0356f5e2c27086e86c43" },
- + { 1409, "a86d1f37d1ed8a3552e9a4f04dceea98" },
- + { 2048, "396905c9b961cd0f6152abfb69c4449c" },
- + { 2049, "49f39bff85d9dcf059fadb89efc4a70f" },
- + { 2050, "3a2b4823bc4d0415656550226a63e34a" },
- + { 2051, "dec60580d406c782540f398ad0bcc7e0" },
- + { 2052, "32f76610a14310309eb748fe025081bf" },
- + { 3072, "45edc1a42bf9d708a621076b63b774da" },
- + { 3074, "9be1b333fe7c0c9f835fb369dc45f778" },
- + { 3075, "8c06fcac7bd0e7b7a17fd6508c09a549" },
- + { 4048, "0ddaef848184bf0ad98507a10f1e90e4" },
- + { 4052, "81976bcaeb274223983996c137875cb8" },
- + { 4058, "0b0a7a1c82bc7cbc64d8b7cd2dc2bb22" },
- + { 6144, "1c24056f52725ede2dff0d7f9fc9855f" },
- + { 6150, "b7f4b65681c4e43ee68ca466ca9ca4ec" },
- + { 6400, "443bbaab9f7331ddd4bf11b659cd43c8" },
- + { 6528, "216f44f23047cfee03a7a64f88f9a995" },
- + { 8192, "ac7a993b2cad54879dba1bde63e39097" },
- + { 8320, "55ed7be9682d6c0025b3221a62088d08" },
- + {16384, "c6c722087653b62007aea668277175e5" },
- + {18432, "f1faca8e907872c809e14ffbd85792d6" },
- + { 0, NULL },
- +};
- +
- +/* HASH-MD5
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * repeated "size" times
- + */
- +static MV_CESA_SIZE_TEST mdMultiSizeTest305[] =
- +{
- + { 80, "57edf4a22be3c955ac49da2e2107b67a" },
- + { 512, "c729ae8f0736cc377a9767a660eaa04e" },
- + { 1000, "f1257a8659eb92d36fe14c6bf3852a6a" },
- + { 1001, "f8a46fe8ea04fdc8c7de0e84042d3878" },
- + { 1002, "da188dd67bff87d58aa3c02af2d0cc0f" },
- + { 1003, "961753017feee04c9b93a8e51658a829" },
- + { 1004, "dd68c4338608dcc87807a711636bf2af" },
- + { 1005, "e338d567d3ce66bf69ada29658a8759b" },
- + { 1006, "443c9811e8b92599b0b149e8d7ec700a" },
- + { 1336, "89a98511706008ba4cbd0b4a24fa5646" },
- + { 1344, "335a919805f370b9e402a62c6fe01739" },
- + { 1399, "5d18d0eddcd84212fe28d812b5e80e3b" },
- + { 1400, "6b695c240d2dffd0dffc99459ca76db6" },
- + { 1401, "49590f61298a76719bc93a57a30136f5" },
- + { 1402, "94c2999fa3ef1910a683d69b2b8476f2" },
- + { 1403, "37073a02ab00ecba2645c57c228860db" },
- + { 1404, "1bcd06994fce28b624f0c5fdc2dcdd2b" },
- + { 1405, "11b93671a64c95079e8cf9e7cddc8b3d" },
- + { 1406, "4b6695772a4c66313fa4871017d05f36" },
- + { 1407, "d1539b97fbfda1c075624e958de19c5b" },
- + { 1408, "b801b9b69920907cd018e8063092ede9" },
- + { 1409, "b765f1406cfe78e238273ed01bbcaf7e" },
- + { 2048, "1d7e2c64ac29e2b3fb4c272844ed31f5" },
- + { 2049, "71d38fac49c6b1f4478d8d88447bcdd0" },
- + { 2050, "141c34a5592b1bebfa731e0b23d0cdba" },
- + { 2051, "c5e1853f21c59f5d6039bd13d4b380d8" },
- + { 2052, "dd44a0d128b63d4b5cccd967906472d7" },
- + { 3072, "37d158e33b21390822739d13db7b87fe" },
- + { 3074, "aef3b209d01d39d0597fe03634bbf441" },
- + { 3075, "335ffb428eabf210bada96d74d5a4012" },
- + { 4048, "2434c2b43d798d2819487a886261fc64" },
- + { 4052, "ac2fa84a8a33065b2e92e36432e861f8" },
- + { 4058, "856781f85616c341c3533d090c1e1e84" },
- + { 6144, "e5d134c652c18bf19833e115f7a82e9b" },
- + { 6150, "a09a353be7795fac2401dac5601872e6" },
- + { 6400, "08b9033ac6a1821398f50af75a2dbc83" },
- + { 6528, "3d47aa193a8540c091e7e02f779e6751" },
- + { 8192, "d3164e710c0626f6f395b38f20141cb7" },
- + { 8320, "b727589d9183ff4e8491dd24466974a3" },
- + {16384, "3f54d970793d2274d5b20d10a69938ac" },
- + {18432, "f558511dcf81985b7a1bb57fad970531" },
- + { 0, NULL },
- +};
- +
- +
- +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
- + * 0xaa, 0xaa, 0xaa, 0xaa
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + */
- +static MV_CESA_SIZE_TEST shaMultiSizeTest402[] =
- +{
- + { 80, "e812f370e659705a1649940d1f78cd7af18affd3" },
- + { 512, "e547f886b2c15d995ed76a8a924cb408c8080f66" },
- + { 1000, "239443194409f1a5342ecde1a092c8f3a3ed790a" },
- + { 1001, "f278ab9a102850a9f48dc4e9e6822afe2d0c52b5" },
- + { 1002, "8bcc667df5ab6ece988b3af361d09747c77f4e72" },
- + { 1003, "0fae6046c7dc1d3e356b25af836f6077a363f338" },
- + { 1004, "0ea48401cc92ae6bc92ae76685269cb0167fbe1a" },
- + { 1005, "ecbcd7c879b295bafcd8766cbeac58cc371e31d1" },
- + { 1006, "eb4a4a3d07d1e9a15e6f1ab8a9c47f243e27324c" },
- + { 1336, "f5950ee1d77c10e9011d2149699c9366fe52529c" },
- + { 1344, "b04263604a63c351b0b3b9cf1785b4bdba6c8838" },
- + { 1399, "8cb1cff61d5b784045974a2fc69386e3b8d24218" },
- + { 1400, "9bb2f3fcbeddb2b90f0be797cd647334a2816d51" },
- + { 1401, "23ae462a7a0cb440f7445791079a5d75a535dd33" },
- + { 1402, "832974b524a4d3f9cc2f45a3cabf5ccef65cd2aa" },
- + { 1403, "d1c683742fe404c3c20d5704a5430e7832a7ec95" },
- + { 1404, "867c79042e64f310628e219d8b85594cd0c7adc3" },
- + { 1405, "c9d81d49d13d94358f56ccfd61af02b36c69f7c3" },
- + { 1406, "0df43daab2786172f9b8d07d61f14a070cf1287a" },
- + { 1407, "0fd8f3ad7f169534b274d4c66bbddd89f759e391" },
- + { 1408, "3987511182b18473a564436003139b808fa46343" },
- + { 1409, "ef667e063c9e9f539a8987a8d0bd3066ee85d901" },
- + { 2048, "921109c99f3fedaca21727156d5f2b4460175327" },
- + { 2049, "47188600dd165eb45f27c27196d3c46f4f042c1b" },
- + { 2050, "8831939904009338de10e7fa670847041387807d" },
- + { 2051, "2f8ebb5db2997d614e767be1050366f3641e7520" },
- + { 2052, "669e51cd730dae158d3bef8adba075bd95a0d011" },
- + { 3072, "cfee66cfd83abc8451af3c96c6b35a41cc6c55f5" },
- + { 3074, "216ea26f02976a261b7d21a4dd3085157bedfabd" },
- + { 3075, "bd612ebba021fd8e012b14c3bd60c8c5161fabc0" },
- + { 4048, "c2564c1fdf2d5e9d7dde7aace2643428e90662e8" },
- + { 4052, "91ce61fe924b445dfe7b5a1dcd10a27caec16df6" },
- + { 4058, "db2a9be5ee8124f091c7ebd699266c5de223c164" },
- + { 6144, "855109903feae2ba3a7a05a326b8a171116eb368" },
- + { 6150, "37520bb3a668294d9c7b073e7e3daf8fee248a78" },
- + { 6400, "60a353c841b6d2b1a05890349dad2fa33c7536b7" },
- + { 6528, "9e53a43a69bb42d7c8522ca8bd632e421d5edb36" },
- + { 8192, "a918cb0da862eaea0a33ee0efea50243e6b4927c" },
- + { 8320, "29a5dcf55d1db29cd113fcf0572ae414f1c71329" },
- + {16384, "6fb27966138e0c8d5a0d65ace817ebd53633cee1" },
- + {18432, "ca09900d891c7c9ae2a559b10f63a217003341c1" },
- + { 0, NULL },
- +};
- +
- +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * 0x11, 0x12, 0x13, 0x14
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + */
- +static MV_CESA_SIZE_TEST shaMultiSizeTest404[] =
- +{
- + { 80, "beaf20a34b06a87558d156c0949bc3957d40222e" },
- + { 512, "3353955358d886bc2940a3c7f337ff7dafb59c7b" },
- + { 1000, "8737a542c5e9b2b6244b757ebb69d5bd602a829f" },
- + { 1001, "fd9e7582d8a5d3c9fe3b923e4e6a41b07a1eb4d4" },
- + { 1002, "a146d14a6fc3c274ff600568f4d75b977989e00d" },
- + { 1003, "be22601bbc027ddef2dec97d30b3dc424fd803c5" },
- + { 1004, "3e71fe99b2fe2b7bfdf4dbf0c7f3da25d7ea35e7" },
- + { 1005, "2c422735d7295408fddd76f5e8a83a2a8da13df3" },
- + { 1006, "6d875319049314b61855101a647b9ba3313428e6" },
- + { 1336, "c1631ea80bad9dc43a180712461b65a0598c711c" },
- + { 1344, "816069bf91d34581005746e2e0283d0f9c7b7605" },
- + { 1399, "4e139866dc61cfcb8b67ca2ebd637b3a538593af" },
- + { 1400, "ff2a0f8dd2b02c5417910f6f55d33a78e081a723" },
- + { 1401, "ab00c12be62336964cbce31ae97fe2a0002984d5" },
- + { 1402, "61349e7f999f3a1acc56c3e9a5060a9c4a7b05b6" },
- + { 1403, "3edbc0f61e435bc1317fa27d840076093fb79353" },
- + { 1404, "d052c6dfdbe63d45dab23ef9893e2aa4636aca1e" },
- + { 1405, "0cc16b7388d67bf0add15a31e6e6c753cfae4987" },
- + { 1406, "c96ba7eaad74253c38c22101b558d2850b1d1b90" },
- + { 1407, "3445428a40d2c6556e7c55797ad8d323b61a48d9" },
- + { 1408, "8d6444f937a09317c89834187b8ea9b8d3a8c56b" },
- + { 1409, "c700acd3ecd19014ea2bdb4d42510c467e088475" },
- + { 2048, "ee27d2a0cb77470c2f496212dfd68b5bb7b04e4b" },
- + { 2049, "683762d7a02983b26a6d046e6451d9cd82c25932" },
- + { 2050, "0fd20f1d55a9ee18363c2a6fd54aa13aee69992f" },
- + { 2051, "86c267d8cc4bc8d59090e4f8b303da960fd228b7" },
- + { 2052, "452395ae05b3ec503eea34f86fc0832485ad97c1" },
- + { 3072, "75198e3cfd0b9bcff2dabdf8e38e6fdaa33ca49a" },
- + { 3074, "4e24785ef080141ce4aab4675986d9acea624d7c" },
- + { 3075, "3a20c5978dd637ec0e809bf84f0d9ccf30bc65bf" },
- + { 4048, "3c32da256be7a7554922bf5fed51b0d2d09e59ad" },
- + { 4052, "fff898426ea16e54325ae391a32c6c9bce4c23c0" },
- + { 4058, "c800b9e562e1c91e1310116341a3c91d37f848ec" },
- + { 6144, "d91d509d0cc4376c2d05bf9a5097717a373530e6" },
- + { 6150, "d957030e0f13c5df07d9eec298542d8f94a07f12" },
- + { 6400, "bb745313c3d7dc17b3f955e5534ad500a1082613" },
- + { 6528, "77905f80d9ca82080bbb3e5654896dabfcfd1bdb" },
- + { 8192, "5237fd9a81830c974396f99f32047586612ff3c0" },
- + { 8320, "57668e28d5f2dba0839518a11db0f6af3d7e08bf" },
- + {16384, "62e093fde467f0748087beea32e9af97d5c61241" },
- + {18432, "845fb33130c7d6ea554fd5aacb9c50cf7ccb5929" },
- + { 0, NULL },
- +};
- +
- +/* HASH-SHA1
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * repeated "size" times
- + */
- +static MV_CESA_SIZE_TEST shaMultiSizeTest405[] =
- +{
- + { 80, "50abf5706a150990a08b2c5ea40fa0e585554732" },
- + { 512, "f14516a08948fa27917a974d219741a697ba0087" },
- + { 1000, "0bd18c378d5788817eb4f1e5dc07d867efa5cbf4" },
- + { 1001, "ca29b85c35db1b8aef83c977893a11159d1b7aa2" },
- + { 1002, "d83bc973eaaedb8a31437994dabbb3304b0be086" },
- + { 1003, "2cf7bbef0acd6c00536b5c58ca470df9a3a90b6c" },
- + { 1004, "e4375d09b1223385a8a393066f8209acfd936a80" },
- + { 1005, "1029b38043e027745d019ce1d2d68e3d8b9d8f99" },
- + { 1006, "deea16dcebbd8ac137e2b984deb639b9fb5e9680" },
- + { 1336, "ea031b065fff63dcfb6a41956e4777520cdbc55d" },
- + { 1344, "b52096c6445e6c0a8355995c70dc36ae186c863c" },
- + { 1399, "cde2f6f8379870db4b32cf17471dc828a8dbff2b" },
- + { 1400, "e53ff664064bc09fe5054c650806bd42d8179518" },
- + { 1401, "d1156db5ddafcace64cdb510ff0d4af9b9a8ad64" },
- + { 1402, "34ede0e9a909dd84a2ae291539105c0507b958e1" },
- + { 1403, "a772ca3536da77e6ad3251e4f9e1234a4d7b87c0" },
- + { 1404, "29740fd2b04e7a8bfd32242db6233156ad699948" },
- + { 1405, "65b17397495b70ce4865dad93bf991b74c97cce1" },
- + { 1406, "a7ee89cd0754061fdb91af7ea6abad2c69d542e3" },
- + { 1407, "3eebf82f7420188e23d328b7ce93580b279a5715" },
- + { 1408, "e08d3363a8b9a490dfb3a4c453452b8f114deeec" },
- + { 1409, "95d74df739181a4ff30b8c39e28793a36598e924" },
- + { 2048, "aa40262509c2abf84aab0197f83187fc90056d91" },
- + { 2049, "7dec28ef105bc313bade8d9a7cdeac58b99de5ea" },
- + { 2050, "d2e30f77ec81197de20f56588a156094ecb88450" },
- + { 2051, "6b22ccc874833e96551a39da0c0edcaa0d969d92" },
- + { 2052, "f843141e57875cd669af58744bc60aa9ea59549c" },
- + { 3072, "09c5fedeaa62c132e673cc3c608a00142273d086" },
- + { 3074, "b09e95eea9c7b1b007a58accec488301901a7f3d" },
- + { 3075, "e6226b77b4ada287a8c9bbcf4ed71eec5ce632dc" },
- + { 4048, "e99394894f855821951ddddf5bfc628547435f5c" },
- + { 4052, "32d2f1af38be9cfba6cd03d55a254d0b3e1eb382" },
- + { 4058, "d906552a4f2aca3a22e1fecccbcd183d7289d0ef" },
- + { 6144, "2e7f62d35a860988e1224dc0543204af19316041" },
- + { 6150, "d6b89698ee133df46fec9d552fadc328aa5a1b51" },
- + { 6400, "dff50e90c46853988fa3a4b4ce5dda6945aae976" },
- + { 6528, "9e63ec0430b96db02d38bc78357a2f63de2ab7f8" },
- + { 8192, "971eb71ed60394d5ab5abb12e88420bdd41b5992" },
- + { 8320, "91606a31b46afeaac965cecf87297e791b211013" },
- + {16384, "547f830a5ec1f5f170ce818f156b1002cabc7569" },
- + {18432, "f16f272787f3b8d539652e4dc315af6ab4fda0ef" },
- + { 0, NULL },
- +};
- +
- +/* CryptoKey = 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef;
- + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
- + */
- +static MV_CESA_SIZE_TEST tripleDesMdMultiSizeTest502[] =
- +{
- + { 64, "9586962a2aaaef28803dec2e17807a7f" },
- + { 80, "b7726a03aad490bd6c5a452a89a1b271" },
- + { 352, "f1ed9563aecc3c0d2766eb2bed3b4e4c" },
- + { 512, "0f9decb11ab40fe86f4d4d9397bc020e" },
- + { 1000, "3ba69deac12cab8ff9dff7dbd9669927" },
- + { 1336, "6cf47bf1e80e03e2c1d0945bc50d37d2" },
- + { 1344, "4be388dab21ceb3fa1b8d302e9b821f7" },
- + { 1400, "a58b79fb21dd9bfc6ec93e3b99fb0ef1" },
- + { 1408, "8bc97379fc2ac3237effcdd4f7a86528" },
- + { 2048, "1339f03ab3076f25a20bc4cba16eb5bf" },
- + { 3072, "731204d2d90c4b36ae41f5e1fb874288" },
- + { 4048, "c028d998cfda5642547b7e1ed5ea16e4" },
- + { 6144, "b1b19cd910cc51bd22992f1e59f1e068" },
- + { 6400, "44e4613496ba622deb0e7cb768135a2f" },
- + { 6528, "3b06b0a86f8db9cd67f9448dfcf10549" },
- + { 8192, "d581780b7163138a0f412be681457d82" },
- + {16384, "03b8ac05527faaf1bed03df149c65ccf" },
- + {18432, "677c8a86a41dab6c5d81b85b8fb10ff6" },
- + { 0, NULL },
- +};
- +
- +
- +/* CryptoKey = 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef;
- + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * 0x11, 0x12, 0x13, 0x14
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
- + */
- +static MV_CESA_SIZE_TEST tripleDesShaMultiSizeTest503[] =
- +{
- + { 64, "44a1e9bcbfc1429630d9ea68b7a48b0427a684f2" },
- + { 80, "b2ddeaca91030eab5b95a234ef2c0f6e738ff883" },
- + { 352, "4b91864c7ff629bdff75d9726421f76705452aaf" },
- + { 512, "6dd37faceeb2aa98ba74f4242ed6734a4d546af5" },
- + { 1000, "463661c30300be512a9df40904f0757cde5f1141" },
- + { 1336, "b931f831d9034fe59c65176400b039fe9c1f44a5" },
- + { 1344, "af8866b1cd4a4887d6185bfe72470ffdfb3648e1" },
- + { 1400, "49c6caf07296d5e31d2504d088bc5b20c3ee7cdb" },
- + { 1408, "fcae8deedbc6ebf0763575dc7e9de075b448a0f4" },
- + { 2048, "edece5012146c1faa0dd10f50b183ba5d2af58ac" },
- + { 3072, "5b83625adb43a488b8d64fecf39bb766818547b7" },
- + { 4048, "d2c533678d26c970293af60f14c8279dc708bfc9" },
- + { 6144, "b8f67af4f991b08b725f969b049ebf813bfacc5c" },
- + { 6400, "d9a6c7f746ac7a60ef2edbed2841cf851c25cfb0" },
- + { 6528, "376792b8c8d18161d15579fb7829e6e3a27e9946" },
- + { 8192, "d890eabdca195b34ef8724b28360cffa92ae5655" },
- + {16384, "a167ee52639ec7bf19aee9c6e8f76667c14134b9" },
- + {18432, "e4396ab56f67296b220985a12078f4a0e365d2cc" },
- + { 0, NULL },
- +};
- +
- +/* CryptoKey = 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef
- + * IV = 0x12345678, 0x90abcdef
- + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
- + */
- +static MV_CESA_SIZE_TEST cbc3desMdMultiSizeTest504[] =
- +{
- + { 64, "8d10e00802460ede0058c139ba48bd2d" },
- + { 80, "6f463057e1a90e0e91ae505b527bcec0" },
- + { 352, "4938d48bdf86aece2c6851e7c6079788" },
- + { 512, "516705d59f3cf810ebf2a13a23a7d42e" },
- + { 1000, "a5a000ee5c830e67ddc6a2d2e5644b31" },
- + { 1336, "44af60087b74ed07950088efbe3b126a" },
- + { 1344, "1f5b39e0577920af731dabbfcf6dfc2a" },
- + { 1400, "6804ea640e29b9cd39e08bc37dbce734" },
- + { 1408, "4fb436624b02516fc9d1535466574bf9" },
- + { 2048, "c909b0985c423d8d86719f701e9e83db" },
- + { 3072, "cfe0bc34ef97213ee3d3f8b10122db21" },
- + { 4048, "03ea10b5ae4ddeb20aed6af373082ed1" },
- + { 6144, "b9a0ff4f87fc14b3c2dc6f0ed0998fdf" },
- + { 6400, "6995f85d9d4985dd99e974ec7dda9dd6" },
- + { 6528, "bbbb548ce2fa3d58467f6a6a5168a0e6" },
- + { 8192, "afe101fbe745bb449ae4f50d10801456" },
- + {16384, "9741706d0b1c923340c4660ff97cacdf" },
- + {18432, "b0217becb73cb8f61fd79c7ce9d023fb" },
- + { 0, NULL },
- +};
- +
- +
- +/* CryptoKey = 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef;
- + * IV = 0x12345678, 0x90abcdef
- + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * 0x11, 0x12, 0x13, 0x14
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
- + */
- +static MV_CESA_SIZE_TEST cbc3desShaMultiSizeTest505[] =
- +{
- + { 64, "409187e5bdb0be4a7754ca3747f7433dc4f01b98" },
- + { 80, "1b002ed050be743aa98860cf35659646bb8efcc0" },
- + { 352, "6cbf7ebe50fa4fa6eecc19eca23f9eae553ccfff" },
- + { 512, "cfb5253fb4bf72b743320c30c7e48c54965853b0" },
- + { 1000, "95e04e1ca2937e7c5a9aba9e42d2bcdb8a7af21f" },
- + { 1336, "3b5c1f5eee5837ebf67b83ae01405542d77a6627" },
- + { 1344, "2b3d42ab25615437f98a1ee310b81d07a02badc2" },
- + { 1400, "7f8687df7c1af44e4baf3c934b6cca5ab6bc993e" },
- + { 1408, "473a581c5f04f7527d50793c845471ac87e86430" },
- + { 2048, "e41d20cae7ebe34e6e828ed62b1e5734019037bb" },
- + { 3072, "275664afd7a561d804e6b0d204e53939cde653ae" },
- + { 4048, "0d220cc5b34aeeb46bbbd637dde6290b5a8285a3" },
- + { 6144, "cb393ddcc8b1c206060625b7d822ef9839e67bc5" },
- + { 6400, "dd3317e2a627fc04800f74a4b05bfda00fab0347" },
- + { 6528, "8a74c3b2441ab3f5a7e08895cc432566219a7c41" },
- + { 8192, "b8e6ef3a549ed0e005bd5b8b1a5fe6689e9711a7" },
- + {16384, "55f59404008276cdac0e2ba0d193af2d40eac5ce" },
- + {18432, "86ae6c4fc72369a54cce39938e2d0296cd9c6ec5" },
- + { 0, NULL },
- +};
- +
- +
- +/* CryptoKey = 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef
- + * IV = 0x12345678, 0x90abcdef
- + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * Note: only sizes aligned to AES block size (16 bytes) allowed
- + */
- +static MV_CESA_SIZE_TEST cbcAes128md5multiSizeTest506[] =
- +{
- + { 16, "7ca4c2ba866751598720c5c4aa0d6786" },
- + { 64, "7dba7fb988e80da609b1fea7254bced8" },
- + { 80, "6b6e863ac5a71d15e3e9b1c86c9ba05f" },
- + { 352, "a1ceb9c2e3021002400d525187a9f38c" },
- + { 512, "596c055c1c55db748379223164075641" },
- + { 1008, "f920989c02f3b3603f53c99d89492377" },
- + { 1344, "2e496b73759d77ed32ea222dbd2e7b41" },
- + { 1408, "7178c046b3a8d772efdb6a71c4991ea4" },
- + { 2048, "a917f0099c69eb94079a8421714b6aad" },
- + { 3072, "693cd5033d7f5391d3c958519fa9e934" },
- + { 4048, "139dca91bcff65b3c40771749052906b" },
- + { 6144, "428d9cef6df4fb70a6e9b6bbe4819e55" },
- + { 6400, "9c0b909e76daa811e12b1fc17000a0c4" },
- + { 6528, "ad876f6297186a7be1f1b907ed860eda" },
- + { 8192, "479cbbaca37dd3191ea1f3e8134a0ef4" },
- + {16384, "60fda559c74f91df538100c9842f2f15" },
- + {18432, "4a3eb1cba1fa45f3981270953f720c42" },
- + { 0, NULL },
- +};
- +
- +
- +/* CryptoKey = 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef,
- + * 0x01234567, 0x89abcdef;
- + * IV = 0x12345678, 0x90abcdef
- + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
- + * 0x11, 0x12, 0x13, 0x14
- + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
- + * Note: only sizes aligned to AES block size (16 bytes) allowed
- + */
- +static MV_CESA_SIZE_TEST cbcAes128sha1multiSizeTest507[] =
- +{
- + { 16, "9aa8dc1c45f0946daf78057fa978759c625c1fee" },
- + { 64, "9f588fc1ede851e5f8b20256abc9979465ae2189" },
- + { 80, "13558472d1fc1c90dffec6e5136c7203452d509b" },
- + { 352, "6b93518e006cfaa1f7adb24615e7291fb0a27e06" },
- + { 512, "096874951a77fbbf333e49d80c096ee2016e09bd" },
- + { 1008, "696fc203c2e4b5ae0ec5d1db3f623c490bc6dbac" },
- + { 1344, "79bf77509935ccd3528caaac6a5eb6481f74029b" },
- + { 1408, "627f9462b95fc188e8cfa7eec15119bdc5d4fcf1" },
- + { 2048, "3d50d0c005feba92fe41502d609fced9c882b4d1" },
- + { 3072, "758807e5b983e3a91c06fb218fe0f73f77111e94" },
- + { 4048, "ca90e85242e33f005da3504416a52098d0d31fb2" },
- + { 6144, "8044c1d4fd06642dfc46990b4f18b61ef1e972cf" },
- + { 6400, "166f1f4ea57409f04feba9fb1e39af0e00bd6f43" },
- + { 6528, "0389016a39485d6e330f8b4215ddf718b404f7e9" },
- + { 8192, "6df7ee2a8b61d6f7f860ce8dbf778f0c2a5b508b" },
- + {16384, "a70a6d8dfa1f91ded621c3dbaed34162bc48783f" },
- + {18432, "8dfad627922ce15df1eed10bdbed49244efa57db" },
- + { 0, NULL },
- +};
- +
- +
- +void cesaTestPrintStatus(void);
- +
- +
- +/*------------------------- LOCAL FUNCTIONs ---------------------------------*/
- +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
- + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize);
- +MV_STATUS testClose(int idx);
- +MV_STATUS testOpen(int idx);
- +void close_session(int sid);
- +void cesaTestCheckReady(const MV_CESA_RESULT *r);
- +void cesaCheckReady(MV_CESA_RESULT* r);
- +void printTestResults(int idx, MV_STATUS status, int checkMode);
- +void cesaLastResult(void);
- +void cesaTestPrintReq(int req, int offset, int size);
- +
- +void cesaTestPrintStatus(void);
- +void cesaTestPrintSession(int idx);
- +void sizeTest(int testIdx, int iter, int checkMode);
- +void multiTest(int iter, int reqSize, int checkMode);
- +void oneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
- +void multiSizeTest(int idx, int iter, int checkMode, char* inputData);
- +void cesaTest(int iter, int reqSize, int checkMode);
- +void cesaOneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
- +void combiTest(int iter, int reqSize, int checkMode);
- +void shaTest(int iter, int reqSize, int checkMode);
- +void mdTest(int iter, int reqSize, int checkMode);
- +void aesTest(int iter, int reqSize, int checkMode);
- +void tripleDesTest(int iter, int reqSize, int checkMode);
- +void desTest(int iter, int reqSize, int checkMode);
- +void cesaTestStop(void);
- +MV_STATUS testRun(int idx, int caseIdx, int iter,int reqSize, int checkMode);
- +void cesaTestStart(int bufNum, int bufSize);
- +
- +
- +static MV_U32 getRate(MV_U32* remainder)
- +{
- + MV_U32 kBits, milliSec, rate;
- +
- + milliSec = 0;
- + if( (cesaEndTicks - cesaBeginTicks) > 0)
- + {
- + milliSec = CESA_TEST_TICK_TO_MS(cesaEndTicks - cesaBeginTicks);
- + }
- + if(milliSec == 0)
- + {
- + if(remainder != NULL)
- + *remainder = 0;
- + return 0;
- + }
- +
- + kBits = (cesaIteration*cesaRateSize*8)/1000;
- + rate = kBits/milliSec;
- + if(remainder != NULL)
- + *remainder = ((kBits % milliSec)*10)/milliSec;
- +
- + return rate;
- +}
- +
- +static char* extractMbuf(MV_CESA_MBUF *pMbuf,
- + int offset, int size, char* hexStr)
- +{
- + mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, size);
- + mvBinToHex((const MV_U8*)cesaBinBuffer, hexStr, size);
- +
- + return hexStr;
- +}
- +
- +static MV_BOOL cesaCheckMbuf(MV_CESA_MBUF *pMbuf,
- + const char* hexString, int offset,
- + int checkSize)
- +{
- + MV_BOOL isFailed = MV_FALSE;
- + MV_STATUS status;
- + int size = strlen(hexString)/2;
- + int checkedSize = 0;
- +/*
- + mvOsPrintf("cesaCheckMbuf: pMbuf=%p, offset=%d, checkSize=%d, mBufSize=%d\n",
- + pMbuf, offset, checkSize, pMbuf->mbufSize);
- +*/
- + if(pMbuf->mbufSize < (checkSize + offset))
- + {
- + mvOsPrintf("checkSize (%d) is too large: offset=%d, mbufSize=%d\n",
- + checkSize, offset, pMbuf->mbufSize);
- + return MV_TRUE;
- + }
- + status = mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, checkSize);
- + if(status != MV_OK)
- + {
- + mvOsPrintf("CesaTest: Can't copy %d bytes from Mbuf=%p to checkBuf=%p\n",
- + checkSize, pMbuf, cesaBinBuffer);
- + return MV_TRUE;
- + }
- +/*
- + mvDebugMemDump(cesaBinBuffer, size, 1);
- +*/
- + mvHexToBin(hexString, (MV_U8*)cesaExpBinBuffer, size);
- +
- + /* Compare buffers */
- + while(checkSize > checkedSize)
- + {
- + size = MV_MIN(size, (checkSize - checkedSize));
- + if(memcmp(cesaExpBinBuffer, &cesaBinBuffer[checkedSize], size) != 0)
- + {
- + mvOsPrintf("CheckMbuf failed: checkSize=%d, size=%d, checkedSize=%d\n",
- + checkSize, size, checkedSize);
- + mvDebugMemDump(&cesaBinBuffer[checkedSize], size, 1);
- + mvDebugMemDump(cesaExpBinBuffer, size, 1);
- +
- + isFailed = MV_TRUE;
- + break;
- + }
- + checkedSize += size;
- + }
- +
- + return isFailed;
- +}
- +
- +static MV_STATUS cesaSetMbuf(MV_CESA_MBUF *pMbuf,
- + const char* hexString,
- + int offset, int reqSize)
- +{
- + MV_STATUS status = MV_OK;
- + int copySize, size = strlen(hexString)/2;
- +
- + mvHexToBin(hexString, (MV_U8*)cesaBinBuffer, size);
- +
- + copySize = 0;
- + while(reqSize > copySize)
- + {
- + size = MV_MIN(size, (reqSize - copySize));
- +
- + status = mvCesaCopyToMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset+copySize, size);
- + if(status != MV_OK)
- + {
- + mvOsPrintf("cesaSetMbuf Error: Copy %d of %d bytes to MBuf\n",
- + copySize, reqSize);
- + break;
- + }
- + copySize += size;
- + }
- + pMbuf->mbufSize = offset+copySize;
- + return status;
- +}
- +
- +static MV_CESA_TEST_SESSION* getTestSessionDb(int idx, int* pTestIdx)
- +{
- + int testIdx, dbIdx = idx/100;
- +
- + if(dbIdx > MAX_TEST_TYPE)
- + {
- + mvOsPrintf("Wrong index %d - No such test type\n", idx);
- + return NULL;
- + }
- + testIdx = idx % 100;
- +
- + if(testIdx >= cesaTestsDB[dbIdx].numSessions)
- + {
- + mvOsPrintf("Wrong index %d - No such test\n", idx);
- + return NULL;
- + }
- + if(pTestIdx != NULL)
- + *pTestIdx = testIdx;
- +
- + return cesaTestsDB[dbIdx].pSessions;
- +}
- +
- +/* Debug */
- +void cesaTestPrintReq(int req, int offset, int size)
- +{
- + MV_CESA_MBUF* pMbuf;
- +
- + mvOsPrintf("cesaTestPrintReq: req=%d, offset=%d, size=%d\n",
- + req, offset, size);
- + mvDebugMemDump(cesaCmdRing, 128, 4);
- +
- + pMbuf = cesaCmdRing[req].pSrc;
- + mvCesaDebugMbuf("src", pMbuf, offset,size);
- + pMbuf = cesaCmdRing[req].pDst;
- + mvCesaDebugMbuf("dst", pMbuf, offset, size);
- +
- + cesaTestPrintStatus();
- +}
- +
- +void cesaLastResult(void)
- +{
- + mvOsPrintf("Last Result: ReqId = %d, SessionId = %d, rc = (%d)\n",
- + (MV_U32)cesaResult.pReqPrv, cesaResult.sessionId,
- + cesaResult.retCode);
- +}
- +
- +void printTestResults(int idx, MV_STATUS status, int checkMode)
- +{
- + int testIdx;
- + MV_CESA_TEST_SESSION* pTestSessions = getTestSessionDb(idx, &testIdx);
- +
- + if(pTestSessions == NULL)
- + return;
- +
- + mvOsPrintf("%-35s %4dx%-4d : ", pTestSessions[testIdx].name,
- + cesaIteration, cesaReqSize);
- + if( (status == MV_OK) &&
- + (cesaCryptoError == 0) &&
- + (cesaError == 0) &&
- + (cesaReqIdError == 0) )
- + {
- + mvOsPrintf("Passed, Rate=%3u.%u Mbps (%5u cpp)\n",
- + cesaRate, cesaRateAfterDot, cesaEndTicks - cesaBeginTicks);
- + }
- + else
- + {
- + mvOsPrintf("Failed, Status = 0x%x\n", status);
- + if(cesaCryptoError > 0)
- + mvOsPrintf("cryptoError : %d\n", cesaCryptoError);
- + if(cesaReqIdError > 0)
- + mvOsPrintf("reqIdError : %d\n", cesaReqIdError);
- + if(cesaError > 0)
- + mvOsPrintf("cesaError : %d\n", cesaError);
- + }
- + if(cesaTestIsrMissCount > 0)
- + mvOsPrintf("cesaIsrMissed : %d\n", cesaTestIsrMissCount);
- +}
- +
- +void cesaCheckReady(MV_CESA_RESULT* r)
- +{
- + int reqId;
- + MV_CESA_MBUF *pMbuf;
- + MV_BOOL isFailed;
- +
- + cesaResult = *r;
- + reqId = (int)cesaResult.pReqPrv;
- + pMbuf = cesaCmdRing[reqId].pDst;
- +
- +/*
- + mvOsPrintf("cesaCheckReady: reqId=%d, checkOffset=%d, checkSize=%d\n",
- + reqId, cesaCheckOffset, cesaCheckSize);
- +*/
- + /* Check expected reqId */
- + if(reqId != cesaExpReqId)
- + {
- + cesaReqIdError++;
- +/*
- + mvOsPrintf("CESA reqId Error: cbIter=%d (%d), reqId=%d, expReqId=%d\n",
- + cesaCbIter, cesaIteration, reqId, cesaExpReqId);
- +*/
- + }
- + else
- + {
- + if( (cesaCheckMode == CESA_FULL_CHECK_MODE) ||
- + (cesaCheckMode == CESA_FAST_CHECK_MODE) )
- + {
- + if(cesaResult.retCode != MV_OK)
- + {
- + cesaError++;
- +
- + mvOsPrintf("CESA Error: cbIter=%d (%d), reqId=%d, rc=%d\n",
- + cesaCbIter, cesaIteration, reqId, cesaResult.retCode);
- + }
- + else
- + {
- + if( (cesaCheckSize > 0) && (cesaOutputHexStr != NULL) )
- + {
- + /* Check expected output */
- +
- + isFailed = cesaCheckMbuf(pMbuf, cesaOutputHexStr, cesaCheckOffset, cesaCheckSize);
- + if(isFailed)
- + {
- + mvOsPrintf("CESA Crypto Error: cbIter=%d (%d), reqId=%d\n",
- + cesaCbIter, cesaIteration, reqId);
- +
- + CESA_TEST_DEBUG_PRINT(("Error: reqId=%d, reqSize=%d, checkOffset=%d, checkSize=%d\n",
- + reqId, cesaReqSize, cesaCheckOffset, cesaCheckSize));
- +
- + CESA_TEST_DEBUG_PRINT(("Output str: %s\n", cesaOutputHexStr));
- +
- + CESA_TEST_DEBUG_CODE( mvCesaDebugMbuf("error", pMbuf, 0, cesaCheckOffset+cesaCheckSize) );
- +
- + cesaCryptoError++;
- + }
- + }
- + }
- + }
- + }
- + if(cesaCheckMode == CESA_SHOW_CHECK_MODE)
- + {
- + extractMbuf(pMbuf, cesaCheckOffset, cesaCheckSize, cesaHexBuffer);
- + mvOsPrintf("%4d, %s\n", cesaCheckOffset, cesaHexBuffer);
- + }
- +
- + cesaCbIter++;
- + if(cesaCbIter >= cesaIteration)
- + {
- + cesaCbIter = 0;
- + cesaExpReqId = 0;
- + cesaIsReady = MV_TRUE;
- +
- + cesaEndTicks = CESA_TEST_TICK_GET();
- + cesaRate = getRate(&cesaRateAfterDot);
- + }
- + else
- + {
- + cesaExpReqId = reqId + 1;
- + if(cesaExpReqId == CESA_DEF_REQ_SIZE)
- + cesaExpReqId = 0;
- + }
- +}
- +
- +
- +#ifdef MV_NETBSD
- +static int cesaTestReadyIsr(void *arg)
- +#else
- +#ifdef __KERNEL__
- +static irqreturn_t cesaTestReadyIsr( int irq , void *dev_id)
- +#endif
- +#ifdef MV_VXWORKS
- +void cesaTestReadyIsr(void)
- +#endif
- +#endif
- +{
- + MV_U32 cause;
- + MV_STATUS status;
- + MV_CESA_RESULT result;
- +
- + cesaTestIsrCount++;
- + /* Clear cause register */
- + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
- + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
- + {
- + mvOsPrintf("cesaTestReadyIsr: cause=0x%x\n", cause);
- +#ifdef MV_NETBSD
- + return 0;
- +#else
- +#ifdef __KERNEL__
- + return 1;
- +#else
- + return;
- +#endif
- +#endif
- + }
- +
- + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
- +
- + while(MV_TRUE)
- + {
- + /* Get Ready requests */
- + status = mvCesaReadyGet(&result);
- + if(status == MV_OK)
- + cesaCheckReady(&result);
- +
- + break;
- + }
- + if( (cesaTestFull == 1) && (status != MV_BUSY) )
- + {
- + cesaTestFull = 0;
- + CESA_TEST_WAKE_UP();
- + }
- +
- +#ifdef __KERNEL__
- + return 1;
- +#endif
- +}
- +
- +void
- +cesaTestCheckReady(const MV_CESA_RESULT *r)
- +{
- + MV_CESA_RESULT result = *r;
- +
- + cesaCheckReady(&result);
- +
- + if (cesaTestFull == 1) {
- + cesaTestFull = 0;
- + CESA_TEST_WAKE_UP();
- + }
- +}
- +
- +static INLINE int open_session(MV_CESA_OPEN_SESSION* pOs)
- +{
- + MV_U16 sid;
- + MV_STATUS status;
- +
- + status = mvCesaSessionOpen(pOs, (short*)&sid);
- + if(status != MV_OK)
- + {
- + mvOsPrintf("CesaTest: Can't open new session - status = 0x%x\n",
- + status);
- + return -1;
- + }
- +
- + return (int)sid;
- +}
- +
- +void close_session(int sid)
- +{
- + MV_STATUS status;
- +
- + status = mvCesaSessionClose(sid);
- + if(status != MV_OK)
- + {
- + mvOsPrintf("CesaTest: Can't close session %d - status = 0x%x\n",
- + sid, status);
- + }
- +}
- +
- +MV_STATUS testOpen(int idx)
- +{
- + MV_CESA_OPEN_SESSION os;
- + int sid, i, testIdx;
- + MV_CESA_TEST_SESSION* pTestSession;
- + MV_U16 digestSize = 0;
- +
- + pTestSession = getTestSessionDb(idx, &testIdx);
- + if(pTestSession == NULL)
- + {
- + mvOsPrintf("Test %d is not exist\n", idx);
- + return MV_BAD_PARAM;
- + }
- + pTestSession = &pTestSession[testIdx];
- +
- + if(pTestSession->sid != -1)
- + {
- + mvOsPrintf("Session for test %d already created: sid=%d\n",
- + idx, pTestSession->sid);
- + return MV_OK;
- + }
- +
- + os.cryptoAlgorithm = pTestSession->cryptoAlgorithm;
- + os.macMode = pTestSession->macAlgorithm;
- + switch(os.macMode)
- + {
- + case MV_CESA_MAC_MD5:
- + case MV_CESA_MAC_HMAC_MD5:
- + digestSize = MV_CESA_MD5_DIGEST_SIZE;
- + break;
- +
- + case MV_CESA_MAC_SHA1:
- + case MV_CESA_MAC_HMAC_SHA1:
- + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
- + break;
- +
- + case MV_CESA_MAC_NULL:
- + digestSize = 0;
- + }
- + os.cryptoMode = pTestSession->cryptoMode;
- + os.direction = pTestSession->direction;
- + os.operation = pTestSession->operation;
- +
- + for(i=0; i<pTestSession->cryptoKeySize; i++)
- + os.cryptoKey[i] = pTestSession->pCryptoKey[i];
- +
- + os.cryptoKeyLength = pTestSession->cryptoKeySize;
- +
- + for(i=0; i<pTestSession->macKeySize; i++)
- + os.macKey[i] = pTestSession->pMacKey[i];
- +
- + os.macKeyLength = pTestSession->macKeySize;
- + os.digestSize = digestSize;
- +
- + sid = open_session(&os);
- + if(sid == -1)
- + {
- + mvOsPrintf("Can't open session for test %d: rc=0x%x\n",
- + idx, cesaResult.retCode);
- + return cesaResult.retCode;
- + }
- + CESA_TEST_DEBUG_PRINT(("Opened session: sid = %d\n", sid));
- + pTestSession->sid = sid;
- + return MV_OK;
- +}
- +
- +MV_STATUS testClose(int idx)
- +{
- + int testIdx;
- + MV_CESA_TEST_SESSION* pTestSession;
- +
- + pTestSession = getTestSessionDb(idx, &testIdx);
- + if(pTestSession == NULL)
- + {
- + mvOsPrintf("Test %d is not exist\n", idx);
- + return MV_BAD_PARAM;
- + }
- + pTestSession = &pTestSession[testIdx];
- +
- + if(pTestSession->sid == -1)
- + {
- + mvOsPrintf("Test session %d is not opened\n", idx);
- + return MV_NO_SUCH;
- + }
- +
- + close_session(pTestSession->sid);
- + pTestSession->sid = -1;
- +
- + return MV_OK;
- +}
- +
- +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
- + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize)
- +{
- + int cmdReqId = 0;
- + int i;
- + MV_STATUS rc = MV_OK;
- + char ivZeroHex[] = "0000";
- +
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + if(pCmd == NULL)
- + {
- + mvOsPrintf("testCmd failed: pCmd=NULL\n");
- + return MV_BAD_PARAM;
- + }
- + pCmd->sessionId = sid;
- +
- + cesaCryptoError = 0;
- + cesaReqIdError = 0;
- + cesaError = 0;
- + cesaTestIsrMissCount = 0;
- + cesaIsReady = MV_FALSE;
- + cesaIteration = iter;
- +
- + if(cesaInputHexStr == NULL)
- + cesaInputHexStr = cesaPlainHexEbc;
- +
- + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
- + {
- + pCmd->pSrc = (MV_CESA_MBUF*)(cesaCmdRing[i].pSrc);
- + if(pIV != NULL)
- + {
- + /* If IV from SA - set IV in Source buffer to zeros */
- + cesaSetMbuf(pCmd->pSrc, ivZeroHex, 0, pCmd->cryptoOffset);
- + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, pCmd->cryptoOffset,
- + (cesaReqSize - pCmd->cryptoOffset));
- + }
- + else
- + {
- + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, 0, cesaReqSize);
- + }
- + pCmd->pDst = (MV_CESA_MBUF*)(cesaCmdRing[i].pDst);
- + cesaSetMbuf(pCmd->pDst, cesaNullPlainHexText, 0, cesaReqSize);
- +
- + memcpy(&cesaCmdRing[i], pCmd, sizeof(*pCmd));
- + }
- +
- + if(cesaCheckMode == CESA_SW_SHOW_CHECK_MODE)
- + {
- + MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
- +
- + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
- + {
- + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
- + mvOsPrintf("SW HASH_MD5: reqSize=%d, macLength=%d\n",
- + cesaReqSize, pCmd->macLength);
- + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
- + return MV_OK;
- + }
- + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
- + {
- + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
- + mvOsPrintf("SW HASH_SHA1: reqSize=%d, macLength=%d\n",
- + cesaReqSize, pCmd->macLength);
- + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
- + return MV_OK;
- + }
- + }
- +
- + cesaBeginTicks = CESA_TEST_TICK_GET();
- + CESA_TEST_DEBUG_CODE( memset(cesaTestTrace, 0, sizeof(cesaTestTrace));
- + cesaTestTraceIdx = 0;
- + );
- +
- + if(cesaCheckMode == CESA_SW_NULL_CHECK_MODE)
- + {
- + volatile MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
- +
- + for(i=0; i<iter; i++)
- + {
- + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
- + {
- + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (unsigned char*)pDigest);
- + }
- + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
- + {
- + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (MV_U8 *)pDigest);
- + }
- + }
- + cesaEndTicks = CESA_TEST_TICK_GET();
- + cesaRate = getRate(&cesaRateAfterDot);
- + cesaIsReady = MV_TRUE;
- +
- + return MV_OK;
- + }
- +
- + /*cesaTestIsrCount = 0;*/
- + /*mvCesaDebugStatsClear();*/
- +
- +#ifndef MV_NETBSD
- + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
- +#endif
- +
- + for(i=0; i<iter; i++)
- + {
- + unsigned long flags;
- +
- + pCmd = &cesaCmdRing[cmdReqId];
- + pCmd->pReqPrv = (void*)cmdReqId;
- +
- + CESA_TEST_LOCK(flags);
- +
- + rc = mvCesaAction(pCmd);
- + if(rc == MV_NO_RESOURCE)
- + cesaTestFull = 1;
- +
- + CESA_TEST_UNLOCK(flags);
- +
- + if(rc == MV_NO_RESOURCE)
- + {
- + CESA_TEST_LOCK(flags);
- + CESA_TEST_WAIT( (cesaTestFull == 0), 100);
- + CESA_TEST_UNLOCK(flags);
- + if(cesaTestFull == 1)
- + {
- + mvOsPrintf("CESA Test timeout: i=%d, iter=%d, cesaTestFull=%d\n",
- + i, iter, cesaTestFull);
- + cesaTestFull = 0;
- + return MV_TIMEOUT;
- + }
- +
- + CESA_TEST_LOCK(flags);
- +
- + rc = mvCesaAction(pCmd);
- +
- + CESA_TEST_UNLOCK(flags);
- + }
- + if( (rc != MV_OK) && (rc != MV_NO_MORE) )
- + {
- + mvOsPrintf("mvCesaAction failed: rc=%d\n", rc);
- + return rc;
- + }
- +
- + cmdReqId++;
- + if(cmdReqId >= CESA_DEF_REQ_SIZE)
- + cmdReqId = 0;
- +
- +#ifdef MV_LINUX
- + /* Reschedule each 16 requests */
- + if( (i & 0xF) == 0)
- + schedule();
- +#endif
- + }
- + return MV_OK;
- +}
- +
- +void cesaTestStart(int bufNum, int bufSize)
- +{
- + int i, j, idx;
- + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
- + MV_BUF_INFO *pFragsSrc, *pFragsDst;
- + char *pBuf;
- +#ifndef MV_NETBSD
- + int numOfSessions, queueDepth;
- + char *pSram;
- + MV_STATUS status;
- + MV_CPU_DEC_WIN addrDecWin;
- +#endif
- +
- + cesaCmdRing = mvOsMalloc(sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
- + if(cesaCmdRing == NULL)
- + {
- + mvOsPrintf("testStart: Can't allocate %ld bytes of memory\n",
- + sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
- + return;
- + }
- + memset(cesaCmdRing, 0, sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
- +
- + if(bufNum == 0)
- + bufNum = CESA_DEF_BUF_NUM;
- +
- + if(bufSize == 0)
- + bufSize = CESA_DEF_BUF_SIZE;
- +
- + cesaBufNum = bufNum;
- + cesaBufSize = bufSize;
- + mvOsPrintf("CESA test started: bufNum = %d, bufSize = %d\n",
- + bufNum, bufSize);
- +
- + cesaHexBuffer = mvOsMalloc(2*bufNum*bufSize);
- + if(cesaHexBuffer == NULL)
- + {
- + mvOsPrintf("testStart: Can't malloc %d bytes for cesaHexBuffer.\n",
- + 2*bufNum*bufSize);
- + return;
- + }
- + memset(cesaHexBuffer, 0, (2*bufNum*bufSize));
- +
- + cesaBinBuffer = mvOsMalloc(bufNum*bufSize);
- + if(cesaBinBuffer == NULL)
- + {
- + mvOsPrintf("testStart: Can't malloc %d bytes for cesaBinBuffer\n",
- + bufNum*bufSize);
- + return;
- + }
- + memset(cesaBinBuffer, 0, (bufNum*bufSize));
- +
- + cesaExpBinBuffer = mvOsMalloc(bufNum*bufSize);
- + if(cesaExpBinBuffer == NULL)
- + {
- + mvOsPrintf("testStart: Can't malloc %d bytes for cesaExpBinBuffer\n",
- + bufNum*bufSize);
- + return;
- + }
- + memset(cesaExpBinBuffer, 0, (bufNum*bufSize));
- +
- + CESA_TEST_WAIT_INIT();
- +
- + pMbufSrc = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
- + pFragsSrc = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
- +
- + pMbufDst = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
- + pFragsDst = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
- +
- + if( (pMbufSrc == NULL) || (pFragsSrc == NULL) ||
- + (pMbufDst == NULL) || (pFragsDst == NULL) )
- + {
- + mvOsPrintf("testStart: Can't malloc Src and Dst pMbuf and pFrags structures.\n");
- + /* !!!! Dima cesaTestCleanup();*/
- + return;
- + }
- +
- + memset(pMbufSrc, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
- + memset(pFragsSrc, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
- +
- + memset(pMbufDst, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
- + memset(pFragsDst, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
- +
- + mvOsPrintf("Cesa Test Start: pMbufSrc=%p, pFragsSrc=%p, pMbufDst=%p, pFragsDst=%p\n",
- + pMbufSrc, pFragsSrc, pMbufDst, pFragsDst);
- +
- + idx = 0;
- + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
- + {
- + pBuf = mvOsIoCachedMalloc(cesaTestOSHandle,bufSize * bufNum * 2,
- + &cesaReqBufs[i].bufPhysAddr,
- + &cesaReqBufs[i].memHandle);
- + if(pBuf == NULL)
- + {
- + mvOsPrintf("testStart: Can't malloc %d bytes for pBuf\n",
- + bufSize * bufNum * 2);
- + return;
- + }
- +
- + memset(pBuf, 0, bufSize * bufNum * 2);
- + mvOsCacheFlush(cesaTestOSHandle,pBuf, bufSize * bufNum * 2);
- + if(pBuf == NULL)
- + {
- + mvOsPrintf("cesaTestStart: Can't allocate %d bytes for req_%d buffers\n",
- + bufSize * bufNum * 2, i);
- + return;
- + }
- +
- + cesaReqBufs[i].bufVirtPtr = (MV_U8*)pBuf;
- + cesaReqBufs[i].bufSize = bufSize * bufNum * 2;
- +
- + cesaCmdRing[i].pSrc = &pMbufSrc[i];
- + cesaCmdRing[i].pSrc->pFrags = &pFragsSrc[idx];
- + cesaCmdRing[i].pSrc->numFrags = bufNum;
- + cesaCmdRing[i].pSrc->mbufSize = 0;
- +
- + cesaCmdRing[i].pDst = &pMbufDst[i];
- + cesaCmdRing[i].pDst->pFrags = &pFragsDst[idx];
- + cesaCmdRing[i].pDst->numFrags = bufNum;
- + cesaCmdRing[i].pDst->mbufSize = 0;
- +
- + for(j=0; j<bufNum; j++)
- + {
- + cesaCmdRing[i].pSrc->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
- + cesaCmdRing[i].pSrc->pFrags[j].bufSize = bufSize;
- + pBuf += bufSize;
- + cesaCmdRing[i].pDst->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
- + cesaCmdRing[i].pDst->pFrags[j].bufSize = bufSize;
- + pBuf += bufSize;
- + }
- + idx += bufNum;
- + }
- +
- +#ifndef MV_NETBSD
- + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
- + pSram = (char*)addrDecWin.addrWin.baseLow;
- + else
- + {
- + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
- + return;
- + }
- +
- +#ifdef MV_CESA_NO_SRAM
- + pSram = mvOsMalloc(4*1024+8);
- + if(pSram == NULL)
- + {
- + mvOsPrintf("CesaTest: can't allocate %d bytes for SRAM simulation\n",
- + 4*1024+8);
- + /* !!!! Dima cesaTestCleanup();*/
- + return;
- + }
- + pSram = (MV_U8*)MV_ALIGN_UP((MV_U32)pSram, 8);
- +#endif /* MV_CESA_NO_SRAM */
- +
- + numOfSessions = CESA_DEF_SESSION_NUM;
- + queueDepth = CESA_DEF_REQ_SIZE - MV_CESA_MAX_CHAN;
- +
- + status = mvCesaInit(numOfSessions, queueDepth, pSram, NULL);
- + if(status != MV_OK)
- + {
- + mvOsPrintf("mvCesaInit is Failed: status = 0x%x\n", status);
- + /* !!!! Dima cesaTestCleanup();*/
- + return;
- + }
- +#endif /* !MV_NETBSD */
- +
- + /* Prepare data for tests */
- + for(i=0; i<50; i++)
- + strcat((char*)cesaDataHexStr3, "dd");
- +
- + strcpy((char*)cesaDataAndMd5digest3, cesaDataHexStr3);
- + strcpy((char*)cesaDataAndSha1digest3, cesaDataHexStr3);
- +
- + /* Digest must be 8 byte aligned */
- + for(; i<56; i++)
- + {
- + strcat((char*)cesaDataAndMd5digest3, "00");
- + strcat((char*)cesaDataAndSha1digest3, "00");
- + }
- + strcat((char*)cesaDataAndMd5digest3, cesaHmacMd5digestHex3);
- + strcat((char*)cesaDataAndSha1digest3, cesaHmacSha1digestHex3);
- +
- +#ifndef MV_NETBSD
- + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
- + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
- +#endif
- +
- +#ifdef MV_VXWORKS
- + {
- + MV_STATUS status;
- +
- + status = intConnect((VOIDFUNCPTR *)INT_LVL_CESA, cesaTestReadyIsr, (int)NULL);
- + if (status != OK)
- + {
- + mvOsPrintf("CESA: Can't connect CESA (%d) interrupt, status=0x%x \n",
- + INT_LVL_CESA, status);
- + /* !!!! Dima cesaTestCleanup();*/
- + return;
- + }
- + cesaSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
- + if(cesaSemId == NULL)
- + {
- + mvOsPrintf("cesaTestStart: Can't create semaphore\n");
- + return;
- + }
- + intEnable(INT_LVL_CESA);
- + }
- +#endif /* MV_VXWORKS */
- +
- +#if !defined(MV_NETBSD) && defined(__KERNEL__)
- + if( request_irq(CESA_IRQ, cesaTestReadyIsr, (SA_INTERRUPT) , "cesa_test", NULL ) )
- + {
- + mvOsPrintf( "cannot assign irq\n" );
- + /* !!!! Dima cesaTestCleanup();*/
- + return;
- + }
- + spin_lock_init( &cesaLock );
- +#endif
- +}
- +
- +MV_STATUS testRun(int idx, int caseIdx, int iter,
- + int reqSize, int checkMode)
- +{
- + int testIdx, count, sid, digestSize;
- + int blockSize;
- + MV_CESA_TEST_SESSION* pTestSession;
- + MV_CESA_COMMAND cmd;
- + MV_STATUS status;
- +
- + memset(&cmd, 0, sizeof(cmd));
- +
- + pTestSession = getTestSessionDb(idx, &testIdx);
- + if(pTestSession == NULL)
- + {
- + mvOsPrintf("Test %d is not exist\n", idx);
- + return MV_BAD_PARAM;
- + }
- + pTestSession = &pTestSession[testIdx];
- +
- + sid = pTestSession->sid;
- + if(sid == -1)
- + {
- + mvOsPrintf("Test %d is not opened\n", idx);
- + return MV_BAD_STATE;
- + }
- + switch(pTestSession->cryptoAlgorithm)
- + {
- + case MV_CESA_CRYPTO_DES:
- + case MV_CESA_CRYPTO_3DES:
- + blockSize = MV_CESA_DES_BLOCK_SIZE;
- + break;
- +
- + case MV_CESA_CRYPTO_AES:
- + blockSize = MV_CESA_AES_BLOCK_SIZE;
- + break;
- +
- + case MV_CESA_CRYPTO_NULL:
- + blockSize = 0;
- + break;
- +
- + default:
- + mvOsPrintf("cesaTestRun: Bad CryptoAlgorithm=%d\n",
- + pTestSession->cryptoAlgorithm);
- + return MV_BAD_PARAM;
- + }
- + switch(pTestSession->macAlgorithm)
- + {
- + case MV_CESA_MAC_MD5:
- + case MV_CESA_MAC_HMAC_MD5:
- + digestSize = MV_CESA_MD5_DIGEST_SIZE;
- + break;
- +
- + case MV_CESA_MAC_SHA1:
- + case MV_CESA_MAC_HMAC_SHA1:
- + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
- + break;
- + default:
- + digestSize = 0;
- + }
- +
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + if(pTestSession->direction == MV_CESA_DIR_ENCODE)
- + {
- + cesaOutputHexStr = cesaTestCases[caseIdx].cipherHexStr;
- + cesaInputHexStr = cesaTestCases[caseIdx].plainHexStr;
- + }
- + else
- + {
- + cesaOutputHexStr = cesaTestCases[caseIdx].plainHexStr;
- + cesaInputHexStr = cesaTestCases[caseIdx].cipherHexStr;
- + }
- +
- + cmd.sessionId = sid;
- + if(checkMode == CESA_FAST_CHECK_MODE)
- + {
- + cmd.cryptoLength = cesaTestCases[caseIdx].cryptoLength;
- + cmd.macLength = cesaTestCases[caseIdx].macLength;
- + }
- + else
- + {
- + cmd.cryptoLength = reqSize;
- + cmd.macLength = reqSize;
- + }
- + cesaRateSize = cmd.cryptoLength;
- + cesaReqSize = cmd.cryptoLength;
- + cmd.cryptoOffset = 0;
- + if(pTestSession->operation != MV_CESA_MAC_ONLY)
- + {
- + if( (pTestSession->cryptoMode == MV_CESA_CRYPTO_CBC) ||
- + (pTestSession->cryptoMode == MV_CESA_CRYPTO_CTR) )
- + {
- + cmd.ivOffset = 0;
- + cmd.cryptoOffset = blockSize;
- + if(cesaTestCases[caseIdx].pCryptoIV == NULL)
- + {
- + cmd.ivFromUser = 1;
- + }
- + else
- + {
- + cmd.ivFromUser = 0;
- + mvCesaCryptoIvSet(cesaTestCases[caseIdx].pCryptoIV, blockSize);
- + }
- + cesaReqSize = cmd.cryptoOffset + cmd.cryptoLength;
- + }
- + }
- +
- +/*
- + mvOsPrintf("ivFromUser=%d, cryptoLength=%d, cesaReqSize=%d, cryptoOffset=%d\n",
- + cmd.ivFromUser, cmd.cryptoLength, cesaReqSize, cmd.cryptoOffset);
- +*/
- + if(pTestSession->operation != MV_CESA_CRYPTO_ONLY)
- + {
- + cmd.macOffset = cmd.cryptoOffset;
- +
- + if(cesaTestCases[caseIdx].digestOffset == -1)
- + {
- + cmd.digestOffset = cmd.macOffset + cmd.macLength;
- + cmd.digestOffset = MV_ALIGN_UP(cmd.digestOffset, 8);
- + }
- + else
- + {
- + cmd.digestOffset = cesaTestCases[caseIdx].digestOffset;
- + }
- + if( (cmd.digestOffset + digestSize) > cesaReqSize)
- + cesaReqSize = cmd.digestOffset + digestSize;
- + }
- +
- + cesaCheckMode = checkMode;
- +
- + if(checkMode == CESA_NULL_CHECK_MODE)
- + {
- + cesaCheckSize = 0;
- + cesaCheckOffset = 0;
- + }
- + else
- + {
- + if(pTestSession->operation == MV_CESA_CRYPTO_ONLY)
- + {
- + cesaCheckOffset = 0;
- + cesaCheckSize = cmd.cryptoLength;
- + }
- + else
- + {
- + cesaCheckSize = digestSize;
- + cesaCheckOffset = cmd.digestOffset;
- + }
- + }
- +/*
- + mvOsPrintf("reqSize=%d, checkSize=%d, checkOffset=%d, checkMode=%d\n",
- + cesaReqSize, cesaCheckSize, cesaCheckOffset, cesaCheckMode);
- +
- + mvOsPrintf("blockSize=%d, ivOffset=%d, ivFromUser=%d, crOffset=%d, crLength=%d\n",
- + blockSize, cmd.ivOffset, cmd.ivFromUser,
- + cmd.cryptoOffset, cmd.cryptoLength);
- +
- + mvOsPrintf("macOffset=%d, digestOffset=%d, macLength=%d\n",
- + cmd.macOffset, cmd.digestOffset, cmd.macLength);
- +*/
- + status = testCmd(sid, iter, &cmd, pTestSession,
- + cesaTestCases[caseIdx].pCryptoIV, blockSize);
- +
- + if(status != MV_OK)
- + return status;
- +
- + /* Wait when all callbacks is received */
- + count = 0;
- + while(cesaIsReady == MV_FALSE)
- + {
- + mvOsSleep(10);
- + count++;
- + if(count > 100)
- + {
- + mvOsPrintf("testRun: Timeout occured\n");
- + return MV_TIMEOUT;
- + }
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +void cesaTestStop(void)
- +{
- + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
- + MV_BUF_INFO *pFragsSrc, *pFragsDst;
- + int i;
- +
- + /* Release all allocated memories */
- + pMbufSrc = (MV_CESA_MBUF*)(cesaCmdRing[0].pSrc);
- + pFragsSrc = cesaCmdRing[0].pSrc->pFrags;
- +
- + pMbufDst = (MV_CESA_MBUF*)(cesaCmdRing[0].pDst);
- + pFragsDst = cesaCmdRing[0].pDst->pFrags;
- +
- + mvOsFree(pMbufSrc);
- + mvOsFree(pMbufDst);
- + mvOsFree(pFragsSrc);
- + mvOsFree(pFragsDst);
- +
- + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
- + {
- + mvOsIoCachedFree(cesaTestOSHandle,cesaReqBufs[i].bufSize,
- + cesaReqBufs[i].bufPhysAddr,cesaReqBufs[i].bufVirtPtr,
- + cesaReqBufs[i].memHandle);
- + }
- + cesaDataHexStr3[0] = '\0';
- +}
- +
- +void desTest(int iter, int reqSize, int checkMode)
- +{
- + int mode, i;
- + MV_STATUS status;
- +
- + mode = checkMode;
- + if(checkMode == CESA_FULL_CHECK_MODE)
- + mode = CESA_FAST_CHECK_MODE;
- + i = iter;
- + if(mode != CESA_NULL_CHECK_MODE)
- + i = 1;
- +
- + testOpen(0);
- + testOpen(1);
- + testOpen(2);
- + testOpen(3);
- +
- +/* DES / ECB mode / Encrypt only */
- + status = testRun(0, 1, iter, reqSize, checkMode);
- + printTestResults(0, status, checkMode);
- +
- +/* DES / ECB mode / Decrypt only */
- + status = testRun(1, 1, iter, reqSize, checkMode);
- + printTestResults(1, status, checkMode);
- +
- +/* DES / CBC mode / Encrypt only */
- + status = testRun(2, 2, i, reqSize, mode);
- + printTestResults(2, status, mode);
- +
- +/* DES / CBC mode / Decrypt only */
- + status = testRun(3, 2, iter, reqSize, mode);
- + printTestResults(3, status, mode);
- +
- + testClose(0);
- + testClose(1);
- + testClose(2);
- + testClose(3);
- +}
- +
- +void tripleDesTest(int iter, int reqSize, int checkMode)
- +{
- + int mode, i;
- + MV_STATUS status;
- +
- + mode = checkMode;
- + if(checkMode == CESA_FULL_CHECK_MODE)
- + mode = CESA_FAST_CHECK_MODE;
- + i = iter;
- + if(mode != CESA_NULL_CHECK_MODE)
- + i = 1;
- +
- + testOpen(100);
- + testOpen(101);
- + testOpen(102);
- + testOpen(103);
- +
- +/* 3DES / ECB mode / Encrypt only */
- + status = testRun(100, 1, iter, reqSize, checkMode);
- + printTestResults(100, status, checkMode);
- +
- +/* 3DES / ECB mode / Decrypt only */
- + status = testRun(101, 1, iter, reqSize, checkMode);
- + printTestResults(101, status, checkMode);
- +
- +/* 3DES / CBC mode / Encrypt only */
- + status = testRun(102, 2, i, reqSize, mode);
- + printTestResults(102, status, mode);
- +
- +/* 3DES / CBC mode / Decrypt only */
- + status = testRun(103, 2, iter, reqSize, mode);
- + printTestResults(103, status, mode);
- +
- + testClose(100);
- + testClose(101);
- + testClose(102);
- + testClose(103);
- +}
- +
- +void aesTest(int iter, int reqSize, int checkMode)
- +{
- + MV_STATUS status;
- + int mode, i;
- +
- + mode = checkMode;
- + if(checkMode == CESA_FULL_CHECK_MODE)
- + mode = CESA_FAST_CHECK_MODE;
- +
- + i = iter;
- + if(mode != CESA_NULL_CHECK_MODE)
- + i = 1;
- +
- + testOpen(200);
- + testOpen(201);
- + testOpen(202);
- + testOpen(203);
- + testOpen(204);
- + testOpen(205);
- + testOpen(206);
- + testOpen(207);
- + testOpen(208);
- +
- +/* AES-128 Encode ECB mode */
- + status = testRun(200, 3, iter, reqSize, checkMode);
- + printTestResults(200, status, checkMode);
- +
- +/* AES-128 Decode ECB mode */
- + status = testRun(201, 3, iter, reqSize, checkMode);
- + printTestResults(201, status, checkMode);
- +
- +/* AES-128 Encode CBC mode (IV from SA) */
- + status = testRun(202, 10, i, reqSize, mode);
- + printTestResults(202, status, mode);
- +
- +/* AES-128 Encode CBC mode (IV from User) */
- + status = testRun(202, 24, i, reqSize, mode);
- + printTestResults(202, status, mode);
- +
- +/* AES-128 Decode CBC mode */
- + status = testRun(203, 24, iter, reqSize, mode);
- + printTestResults(203, status, checkMode);
- +
- +/* AES-192 Encode ECB mode */
- + status = testRun(204, 4, iter, reqSize, checkMode);
- + printTestResults(204, status, checkMode);
- +
- +/* AES-192 Decode ECB mode */
- + status = testRun(205, 4, iter, reqSize, checkMode);
- + printTestResults(205, status, checkMode);
- +
- +/* AES-256 Encode ECB mode */
- + status = testRun(206, 5, iter, reqSize, checkMode);
- + printTestResults(206, status, checkMode);
- +
- +/* AES-256 Decode ECB mode */
- + status = testRun(207, 5, iter, reqSize, checkMode);
- + printTestResults(207, status, checkMode);
- +
- +#if defined(MV_LINUX)
- +/* AES-128 Encode CTR mode */
- + status = testRun(208, 23, iter, reqSize, mode);
- + printTestResults(208, status, checkMode);
- +#endif
- + testClose(200);
- + testClose(201);
- + testClose(202);
- + testClose(203);
- + testClose(204);
- + testClose(205);
- + testClose(206);
- + testClose(207);
- + testClose(208);
- +}
- +
- +
- +void mdTest(int iter, int reqSize, int checkMode)
- +{
- + int mode;
- + MV_STATUS status;
- +
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + mode = checkMode;
- + if(checkMode == CESA_FULL_CHECK_MODE)
- + mode = CESA_FAST_CHECK_MODE;
- +
- + testOpen(300);
- + testOpen(301);
- + testOpen(302);
- + testOpen(303);
- + testOpen(305);
- +
- +/* HMAC-MD5 Generate signature test */
- + status = testRun(300, 6, iter, reqSize, mode);
- + printTestResults(300, status, checkMode);
- +
- +/* HMAC-MD5 Verify Signature test */
- + status = testRun(301, 7, iter, reqSize, mode);
- + printTestResults(301, status, checkMode);
- +
- +/* HMAC-MD5 Generate signature test */
- + status = testRun(302, 8, iter, reqSize, mode);
- + printTestResults(302, status, checkMode);
- +
- +/* HMAC-MD5 Verify Signature test */
- + status = testRun(303, 9, iter, reqSize, mode);
- + printTestResults(303, status, checkMode);
- +
- +/* HASH-MD5 Generate signature test */
- + status = testRun(305, 15, iter, reqSize, mode);
- + printTestResults(305, status, checkMode);
- +
- + testClose(300);
- + testClose(301);
- + testClose(302);
- + testClose(303);
- + testClose(305);
- +}
- +
- +void shaTest(int iter, int reqSize, int checkMode)
- +{
- + int mode;
- + MV_STATUS status;
- +
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + mode = checkMode;
- + if(checkMode == CESA_FULL_CHECK_MODE)
- + mode = CESA_FAST_CHECK_MODE;
- +
- + testOpen(400);
- + testOpen(401);
- + testOpen(402);
- + testOpen(403);
- + testOpen(405);
- +
- +/* HMAC-SHA1 Generate signature test */
- + status = testRun(400, 11, iter, reqSize, mode);
- + printTestResults(400, status, checkMode);
- +
- +/* HMAC-SHA1 Verify Signature test */
- + status = testRun(401, 12, iter, reqSize, mode);
- + printTestResults(401, status, checkMode);
- +
- +/* HMAC-SHA1 Generate signature test */
- + status = testRun(402, 13, iter, reqSize, mode);
- + printTestResults(402, status, checkMode);
- +
- +/* HMAC-SHA1 Verify Signature test */
- + status = testRun(403, 14, iter, reqSize, mode);
- + printTestResults(403, status, checkMode);
- +
- +/* HMAC-SHA1 Generate signature test */
- + status = testRun(405, 16, iter, reqSize, mode);
- + printTestResults(405, status, checkMode);
- +
- + testClose(400);
- + testClose(401);
- + testClose(402);
- + testClose(403);
- + testClose(405);
- +}
- +
- +void combiTest(int iter, int reqSize, int checkMode)
- +{
- + MV_STATUS status;
- + int mode, i;
- +
- + mode = checkMode;
- + if(checkMode == CESA_FULL_CHECK_MODE)
- + mode = CESA_FAST_CHECK_MODE;
- +
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + i = iter;
- + if(mode != CESA_NULL_CHECK_MODE)
- + i = 1;
- +
- + testOpen(500);
- + testOpen(501);
- + testOpen(502);
- + testOpen(503);
- + testOpen(504);
- + testOpen(505);
- + testOpen(506);
- + testOpen(507);
- +
- +/* DES ECB + MD5 encode test */
- + status = testRun(500, 17, iter, reqSize, mode);
- + printTestResults(500, status, mode);
- +
- +/* DES ECB + SHA1 encode test */
- + status = testRun(501, 18, iter, reqSize, mode);
- + printTestResults(501, status, mode);
- +
- +/* 3DES ECB + MD5 encode test */
- + status = testRun(502, 17, iter, reqSize, mode);
- + printTestResults(502, status, mode);
- +
- +/* 3DES ECB + SHA1 encode test */
- + status = testRun(503, 18, iter, reqSize, mode);
- + printTestResults(503, status, mode);
- +
- +/* 3DES CBC + MD5 encode test */
- + status = testRun(504, 19, i, reqSize, mode);
- + printTestResults(504, status, mode);
- +
- +/* 3DES CBC + SHA1 encode test */
- + status = testRun(505, 20, i, reqSize, mode);
- + printTestResults(505, status, mode);
- +
- +/* AES-128 CBC + MD5 encode test */
- + status = testRun(506, 21, i, reqSize, mode);
- + printTestResults(506, status, mode);
- +
- +/* AES-128 CBC + SHA1 encode test */
- + status = testRun(507, 22, i, reqSize, mode);
- + printTestResults(507, status, mode);
- +
- + testClose(500);
- + testClose(501);
- + testClose(502);
- + testClose(503);
- + testClose(504);
- + testClose(505);
- + testClose(506);
- + testClose(507);
- +}
- +
- +void cesaOneTest(int testIdx, int caseIdx,
- + int iter, int reqSize, int checkMode)
- +{
- + MV_STATUS status;
- +
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + mvOsPrintf("test=%d, case=%d, size=%d, iter=%d\n",
- + testIdx, caseIdx, reqSize, iter);
- +
- + status = testOpen(testIdx);
- +
- + status = testRun(testIdx, caseIdx, iter, reqSize, checkMode);
- + printTestResults(testIdx, status, checkMode);
- + status = testClose(testIdx);
- +
- +}
- +
- +void cesaTest(int iter, int reqSize, int checkMode)
- +{
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + mvOsPrintf("%d iteration\n", iter);
- + mvOsPrintf("%d size\n\n", reqSize);
- +
- +/* DES tests */
- + desTest(iter, reqSize, checkMode);
- +
- +/* 3DES tests */
- + tripleDesTest(iter, reqSize, checkMode);
- +
- +/* AES tests */
- + aesTest(iter, reqSize, checkMode);
- +
- +/* MD5 tests */
- + mdTest(iter, reqSize, checkMode);
- +
- +/* SHA-1 tests */
- + shaTest(iter, reqSize, checkMode);
- +}
- +
- +void multiSizeTest(int idx, int iter, int checkMode, char* inputData)
- +{
- + MV_STATUS status;
- + int i;
- + MV_CESA_SIZE_TEST* pMultiTest;
- +
- + if( testOpen(idx) != MV_OK)
- + return;
- +
- + if(iter == 0)
- + iter = CESA_DEF_ITER_NUM;
- +
- + if(checkMode == CESA_SHOW_CHECK_MODE)
- + {
- + iter = 1;
- + }
- + else
- + checkMode = CESA_FULL_CHECK_MODE;
- +
- + cesaTestCases[0].plainHexStr = inputData;
- + cesaTestCases[0].pCryptoIV = NULL;
- +
- + switch(idx)
- + {
- + case 302:
- + pMultiTest = mdMultiSizeTest302;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = cesaDataHexStr3;
- + break;
- +
- + case 304:
- + pMultiTest = mdMultiSizeTest304;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 305:
- + pMultiTest = mdMultiSizeTest305;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 402:
- + pMultiTest = shaMultiSizeTest402;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 404:
- + pMultiTest = shaMultiSizeTest404;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 405:
- + pMultiTest = shaMultiSizeTest405;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 502:
- + pMultiTest = tripleDesMdMultiSizeTest502;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 503:
- + pMultiTest = tripleDesShaMultiSizeTest503;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 504:
- + iter = 1;
- + pMultiTest = cbc3desMdMultiSizeTest504;
- + cesaTestCases[0].pCryptoIV = iv1;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 505:
- + iter = 1;
- + pMultiTest = cbc3desShaMultiSizeTest505;
- + cesaTestCases[0].pCryptoIV = iv1;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 506:
- + iter = 1;
- + pMultiTest = cbcAes128md5multiSizeTest506;
- + cesaTestCases[0].pCryptoIV = iv5;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + case 507:
- + iter = 1;
- + pMultiTest = cbcAes128sha1multiSizeTest507;
- + cesaTestCases[0].pCryptoIV = iv5;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + break;
- +
- + default:
- + iter = 1;
- + checkMode = CESA_SHOW_CHECK_MODE;
- + pMultiTest = mdMultiSizeTest302;
- + if(inputData == NULL)
- + cesaTestCases[0].plainHexStr = hashHexStr80;
- + }
- + i = 0;
- + while(pMultiTest[i].outputHexStr != NULL)
- + {
- + cesaTestCases[0].cipherHexStr = (char *)pMultiTest[i].outputHexStr;
- + status = testRun(idx, 0, iter, pMultiTest[i].size,
- + checkMode);
- + if(checkMode != CESA_SHOW_CHECK_MODE)
- + {
- + cesaReqSize = pMultiTest[i].size;
- + printTestResults(idx, status, checkMode);
- + }
- + if(status != MV_OK)
- + break;
- + i++;
- + }
- + testClose(idx);
- +/*
- + mvCesaDebugStatus();
- + cesaTestPrintStatus();
- +*/
- +}
- +
- +void open_session_test(int idx, int caseIdx, int iter)
- +{
- + int reqIdError, cryptoError, openErrors, i;
- + int openErrDisp[100];
- + MV_STATUS status;
- +
- + memset(openErrDisp, 0, sizeof(openErrDisp));
- + openErrors = 0;
- + reqIdError = 0;
- + cryptoError = 0;
- + for(i=0; i<iter; i++)
- + {
- + status = testOpen(idx);
- + if(status != MV_OK)
- + {
- + openErrors++;
- + openErrDisp[status]++;
- + }
- + else
- + {
- + testRun(idx, caseIdx, 1, 0, CESA_FAST_CHECK_MODE);
- + if(cesaCryptoError > 0)
- + cryptoError++;
- + if(cesaReqIdError > 0)
- + reqIdError++;
- +
- + testClose(idx);
- + }
- + }
- + if(cryptoError > 0)
- + mvOsPrintf("cryptoError : %d\n", cryptoError);
- + if(reqIdError > 0)
- + mvOsPrintf("reqIdError : %d\n", reqIdError);
- +
- + if(openErrors > 0)
- + {
- + mvOsPrintf("Open Errors = %d\n", openErrors);
- + for(i=0; i<100; i++)
- + {
- + if(openErrDisp[i] != 0)
- + mvOsPrintf("Error %d - occurs %d times\n", i, openErrDisp[i]);
- + }
- + }
- +}
- +
- +
- +void loopback_test(int idx, int iter, int size, char* pPlainData)
- +{
- +}
- +
- +
- +#if defined(MV_VXWORKS)
- +int testMode = 0;
- +unsigned __TASKCONV cesaTask(void* args)
- +{
- + int reqSize = cesaReqSize;
- +
- + if(testMode == 0)
- + {
- + cesaOneTest(cesaTestIdx, cesaCaseIdx, cesaIteration,
- + reqSize, cesaCheckMode);
- + }
- + else
- + {
- + if(testMode == 1)
- + {
- + cesaTest(cesaIteration, reqSize, cesaCheckMode);
- + combiTest(cesaIteration, reqSize, cesaCheckMode);
- + }
- + else
- + {
- + multiSizeTest(cesaIdx, cesaIteration, cesaCheckMode, NULL);
- + }
- + }
- + return 0;
- +}
- +
- +void oneTest(int testIdx, int caseIdx,
- + int iter, int reqSize, int checkMode)
- +{
- + long rc;
- +
- + cesaIteration = iter;
- + cesaReqSize = cesaRateSize = reqSize;
- + cesaCheckMode = checkMode;
- + testMode = 0;
- + cesaTestIdx = testIdx;
- + cesaCaseIdx = caseIdx;
- + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
- + if (rc != MV_OK)
- + {
- + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
- + }
- +}
- +
- +void multiTest(int iter, int reqSize, int checkMode)
- +{
- + long rc;
- +
- + cesaIteration = iter;
- + cesaCheckMode = checkMode;
- + cesaReqSize = reqSize;
- + testMode = 1;
- + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
- + if (rc != MV_OK)
- + {
- + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
- + }
- +}
- +
- +void sizeTest(int testIdx, int iter, int checkMode)
- +{
- + long rc;
- +
- + cesaIteration = iter;
- + cesaCheckMode = checkMode;
- + testMode = 2;
- + cesaIdx = testIdx;
- + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
- + if (rc != MV_OK)
- + {
- + mvOsPrintf("hMW: Can't create CESA test task, rc = %ld\n", rc);
- + }
- +}
- +
- +#endif /* MV_VXWORKS */
- +
- +extern void mvCesaDebugSA(short sid, int mode);
- +void cesaTestPrintSession(int idx)
- +{
- + int testIdx;
- + MV_CESA_TEST_SESSION* pTestSession;
- +
- + pTestSession = getTestSessionDb(idx, &testIdx);
- + if(pTestSession == NULL)
- + {
- + mvOsPrintf("Test %d is not exist\n", idx);
- + return;
- + }
- + pTestSession = &pTestSession[testIdx];
- +
- + if(pTestSession->sid == -1)
- + {
- + mvOsPrintf("Test session %d is not opened\n", idx);
- + return;
- + }
- +
- + mvCesaDebugSA(pTestSession->sid, 1);
- +}
- +
- +void cesaTestPrintStatus(void)
- +{
- + mvOsPrintf("\n\t Cesa Test Status\n\n");
- +
- + mvOsPrintf("isrCount=%d\n",
- + cesaTestIsrCount);
- +
- +#ifdef CESA_TEST_DEBUG
- + {
- + int i, j;
- + j = cesaTestTraceIdx;
- + mvOsPrintf("No Type Cause rCause iCause Res Time pReady pProc pEmpty\n");
- + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
- + {
- + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
- + j, cesaTestTrace[j].type, cesaTestTrace[j].cause, cesaTestTrace[j].realCause,
- + cesaTestTrace[j].dmaCause, cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
- + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
- + j++;
- + if(j == MV_CESA_TEST_TRACE_SIZE)
- + j = 0;
- + }
- + }
- +#endif /* CESA_TEST_DEBUG */
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.c 2010-11-09 20:28:05.822495424 +0100
- @@ -0,0 +1,158 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvOs.h"
- +#include "mvLru.h"
- +/* LRU Cache support */
- +
- +
- +/* Init LRU cache database */
- +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries)
- +{
- + int i;
- + MV_LRU_CACHE* pLruCache;
- +
- + pLruCache = mvOsMalloc(sizeof(MV_LRU_CACHE));
- + if(pLruCache == NULL)
- + {
- + return NULL;
- + }
- + memset(pLruCache, 0, sizeof(MV_LRU_CACHE));
- +
- + pLruCache->table = mvOsMalloc(numOfEntries*sizeof(MV_LRU_ENTRY));
- + if(pLruCache->table == NULL)
- + {
- + mvOsFree(pLruCache);
- + return NULL;
- + }
- + memset(pLruCache->table, 0, numOfEntries*sizeof(MV_LRU_ENTRY));
- + pLruCache->tableSize = numOfEntries;
- +
- + for(i=0; i<numOfEntries; i++)
- + {
- + pLruCache->table[i].next = i+1;
- + pLruCache->table[i].prev = i-1;
- + }
- + pLruCache->least = 0;
- + pLruCache->most = numOfEntries-1;
- +
- + return pLruCache;
- +}
- +
- +void mvLruCacheFinish(MV_LRU_CACHE* pLruCache)
- +{
- + mvOsFree(pLruCache->table);
- + mvOsFree(pLruCache);
- +}
- +
- +/* Update LRU cache database after using cache Index */
- +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx)
- +{
- + int prev, next;
- +
- + if(cacheIdx == pLruHndl->most)
- + return;
- +
- + next = pLruHndl->table[cacheIdx].next;
- + if(cacheIdx == pLruHndl->least)
- + {
- + pLruHndl->least = next;
- + }
- + else
- + {
- + prev = pLruHndl->table[cacheIdx].prev;
- +
- + pLruHndl->table[next].prev = prev;
- + pLruHndl->table[prev].next = next;
- + }
- +
- + pLruHndl->table[pLruHndl->most].next = cacheIdx;
- + pLruHndl->table[cacheIdx].prev = pLruHndl->most;
- + pLruHndl->most = cacheIdx;
- +}
- +
- +/* Delete LRU cache entry */
- +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx)
- +{
- + int prev, next;
- +
- + if(cacheIdx == pLruHndl->least)
- + return;
- +
- + prev = pLruHndl->table[cacheIdx].prev;
- + if(cacheIdx == pLruHndl->most)
- + {
- + pLruHndl->most = prev;
- + }
- + else
- + {
- + next = pLruHndl->table[cacheIdx].next;
- +
- + pLruHndl->table[next].prev = prev;
- + pLruHndl->table[prev].next = next;
- + }
- + pLruHndl->table[pLruHndl->least].prev = cacheIdx;
- + pLruHndl->table[cacheIdx].next = pLruHndl->least;
- + pLruHndl->least = cacheIdx;
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.h 2010-11-09 20:28:05.861235773 +0100
- @@ -0,0 +1,112 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +/*******************************************************************************
- +* mvLru.h - Header File for Least Recently Used Cache algorithm
- +*
- +* DESCRIPTION:
- +* This header file contains macros typedefs and function declaration for
- +* the Least Recently Used Cache algorithm.
- +*
- +*******************************************************************************/
- +
- +#ifndef __mvLru_h__
- +#define __mvLru_h__
- +
- +
- +typedef struct
- +{
- + int next;
- + int prev;
- +} MV_LRU_ENTRY;
- +
- +typedef struct
- +{
- + int least;
- + int most;
- + MV_LRU_ENTRY* table;
- + int tableSize;
- +
- +}MV_LRU_CACHE;
- +
- +
- +/* Find Cache index for replacement LRU */
- +static INLINE int mvLruCacheIdxFind(MV_LRU_CACHE* pLruHndl)
- +{
- + return pLruHndl->least;
- +}
- +
- +/* Init LRU cache module */
- +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries);
- +
- +/* Finish LRU cache module */
- +void mvLruCacheFinish(MV_LRU_CACHE* pLruHndl);
- +
- +/* Update LRU cache database after using cache Index */
- +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx);
- +
- +/* Delete LRU cache entry */
- +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx);
- +
- +
- +#endif /* __mvLru_h__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.c 2010-11-09 20:28:05.902495799 +0100
- @@ -0,0 +1,349 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvOs.h"
- +#include "mvMD5.h"
- +
- +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN]);
- +
- +#ifdef MV_CPU_LE
- +#define mvByteReverse(buf, len) /* Nothing */
- +#else
- +static void mvByteReverse(unsigned char *buf, unsigned longs);
- +
- +/*
- + * Note: this code is harmless on little-endian machines.
- + */
- +static void mvByteReverse(unsigned char *buf, unsigned longs)
- +{
- + MV_U32 t;
- +
- + do
- + {
- + t = (MV_U32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- + ((unsigned) buf[1] << 8 | buf[0]);
- + *(MV_U32 *) buf = t;
- + buf += 4;
- + } while (--longs);
- +}
- +#endif
- +
- +/*
- + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- + * initialization constants.
- + */
- +void mvMD5Init(MV_MD5_CONTEXT *ctx)
- +{
- + ctx->buf[0] = 0x67452301;
- + ctx->buf[1] = 0xefcdab89;
- + ctx->buf[2] = 0x98badcfe;
- + ctx->buf[3] = 0x10325476;
- +
- + ctx->bits[0] = 0;
- + ctx->bits[1] = 0;
- +}
- +
- +/*
- + * Update context to reflect the concatenation of another buffer full
- + * of bytes.
- + */
- +void mvMD5Update(MV_MD5_CONTEXT *ctx, unsigned char const *buf, unsigned len)
- +{
- + MV_U32 t;
- +
- + /* Update bitcount */
- +
- + t = ctx->bits[0];
- + if ((ctx->bits[0] = t + ((MV_U32) len << 3)) < t)
- + ctx->bits[1]++; /* Carry from low to high */
- + ctx->bits[1] += len >> 29;
- +
- + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
- +
- + /* Handle any leading odd-sized chunks */
- +
- + if (t)
- + {
- + unsigned char *p = (unsigned char *) ctx->in + t;
- +
- + t = 64 - t;
- + if (len < t)
- + {
- + memcpy(p, buf, len);
- + return;
- + }
- + memcpy(p, buf, t);
- + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
- + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
- + buf += t;
- + len -= t;
- + }
- + /* Process data in 64-byte chunks */
- +
- + while (len >= 64)
- + {
- + memcpy(ctx->in, buf, 64);
- + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
- + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
- + buf += 64;
- + len -= 64;
- + }
- +
- + /* Handle any remaining bytes of data. */
- +
- + memcpy(ctx->in, buf, len);
- +}
- +
- +/*
- + * Final wrapup - pad to 64-byte boundary with the bit pattern
- + * 1 0* (64-bit count of bits processed, MSB-first)
- + */
- +void mvMD5Final(unsigned char digest[MV_MD5_MAC_LEN], MV_MD5_CONTEXT *ctx)
- +{
- + unsigned count;
- + unsigned char *p;
- +
- + /* Compute number of bytes mod 64 */
- + count = (ctx->bits[0] >> 3) & 0x3F;
- +
- + /* Set the first char of padding to 0x80. This is safe since there is
- + always at least one byte free */
- + p = ctx->in + count;
- + *p++ = 0x80;
- +
- + /* Bytes of padding needed to make 64 bytes */
- + count = 64 - 1 - count;
- +
- + /* Pad out to 56 mod 64 */
- + if (count < 8)
- + {
- + /* Two lots of padding: Pad the first block to 64 bytes */
- + memset(p, 0, count);
- + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
- + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
- +
- + /* Now fill the next block with 56 bytes */
- + memset(ctx->in, 0, 56);
- + }
- + else
- + {
- + /* Pad block to 56 bytes */
- + memset(p, 0, count - 8);
- + }
- + mvByteReverse(ctx->in, 14);
- +
- + /* Append length in bits and transform */
- + ((MV_U32 *) ctx->in)[14] = ctx->bits[0];
- + ((MV_U32 *) ctx->in)[15] = ctx->bits[1];
- +
- + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
- + mvByteReverse((unsigned char *) ctx->buf, 4);
- + memcpy(digest, ctx->buf, MV_MD5_MAC_LEN);
- + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
- +}
- +
- +/* The four core functions - F1 is optimized somewhat */
- +
- +/* #define F1(x, y, z) (x & y | ~x & z) */
- +#define F1(x, y, z) (z ^ (x & (y ^ z)))
- +#define F2(x, y, z) F1(z, x, y)
- +#define F3(x, y, z) (x ^ y ^ z)
- +#define F4(x, y, z) (y ^ (x | ~z))
- +
- +/* This is the central step in the MD5 algorithm. */
- +#define MD5STEP(f, w, x, y, z, data, s) \
- + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
- +
- +/*
- + * The core of the MD5 algorithm, this alters an existing MD5 hash to
- + * reflect the addition of 16 longwords of new data. MD5Update blocks
- + * the data and converts bytes into longwords for this routine.
- + */
- +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN])
- +{
- + register MV_U32 a, b, c, d;
- +
- + a = buf[0];
- + b = buf[1];
- + c = buf[2];
- + d = buf[3];
- +
- + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
- +
- + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
- +
- + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
- +
- + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
- +
- + buf[0] += a;
- + buf[1] += b;
- + buf[2] += c;
- + buf[3] += d;
- +}
- +
- +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest)
- +{
- + MV_MD5_CONTEXT ctx;
- +
- + mvMD5Init(&ctx);
- + mvMD5Update(&ctx, buf, len);
- + mvMD5Final(digest, &ctx);
- +}
- +
- +
- +void mvHmacMd5(unsigned char const* text, int text_len,
- + unsigned char const* key, int key_len,
- + unsigned char* digest)
- +{
- + int i;
- + MV_MD5_CONTEXT ctx;
- + unsigned char k_ipad[64+1]; /* inner padding - key XORd with ipad */
- + unsigned char k_opad[64+1]; /* outer padding - key XORd with opad */
- +
- + /* start out by storing key in pads */
- + memset(k_ipad, 0, 64);
- + memcpy(k_ipad, key, key_len);
- + memset(k_opad, 0, 64);
- + memcpy(k_opad, key, key_len);
- +
- + /* XOR key with ipad and opad values */
- + for (i=0; i<64; i++)
- + {
- + k_ipad[i] ^= 0x36;
- + k_opad[i] ^= 0x5c;
- + }
- +
- + /* perform inner MD5 */
- + mvMD5Init(&ctx); /* init ctx for 1st pass */
- + mvMD5Update(&ctx, k_ipad, 64); /* start with inner pad */
- + mvMD5Update(&ctx, text, text_len); /* then text of datagram */
- + mvMD5Final(digest, &ctx); /* finish up 1st pass */
- +
- + /* perform outer MD5 */
- + mvMD5Init(&ctx); /* init ctx for 2nd pass */
- + mvMD5Update(&ctx, k_opad, 64); /* start with outer pad */
- + mvMD5Update(&ctx, digest, 16); /* then results of 1st hash */
- + mvMD5Final(digest, &ctx); /* finish up 2nd pass */
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.h 2010-11-09 20:28:05.942495390 +0100
- @@ -0,0 +1,93 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __mvMD5_h__
- +#define __mvMD5_h__
- +
- +#include "mvMD5.h"
- +
- +#define MV_MD5_MAC_LEN 16
- +
- +
- +typedef struct
- +{
- + MV_U32 buf[4];
- + MV_U32 bits[2];
- + MV_U8 in[64];
- +
- +} MV_MD5_CONTEXT;
- +
- +void mvMD5Init(MV_MD5_CONTEXT *context);
- +void mvMD5Update(MV_MD5_CONTEXT *context, unsigned char const *buf,
- + unsigned len);
- +void mvMD5Final(unsigned char digest[16], MV_MD5_CONTEXT *context);
- +
- +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest);
- +
- +void mvHmacMd5(unsigned char const* text, int text_len,
- + unsigned char const* key, int key_len,
- + unsigned char* digest);
- +
- +
- +#endif /* __mvMD5_h__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.c 2010-11-09 20:28:05.972495400 +0100
- @@ -0,0 +1,239 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvOs.h"
- +#include "mvSHA1.h"
- +
- +#define SHA1HANDSOFF
- +
- +typedef union
- +{
- + MV_U8 c[64];
- + MV_U32 l[16];
- +
- +} CHAR64LONG16;
- +
- +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer);
- +
- +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
- +
- +
- +#ifdef MV_CPU_LE
- +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
- + (rol(block->l[i], 8) & 0x00FF00FF))
- +#else
- +#define blk0(i) block->l[i]
- +#endif
- +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
- + block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
- +
- +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
- +#define R0(v,w,x,y,z,i) \
- + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
- + w = rol(w, 30);
- +#define R1(v,w,x,y,z,i) \
- + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
- + w = rol(w, 30);
- +#define R2(v,w,x,y,z,i) \
- + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
- +#define R3(v,w,x,y,z,i) \
- + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
- + w = rol(w, 30);
- +#define R4(v,w,x,y,z,i) \
- + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
- + w=rol(w, 30);
- +
- +/* Hash a single 512-bit block. This is the core of the algorithm. */
- +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer)
- +{
- + MV_U32 a, b, c, d, e;
- + CHAR64LONG16* block;
- +
- +#ifdef SHA1HANDSOFF
- + static MV_U32 workspace[16];
- +
- + block = (CHAR64LONG16 *) workspace;
- + memcpy(block, buffer, 64);
- +#else
- + block = (CHAR64LONG16 *) buffer;
- +#endif
- + /* Copy context->state[] to working vars */
- + a = state[0];
- + b = state[1];
- + c = state[2];
- + d = state[3];
- + e = state[4];
- + /* 4 rounds of 20 operations each. Loop unrolled. */
- + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- + /* Add the working vars back into context.state[] */
- + state[0] += a;
- + state[1] += b;
- + state[2] += c;
- + state[3] += d;
- + state[4] += e;
- + /* Wipe variables */
- + a = b = c = d = e = 0;
- +}
- +
- +void mvSHA1Init(MV_SHA1_CTX* context)
- +{
- + /* SHA1 initialization constants */
- + context->state[0] = 0x67452301;
- + context->state[1] = 0xEFCDAB89;
- + context->state[2] = 0x98BADCFE;
- + context->state[3] = 0x10325476;
- + context->state[4] = 0xC3D2E1F0;
- + context->count[0] = context->count[1] = 0;
- +}
- +
- +
- +/* Run your data through this. */
- +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *data,
- + unsigned int len)
- +{
- + MV_U32 i, j;
- +
- + j = (context->count[0] >> 3) & 63;
- + if ((context->count[0] += len << 3) < (len << 3))
- + context->count[1]++;
- + context->count[1] += (len >> 29);
- + if ((j + len) > 63)
- + {
- + memcpy(&context->buffer[j], data, (i = 64-j));
- + mvSHA1Transform(context->state, context->buffer);
- + for ( ; i + 63 < len; i += 64)
- + {
- + mvSHA1Transform(context->state, &data[i]);
- + }
- + j = 0;
- + }
- + else
- + {
- + i = 0;
- + }
- + memcpy(&context->buffer[j], &data[i], len - i);
- +}
- +
- +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX* context)
- +{
- + MV_U32 i;
- + MV_U8 finalcount[8];
- +
- + for (i = 0; i < 8; i++)
- + {
- + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
- + ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- + }
- + mvSHA1Update(context, (const unsigned char *) "\200", 1);
- + while ((context->count[0] & 504) != 448)
- + {
- + mvSHA1Update(context, (const unsigned char *) "\0", 1);
- + }
- + mvSHA1Update(context, finalcount, 8); /* Should cause a mvSHA1Transform()
- + */
- + for (i = 0; i < 20; i++)
- + {
- + digest[i] = (unsigned char)
- + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
- + }
- + /* Wipe variables */
- + i = 0;
- + memset(context->buffer, 0, 64);
- + memset(context->state, 0, 20);
- + memset(context->count, 0, 8);
- + memset(finalcount, 0, 8);
- +
- +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
- + mvSHA1Transform(context->state, context->buffer);
- +#endif
- +}
- +
- +
- +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest)
- +{
- + MV_SHA1_CTX ctx;
- +
- + mvSHA1Init(&ctx);
- + mvSHA1Update(&ctx, buf, len);
- + mvSHA1Final(digest, &ctx);
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.h 2010-11-09 20:28:06.012495345 +0100
- @@ -0,0 +1,88 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __mvSHA1_h__
- +#define __mvSHA1_h__
- +
- +#include "mvSHA1.h"
- +
- +#define MV_SHA1_MAC_LEN 20
- +
- +
- +typedef struct
- +{
- + MV_U32 state[5];
- + MV_U32 count[2];
- + MV_U8 buffer[64];
- +
- +} MV_SHA1_CTX;
- +
- +void mvSHA1Init(MV_SHA1_CTX *context);
- +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *buf, unsigned int len);
- +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX *context);
- +
- +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest);
- +
- +
- +#endif /* __mvSHA1_h__ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c linux-2.6.36/crypto/ocf/kirkwood/cesa_ocf_drv.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/cesa_ocf_drv.c 2010-11-09 20:28:06.052495403 +0100
- @@ -0,0 +1,1296 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +*******************************************************************************/
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/sched.h>
- +#include <linux/wait.h>
- +#include <linux/crypto.h>
- +#include <linux/mm.h>
- +#include <linux/skbuff.h>
- +#include <linux/random.h>
- +#include <linux/platform_device.h>
- +#include <asm/scatterlist.h>
- +#include <linux/spinlock.h>
- +#include "ctrlEnv/sys/mvSysCesa.h"
- +#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */
- +#include <cryptodev.h>
- +#include <uio.h>
- +#include <plat/mv_cesa.h>
- +#include <linux/mbus.h>
- +#include "mvDebug.h"
- +
- +#include "cesa/mvMD5.h"
- +#include "cesa/mvSHA1.h"
- +
- +#include "cesa/mvCesaRegs.h"
- +#include "cesa/AES/mvAes.h"
- +#include "cesa/mvLru.h"
- +
- +#undef RT_DEBUG
- +#ifdef RT_DEBUG
- +static int debug = 1;
- +module_param(debug, int, 1);
- +MODULE_PARM_DESC(debug, "Enable debug");
- +#undef dprintk
- +#define dprintk(a...) if (debug) { printk(a); } else
- +#else
- +static int debug = 0;
- +#undef dprintk
- +#define dprintk(a...)
- +#endif
- +
- +
- +/* TDMA Regs */
- +#define WINDOW_BASE(i) 0xA00 + (i << 3)
- +#define WINDOW_CTRL(i) 0xA04 + (i << 3)
- +
- +/* interrupt handling */
- +#undef CESA_OCF_POLLING
- +#undef CESA_OCF_TASKLET
- +
- +#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)
- +#error "don't use both tasklet and polling mode"
- +#endif
- +
- +extern int cesaReqResources;
- +/* support for spliting action into 2 actions */
- +#define CESA_OCF_SPLIT
- +
- +/* general defines */
- +#define CESA_OCF_MAX_SES 128
- +#define CESA_Q_SIZE 64
- +
- +
- +/* data structures */
- +struct cesa_ocf_data {
- + int cipher_alg;
- + int auth_alg;
- + int encrypt_tn_auth;
- +#define auth_tn_decrypt encrypt_tn_auth
- + int ivlen;
- + int digestlen;
- + short sid_encrypt;
- + short sid_decrypt;
- + /* fragment workaround sessions */
- + short frag_wa_encrypt;
- + short frag_wa_decrypt;
- + short frag_wa_auth;
- +};
- +
- +/* CESA device data */
- +struct cesa_dev {
- + void __iomem *sram;
- + void __iomem *reg;
- + struct mv_cesa_platform_data *plat_data;
- + int irq;
- +};
- +
- +#define DIGEST_BUF_SIZE 32
- +struct cesa_ocf_process {
- + MV_CESA_COMMAND cesa_cmd;
- + MV_CESA_MBUF cesa_mbuf;
- + MV_BUF_INFO cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];
- + char digest[DIGEST_BUF_SIZE];
- + int digest_len;
- + struct cryptop *crp;
- + int need_cb;
- +};
- +
- +/* global variables */
- +static int32_t cesa_ocf_id = -1;
- +static struct cesa_ocf_data *cesa_ocf_sessions[CESA_OCF_MAX_SES];
- +static spinlock_t cesa_lock;
- +static struct cesa_dev cesa_device;
- +
- +/* static APIs */
- +static int cesa_ocf_process (device_t, struct cryptop *, int);
- +static int cesa_ocf_newsession (device_t, u_int32_t *, struct cryptoini *);
- +static int cesa_ocf_freesession (device_t, u_int64_t);
- +static void cesa_callback (unsigned long);
- +static irqreturn_t cesa_interrupt_handler (int, void *);
- +#ifdef CESA_OCF_POLLING
- +static void cesa_interrupt_polling(void);
- +#endif
- +#ifdef CESA_OCF_TASKLET
- +static struct tasklet_struct cesa_ocf_tasklet;
- +#endif
- +
- +static struct timeval tt_start;
- +static struct timeval tt_end;
- +
- +/*
- + * dummy device structure
- + */
- +
- +static struct {
- + softc_device_decl sc_dev;
- +} mv_cesa_dev;
- +
- +static device_method_t mv_cesa_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, cesa_ocf_newsession),
- + DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),
- + DEVMETHOD(cryptodev_process, cesa_ocf_process),
- + DEVMETHOD(cryptodev_kprocess, NULL),
- +};
- +
- +
- +
- +/* Add debug Trace */
- +#undef CESA_OCF_TRACE_DEBUG
- +#ifdef CESA_OCF_TRACE_DEBUG
- +
- +#define MV_CESA_USE_TIMER_ID 0
- +
- +typedef struct
- +{
- + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
- + MV_U32 timeStamp;
- + MV_U32 cause;
- + MV_U32 realCause;
- + MV_U32 dmaCause;
- + int resources;
- + MV_CESA_REQ* pReqReady;
- + MV_CESA_REQ* pReqEmpty;
- + MV_CESA_REQ* pReqProcess;
- +} MV_CESA_TEST_TRACE;
- +
- +#define MV_CESA_TEST_TRACE_SIZE 50
- +
- +static int cesaTestTraceIdx = 0;
- +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
- +
- +static void cesaTestTraceAdd(int type)
- +{
- + cesaTestTrace[cesaTestTraceIdx].type = type;
- + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
- + //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);
- + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
- + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
- + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
- + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
- + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
- + cesaTestTraceIdx++;
- + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
- + cesaTestTraceIdx = 0;
- +}
- +
- +#else /* CESA_OCF_TRACE_DEBUG */
- +
- +#define cesaTestTraceAdd(x)
- +
- +#endif /* CESA_OCF_TRACE_DEBUG */
- +
- +unsigned int
- +get_usec(unsigned int start)
- +{
- + if(start) {
- + do_gettimeofday (&tt_start);
- + return 0;
- + }
- + else {
- + do_gettimeofday (&tt_end);
- + tt_end.tv_sec -= tt_start.tv_sec;
- + tt_end.tv_usec -= tt_start.tv_usec;
- + if (tt_end.tv_usec < 0) {
- + tt_end.tv_usec += 1000 * 1000;
- + tt_end.tv_sec -= 1;
- + }
- + }
- + printk("time taken is %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));
- + return (tt_end.tv_usec + tt_end.tv_sec * 1000000);
- +}
- +
- +#ifdef RT_DEBUG
- +/*
- + * check that the crp action match the current session
- + */
- +static int
- +ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {
- + int count = 0;
- + int encrypt = 0, decrypt = 0, auth = 0;
- + struct cryptodesc *crd;
- +
- + /* Go through crypto descriptors, processing as we go */
- + for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {
- + if(count > 2) {
- + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- + return 1;
- + }
- +
- + /* Encryption /Decryption */
- + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
- + /* check that the action is compatible with session */
- + if(encrypt || decrypt) {
- + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- + return 1;
- + }
- +
- + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
- + if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {
- + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- + return 1;
- + }
- + encrypt++;
- + }
- + else { /* decrypt */
- + if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {
- + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- + return 1;
- + }
- + decrypt++;
- + }
- +
- + }
- + /* Authentication */
- + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
- + /* check that the action is compatible with session */
- + if(auth) {
- + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- + return 1;
- + }
- + if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
- + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- + return 1;
- + }
- + if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {
- + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- + return 1;
- + }
- + auth++;
- + }
- + else {
- + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
- + return 1;
- + }
- + }
- + return 0;
- +
- +}
- +#endif
- +
- +/*
- + * Process a request.
- + */
- +static int
- +cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
- + struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;
- + MV_CESA_COMMAND *cesa_cmd;
- + struct cryptodesc *crd;
- + struct cesa_ocf_data *cesa_ocf_cur_ses;
- + int sid = 0, temp_len = 0, i;
- + int encrypt = 0, decrypt = 0, auth = 0;
- + int status;
- + struct sk_buff *skb = NULL;
- + struct uio *uiop = NULL;
- + unsigned char *ivp;
- + MV_BUF_INFO *p_buf_info;
- + MV_CESA_MBUF *p_mbuf_info;
- + unsigned long flags;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + if( cesaReqResources <= 1 ) {
- + dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);
- + return ERESTART;
- + }
- +
- +#ifdef RT_DEBUG
- + /* Sanity check */
- + if (crp == NULL) {
- + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {
- + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + return EINVAL;
- + }
- +
- + sid = crp->crp_sid & 0xffffffff;
- + if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {
- + crp->crp_etype = ENOENT;
- + printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);
- + return EINVAL;
- + }
- +#endif
- +
- + sid = crp->crp_sid & 0xffffffff;
- + crp->crp_etype = 0;
- + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
- +
- +#ifdef RT_DEBUG
- + if(ocf_check_action(crp, cesa_ocf_cur_ses)){
- + goto p_error;
- + }
- +#endif
- +
- + /* malloc a new cesa process */
- + cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
- +
- + if (cesa_ocf_cmd == NULL) {
- + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
- + goto p_error;
- + }
- + memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));
- +
- + /* init cesa_process */
- + cesa_ocf_cmd->crp = crp;
- + /* always call callback */
- + cesa_ocf_cmd->need_cb = 1;
- +
- + /* init cesa_cmd for usage of the HALs */
- + cesa_cmd = &cesa_ocf_cmd->cesa_cmd;
- + cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;
- + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */
- +
- + /* prepare src buffer */
- + /* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth. */
- + /* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */
- + /* from skip to crd_len. */
- + p_buf_info = cesa_ocf_cmd->cesa_bufs;
- + p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;
- +
- + p_buf_info += 2; /* save 2 first buffers for IV and digest -
- + we won't append them to the end since, they
- + might be places in an unaligned addresses. */
- +
- + p_mbuf_info->pFrags = p_buf_info;
- + temp_len = 0;
- +
- + /* handle SKB */
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- +
- + dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);
- + skb = (struct sk_buff *) crp->crp_buf;
- +
- + if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {
- + printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);
- + goto p_error;
- + }
- +
- + p_mbuf_info->mbufSize = skb->len;
- + temp_len = skb->len;
- + /* first skb fragment */
- + p_buf_info->bufSize = skb_headlen(skb);
- + p_buf_info->bufVirtPtr = skb->data;
- + p_buf_info++;
- +
- + /* now handle all other skb fragments */
- + for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {
- + skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- + p_buf_info->bufSize = frag->size;
- + p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;
- + p_buf_info++;
- + }
- + p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;
- + }
- + /* handle UIO */
- + else if(crp->crp_flags & CRYPTO_F_IOV) {
- +
- + dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);
- + uiop = (struct uio *) crp->crp_buf;
- +
- + if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {
- + printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);
- + goto p_error;
- + }
- +
- + p_mbuf_info->mbufSize = crp->crp_ilen;
- + p_mbuf_info->numFrags = uiop->uio_iovcnt;
- + for(i = 0; i < uiop->uio_iovcnt; i++) {
- + p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;
- + p_buf_info->bufSize = uiop->uio_iov[i].iov_len;
- + temp_len += p_buf_info->bufSize;
- + dprintk("%s,%d: buf %x-> addr %x, size %x \n"
- + , __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);
- + p_buf_info++;
- + }
- +
- + }
- + /* handle CONTIG */
- + else {
- + dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__);
- + p_mbuf_info->numFrags = 1;
- + p_mbuf_info->mbufSize = crp->crp_ilen;
- + p_buf_info->bufVirtPtr = crp->crp_buf;
- + p_buf_info->bufSize = crp->crp_ilen;
- + temp_len = crp->crp_ilen;
- + p_buf_info++;
- + }
- +
- + /* Support up to 64K why? cause! */
- + if(crp->crp_ilen > 64*1024) {
- + printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);
- + goto p_error;
- + }
- +
- + if( temp_len != crp->crp_ilen ) {
- + printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);
- + }
- +
- + cesa_cmd->pSrc = p_mbuf_info;
- + cesa_cmd->pDst = p_mbuf_info;
- +
- + /* restore p_buf_info to point to first available buf */
- + p_buf_info = cesa_ocf_cmd->cesa_bufs;
- + p_buf_info += 1;
- +
- +
- + /* Go through crypto descriptors, processing as we go */
- + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
- +
- + /* Encryption /Decryption */
- + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
- +
- + dprintk("%s,%d: cipher", __FILE__, __LINE__);
- +
- + cesa_cmd->cryptoOffset = crd->crd_skip;
- + cesa_cmd->cryptoLength = crd->crd_len;
- +
- + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
- + dprintk(" encrypt \n");
- + encrypt++;
- +
- + /* handle IV */
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT) { /* IV from USER */
- + dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);
- + cesa_cmd->ivFromUser = 1;
- + ivp = crd->crd_iv;
- +
- + /*
- + * do we have to copy the IV back to the buffer ?
- + */
- + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- + dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
- + cesa_cmd->ivOffset = crd->crd_inject;
- + crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
- + }
- + else {
- + dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);
- + p_mbuf_info->numFrags++;
- + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
- + p_mbuf_info->pFrags = p_buf_info;
- +
- + p_buf_info->bufVirtPtr = ivp;
- + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
- + p_buf_info--;
- +
- + /* offsets */
- + cesa_cmd->ivOffset = 0;
- + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
- + if(auth) {
- + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
- + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
- + }
- + }
- + }
- + else { /* random IV */
- + dprintk("%s,%d: random IV \n", __FILE__, __LINE__);
- + cesa_cmd->ivFromUser = 0;
- +
- + /*
- + * do we have to copy the IV back to the buffer ?
- + */
- + /* in this mode the HAL will always copy the IV */
- + /* given by the session to the ivOffset */
- + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- + cesa_cmd->ivOffset = crd->crd_inject;
- + }
- + else {
- + /* if IV isn't copy, then how will the user know which IV did we use??? */
- + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + goto p_error;
- + }
- + }
- + }
- + else { /* decrypt */
- + dprintk(" decrypt \n");
- + decrypt++;
- + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;
- +
- + /* handle IV */
- + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
- + dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);
- + /* append the IV buf to the mbuf */
- + cesa_cmd->ivFromUser = 1;
- + p_mbuf_info->numFrags++;
- + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
- + p_mbuf_info->pFrags = p_buf_info;
- +
- + p_buf_info->bufVirtPtr = crd->crd_iv;
- + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
- + p_buf_info--;
- +
- + /* offsets */
- + cesa_cmd->ivOffset = 0;
- + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
- + if(auth) {
- + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
- + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
- + }
- + }
- + else {
- + dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);
- + cesa_cmd->ivFromUser = 0;
- + cesa_cmd->ivOffset = crd->crd_inject;
- + }
- + }
- +
- + }
- + /* Authentication */
- + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
- + dprintk("%s,%d: Authentication \n", __FILE__, __LINE__);
- + auth++;
- + cesa_cmd->macOffset = crd->crd_skip;
- + cesa_cmd->macLength = crd->crd_len;
- +
- + /* digest + mac */
- + cesa_cmd->digestOffset = crd->crd_inject;
- + }
- + else {
- + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
- + goto p_error;
- + }
- + }
- +
- + dprintk("\n");
- + dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);
- + dprintk("%s,%d: IV from user: %d. IV offset %x \n", __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);
- + dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);
- + dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);
- + dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);
- + if(debug) {
- + mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);
- + }
- +
- +
- + /* send action to HAL */
- + spin_lock_irqsave(&cesa_lock, flags);
- + status = mvCesaAction(cesa_cmd);
- + spin_unlock_irqrestore(&cesa_lock, flags);
- +
- + /* action not allowed */
- + if(status == MV_NOT_ALLOWED) {
- +#ifdef CESA_OCF_SPLIT
- + /* if both encrypt and auth try to split */
- + if(auth && (encrypt || decrypt)) {
- + MV_CESA_COMMAND *cesa_cmd_wa;
- +
- + /* malloc a new cesa process and init it */
- + cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
- +
- + if (cesa_ocf_cmd_wa == NULL) {
- + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
- + goto p_error;
- + }
- + memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));
- + cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;
- + cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;
- + cesa_ocf_cmd_wa->need_cb = 0;
- +
- + /* break requests to two operation, first operation completion won't call callback */
- + if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
- + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
- + }
- + else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {
- + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
- + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- + }
- + else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {
- + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
- + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- + }
- + else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){
- + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
- + }
- + else {
- + printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);
- + goto p_error;
- + }
- +
- + /* send the 2 actions to the HAL */
- + spin_lock_irqsave(&cesa_lock, flags);
- + status = mvCesaAction(cesa_cmd_wa);
- + spin_unlock_irqrestore(&cesa_lock, flags);
- +
- + if((status != MV_NO_MORE) && (status != MV_OK)) {
- + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
- + goto p_error;
- + }
- + spin_lock_irqsave(&cesa_lock, flags);
- + status = mvCesaAction(cesa_cmd);
- + spin_unlock_irqrestore(&cesa_lock, flags);
- +
- + }
- + /* action not allowed and can't split */
- + else
- +#endif
- + {
- + goto p_error;
- + }
- + }
- +
- + /* Hal Q is full, send again. This should never happen */
- + if(status == MV_NO_RESOURCE) {
- + printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);
- + if(cesa_ocf_cmd)
- + kfree(cesa_ocf_cmd);
- + if(cesa_ocf_cmd_wa)
- + kfree(cesa_ocf_cmd_wa);
- + return ERESTART;
- + }
- + else if((status != MV_NO_MORE) && (status != MV_OK)) {
- + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
- + goto p_error;
- + }
- +
- +
- +#ifdef CESA_OCF_POLLING
- + cesa_interrupt_polling();
- +#endif
- + cesaTestTraceAdd(5);
- +
- + return 0;
- +p_error:
- + crp->crp_etype = EINVAL;
- + if(cesa_ocf_cmd)
- + kfree(cesa_ocf_cmd);
- + if(cesa_ocf_cmd_wa)
- + kfree(cesa_ocf_cmd_wa);
- + return EINVAL;
- +}
- +
- +/*
- + * cesa callback.
- + */
- +static void
- +cesa_callback(unsigned long dummy)
- +{
- + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
- + struct cryptop *crp = NULL;
- + MV_CESA_RESULT result[MV_CESA_MAX_CHAN];
- + int res_idx = 0,i;
- + MV_STATUS status;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- +#ifdef CESA_OCF_TASKLET
- + disable_irq(cesa_device.irq);
- +#endif
- + while(MV_TRUE) {
- +
- + /* Get Ready requests */
- + spin_lock(&cesa_lock);
- + status = mvCesaReadyGet(&result[res_idx]);
- + spin_unlock(&cesa_lock);
- +
- + cesaTestTraceAdd(2);
- +
- + if(status != MV_OK) {
- +#ifdef CESA_OCF_POLLING
- + if(status == MV_BUSY) { /* Fragment */
- + cesa_interrupt_polling();
- + return;
- + }
- +#endif
- + break;
- + }
- + res_idx++;
- + break;
- + }
- +
- + for(i = 0; i < res_idx; i++) {
- +
- + if(!result[i].pReqPrv) {
- + printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);
- + break;
- + }
- +
- + cesa_ocf_cmd = result[i].pReqPrv;
- + crp = cesa_ocf_cmd->crp;
- +
- + // ignore HMAC error.
- + //if(result->retCode)
- + // crp->crp_etype = EIO;
- +
- +#if defined(CESA_OCF_POLLING)
- + if(!cesa_ocf_cmd->need_cb){
- + cesa_interrupt_polling();
- + }
- +#endif
- + if(cesa_ocf_cmd->need_cb) {
- + if(debug) {
- + mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);
- + }
- + crypto_done(crp);
- + }
- + kfree(cesa_ocf_cmd);
- + }
- +#ifdef CESA_OCF_TASKLET
- + enable_irq(cesa_device.irq);
- +#endif
- +
- + cesaTestTraceAdd(3);
- +
- + return;
- +}
- +
- +#ifdef CESA_OCF_POLLING
- +static void
- +cesa_interrupt_polling(void)
- +{
- + u32 cause;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + /* Read cause register */
- + do {
- + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
- + cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;
- +
- + } while (cause == 0);
- +
- + /* clear interrupts */
- + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
- +
- + cesa_callback(0);
- +
- + return;
- +}
- +
- +#endif
- +
- +/*
- + * cesa Interrupt polling routine.
- + */
- +static irqreturn_t
- +cesa_interrupt_handler(int irq, void *arg)
- +{
- + u32 cause;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + cesaTestTraceAdd(0);
- +
- + /* Read cause register */
- + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
- +
- + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
- + {
- + /* Empty interrupt */
- + dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);
- + return IRQ_HANDLED;
- + }
- +
- + /* clear interrupts */
- + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
- +
- + cesaTestTraceAdd(1);
- +#ifdef CESA_OCF_TASKLET
- + tasklet_hi_schedule(&cesa_ocf_tasklet);
- +#else
- + cesa_callback(0);
- +#endif
- + return IRQ_HANDLED;
- +}
- +
- +/*
- + * Open a session.
- + */
- +static int
- +/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/
- +cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
- +{
- + u32 status = 0, i;
- + u32 count = 0, auth = 0, encrypt =0;
- + struct cesa_ocf_data *cesa_ocf_cur_ses;
- + MV_CESA_OPEN_SESSION cesa_session;
- + MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;
- +
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid == NULL || cri == NULL) {
- + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + /* leave first empty like in other implementations */
- + for (i = 1; i < CESA_OCF_MAX_SES; i++) {
- + if (cesa_ocf_sessions[i] == NULL)
- + break;
- + }
- +
- + if(i >= CESA_OCF_MAX_SES) {
- + printk("%s,%d: no more sessions \n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);
- + if (cesa_ocf_sessions[i] == NULL) {
- + cesa_ocf_freesession(NULL, i);
- + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
- + return ENOBUFS;
- + }
- + dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);
- +
- + *sid = i;
- + cesa_ocf_cur_ses = cesa_ocf_sessions[i];
- + memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));
- + cesa_ocf_cur_ses->sid_encrypt = -1;
- + cesa_ocf_cur_ses->sid_decrypt = -1;
- + cesa_ocf_cur_ses->frag_wa_encrypt = -1;
- + cesa_ocf_cur_ses->frag_wa_decrypt = -1;
- + cesa_ocf_cur_ses->frag_wa_auth = -1;
- +
- + /* init the session */
- + memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));
- + count = 1;
- + while (cri) {
- + if(count > 2) {
- + printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);
- + goto error;
- + }
- + switch (cri->cri_alg) {
- + case CRYPTO_AES_CBC:
- + dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);
- + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
- + cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;
- + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;
- + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
- + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
- + goto error;
- + }
- + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
- + dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);
- + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
- + encrypt += count;
- + break;
- + case CRYPTO_3DES_CBC:
- + dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);
- + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
- + cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;
- + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;
- + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
- + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
- + goto error;
- + }
- + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
- + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
- + encrypt += count;
- + break;
- + case CRYPTO_DES_CBC:
- + dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);
- + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
- + cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;
- + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;
- + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
- + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
- + goto error;
- + }
- + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
- + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
- + encrypt += count;
- + break;
- + case CRYPTO_MD5:
- + case CRYPTO_MD5_HMAC:
- + dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");
- + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
- + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;
- + cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;
- + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
- + goto error;
- + }
- + cesa_ses->macKeyLength = cri->cri_klen/8;
- + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
- + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
- + auth += count;
- + break;
- + case CRYPTO_SHA1:
- + case CRYPTO_SHA1_HMAC:
- + dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");
- + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
- + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12;
- + cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;
- + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
- + goto error;
- + }
- + cesa_ses->macKeyLength = cri->cri_klen/8;
- + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
- + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
- + auth += count;
- + break;
- + default:
- + printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);
- + goto error;
- + }
- + cri = cri->cri_next;
- + count++;
- + }
- +
- + if((encrypt > 2) || (auth > 2)) {
- + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- + goto error;
- + }
- + /* create new sessions in HAL */
- + if(encrypt) {
- + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
- + /* encrypt session */
- + if(auth == 1) {
- + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
- + }
- + else if(auth == 2) {
- + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
- + cesa_ocf_cur_ses->encrypt_tn_auth = 1;
- + }
- + else {
- + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
- + }
- + cesa_ses->direction = MV_CESA_DIR_ENCODE;
- + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
- + if(status != MV_OK) {
- + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- + goto error;
- + }
- + /* decrypt session */
- + if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {
- + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
- + }
- + else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {
- + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
- + }
- + cesa_ses->direction = MV_CESA_DIR_DECODE;
- + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);
- + if(status != MV_OK) {
- + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- + goto error;
- + }
- +
- + /* preapre one action sessions for case we will need to split an action */
- +#ifdef CESA_OCF_SPLIT
- + if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) ||
- + ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {
- + /* open one session for encode and one for decode */
- + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
- + cesa_ses->direction = MV_CESA_DIR_ENCODE;
- + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);
- + if(status != MV_OK) {
- + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- + goto error;
- + }
- +
- + cesa_ses->direction = MV_CESA_DIR_DECODE;
- + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);
- + if(status != MV_OK) {
- + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- + goto error;
- + }
- + /* open one session for auth */
- + cesa_ses->operation = MV_CESA_MAC_ONLY;
- + cesa_ses->direction = MV_CESA_DIR_ENCODE;
- + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);
- + if(status != MV_OK) {
- + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- + goto error;
- + }
- + }
- +#endif
- + }
- + else { /* only auth */
- + cesa_ses->operation = MV_CESA_MAC_ONLY;
- + cesa_ses->direction = MV_CESA_DIR_ENCODE;
- + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
- + if(status != MV_OK) {
- + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- + goto error;
- + }
- + }
- +
- + return 0;
- +error:
- + cesa_ocf_freesession(NULL, *sid);
- + return EINVAL;
- +
- +}
- +
- +
- +/*
- + * Free a session.
- + */
- +static int
- +cesa_ocf_freesession(device_t dev, u_int64_t tid)
- +{
- + struct cesa_ocf_data *cesa_ocf_cur_ses;
- + u_int32_t sid = CRYPTO_SESID2LID(tid);
- + //unsigned long flags;
- +
- + dprintk("%s() %d \n", __FUNCTION__, sid);
- + if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {
- + printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);
- + return(EINVAL);
- + }
- +
- + /* Silently accept and return */
- + if (sid == 0)
- + return(0);
- +
- + /* release session from HAL */
- + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
- + if (cesa_ocf_cur_ses->sid_encrypt != -1) {
- + mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);
- + }
- + if (cesa_ocf_cur_ses->sid_decrypt != -1) {
- + mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);
- + }
- + if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {
- + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);
- + }
- + if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {
- + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);
- + }
- + if (cesa_ocf_cur_ses->frag_wa_auth != -1) {
- + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);
- + }
- +
- + kfree(cesa_ocf_cur_ses);
- + cesa_ocf_sessions[sid] = NULL;
- +
- + return 0;
- +}
- +
- +
- +/* TDMA Window setup */
- +
- +static void __init
- +setup_tdma_mbus_windows(struct cesa_dev *dev)
- +{
- + int i;
- +
- + for (i = 0; i < 4; i++) {
- + writel(0, dev->reg + WINDOW_BASE(i));
- + writel(0, dev->reg + WINDOW_CTRL(i));
- + }
- +
- + for (i = 0; i < dev->plat_data->dram->num_cs; i++) {
- + struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;
- + writel(
- + ((cs->size - 1) & 0xffff0000) |
- + (cs->mbus_attr << 8) |
- + (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,
- + dev->reg + WINDOW_CTRL(i)
- + );
- + writel(cs->base, dev->reg + WINDOW_BASE(i));
- + }
- +}
- +
- +/*
- + * our driver startup and shutdown routines
- + */
- +static int
- +mv_cesa_ocf_init(struct platform_device *pdev)
- +{
- +#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)
- + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))
- + {
- + dprintk("CESA is not mapped to this CPU\n");
- + return -ENODEV;
- + }
- +#endif
- +
- + dprintk("%s\n", __FUNCTION__);
- + memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));
- + softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);
- + cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);
- +
- + if (cesa_ocf_id < 0)
- + panic("MV CESA crypto device cannot initialize!");
- +
- + dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);
- +
- + /* CESA unit is auto power on off */
- +#if 0
- + if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))
- + {
- + printk("\nWarning CESA %d is Powered Off\n",0);
- + return EINVAL;
- + }
- +#endif
- +
- + memset(&cesa_device, 0, sizeof(struct cesa_dev));
- + /* Get the IRQ, and crypto memory regions */
- + {
- + struct resource *res;
- + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
- +
- + if (!res)
- + return -ENXIO;
- +
- + cesa_device.sram = ioremap(res->start, res->end - res->start + 1);
- + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
- +
- + if (!res) {
- + iounmap(cesa_device.sram);
- + return -ENXIO;
- + }
- + cesa_device.reg = ioremap(res->start, res->end - res->start + 1);
- + cesa_device.irq = platform_get_irq(pdev, 0);
- + cesa_device.plat_data = pdev->dev.platform_data;
- + setup_tdma_mbus_windows(&cesa_device);
- +
- + }
- +
- +
- + if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,
- + NULL) ) {
- + printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + /* clear and unmask Int */
- + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
- +#ifndef CESA_OCF_POLLING
- + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
- +#endif
- +#ifdef CESA_OCF_TASKLET
- + tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);
- +#endif
- + /* register interrupt */
- + if( request_irq( cesa_device.irq, cesa_interrupt_handler,
- + (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {
- + printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);
- + return EINVAL;
- + }
- +
- +
- + memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);
- +
- +#define REGISTER(alg) \
- + crypto_register(cesa_ocf_id, alg, 0,0)
- + REGISTER(CRYPTO_AES_CBC);
- + REGISTER(CRYPTO_DES_CBC);
- + REGISTER(CRYPTO_3DES_CBC);
- + REGISTER(CRYPTO_MD5);
- + REGISTER(CRYPTO_MD5_HMAC);
- + REGISTER(CRYPTO_SHA1);
- + REGISTER(CRYPTO_SHA1_HMAC);
- +#undef REGISTER
- +
- + return 0;
- +}
- +
- +static void
- +mv_cesa_ocf_exit(struct platform_device *pdev)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- +
- + crypto_unregister_all(cesa_ocf_id);
- + cesa_ocf_id = -1;
- + iounmap(cesa_device.reg);
- + iounmap(cesa_device.sram);
- + free_irq(cesa_device.irq, NULL);
- +
- + /* mask and clear Int */
- + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
- + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
- +
- +
- + if( MV_OK != mvCesaFinish() ) {
- + printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);
- + return;
- + }
- +}
- +
- +
- +void cesa_ocf_debug(void)
- +{
- +
- +#ifdef CESA_OCF_TRACE_DEBUG
- + {
- + int i, j;
- + j = cesaTestTraceIdx;
- + mvOsPrintf("No Type rCause iCause Proc Isr Res Time pReady pProc pEmpty\n");
- + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
- + {
- + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
- + j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,
- + cesaTestTrace[j].idmaCause,
- + cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
- + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
- + j++;
- + if(j == MV_CESA_TEST_TRACE_SIZE)
- + j = 0;
- + }
- + }
- +#endif
- +
- +}
- +
- +static struct platform_driver marvell_cesa = {
- + .probe = mv_cesa_ocf_init,
- + .remove = mv_cesa_ocf_exit,
- + .driver = {
- + .owner = THIS_MODULE,
- + .name = "mv_crypto",
- + },
- +};
- +
- +MODULE_ALIAS("platform:mv_crypto");
- +
- +static int __init mv_cesa_init(void)
- +{
- + return platform_driver_register(&marvell_cesa);
- +}
- +
- +module_init(mv_cesa_init);
- +
- +static void __exit mv_cesa_exit(void)
- +{
- + platform_driver_unregister(&marvell_cesa);
- +}
- +
- +module_exit(mv_cesa_exit);
- +
- +MODULE_LICENSE("GPL");
- +MODULE_AUTHOR("Ronen Shitrit");
- +MODULE_DESCRIPTION("OCF module for Orion CESA crypto");
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/Makefile linux-2.6.36/crypto/ocf/kirkwood/Makefile
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/Makefile 2010-11-09 20:28:06.092495440 +0100
- @@ -0,0 +1,19 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_KIRKWOOD) += mv_cesa.o
- +
- +mv_cesa-y := cesa/mvCesa.o cesa/mvLru.o cesa/mvMD5.o cesa/mvSHA1.o cesa/AES/mvAesAlg.o cesa/AES/mvAesApi.o cesa/mvCesaDebug.o cesa_ocf_drv.o
- +
- +# Extra objects required by the CESA driver
- +mv_cesa-y += mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.o mvHal/kw_family/boardEnv/mvBoardEnvLib.o mvHal/mv_hal/twsi/mvTwsi.o mvHal/kw_family/ctrlEnv/sys/mvCpuIf.o mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.o mvHal/kw_family/ctrlEnv/sys/mvSysDram.o mvHal/linux_oss/mvOs.o mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.o mvHal/mv_hal/gpp/mvGpp.o mvHal/kw_family/ctrlEnv/sys/mvSysPex.o mvHal/mv_hal/pex/mvPex.o mvHal/kw_family/boardEnv/mvBoardEnvSpec.o mvHal/common/mvCommon.o mvHal/common/mvDebug.o mvHal/kw_family/ctrlEnv/sys/mvSysCesa.o
- +
- +ifdef src
- +EXTRA_CFLAGS += -I$(src)/.. -I$(src)/cesa -I$(src)/mvHal -I$(src)/mvHal/common -I$(src)/mvHal/kw_family -I$(src)/mvHal/mv_hal -I$(src)/mvHal/linux_oss -I$(src)
- +endif
- +
- +EXTRA_CFLAGS += -DMV_LINUX -DMV_CPU_LE -DMV_ARM -DMV_INCLUDE_CESA -DMV_INCLUDE_PEX -DMV_CACHE_COHERENCY=3
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mv802_3.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 2010-11-09 20:28:06.131247793 +0100
- @@ -0,0 +1,213 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmv802_3h
- +#define __INCmv802_3h
- +
- +
- +/* includes */
- +#include "mvTypes.h"
- +
- +/* Defines */
- +#define MV_MAX_ETH_DATA 1500
- +
- +/* 802.3 types */
- +#define MV_IP_TYPE 0x0800
- +#define MV_IP_ARP_TYPE 0x0806
- +#define MV_APPLE_TALK_ARP_TYPE 0x80F3
- +#define MV_NOVELL_IPX_TYPE 0x8137
- +#define MV_EAPOL_TYPE 0x888e
- +
- +
- +
- +/* Encapsulation header for RFC1042 and Ethernet_tunnel */
- +
- +#define MV_RFC1042_SNAP_HEADER {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}
- +
- +#define MV_ETH_SNAP_LSB 0xF8
- +
- +
- +#define MV_MAC_ADDR_SIZE (6)
- +#define MV_MAC_STR_SIZE (20)
- +#define MV_VLAN_HLEN (4)
- +
- +/* This macro checks for a multicast mac address */
- +#define MV_IS_MULTICAST_MAC(mac) (((mac)[0] & 0x1) == 1)
- +
- +
- +/* This macro checks for an broadcast mac address */
- +#define MV_IS_BROADCAST_MAC(mac) \
- + (((mac)[0] == 0xFF) && \
- + ((mac)[1] == 0xFF) && \
- + ((mac)[2] == 0xFF) && \
- + ((mac)[3] == 0xFF) && \
- + ((mac)[4] == 0xFF) && \
- + ((mac)[5] == 0xFF))
- +
- +
- +/* Typedefs */
- +typedef struct
- +{
- + MV_U8 pDA[MV_MAC_ADDR_SIZE];
- + MV_U8 pSA[MV_MAC_ADDR_SIZE];
- + MV_U16 typeOrLen;
- +
- +} MV_802_3_HEADER;
- +
- +enum {
- + MV_IP_PROTO_NULL = 0, /* Dummy protocol for TCP */
- + MV_IP_PROTO_ICMP = 1, /* Internet Control Message Protocol */
- + MV_IP_PROTO_IGMP = 2, /* Internet Group Management Protocol */
- + MV_IP_PROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
- + MV_IP_PROTO_TCP = 6, /* Transmission Control Protocol */
- + MV_IP_PROTO_EGP = 8, /* Exterior Gateway Protocol */
- + MV_IP_PROTO_PUP = 12, /* PUP protocol */
- + MV_IP_PROTO_UDP = 17, /* User Datagram Protocol */
- + MV_IP_PROTO_IDP = 22, /* XNS IDP protocol */
- + MV_IP_PROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
- + MV_IP_PROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
- + MV_IP_PROTO_RSVP = 46, /* RSVP protocol */
- + MV_IP_PROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
- + MV_IP_PROTO_ESP = 50, /* Encapsulation Security Payload protocol */
- + MV_IP_PROTO_AH = 51, /* Authentication Header protocol */
- + MV_IP_PROTO_BEETPH = 94, /* IP option pseudo header for BEET */
- + MV_IP_PROTO_PIM = 103,
- + MV_IP_PROTO_COMP = 108, /* Compression Header protocol */
- + MV_IP_PROTO_ZERO_HOP = 114, /* Any 0 hop protocol (IANA) */
- + MV_IP_PROTO_SCTP = 132, /* Stream Control Transport Protocol */
- + MV_IP_PROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
- +
- + MV_IP_PROTO_RAW = 255, /* Raw IP packets */
- + MV_IP_PROTO_MAX
- +};
- +
- +typedef struct
- +{
- + MV_U8 version;
- + MV_U8 tos;
- + MV_U16 totalLength;
- + MV_U16 identifier;
- + MV_U16 fragmentCtrl;
- + MV_U8 ttl;
- + MV_U8 protocol;
- + MV_U16 checksum;
- + MV_U32 srcIP;
- + MV_U32 dstIP;
- +
- +} MV_IP_HEADER;
- +
- +typedef struct
- +{
- + MV_U32 spi;
- + MV_U32 seqNum;
- +} MV_ESP_HEADER;
- +
- +#define MV_ICMP_ECHOREPLY 0 /* Echo Reply */
- +#define MV_ICMP_DEST_UNREACH 3 /* Destination Unreachable */
- +#define MV_ICMP_SOURCE_QUENCH 4 /* Source Quench */
- +#define MV_ICMP_REDIRECT 5 /* Redirect (change route) */
- +#define MV_ICMP_ECHO 8 /* Echo Request */
- +#define MV_ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
- +#define MV_ICMP_PARAMETERPROB 12 /* Parameter Problem */
- +#define MV_ICMP_TIMESTAMP 13 /* Timestamp Request */
- +#define MV_ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
- +#define MV_ICMP_INFO_REQUEST 15 /* Information Request */
- +#define MV_ICMP_INFO_REPLY 16 /* Information Reply */
- +#define MV_ICMP_ADDRESS 17 /* Address Mask Request */
- +#define MV_ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
- +
- +typedef struct
- +{
- + MV_U8 type;
- + MV_U8 code;
- + MV_U16 checksum;
- + MV_U16 id;
- + MV_U16 sequence;
- +
- +} MV_ICMP_ECHO_HEADER;
- +
- +typedef struct
- +{
- + MV_U16 source;
- + MV_U16 dest;
- + MV_U32 seq;
- + MV_U32 ack_seq;
- + MV_U16 flags;
- + MV_U16 window;
- + MV_U16 chksum;
- + MV_U16 urg_offset;
- +
- +} MV_TCP_HEADER;
- +
- +typedef struct
- +{
- + MV_U16 source;
- + MV_U16 dest;
- + MV_U16 len;
- + MV_U16 check;
- +
- +} MV_UDP_HEADER;
- +
- +#endif /* __INCmv802_3h */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 2010-11-09 20:28:06.172495450 +0100
- @@ -0,0 +1,277 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvOs.h"
- +#include "mv802_3.h"
- +#include "mvCommon.h"
- +
- +
- +/*******************************************************************************
- +* mvMacStrToHex - Convert MAC format string to hex.
- +*
- +* DESCRIPTION:
- +* This function convert MAC format string to hex.
- +*
- +* INPUT:
- +* macStr - MAC address string. Fornat of address string is
- +* uu:vv:ww:xx:yy:zz, where ":" can be any delimiter.
- +*
- +* OUTPUT:
- +* macHex - MAC in hex format.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex)
- +{
- + int i;
- + char tmp[3];
- +
- + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
- + {
- + tmp[0] = macStr[(i * 3) + 0];
- + tmp[1] = macStr[(i * 3) + 1];
- + tmp[2] = '\0';
- + macHex[i] = (MV_U8) (strtol(tmp, NULL, 16));
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvMacHexToStr - Convert MAC in hex format to string format.
- +*
- +* DESCRIPTION:
- +* This function convert MAC in hex format to string format.
- +*
- +* INPUT:
- +* macHex - MAC in hex format.
- +*
- +* OUTPUT:
- +* macStr - MAC address string. String format is uu:vv:ww:xx:yy:zz.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr)
- +{
- + int i;
- +
- + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
- + {
- + mvOsSPrintf(&macStr[i * 3], "%02x:", macHex[i]);
- + }
- + macStr[(i * 3) - 1] = '\0';
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSizePrint - Print the given size with size unit description.
- +*
- +* DESCRIPTION:
- +* This function print the given size with size unit description.
- +* FOr example when size paramter is 0x180000, the function prints:
- +* "size 1MB+500KB"
- +*
- +* INPUT:
- +* size - Size in bytes.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvSizePrint(MV_U32 size)
- +{
- + mvOsOutput("size ");
- +
- + if(size >= _1G)
- + {
- + mvOsOutput("%3dGB ", size / _1G);
- + size %= _1G;
- + if(size)
- + mvOsOutput("+");
- + }
- + if(size >= _1M )
- + {
- + mvOsOutput("%3dMB ", size / _1M);
- + size %= _1M;
- + if(size)
- + mvOsOutput("+");
- + }
- + if(size >= _1K)
- + {
- + mvOsOutput("%3dKB ", size / _1K);
- + size %= _1K;
- + if(size)
- + mvOsOutput("+");
- + }
- + if(size > 0)
- + {
- + mvOsOutput("%3dB ", size);
- + }
- +}
- +
- +/*******************************************************************************
- +* mvHexToBin - Convert hex to binary
- +*
- +* DESCRIPTION:
- +* This function Convert hex to binary.
- +*
- +* INPUT:
- +* pHexStr - hex buffer pointer.
- +* size - Size to convert.
- +*
- +* OUTPUT:
- +* pBin - Binary buffer pointer.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size)
- +{
- + int j, i;
- + char tmp[3];
- + MV_U8 byte;
- +
- + for(j=0, i=0; j<size; j++, i+=2)
- + {
- + tmp[0] = pHexStr[i];
- + tmp[1] = pHexStr[i+1];
- + tmp[2] = '\0';
- + byte = (MV_U8) (strtol(tmp, NULL, 16) & 0xFF);
- + pBin[j] = byte;
- + }
- +}
- +
- +void mvAsciiToHex(const char* asciiStr, char* hexStr)
- +{
- + int i=0;
- +
- + while(asciiStr[i] != 0)
- + {
- + mvOsSPrintf(&hexStr[i*2], "%02x", asciiStr[i]);
- + i++;
- + }
- + hexStr[i*2] = 0;
- +}
- +
- +
- +void mvBinToHex(const MV_U8* bin, char* hexStr, int size)
- +{
- + int i;
- +
- + for(i=0; i<size; i++)
- + {
- + mvOsSPrintf(&hexStr[i*2], "%02x", bin[i]);
- + }
- + hexStr[i*2] = '\0';
- +}
- +
- +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size)
- +{
- + int i;
- +
- + for(i=0; i<size; i++)
- + {
- + mvOsSPrintf(&asciiStr[i*2], "%c", bin[i]);
- + }
- + asciiStr[i*2] = '\0';
- +}
- +
- +/*******************************************************************************
- +* mvLog2 -
- +*
- +* DESCRIPTION:
- +* Calculate the Log2 of a given number.
- +*
- +* INPUT:
- +* num - A number to calculate the Log2 for.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Log 2 of the input number, or 0xFFFFFFFF if input is 0.
- +*
- +*******************************************************************************/
- +MV_U32 mvLog2(MV_U32 num)
- +{
- + MV_U32 result = 0;
- + if(num == 0)
- + return 0xFFFFFFFF;
- + while(num != 1)
- + {
- + num = num >> 1;
- + result++;
- + }
- + return result;
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 2010-11-09 20:28:06.212495496 +0100
- @@ -0,0 +1,308 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +
- +#ifndef __INCmvCommonh
- +#define __INCmvCommonh
- +
- +#include "mvTypes.h"
- +
- +/* Swap tool */
- +
- +/* 16bit nibble swap. For example 0x1234 -> 0x2143 */
- +#define MV_NIBBLE_SWAP_16BIT(X) (((X&0xf) << 4) | \
- + ((X&0xf0) >> 4) | \
- + ((X&0xf00) << 4) | \
- + ((X&0xf000) >> 4))
- +
- +/* 32bit nibble swap. For example 0x12345678 -> 0x21436587 */
- +#define MV_NIBBLE_SWAP_32BIT(X) (((X&0xf) << 4) | \
- + ((X&0xf0) >> 4) | \
- + ((X&0xf00) << 4) | \
- + ((X&0xf000) >> 4) | \
- + ((X&0xf0000) << 4) | \
- + ((X&0xf00000) >> 4) | \
- + ((X&0xf000000) << 4) | \
- + ((X&0xf0000000) >> 4))
- +
- +/* 16bit byte swap. For example 0x1122 -> 0x2211 */
- +#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff)<<8) | (((X)&0xff00)>>8))
- +
- +/* 32bit byte swap. For example 0x11223344 -> 0x44332211 */
- +#define MV_BYTE_SWAP_32BIT(X) ((((X)&0xff)<<24) | \
- + (((X)&0xff00)<<8) | \
- + (((X)&0xff0000)>>8) | \
- + (((X)&0xff000000)>>24))
- +
- +/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211 */
- +#define MV_BYTE_SWAP_64BIT(X) ((l64) ((((X)&0xffULL)<<56) | \
- + (((X)&0xff00ULL)<<40) | \
- + (((X)&0xff0000ULL)<<24) | \
- + (((X)&0xff000000ULL)<<8) | \
- + (((X)&0xff00000000ULL)>>8) | \
- + (((X)&0xff0000000000ULL)>>24) | \
- + (((X)&0xff000000000000ULL)>>40) | \
- + (((X)&0xff00000000000000ULL)>>56)))
- +
- +/* Endianess macros. */
- +#if defined(MV_CPU_LE)
- + #define MV_16BIT_LE(X) (X)
- + #define MV_32BIT_LE(X) (X)
- + #define MV_64BIT_LE(X) (X)
- + #define MV_16BIT_BE(X) MV_BYTE_SWAP_16BIT(X)
- + #define MV_32BIT_BE(X) MV_BYTE_SWAP_32BIT(X)
- + #define MV_64BIT_BE(X) MV_BYTE_SWAP_64BIT(X)
- +#elif defined(MV_CPU_BE)
- + #define MV_16BIT_LE(X) MV_BYTE_SWAP_16BIT(X)
- + #define MV_32BIT_LE(X) MV_BYTE_SWAP_32BIT(X)
- + #define MV_64BIT_LE(X) MV_BYTE_SWAP_64BIT(X)
- + #define MV_16BIT_BE(X) (X)
- + #define MV_32BIT_BE(X) (X)
- + #define MV_64BIT_BE(X) (X)
- +#else
- + #error "CPU endianess isn't defined!\n"
- +#endif
- +
- +
- +/* Bit field definitions */
- +#define NO_BIT 0x00000000
- +#define BIT0 0x00000001
- +#define BIT1 0x00000002
- +#define BIT2 0x00000004
- +#define BIT3 0x00000008
- +#define BIT4 0x00000010
- +#define BIT5 0x00000020
- +#define BIT6 0x00000040
- +#define BIT7 0x00000080
- +#define BIT8 0x00000100
- +#define BIT9 0x00000200
- +#define BIT10 0x00000400
- +#define BIT11 0x00000800
- +#define BIT12 0x00001000
- +#define BIT13 0x00002000
- +#define BIT14 0x00004000
- +#define BIT15 0x00008000
- +#define BIT16 0x00010000
- +#define BIT17 0x00020000
- +#define BIT18 0x00040000
- +#define BIT19 0x00080000
- +#define BIT20 0x00100000
- +#define BIT21 0x00200000
- +#define BIT22 0x00400000
- +#define BIT23 0x00800000
- +#define BIT24 0x01000000
- +#define BIT25 0x02000000
- +#define BIT26 0x04000000
- +#define BIT27 0x08000000
- +#define BIT28 0x10000000
- +#define BIT29 0x20000000
- +#define BIT30 0x40000000
- +#define BIT31 0x80000000
- +
- +/* Handy sizes */
- +#define _1K 0x00000400
- +#define _2K 0x00000800
- +#define _4K 0x00001000
- +#define _8K 0x00002000
- +#define _16K 0x00004000
- +#define _32K 0x00008000
- +#define _64K 0x00010000
- +#define _128K 0x00020000
- +#define _256K 0x00040000
- +#define _512K 0x00080000
- +
- +#define _1M 0x00100000
- +#define _2M 0x00200000
- +#define _4M 0x00400000
- +#define _8M 0x00800000
- +#define _16M 0x01000000
- +#define _32M 0x02000000
- +#define _64M 0x04000000
- +#define _128M 0x08000000
- +#define _256M 0x10000000
- +#define _512M 0x20000000
- +
- +#define _1G 0x40000000
- +#define _2G 0x80000000
- +
- +/* Tclock and Sys clock define */
- +#define _100MHz 100000000
- +#define _125MHz 125000000
- +#define _133MHz 133333334
- +#define _150MHz 150000000
- +#define _160MHz 160000000
- +#define _166MHz 166666667
- +#define _175MHz 175000000
- +#define _178MHz 178000000
- +#define _183MHz 183333334
- +#define _187MHz 187000000
- +#define _192MHz 192000000
- +#define _194MHz 194000000
- +#define _200MHz 200000000
- +#define _233MHz 233333334
- +#define _250MHz 250000000
- +#define _266MHz 266666667
- +#define _300MHz 300000000
- +
- +/* For better address window table readability */
- +#define EN MV_TRUE
- +#define DIS MV_FALSE
- +#define N_A -1 /* Not applicable */
- +
- +/* Cache configuration options for memory (DRAM, SRAM, ... ) */
- +
- +/* Memory uncached, HW or SW cache coherency is not needed */
- +#define MV_UNCACHED 0
- +/* Memory cached, HW cache coherency supported in WriteThrough mode */
- +#define MV_CACHE_COHER_HW_WT 1
- +/* Memory cached, HW cache coherency supported in WriteBack mode */
- +#define MV_CACHE_COHER_HW_WB 2
- +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
- +#define MV_CACHE_COHER_SW 3
- +
- +
- +/* Macro for testing aligment. Positive if number is NOT aligned */
- +#define MV_IS_NOT_ALIGN(number, align) ((number) & ((align) - 1))
- +
- +/* Macro for alignment up. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0340 */
- +#define MV_ALIGN_UP(number, align) \
- +(((number) & ((align) - 1)) ? (((number) + (align)) & ~((align)-1)) : (number))
- +
- +/* Macro for alignment down. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0320 */
- +#define MV_ALIGN_DOWN(number, align) ((number) & ~((align)-1))
- +
- +/* This macro returns absolute value */
- +#define MV_ABS(number) (((int)(number) < 0) ? -(int)(number) : (int)(number))
- +
- +
- +/* Bit fields manipulation macros */
- +
- +/* An integer word which its 'x' bit is set */
- +#define MV_BIT_MASK(bitNum) (1 << (bitNum) )
- +
- +/* Checks wheter bit 'x' in integer word is set */
- +#define MV_BIT_CHECK(word, bitNum) ( (word) & MV_BIT_MASK(bitNum) )
- +
- +/* Clear (reset) bit 'x' in integer word (RMW - Read-Modify-Write) */
- +#define MV_BIT_CLEAR(word, bitNum) ( (word) &= ~(MV_BIT_MASK(bitNum)) )
- +
- +/* Set bit 'x' in integer word (RMW) */
- +#define MV_BIT_SET(word, bitNum) ( (word) |= MV_BIT_MASK(bitNum) )
- +
- +/* Invert bit 'x' in integer word (RMW) */
- +#define MV_BIT_INV(word, bitNum) ( (word) ^= MV_BIT_MASK(bitNum) )
- +
- +/* Get the min between 'a' or 'b' */
- +#define MV_MIN(a,b) (((a) < (b)) ? (a) : (b))
- +
- +/* Get the max between 'a' or 'b' */
- +#define MV_MAX(a,b) (((a) < (b)) ? (b) : (a))
- +
- +/* Temporary */
- +#define mvOsDivide(num, div) \
- +({ \
- + int i=0, rem=(num); \
- + \
- + while(rem >= (div)) \
- + { \
- + rem -= (div); \
- + i++; \
- + } \
- + (i); \
- +})
- +
- +/* Temporary */
- +#define mvOsReminder(num, div) \
- +({ \
- + int rem = (num); \
- + \
- + while(rem >= (div)) \
- + rem -= (div); \
- + (rem); \
- +})
- +
- +#define MV_IP_QUAD(ipAddr) ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF), \
- + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF)
- +
- +#define MV_IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))
- +
- +#ifndef MV_ASMLANGUAGE
- +/* mvCommon API list */
- +
- +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size);
- +void mvAsciiToHex(const char* asciiStr, char* hexStr);
- +void mvBinToHex(const MV_U8* bin, char* hexStr, int size);
- +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size);
- +
- +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex);
- +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr);
- +void mvSizePrint(MV_U32);
- +
- +MV_U32 mvLog2(MV_U32 num);
- +
- +#endif /* MV_ASMLANGUAGE */
- +
- +
- +#endif /* __INCmvCommonh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 2010-11-09 20:28:06.252495437 +0100
- @@ -0,0 +1,326 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +
- +/* includes */
- +#include "mvOs.h"
- +#include "mv802_3.h"
- +#include "mvCommon.h"
- +#include "mvDebug.h"
- +
- +/* Global variables effect on behave MV_DEBUG_PRINT and MV_DEBUG_CODE macros
- + * mvDebug - map of bits (one for each module) bit=1 means enable
- + * debug code and messages for this module
- + * mvModuleDebug - array of 32 bits varables one for each module
- + */
- +MV_U32 mvDebug = 0;
- +MV_U32 mvDebugModules[MV_MODULE_MAX];
- +
- +/* Init mvModuleDebug array to default values */
- +void mvDebugInit(void)
- +{
- + int bit;
- +
- + mvDebug = 0;
- + for(bit=0; bit<MV_MODULE_MAX; bit++)
- + {
- + mvDebugModules[bit] = MV_DEBUG_FLAG_ERR | MV_DEBUG_FLAG_STATS;
- + mvDebug |= MV_BIT_MASK(bit);
- + }
- +}
- +
- +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable)
- +{
- + if (isEnable)
- + {
- + MV_BIT_SET(mvDebug, module);
- + }
- + else
- + MV_BIT_CLEAR(mvDebug, module);
- +}
- +
- +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags)
- +{
- + mvDebugModules[module] |= flags;
- +}
- +
- +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags)
- +{
- + mvDebugModules[module] &= ~flags;
- +}
- +
- +/* Dump memory in specific format:
- + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
- + */
- +void mvDebugMemDump(void* addr, int size, int access)
- +{
- + int i, j;
- + MV_U32 memAddr = (MV_U32)addr;
- +
- + if(access == 0)
- + access = 1;
- +
- + if( (access != 4) && (access != 2) && (access != 1) )
- + {
- + mvOsPrintf("%d wrong access size. Access must be 1 or 2 or 4\n",
- + access);
- + return;
- + }
- + memAddr = MV_ALIGN_DOWN( (unsigned int)addr, 4);
- + size = MV_ALIGN_UP(size, 4);
- + addr = (void*)MV_ALIGN_DOWN( (unsigned int)addr, access);
- + while(size > 0)
- + {
- + mvOsPrintf("%08x: ", memAddr);
- + i = 0;
- + /* 32 bytes in the line */
- + while(i < 32)
- + {
- + if(memAddr >= (MV_U32)addr)
- + {
- + switch(access)
- + {
- + case 1:
- + if( memAddr == CPU_PHY_MEM(memAddr) )
- + {
- + mvOsPrintf("%02x ", MV_MEMIO8_READ(memAddr));
- + }
- + else
- + {
- + mvOsPrintf("%02x ", *((MV_U8*)memAddr));
- + }
- + break;
- +
- + case 2:
- + if( memAddr == CPU_PHY_MEM(memAddr) )
- + {
- + mvOsPrintf("%04x ", MV_MEMIO16_READ(memAddr));
- + }
- + else
- + {
- + mvOsPrintf("%04x ", *((MV_U16*)memAddr));
- + }
- + break;
- +
- + case 4:
- + if( memAddr == CPU_PHY_MEM(memAddr) )
- + {
- + mvOsPrintf("%08x ", MV_MEMIO32_READ(memAddr));
- + }
- + else
- + {
- + mvOsPrintf("%08x ", *((MV_U32*)memAddr));
- + }
- + break;
- + }
- + }
- + else
- + {
- + for(j=0; j<(access*2+1); j++)
- + mvOsPrintf(" ");
- + }
- + i += access;
- + memAddr += access;
- + size -= access;
- + if(size <= 0)
- + break;
- + }
- + mvOsPrintf("\n");
- + }
- +}
- +
- +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access)
- +{
- + if(pBufInfo == NULL)
- + {
- + mvOsPrintf("\n!!! pBufInfo = NULL\n");
- + return;
- + }
- + mvOsPrintf("\n*** pBufInfo=0x%x, cmdSts=0x%08x, pBuf=0x%x, bufSize=%d\n",
- + (unsigned int)pBufInfo,
- + (unsigned int)pBufInfo->cmdSts,
- + (unsigned int)pBufInfo->pBuff,
- + (unsigned int)pBufInfo->bufSize);
- + mvOsPrintf("pData=0x%x, byteCnt=%d, pNext=0x%x, uInfo1=0x%x, uInfo2=0x%x\n",
- + (unsigned int)pBufInfo->pData,
- + (unsigned int)pBufInfo->byteCnt,
- + (unsigned int)pBufInfo->pNextBufInfo,
- + (unsigned int)pBufInfo->userInfo1,
- + (unsigned int)pBufInfo->userInfo2);
- + if(pBufInfo->pData != NULL)
- + {
- + if(size > pBufInfo->byteCnt)
- + size = pBufInfo->byteCnt;
- + mvDebugMemDump(pBufInfo->pData, size, access);
- + }
- +}
- +
- +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access)
- +{
- + int frag, len;
- +
- + if(pPktInfo == NULL)
- + {
- + mvOsPrintf("\n!!! pPktInfo = NULL\n");
- + return;
- + }
- + mvOsPrintf("\npPkt=%p, stat=0x%08x, numFr=%d, size=%d, pFr=%p, osInfo=0x%lx\n",
- + pPktInfo, pPktInfo->status, pPktInfo->numFrags, pPktInfo->pktSize,
- + pPktInfo->pFrags, pPktInfo->osInfo);
- +
- + for(frag=0; frag<pPktInfo->numFrags; frag++)
- + {
- + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
- + frag, pPktInfo->pFrags[frag].bufVirtPtr,
- + pPktInfo->pFrags[frag].bufSize);
- + if(size > 0)
- + {
- + len = MV_MIN((int)pPktInfo->pFrags[frag].bufSize, size);
- + mvDebugMemDump(pPktInfo->pFrags[frag].bufVirtPtr, len, access);
- + size -= len;
- + }
- + }
- +
- +}
- +
- +void mvDebugPrintIpAddr(MV_U32 ipAddr)
- +{
- + mvOsPrintf("%d.%d.%d.%d", ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF),
- + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF));
- +}
- +
- +void mvDebugPrintMacAddr(const MV_U8* pMacAddr)
- +{
- + int i;
- +
- + mvOsPrintf("%02x", (unsigned int)pMacAddr[0]);
- + for(i=1; i<MV_MAC_ADDR_SIZE; i++)
- + {
- + mvOsPrintf(":%02x", pMacAddr[i]);
- + }
- + /* mvOsPrintf("\n");*/
- +}
- +
- +
- +/******* There are three functions deals with MV_DEBUG_TIMES structure ********/
- +
- +/* Reset MV_DEBUG_TIMES entry */
- +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* pName)
- +{
- + pTimeEntry->begin = 0;
- + pTimeEntry->count = count;
- + pTimeEntry->end = 0;
- + pTimeEntry->left = pTimeEntry->count;
- + pTimeEntry->total = 0;
- + pTimeEntry->min = 0xFFFFFFFF;
- + pTimeEntry->max = 0x0;
- + strncpy(pTimeEntry->name, pName, sizeof(pTimeEntry->name)-1);
- + pTimeEntry->name[sizeof(pTimeEntry->name)-1] = '\0';
- +}
- +
- +/* Print out MV_DEBUG_TIMES entry */
- +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle)
- +{
- + int num;
- +
- + if(isTitle == MV_TRUE)
- + mvOsPrintf("Event NumOfEvents TotalTime Average Min Max\n");
- +
- + num = pTimeEntry->count-pTimeEntry->left;
- + if(num > 0)
- + {
- + mvOsPrintf("%-11s %6u 0x%08lx %6lu %6lu %6lu\n",
- + pTimeEntry->name, num, pTimeEntry->total, pTimeEntry->total/num,
- + pTimeEntry->min, pTimeEntry->max);
- + }
- +}
- +
- +/* Update MV_DEBUG_TIMES entry */
- +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry)
- +{
- + MV_U32 delta;
- +
- + if(pTimeEntry->left > 0)
- + {
- + if(pTimeEntry->end <= pTimeEntry->begin)
- + {
- + delta = pTimeEntry->begin - pTimeEntry->end;
- + }
- + else
- + {
- + delta = ((MV_U32)0x10000 - pTimeEntry->end) + pTimeEntry->begin;
- + }
- + pTimeEntry->total += delta;
- +
- + if(delta < pTimeEntry->min)
- + pTimeEntry->min = delta;
- +
- + if(delta > pTimeEntry->max)
- + pTimeEntry->max = delta;
- +
- + pTimeEntry->left--;
- + }
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 2010-11-09 20:28:06.292495404 +0100
- @@ -0,0 +1,178 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +
- +#ifndef __INCmvDebugh
- +#define __INCmvDebugh
- +
- +/* includes */
- +#include "mvTypes.h"
- +
- +typedef enum
- +{
- + MV_MODULE_INVALID = -1,
- + MV_MODULE_ETH = 0,
- + MV_MODULE_IDMA,
- + MV_MODULE_XOR,
- + MV_MODULE_TWASI,
- + MV_MODULE_MGI,
- + MV_MODULE_USB,
- + MV_MODULE_CESA,
- +
- + MV_MODULE_MAX
- +}MV_MODULE_ID;
- +
- +/* Define generic flags useful for most of modules */
- +#define MV_DEBUG_FLAG_ALL (0)
- +#define MV_DEBUG_FLAG_INIT (1 << 0)
- +#define MV_DEBUG_FLAG_RX (1 << 1)
- +#define MV_DEBUG_FLAG_TX (1 << 2)
- +#define MV_DEBUG_FLAG_ERR (1 << 3)
- +#define MV_DEBUG_FLAG_TRACE (1 << 4)
- +#define MV_DEBUG_FLAG_DUMP (1 << 5)
- +#define MV_DEBUG_FLAG_CACHE (1 << 6)
- +#define MV_DEBUG_FLAG_IOCTL (1 << 7)
- +#define MV_DEBUG_FLAG_STATS (1 << 8)
- +
- +extern MV_U32 mvDebug;
- +extern MV_U32 mvDebugModules[MV_MODULE_MAX];
- +
- +#ifdef MV_DEBUG
- +# define MV_DEBUG_PRINT(module, flags, msg) mvOsPrintf msg
- +# define MV_DEBUG_CODE(module, flags, code) code
- +#elif defined(MV_RT_DEBUG)
- +# define MV_DEBUG_PRINT(module, flags, msg) \
- + if( (mvDebug & (1<<(module))) && \
- + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
- + mvOsPrintf msg
- +# define MV_DEBUG_CODE(module, flags, code) \
- + if( (mvDebug & (1<<(module))) && \
- + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
- + code
- +#else
- +# define MV_DEBUG_PRINT(module, flags, msg)
- +# define MV_DEBUG_CODE(module, flags, code)
- +#endif
- +
- +
- +
- +/* typedefs */
- +
- +/* time measurement structure used to check how much time pass between
- + * two points
- + */
- +typedef struct {
- + char name[20]; /* name of the entry */
- + unsigned long begin; /* time measured on begin point */
- + unsigned long end; /* time measured on end point */
- + unsigned long total; /* Accumulated time */
- + unsigned long left; /* The rest measurement actions */
- + unsigned long count; /* Maximum measurement actions */
- + unsigned long min; /* Minimum time from begin to end */
- + unsigned long max; /* Maximum time from begin to end */
- +} MV_DEBUG_TIMES;
- +
- +
- +/* mvDebug.h API list */
- +
- +/****** Error Recording ******/
- +
- +/* Dump memory in specific format:
- + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
- + */
- +void mvDebugMemDump(void* addr, int size, int access);
- +
- +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access);
- +
- +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access);
- +
- +void mvDebugPrintIpAddr(MV_U32 ipAddr);
- +
- +void mvDebugPrintMacAddr(const MV_U8* pMacAddr);
- +
- +/**** There are three functions deals with MV_DEBUG_TIMES structure ****/
- +
- +/* Reset MV_DEBUG_TIMES entry */
- +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* name);
- +
- +/* Update MV_DEBUG_TIMES entry */
- +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry);
- +
- +/* Print out MV_DEBUG_TIMES entry */
- +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle);
- +
- +
- +/******** General ***********/
- +
- +/* Change value of mvDebugPrint global variable */
- +
- +void mvDebugInit(void);
- +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable);
- +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags);
- +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags);
- +
- +
- +#endif /* __INCmvDebug.h */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 2010-11-09 20:28:06.332495486 +0100
- @@ -0,0 +1,225 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvDeviceIdh
- +#define __INCmvDeviceIdh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* defines */
- +#define MARVELL_VEN_ID 0x11ab
- +
- +/* Disco-3 */
- +#define MV64460_DEV_ID 0x6480
- +#define MV64460B_DEV_ID 0x6485
- +#define MV64430_DEV_ID 0x6420
- +
- +/* Disco-5 */
- +#define MV64560_DEV_ID 0x6450
- +
- +/* Disco-6 */
- +#define MV64660_DEV_ID 0x6460
- +
- +/* Orion */
- +#define MV_1181_DEV_ID 0x1181
- +#define MV_5181_DEV_ID 0x5181
- +#define MV_5281_DEV_ID 0x5281
- +#define MV_5182_DEV_ID 0x5182
- +#define MV_8660_DEV_ID 0x8660
- +#define MV_5180_DEV_ID 0x5180
- +#define MV_5082_DEV_ID 0x5082
- +#define MV_1281_DEV_ID 0x1281
- +#define MV_6082_DEV_ID 0x6082
- +#define MV_6183_DEV_ID 0x6183
- +#define MV_6183L_DEV_ID 0x6083
- +
- +#define MV_5281_D0_REV 0x4
- +#define MV_5281_D0_ID ((MV_5281_DEV_ID << 16) | MV_5281_D0_REV)
- +#define MV_5281_D0_NAME "88F5281 D0"
- +
- +#define MV_5281_D1_REV 0x5
- +#define MV_5281_D1_ID ((MV_5281_DEV_ID << 16) | MV_5281_D1_REV)
- +#define MV_5281_D1_NAME "88F5281 D1"
- +
- +#define MV_5281_D2_REV 0x6
- +#define MV_5281_D2_ID ((MV_5281_DEV_ID << 16) | MV_5281_D2_REV)
- +#define MV_5281_D2_NAME "88F5281 D2"
- +
- +
- +#define MV_5181L_A0_REV 0x8 /* need for PCIE Er */
- +#define MV_5181_A1_REV 0x1 /* for USB Er ..*/
- +#define MV_5181_B0_REV 0x2
- +#define MV_5181_B1_REV 0x3
- +#define MV_5182_A1_REV 0x1
- +#define MV_5180N_B1_REV 0x3
- +#define MV_5181L_A0_ID ((MV_5181_DEV_ID << 16) | MV_5181L_A0_REV)
- +
- +
- +
- +/* kw */
- +#define MV_6281_DEV_ID 0x6281
- +#define MV_6192_DEV_ID 0x6192
- +#define MV_6190_DEV_ID 0x6190
- +#define MV_6180_DEV_ID 0x6180
- +
- +#define MV_6281_A0_REV 0x2
- +#define MV_6281_A0_ID ((MV_6281_DEV_ID << 16) | MV_6281_A0_REV)
- +#define MV_6281_A0_NAME "88F6281 A0"
- +
- +#define MV_6192_A0_REV 0x2
- +#define MV_6192_A0_ID ((MV_6192_DEV_ID << 16) | MV_6192_A0_REV)
- +#define MV_6192_A0_NAME "88F6192 A0"
- +
- +#define MV_6190_A0_REV 0x2
- +#define MV_6190_A0_ID ((MV_6190_DEV_ID << 16) | MV_6190_A0_REV)
- +#define MV_6190_A0_NAME "88F6190 A0"
- +
- +#define MV_6180_A0_REV 0x2
- +#define MV_6180_A0_ID ((MV_6180_DEV_ID << 16) | MV_6180_A0_REV)
- +#define MV_6180_A0_NAME "88F6180 A0"
- +
- +#define MV_6281_A1_REV 0x3
- +#define MV_6281_A1_ID ((MV_6281_DEV_ID << 16) | MV_6281_A1_REV)
- +#define MV_6281_A1_NAME "88F6281 A1"
- +
- +#define MV_6192_A1_REV 0x3
- +#define MV_6192_A1_ID ((MV_6192_DEV_ID << 16) | MV_6192_A1_REV)
- +#define MV_6192_A1_NAME "88F6192 A1"
- +
- +#define MV_6190_A1_REV 0x3
- +#define MV_6190_A1_ID ((MV_6190_DEV_ID << 16) | MV_6190_A1_REV)
- +#define MV_6190_A1_NAME "88F6190 A1"
- +
- +#define MV_6180_A1_REV 0x3
- +#define MV_6180_A1_ID ((MV_6180_DEV_ID << 16) | MV_6180_A1_REV)
- +#define MV_6180_A1_NAME "88F6180 A1"
- +
- +#define MV_88F6XXX_A0_REV 0x2
- +#define MV_88F6XXX_A1_REV 0x3
- +/* Disco-Duo */
- +#define MV_78XX0_ZY_DEV_ID 0x6381
- +#define MV_78XX0_ZY_NAME "MV78X00"
- +
- +#define MV_78XX0_Z0_REV 0x1
- +#define MV_78XX0_Z0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Z0_REV)
- +#define MV_78XX0_Z0_NAME "78X00 Z0"
- +
- +#define MV_78XX0_Y0_REV 0x2
- +#define MV_78XX0_Y0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Y0_REV)
- +#define MV_78XX0_Y0_NAME "78X00 Y0"
- +
- +#define MV_78XX0_DEV_ID 0x7800
- +#define MV_78XX0_NAME "MV78X00"
- +
- +#define MV_76100_DEV_ID 0x7610
- +#define MV_78200_DEV_ID 0x7820
- +#define MV_78100_DEV_ID 0x7810
- +#define MV_78XX0_A0_REV 0x1
- +#define MV_78XX0_A1_REV 0x2
- +
- +#define MV_76100_NAME "MV76100"
- +#define MV_78100_NAME "MV78100"
- +#define MV_78200_NAME "MV78200"
- +
- +#define MV_76100_A0_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A0_REV)
- +#define MV_78100_A0_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A0_REV)
- +#define MV_78200_A0_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A0_REV)
- +
- +#define MV_76100_A1_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A1_REV)
- +#define MV_78100_A1_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A1_REV)
- +#define MV_78200_A1_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A1_REV)
- +
- +#define MV_76100_A0_NAME "MV76100 A0"
- +#define MV_78100_A0_NAME "MV78100 A0"
- +#define MV_78200_A0_NAME "MV78200 A0"
- +#define MV_78XX0_A0_NAME "MV78XX0 A0"
- +
- +#define MV_76100_A1_NAME "MV76100 A1"
- +#define MV_78100_A1_NAME "MV78100 A1"
- +#define MV_78200_A1_NAME "MV78200 A1"
- +#define MV_78XX0_A1_NAME "MV78XX0 A1"
- +
- +/*MV88F632X family*/
- +#define MV_6321_DEV_ID 0x6321
- +#define MV_6322_DEV_ID 0x6322
- +#define MV_6323_DEV_ID 0x6323
- +
- +#define MV_6321_NAME "88F6321"
- +#define MV_6322_NAME "88F6322"
- +#define MV_6323_NAME "88F6323"
- +
- +#define MV_632X_A1_REV 0x2
- +
- +#define MV_6321_A1_ID ((MV_6321_DEV_ID << 16) | MV_632X_A1_REV)
- +#define MV_6322_A1_ID ((MV_6322_DEV_ID << 16) | MV_632X_A1_REV)
- +#define MV_6323_A1_ID ((MV_6323_DEV_ID << 16) | MV_632X_A1_REV)
- +
- +#define MV_6321_A1_NAME "88F6321 A1"
- +#define MV_6322_A1_NAME "88F6322 A1"
- +#define MV_6323_A1_NAME "88F6323 A1"
- +
- +
- +#endif /* __INCmvDeviceIdh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 2010-11-09 20:28:07.069296580 +0100
- @@ -0,0 +1,73 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvHalVerh
- +#define __INCmvHalVerh
- +
- +/* Defines */
- +#define MV_HAL_VERSION "FEROCEON_HAL_3_1_7"
- +#define MV_RELEASE_BASELINE "SoCandControllers_FEROCEON_RELEASE_7_9_2009_KW_4_3_4_DD_2_1_4_6183_1_1_4"
- +
- +#endif /* __INCmvHalVerh */
- \ No newline at end of file
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.c 2010-11-09 20:28:07.102606889 +0100
- @@ -0,0 +1,100 @@
- +/*******************************************************************************
- +* Copyright 2003, Marvell Semiconductor Israel LTD. *
- +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
- +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
- +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
- +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
- +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
- +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
- +* *
- +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
- +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
- +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
- +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
- +********************************************************************************
- +* mvQueue.c
- +*
- +* FILENAME: $Workfile: mvStack.c $
- +* REVISION: $Revision: 1.1 $
- +* LAST UPDATE: $Modtime: $
- +*
- +* DESCRIPTION:
- +* This file implements simple Stack LIFO functionality.
- +*******************************************************************************/
- +
- +/* includes */
- +#include "mvOs.h"
- +#include "mvTypes.h"
- +#include "mvDebug.h"
- +#include "mvStack.h"
- +
- +/* defines */
- +
- +
- +/* Public functions */
- +
- +
- +/* Purpose: Create new stack
- + * Inputs:
- + * - MV_U32 noOfElements - maximum number of elements in the stack.
- + * Each element 4 bytes size
- + * Return: void* - pointer to created stack.
- + */
- +void* mvStackCreate(int numOfElements)
- +{
- + MV_STACK* pStack;
- + MV_U32* pStackElements;
- +
- + pStack = (MV_STACK*)mvOsMalloc(sizeof(MV_STACK));
- + pStackElements = (MV_U32*)mvOsMalloc(numOfElements*sizeof(MV_U32));
- + if( (pStack == NULL) || (pStackElements == NULL) )
- + {
- + mvOsPrintf("mvStack: Can't create new stack\n");
- + return NULL;
- + }
- + memset(pStackElements, 0, numOfElements*sizeof(MV_U32));
- + pStack->numOfElements = numOfElements;
- + pStack->stackIdx = 0;
- + pStack->stackElements = pStackElements;
- +
- + return pStack;
- +}
- +
- +/* Purpose: Delete existing stack
- + * Inputs:
- + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function
- + *
- + * Return: MV_STATUS MV_NOT_FOUND - Failure. StackHandle is not valid.
- + * MV_OK - Success.
- + */
- +MV_STATUS mvStackDelete(void* stackHndl)
- +{
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- + if( (pStack == NULL) || (pStack->stackElements == NULL) )
- + return MV_NOT_FOUND;
- +
- + mvOsFree(pStack->stackElements);
- + mvOsFree(pStack);
- +
- + return MV_OK;
- +}
- +
- +
- +/* PrintOut status of the stack */
- +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements)
- +{
- + int i;
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- + mvOsPrintf("StackHandle=%p, pElements=%p, numElements=%d, stackIdx=%d\n",
- + stackHndl, pStack->stackElements, pStack->numOfElements,
- + pStack->stackIdx);
- + if(isPrintElements == MV_TRUE)
- + {
- + for(i=0; i<pStack->stackIdx; i++)
- + {
- + mvOsPrintf("%3d. Value=0x%x\n", i, pStack->stackElements[i]);
- + }
- + }
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.h 2010-11-09 20:28:07.160842220 +0100
- @@ -0,0 +1,140 @@
- +/*******************************************************************************
- +* Copyright 2003, Marvell Semiconductor Israel LTD. *
- +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
- +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
- +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
- +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
- +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
- +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
- +* *
- +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
- +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
- +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
- +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
- +********************************************************************************
- +* mvStack.h - Header File for :
- +*
- +* FILENAME: $Workfile: mvStack.h $
- +* REVISION: $Revision: 1.1 $
- +* LAST UPDATE: $Modtime: $
- +*
- +* DESCRIPTION:
- +* This file defines simple Stack (LIFO) functionality.
- +*
- +*******************************************************************************/
- +
- +#ifndef __mvStack_h__
- +#define __mvStack_h__
- +
- +
- +/* includes */
- +#include "mvTypes.h"
- +
- +
- +/* defines */
- +
- +
- +/* typedefs */
- +/* Data structure describes general purpose Stack */
- +typedef struct
- +{
- + int stackIdx;
- + int numOfElements;
- + MV_U32* stackElements;
- +} MV_STACK;
- +
- +static INLINE MV_BOOL mvStackIsFull(void* stackHndl)
- +{
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- + if(pStack->stackIdx == pStack->numOfElements)
- + return MV_TRUE;
- +
- + return MV_FALSE;
- +}
- +
- +static INLINE MV_BOOL mvStackIsEmpty(void* stackHndl)
- +{
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- + if(pStack->stackIdx == 0)
- + return MV_TRUE;
- +
- + return MV_FALSE;
- +}
- +/* Purpose: Push new element to stack
- + * Inputs:
- + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
- + * - MV_U32 value - New element.
- + *
- + * Return: MV_STATUS MV_FULL - Failure. Stack is full.
- + * MV_OK - Success. Element is put to stack.
- + */
- +static INLINE void mvStackPush(void* stackHndl, MV_U32 value)
- +{
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- +#ifdef MV_RT_DEBUG
- + if(pStack->stackIdx == pStack->numOfElements)
- + {
- + mvOsPrintf("mvStackPush: Stack is FULL\n");
- + return;
- + }
- +#endif /* MV_RT_DEBUG */
- +
- + pStack->stackElements[pStack->stackIdx] = value;
- + pStack->stackIdx++;
- +}
- +
- +/* Purpose: Pop element from the top of stack and copy it to "pValue"
- + * Inputs:
- + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
- + * - MV_U32 value - Element in the top of stack.
- + *
- + * Return: MV_STATUS MV_EMPTY - Failure. Stack is empty.
- + * MV_OK - Success. Element is removed from the stack and
- + * copied to pValue argument
- + */
- +static INLINE MV_U32 mvStackPop(void* stackHndl)
- +{
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- +#ifdef MV_RT_DEBUG
- + if(pStack->stackIdx == 0)
- + {
- + mvOsPrintf("mvStackPop: Stack is EMPTY\n");
- + return 0;
- + }
- +#endif /* MV_RT_DEBUG */
- +
- + pStack->stackIdx--;
- + return pStack->stackElements[pStack->stackIdx];
- +}
- +
- +static INLINE int mvStackIndex(void* stackHndl)
- +{
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- + return pStack->stackIdx;
- +}
- +
- +static INLINE int mvStackFreeElements(void* stackHndl)
- +{
- + MV_STACK* pStack = (MV_STACK*)stackHndl;
- +
- + return (pStack->numOfElements - pStack->stackIdx);
- +}
- +
- +/* mvStack.h API list */
- +
- +/* Create new Stack */
- +void* mvStackCreate(int numOfElements);
- +
- +/* Delete existing stack */
- +MV_STATUS mvStackDelete(void* stackHndl);
- +
- +/* Print status of the stack */
- +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements);
- +
- +#endif /* __mvStack_h__ */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvTypes.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 2010-11-09 20:28:07.191385803 +0100
- @@ -0,0 +1,245 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvTypesh
- +#define __INCmvTypesh
- +
- +/* Defines */
- +
- +/* The following is a list of Marvell status */
- +#define MV_ERROR (-1)
- +#define MV_OK (0x00) /* Operation succeeded */
- +#define MV_FAIL (0x01) /* Operation failed */
- +#define MV_BAD_VALUE (0x02) /* Illegal value (general) */
- +#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */
- +#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */
- +#define MV_BAD_PTR (0x05) /* Illegal pointer value */
- +#define MV_BAD_SIZE (0x06) /* Illegal size */
- +#define MV_BAD_STATE (0x07) /* Illegal state of state machine */
- +#define MV_SET_ERROR (0x08) /* Set operation failed */
- +#define MV_GET_ERROR (0x09) /* Get operation failed */
- +#define MV_CREATE_ERROR (0x0A) /* Fail while creating an item */
- +#define MV_NOT_FOUND (0x0B) /* Item not found */
- +#define MV_NO_MORE (0x0C) /* No more items found */
- +#define MV_NO_SUCH (0x0D) /* No such item */
- +#define MV_TIMEOUT (0x0E) /* Time Out */
- +#define MV_NO_CHANGE (0x0F) /* Parameter(s) is already in this value */
- +#define MV_NOT_SUPPORTED (0x10) /* This request is not support */
- +#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented */
- +#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */
- +#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */
- +#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */
- +#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */
- +#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */
- +#define MV_HW_ERROR (0x17) /* Hardware error */
- +#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */
- +#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */
- +#define MV_NOT_READY (0x1A) /* The other side is not ready yet */
- +#define MV_ALREADY_EXIST (0x1B) /* Tried to create existing item */
- +#define MV_OUT_OF_CPU_MEM (0x1C) /* Cpu memory allocation failed. */
- +#define MV_NOT_STARTED (0x1D) /* Not started yet */
- +#define MV_BUSY (0x1E) /* Item is busy. */
- +#define MV_TERMINATE (0x1F) /* Item terminates it's work. */
- +#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */
- +#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */
- +#define MV_WRITE_PROTECT (0x22) /* Write protected */
- +
- +
- +#define MV_INVALID (int)(-1)
- +
- +#define MV_FALSE 0
- +#define MV_TRUE (!(MV_FALSE))
- +
- +
- +#ifndef NULL
- +#define NULL ((void*)0)
- +#endif
- +
- +
- +#ifndef MV_ASMLANGUAGE
- +/* typedefs */
- +
- +typedef char MV_8;
- +typedef unsigned char MV_U8;
- +
- +typedef int MV_32;
- +typedef unsigned int MV_U32;
- +
- +typedef short MV_16;
- +typedef unsigned short MV_U16;
- +
- +#ifdef MV_PPC64
- +typedef long MV_64;
- +typedef unsigned long MV_U64;
- +#else
- +typedef long long MV_64;
- +typedef unsigned long long MV_U64;
- +#endif
- +
- +typedef long MV_LONG; /* 32/64 */
- +typedef unsigned long MV_ULONG; /* 32/64 */
- +
- +typedef int MV_STATUS;
- +typedef int MV_BOOL;
- +typedef void MV_VOID;
- +typedef float MV_FLOAT;
- +
- +typedef int (*MV_FUNCPTR) (void); /* ptr to function returning int */
- +typedef void (*MV_VOIDFUNCPTR) (void); /* ptr to function returning void */
- +typedef double (*MV_DBLFUNCPTR) (void); /* ptr to function returning double*/
- +typedef float (*MV_FLTFUNCPTR) (void); /* ptr to function returning float */
- +
- +typedef MV_U32 MV_KHZ;
- +typedef MV_U32 MV_MHZ;
- +typedef MV_U32 MV_HZ;
- +
- +
- +/* This enumerator describes the set of commands that can be applied on */
- +/* an engine (e.g. IDMA, XOR). Appling a comman depends on the current */
- +/* status (see MV_STATE enumerator) */
- +/* Start can be applied only when status is IDLE */
- +/* Stop can be applied only when status is IDLE, ACTIVE or PAUSED */
- +/* Pause can be applied only when status is ACTIVE */
- +/* Restart can be applied only when status is PAUSED */
- +typedef enum _mvCommand
- +{
- + MV_START, /* Start */
- + MV_STOP, /* Stop */
- + MV_PAUSE, /* Pause */
- + MV_RESTART /* Restart */
- +} MV_COMMAND;
- +
- +/* This enumerator describes the set of state conditions. */
- +/* Moving from one state to other is stricted. */
- +typedef enum _mvState
- +{
- + MV_IDLE,
- + MV_ACTIVE,
- + MV_PAUSED,
- + MV_UNDEFINED_STATE
- +} MV_STATE;
- +
- +
- +/* This structure describes address space window. Window base can be */
- +/* 64 bit, window size up to 4GB */
- +typedef struct _mvAddrWin
- +{
- + MV_U32 baseLow; /* 32bit base low */
- + MV_U32 baseHigh; /* 32bit base high */
- + MV_U32 size; /* 32bit size */
- +}MV_ADDR_WIN;
- +
- +/* This binary enumerator describes protection attribute status */
- +typedef enum _mvProtRight
- +{
- + ALLOWED, /* Protection attribute allowed */
- + FORBIDDEN /* Protection attribute forbidden */
- +}MV_PROT_RIGHT;
- +
- +/* Unified struct for Rx and Tx packet operations. The user is required to */
- +/* be familier only with Tx/Rx descriptor command status. */
- +typedef struct _bufInfo
- +{
- + MV_U32 cmdSts; /* Tx/Rx command status */
- + MV_U16 byteCnt; /* Size of valid data in the buffer */
- + MV_U16 bufSize; /* Total size of the buffer */
- + MV_U8 *pBuff; /* Pointer to Buffer */
- + MV_U8 *pData; /* Pointer to data in the Buffer */
- + MV_U32 userInfo1; /* Tx/Rx attached user information 1 */
- + MV_U32 userInfo2; /* Tx/Rx attached user information 2 */
- + struct _bufInfo *pNextBufInfo; /* Next buffer in packet */
- +} BUF_INFO;
- +
- +/* This structure contains information describing one of buffers
- + * (fragments) they are built Ethernet packet.
- + */
- +typedef struct
- +{
- + MV_U8* bufVirtPtr;
- + MV_ULONG bufPhysAddr;
- + MV_U32 bufSize;
- + MV_U32 dataSize;
- + MV_U32 memHandle;
- + MV_32 bufAddrShift;
- +} MV_BUF_INFO;
- +
- +/* This structure contains information describing Ethernet packet.
- + * The packet can be divided for few buffers (fragments)
- + */
- +typedef struct
- +{
- + MV_ULONG osInfo;
- + MV_BUF_INFO *pFrags;
- + MV_U32 status;
- + MV_U16 pktSize;
- + MV_U16 numFrags;
- + MV_U32 ownerId;
- + MV_U32 fragIP;
- +} MV_PKT_INFO;
- +
- +#endif /* MV_ASMLANGUAGE */
- +
- +#endif /* __INCmvTypesh */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.c 2010-11-09 20:28:07.232495685 +0100
- @@ -0,0 +1,110 @@
- +#include <linux/kernel.h>
- +#include <linux/slab.h>
- +#include <linux/time.h>
- +#include "dbg-trace.h"
- +
- +#define TRACE_ARR_LEN 800
- +#define STR_LEN 128
- +struct trace {
- + struct timeval tv;
- + char str[STR_LEN];
- + unsigned int callback_val1;
- + unsigned int callback_val2;
- + char valid;
- +};
- +static unsigned int (*trc_callback1) (unsigned char) = NULL;
- +static unsigned int (*trc_callback2) (unsigned char) = NULL;
- +static unsigned char trc_param1 = 0;
- +static unsigned char trc_param2 = 0;
- +struct trace *trc_arr;
- +static int trc_index;
- +static int trc_active = 0;
- +
- +void TRC_START()
- +{
- + trc_active = 1;
- +}
- +
- +void TRC_STOP()
- +{
- + trc_active = 0;
- +}
- +
- +void TRC_INIT(void *callback1, void *callback2, unsigned char callback1_param, unsigned char callback2_param)
- +{
- + printk("Marvell debug tracing is on\n");
- + trc_arr = (struct trace *)kmalloc(TRACE_ARR_LEN*sizeof(struct trace),GFP_KERNEL);
- + if(trc_arr == NULL)
- + {
- + printk("Can't allocate Debug Trace buffer\n");
- + return;
- + }
- + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
- + trc_index = 0;
- + trc_callback1 = callback1;
- + trc_callback2 = callback2;
- + trc_param1 = callback1_param;
- + trc_param2 = callback2_param;
- +}
- +void TRC_REC(char *fmt,...)
- +{
- + va_list args;
- + struct trace *trc = &trc_arr[trc_index];
- +
- + if(trc_active == 0)
- + return;
- +
- + do_gettimeofday(&trc->tv);
- + if(trc_callback1)
- + trc->callback_val1 = trc_callback1(trc_param1);
- + if(trc_callback2)
- + trc->callback_val2 = trc_callback2(trc_param2);
- + va_start(args, fmt);
- + vsprintf(trc->str,fmt,args);
- + va_end(args);
- + trc->valid = 1;
- + if((++trc_index) == TRACE_ARR_LEN) {
- + trc_index = 0;
- + }
- +}
- +void TRC_OUTPUT(void)
- +{
- + int i,j;
- + struct trace *p;
- + printk("\n\nTrace %d items\n",TRACE_ARR_LEN);
- + for(i=0,j=trc_index; i<TRACE_ARR_LEN; i++,j++) {
- + if(j == TRACE_ARR_LEN)
- + j = 0;
- + p = &trc_arr[j];
- + if(p->valid) {
- + unsigned long uoffs;
- + struct trace *plast;
- + if(p == &trc_arr[0])
- + plast = &trc_arr[TRACE_ARR_LEN-1];
- + else
- + plast = p-1;
- + if(p->tv.tv_sec == ((plast)->tv.tv_sec))
- + uoffs = (p->tv.tv_usec - ((plast)->tv.tv_usec));
- + else
- + uoffs = (1000000 - ((plast)->tv.tv_usec)) +
- + ((p->tv.tv_sec - ((plast)->tv.tv_sec) - 1) * 1000000) +
- + p->tv.tv_usec;
- + printk("%03d: [+%ld usec]", j, (unsigned long)uoffs);
- + if(trc_callback1)
- + printk("[%u]",p->callback_val1);
- + if(trc_callback2)
- + printk("[%u]",p->callback_val2);
- + printk(": %s",p->str);
- + }
- + p->valid = 0;
- + }
- + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
- + trc_index = 0;
- +}
- +void TRC_RELEASE(void)
- +{
- + kfree(trc_arr);
- + trc_index = 0;
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.h 2010-11-09 20:28:07.276291416 +0100
- @@ -0,0 +1,24 @@
- +
- +#ifndef _MV_DBG_TRCE_H_
- +#define _MV_DBG_TRCE_H_
- +
- +#ifdef CONFIG_MV_DBG_TRACE
- +void TRC_INIT(void *callback1, void *callback2,
- + unsigned char callback1_param, unsigned char callback2_param);
- +void TRC_REC(char *fmt,...);
- +void TRC_OUTPUT(void);
- +void TRC_RELEASE(void);
- +void TRC_START(void);
- +void TRC_STOP(void);
- +
- +#else
- +#define TRC_INIT(x1,x2,x3,x4)
- +#define TRC_REC(X...)
- +#define TRC_OUTPUT()
- +#define TRC_RELEASE()
- +#define TRC_START()
- +#define TRC_STOP()
- +#endif
- +
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 2010-11-09 20:28:07.327371127 +0100
- @@ -0,0 +1,2513 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "boardEnv/mvBoardEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "cpu/mvCpu.h"
- +#include "cntmr/mvCntmr.h"
- +#include "gpp/mvGpp.h"
- +#include "twsi/mvTwsi.h"
- +#include "pex/mvPex.h"
- +#include "device/mvDevice.h"
- +#include "eth/gbe/mvEthRegs.h"
- +
- +/* defines */
- +/* #define MV_DEBUG */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +extern MV_CPU_ARM_CLK _cpuARMDDRCLK[];
- +
- +#define CODE_IN_ROM MV_FALSE
- +#define CODE_IN_RAM MV_TRUE
- +
- +extern MV_BOARD_INFO* boardInfoTbl[];
- +#define BOARD_INFO(boardId) boardInfoTbl[boardId - BOARD_ID_BASE]
- +
- +/* Locals */
- +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
- +
- +MV_U32 tClkRate = -1;
- +
- +
- +/*******************************************************************************
- +* mvBoardEnvInit - Init board
- +*
- +* DESCRIPTION:
- +* In this function the board environment take care of device bank
- +* initialization.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardEnvInit(MV_VOID)
- +{
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardEnvInit:Board unknown.\n");
- + return;
- +
- + }
- +
- + /* Set GPP Out value */
- + MV_REG_WRITE(GPP_DATA_OUT_REG(0), BOARD_INFO(boardId)->gppOutValLow);
- + MV_REG_WRITE(GPP_DATA_OUT_REG(1), BOARD_INFO(boardId)->gppOutValHigh);
- +
- + /* set GPP polarity */
- + mvGppPolaritySet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValLow);
- + mvGppPolaritySet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValHigh);
- +
- + /* Workaround for Erratum FE-MISC-70*/
- + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV)
- + {
- + BOARD_INFO(boardId)->gppOutEnValLow &= 0xfffffffd;
- + BOARD_INFO(boardId)->gppOutEnValLow |= (BOARD_INFO(boardId)->gppOutEnValHigh) & 0x00000002;
- + } /*End of WA*/
- +
- + /* Set GPP Out Enable*/
- + mvGppTypeSet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValLow);
- + mvGppTypeSet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValHigh);
- +
- + /* Nand CE */
- + MV_REG_BIT_SET(NAND_CTRL_REG, NAND_ACTCEBOOT_BIT);
- +}
- +
- +/*******************************************************************************
- +* mvBoardModelGet - Get Board model
- +*
- +* DESCRIPTION:
- +* This function returns 16bit describing board model.
- +* Board model is constructed of one byte major and minor numbers in the
- +* following manner:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* String describing board model.
- +*
- +*******************************************************************************/
- +MV_U16 mvBoardModelGet(MV_VOID)
- +{
- + return (mvBoardIdGet() >> 16);
- +}
- +
- +/*******************************************************************************
- +* mbBoardRevlGet - Get Board revision
- +*
- +* DESCRIPTION:
- +* This function returns a 32bit describing the board revision.
- +* Board revision is constructed of 4bytes. 2bytes describes major number
- +* and the other 2bytes describes minor munber.
- +* For example for board revision 3.4 the function will return
- +* 0x00030004.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* String describing board model.
- +*
- +*******************************************************************************/
- +MV_U16 mvBoardRevGet(MV_VOID)
- +{
- + return (mvBoardIdGet() & 0xFFFF);
- +}
- +
- +/*******************************************************************************
- +* mvBoardNameGet - Get Board name
- +*
- +* DESCRIPTION:
- +* This function returns a string describing the board model and revision.
- +* String is extracted from board I2C EEPROM.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
- +*
- +* RETURN:
- +*
- +* MV_ERROR if informantion can not be read.
- +*******************************************************************************/
- +MV_STATUS mvBoardNameGet(char *pNameBuff)
- +{
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsSPrintf (pNameBuff, "Board unknown.\n");
- + return MV_ERROR;
- +
- + }
- +
- + mvOsSPrintf (pNameBuff, "%s",BOARD_INFO(boardId)->boardName);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvBoardIsPortInSgmii -
- +*
- +* DESCRIPTION:
- +* This routine returns MV_TRUE for port number works in SGMII or MV_FALSE
- +* For all other options.
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE - port in SGMII.
- +* MV_FALSE - other.
- +*
- +*******************************************************************************/
- +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)
- +{
- + MV_BOOL ethPortSgmiiSupport[BOARD_ETH_PORT_NUM] = MV_ETH_PORT_SGMII;
- +
- + if(ethPortNum >= BOARD_ETH_PORT_NUM)
- + {
- + mvOsPrintf ("Invalid portNo=%d\n", ethPortNum);
- + return MV_FALSE;
- + }
- + return ethPortSgmiiSupport[ethPortNum];
- +}
- +
- +/*******************************************************************************
- +* mvBoardIsPortInGmii -
- +*
- +* DESCRIPTION:
- +* This routine returns MV_TRUE for port number works in GMII or MV_FALSE
- +* For all other options.
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE - port in GMII.
- +* MV_FALSE - other.
- +*
- +*******************************************************************************/
- +MV_BOOL mvBoardIsPortInGmii(MV_VOID)
- +{
- + MV_U32 devClassId, devClass = 0;
- + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
- + {
- + /* Get MPP module ID */
- + devClassId = mvBoarModuleTypeGet(devClass);
- + if (MV_BOARD_MODULE_GMII_ID == devClassId)
- + return MV_TRUE;
- + }
- + else if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII)
- + return MV_TRUE;
- +
- + return MV_FALSE;
- +}
- +/*******************************************************************************
- +* mvBoardPhyAddrGet - Get the phy address
- +*
- +* DESCRIPTION:
- +* This routine returns the Phy address of a given ethernet port.
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit describing Phy address, -1 if the port number is wrong.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum)
- +{
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardPhyAddrGet: Board unknown.\n");
- + return MV_ERROR;
- + }
- +
- + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardEthSmiAddr;
- +}
- +
- +/*******************************************************************************
- +* mvBoardMacSpeedGet - Get the Mac speed
- +*
- +* DESCRIPTION:
- +* This routine returns the Mac speed if pre define of a given ethernet port.
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BOARD_MAC_SPEED, -1 if the port number is wrong.
- +*
- +*******************************************************************************/
- +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum)
- +{
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardMacSpeedGet: Board unknown.\n");
- + return MV_ERROR;
- + }
- +
- + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardMacSpeed;
- +}
- +
- +/*******************************************************************************
- +* mvBoardLinkStatusIrqGet - Get the IRQ number for the link status indication
- +*
- +* DESCRIPTION:
- +* This routine returns the IRQ number for the link status indication.
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* the number of the IRQ for the link status indication, -1 if the port
- +* number is wrong or if not relevant.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum)
- +{
- + MV_U32 boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardLinkStatusIrqGet: Board unknown.\n");
- + return MV_ERROR;
- + }
- +
- + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].linkStatusIrq;
- +}
- +
- +/*******************************************************************************
- +* mvBoardSwitchPortGet - Get the mapping between the board connector and the
- +* Ethernet Switch port
- +*
- +* DESCRIPTION:
- +* This routine returns the matching Switch port.
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +* boardPortNum - logical number of the connector on the board
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* the matching Switch port, -1 if the port number is wrong or if not relevant.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum)
- +{
- + MV_U32 boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardSwitchPortGet: Board unknown.\n");
- + return MV_ERROR;
- + }
- + if (boardPortNum >= BOARD_ETH_SWITCH_PORT_NUM)
- + {
- + mvOsPrintf("mvBoardSwitchPortGet: Illegal board port number.\n");
- + return MV_ERROR;
- + }
- +
- + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdPort[boardPortNum];
- +}
- +
- +/*******************************************************************************
- +* mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port
- +*
- +* DESCRIPTION:
- +* This routine returns the Switch CPU port.
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* the Switch CPU port, -1 if the port number is wrong or if not relevant.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum)
- +{
- + MV_U32 boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardSwitchCpuPortGet: Board unknown.\n");
- + return MV_ERROR;
- + }
- +
- + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdCpuPort;
- +}
- +
- +/*******************************************************************************
- +* mvBoardIsSwitchConnected - Get switch connection status
- +* DESCRIPTION:
- +* This routine returns port's connection status
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 1 - if ethPortNum is connected to switch, 0 otherwise
- +*
- +*******************************************************************************/
- +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum)
- +{
- + MV_U32 boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardIsSwitchConnected: Board unknown.\n");
- + return MV_ERROR;
- + }
- +
- + if(ethPortNum >= BOARD_INFO(boardId)->numBoardMacInfo)
- + {
- + mvOsPrintf("mvBoardIsSwitchConnected: Illegal port number(%u)\n", ethPortNum);
- + return MV_ERROR;
- + }
- +
- + if((MV_32)(BOARD_INFO(boardId)->pSwitchInfo))
- + return (MV_32)(BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].switchOnPort == ethPortNum);
- + else
- + return 0;
- +}
- +/*******************************************************************************
- +* mvBoardSmiScanModeGet - Get Switch SMI scan mode
- +*
- +* DESCRIPTION:
- +* This routine returns Switch SMI scan mode.
- +*
- +* INPUT:
- +* ethPortNum - Ethernet port number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum)
- +{
- + MV_U32 boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardSmiScanModeGet: Board unknown.\n");
- + return MV_ERROR;
- + }
- +
- + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].smiScanMode;
- +}
- +/*******************************************************************************
- +* mvBoardSpecInitGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN: Return MV_TRUE and parameters in case board need spesific phy init,
- +* otherwise return MV_FALSE.
- +*
- +*
- +*******************************************************************************/
- +
- +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data)
- +{
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* mvBoardTclkGet - Get the board Tclk (Controller clock)
- +*
- +* DESCRIPTION:
- +* This routine extract the controller core clock.
- +* This function uses the controller counters to make identification.
- +* Note: In order to avoid interference, make sure task context switch
- +* and interrupts will not occure during this function operation
- +*
- +* INPUT:
- +* countNum - Counter number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit clock cycles in Hertz.
- +*
- +*******************************************************************************/
- +MV_U32 mvBoardTclkGet(MV_VOID)
- +{
- + if(mvCtrlModelGet()==MV_6281_DEV_ID)
- + {
- +#if defined(TCLK_AUTO_DETECT)
- + MV_U32 tmpTClkRate = MV_BOARD_TCLK_166MHZ;
- +
- + tmpTClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + tmpTClkRate &= MSAR_TCLCK_MASK;
- +
- + switch (tmpTClkRate)
- + {
- + case MSAR_TCLCK_166:
- + return MV_BOARD_TCLK_166MHZ;
- + break;
- + case MSAR_TCLCK_200:
- + return MV_BOARD_TCLK_200MHZ;
- + break;
- + }
- +#else
- + return MV_BOARD_TCLK_200MHZ;
- +#endif
- + }
- +
- + return MV_BOARD_TCLK_166MHZ;
- +
- +}
- +/*******************************************************************************
- +* mvBoardSysClkGet - Get the board SysClk (CPU bus clock)
- +*
- +* DESCRIPTION:
- +* This routine extract the CPU bus clock.
- +*
- +* INPUT:
- +* countNum - Counter number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit clock cycles in Hertz.
- +*
- +*******************************************************************************/
- +static MV_U32 mvBoard6180SysClkGet(MV_VOID)
- +{
- + MV_U32 sysClkRate=0;
- + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
- +
- + sysClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + sysClkRate = sysClkRate & MSAR_CPUCLCK_MASK_6180;
- + sysClkRate = sysClkRate >> MSAR_CPUCLCK_OFFS_6180;
- +
- + sysClkRate = _cpu6180_ddr_l2_CLK[sysClkRate].ddrClk;
- +
- + return sysClkRate;
- +
- +}
- +
- +MV_U32 mvBoardSysClkGet(MV_VOID)
- +{
- +#ifdef SYSCLK_AUTO_DETECT
- + MV_U32 sysClkRate, tmp, pClkRate, indexDdrRtio;
- + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
- + MV_U32 ddrRtio[][2] = MV_DDR_CLCK_RTIO_TBL;
- +
- + if(mvCtrlModelGet() == MV_6180_DEV_ID)
- + return mvBoard6180SysClkGet();
- +
- + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + pClkRate = MSAR_CPUCLCK_EXTRACT(tmp);
- + pClkRate = cpuCLK[pClkRate];
- +
- + indexDdrRtio = tmp & MSAR_DDRCLCK_RTIO_MASK;
- + indexDdrRtio = indexDdrRtio >> MSAR_DDRCLCK_RTIO_OFFS;
- + if(ddrRtio[indexDdrRtio][0] != 0)
- + sysClkRate = ((pClkRate * ddrRtio[indexDdrRtio][1]) / ddrRtio[indexDdrRtio][0]);
- + else
- + sysClkRate = 0;
- + return sysClkRate;
- +#else
- + return MV_BOARD_DEFAULT_SYSCLK;
- +#endif
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoardPexBridgeIntPinGet - Get PEX to PCI bridge interrupt pin number
- +*
- +* DESCRIPTION:
- +* Multi-ported PCI Express bridges that is implemented on the board
- +* collapse interrupts across multiple conventional PCI/PCI-X buses.
- +* A dual-headed PCI Express bridge would map (or "swizzle") the
- +* interrupts per the following table (in accordance with the respective
- +* logical PCI/PCI-X bridge's Device Number), collapse the INTA#-INTD#
- +* signals from its two logical PCI/PCI-X bridges, collapse the
- +* INTA#-INTD# signals from any internal sources, and convert the
- +* signals to in-band PCI Express messages. 10
- +* This function returns the upstream interrupt as it was converted by
- +* the bridge, according to board configuration and the following table:
- +* PCI dev num
- +* Interrupt pin 7, 8, 9
- +* A -> A D C
- +* B -> B A D
- +* C -> C B A
- +* D -> D C B
- +*
- +*
- +* INPUT:
- +* devNum - PCI/PCIX device number.
- +* intPin - PCI Int pin
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Int pin connected to the Interrupt controller
- +*
- +*******************************************************************************/
- +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin)
- +{
- + MV_U32 realIntPin = ((intPin + (3 - (devNum % 4))) %4 );
- +
- + if (realIntPin == 0) return 4;
- + else return realIntPin;
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardDebugLedNumGet - Get number of debug Leds
- +*
- +* DESCRIPTION:
- +* INPUT:
- +* boardId
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId)
- +{
- + return BOARD_INFO(boardId)->activeLedsNumber;
- +}
- +
- +/*******************************************************************************
- +* mvBoardDebugLeg - Set the board debug Leds
- +*
- +* DESCRIPTION: turn on/off status leds.
- +* Note: assume MPP leds are part of group 0 only.
- +*
- +* INPUT:
- +* hexNum - Number to be displied in hex by Leds.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardDebugLed(MV_U32 hexNum)
- +{
- + MV_U32 val = 0,totalMask, currentBitMask = 1,i;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (BOARD_INFO(boardId)->pLedGppPin == NULL)
- + return;
- +
- + totalMask = (1 << BOARD_INFO(boardId)->activeLedsNumber) -1;
- + hexNum &= totalMask;
- + totalMask = 0;
- +
- + for (i = 0 ; i < BOARD_INFO(boardId)->activeLedsNumber ; i++)
- + {
- + if (hexNum & currentBitMask)
- + {
- + val |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
- + }
- +
- + totalMask |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
- +
- + currentBitMask = (currentBitMask << 1);
- + }
- +
- + if (BOARD_INFO(boardId)->ledsPolarity)
- + {
- + mvGppValueSet(0, totalMask, val);
- + }
- + else
- + {
- + mvGppValueSet(0, totalMask, ~val);
- + }
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoarGpioPinGet - mvBoarGpioPinGet
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* class - MV_BOARD_GPP_CLASS enum.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* GPIO pin number. The function return -1 for bad parameters.
- +*
- +*******************************************************************************/
- +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index)
- +{
- + MV_U32 boardId, i;
- + MV_U32 indexFound = 0;
- +
- + boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardRTCGpioPinGet:Board unknown.\n");
- + return MV_ERROR;
- +
- + }
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardGppInfo; i++)
- + if (BOARD_INFO(boardId)->pBoardGppInfo[i].devClass == class) {
- + if (indexFound == index)
- + return (MV_U32)BOARD_INFO(boardId)->pBoardGppInfo[i].gppPinNum;
- + else
- + indexFound++;
- +
- + }
- +
- + return MV_ERROR;
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoardRTCGpioPinGet - mvBoardRTCGpioPinGet
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* GPIO pin number. The function return -1 for bad parameters.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardRTCGpioPinGet(MV_VOID)
- +{
- + return mvBoarGpioPinNumGet(BOARD_GPP_RTC, 0);
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoardReset - mvBoardReset
- +*
- +* DESCRIPTION:
- +* Reset the board
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardReset(MV_VOID)
- +{
- + MV_32 resetPin;
- +
- + /* Get gpp reset pin if define */
- + resetPin = mvBoardResetGpioPinGet();
- + if (resetPin != MV_ERROR)
- + {
- + MV_REG_BIT_RESET( GPP_DATA_OUT_REG(0) ,(1 << resetPin));
- + MV_REG_BIT_RESET( GPP_DATA_OUT_EN_REG(0) ,(1 << resetPin));
- +
- + }
- + else
- + {
- + /* No gpp reset pin was found, try to reset ussing
- + system reset out */
- + MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT2);
- + MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0);
- + }
- +}
- +
- +/*******************************************************************************
- +* mvBoardResetGpioPinGet - mvBoardResetGpioPinGet
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* GPIO pin number. The function return -1 for bad parameters.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardResetGpioPinGet(MV_VOID)
- +{
- + return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);
- +}
- +/*******************************************************************************
- +* mvBoardSDIOGpioPinGet - mvBoardSDIOGpioPinGet
- +*
- +* DESCRIPTION:
- +* used for hotswap detection
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* GPIO pin number. The function return -1 for bad parameters.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardSDIOGpioPinGet(MV_VOID)
- +{
- + return mvBoarGpioPinNumGet(BOARD_GPP_SDIO_DETECT, 0);
- +}
- +
- +/*******************************************************************************
- +* mvBoardUSBVbusGpioPinGet - return Vbus input GPP
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* int devNo.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* GPIO pin number. The function return -1 for bad parameters.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId)
- +{
- + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId);
- +}
- +
- +/*******************************************************************************
- +* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* int devNo.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* GPIO pin number. The function return -1 for bad parameters.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)
- +{
- + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins
- +*
- +* DESCRIPTION:
- +* This function returns a 32-bit mask of GPP pins that connected to
- +* interrupt generating sources on board.
- +* For example if UART channel A is hardwired to GPP pin 8 and
- +* UART channel B is hardwired to GPP pin 4 the fuinction will return
- +* the value 0x000000110
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* See description. The function return -1 if board is not identified.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID)
- +{
- + MV_U32 boardId;
- +
- + boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
- + return MV_ERROR;
- +
- + }
- +
- + return BOARD_INFO(boardId)->intsGppMaskLow;
- +}
- +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID)
- +{
- + MV_U32 boardId;
- +
- + boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
- + return MV_ERROR;
- +
- + }
- +
- + return BOARD_INFO(boardId)->intsGppMaskHigh;
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoardMppGet - Get board dependent MPP register value
- +*
- +* DESCRIPTION:
- +* MPP settings are derived from board design.
- +* MPP group consist of 8 MPPs. An MPP group represent MPP
- +* control register.
- +* This function retrieves board dependend MPP register value.
- +*
- +* INPUT:
- +* mppGroupNum - MPP group number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit value describing MPP control register value.
- +*
- +*******************************************************************************/
- +MV_32 mvBoardMppGet(MV_U32 mppGroupNum)
- +{
- + MV_U32 boardId;
- +
- + boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
- + return MV_ERROR;
- +
- + }
- +
- + return BOARD_INFO(boardId)->pBoardMppConfigValue[0].mppGroup[mppGroupNum];
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoardMppGroupId - If MPP group type is AUTO then identify it using twsi
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID)
- +{
- +
- + MV_BOARD_MPP_GROUP_CLASS devClass;
- + MV_BOARD_MODULE_ID_CLASS devClassId;
- + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
- + MV_U32 devId;
- + MV_U32 maxMppGrp = 1;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + maxMppGrp = MV_6281_MPP_MAX_MODULE;
- + break;
- + case MV_6192_DEV_ID:
- + maxMppGrp = MV_6192_MPP_MAX_MODULE;
- + break;
- + case MV_6190_DEV_ID:
- + maxMppGrp = MV_6190_MPP_MAX_MODULE;
- + break;
- + case MV_6180_DEV_ID:
- + maxMppGrp = MV_6180_MPP_MAX_MODULE;
- + break;
- + }
- +
- + for (devClass = 0; devClass < maxMppGrp; devClass++)
- + {
- + /* If MPP group can be defined by the module connected to it */
- + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
- + {
- + /* Get MPP module ID */
- + devClassId = mvBoarModuleTypeGet(devClass);
- + if (MV_ERROR != devClassId)
- + {
- + switch(devClassId)
- + {
- + case MV_BOARD_MODULE_TDM_ID:
- + case MV_BOARD_MODULE_TDM_5CHAN_ID:
- + mppGroupType = MV_BOARD_TDM;
- + break;
- + case MV_BOARD_MODULE_AUDIO_ID:
- + mppGroupType = MV_BOARD_AUDIO;
- + break;
- + case MV_BOARD_MODULE_RGMII_ID:
- + mppGroupType = MV_BOARD_RGMII;
- + break;
- + case MV_BOARD_MODULE_GMII_ID:
- + mppGroupType = MV_BOARD_GMII;
- + break;
- + case MV_BOARD_MODULE_TS_ID:
- + mppGroupType = MV_BOARD_TS;
- + break;
- + case MV_BOARD_MODULE_MII_ID:
- + mppGroupType = MV_BOARD_MII;
- + break;
- + default:
- + mppGroupType = MV_BOARD_OTHER;
- + break;
- + }
- + }
- + else
- + /* The module bay is empty */
- + mppGroupType = MV_BOARD_OTHER;
- +
- + /* Update MPP group type */
- + mvBoardMppGroupTypeSet(devClass, mppGroupType);
- + }
- +
- + /* Update MPP output voltage for RGMII 1.8V. Set port to GMII for GMII module */
- + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_RGMII))
- + MV_REG_BIT_SET(MPP_OUTPUT_DRIVE_REG,MPP_1_8_RGMII1_OUTPUT_DRIVE | MPP_1_8_RGMII0_OUTPUT_DRIVE);
- + else
- + {
- + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII))
- + {
- + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
- + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(0),BIT3);
- + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
- + }
- + else if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_MII))
- + {
- + /* Assumption that the MDC & MDIO should be 3.3V */
- + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
- + /* Assumption that only ETH1 can be MII when using modules on DB */
- + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
- + }
- + }
- + }
- +}
- +
- +/*******************************************************************************
- +* mvBoardMppGroupTypeGet
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass)
- +{
- + MV_U32 boardId;
- +
- + boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
- + return MV_ERROR;
- +
- + }
- +
- + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
- + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1;
- + else
- + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2;
- +}
- +
- +/*******************************************************************************
- +* mvBoardMppGroupTypeSet
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
- +* mppGroupType - MPP group type for MPP[35:20] or for MPP[49:36].
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
- + MV_BOARD_MPP_TYPE_CLASS mppGroupType)
- +{
- + MV_U32 boardId;
- +
- + boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
- + }
- +
- + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
- + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1 = mppGroupType;
- + else
- + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2 = mppGroupType;
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardMppMuxSet - Update MPP mux
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardMppMuxSet(MV_VOID)
- +{
- +
- + MV_BOARD_MPP_GROUP_CLASS devClass;
- + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
- + MV_U32 devId;
- + MV_U8 muxVal = 0xf;
- + MV_U32 maxMppGrp = 1;
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + maxMppGrp = MV_6281_MPP_MAX_MODULE;
- + break;
- + case MV_6192_DEV_ID:
- + maxMppGrp = MV_6192_MPP_MAX_MODULE;
- + break;
- + case MV_6190_DEV_ID:
- + maxMppGrp = MV_6190_MPP_MAX_MODULE;
- + break;
- + case MV_6180_DEV_ID:
- + maxMppGrp = MV_6180_MPP_MAX_MODULE;
- + break;
- + }
- +
- + for (devClass = 0; devClass < maxMppGrp; devClass++)
- + {
- + mppGroupType = mvBoardMppGroupTypeGet(devClass);
- +
- + switch(mppGroupType)
- + {
- + case MV_BOARD_TDM:
- + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
- + break;
- + case MV_BOARD_AUDIO:
- + muxVal &= ~(devClass ? 0x7 : 0x0); /*old Z0 value 0xd:0x0*/
- + break;
- + case MV_BOARD_TS:
- + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
- + break;
- + default:
- + muxVal |= (devClass ? 0xf : 0);
- + break;
- + }
- + }
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + DB(mvOsPrintf("Board: twsi exp set\n"));
- + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
- + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
- + twsiSlave.validOffset = MV_TRUE;
- + /* Offset is the first command after the address which indicate the register number to be read
- + in next operation */
- + twsiSlave.offset = 2;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- +
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
- + return;
- + }
- + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
- +
- + /* Change twsi exp to output */
- + twsiSlave.offset = 6;
- + muxVal = 0;
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
- + return;
- + }
- + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardTdmMppSet - set MPPs in TDM module
- +*
- +* DESCRIPTION:
- +*
- +* INPUT: type of second telephony device
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardTdmMppSet(MV_32 chType)
- +{
- +
- + MV_BOARD_MPP_GROUP_CLASS devClass;
- + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
- + MV_U32 devId;
- + MV_U8 muxVal = 1;
- + MV_U8 muxValMask = 1;
- + MV_U8 twsiVal;
- + MV_U32 maxMppGrp = 1;
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + maxMppGrp = MV_6281_MPP_MAX_MODULE;
- + break;
- + case MV_6192_DEV_ID:
- + maxMppGrp = MV_6192_MPP_MAX_MODULE;
- + break;
- + case MV_6190_DEV_ID:
- + maxMppGrp = MV_6190_MPP_MAX_MODULE;
- + break;
- + case MV_6180_DEV_ID:
- + maxMppGrp = MV_6180_MPP_MAX_MODULE;
- + break;
- + }
- +
- + for (devClass = 0; devClass < maxMppGrp; devClass++)
- + {
- + mppGroupType = mvBoardMppGroupTypeGet(devClass);
- + if(mppGroupType == MV_BOARD_TDM)
- + break;
- + }
- +
- + if(devClass == maxMppGrp)
- + return; /* TDM module not found */
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + DB(mvOsPrintf("Board: twsi exp set\n"));
- + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + /* Offset is the first command after the address which indicate the register number to be read
- + in next operation */
- + twsiSlave.offset = 3;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + if(mvBoardIdGet() == RD_88F6281A_ID)
- + {
- + muxVal = 0xc;
- + muxValMask = 0xf3;
- + }
- +
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + muxVal = (twsiVal & muxValMask) | muxVal;
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + mvOsPrintf("Board: twsi exp out val fail\n");
- + return;
- + }
- + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
- +
- + /* Change twsi exp to output */
- + twsiSlave.offset = 7;
- + muxVal = 0xfe;
- + if(mvBoardIdGet() == RD_88F6281A_ID)
- + muxVal = 0xf3;
- +
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + muxVal = (twsiVal & muxVal);
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + mvOsPrintf("Board: twsi exp change to out fail\n");
- + return;
- + }
- + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
- + /* reset the line to 0 */
- + twsiSlave.offset = 3;
- + muxVal = 0;
- + muxValMask = 1;
- +
- + if(mvBoardIdGet() == RD_88F6281A_ID) {
- + muxVal = 0x0;
- + muxValMask = 0xf3;
- + }
- +
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + muxVal = (twsiVal & muxValMask) | muxVal;
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + mvOsPrintf("Board: twsi exp out val fail\n");
- + return;
- + }
- + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
- +
- + mvOsDelay(20);
- +
- + /* set the line to 1 */
- + twsiSlave.offset = 3;
- + muxVal = 1;
- + muxValMask = 1;
- +
- + if(mvBoardIdGet() == RD_88F6281A_ID)
- + {
- + muxVal = 0xc;
- + muxValMask = 0xf3;
- + if(chType) /* FXS - issue reset properly */
- + {
- + MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), MV_GPP12);
- + mvOsDelay(50);
- + MV_REG_BIT_RESET(GPP_DATA_OUT_REG(1), MV_GPP12);
- + }
- + else /* FXO - issue reset via TDM_CODEC_RST*/
- + {
- + /* change MPP44 type to TDM_CODEC_RST(0x2) */
- + MV_REG_WRITE(MPP_CONTROL_REG5, ((MV_REG_READ(MPP_CONTROL_REG5) & 0xFFF0FFFF) | BIT17));
- + }
- + }
- +
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + muxVal = (twsiVal & muxValMask) | muxVal;
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + mvOsPrintf("Board: twsi exp out val fail\n");
- + return;
- + }
- +
- + /* TBD - 5 channels */
- +#if defined(MV_TDM_5CHANNELS)
- + /* change MPP38 type to GPIO(0x0) & polarity for TDM_STROBE */
- + MV_REG_WRITE(MPP_CONTROL_REG4, (MV_REG_READ(MPP_CONTROL_REG4) & 0xF0FFFFFF));
- + mvGppPolaritySet(1, MV_GPP6, 0);
- +
- + twsiSlave.offset = 6;
- + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(2);
- +
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + muxVal = (twsiVal & ~BIT2);
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + mvOsPrintf("Board: twsi exp change to out fail\n");
- + return;
- + }
- +
- +
- + twsiSlave.offset = 2;
- +
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + muxVal = (twsiVal & ~BIT2);
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
- + {
- + mvOsPrintf("Board: twsi exp change to out fail\n");
- + return;
- + }
- +#endif
- + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
- +
- +
- +}
- +/*******************************************************************************
- +* mvBoardVoiceConnModeGet - return SLIC/DAA connection & interrupt modes
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +
- +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode)
- +{
- + switch(mvBoardIdGet())
- + {
- + case RD_88F6281A_ID:
- + *connMode = DAISY_CHAIN_MODE;
- + *irqMode = INTERRUPT_TO_TDM;
- + break;
- + case DB_88F6281A_BP_ID:
- + *connMode = DUAL_CHIP_SELECT_MODE;
- + *irqMode = INTERRUPT_TO_TDM;
- + break;
- + case RD_88F6192A_ID:
- + *connMode = DUAL_CHIP_SELECT_MODE;
- + *irqMode = INTERRUPT_TO_TDM;
- + break;
- + case DB_88F6192A_BP_ID:
- + *connMode = DUAL_CHIP_SELECT_MODE;
- + *irqMode = INTERRUPT_TO_TDM;
- + break;
- + default:
- + *connMode = *irqMode = -1;
- + mvOsPrintf("mvBoardVoiceAssembleModeGet: TDM not supported(boardId=0x%x)\n",mvBoardIdGet());
- + }
- + return;
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardMppModuleTypePrint - print module detect
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_VOID mvBoardMppModuleTypePrint(MV_VOID)
- +{
- +
- + MV_BOARD_MPP_GROUP_CLASS devClass;
- + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
- + MV_U32 devId;
- + MV_U32 maxMppGrp = 1;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + maxMppGrp = MV_6281_MPP_MAX_MODULE;
- + break;
- + case MV_6192_DEV_ID:
- + maxMppGrp = MV_6192_MPP_MAX_MODULE;
- + break;
- + case MV_6190_DEV_ID:
- + maxMppGrp = MV_6190_MPP_MAX_MODULE;
- + break;
- + case MV_6180_DEV_ID:
- + maxMppGrp = MV_6180_MPP_MAX_MODULE;
- + break;
- + }
- +
- + for (devClass = 0; devClass < maxMppGrp; devClass++)
- + {
- + mppGroupType = mvBoardMppGroupTypeGet(devClass);
- +
- + switch(mppGroupType)
- + {
- + case MV_BOARD_TDM:
- + if(devId != MV_6190_DEV_ID)
- + mvOsPrintf("Module %d is TDM\n", devClass);
- + break;
- + case MV_BOARD_AUDIO:
- + if(devId != MV_6190_DEV_ID)
- + mvOsPrintf("Module %d is AUDIO\n", devClass);
- + break;
- + case MV_BOARD_RGMII:
- + if(devId != MV_6190_DEV_ID)
- + mvOsPrintf("Module %d is RGMII\n", devClass);
- + break;
- + case MV_BOARD_GMII:
- + if(devId != MV_6190_DEV_ID)
- + mvOsPrintf("Module %d is GMII\n", devClass);
- + break;
- + case MV_BOARD_TS:
- + if(devId != MV_6190_DEV_ID)
- + mvOsPrintf("Module %d is TS\n", devClass);
- + break;
- + default:
- + break;
- + }
- + }
- +}
- +
- +/* Board devices API managments */
- +
- +/*******************************************************************************
- +* mvBoardGetDeviceNumber - Get number of device of some type on the board
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* devType - The device type ( Flash,RTC , etc .. )
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* If the device is found on the board the then the functions returns the
- +* number of those devices else the function returns 0
- +*
- +*
- +*******************************************************************************/
- +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass)
- +{
- + MV_U32 foundIndex=0,devNum;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("mvBoardGetDeviceNumber:Board unknown.\n");
- + return 0xFFFFFFFF;
- +
- + }
- +
- + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
- + {
- + if (BOARD_INFO(boardId)->pDevCsInfo[devNum].devClass == devClass)
- + {
- + foundIndex++;
- + }
- + }
- +
- + return foundIndex;
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* devIndex - The device sequential number on the board
- +* devType - The device type ( Flash,RTC , etc .. )
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* If the device is found on the board the then the functions returns the
- +* Base address else the function returns 0xffffffff
- +*
- +*
- +*******************************************************************************/
- +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
- +{
- + MV_DEV_CS_INFO* devEntry;
- + devEntry = boardGetDevEntry(devNum,devClass);
- + if (devEntry != NULL)
- + {
- + return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS));
- +
- + }
- +
- + return 0xFFFFFFFF;
- +}
- +
- +/*******************************************************************************
- +* mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* devIndex - The device sequential number on the board
- +* devType - The device type ( Flash,RTC , etc .. )
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* If the device is found on the board the then the functions returns the
- +* Bus width else the function returns 0xffffffff
- +*
- +*
- +*******************************************************************************/
- +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
- +{
- + MV_DEV_CS_INFO* devEntry;
- +
- + devEntry = boardGetDevEntry(devNum,devClass);
- + if (devEntry != NULL)
- + {
- + return 8;
- + }
- +
- + return 0xFFFFFFFF;
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardGetDeviceWidth - Get dev width of a device existing on the board
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* devIndex - The device sequential number on the board
- +* devType - The device type ( Flash,RTC , etc .. )
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* If the device is found on the board the then the functions returns the
- +* dev width else the function returns 0xffffffff
- +*
- +*
- +*******************************************************************************/
- +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
- +{
- + MV_DEV_CS_INFO* devEntry;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("Board unknown.\n");
- + return 0xFFFFFFFF;
- + }
- +
- + devEntry = boardGetDevEntry(devNum,devClass);
- + if (devEntry != NULL)
- + return devEntry->devWidth;
- +
- + return MV_ERROR;
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardGetDeviceWinSize - Get the window size of a device existing on the board
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* devIndex - The device sequential number on the board
- +* devType - The device type ( Flash,RTC , etc .. )
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* If the device is found on the board the then the functions returns the
- +* window size else the function returns 0xffffffff
- +*
- +*
- +*******************************************************************************/
- +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
- +{
- + MV_DEV_CS_INFO* devEntry;
- + MV_U32 boardId = mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("Board unknown.\n");
- + return 0xFFFFFFFF;
- + }
- +
- + devEntry = boardGetDevEntry(devNum,devClass);
- + if (devEntry != NULL)
- + {
- + return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS));
- + }
- +
- + return 0xFFFFFFFF;
- +}
- +
- +
- +/*******************************************************************************
- +* boardGetDevEntry - returns the entry pointer of a device on the board
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* devIndex - The device sequential number on the board
- +* devType - The device type ( Flash,RTC , etc .. )
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* If the device is found on the board the then the functions returns the
- +* dev number else the function returns 0x0
- +*
- +*
- +*******************************************************************************/
- +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
- +{
- + MV_U32 foundIndex=0,devIndex;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("boardGetDevEntry: Board unknown.\n");
- + return NULL;
- +
- + }
- +
- + for (devIndex = START_DEV_CS; devIndex < BOARD_INFO(boardId)->numBoardDeviceIf; devIndex++)
- + {
- + /* TBR */
- + /*if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].deviceCS == MV_BOOTDEVICE_INDEX)
- + continue;*/
- +
- + if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].devClass == devClass)
- + {
- + if (foundIndex == devNum)
- + {
- + return &(BOARD_INFO(boardId)->pDevCsInfo[devIndex]);
- + }
- + foundIndex++;
- + }
- + }
- +
- + /* device not found */
- + return NULL;
- +}
- +
- +/* Get device CS number */
- +
- +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
- +{
- + MV_DEV_CS_INFO* devEntry;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
- + {
- + mvOsPrintf("Board unknown.\n");
- + return 0xFFFFFFFF;
- +
- + }
- +
- +
- + devEntry = boardGetDevEntry(devNum,devClass);
- + if (devEntry != NULL)
- + return devEntry->deviceCS;
- +
- + return 0xFFFFFFFF;
- +
- +}
- +
- +/*******************************************************************************
- +* mvBoardRtcTwsiAddrTypeGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardRtcTwsiAddrTypeGet()
- +{
- + int i;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
- + return (MV_ERROR);
- +}
- +
- +/*******************************************************************************
- +* mvBoardRtcTwsiAddrGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardRtcTwsiAddrGet()
- +{
- + int i;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
- + return (0xFF);
- +}
- +
- +/*******************************************************************************
- +* mvBoardA2DTwsiAddrTypeGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardA2DTwsiAddrTypeGet()
- +{
- + int i;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
- + return (MV_ERROR);
- +}
- +
- +/*******************************************************************************
- +* mvBoardA2DTwsiAddrGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardA2DTwsiAddrGet()
- +{
- + int i;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
- + return (0xFF);
- +}
- +
- +/*******************************************************************************
- +* mvBoardTwsiExpAddrTypeGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index)
- +{
- + int i;
- + MV_U32 indexFound = 0;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
- + {
- + if (indexFound == index)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
- + else
- + indexFound++;
- + }
- +
- + return (MV_ERROR);
- +}
- +
- +/*******************************************************************************
- +* mvBoardTwsiExpAddrGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index)
- +{
- + int i;
- + MV_U32 indexFound = 0;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
- + {
- + if (indexFound == index)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
- + else
- + indexFound++;
- + }
- +
- + return (0xFF);
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoardTwsiSatRAddrTypeGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index)
- +{
- + int i;
- + MV_U32 indexFound = 0;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
- + {
- + if (indexFound == index)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
- + else
- + indexFound++;
- + }
- +
- + return (MV_ERROR);
- +}
- +
- +/*******************************************************************************
- +* mvBoardTwsiSatRAddrGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index)
- +{
- + int i;
- + MV_U32 indexFound = 0;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
- + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
- + {
- + if (indexFound == index)
- + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
- + else
- + indexFound++;
- + }
- +
- + return (0xFF);
- +}
- +
- +/*******************************************************************************
- +* mvBoardNandWidthGet -
- +*
- +* DESCRIPTION: Get the width of the first NAND device in byte.
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN: 1, 2, 4 or MV_ERROR
- +*
- +*
- +*******************************************************************************/
- +/* */
- +MV_32 mvBoardNandWidthGet(void)
- +{
- + MV_U32 devNum;
- + MV_U32 devWidth;
- + MV_U32 boardId= mvBoardIdGet();
- +
- + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
- + {
- + devWidth = mvBoardGetDeviceWidth(devNum, BOARD_DEV_NAND_FLASH);
- + if (devWidth != MV_ERROR)
- + return (devWidth / 8);
- + }
- +
- + /* NAND wasn't found */
- + return MV_ERROR;
- +}
- +
- +MV_U32 gBoardId = -1;
- +
- +/*******************************************************************************
- +* mvBoardIdGet - Get Board model
- +*
- +* DESCRIPTION:
- +* This function returns board ID.
- +* Board ID is 32bit word constructed of board model (16bit) and
- +* board revision (16bit) in the following way: 0xMMMMRRRR.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit board ID number, '-1' if board is undefined.
- +*
- +*******************************************************************************/
- +MV_U32 mvBoardIdGet(MV_VOID)
- +{
- + MV_U32 tmpBoardId = -1;
- +
- + if(gBoardId == -1)
- + {
- + #if defined(DB_88F6281A)
- + tmpBoardId = DB_88F6281A_BP_ID;
- + #elif defined(RD_88F6281A)
- + tmpBoardId = RD_88F6281A_ID;
- + #elif defined(DB_88F6192A)
- + tmpBoardId = DB_88F6192A_BP_ID;
- + #elif defined(DB_88F6190A)
- + tmpBoardId = DB_88F6190A_BP_ID;
- + #elif defined(RD_88F6192A)
- + tmpBoardId = RD_88F6192A_ID;
- + #elif defined(RD_88F6190A)
- + tmpBoardId = RD_88F6190A_ID;
- + #elif defined(DB_88F6180A)
- + tmpBoardId = DB_88F6180A_BP_ID;
- + #elif defined(RD_88F6281A_PCAC)
- + tmpBoardId = RD_88F6281A_PCAC_ID;
- + #elif defined(RD_88F6281A_SHEEVA_PLUG)
- + tmpBoardId = SHEEVA_PLUG_ID;
- + #elif defined(DB_CUSTOMER)
- + tmpBoardId = DB_CUSTOMER_ID;
- + #endif
- + gBoardId = tmpBoardId;
- + }
- +
- + return gBoardId;
- +}
- +
- +
- +/*******************************************************************************
- +* mvBoarModuleTypeGet - mvBoarModuleTypeGet
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* group num - MV_BOARD_MPP_GROUP_CLASS enum
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* module num - MV_BOARD_MODULE_CLASS enum
- +*
- +*******************************************************************************/
- +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass)
- +{
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- + MV_U8 data;
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + DB(mvOsPrintf("Board: Read MPP module ID\n"));
- + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
- + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(devClass);
- + twsiSlave.validOffset = MV_TRUE;
- + /* Offset is the first command after the address which indicate the register number to be read
- + in next operation */
- + twsiSlave.offset = 0;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- +
- +
- + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
- + {
- + DB(mvOsPrintf("Board: Read MPP module ID fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: Read MPP module ID succeded\n"));
- +
- + return data;
- +}
- +
- +/*******************************************************************************
- +* mvBoarTwsiSatRGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* device num - one of three devices
- +* reg num - 0 or 1
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* reg value
- +*
- +*******************************************************************************/
- +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum)
- +{
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- + MV_U8 data;
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + DB(mvOsPrintf("Board: Read S@R device read\n"));
- + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
- + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
- + twsiSlave.validOffset = MV_TRUE;
- + /* Use offset as command */
- + twsiSlave.offset = regNum;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
- + {
- + DB(mvOsPrintf("Board: Read S@R fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: Read S@R succeded\n"));
- +
- + return data;
- +}
- +
- +/*******************************************************************************
- +* mvBoarTwsiSatRSet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* devNum - one of three devices
- +* regNum - 0 or 1
- +* regVal - value
- +*
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* reg value
- +*
- +*******************************************************************************/
- +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal)
- +{
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
- + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
- + twsiSlave.validOffset = MV_TRUE;
- + DB(mvOsPrintf("Board: Write S@R device addr %x, type %x, data %x\n", twsiSlave.slaveAddr.address,\
- + twsiSlave.slaveAddr.type, regVal));
- + /* Use offset as command */
- + twsiSlave.offset = regNum;
- + twsiSlave.moreThen256 = MV_FALSE;
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, ®Val, 1) )
- + {
- + DB(mvOsPrintf("Board: Write S@R fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: Write S@R succeded\n"));
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvBoardSlicGpioPinGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*
- +*******************************************************************************/
- +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum)
- +{
- + MV_U32 boardId;
- + boardId = mvBoardIdGet();
- +
- + switch (boardId)
- + {
- + case DB_88F6281A_BP_ID:
- + case RD_88F6281A_ID:
- + default:
- + return MV_ERROR;
- + break;
- +
- + }
- +}
- +
- +/*******************************************************************************
- +* mvBoardFanPowerControl - Turn on/off the fan power control on the RD-6281A
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* mode - MV_TRUE = on ; MV_FALSE = off
- +*
- +* OUTPUT:
- +* MV_STATUS - MV_OK , MV_ERROR.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode)
- +{
- +
- + MV_U8 val = 1, twsiVal;
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- +
- + if(mvBoardIdGet() != RD_88F6281A_ID)
- + return MV_ERROR;
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + DB(mvOsPrintf("Board: twsi exp set\n"));
- + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + /* Offset is the first command after the address which indicate the register number to be read
- + in next operation */
- + twsiSlave.offset = 3;
- + twsiSlave.moreThen256 = MV_FALSE;
- + if(mode == MV_TRUE)
- + val = 0x1;
- + else
- + val = 0;
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + val = (twsiVal & 0xfe) | val;
- +
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
- +
- + /* Change twsi exp to output */
- + twsiSlave.offset = 7;
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + val = (twsiVal & 0xfe);
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvBoardHDDPowerControl - Turn on/off the HDD power control on the RD-6281A
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* mode - MV_TRUE = on ; MV_FALSE = off
- +*
- +* OUTPUT:
- +* MV_STATUS - MV_OK , MV_ERROR.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode)
- +{
- +
- + MV_U8 val = 1, twsiVal;
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- +
- + if(mvBoardIdGet() != RD_88F6281A_ID)
- + return MV_ERROR;
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + DB(mvOsPrintf("Board: twsi exp set\n"));
- + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + /* Offset is the first command after the address which indicate the register number to be read
- + in next operation */
- + twsiSlave.offset = 3;
- + twsiSlave.moreThen256 = MV_FALSE;
- + if(mode == MV_TRUE)
- + val = 0x2;
- + else
- + val = 0;
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + val = (twsiVal & 0xfd) | val;
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
- +
- + /* Change twsi exp to output */
- + twsiSlave.offset = 7;
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + val = (twsiVal & 0xfd);
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvBoardSDioWPControl - Turn on/off the SDIO WP on the RD-6281A
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* mode - MV_TRUE = on ; MV_FALSE = off
- +*
- +* OUTPUT:
- +* MV_STATUS - MV_OK , MV_ERROR.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode)
- +{
- +
- + MV_U8 val = 1, twsiVal;
- + MV_TWSI_SLAVE twsiSlave;
- + MV_TWSI_ADDR slave;
- +
- + if(mvBoardIdGet() != RD_88F6281A_ID)
- + return MV_ERROR;
- +
- + /* TWSI init */
- + slave.type = ADDR7_BIT;
- + slave.address = 0;
- + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
- +
- + /* Read MPP module ID */
- + DB(mvOsPrintf("Board: twsi exp set\n"));
- + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(0);
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + /* Offset is the first command after the address which indicate the register number to be read
- + in next operation */
- + twsiSlave.offset = 3;
- + twsiSlave.moreThen256 = MV_FALSE;
- + if(mode == MV_TRUE)
- + val = 0x10;
- + else
- + val = 0;
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + val = (twsiVal & 0xef) | val;
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
- +
- + /* Change twsi exp to output */
- + twsiSlave.offset = 7;
- + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
- + val = (twsiVal & 0xef);
- + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
- + {
- + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
- + return MV_OK;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 2010-11-09 20:28:07.362495449 +0100
- @@ -0,0 +1,376 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#ifndef __INCmvBoardEnvLibh
- +#define __INCmvBoardEnvLibh
- +
- +/* defines */
- +/* The below constant macros defines the board I2C EEPROM data offsets */
- +
- +
- +
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "mvSysHwConfig.h"
- +#include "boardEnv/mvBoardEnvSpec.h"
- +
- +
- +/* DUART stuff for Tclk detection only */
- +#define DUART_BAUD_RATE 115200
- +#define MAX_CLOCK_MARGINE 5000000 /* Maximum detected clock margine */
- +
- +/* Voice devices assembly modes */
- +#define DAISY_CHAIN_MODE 1
- +#define DUAL_CHIP_SELECT_MODE 0
- +#define INTERRUPT_TO_MPP 1
- +#define INTERRUPT_TO_TDM 0
- +
- +
- +#define BOARD_ETH_PORT_NUM MV_ETH_MAX_PORTS
- +#define BOARD_ETH_SWITCH_PORT_NUM 5
- +
- +#define MV_BOARD_MAX_USB_IF 1
- +#define MV_BOARD_MAX_MPP 7
- +#define MV_BOARD_NAME_LEN 0x20
- +
- +typedef struct _boardData
- +{
- + MV_U32 magic;
- + MV_U16 boardId;
- + MV_U8 boardVer;
- + MV_U8 boardRev;
- + MV_U32 reserved1;
- + MV_U32 reserved2;
- +
- +}BOARD_DATA;
- +
- +typedef enum _devBoardMppGroupClass
- +{
- + MV_BOARD_MPP_GROUP_1,
- + MV_BOARD_MPP_GROUP_2,
- + MV_BOARD_MAX_MPP_GROUP
- +}MV_BOARD_MPP_GROUP_CLASS;
- +
- +typedef enum _devBoardMppTypeClass
- +{
- + MV_BOARD_AUTO,
- + MV_BOARD_TDM,
- + MV_BOARD_AUDIO,
- + MV_BOARD_RGMII,
- + MV_BOARD_GMII,
- + MV_BOARD_TS,
- + MV_BOARD_MII,
- + MV_BOARD_OTHER
- +}MV_BOARD_MPP_TYPE_CLASS;
- +
- +typedef enum _devBoardModuleIdClass
- +{
- + MV_BOARD_MODULE_TDM_ID = 1,
- + MV_BOARD_MODULE_AUDIO_ID,
- + MV_BOARD_MODULE_RGMII_ID,
- + MV_BOARD_MODULE_GMII_ID,
- + MV_BOARD_MODULE_TS_ID,
- + MV_BOARD_MODULE_MII_ID,
- + MV_BOARD_MODULE_TDM_5CHAN_ID,
- + MV_BOARD_MODULE_OTHER_ID
- +}MV_BOARD_MODULE_ID_CLASS;
- +
- +typedef struct _boardMppTypeInfo
- +{
- + MV_BOARD_MPP_TYPE_CLASS boardMppGroup1;
- + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2;
- +
- +}MV_BOARD_MPP_TYPE_INFO;
- +
- +
- +typedef enum _devBoardClass
- +{
- + BOARD_DEV_NOR_FLASH,
- + BOARD_DEV_NAND_FLASH,
- + BOARD_DEV_SEVEN_SEG,
- + BOARD_DEV_FPGA,
- + BOARD_DEV_SRAM,
- + BOARD_DEV_SPI_FLASH,
- + BOARD_DEV_OTHER,
- +}MV_BOARD_DEV_CLASS;
- +
- +typedef enum _devTwsiBoardClass
- +{
- + BOARD_TWSI_RTC,
- + BOARD_DEV_TWSI_EXP,
- + BOARD_DEV_TWSI_SATR,
- + BOARD_TWSI_AUDIO_DEC,
- + BOARD_TWSI_OTHER
- +}MV_BOARD_TWSI_CLASS;
- +
- +typedef enum _devGppBoardClass
- +{
- + BOARD_GPP_RTC,
- + BOARD_GPP_MV_SWITCH,
- + BOARD_GPP_USB_VBUS,
- + BOARD_GPP_USB_VBUS_EN,
- + BOARD_GPP_USB_OC,
- + BOARD_GPP_USB_HOST_DEVICE,
- + BOARD_GPP_REF_CLCK,
- + BOARD_GPP_VOIP_SLIC,
- + BOARD_GPP_LIFELINE,
- + BOARD_GPP_BUTTON,
- + BOARD_GPP_TS_BUTTON_C,
- + BOARD_GPP_TS_BUTTON_U,
- + BOARD_GPP_TS_BUTTON_D,
- + BOARD_GPP_TS_BUTTON_L,
- + BOARD_GPP_TS_BUTTON_R,
- + BOARD_GPP_POWER_BUTTON,
- + BOARD_GPP_RESTOR_BUTTON,
- + BOARD_GPP_WPS_BUTTON,
- + BOARD_GPP_HDD0_POWER,
- + BOARD_GPP_HDD1_POWER,
- + BOARD_GPP_FAN_POWER,
- + BOARD_GPP_RESET,
- + BOARD_GPP_POWER_ON_LED,
- + BOARD_GPP_HDD_POWER,
- + BOARD_GPP_SDIO_POWER,
- + BOARD_GPP_SDIO_DETECT,
- + BOARD_GPP_SDIO_WP,
- + BOARD_GPP_SWITCH_PHY_INT,
- + BOARD_GPP_TSU_DIRCTION,
- + BOARD_GPP_OTHER
- +}MV_BOARD_GPP_CLASS;
- +
- +
- +typedef struct _devCsInfo
- +{
- + MV_U8 deviceCS;
- + MV_U32 params;
- + MV_U32 devClass; /* MV_BOARD_DEV_CLASS */
- + MV_U8 devWidth;
- +
- +}MV_DEV_CS_INFO;
- +
- +
- +#define MV_BOARD_PHY_FORCE_10MB 0x0
- +#define MV_BOARD_PHY_FORCE_100MB 0x1
- +#define MV_BOARD_PHY_FORCE_1000MB 0x2
- +#define MV_BOARD_PHY_SPEED_AUTO 0x3
- +
- +typedef struct _boardSwitchInfo
- +{
- + MV_32 linkStatusIrq;
- + MV_32 qdPort[BOARD_ETH_SWITCH_PORT_NUM];
- + MV_32 qdCpuPort;
- + MV_32 smiScanMode; /* 1 for SMI_MANUAL_MODE, 0 otherwise */
- + MV_32 switchOnPort;
- +
- +}MV_BOARD_SWITCH_INFO;
- +
- +typedef struct _boardLedInfo
- +{
- + MV_U8 activeLedsNumber;
- + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
- + MV_U8* gppPinNum; /* Pointer to GPP values */
- +
- +}MV_BOARD_LED_INFO;
- +
- +typedef struct _boardGppInfo
- +{
- + MV_BOARD_GPP_CLASS devClass;
- + MV_U8 gppPinNum;
- +
- +}MV_BOARD_GPP_INFO;
- +
- +
- +typedef struct _boardTwsiInfo
- +{
- + MV_BOARD_TWSI_CLASS devClass;
- + MV_U8 twsiDevAddr;
- + MV_U8 twsiDevAddrType;
- +
- +}MV_BOARD_TWSI_INFO;
- +
- +
- +typedef enum _boardMacSpeed
- +{
- + BOARD_MAC_SPEED_10M,
- + BOARD_MAC_SPEED_100M,
- + BOARD_MAC_SPEED_1000M,
- + BOARD_MAC_SPEED_AUTO,
- +
- +}MV_BOARD_MAC_SPEED;
- +
- +typedef struct _boardMacInfo
- +{
- + MV_BOARD_MAC_SPEED boardMacSpeed;
- + MV_U8 boardEthSmiAddr;
- +
- +}MV_BOARD_MAC_INFO;
- +
- +typedef struct _boardMppInfo
- +{
- + MV_U32 mppGroup[MV_BOARD_MAX_MPP];
- +
- +}MV_BOARD_MPP_INFO;
- +
- +typedef struct _boardInfo
- +{
- + char boardName[MV_BOARD_NAME_LEN];
- + MV_U8 numBoardMppTypeValue;
- + MV_BOARD_MPP_TYPE_INFO* pBoardMppTypeValue;
- + MV_U8 numBoardMppConfigValue;
- + MV_BOARD_MPP_INFO* pBoardMppConfigValue;
- + MV_U32 intsGppMaskLow;
- + MV_U32 intsGppMaskHigh;
- + MV_U8 numBoardDeviceIf;
- + MV_DEV_CS_INFO* pDevCsInfo;
- + MV_U8 numBoardTwsiDev;
- + MV_BOARD_TWSI_INFO* pBoardTwsiDev;
- + MV_U8 numBoardMacInfo;
- + MV_BOARD_MAC_INFO* pBoardMacInfo;
- + MV_U8 numBoardGppInfo;
- + MV_BOARD_GPP_INFO* pBoardGppInfo;
- + MV_U8 activeLedsNumber;
- + MV_U8* pLedGppPin;
- + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
- + /* GPP values */
- + MV_U32 gppOutEnValLow;
- + MV_U32 gppOutEnValHigh;
- + MV_U32 gppOutValLow;
- + MV_U32 gppOutValHigh;
- + MV_U32 gppPolarityValLow;
- + MV_U32 gppPolarityValHigh;
- +
- + /* Switch Configuration */
- + MV_BOARD_SWITCH_INFO* pSwitchInfo;
- +}MV_BOARD_INFO;
- +
- +
- +
- +MV_VOID mvBoardEnvInit(MV_VOID);
- +MV_U32 mvBoardIdGet(MV_VOID);
- +MV_U16 mvBoardModelGet(MV_VOID);
- +MV_U16 mvBoardRevGet(MV_VOID);
- +MV_STATUS mvBoardNameGet(char *pNameBuff);
- +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum);
- +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum);
- +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum);
- +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum);
- +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum);
- +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum);
- +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum);
- +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum);
- +MV_BOOL mvBoardIsPortInGmii(MV_VOID);
- +MV_U32 mvBoardTclkGet(MV_VOID);
- +MV_U32 mvBoardSysClkGet(MV_VOID);
- +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId);
- +MV_VOID mvBoardDebugLed(MV_U32 hexNum);
- +MV_32 mvBoardMppGet(MV_U32 mppGroupNum);
- +
- +MV_U8 mvBoardRtcTwsiAddrTypeGet(MV_VOID);
- +MV_U8 mvBoardRtcTwsiAddrGet(MV_VOID);
- +
- +MV_U8 mvBoardA2DTwsiAddrTypeGet(MV_VOID);
- +MV_U8 mvBoardA2DTwsiAddrGet(MV_VOID);
- +
- +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index);
- +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index);
- +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index);
- +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index);
- +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass);
- +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass);
- +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
- + MV_BOARD_MPP_TYPE_CLASS mppGroupType);
- +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID);
- +MV_VOID mvBoardMppMuxSet(MV_VOID);
- +MV_VOID mvBoardTdmMppSet(MV_32 chType);
- +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode);
- +
- +MV_VOID mvBoardMppModuleTypePrint(MV_VOID);
- +MV_VOID mvBoardReset(MV_VOID);
- +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum);
- +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal);
- +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data);
- +/* Board devices API managments */
- +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass);
- +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
- +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
- +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
- +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
- +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
- +
- +/* Gpio Pin Connections API */
- +MV_32 mvBoardUSBVbusGpioPinGet(int devId);
- +MV_32 mvBoardUSBVbusEnGpioPinGet(int devId);
- +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin);
- +
- +MV_32 mvBoardResetGpioPinGet(MV_VOID);
- +MV_32 mvBoardRTCGpioPinGet(MV_VOID);
- +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID);
- +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID);
- +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum);
- +
- +MV_32 mvBoardSDIOGpioPinGet(MV_VOID);
- +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode);
- +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index);
- +
- +MV_32 mvBoardNandWidthGet(void);
- +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode);
- +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode);
- +#endif /* __INCmvBoardEnvLibh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 2010-11-09 20:28:07.443751783 +0100
- @@ -0,0 +1,848 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#include "mvCommon.h"
- +#include "mvBoardEnvLib.h"
- +#include "mvBoardEnvSpec.h"
- +#include "twsi/mvTwsi.h"
- +
- +#define DB_88F6281A_BOARD_PCI_IF_NUM 0x0
- +#define DB_88F6281A_BOARD_TWSI_DEF_NUM 0x7
- +#define DB_88F6281A_BOARD_MAC_INFO_NUM 0x2
- +#define DB_88F6281A_BOARD_GPP_INFO_NUM 0x3
- +#define DB_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
- +#define DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
- +#else
- + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#endif
- +#define DB_88F6281A_BOARD_DEBUG_LED_NUM 0x0
- +
- +
- +MV_BOARD_TWSI_INFO db88f6281AInfoBoardTwsiDev[] =
- + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
- + {
- + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
- + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
- + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
- + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
- + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
- + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
- + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
- + };
- +
- +MV_BOARD_MAC_INFO db88f6281AInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {
- + {BOARD_MAC_SPEED_AUTO, 0x8},
- + {BOARD_MAC_SPEED_AUTO, 0x9}
- + };
- +
- +MV_BOARD_MPP_TYPE_INFO db88f6281AInfoBoardMppTypeInfo[] =
- + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
- + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
- + {{MV_BOARD_AUTO, MV_BOARD_AUTO}
- + };
- +
- +MV_BOARD_GPP_INFO db88f6281AInfoBoardGppInfo[] =
- + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
- + {
- + {BOARD_GPP_TSU_DIRCTION, 33}
- + /*muxed with TDM/Audio module via IOexpender
- + {BOARD_GPP_SDIO_DETECT, 38},
- + {BOARD_GPP_USB_VBUS, 49}*/
- + };
- +
- +MV_DEV_CS_INFO db88f6281AInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + {
- + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
- + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
- + };
- +#else
- + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
- +#endif
- +
- +MV_BOARD_MPP_INFO db88f6281AInfoBoardMppConfigValue[] =
- + {{{
- + DB_88F6281A_MPP0_7,
- + DB_88F6281A_MPP8_15,
- + DB_88F6281A_MPP16_23,
- + DB_88F6281A_MPP24_31,
- + DB_88F6281A_MPP32_39,
- + DB_88F6281A_MPP40_47,
- + DB_88F6281A_MPP48_55
- + }}};
- +
- +
- +MV_BOARD_INFO db88f6281AInfo = {
- + "DB-88F6281A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
- + DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + db88f6281AInfoBoardMppTypeInfo,
- + DB_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + db88f6281AInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + 0, /* intsGppMaskHigh */
- + DB_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + db88f6281AInfoBoardDeCsInfo,
- + DB_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + db88f6281AInfoBoardTwsiDev,
- + DB_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + db88f6281AInfoBoardMacInfo,
- + DB_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + db88f6281AInfoBoardGppInfo,
- + DB_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + NULL,
- + 0, /* ledsPolarity */
- + DB_88F6281A_OE_LOW, /* gppOutEnLow */
- + DB_88F6281A_OE_HIGH, /* gppOutEnHigh */
- + DB_88F6281A_OE_VAL_LOW, /* gppOutValLow */
- + DB_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + BIT6, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +
- +#define RD_88F6281A_BOARD_PCI_IF_NUM 0x0
- +#define RD_88F6281A_BOARD_TWSI_DEF_NUM 0x2
- +#define RD_88F6281A_BOARD_MAC_INFO_NUM 0x2
- +#define RD_88F6281A_BOARD_GPP_INFO_NUM 0x5
- +#define RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
- +#define RD_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
- +#else
- + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#endif
- +#define RD_88F6281A_BOARD_DEBUG_LED_NUM 0x0
- +
- +MV_BOARD_MAC_INFO rd88f6281AInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {{BOARD_MAC_SPEED_1000M, 0xa},
- + {BOARD_MAC_SPEED_AUTO, 0xb}
- + };
- +
- +MV_BOARD_SWITCH_INFO rd88f6281AInfoBoardSwitchInfo[] =
- + /* MV_32 linkStatusIrq, {MV_32 qdPort0, MV_32 qdPort1, MV_32 qdPort2, MV_32 qdPort3, MV_32 qdPort4},
- + MV_32 qdCpuPort, MV_32 smiScanMode, MV_32 switchOnPort} */
- + {{38, {0, 1, 2, 3, -1}, 5, 2, 0},
- + {-1, {-1}, -1, -1, -1}};
- +
- +MV_BOARD_TWSI_INFO rd88f6281AInfoBoardTwsiDev[] =
- + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
- + {
- + {BOARD_DEV_TWSI_EXP, 0xFF, ADDR7_BIT}, /* dummy entry to align with modules indexes */
- + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT}
- + };
- +
- +MV_BOARD_MPP_TYPE_INFO rd88f6281AInfoBoardMppTypeInfo[] =
- + {{MV_BOARD_RGMII, MV_BOARD_TDM}
- + };
- +
- +MV_DEV_CS_INFO rd88f6281AInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + {
- + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
- + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
- + };
- +#else
- + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
- +#endif
- +
- +MV_BOARD_GPP_INFO rd88f6281AInfoBoardGppInfo[] =
- + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
- + {{BOARD_GPP_SDIO_DETECT, 28},
- + {BOARD_GPP_USB_OC, 29},
- + {BOARD_GPP_WPS_BUTTON, 35},
- + {BOARD_GPP_MV_SWITCH, 38},
- + {BOARD_GPP_USB_VBUS, 49}
- + };
- +
- +MV_BOARD_MPP_INFO rd88f6281AInfoBoardMppConfigValue[] =
- + {{{
- + RD_88F6281A_MPP0_7,
- + RD_88F6281A_MPP8_15,
- + RD_88F6281A_MPP16_23,
- + RD_88F6281A_MPP24_31,
- + RD_88F6281A_MPP32_39,
- + RD_88F6281A_MPP40_47,
- + RD_88F6281A_MPP48_55
- + }}};
- +
- +MV_BOARD_INFO rd88f6281AInfo = {
- + "RD-88F6281A", /* boardName[MAX_BOARD_NAME_LEN] */
- + RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + rd88f6281AInfoBoardMppTypeInfo,
- + RD_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + rd88f6281AInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + (1 << 3), /* intsGppMaskHigh */
- + RD_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + rd88f6281AInfoBoardDeCsInfo,
- + RD_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + rd88f6281AInfoBoardTwsiDev,
- + RD_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + rd88f6281AInfoBoardMacInfo,
- + RD_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + rd88f6281AInfoBoardGppInfo,
- + RD_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + NULL,
- + 0, /* ledsPolarity */
- + RD_88F6281A_OE_LOW, /* gppOutEnLow */
- + RD_88F6281A_OE_HIGH, /* gppOutEnHigh */
- + RD_88F6281A_OE_VAL_LOW, /* gppOutValLow */
- + RD_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + BIT6, /* gppPolarityValHigh */
- + rd88f6281AInfoBoardSwitchInfo /* pSwitchInfo */
- +};
- +
- +
- +#define DB_88F6192A_BOARD_PCI_IF_NUM 0x0
- +#define DB_88F6192A_BOARD_TWSI_DEF_NUM 0x7
- +#define DB_88F6192A_BOARD_MAC_INFO_NUM 0x2
- +#define DB_88F6192A_BOARD_GPP_INFO_NUM 0x3
- +#define DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
- +#define DB_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x2
- +#else
- + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#endif
- +#define DB_88F6192A_BOARD_DEBUG_LED_NUM 0x0
- +
- +MV_BOARD_TWSI_INFO db88f6192AInfoBoardTwsiDev[] =
- + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
- + {
- + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
- + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
- + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
- + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
- + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
- + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
- + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
- + };
- +
- +MV_BOARD_MAC_INFO db88f6192AInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {
- + {BOARD_MAC_SPEED_AUTO, 0x8},
- + {BOARD_MAC_SPEED_AUTO, 0x9}
- + };
- +
- +MV_BOARD_MPP_TYPE_INFO db88f6192AInfoBoardMppTypeInfo[] =
- + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
- + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
- + {{MV_BOARD_AUTO, MV_BOARD_OTHER}
- + };
- +
- +MV_DEV_CS_INFO db88f6192AInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + {
- + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
- + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
- + };
- +#else
- + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
- +#endif
- +
- +MV_BOARD_GPP_INFO db88f6192AInfoBoardGppInfo[] =
- + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
- + {
- + {BOARD_GPP_SDIO_WP, 20},
- + {BOARD_GPP_USB_VBUS, 22},
- + {BOARD_GPP_SDIO_DETECT, 23},
- + };
- +
- +MV_BOARD_MPP_INFO db88f6192AInfoBoardMppConfigValue[] =
- + {{{
- + DB_88F6192A_MPP0_7,
- + DB_88F6192A_MPP8_15,
- + DB_88F6192A_MPP16_23,
- + DB_88F6192A_MPP24_31,
- + DB_88F6192A_MPP32_35
- + }}};
- +
- +MV_BOARD_INFO db88f6192AInfo = {
- + "DB-88F6192A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
- + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + db88f6192AInfoBoardMppTypeInfo,
- + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + db88f6192AInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + (1 << 3), /* intsGppMaskHigh */
- + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + db88f6192AInfoBoardDeCsInfo,
- + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + db88f6192AInfoBoardTwsiDev,
- + DB_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + db88f6192AInfoBoardMacInfo,
- + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + db88f6192AInfoBoardGppInfo,
- + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + NULL,
- + 0, /* ledsPolarity */
- + DB_88F6192A_OE_LOW, /* gppOutEnLow */
- + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
- + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
- + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +#define DB_88F6190A_BOARD_MAC_INFO_NUM 0x1
- +
- +MV_BOARD_INFO db88f6190AInfo = {
- + "DB-88F6190A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
- + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + db88f6192AInfoBoardMppTypeInfo,
- + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + db88f6192AInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + (1 << 3), /* intsGppMaskHigh */
- + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + db88f6192AInfoBoardDeCsInfo,
- + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + db88f6192AInfoBoardTwsiDev,
- + DB_88F6190A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + db88f6192AInfoBoardMacInfo,
- + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + db88f6192AInfoBoardGppInfo,
- + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + NULL,
- + 0, /* ledsPolarity */
- + DB_88F6192A_OE_LOW, /* gppOutEnLow */
- + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
- + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
- + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +#define RD_88F6192A_BOARD_PCI_IF_NUM 0x0
- +#define RD_88F6192A_BOARD_TWSI_DEF_NUM 0x0
- +#define RD_88F6192A_BOARD_MAC_INFO_NUM 0x1
- +#define RD_88F6192A_BOARD_GPP_INFO_NUM 0xE
- +#define RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
- +#define RD_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
- +#define RD_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#define RD_88F6192A_BOARD_DEBUG_LED_NUM 0x3
- +
- +MV_U8 rd88f6192AInfoBoardDebugLedIf[] =
- + {17, 28, 29};
- +
- +MV_BOARD_MAC_INFO rd88f6192AInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {{BOARD_MAC_SPEED_AUTO, 0x8}
- + };
- +
- +MV_BOARD_MPP_TYPE_INFO rd88f6192AInfoBoardMppTypeInfo[] =
- + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
- + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
- + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
- + };
- +
- +MV_DEV_CS_INFO rd88f6192AInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
- +
- +MV_BOARD_GPP_INFO rd88f6192AInfoBoardGppInfo[] =
- + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
- + {
- + {BOARD_GPP_USB_VBUS_EN, 10},
- + {BOARD_GPP_USB_HOST_DEVICE, 11},
- + {BOARD_GPP_RESET, 14},
- + {BOARD_GPP_POWER_ON_LED, 15},
- + {BOARD_GPP_HDD_POWER, 16},
- + {BOARD_GPP_WPS_BUTTON, 24},
- + {BOARD_GPP_TS_BUTTON_C, 25},
- + {BOARD_GPP_USB_VBUS, 26},
- + {BOARD_GPP_USB_OC, 27},
- + {BOARD_GPP_TS_BUTTON_U, 30},
- + {BOARD_GPP_TS_BUTTON_R, 31},
- + {BOARD_GPP_TS_BUTTON_L, 32},
- + {BOARD_GPP_TS_BUTTON_D, 34},
- + {BOARD_GPP_FAN_POWER, 35}
- + };
- +
- +MV_BOARD_MPP_INFO rd88f6192AInfoBoardMppConfigValue[] =
- + {{{
- + RD_88F6192A_MPP0_7,
- + RD_88F6192A_MPP8_15,
- + RD_88F6192A_MPP16_23,
- + RD_88F6192A_MPP24_31,
- + RD_88F6192A_MPP32_35
- + }}};
- +
- +MV_BOARD_INFO rd88f6192AInfo = {
- + "RD-88F6192A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
- + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + rd88f6192AInfoBoardMppTypeInfo,
- + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + rd88f6192AInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + (1 << 3), /* intsGppMaskHigh */
- + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + rd88f6192AInfoBoardDeCsInfo,
- + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + NULL,
- + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + rd88f6192AInfoBoardMacInfo,
- + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + rd88f6192AInfoBoardGppInfo,
- + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + rd88f6192AInfoBoardDebugLedIf,
- + 0, /* ledsPolarity */
- + RD_88F6192A_OE_LOW, /* gppOutEnLow */
- + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
- + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
- + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +MV_BOARD_INFO rd88f6190AInfo = {
- + "RD-88F6190A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
- + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + rd88f6192AInfoBoardMppTypeInfo,
- + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + rd88f6192AInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + (1 << 3), /* intsGppMaskHigh */
- + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + rd88f6192AInfoBoardDeCsInfo,
- + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + NULL,
- + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + rd88f6192AInfoBoardMacInfo,
- + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + rd88f6192AInfoBoardGppInfo,
- + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + rd88f6192AInfoBoardDebugLedIf,
- + 0, /* ledsPolarity */
- + RD_88F6192A_OE_LOW, /* gppOutEnLow */
- + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
- + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
- + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +#define DB_88F6180A_BOARD_PCI_IF_NUM 0x0
- +#define DB_88F6180A_BOARD_TWSI_DEF_NUM 0x5
- +#define DB_88F6180A_BOARD_MAC_INFO_NUM 0x1
- +#define DB_88F6180A_BOARD_GPP_INFO_NUM 0x0
- +#define DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM 0x2
- +#define DB_88F6180A_BOARD_MPP_CONFIG_NUM 0x1
- +#define DB_88F6180A_BOARD_DEVICE_CONFIG_NUM 0x1
- +#define DB_88F6180A_BOARD_DEBUG_LED_NUM 0x0
- +
- +MV_BOARD_TWSI_INFO db88f6180AInfoBoardTwsiDev[] =
- + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
- + {
- + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
- + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
- + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
- + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
- + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
- + };
- +
- +MV_BOARD_MAC_INFO db88f6180AInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {{BOARD_MAC_SPEED_AUTO, 0x8}
- + };
- +
- +MV_BOARD_GPP_INFO db88f6180AInfoBoardGppInfo[] =
- + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
- + {
- + /* Muxed with TDM/Audio module via IOexpender
- + {BOARD_GPP_USB_VBUS, 6} */
- + };
- +
- +MV_BOARD_MPP_TYPE_INFO db88f6180AInfoBoardMppTypeInfo[] =
- + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
- + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
- + {{MV_BOARD_OTHER, MV_BOARD_AUTO}
- + };
- +
- +MV_DEV_CS_INFO db88f6180AInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- +#if defined(MV_NAND_BOOT)
- + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
- +#else
- + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
- +#endif
- +
- +MV_BOARD_MPP_INFO db88f6180AInfoBoardMppConfigValue[] =
- + {{{
- + DB_88F6180A_MPP0_7,
- + DB_88F6180A_MPP8_15,
- + DB_88F6180A_MPP16_23,
- + DB_88F6180A_MPP24_31,
- + DB_88F6180A_MPP32_39,
- + DB_88F6180A_MPP40_44
- + }}};
- +
- +MV_BOARD_INFO db88f6180AInfo = {
- + "DB-88F6180A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
- + DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + db88f6180AInfoBoardMppTypeInfo,
- + DB_88F6180A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + db88f6180AInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + 0, /* intsGppMaskHigh */
- + DB_88F6180A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + db88f6180AInfoBoardDeCsInfo,
- + DB_88F6180A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + db88f6180AInfoBoardTwsiDev,
- + DB_88F6180A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + db88f6180AInfoBoardMacInfo,
- + DB_88F6180A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + NULL,
- + DB_88F6180A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + NULL,
- + 0, /* ledsPolarity */
- + DB_88F6180A_OE_LOW, /* gppOutEnLow */
- + DB_88F6180A_OE_HIGH, /* gppOutEnHigh */
- + DB_88F6180A_OE_VAL_LOW, /* gppOutValLow */
- + DB_88F6180A_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +
- +#define RD_88F6281A_PCAC_BOARD_PCI_IF_NUM 0x0
- +#define RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM 0x1
- +#define RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM 0x1
- +#define RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM 0x0
- +#define RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM 0x1
- +#define RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM 0x1
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x2
- +#else
- + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
- +#endif
- +#define RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM 0x4
- +
- +MV_U8 rd88f6281APcacInfoBoardDebugLedIf[] =
- + {38, 39, 40, 41};
- +
- +MV_BOARD_MAC_INFO rd88f6281APcacInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {{BOARD_MAC_SPEED_AUTO, 0x8}
- + };
- +
- +MV_BOARD_TWSI_INFO rd88f6281APcacInfoBoardTwsiDev[] =
- + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
- + {
- + {BOARD_TWSI_OTHER, 0xa7, ADDR7_BIT}
- + };
- +
- +MV_BOARD_MPP_TYPE_INFO rd88f6281APcacInfoBoardMppTypeInfo[] =
- + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
- + };
- +
- +MV_DEV_CS_INFO rd88f6281APcacInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + {
- + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
- + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
- + };
- +#else
- + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
- +#endif
- +
- +MV_BOARD_MPP_INFO rd88f6281APcacInfoBoardMppConfigValue[] =
- + {{{
- + RD_88F6281A_PCAC_MPP0_7,
- + RD_88F6281A_PCAC_MPP8_15,
- + RD_88F6281A_PCAC_MPP16_23,
- + RD_88F6281A_PCAC_MPP24_31,
- + RD_88F6281A_PCAC_MPP32_39,
- + RD_88F6281A_PCAC_MPP40_47,
- + RD_88F6281A_PCAC_MPP48_55
- + }}};
- +
- +MV_BOARD_INFO rd88f6281APcacInfo = {
- + "RD-88F6281A-PCAC", /* boardName[MAX_BOARD_NAME_LEN] */
- + RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
- + rd88f6281APcacInfoBoardMppTypeInfo,
- + RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + rd88f6281APcacInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + (1 << 3), /* intsGppMaskHigh */
- + RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + rd88f6281APcacInfoBoardDeCsInfo,
- + RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + rd88f6281APcacInfoBoardTwsiDev,
- + RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + rd88f6281APcacInfoBoardMacInfo,
- + RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + 0,
- + RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + NULL,
- + 0, /* ledsPolarity */
- + RD_88F6281A_PCAC_OE_LOW, /* gppOutEnLow */
- + RD_88F6281A_PCAC_OE_HIGH, /* gppOutEnHigh */
- + RD_88F6281A_PCAC_OE_VAL_LOW, /* gppOutValLow */
- + RD_88F6281A_PCAC_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +
- +/* 6281 Sheeva Plug*/
- +
- +#define SHEEVA_PLUG_BOARD_PCI_IF_NUM 0x0
- +#define SHEEVA_PLUG_BOARD_TWSI_DEF_NUM 0x0
- +#define SHEEVA_PLUG_BOARD_MAC_INFO_NUM 0x1
- +#define SHEEVA_PLUG_BOARD_GPP_INFO_NUM 0x0
- +#define SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN 0x1
- +#define SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM 0x1
- +#define SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM 0x1
- +#define SHEEVA_PLUG_BOARD_DEBUG_LED_NUM 0x1
- +
- +MV_U8 sheevaPlugInfoBoardDebugLedIf[] =
- + {49};
- +
- +MV_BOARD_MAC_INFO sheevaPlugInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {{BOARD_MAC_SPEED_AUTO, 0x0}};
- +
- +MV_BOARD_TWSI_INFO sheevaPlugInfoBoardTwsiDev[] =
- + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
- + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
- +
- +MV_BOARD_MPP_TYPE_INFO sheevaPlugInfoBoardMppTypeInfo[] =
- + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
- + };
- +
- +MV_DEV_CS_INFO sheevaPlugInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
- +
- +MV_BOARD_MPP_INFO sheevaPlugInfoBoardMppConfigValue[] =
- + {{{
- + RD_SHEEVA_PLUG_MPP0_7,
- + RD_SHEEVA_PLUG_MPP8_15,
- + RD_SHEEVA_PLUG_MPP16_23,
- + RD_SHEEVA_PLUG_MPP24_31,
- + RD_SHEEVA_PLUG_MPP32_39,
- + RD_SHEEVA_PLUG_MPP40_47,
- + RD_SHEEVA_PLUG_MPP48_55
- + }}};
- +
- +MV_BOARD_INFO sheevaPlugInfo = {
- + "SHEEVA PLUG", /* boardName[MAX_BOARD_NAME_LEN] */
- + SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
- + sheevaPlugInfoBoardMppTypeInfo,
- + SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + sheevaPlugInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + 0, /* intsGppMaskHigh */
- + SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + sheevaPlugInfoBoardDeCsInfo,
- + SHEEVA_PLUG_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + sheevaPlugInfoBoardTwsiDev,
- + SHEEVA_PLUG_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + sheevaPlugInfoBoardMacInfo,
- + SHEEVA_PLUG_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + 0,
- + SHEEVA_PLUG_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + sheevaPlugInfoBoardDebugLedIf,
- + 0, /* ledsPolarity */
- + RD_SHEEVA_PLUG_OE_LOW, /* gppOutEnLow */
- + RD_SHEEVA_PLUG_OE_HIGH, /* gppOutEnHigh */
- + RD_SHEEVA_PLUG_OE_VAL_LOW, /* gppOutValLow */
- + RD_SHEEVA_PLUG_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +/* Customer specific board place holder*/
- +
- +#define DB_CUSTOMER_BOARD_PCI_IF_NUM 0x0
- +#define DB_CUSTOMER_BOARD_TWSI_DEF_NUM 0x0
- +#define DB_CUSTOMER_BOARD_MAC_INFO_NUM 0x0
- +#define DB_CUSTOMER_BOARD_GPP_INFO_NUM 0x0
- +#define DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN 0x0
- +#define DB_CUSTOMER_BOARD_MPP_CONFIG_NUM 0x0
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
- +#else
- + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
- +#endif
- +#define DB_CUSTOMER_BOARD_DEBUG_LED_NUM 0x0
- +
- +MV_U8 dbCustomerInfoBoardDebugLedIf[] =
- + {0};
- +
- +MV_BOARD_MAC_INFO dbCustomerInfoBoardMacInfo[] =
- + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
- + {{BOARD_MAC_SPEED_AUTO, 0x0}};
- +
- +MV_BOARD_TWSI_INFO dbCustomerInfoBoardTwsiDev[] =
- + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
- + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
- +
- +MV_BOARD_MPP_TYPE_INFO dbCustomerInfoBoardMppTypeInfo[] =
- + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
- + };
- +
- +MV_DEV_CS_INFO dbCustomerInfoBoardDeCsInfo[] =
- + /*{deviceCS, params, devType, devWidth}*/
- +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
- + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
- +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
- + {
- + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
- + {2, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
- + };
- +#else
- + {{2, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
- +#endif
- +
- +MV_BOARD_MPP_INFO dbCustomerInfoBoardMppConfigValue[] =
- + {{{
- + DB_CUSTOMER_MPP0_7,
- + DB_CUSTOMER_MPP8_15,
- + DB_CUSTOMER_MPP16_23,
- + DB_CUSTOMER_MPP24_31,
- + DB_CUSTOMER_MPP32_39,
- + DB_CUSTOMER_MPP40_47,
- + DB_CUSTOMER_MPP48_55
- + }}};
- +
- +MV_BOARD_INFO dbCustomerInfo = {
- + "DB-CUSTOMER", /* boardName[MAX_BOARD_NAME_LEN] */
- + DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
- + dbCustomerInfoBoardMppTypeInfo,
- + DB_CUSTOMER_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
- + dbCustomerInfoBoardMppConfigValue,
- + 0, /* intsGppMaskLow */
- + 0, /* intsGppMaskHigh */
- + DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
- + dbCustomerInfoBoardDeCsInfo,
- + DB_CUSTOMER_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
- + dbCustomerInfoBoardTwsiDev,
- + DB_CUSTOMER_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
- + dbCustomerInfoBoardMacInfo,
- + DB_CUSTOMER_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
- + 0,
- + DB_CUSTOMER_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
- + NULL,
- + 0, /* ledsPolarity */
- + DB_CUSTOMER_OE_LOW, /* gppOutEnLow */
- + DB_CUSTOMER_OE_HIGH, /* gppOutEnHigh */
- + DB_CUSTOMER_OE_VAL_LOW, /* gppOutValLow */
- + DB_CUSTOMER_OE_VAL_HIGH, /* gppOutValHigh */
- + 0, /* gppPolarityValLow */
- + 0, /* gppPolarityValHigh */
- + NULL /* pSwitchInfo */
- +};
- +
- +MV_BOARD_INFO* boardInfoTbl[] = {
- + &db88f6281AInfo,
- + &rd88f6281AInfo,
- + &db88f6192AInfo,
- + &rd88f6192AInfo,
- + &db88f6180AInfo,
- + &db88f6190AInfo,
- + &rd88f6190AInfo,
- + &rd88f6281APcacInfo,
- + &dbCustomerInfo,
- + &sheevaPlugInfo
- + };
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 2010-11-09 20:28:07.482495476 +0100
- @@ -0,0 +1,262 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvBoardEnvSpech
- +#define __INCmvBoardEnvSpech
- +
- +#include "mvSysHwConfig.h"
- +
- +
- +/* For future use */
- +#define BD_ID_DATA_START_OFFS 0x0
- +#define BD_DETECT_SEQ_OFFS 0x0
- +#define BD_SYS_NUM_OFFS 0x4
- +#define BD_NAME_OFFS 0x8
- +
- +/* I2C bus addresses */
- +#define MV_BOARD_CTRL_I2C_ADDR 0x0 /* Controller slave addr */
- +#define MV_BOARD_CTRL_I2C_ADDR_TYPE ADDR7_BIT
- +#define MV_BOARD_DIMM0_I2C_ADDR 0x56
- +#define MV_BOARD_DIMM0_I2C_ADDR_TYPE ADDR7_BIT
- +#define MV_BOARD_DIMM1_I2C_ADDR 0x54
- +#define MV_BOARD_DIMM1_I2C_ADDR_TYPE ADDR7_BIT
- +#define MV_BOARD_EEPROM_I2C_ADDR 0x51
- +#define MV_BOARD_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
- +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR 0x50
- +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
- +#define MV_BOARD_MUX_I2C_ADDR_ENTRY 0x2
- +#define MV_BOARD_DIMM_I2C_CHANNEL 0x0
- +
- +#define BOOT_FLASH_INDEX 0
- +#define MAIN_FLASH_INDEX 1
- +
- +#define BOARD_ETH_START_PORT_NUM 0
- +
- +/* Supported clocks */
- +#define MV_BOARD_TCLK_100MHZ 100000000
- +#define MV_BOARD_TCLK_125MHZ 125000000
- +#define MV_BOARD_TCLK_133MHZ 133333333
- +#define MV_BOARD_TCLK_150MHZ 150000000
- +#define MV_BOARD_TCLK_166MHZ 166666667
- +#define MV_BOARD_TCLK_200MHZ 200000000
- +
- +#define MV_BOARD_SYSCLK_100MHZ 100000000
- +#define MV_BOARD_SYSCLK_125MHZ 125000000
- +#define MV_BOARD_SYSCLK_133MHZ 133333333
- +#define MV_BOARD_SYSCLK_150MHZ 150000000
- +#define MV_BOARD_SYSCLK_166MHZ 166666667
- +#define MV_BOARD_SYSCLK_200MHZ 200000000
- +#define MV_BOARD_SYSCLK_233MHZ 233333333
- +#define MV_BOARD_SYSCLK_250MHZ 250000000
- +#define MV_BOARD_SYSCLK_267MHZ 266666667
- +#define MV_BOARD_SYSCLK_300MHZ 300000000
- +#define MV_BOARD_SYSCLK_333MHZ 333333334
- +#define MV_BOARD_SYSCLK_400MHZ 400000000
- +
- +#define MV_BOARD_REFCLK_25MHZ 25000000
- +
- +/* Board specific */
- +/* =============================== */
- +
- +/* boards ID numbers */
- +
- +#define BOARD_ID_BASE 0x0
- +
- +/* New board ID numbers */
- +#define DB_88F6281A_BP_ID (BOARD_ID_BASE)
- +#define DB_88F6281_BP_MLL_ID 1680
- +#define RD_88F6281A_ID (BOARD_ID_BASE+0x1)
- +#define RD_88F6281_MLL_ID 1682
- +#define DB_88F6192A_BP_ID (BOARD_ID_BASE+0x2)
- +#define RD_88F6192A_ID (BOARD_ID_BASE+0x3)
- +#define RD_88F6192_MLL_ID 1681
- +#define DB_88F6180A_BP_ID (BOARD_ID_BASE+0x4)
- +#define DB_88F6190A_BP_ID (BOARD_ID_BASE+0x5)
- +#define RD_88F6190A_ID (BOARD_ID_BASE+0x6)
- +#define RD_88F6281A_PCAC_ID (BOARD_ID_BASE+0x7)
- +#define DB_CUSTOMER_ID (BOARD_ID_BASE+0x8)
- +#define SHEEVA_PLUG_ID (BOARD_ID_BASE+0x9)
- +#define MV_MAX_BOARD_ID (SHEEVA_PLUG_ID + 1)
- +
- +/* DB-88F6281A-BP */
- +#if defined(MV_NAND)
- + #define DB_88F6281A_MPP0_7 0x21111111
- +#else
- + #define DB_88F6281A_MPP0_7 0x21112220
- +#endif
- +#define DB_88F6281A_MPP8_15 0x11113311
- +#define DB_88F6281A_MPP16_23 0x00551111
- +#define DB_88F6281A_MPP24_31 0x00000000
- +#define DB_88F6281A_MPP32_39 0x00000000
- +#define DB_88F6281A_MPP40_47 0x00000000
- +#define DB_88F6281A_MPP48_55 0x00000000
- +#define DB_88F6281A_OE_LOW 0x0
- +#if defined(MV_TDM_5CHANNELS)
- + #define DB_88F6281A_OE_HIGH (BIT6)
- +#else
- +#define DB_88F6281A_OE_HIGH 0x0
- +#endif
- +#define DB_88F6281A_OE_VAL_LOW 0x0
- +#define DB_88F6281A_OE_VAL_HIGH 0x0
- +
- +/* RD-88F6281A */
- +#if defined(MV_NAND)
- + #define RD_88F6281A_MPP0_7 0x21111111
- +#else
- + #define RD_88F6281A_MPP0_7 0x21112220
- +#endif
- +#define RD_88F6281A_MPP8_15 0x11113311
- +#define RD_88F6281A_MPP16_23 0x33331111
- +#define RD_88F6281A_MPP24_31 0x33003333
- +#define RD_88F6281A_MPP32_39 0x20440533
- +#define RD_88F6281A_MPP40_47 0x22202222
- +#define RD_88F6281A_MPP48_55 0x00000002
- +#define RD_88F6281A_OE_LOW (BIT28 | BIT29)
- +#define RD_88F6281A_OE_HIGH (BIT3 | BIT6 | BIT17)
- +#define RD_88F6281A_OE_VAL_LOW 0x0
- +#define RD_88F6281A_OE_VAL_HIGH 0x0
- +
- +/* DB-88F6192A-BP */
- +#if defined(MV_NAND)
- + #define DB_88F6192A_MPP0_7 0x21111111
- +#else
- + #define DB_88F6192A_MPP0_7 0x21112220
- +#endif
- +#define DB_88F6192A_MPP8_15 0x11113311
- +#define DB_88F6192A_MPP16_23 0x00501111
- +#define DB_88F6192A_MPP24_31 0x00000000
- +#define DB_88F6192A_MPP32_35 0x00000000
- +#define DB_88F6192A_OE_LOW (BIT22 | BIT23)
- +#define DB_88F6192A_OE_HIGH 0x0
- +#define DB_88F6192A_OE_VAL_LOW 0x0
- +#define DB_88F6192A_OE_VAL_HIGH 0x0
- +
- +/* RD-88F6192A */
- +#define RD_88F6192A_MPP0_7 0x01222222
- +#define RD_88F6192A_MPP8_15 0x00000011
- +#define RD_88F6192A_MPP16_23 0x05550000
- +#define RD_88F6192A_MPP24_31 0x0
- +#define RD_88F6192A_MPP32_35 0x0
- +#define RD_88F6192A_OE_LOW (BIT11 | BIT14 | BIT24 | BIT25 | BIT26 | BIT27 | BIT30 | BIT31)
- +#define RD_88F6192A_OE_HIGH (BIT0 | BIT2)
- +#define RD_88F6192A_OE_VAL_LOW 0x18400
- +#define RD_88F6192A_OE_VAL_HIGH 0x8
- +
- +/* DB-88F6180A-BP */
- +#if defined(MV_NAND)
- + #define DB_88F6180A_MPP0_7 0x21111111
- +#else
- + #define DB_88F6180A_MPP0_7 0x01112222
- +#endif
- +#define DB_88F6180A_MPP8_15 0x11113311
- +#define DB_88F6180A_MPP16_23 0x00001111
- +#define DB_88F6180A_MPP24_31 0x0
- +#define DB_88F6180A_MPP32_39 0x4444c000
- +#define DB_88F6180A_MPP40_44 0x00044444
- +#define DB_88F6180A_OE_LOW 0x0
- +#define DB_88F6180A_OE_HIGH 0x0
- +#define DB_88F6180A_OE_VAL_LOW 0x0
- +#define DB_88F6180A_OE_VAL_HIGH 0x0
- +
- +/* RD-88F6281A_PCAC */
- +#define RD_88F6281A_PCAC_MPP0_7 0x21111111
- +#define RD_88F6281A_PCAC_MPP8_15 0x00003311
- +#define RD_88F6281A_PCAC_MPP16_23 0x00001100
- +#define RD_88F6281A_PCAC_MPP24_31 0x00000000
- +#define RD_88F6281A_PCAC_MPP32_39 0x00000000
- +#define RD_88F6281A_PCAC_MPP40_47 0x00000000
- +#define RD_88F6281A_PCAC_MPP48_55 0x00000000
- +#define RD_88F6281A_PCAC_OE_LOW 0x0
- +#define RD_88F6281A_PCAC_OE_HIGH 0x0
- +#define RD_88F6281A_PCAC_OE_VAL_LOW 0x0
- +#define RD_88F6281A_PCAC_OE_VAL_HIGH 0x0
- +
- +/* SHEEVA PLUG */
- +#define RD_SHEEVA_PLUG_MPP0_7 0x01111111
- +#define RD_SHEEVA_PLUG_MPP8_15 0x11113322
- +#define RD_SHEEVA_PLUG_MPP16_23 0x00001111
- +#define RD_SHEEVA_PLUG_MPP24_31 0x00100000
- +#define RD_SHEEVA_PLUG_MPP32_39 0x00000000
- +#define RD_SHEEVA_PLUG_MPP40_47 0x00000000
- +#define RD_SHEEVA_PLUG_MPP48_55 0x00000000
- +#define RD_SHEEVA_PLUG_OE_LOW 0x0
- +#define RD_SHEEVA_PLUG_OE_HIGH 0x0
- +#define RD_SHEEVA_PLUG_OE_VAL_LOW (BIT29)
- +#define RD_SHEEVA_PLUG_OE_VAL_HIGH ((~(BIT17 | BIT16 | BIT15)) | BIT14)
- +
- +/* DB-CUSTOMER */
- +#define DB_CUSTOMER_MPP0_7 0x21111111
- +#define DB_CUSTOMER_MPP8_15 0x00003311
- +#define DB_CUSTOMER_MPP16_23 0x00001100
- +#define DB_CUSTOMER_MPP24_31 0x00000000
- +#define DB_CUSTOMER_MPP32_39 0x00000000
- +#define DB_CUSTOMER_MPP40_47 0x00000000
- +#define DB_CUSTOMER_MPP48_55 0x00000000
- +#define DB_CUSTOMER_OE_LOW 0x0
- +#define DB_CUSTOMER_OE_HIGH (~((BIT6) | (BIT7) | (BIT8) | (BIT9)))
- +#define DB_CUSTOMER_OE_VAL_LOW 0x0
- +#define DB_CUSTOMER_OE_VAL_HIGH 0x0
- +
- +#endif /* __INCmvBoardEnvSpech */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 2010-11-09 20:28:07.522495500 +0100
- @@ -0,0 +1,320 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#include "cpu/mvCpu.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvRegs.h"
- +#include "ctrlEnv/sys/mvCpuIfRegs.h"
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +/* locals */
- +
- +/*******************************************************************************
- +* mvCpuPclkGet - Get the CPU pClk (pipe clock)
- +*
- +* DESCRIPTION:
- +* This routine extract the CPU core clock.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit clock cycles in MHertz.
- +*
- +*******************************************************************************/
- +/* 6180 have different clk reset sampling */
- +
- +static MV_U32 mvCpu6180PclkGet(MV_VOID)
- +{
- + MV_U32 tmpPClkRate=0;
- + MV_CPU_ARM_CLK cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
- +
- + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + tmpPClkRate = tmpPClkRate & MSAR_CPUCLCK_MASK_6180;
- + tmpPClkRate = tmpPClkRate >> MSAR_CPUCLCK_OFFS_6180;
- +
- + tmpPClkRate = cpu6180_ddr_l2_CLK[tmpPClkRate].cpuClk;
- +
- + return tmpPClkRate;
- +}
- +
- +
- +MV_U32 mvCpuPclkGet(MV_VOID)
- +{
- +#if defined(PCLCK_AUTO_DETECT)
- + MV_U32 tmpPClkRate=0;
- + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
- +
- + if(mvCtrlModelGet() == MV_6180_DEV_ID)
- + return mvCpu6180PclkGet();
- +
- + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + tmpPClkRate = MSAR_CPUCLCK_EXTRACT(tmpPClkRate);
- + tmpPClkRate = cpuCLK[tmpPClkRate];
- +
- + return tmpPClkRate;
- +#else
- + return MV_DEFAULT_PCLK
- +#endif
- +}
- +
- +/*******************************************************************************
- +* mvCpuL2ClkGet - Get the CPU L2 (CPU bus clock)
- +*
- +* DESCRIPTION:
- +* This routine extract the CPU L2 clock.
- +*
- +* RETURN:
- +* 32bit clock cycles in Hertz.
- +*
- +*******************************************************************************/
- +static MV_U32 mvCpu6180L2ClkGet(MV_VOID)
- +{
- + MV_U32 L2ClkRate=0;
- + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
- +
- + L2ClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + L2ClkRate = L2ClkRate & MSAR_CPUCLCK_MASK_6180;
- + L2ClkRate = L2ClkRate >> MSAR_CPUCLCK_OFFS_6180;
- +
- + L2ClkRate = _cpu6180_ddr_l2_CLK[L2ClkRate].l2Clk;
- +
- + return L2ClkRate;
- +
- +}
- +
- +MV_U32 mvCpuL2ClkGet(MV_VOID)
- +{
- +#ifdef L2CLK_AUTO_DETECT
- + MV_U32 L2ClkRate, tmp, pClkRate, indexL2Rtio;
- + MV_U32 L2Rtio[][2] = MV_L2_CLCK_RTIO_TBL;
- +
- + if(mvCtrlModelGet() == MV_6180_DEV_ID)
- + return mvCpu6180L2ClkGet();
- +
- + pClkRate = mvCpuPclkGet();
- +
- + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + indexL2Rtio = MSAR_L2CLCK_EXTRACT(tmp);
- +
- + L2ClkRate = ((pClkRate * L2Rtio[indexL2Rtio][1]) / L2Rtio[indexL2Rtio][0]);
- +
- + return L2ClkRate;
- +#else
- + return MV_BOARD_DEFAULT_L2CLK;
- +#endif
- +}
- +
- +
- +/*******************************************************************************
- +* mvCpuNameGet - Get CPU name
- +*
- +* DESCRIPTION:
- +* This function returns a string describing the CPU model and revision.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
- +*
- +* RETURN:
- +* None.
- +*******************************************************************************/
- +MV_VOID mvCpuNameGet(char *pNameBuff)
- +{
- + MV_U32 cpuModel;
- +
- + cpuModel = mvOsCpuPartGet();
- +
- + /* The CPU module is indicated in the Processor Version Register (PVR) */
- + switch(cpuModel)
- + {
- + case CPU_PART_MRVL131:
- + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "Marvell Feroceon",mvOsCpuRevGet());
- + break;
- + case CPU_PART_ARM926:
- + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM926",mvOsCpuRevGet());
- + break;
- + case CPU_PART_ARM946:
- + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM946",mvOsCpuRevGet());
- + break;
- + default:
- + mvOsSPrintf(pNameBuff,"??? (0x%04x) (Rev %d)",cpuModel,mvOsCpuRevGet());
- + break;
- + } /* switch */
- +
- + return;
- +}
- +
- +
- +#define MV_PROC_STR_SIZE 50
- +
- +static void mvCpuIfGetL2EccMode(MV_8 *buf)
- +{
- + MV_U32 regVal = MV_REG_READ(CPU_L2_CONFIG_REG);
- + if (regVal & BIT2)
- + mvOsSPrintf(buf, "L2 ECC Enabled");
- + else
- + mvOsSPrintf(buf, "L2 ECC Disabled");
- +}
- +
- +static void mvCpuIfGetL2Mode(MV_8 *buf)
- +{
- + MV_U32 regVal = 0;
- + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
- + if (regVal & BIT22)
- + mvOsSPrintf(buf, "L2 Enabled");
- + else
- + mvOsSPrintf(buf, "L2 Disabled");
- +}
- +
- +static void mvCpuIfGetL2PrefetchMode(MV_8 *buf)
- +{
- + MV_U32 regVal = 0;
- + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
- + if (regVal & BIT24)
- + mvOsSPrintf(buf, "L2 Prefetch Disabled");
- + else
- + mvOsSPrintf(buf, "L2 Prefetch Enabled");
- +}
- +
- +static void mvCpuIfGetWriteAllocMode(MV_8 *buf)
- +{
- + MV_U32 regVal = 0;
- + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
- + if (regVal & BIT28)
- + mvOsSPrintf(buf, "Write Allocate Enabled");
- + else
- + mvOsSPrintf(buf, "Write Allocate Disabled");
- +}
- +
- +static void mvCpuIfGetCpuStreamMode(MV_8 *buf)
- +{
- + MV_U32 regVal = 0;
- + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
- + if (regVal & BIT29)
- + mvOsSPrintf(buf, "CPU Streaming Enabled");
- + else
- + mvOsSPrintf(buf, "CPU Streaming Disabled");
- +}
- +
- +static void mvCpuIfPrintCpuRegs(void)
- +{
- + MV_U32 regVal = 0;
- +
- + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
- + mvOsPrintf("Extra Feature Reg = 0x%x\n",regVal);
- +
- + __asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (regVal)); /* Read Control register */
- + mvOsPrintf("Control Reg = 0x%x\n",regVal);
- +
- + __asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (regVal)); /* Read ID Code register */
- + mvOsPrintf("ID Code Reg = 0x%x\n",regVal);
- +
- + __asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r" (regVal)); /* Read Cache Type register */
- + mvOsPrintf("Cache Type Reg = 0x%x\n",regVal);
- +
- +}
- +
- +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index)
- +{
- + MV_U32 count = 0;
- +
- + MV_8 L2_ECC_str[MV_PROC_STR_SIZE];
- + MV_8 L2_En_str[MV_PROC_STR_SIZE];
- + MV_8 L2_Prefetch_str[MV_PROC_STR_SIZE];
- + MV_8 Write_Alloc_str[MV_PROC_STR_SIZE];
- + MV_8 Cpu_Stream_str[MV_PROC_STR_SIZE];
- +
- + mvCpuIfGetL2Mode(L2_En_str);
- + mvCpuIfGetL2EccMode(L2_ECC_str);
- + mvCpuIfGetL2PrefetchMode(L2_Prefetch_str);
- + mvCpuIfGetWriteAllocMode(Write_Alloc_str);
- + mvCpuIfGetCpuStreamMode(Cpu_Stream_str);
- + mvCpuIfPrintCpuRegs();
- +
- + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_En_str);
- + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_ECC_str);
- + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_Prefetch_str);
- + count += mvOsSPrintf(buffer + count + index, "%s\n", Write_Alloc_str);
- + count += mvOsSPrintf(buffer + count + index, "%s\n", Cpu_Stream_str);
- + return count;
- +}
- +
- +MV_U32 whoAmI(MV_VOID)
- +{
- + return 0;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 2010-11-09 20:28:07.562495452 +0100
- @@ -0,0 +1,99 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvCpuh
- +#define __INCmvCpuh
- +
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +
- +/* defines */
- +#define CPU_PART_MRVL131 0x131
- +#define CPU_PART_ARM926 0x926
- +#define CPU_PART_ARM946 0x946
- +#define MV_CPU_ARM_CLK_ELM_SIZE 12
- +#define MV_CPU_ARM_CLK_RATIO_OFF 8
- +#define MV_CPU_ARM_CLK_DDR_OFF 4
- +
- +#ifndef MV_ASMLANGUAGE
- +typedef struct _mvCpuArmClk
- +{
- + MV_U32 cpuClk; /* CPU clock in MHz */
- + MV_U32 ddrClk; /* DDR clock in MHz */
- + MV_U32 l2Clk; /* CPU DDR clock ratio */
- +
- +}MV_CPU_ARM_CLK;
- +
- +MV_U32 mvCpuPclkGet(MV_VOID);
- +MV_VOID mvCpuNameGet(char *pNameBuff);
- +MV_U32 mvCpuL2ClkGet(MV_VOID);
- +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index);
- +MV_U32 whoAmI(MV_VOID);
- +
- +#endif /* MV_ASMLANGUAGE */
- +
- +
- +#endif /* __INCmvCpuh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 2010-11-09 20:28:07.602495466 +0100
- @@ -0,0 +1,296 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +/*******************************************************************************
- +* mvCtrlEnvAddrDec.h - Marvell controller address decode library
- +*
- +* DESCRIPTION:
- +*
- +* DEPENDENCIES:
- +* None.
- +*
- +*******************************************************************************/
- +
- +/* includes */
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
- +#include "ddr2/mvDramIfRegs.h"
- +#include "pex/mvPexRegs.h"
- +
- +#define MV_DEBUG
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +/* Default Attributes array */
- +MV_TARGET_ATTRIB mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;
- +extern MV_TARGET *sampleAtResetTargetArray;
- +/* Dram\AHBToMbus\PEX share regsiter */
- +
- +#define CTRL_DEC_BASE_OFFS 16
- +#define CTRL_DEC_BASE_MASK (0xffff << CTRL_DEC_BASE_OFFS)
- +#define CTRL_DEC_BASE_ALIGNMENT 0x10000
- +
- +#define CTRL_DEC_SIZE_OFFS 16
- +#define CTRL_DEC_SIZE_MASK (0xffff << CTRL_DEC_SIZE_OFFS)
- +#define CTRL_DEC_SIZE_ALIGNMENT 0x10000
- +
- +#define CTRL_DEC_WIN_EN BIT0
- +
- +
- +
- +/*******************************************************************************
- +* mvCtrlAddrDecToReg - Get address decode register format values
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)
- +{
- +
- + MV_U32 baseToReg=0 , sizeToReg=0;
- +
- + /* BaseLow[31:16] => base register [31:16] */
- + baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;
- +
- + /* Write to address decode Base Address Register */
- + pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;
- + pAddrDecRegs->baseReg |= baseToReg;
- +
- + /* Get size register value according to window size */
- + sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);
- +
- + /* Size parameter validity check. */
- + if (-1 == sizeToReg)
- + {
- + return MV_BAD_PARAM;
- + }
- +
- + /* set size */
- + pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;
- + pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);
- +
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvCtrlRegToAddrDec - Extract address decode struct from registers.
- +*
- +* DESCRIPTION:
- +* This function extract address decode struct from address decode
- +* registers given as parameters.
- +*
- +* INPUT:
- +* pAddrDecRegs - Address decode register struct.
- +*
- +* OUTPUT:
- +* pAddrDecWin - Target window data structure.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if address decode registers data is invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs, MV_ADDR_WIN *pAddrDecWin)
- +{
- + MV_U32 sizeRegVal;
- +
- + sizeRegVal = (pAddrDecRegs->sizeReg & CTRL_DEC_SIZE_MASK) >>
- + CTRL_DEC_SIZE_OFFS;
- +
- + pAddrDecWin->size = ctrlRegToSize(sizeRegVal, CTRL_DEC_SIZE_ALIGNMENT);
- +
- +
- + /* Extract base address */
- + /* Base register [31:16] ==> baseLow[31:16] */
- + pAddrDecWin->baseLow = pAddrDecRegs->baseReg & CTRL_DEC_BASE_MASK;
- +
- + pAddrDecWin->baseHigh = 0;
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvCtrlAttribGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +
- +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
- + MV_TARGET_ATTRIB *targetAttrib)
- +{
- +
- + targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;
- + targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvCtrlGetAttrib -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib)
- +{
- + MV_TARGET target;
- + MV_TARGET x;
- + for (target = SDRAM_CS0; target < MAX_TARGETS ; target ++)
- + {
- + x = MV_CHANGE_BOOT_CS(target);
- + if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&
- + (mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId == targetAttrib->targetId))
- + {
- + /* found it */
- + break;
- + }
- + }
- +
- + return target;
- +}
- +
- +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
- + MV_DEC_WIN_PARAMS *pWinParam)
- +{
- + MV_U32 baseToReg=0, sizeToReg=0;
- +
- + /* BaseLow[31:16] => base register [31:16] */
- + baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;
- +
- + /* Write to address decode Base Address Register */
- + pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;
- + pWinParam->baseAddr |= baseToReg;
- +
- + /* Get size register value according to window size */
- + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);
- +
- + /* Size parameter validity check. */
- + if (-1 == sizeToReg)
- + {
- + mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");
- + return MV_BAD_PARAM;
- + }
- + pWinParam->size = sizeToReg;
- +
- + pWinParam->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;
- + pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;
- +
- + return MV_OK;
- +}
- +
- +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
- + MV_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttrib;
- +
- + pAddrDecWin->addrWin.baseLow = pWinParam->baseAddr;
- +
- + /* Upper 32bit address base is supported under PCI High Address remap */
- + pAddrDecWin->addrWin.baseHigh = 0;
- +
- + /* Prepare sizeReg to ctrlRegToSize function */
- + pAddrDecWin->addrWin.size = ctrlRegToSize(pWinParam->size, CTRL_DEC_SIZE_ALIGNMENT);
- +
- + if (-1 == pAddrDecWin->addrWin.size)
- + {
- + DB(mvOsPrintf("mvCtrlParamsToAddrDec: ERR. ctrlRegToSize failed.\n"));
- + return MV_BAD_PARAM;
- + }
- + targetAttrib.targetId = pWinParam->targetId;
- + targetAttrib.attrib = pWinParam->attrib;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + return MV_OK;
- +}
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 2010-11-09 20:28:07.642495620 +0100
- @@ -0,0 +1,203 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvCtrlEnvAddrDech
- +#define __INCmvCtrlEnvAddrDech
- +
- +/* includes */
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvRegs.h"
- +
- +
- +/* defines */
- +/* DUnit attributes */
- +#define ATMWCR_WIN_DUNIT_CS0_OFFS 0
- +#define ATMWCR_WIN_DUNIT_CS0_MASK BIT0
- +#define ATMWCR_WIN_DUNIT_CS0_REQ (0 << ATMWCR_WIN_DUNIT_CS0_OFFS)
- +
- +#define ATMWCR_WIN_DUNIT_CS1_OFFS 1
- +#define ATMWCR_WIN_DUNIT_CS1_MASK BIT1
- +#define ATMWCR_WIN_DUNIT_CS1_REQ (0 << ATMWCR_WIN_DUNIT_CS1_OFFS)
- +
- +#define ATMWCR_WIN_DUNIT_CS2_OFFS 2
- +#define ATMWCR_WIN_DUNIT_CS2_MASK BIT2
- +#define ATMWCR_WIN_DUNIT_CS2_REQ (0 << ATMWCR_WIN_DUNIT_CS2_OFFS)
- +
- +#define ATMWCR_WIN_DUNIT_CS3_OFFS 3
- +#define ATMWCR_WIN_DUNIT_CS3_MASK BIT3
- +#define ATMWCR_WIN_DUNIT_CS3_REQ (0 << ATMWCR_WIN_DUNIT_CS3_OFFS)
- +
- +/* RUnit (Device) attributes */
- +#define ATMWCR_WIN_RUNIT_DEVCS0_OFFS 0
- +#define ATMWCR_WIN_RUNIT_DEVCS0_MASK BIT0
- +#define ATMWCR_WIN_RUNIT_DEVCS0_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS0_OFFS)
- +
- +#define ATMWCR_WIN_RUNIT_DEVCS1_OFFS 1
- +#define ATMWCR_WIN_RUNIT_DEVCS1_MASK BIT1
- +#define ATMWCR_WIN_RUNIT_DEVCS1_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS1_OFFS)
- +
- +#define ATMWCR_WIN_RUNIT_DEVCS2_OFFS 2
- +#define ATMWCR_WIN_RUNIT_DEVCS2_MASK BIT2
- +#define ATMWCR_WIN_RUNIT_DEVCS2_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS2_OFFS)
- +
- +#define ATMWCR_WIN_RUNIT_BOOTCS_OFFS 4
- +#define ATMWCR_WIN_RUNIT_BOOTCS_MASK BIT4
- +#define ATMWCR_WIN_RUNIT_BOOTCS_REQ (0 << ATMWCR_WIN_RUNIT_BOOTCS_OFFS)
- +
- +/* LMaster (PCI) attributes */
- +#define ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS 0
- +#define ATMWCR_WIN_LUNIT_BYTE_SWP_MASK BIT0
- +#define ATMWCR_WIN_LUNIT_BYTE_SWP (0 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
- +#define ATMWCR_WIN_LUNIT_BYTE_NO_SWP (1 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
- +
- +
- +#define ATMWCR_WIN_LUNIT_WORD_SWP_OFFS 1
- +#define ATMWCR_WIN_LUNIT_WORD_SWP_MASK BIT1
- +#define ATMWCR_WIN_LUNIT_WORD_SWP (0 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
- +#define ATMWCR_WIN_LUNIT_WORD_NO_SWP (1 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
- +
- +#define ATMWCR_WIN_LUNIT_NO_SNOOP BIT2
- +
- +#define ATMWCR_WIN_LUNIT_TYPE_OFFS 3
- +#define ATMWCR_WIN_LUNIT_TYPE_MASK BIT3
- +#define ATMWCR_WIN_LUNIT_TYPE_IO (0 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
- +#define ATMWCR_WIN_LUNIT_TYPE_MEM (1 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
- +
- +#define ATMWCR_WIN_LUNIT_FORCE64_OFFS 4
- +#define ATMWCR_WIN_LUNIT_FORCE64_MASK BIT4
- +#define ATMWCR_WIN_LUNIT_FORCE64 (0 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
- +
- +#define ATMWCR_WIN_LUNIT_ORDERING_OFFS 6
- +#define ATMWCR_WIN_LUNIT_ORDERING_MASK BIT6
- +#define ATMWCR_WIN_LUNIT_ORDERING (1 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
- +
- +/* PEX Attributes */
- +#define ATMWCR_WIN_PEX_TYPE_OFFS 3
- +#define ATMWCR_WIN_PEX_TYPE_MASK BIT3
- +#define ATMWCR_WIN_PEX_TYPE_IO (0 << ATMWCR_WIN_PEX_TYPE_OFFS)
- +#define ATMWCR_WIN_PEX_TYPE_MEM (1 << ATMWCR_WIN_PEX_TYPE_OFFS)
- +
- +/* typedefs */
- +
- +/* Unsupported attributes for address decode: */
- +/* 2) PCI0/1_REQ64n control */
- +
- +typedef struct _mvDecRegs
- +{
- + MV_U32 baseReg;
- + MV_U32 baseRegHigh;
- + MV_U32 sizeReg;
- +
- +}MV_DEC_REGS;
- +
- +typedef struct _mvTargetAttrib
- +{
- + MV_U8 attrib; /* chip select attributes */
- + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
- +
- +}MV_TARGET_ATTRIB;
- +
- +
- +/* This structure describes address decode window */
- +typedef struct _mvDecWin
- +{
- + MV_TARGET target; /* Target for addr decode window */
- + MV_ADDR_WIN addrWin; /* Address window of target */
- + MV_BOOL enable; /* Window enable/disable */
- +}MV_DEC_WIN;
- +
- +typedef struct _mvDecWinParams
- +{
- + MV_TARGET_ID targetId; /* Target ID field */
- + MV_U8 attrib; /* Attribute field */
- + MV_U32 baseAddr; /* Base address in register format */
- + MV_U32 size; /* Size in register format */
- +}MV_DEC_WIN_PARAMS;
- +
- +
- +/* mvCtrlEnvAddrDec API list */
- +
- +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin,
- + MV_DEC_REGS *pAddrDecRegs);
- +
- +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs,
- + MV_ADDR_WIN *pAddrDecWin);
- +
- +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
- + MV_TARGET_ATTRIB *targetAttrib);
- +
- +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib);
- +
- +
- +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
- + MV_DEC_WIN_PARAMS *pWinParam);
- +
- +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
- + MV_DEC_WIN *pAddrDecWin);
- +
- +
- +
- +
- +#endif /* __INCmvCtrlEnvAddrDech */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 2010-11-09 20:28:07.682495401 +0100
- @@ -0,0 +1,98 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvCtrlEnvAsmh
- +#define __INCmvCtrlEnvAsmh
- +#include "pex/mvPexRegs.h"
- +
- +#define CHIP_BOND_REG 0x10034
- +#define PCKG_OPT_MASK_AS #3
- +#define PXCCARI_REVID_MASK_AS #PXCCARI_REVID_MASK
- +
- +/* Read device ID into toReg bits 15:0 from 0xd0000000 */
- +/* defines */
- +#define MV_DV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
- + MV_DV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
- + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
- +
- +/* Read device ID into toReg bits 15:0 from 0xf1000000*/
- +#define MV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
- + MV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
- + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
- +
- +/* Read Revision into toReg bits 7:0 0xd0000000*/
- +#define MV_DV_CTRL_REV_GET_ASM(toReg, tmpReg) \
- + /* Read device revision */ \
- + MV_DV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
- + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
- +
- +/* Read Revision into toReg bits 7:0 0xf1000000*/
- +#define MV_CTRL_REV_GET_ASM(toReg, tmpReg) \
- + /* Read device revision */ \
- + MV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
- + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
- +
- +
- +#endif /* __INCmvCtrlEnvAsmh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 2010-11-09 20:28:07.712495488 +0100
- @@ -0,0 +1,1825 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +/* includes */
- +#include "mvCommon.h"
- +#include "mvCtrlEnvLib.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +#if defined(MV_INCLUDE_PEX)
- +#include "pex/mvPex.h"
- +#include "ctrlEnv/sys/mvSysPex.h"
- +#endif
- +
- +#if defined(MV_INCLUDE_GIG_ETH)
- +#include "ctrlEnv/sys/mvSysGbe.h"
- +#endif
- +
- +#if defined(MV_INCLUDE_XOR)
- +#include "ctrlEnv/sys/mvSysXor.h"
- +#endif
- +
- +#if defined(MV_INCLUDE_SATA)
- +#include "ctrlEnv/sys/mvSysSata.h"
- +#endif
- +
- +#if defined(MV_INCLUDE_USB)
- +#include "ctrlEnv/sys/mvSysUsb.h"
- +#endif
- +
- +#if defined(MV_INCLUDE_AUDIO)
- +#include "ctrlEnv/sys/mvSysAudio.h"
- +#endif
- +
- +#if defined(MV_INCLUDE_CESA)
- +#include "ctrlEnv/sys/mvSysCesa.h"
- +#endif
- +
- +#if defined(MV_INCLUDE_TS)
- +#include "ctrlEnv/sys/mvSysTs.h"
- +#endif
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +/*******************************************************************************
- +* mvCtrlEnvInit - Initialize Marvell controller environment.
- +*
- +* DESCRIPTION:
- +* This function get environment information and initialize controller
- +* internal/external environment. For example
- +* 1) MPP settings according to board MPP macros.
- +* NOTE: It is the user responsibility to shut down all DMA channels
- +* in device and disable controller sub units interrupts during
- +* boot process.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCtrlEnvInit(MV_VOID)
- +{
- + MV_U32 mppGroup;
- + MV_U32 devId;
- + MV_U32 boardId;
- + MV_U32 i;
- + MV_U32 maxMppGrp = 1;
- + MV_U32 mppVal = 0;
- + MV_U32 bootVal = 0;
- + MV_U32 mppGroupType = 0;
- + MV_U32 mppGroup1[][3] = MPP_GROUP_1_TYPE;
- + MV_U32 mppGroup2[][3] = MPP_GROUP_2_TYPE;
- +
- + devId = mvCtrlModelGet();
- + boardId= mvBoardIdGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + maxMppGrp = MV_6281_MPP_MAX_GROUP;
- + break;
- + case MV_6192_DEV_ID:
- + maxMppGrp = MV_6192_MPP_MAX_GROUP;
- + break;
- + case MV_6190_DEV_ID:
- + maxMppGrp = MV_6190_MPP_MAX_GROUP;
- + break;
- + case MV_6180_DEV_ID:
- + maxMppGrp = MV_6180_MPP_MAX_GROUP;
- + break;
- + }
- +
- + /* MPP Init */
- + /* We split mpp init to 3 phases:
- + * 1. We init mpp[19:0] from the board info. mpp[23:20] will be over write
- + * in phase 2.
- + * 2. We detect the mpp group type and according the mpp values [35:20].
- + * 3. We detect the mpp group type and according the mpp values [49:36].
- + */
- + /* Mpp phase 1 mpp[19:0] */
- + /* Read MPP group from board level and assign to MPP register */
- + for (mppGroup = 0; mppGroup < 3; mppGroup++)
- + {
- + mppVal = mvBoardMppGet(mppGroup);
- + if (mppGroup == 0)
- + {
- + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
- + if (mvCtrlIsBootFromSPI())
- + {
- + mppVal &= ~0xffff;
- + bootVal &= 0xffff;
- + mppVal |= bootVal;
- + }
- + else if (mvCtrlIsBootFromSPIUseNAND())
- + {
- + mppVal &= ~0xf0000000;
- + bootVal &= 0xf0000000;
- + mppVal |= bootVal;
- + }
- + else if (mvCtrlIsBootFromNAND())
- + {
- + mppVal &= ~0xffffff;
- + bootVal &= 0xffffff;
- + mppVal |= bootVal;
- + }
- + }
- +
- + if (mppGroup == 2)
- + {
- + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
- + if (mvCtrlIsBootFromNAND())
- + {
- + mppVal &= ~0xff00;
- + bootVal &= 0xff00;
- + mppVal |= bootVal;
- + }
- + }
- +
- + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
- + }
- +
- + /* Identify MPPs group */
- + mvBoardMppGroupIdUpdate();
- +
- + /* Update MPPs mux relevent only on Marvell DB */
- + if ((boardId == DB_88F6281A_BP_ID) ||
- + (boardId == DB_88F6180A_BP_ID))
- + mvBoardMppMuxSet();
- +
- + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_1);
- +
- + /* Mpp phase 2 */
- + /* Read MPP group from board level and assign to MPP register */
- + if (devId != MV_6180_DEV_ID)
- + {
- + i = 0;
- + for (mppGroup = 2; mppGroup < 5; mppGroup++)
- + {
- + if ((mppGroupType == MV_BOARD_OTHER) ||
- + (boardId == RD_88F6281A_ID) ||
- + (boardId == RD_88F6192A_ID) ||
- + (boardId == RD_88F6190A_ID) ||
- + (boardId == RD_88F6281A_PCAC_ID) ||
- + (boardId == SHEEVA_PLUG_ID))
- + mppVal = mvBoardMppGet(mppGroup);
- + else
- + {
- + mppVal = mppGroup1[mppGroupType][i];
- + i++;
- + }
- +
- + /* Group 2 is shared mpp[23:16] */
- + if (mppGroup == 2)
- + {
- + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
- + mppVal &= ~0xffff;
- + bootVal &= 0xffff;
- + mppVal |= bootVal;
- + }
- +
- + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
- + }
- + }
- +
- + if ((devId == MV_6192_DEV_ID) || (devId == MV_6190_DEV_ID))
- + return MV_OK;
- +
- + /* Mpp phase 3 */
- + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_2);
- + /* Read MPP group from board level and assign to MPP register */
- + i = 0;
- + for (mppGroup = 4; mppGroup < 7; mppGroup++)
- + {
- + if ((mppGroupType == MV_BOARD_OTHER) ||
- + (boardId == RD_88F6281A_ID) ||
- + (boardId == RD_88F6281A_PCAC_ID) ||
- + (boardId == SHEEVA_PLUG_ID))
- + mppVal = mvBoardMppGet(mppGroup);
- + else
- + {
- + mppVal = mppGroup2[mppGroupType][i];
- + i++;
- + }
- +
- + /* Group 4 is shared mpp[35:32] */
- + if (mppGroup == 4)
- + {
- + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
- + mppVal &= ~0xffff;
- + bootVal &= 0xffff;
- + mppVal |= bootVal;
- + }
- +
- + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
- + }
- + /* Update SSCG configuration register*/
- + if(mvBoardIdGet() == DB_88F6281A_BP_ID || mvBoardIdGet() == DB_88F6192A_BP_ID ||
- + mvBoardIdGet() == DB_88F6190A_BP_ID || mvBoardIdGet() == DB_88F6180A_BP_ID)
- + MV_REG_WRITE(0x100d8, 0x53);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCtrlMppRegGet - return reg address of mpp group
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* mppGroup - MPP group.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_U32 - Register address.
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)
- +{
- + MV_U32 ret;
- +
- + switch(mppGroup){
- + case (0): ret = MPP_CONTROL_REG0;
- + break;
- + case (1): ret = MPP_CONTROL_REG1;
- + break;
- + case (2): ret = MPP_CONTROL_REG2;
- + break;
- + case (3): ret = MPP_CONTROL_REG3;
- + break;
- + case (4): ret = MPP_CONTROL_REG4;
- + break;
- + case (5): ret = MPP_CONTROL_REG5;
- + break;
- + case (6): ret = MPP_CONTROL_REG6;
- + break;
- + default: ret = MPP_CONTROL_REG0;
- + break;
- + }
- + return ret;
- +}
- +#if defined(MV_INCLUDE_PEX)
- +/*******************************************************************************
- +* mvCtrlPexMaxIfGet - Get Marvell controller number of PEX interfaces.
- +*
- +* DESCRIPTION:
- +* This function returns Marvell controller number of PEX interfaces.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Marvell controller number of PEX interfaces. If controller
- +* ID is undefined the function returns '0'.
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
- +{
- +
- + return MV_PEX_MAX_IF;
- +}
- +#endif
- +
- +#if defined(MV_INCLUDE_GIG_ETH)
- +/*******************************************************************************
- +* mvCtrlEthMaxPortGet - Get Marvell controller number of etherent ports.
- +*
- +* DESCRIPTION:
- +* This function returns Marvell controller number of etherent port.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Marvell controller number of etherent port.
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlEthMaxPortGet(MV_VOID)
- +{
- + MV_U32 devId;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + return MV_6281_ETH_MAX_PORTS;
- + break;
- + case MV_6192_DEV_ID:
- + return MV_6192_ETH_MAX_PORTS;
- + break;
- + case MV_6190_DEV_ID:
- + return MV_6190_ETH_MAX_PORTS;
- + break;
- + case MV_6180_DEV_ID:
- + return MV_6180_ETH_MAX_PORTS;
- + break;
- + }
- + return 0;
- +
- +}
- +#endif
- +
- +#if defined(MV_INCLUDE_XOR)
- +/*******************************************************************************
- +* mvCtrlXorMaxChanGet - Get Marvell controller number of XOR channels.
- +*
- +* DESCRIPTION:
- +* This function returns Marvell controller number of XOR channels.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Marvell controller number of XOR channels.
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlXorMaxChanGet(MV_VOID)
- +{
- + return MV_XOR_MAX_CHAN;
- +}
- +#endif
- +
- +#if defined(MV_INCLUDE_USB)
- +/*******************************************************************************
- +* mvCtrlUsbHostMaxGet - Get number of Marvell Usb controllers
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* returns number of Marvell USB controllers.
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlUsbMaxGet(void)
- +{
- + return MV_USB_MAX_PORTS;
- +}
- +#endif
- +
- +
- +#if defined(MV_INCLUDE_NAND)
- +/*******************************************************************************
- +* mvCtrlNandSupport - Return if this controller has integrated NAND flash support
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if NAND is supported and MV_FALSE otherwise
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlNandSupport(MV_VOID)
- +{
- + MV_U32 devId;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + return MV_6281_NAND;
- + break;
- + case MV_6192_DEV_ID:
- + return MV_6192_NAND;
- + break;
- + case MV_6190_DEV_ID:
- + return MV_6190_NAND;
- + break;
- + case MV_6180_DEV_ID:
- + return MV_6180_NAND;
- + break;
- + }
- + return 0;
- +
- +}
- +#endif
- +
- +#if defined(MV_INCLUDE_SDIO)
- +/*******************************************************************************
- +* mvCtrlSdioSupport - Return if this controller has integrated SDIO flash support
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if SDIO is supported and MV_FALSE otherwise
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlSdioSupport(MV_VOID)
- +{
- + MV_U32 devId;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + return MV_6281_SDIO;
- + break;
- + case MV_6192_DEV_ID:
- + return MV_6192_SDIO;
- + break;
- + case MV_6190_DEV_ID:
- + return MV_6190_SDIO;
- + break;
- + case MV_6180_DEV_ID:
- + return MV_6180_SDIO;
- + break;
- + }
- + return 0;
- +
- +}
- +#endif
- +
- +#if defined(MV_INCLUDE_TS)
- +/*******************************************************************************
- +* mvCtrlTsSupport - Return if this controller has integrated TS flash support
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if TS is supported and MV_FALSE otherwise
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlTsSupport(MV_VOID)
- +{
- + MV_U32 devId;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + return MV_6281_TS;
- + break;
- + case MV_6192_DEV_ID:
- + return MV_6192_TS;
- + break;
- + case MV_6190_DEV_ID:
- + return MV_6190_TS;
- + break;
- + case MV_6180_DEV_ID:
- + return MV_6180_TS;
- + break;
- + }
- + return 0;
- +}
- +#endif
- +
- +#if defined(MV_INCLUDE_AUDIO)
- +/*******************************************************************************
- +* mvCtrlAudioSupport - Return if this controller has integrated AUDIO flash support
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if AUDIO is supported and MV_FALSE otherwise
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlAudioSupport(MV_VOID)
- +{
- + MV_U32 devId;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + return MV_6281_AUDIO;
- + break;
- + case MV_6192_DEV_ID:
- + return MV_6192_AUDIO;
- + break;
- + case MV_6190_DEV_ID:
- + return MV_6190_AUDIO;
- + break;
- + case MV_6180_DEV_ID:
- + return MV_6180_AUDIO;
- + break;
- + }
- + return 0;
- +
- +}
- +#endif
- +
- +#if defined(MV_INCLUDE_TDM)
- +/*******************************************************************************
- +* mvCtrlTdmSupport - Return if this controller has integrated TDM flash support
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if TDM is supported and MV_FALSE otherwise
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlTdmSupport(MV_VOID)
- +{
- + MV_U32 devId;
- +
- + devId = mvCtrlModelGet();
- +
- + switch(devId){
- + case MV_6281_DEV_ID:
- + return MV_6281_TDM;
- + break;
- + case MV_6192_DEV_ID:
- + return MV_6192_TDM;
- + break;
- + case MV_6190_DEV_ID:
- + return MV_6190_TDM;
- + break;
- + case MV_6180_DEV_ID:
- + return MV_6180_TDM;
- + break;
- + }
- + return 0;
- +
- +}
- +#endif
- +
- +/*******************************************************************************
- +* mvCtrlModelGet - Get Marvell controller device model (Id)
- +*
- +* DESCRIPTION:
- +* This function returns 16bit describing the device model (ID) as defined
- +* in PCI Device and Vendor ID configuration register offset 0x0.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 16bit desscribing Marvell controller ID
- +*
- +*******************************************************************************/
- +MV_U16 mvCtrlModelGet(MV_VOID)
- +{
- + MV_U32 devId;
- +
- + devId = MV_REG_READ(CHIP_BOND_REG);
- + devId &= PCKG_OPT_MASK;
- +
- + switch(devId){
- + case 2:
- + return MV_6281_DEV_ID;
- + break;
- + case 1:
- + if (((MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PEX_DEVICE_AND_VENDOR_ID))& 0xffff0000) >> 16)
- + == MV_6190_DEV_ID)
- + return MV_6190_DEV_ID;
- + else
- + return MV_6192_DEV_ID;
- + break;
- + case 0:
- + return MV_6180_DEV_ID;
- + break;
- + }
- +
- + return 0;
- +}
- +/*******************************************************************************
- +* mvCtrlRevGet - Get Marvell controller device revision number
- +*
- +* DESCRIPTION:
- +* This function returns 8bit describing the device revision as defined
- +* in PCI Express Class Code and Revision ID Register.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 8bit desscribing Marvell controller revision number
- +*
- +*******************************************************************************/
- +MV_U8 mvCtrlRevGet(MV_VOID)
- +{
- + MV_U8 revNum;
- +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
- + /* Check pex power state */
- + MV_U32 pexPower;
- + pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID,0);
- + if (pexPower == MV_FALSE)
- + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
- +#endif
- + revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PCI_CLASS_CODE_AND_REVISION_ID));
- +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
- + /* Return to power off state */
- + if (pexPower == MV_FALSE)
- + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
- +#endif
- + return ((revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS);
- +}
- +
- +/*******************************************************************************
- +* mvCtrlNameGet - Get Marvell controller name
- +*
- +* DESCRIPTION:
- +* This function returns a string describing the device model and revision.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
- +*
- +* RETURN:
- +*
- +* MV_ERROR if informantion can not be read.
- +*******************************************************************************/
- +MV_STATUS mvCtrlNameGet(char *pNameBuff)
- +{
- + mvOsSPrintf (pNameBuff, "%s%x Rev %d", SOC_NAME_PREFIX,
- + mvCtrlModelGet(), mvCtrlRevGet());
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCtrlModelRevGet - Get Controller Model (Device ID) and Revision
- +*
- +* DESCRIPTION:
- +* This function returns 32bit value describing both Device ID and Revision
- +* as defined in PCI Express Device and Vendor ID Register and device revision
- +* as defined in PCI Express Class Code and Revision ID Register.
- +
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit describing both controller device ID and revision number
- +*
- +*******************************************************************************/
- +MV_U32 mvCtrlModelRevGet(MV_VOID)
- +{
- + return ((mvCtrlModelGet() << 16) | mvCtrlRevGet());
- +}
- +
- +/*******************************************************************************
- +* mvCtrlModelRevNameGet - Get Marvell controller name
- +*
- +* DESCRIPTION:
- +* This function returns a string describing the device model and revision.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
- +*
- +* RETURN:
- +*
- +* MV_ERROR if informantion can not be read.
- +*******************************************************************************/
- +
- +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff)
- +{
- +
- + switch (mvCtrlModelRevGet())
- + {
- + case MV_6281_A0_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6281_A0_NAME);
- + break;
- + case MV_6192_A0_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6192_A0_NAME);
- + break;
- + case MV_6180_A0_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6180_A0_NAME);
- + break;
- + case MV_6190_A0_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6190_A0_NAME);
- + break;
- + case MV_6281_A1_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6281_A1_NAME);
- + break;
- + case MV_6192_A1_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6192_A1_NAME);
- + break;
- + case MV_6180_A1_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6180_A1_NAME);
- + break;
- + case MV_6190_A1_ID:
- + mvOsSPrintf (pNameBuff, "%s",MV_6190_A1_NAME);
- + break;
- + default:
- + mvCtrlNameGet(pNameBuff);
- + break;
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* ctrlWinOverlapTest - Test address windows for overlaping.
- +*
- +* DESCRIPTION:
- +* This function checks the given two address windows for overlaping.
- +*
- +* INPUT:
- +* pAddrWin1 - Address window 1.
- +* pAddrWin2 - Address window 2.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +* MV_TRUE if address window overlaps, MV_FALSE otherwise.
- +*******************************************************************************/
- +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
- +{
- + MV_U32 winBase1, winBase2;
- + MV_U32 winTop1, winTop2;
- +
- + /* check if we have overflow than 4G*/
- + if (((0xffffffff - pAddrWin1->baseLow) < pAddrWin1->size-1)||
- + ((0xffffffff - pAddrWin2->baseLow) < pAddrWin2->size-1))
- + {
- + return MV_TRUE;
- + }
- +
- + winBase1 = pAddrWin1->baseLow;
- + winBase2 = pAddrWin2->baseLow;
- + winTop1 = winBase1 + pAddrWin1->size-1;
- + winTop2 = winBase2 + pAddrWin2->size-1;
- +
- +
- + if (((winBase1 <= winTop2 ) && ( winTop2 <= winTop1)) ||
- + ((winBase1 <= winBase2) && (winBase2 <= winTop1)))
- + {
- + return MV_TRUE;
- + }
- + else
- + {
- + return MV_FALSE;
- + }
- +}
- +
- +/*******************************************************************************
- +* ctrlWinWithinWinTest - Test address windows for overlaping.
- +*
- +* DESCRIPTION:
- +* This function checks the given win1 boundries is within
- +* win2 boundries.
- +*
- +* INPUT:
- +* pAddrWin1 - Address window 1.
- +* pAddrWin2 - Address window 2.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +* MV_TRUE if found win1 inside win2, MV_FALSE otherwise.
- +*******************************************************************************/
- +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
- +{
- + MV_U32 winBase1, winBase2;
- + MV_U32 winTop1, winTop2;
- +
- + winBase1 = pAddrWin1->baseLow;
- + winBase2 = pAddrWin2->baseLow;
- + winTop1 = winBase1 + pAddrWin1->size -1;
- + winTop2 = winBase2 + pAddrWin2->size -1;
- +
- + if (((winBase1 >= winBase2 ) && ( winBase1 <= winTop2)) ||
- + ((winTop1 >= winBase2) && (winTop1 <= winTop2)))
- + {
- + return MV_TRUE;
- + }
- + else
- + {
- + return MV_FALSE;
- + }
- +}
- +
- +static const char* cntrlName[] = TARGETS_NAME_ARRAY;
- +
- +/*******************************************************************************
- +* mvCtrlTargetNameGet - Get Marvell controller target name
- +*
- +* DESCRIPTION:
- +* This function convert the trget enumeration to string.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Target name (const MV_8 *)
- +*******************************************************************************/
- +const MV_8* mvCtrlTargetNameGet( MV_TARGET target )
- +{
- +
- + if (target >= MAX_TARGETS)
- + {
- + return "target unknown";
- + }
- +
- + return cntrlName[target];
- +}
- +
- +/*******************************************************************************
- +* mvCtrlAddrDecShow - Print the Controller units address decode map.
- +*
- +* DESCRIPTION:
- +* This function the Controller units address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvCtrlAddrDecShow(MV_VOID)
- +{
- + mvCpuIfAddDecShow();
- + mvAhbToMbusAddDecShow();
- +#if defined(MV_INCLUDE_PEX)
- + mvPexAddrDecShow();
- +#endif
- +#if defined(MV_INCLUDE_USB)
- + mvUsbAddrDecShow();
- +#endif
- +#if defined(MV_INCLUDE_GIG_ETH)
- + mvEthAddrDecShow();
- +#endif
- +#if defined(MV_INCLUDE_XOR)
- + mvXorAddrDecShow();
- +#endif
- +#if defined(MV_INCLUDE_SATA)
- + mvSataAddrDecShow();
- +#endif
- +#if defined(MV_INCLUDE_AUDIO)
- + mvAudioAddrDecShow();
- +#endif
- +#if defined(MV_INCLUDE_TS)
- + mvTsuAddrDecShow();
- +#endif
- +}
- +
- +/*******************************************************************************
- +* ctrlSizeToReg - Extract size value for register assignment.
- +*
- +* DESCRIPTION:
- +* Address decode size parameter must be programed from LSB to MSB as
- +* sequence of 1's followed by sequence of 0's. The number of 1's
- +* specifies the size of the window in 64 KB granularity (e.g. a
- +* value of 0x00ff specifies 256x64k = 16 MB).
- +* This function extract the size value from the size parameter according
- +* to given aligment paramter. For example for size 0x1000000 (16MB) and
- +* aligment 0x10000 (64KB) the function will return 0x00FF.
- +*
- +* INPUT:
- +* size - Size.
- +* alignment - Size alignment. Note that alignment must be power of 2!
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit describing size register value correspond to size parameter.
- +* If value is '-1' size parameter or aligment are invalid.
- +*******************************************************************************/
- +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment)
- +{
- + MV_U32 retVal;
- +
- + /* Check size parameter alignment */
- + if ((0 == size) || (MV_IS_NOT_ALIGN(size, alignment)))
- + {
- + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size is zero or not aligned.\n"));
- + return -1;
- + }
- +
- + /* Take out the "alignment" portion out of the size parameter */
- + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
- + /* and size is 0x1000000 (16MB) for example */
- + while(alignment & 1) /* Check that alignmet LSB is set */
- + {
- + size = (size >> 1); /* If LSB is set, move 'size' one bit to right */
- + alignment = (alignment >> 1);
- + }
- +
- + /* If after the alignment first '0' was met we still have '1' in */
- + /* it then aligment is invalid (not power of 2) */
- + if (alignment)
- + {
- + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
- + (MV_U32)alignment));
- + return -1;
- + }
- +
- + /* Now the size is shifted right according to aligment: 0x0100 */
- + size--; /* Now the size is a sequance of '1': 0x00ff */
- +
- + retVal = size ;
- +
- + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
- + while(size & 1) /* Check that LSB is set */
- + {
- + size = (size >> 1); /* If LSB is set, move one bit to the right */
- + }
- +
- + if (size) /* Sequance of 1's is over. Check that we have no other 1's */
- + {
- + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size parameter 0x%x invalid.\n",
- + size));
- + return -1;
- + }
- +
- + return retVal;
- +
- +}
- +
- +/*******************************************************************************
- +* ctrlRegToSize - Extract size value from register value.
- +*
- +* DESCRIPTION:
- +* This function extract a size value from the register size parameter
- +* according to given aligment paramter. For example for register size
- +* value 0xff and aligment 0x10000 the function will return 0x01000000.
- +*
- +* INPUT:
- +* regSize - Size as in register format. See ctrlSizeToReg.
- +* alignment - Size alignment. Note that alignment must be power of 2!
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit describing size.
- +* If value is '-1' size parameter or aligment are invalid.
- +*******************************************************************************/
- +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment)
- +{
- + MV_U32 temp;
- +
- + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
- + temp = regSize; /* Now the size is a sequance of '1': 0x00ff */
- +
- + while(temp & 1) /* Check that LSB is set */
- + {
- + temp = (temp >> 1); /* If LSB is set, move one bit to the right */
- + }
- +
- + if (temp) /* Sequance of 1's is over. Check that we have no other 1's */
- + {
- + DB(mvOsPrintf("ctrlRegToSize: ERR. Size parameter 0x%x invalid.\n",
- + regSize));
- + return -1;
- + }
- +
- +
- + /* Check that aligment is a power of two */
- + temp = alignment - 1;/* Now the alignmet is a sequance of '1' (0xffff) */
- +
- + while(temp & 1) /* Check that alignmet LSB is set */
- + {
- + temp = (temp >> 1); /* If LSB is set, move 'size' one bit to right */
- + }
- +
- + /* If after the 'temp' first '0' was met we still have '1' in 'temp' */
- + /* then 'temp' is invalid (not power of 2) */
- + if (temp)
- + {
- + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
- + alignment));
- + return -1;
- + }
- +
- + regSize++; /* Now the size is 0x0100 */
- +
- + /* Add in the "alignment" portion to the register size parameter */
- + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
- +
- + while(alignment & 1) /* Check that alignmet LSB is set */
- + {
- + regSize = (regSize << 1); /* LSB is set, move 'size' one bit left */
- + alignment = (alignment >> 1);
- + }
- +
- + return regSize;
- +}
- +
- +
- +/*******************************************************************************
- +* ctrlSizeRegRoundUp - Round up given size
- +*
- +* DESCRIPTION:
- +* This function round up a given size to a size that fits the
- +* restrictions of size format given an aligment parameter.
- +* to given aligment paramter. For example for size parameter 0xa1000 and
- +* aligment 0x1000 the function will return 0xFF000.
- +*
- +* INPUT:
- +* size - Size.
- +* alignment - Size alignment. Note that alignment must be power of 2!
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit describing size value correspond to size in register.
- +*******************************************************************************/
- +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment)
- +{
- + MV_U32 msbBit = 0;
- + MV_U32 retSize;
- +
- + /* Check if size parameter is already comply with restriction */
- + if (!(-1 == ctrlSizeToReg(size, alignment)))
- + {
- + return size;
- + }
- +
- + while(size)
- + {
- + size = (size >> 1);
- + msbBit++;
- + }
- +
- + retSize = (1 << msbBit);
- +
- + if (retSize < alignment)
- + {
- + return alignment;
- + }
- + else
- + {
- + return retSize;
- + }
- +}
- +/*******************************************************************************
- +* mvCtrlSysRstLengthCounterGet - Return number of milliseconds the reset button
- +* was pressed and clear counter
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN: number of milliseconds the reset button was pressed
- +*******************************************************************************/
- +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID)
- +{
- + static volatile MV_U32 Count = 0;
- +
- + if(!Count) {
- + Count = (MV_REG_READ(SYSRST_LENGTH_COUNTER_REG) & SLCR_COUNT_MASK);
- + Count = (Count / (MV_BOARD_REFCLK_25MHZ / 1000));
- + /* clear counter for next boot */
- + MV_REG_BIT_SET(SYSRST_LENGTH_COUNTER_REG, SLCR_CLR_MASK);
- + }
- +
- + DB(mvOsPrintf("mvCtrlSysRstLengthCounterGet: Reset button was pressed for %u milliseconds\n", Count));
- +
- + return Count;
- +}
- +
- +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID)
- +{
- + MV_U32 satr = 0;
- + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + if(mvCtrlModelGet() == MV_6180_DEV_ID)
- + {
- + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_SPI_WITH_BOOTROM_6180)
- + return MV_TRUE;
- + else
- + return MV_FALSE;
- + }
- + satr = satr & MSAR_BOOT_MODE_MASK;
- + if (satr == MSAR_BOOT_SPI_WITH_BOOTROM)
- + return MV_TRUE;
- + else
- + return MV_FALSE;
- +}
- +
- +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID)
- +{
- + MV_U32 satr = 0;
- + if(mvCtrlModelGet() == MV_6180_DEV_ID)
- + return MV_FALSE;
- + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + satr = satr & MSAR_BOOT_MODE_MASK;
- +
- + if (satr == MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM)
- + return MV_TRUE;
- + else
- + return MV_FALSE;
- +}
- +
- +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID)
- +{
- + MV_U32 satr = 0;
- + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
- + if(mvCtrlModelGet() == MV_6180_DEV_ID)
- + {
- + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_NAND_WITH_BOOTROM_6180)
- + return MV_TRUE;
- + else
- + return MV_FALSE;
- + }
- + satr = satr & MSAR_BOOT_MODE_MASK;
- + if ((satr == MSAR_BOOT_NAND_WITH_BOOTROM))
- + return MV_TRUE;
- + else
- + return MV_FALSE;
- +}
- +
- +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
- +/*******************************************************************************
- +* mvCtrlPwrSaveOn - Set Power save mode
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*******************************************************************************/
- +MV_VOID mvCtrlPwrSaveOn(MV_VOID)
- +{
- + unsigned long old,temp;
- + /* Disable int */
- + __asm__ __volatile__("mrs %0, cpsr\n"
- + "orr %1, %0, #0xc0\n"
- + "msr cpsr_c, %1"
- + : "=r" (old), "=r" (temp)
- + :
- + : "memory");
- +
- + /* Set SoC in power save */
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, BIT11);
- + /* Wait for int */
- + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
- +
- + /* Enabled int */
- + __asm__ __volatile__("msr cpsr_c, %0"
- + :
- + : "r" (old)
- + : "memory");
- +}
- +
- +
- +
- +/*******************************************************************************
- +* mvCtrlPwrSaveOff - Go out of power save mode
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*******************************************************************************/
- +MV_VOID mvCtrlPwrSaveOff(MV_VOID)
- +{
- + unsigned long old,temp;
- + /* Disable int */
- + __asm__ __volatile__("mrs %0, cpsr\n"
- + "orr %1, %0, #0xc0\n"
- + "msr cpsr_c, %1"
- + : "=r" (old), "=r" (temp)
- + :
- + : "memory");
- +
- + /* Set SoC in power save */
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, BIT11);
- + /* Wait for int */
- + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
- +
- + /* Enabled int */
- + __asm__ __volatile__("msr cpsr_c, %0"
- + :
- + : "r" (old)
- + : "memory");
- +}
- +
- +/*******************************************************************************
- +* mvCtrlPwrClckSet - Set Power State for specific Unit
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*******************************************************************************/
- +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
- +{
- + switch (unitId)
- + {
- +#if defined(MV_INCLUDE_PEX)
- + case PEX_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_GIG_ETH)
- + case ETH_GIG_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_INTEG_SATA)
- + case SATA_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_CESA)
- + case CESA_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_USB)
- + case USB_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_AUDIO)
- + case AUDIO_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_TS)
- + case TS_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_SDIO)
- + case SDIO_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_TDM)
- + case TDM_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
- + }
- + break;
- +#endif
- +
- + default:
- +
- + break;
- +
- + }
- +}
- +
- +/*******************************************************************************
- +* mvCtrlPwrClckGet - Get Power State of specific Unit
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +******************************************************************************/
- +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index)
- +{
- + MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);
- + MV_BOOL state = MV_TRUE;
- +
- + switch (unitId)
- + {
- +#if defined(MV_INCLUDE_PEX)
- + case PEX_UNIT_ID:
- + if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- +
- + break;
- +#endif
- +#if defined(MV_INCLUDE_GIG_ETH)
- + case ETH_GIG_UNIT_ID:
- + if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_SATA)
- + case SATA_UNIT_ID:
- + if ((reg & PMC_SATASTOPCLOCK_MASK(index)) == PMC_SATASTOPCLOCK_STOP(index))
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_CESA)
- + case CESA_UNIT_ID:
- + if ((reg & PMC_SESTOPCLOCK_MASK) == PMC_SESTOPCLOCK_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_USB)
- + case USB_UNIT_ID:
- + if ((reg & PMC_USBSTOPCLOCK_MASK) == PMC_USBSTOPCLOCK_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_AUDIO)
- + case AUDIO_UNIT_ID:
- + if ((reg & PMC_AUDIOSTOPCLOCK_MASK) == PMC_AUDIOSTOPCLOCK_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_TS)
- + case TS_UNIT_ID:
- + if ((reg & PMC_TSSTOPCLOCK_MASK) == PMC_TSSTOPCLOCK_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_SDIO)
- + case SDIO_UNIT_ID:
- + if ((reg & PMC_SDIOSTOPCLOCK_MASK)== PMC_SDIOSTOPCLOCK_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_TDM)
- + case TDM_UNIT_ID:
- + if ((reg & PMC_TDMSTOPCLOCK_MASK) == PMC_TDMSTOPCLOCK_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +
- + default:
- + state = MV_TRUE;
- + break;
- + }
- +
- +
- + return state;
- +}
- +/*******************************************************************************
- +* mvCtrlPwrMemSet - Set Power State for memory on specific Unit
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*******************************************************************************/
- +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
- +{
- + switch (unitId)
- + {
- +#if defined(MV_INCLUDE_PEX)
- + case PEX_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_GIG_ETH)
- + case ETH_GIG_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
- + }
- + else
- + {
- + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_INTEG_SATA)
- + case SATA_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
- + }
- + else
- + {
- + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_CESA)
- + case CESA_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_USB)
- + case USB_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_AUDIO)
- + case AUDIO_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
- + }
- + else
- + {
- + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
- + }
- + break;
- +#endif
- +#if defined(MV_INCLUDE_XOR)
- + case XOR_UNIT_ID:
- + if (enable == MV_FALSE)
- + {
- + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
- + }
- + else
- + {
- + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
- + }
- + break;
- +#endif
- + default:
- +
- + break;
- +
- + }
- +}
- +
- +/*******************************************************************************
- +* mvCtrlPwrMemGet - Get Power State of memory on specific Unit
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +******************************************************************************/
- +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index)
- +{
- + MV_U32 reg = MV_REG_READ(POWER_MNG_MEM_CTRL_REG);
- + MV_BOOL state = MV_TRUE;
- +
- + switch (unitId)
- + {
- +#if defined(MV_INCLUDE_PEX)
- + case PEX_UNIT_ID:
- + if ((reg & PMC_PEXSTOPMEM_MASK) == PMC_PEXSTOPMEM_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- +
- + break;
- +#endif
- +#if defined(MV_INCLUDE_GIG_ETH)
- + case ETH_GIG_UNIT_ID:
- + if ((reg & PMC_GESTOPMEM_MASK(index)) == PMC_GESTOPMEM_STOP(index))
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_SATA)
- + case SATA_UNIT_ID:
- + if ((reg & PMC_SATASTOPMEM_MASK(index)) == PMC_SATASTOPMEM_STOP(index))
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_CESA)
- + case CESA_UNIT_ID:
- + if ((reg & PMC_SESTOPMEM_MASK) == PMC_SESTOPMEM_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_USB)
- + case USB_UNIT_ID:
- + if ((reg & PMC_USBSTOPMEM_MASK) == PMC_USBSTOPMEM_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_AUDIO)
- + case AUDIO_UNIT_ID:
- + if ((reg & PMC_AUDIOSTOPMEM_MASK) == PMC_AUDIOSTOPMEM_STOP)
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +#if defined(MV_INCLUDE_XOR)
- + case XOR_UNIT_ID:
- + if ((reg & PMC_XORSTOPMEM_MASK(index)) == PMC_XORSTOPMEM_STOP(index))
- + {
- + state = MV_FALSE;
- + }
- + else state = MV_TRUE;
- + break;
- +#endif
- +
- + default:
- + state = MV_TRUE;
- + break;
- + }
- +
- +
- + return state;
- +}
- +#else
- +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable) {return;}
- +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index) {return MV_TRUE;}
- +#endif /* #if defined(MV_INCLUDE_CLK_PWR_CNTRL) */
- +
- +
- +/*******************************************************************************
- +* mvMPPConfigToSPI - Change MPP[3:0] configuration to SPI mode
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +******************************************************************************/
- +MV_VOID mvMPPConfigToSPI(MV_VOID)
- +{
- + MV_U32 mppVal = 0;
- + MV_U32 bootVal = 0;
- +
- + if(!mvCtrlIsBootFromSPIUseNAND())
- + return;
- + mppVal = 0x00002220; /* Set MPP [3:1] to SPI mode */
- + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
- + bootVal &= 0xffff000f;
- + mppVal |= bootVal;
- +
- + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
- +}
- +
- +
- +/*******************************************************************************
- +* mvMPPConfigToDefault - Change MPP[7:0] configuration to default configuration
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +******************************************************************************/
- +MV_VOID mvMPPConfigToDefault(MV_VOID)
- +{
- + MV_U32 mppVal = 0;
- + MV_U32 bootVal = 0;
- +
- + if(!mvCtrlIsBootFromSPIUseNAND())
- + return;
- + mppVal = mvBoardMppGet(0);
- + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
- + mppVal &= ~0xffff000f;
- + bootVal &= 0xffff000f;
- + mppVal |= bootVal;
- +
- + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 2010-11-09 20:28:07.742495476 +0100
- @@ -0,0 +1,185 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvCtrlEnvLibh
- +#define __INCmvCtrlEnvLibh
- +
- +/* includes */
- +#include "mvSysHwConfig.h"
- +#include "mvCommon.h"
- +#include "mvTypes.h"
- +#include "mvOs.h"
- +#include "boardEnv/mvBoardEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +#include "ctrlEnv/mvCtrlEnvRegs.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +
- +/* typedefs */
- +
- +/* This enumerator describes the possible HW cache coherency policies the */
- +/* controllers supports. */
- +typedef enum _mvCachePolicy
- +{
- + NO_COHERENCY, /* No HW cache coherency support */
- + WT_COHERENCY, /* HW cache coherency supported in Write Through policy */
- + WB_COHERENCY /* HW cache coherency supported in Write Back policy */
- +}MV_CACHE_POLICY;
- +
- +
- +/* The swapping is referred to a 64-bit words (as this is the controller */
- +/* internal data path width). This enumerator describes the possible */
- +/* data swap types. Below is an example of the data 0x0011223344556677 */
- +typedef enum _mvSwapType
- +{
- + MV_BYTE_SWAP, /* Byte Swap 77 66 55 44 33 22 11 00 */
- + MV_NO_SWAP, /* No swapping 00 11 22 33 44 55 66 77 */
- + MV_BYTE_WORD_SWAP, /* Both byte and word swap 33 22 11 00 77 66 55 44 */
- + MV_WORD_SWAP, /* Word swap 44 55 66 77 00 11 22 33 */
- + SWAP_TYPE_MAX /* Delimiter for this enumerator */
- +}MV_SWAP_TYPE;
- +
- +/* This structure describes access rights for Access protection windows */
- +/* that can be found in IDMA, XOR, Ethernet and MPSC units. */
- +/* Note that the permission enumerator coresponds to its register format. */
- +/* For example, Read only premission is presented as "1" in register field. */
- +typedef enum _mvAccessRights
- +{
- + NO_ACCESS_ALLOWED = 0, /* No access allowed */
- + READ_ONLY = 1, /* Read only permission */
- + ACC_RESERVED = 2, /* Reserved access right */
- + FULL_ACCESS = 3, /* Read and Write permission */
- + MAX_ACC_RIGHTS
- +}MV_ACCESS_RIGHTS;
- +
- +
- +/* mcspLib.h API list */
- +
- +MV_STATUS mvCtrlEnvInit(MV_VOID);
- +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup);
- +
- +#if defined(MV_INCLUDE_PEX)
- +MV_U32 mvCtrlPexMaxIfGet(MV_VOID);
- +#else
- +#define mvCtrlPexMaxIfGet() (0)
- +#endif
- +
- +#define mvCtrlPciIfMaxIfGet() (0)
- +
- +#if defined(MV_INCLUDE_GIG_ETH)
- +MV_U32 mvCtrlEthMaxPortGet(MV_VOID);
- +#endif
- +#if defined(MV_INCLUDE_XOR)
- +MV_U32 mvCtrlXorMaxChanGet(MV_VOID);
- +#endif
- +#if defined(MV_INCLUDE_USB)
- +MV_U32 mvCtrlUsbMaxGet(MV_VOID);
- +#endif
- +#if defined(MV_INCLUDE_NAND)
- +MV_U32 mvCtrlNandSupport(MV_VOID);
- +#endif
- +#if defined(MV_INCLUDE_SDIO)
- +MV_U32 mvCtrlSdioSupport(MV_VOID);
- +#endif
- +#if defined(MV_INCLUDE_TS)
- +MV_U32 mvCtrlTsSupport(MV_VOID);
- +#endif
- +#if defined(MV_INCLUDE_AUDIO)
- +MV_U32 mvCtrlAudioSupport(MV_VOID);
- +#endif
- +#if defined(MV_INCLUDE_TDM)
- +MV_U32 mvCtrlTdmSupport(MV_VOID);
- +#endif
- +
- +MV_U16 mvCtrlModelGet(MV_VOID);
- +MV_U8 mvCtrlRevGet(MV_VOID);
- +MV_STATUS mvCtrlNameGet(char *pNameBuff);
- +MV_U32 mvCtrlModelRevGet(MV_VOID);
- +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff);
- +MV_VOID mvCtrlAddrDecShow(MV_VOID);
- +const MV_8* mvCtrlTargetNameGet(MV_TARGET target);
- +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment);
- +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment);
- +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment);
- +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID);
- +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
- +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
- +
- +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
- +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index);
- +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
- +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID);
- +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID);
- +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID);
- +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
- +MV_VOID mvCtrlPwrSaveOn(MV_VOID);
- +MV_VOID mvCtrlPwrSaveOff(MV_VOID);
- +#endif
- +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
- +MV_VOID mvMPPConfigToSPI(MV_VOID);
- +MV_VOID mvMPPConfigToDefault(MV_VOID);
- +
- +
- +#endif /* __INCmvCtrlEnvLibh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 2010-11-09 20:28:07.772495664 +0100
- @@ -0,0 +1,419 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvCtrlEnvRegsh
- +#define __INCmvCtrlEnvRegsh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* CV Support */
- +#define PEX0_MEM0 PEX0_MEM
- +#define PCI0_MEM0 PEX0_MEM
- +
- +/* Controller revision info */
- +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
- +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
- +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
- +
- +/* Controler environment registers offsets */
- +
- +/* Power Managment Control */
- +#define POWER_MNG_MEM_CTRL_REG 0x20118
- +
- +#define PMC_GESTOPMEM_OFFS(port) ((port)? 13 : 0)
- +#define PMC_GESTOPMEM_MASK(port) (1 << PMC_GESTOPMEM_OFFS(port))
- +#define PMC_GESTOPMEM_EN(port) (0 << PMC_GESTOPMEM_OFFS(port))
- +#define PMC_GESTOPMEM_STOP(port) (1 << PMC_GESTOPMEM_OFFS(port))
- +
- +#define PMC_PEXSTOPMEM_OFFS 1
- +#define PMC_PEXSTOPMEM_MASK (1 << PMC_PEXSTOPMEM_OFFS)
- +#define PMC_PEXSTOPMEM_EN (0 << PMC_PEXSTOPMEM_OFFS)
- +#define PMC_PEXSTOPMEM_STOP (1 << PMC_PEXSTOPMEM_OFFS)
- +
- +#define PMC_USBSTOPMEM_OFFS 2
- +#define PMC_USBSTOPMEM_MASK (1 << PMC_USBSTOPMEM_OFFS)
- +#define PMC_USBSTOPMEM_EN (0 << PMC_USBSTOPMEM_OFFS)
- +#define PMC_USBSTOPMEM_STOP (1 << PMC_USBSTOPMEM_OFFS)
- +
- +#define PMC_DUNITSTOPMEM_OFFS 3
- +#define PMC_DUNITSTOPMEM_MASK (1 << PMC_DUNITSTOPMEM_OFFS)
- +#define PMC_DUNITSTOPMEM_EN (0 << PMC_DUNITSTOPMEM_OFFS)
- +#define PMC_DUNITSTOPMEM_STOP (1 << PMC_DUNITSTOPMEM_OFFS)
- +
- +#define PMC_RUNITSTOPMEM_OFFS 4
- +#define PMC_RUNITSTOPMEM_MASK (1 << PMC_RUNITSTOPMEM_OFFS)
- +#define PMC_RUNITSTOPMEM_EN (0 << PMC_RUNITSTOPMEM_OFFS)
- +#define PMC_RUNITSTOPMEM_STOP (1 << PMC_RUNITSTOPMEM_OFFS)
- +
- +#define PMC_XORSTOPMEM_OFFS(port) (5+(port*2))
- +#define PMC_XORSTOPMEM_MASK(port) (1 << PMC_XORSTOPMEM_OFFS(port))
- +#define PMC_XORSTOPMEM_EN(port) (0 << PMC_XORSTOPMEM_OFFS(port))
- +#define PMC_XORSTOPMEM_STOP(port) (1 << PMC_XORSTOPMEM_OFFS(port))
- +
- +#define PMC_SATASTOPMEM_OFFS(port) (6+(port*5))
- +#define PMC_SATASTOPMEM_MASK(port) (1 << PMC_SATASTOPMEM_OFFS(port))
- +#define PMC_SATASTOPMEM_EN(port) (0 << PMC_SATASTOPMEM_OFFS(port))
- +#define PMC_SATASTOPMEM_STOP(port) (1 << PMC_SATASTOPMEM_OFFS(port))
- +
- +#define PMC_SESTOPMEM_OFFS 8
- +#define PMC_SESTOPMEM_MASK (1 << PMC_SESTOPMEM_OFFS)
- +#define PMC_SESTOPMEM_EN (0 << PMC_SESTOPMEM_OFFS)
- +#define PMC_SESTOPMEM_STOP (1 << PMC_SESTOPMEM_OFFS)
- +
- +#define PMC_AUDIOSTOPMEM_OFFS 9
- +#define PMC_AUDIOSTOPMEM_MASK (1 << PMC_AUDIOSTOPMEM_OFFS)
- +#define PMC_AUDIOSTOPMEM_EN (0 << PMC_AUDIOSTOPMEM_OFFS)
- +#define PMC_AUDIOSTOPMEM_STOP (1 << PMC_AUDIOSTOPMEM_OFFS)
- +
- +#define POWER_MNG_CTRL_REG 0x2011C
- +
- +#define PMC_GESTOPCLOCK_OFFS(port) ((port)? 19 : 0)
- +#define PMC_GESTOPCLOCK_MASK(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
- +#define PMC_GESTOPCLOCK_EN(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
- +#define PMC_GESTOPCLOCK_STOP(port) (0 << PMC_GESTOPCLOCK_OFFS(port))
- +
- +#define PMC_PEXPHYSTOPCLOCK_OFFS 1
- +#define PMC_PEXPHYSTOPCLOCK_MASK (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
- +#define PMC_PEXPHYSTOPCLOCK_EN (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
- +#define PMC_PEXPHYSTOPCLOCK_STOP (0 << PMC_PEXPHYSTOPCLOCK_OFFS)
- +
- +#define PMC_PEXSTOPCLOCK_OFFS 2
- +#define PMC_PEXSTOPCLOCK_MASK (1 << PMC_PEXSTOPCLOCK_OFFS)
- +#define PMC_PEXSTOPCLOCK_EN (1 << PMC_PEXSTOPCLOCK_OFFS)
- +#define PMC_PEXSTOPCLOCK_STOP (0 << PMC_PEXSTOPCLOCK_OFFS)
- +
- +#define PMC_USBSTOPCLOCK_OFFS 3
- +#define PMC_USBSTOPCLOCK_MASK (1 << PMC_USBSTOPCLOCK_OFFS)
- +#define PMC_USBSTOPCLOCK_EN (1 << PMC_USBSTOPCLOCK_OFFS)
- +#define PMC_USBSTOPCLOCK_STOP (0 << PMC_USBSTOPCLOCK_OFFS)
- +
- +#define PMC_SDIOSTOPCLOCK_OFFS 4
- +#define PMC_SDIOSTOPCLOCK_MASK (1 << PMC_SDIOSTOPCLOCK_OFFS)
- +#define PMC_SDIOSTOPCLOCK_EN (1 << PMC_SDIOSTOPCLOCK_OFFS)
- +#define PMC_SDIOSTOPCLOCK_STOP (0 << PMC_SDIOSTOPCLOCK_OFFS)
- +
- +#define PMC_TSSTOPCLOCK_OFFS 5
- +#define PMC_TSSTOPCLOCK_MASK (1 << PMC_TSSTOPCLOCK_OFFS)
- +#define PMC_TSSTOPCLOCK_EN (1 << PMC_TSSTOPCLOCK_OFFS)
- +#define PMC_TSSTOPCLOCK_STOP (0 << PMC_TSSTOPCLOCK_OFFS)
- +
- +#define PMC_AUDIOSTOPCLOCK_OFFS 9
- +#define PMC_AUDIOSTOPCLOCK_MASK (1 << PMC_AUDIOSTOPCLOCK_OFFS)
- +#define PMC_AUDIOSTOPCLOCK_EN (1 << PMC_AUDIOSTOPCLOCK_OFFS)
- +#define PMC_AUDIOSTOPCLOCK_STOP (0 << PMC_AUDIOSTOPCLOCK_OFFS)
- +
- +#define PMC_POWERSAVE_OFFS 11
- +#define PMC_POWERSAVE_MASK (1 << PMC_POWERSAVE_OFFS)
- +#define PMC_POWERSAVE_EN (1 << PMC_POWERSAVE_OFFS)
- +#define PMC_POWERSAVE_STOP (0 << PMC_POWERSAVE_OFFS)
- +
- +
- +
- +
- +#define PMC_SATASTOPCLOCK_OFFS(port) (14+(port))
- +#define PMC_SATASTOPCLOCK_MASK(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
- +#define PMC_SATASTOPCLOCK_EN(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
- +#define PMC_SATASTOPCLOCK_STOP(port) (0 << PMC_SATASTOPCLOCK_OFFS(port))
- +
- +#define PMC_SESTOPCLOCK_OFFS 17
- +#define PMC_SESTOPCLOCK_MASK (1 << PMC_SESTOPCLOCK_OFFS)
- +#define PMC_SESTOPCLOCK_EN (1 << PMC_SESTOPCLOCK_OFFS)
- +#define PMC_SESTOPCLOCK_STOP (0 << PMC_SESTOPCLOCK_OFFS)
- +
- +#define PMC_TDMSTOPCLOCK_OFFS 20
- +#define PMC_TDMSTOPCLOCK_MASK (1 << PMC_TDMSTOPCLOCK_OFFS)
- +#define PMC_TDMSTOPCLOCK_EN (1 << PMC_TDMSTOPCLOCK_OFFS)
- +#define PMC_TDMSTOPCLOCK_STOP (0 << PMC_TDMSTOPCLOCK_OFFS)
- +
- +
- +/* Controler environment registers offsets */
- +#define MPP_CONTROL_REG0 0x10000
- +#define MPP_CONTROL_REG1 0x10004
- +#define MPP_CONTROL_REG2 0x10008
- +#define MPP_CONTROL_REG3 0x1000C
- +#define MPP_CONTROL_REG4 0x10010
- +#define MPP_CONTROL_REG5 0x10014
- +#define MPP_CONTROL_REG6 0x10018
- +#define MPP_SAMPLE_AT_RESET 0x10030
- +#define CHIP_BOND_REG 0x10034
- +#define SYSRST_LENGTH_COUNTER_REG 0x10050
- +#define SLCR_COUNT_OFFS 0
- +#define SLCR_COUNT_MASK (0x1FFFFFFF << SLCR_COUNT_OFFS)
- +#define SLCR_CLR_OFFS 31
- +#define SLCR_CLR_MASK (1 << SLCR_CLR_OFFS)
- +#define PCKG_OPT_MASK 0x3
- +#define MPP_OUTPUT_DRIVE_REG 0x100E0
- +#define MPP_RGMII0_OUTPUT_DRIVE_OFFS 7
- +#define MPP_3_3_RGMII0_OUTPUT_DRIVE (0x0 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
- +#define MPP_1_8_RGMII0_OUTPUT_DRIVE (0x1 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
- +#define MPP_RGMII1_OUTPUT_DRIVE_OFFS 15
- +#define MPP_3_3_RGMII1_OUTPUT_DRIVE (0x0 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
- +#define MPP_1_8_RGMII1_OUTPUT_DRIVE (0x1 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
- +
- +#define MSAR_BOOT_MODE_OFFS 12
- +#define MSAR_BOOT_MODE_MASK (0x7 << MSAR_BOOT_MODE_OFFS)
- +#define MSAR_BOOT_NAND_WITH_BOOTROM (0x5 << MSAR_BOOT_MODE_OFFS)
- +#define MSAR_BOOT_SPI_WITH_BOOTROM (0x4 << MSAR_BOOT_MODE_OFFS)
- +#define MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM (0x2 << MSAR_BOOT_MODE_OFFS)
- +
- +#define MSAR_BOOT_MODE_6180(X) (((X & 0x3000) >> 12) | \
- + ((X & 0x2) << 1))
- +#define MSAR_BOOT_SPI_WITH_BOOTROM_6180 0x1
- +#define MSAR_BOOT_NAND_WITH_BOOTROM_6180 0x5
- +
- +#define MSAR_TCLCK_OFFS 21
- +#define MSAR_TCLCK_MASK (0x1 << MSAR_TCLCK_OFFS)
- +#define MSAR_TCLCK_166 (0x1 << MSAR_TCLCK_OFFS)
- +#define MSAR_TCLCK_200 (0x0 << MSAR_TCLCK_OFFS)
- +
- +
- +#define MSAR_CPUCLCK_EXTRACT(X) (((X & 0x2) >> 1) | ((X & 0x400000) >> 21) | \
- + ((X & 0x18) >> 1))
- +
- +#define MSAR_CPUCLCK_OFFS_6180 2
- +#define MSAR_CPUCLCK_MASK_6180 (0x7 << MSAR_CPUCLCK_OFFS_6180)
- +
- +#define MSAR_DDRCLCK_RTIO_OFFS 5
- +#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
- +
- +#define MSAR_L2CLCK_EXTRACT(X) (((X & 0x600) >> 9) | ((X & 0x80000) >> 17))
- +
- +#ifndef MV_ASMLANGUAGE
- +/* CPU clock for 6281,6192 0->Resereved */
- +#define MV_CPU_CLCK_TBL { 0, 0, 0, 0, \
- + 600000000, 0, 800000000, 1000000000, \
- + 0, 1200000000, 0, 0, \
- + 1500000000, 0, 0, 0}
- +
- +/* DDR clock RATIO for 6281,6192 {0,0}->Reserved */
- +#define MV_DDR_CLCK_RTIO_TBL {\
- + {0, 0}, {0, 0}, {2, 1}, {0, 0}, \
- + {3, 1}, {0, 0}, {4, 1}, {9, 2}, \
- + {5, 1}, {6, 1}, {0, 0}, {0, 0}, \
- + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
- +}
- +
- +/* L2 clock RATIO for 6281,6192 {1,1}->Reserved */
- +#define MV_L2_CLCK_RTIO_TBL {\
- + {0, 0}, {2, 1}, {0, 0}, {3, 1}, \
- + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
- +}
- +
- +/* 6180 have different clk reset sampling */
- +/* ARM CPU, DDR, L2 clock for 6180 {0,0,0}->Reserved */
- +#define MV_CPU6180_DDR_L2_CLCK_TBL { \
- + {0, 0, 0 },\
- + {0, 0, 0 },\
- + {0, 0, 0 },\
- + {0, 0, 0 },\
- + {0, 0, 0 },\
- + {600000000, 200000000, 300000000 },\
- + {800000000, 200000000, 400000000 },\
- + {0, 0, 0 }\
- +}
- +
- +
- +
- +/* These macros help units to identify a target Mbus Arbiter group */
- +#define MV_TARGET_IS_DRAM(target) \
- + ((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
- +
- +#define MV_TARGET_IS_PEX0(target) \
- + ((target >= PEX0_MEM) && (target <= PEX0_IO))
- +
- +#define MV_TARGET_IS_PEX1(target) 0
- +
- +#define MV_TARGET_IS_PEX(target) (MV_TARGET_IS_PEX0(target) || MV_TARGET_IS_PEX1(target))
- +
- +#define MV_TARGET_IS_DEVICE(target) \
- + ((target >= DEVICE_CS0) && (target <= DEVICE_CS3))
- +
- +#define MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar) 0
- +
- +#define MV_TARGET_IS_AS_BOOT(target) ((target) == (sampleAtResetTargetArray[ \
- + (mvCtrlModelGet() == MV_6180_DEV_ID)? MSAR_BOOT_MODE_6180 \
- + (MV_REG_READ(MPP_SAMPLE_AT_RESET)):((MV_REG_READ(MPP_SAMPLE_AT_RESET)\
- + & MSAR_BOOT_MODE_MASK) >> MSAR_BOOT_MODE_OFFS)]))
- +
- +
- +#define MV_CHANGE_BOOT_CS(target) (((target) == DEV_BOOCS)?\
- + sampleAtResetTargetArray[(mvCtrlModelGet() == MV_6180_DEV_ID)? \
- + MSAR_BOOT_MODE_6180(MV_REG_READ(MPP_SAMPLE_AT_RESET)): \
- + ((MV_REG_READ(MPP_SAMPLE_AT_RESET) & MSAR_BOOT_MODE_MASK)\
- + >> MSAR_BOOT_MODE_OFFS)]:(target))
- +
- +#define TCLK_TO_COUNTER_RATIO 1 /* counters running in Tclk */
- +
- +#define BOOT_TARGETS_NAME_ARRAY { \
- + TBL_TERM, \
- + TBL_TERM, \
- + BOOT_ROM_CS, \
- + TBL_TERM, \
- + BOOT_ROM_CS, \
- + BOOT_ROM_CS, \
- + TBL_TERM, \
- + TBL_TERM \
- +}
- +
- +#define BOOT_TARGETS_NAME_ARRAY_6180 { \
- + TBL_TERM, \
- + BOOT_ROM_CS, \
- + TBL_TERM, \
- + TBL_TERM, \
- + TBL_TERM, \
- + BOOT_ROM_CS, \
- + TBL_TERM, \
- + TBL_TERM \
- +}
- +
- +
- +/* For old competability */
- +#define DEVICE_CS0 NFLASH_CS
- +#define DEVICE_CS1 SPI_CS
- +#define DEVICE_CS2 BOOT_ROM_CS
- +#define DEVICE_CS3 DEV_BOOCS
- +#define MV_BOOTDEVICE_INDEX 0
- +
- +#define START_DEV_CS DEV_CS0
- +#define DEV_TO_TARGET(dev) ((dev) + DEVICE_CS0)
- +
- +#define PCI_IF0_MEM0 PEX0_MEM
- +#define PCI_IF0_IO PEX0_IO
- +
- +
- +/* This enumerator defines the Marvell controller target ID */
- +typedef enum _mvTargetId
- +{
- + DRAM_TARGET_ID = 0 , /* Port 0 -> DRAM interface */
- + DEV_TARGET_ID = 1, /* Port 1 -> Nand/SPI */
- + PEX0_TARGET_ID = 4 , /* Port 4 -> PCI Express0 */
- + CRYPT_TARGET_ID = 3 , /* Port 3 --> Crypto Engine */
- + SAGE_TARGET_ID = 12 , /* Port 12 -> SAGE Unit */
- + MAX_TARGETS_ID
- +}MV_TARGET_ID;
- +
- +
- +/* This enumerator described the possible Controller paripheral targets. */
- +/* Controller peripherals are designated memory/IO address spaces that the */
- +/* controller can access. They are also refered as "targets" */
- +typedef enum _mvTarget
- +{
- + TBL_TERM = -1, /* none valid target, used as targets list terminator*/
- + SDRAM_CS0, /* SDRAM chip select 0 */
- + SDRAM_CS1, /* SDRAM chip select 1 */
- + SDRAM_CS2, /* SDRAM chip select 2 */
- + SDRAM_CS3, /* SDRAM chip select 3 */
- + PEX0_MEM, /* PCI Express 0 Memory */
- + PEX0_IO, /* PCI Express 0 IO */
- + INTER_REGS, /* Internal registers */
- + NFLASH_CS, /* NFLASH_CS */
- + SPI_CS, /* SPI_CS */
- + BOOT_ROM_CS, /* BOOT_ROM_CS */
- + DEV_BOOCS, /* DEV_BOOCS */
- + CRYPT_ENG, /* Crypto Engine */
- +#ifdef MV_INCLUDE_SAGE
- + SAGE_UNIT, /* SAGE Unit */
- +#endif
- + MAX_TARGETS
- +
- +}MV_TARGET;
- +
- +#define TARGETS_DEF_ARRAY { \
- + {0x0E, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
- + {0x0D, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
- + {0x0B, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
- + {0x07, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
- + {0xE8, PEX0_TARGET_ID }, /* PEX0_MEM */ \
- + {0xE0, PEX0_TARGET_ID }, /* PEX0_IO */ \
- + {0xFF, 0xFF }, /* INTER_REGS */ \
- + {0x2F, DEV_TARGET_ID }, /* NFLASH_CS */ \
- + {0x1E, DEV_TARGET_ID }, /* SPI_CS */ \
- + {0x1D, DEV_TARGET_ID }, /* BOOT_ROM_CS */ \
- + {0x1E, DEV_TARGET_ID }, /* DEV_BOOCS */ \
- + {0x01, CRYPT_TARGET_ID}, /* CRYPT_ENG */ \
- + {0x00, SAGE_TARGET_ID } \
- +}
- +
- +
- +#define TARGETS_NAME_ARRAY { \
- + "SDRAM_CS0", /* SDRAM_CS0 */ \
- + "SDRAM_CS1", /* SDRAM_CS1 */ \
- + "SDRAM_CS2", /* SDRAM_CS2 */ \
- + "SDRAM_CS3", /* SDRAM_CS3 */ \
- + "PEX0_MEM", /* PEX0_MEM */ \
- + "PEX0_IO", /* PEX0_IO */ \
- + "INTER_REGS", /* INTER_REGS */ \
- + "NFLASH_CS", /* NFLASH_CS */ \
- + "SPI_CS", /* SPI_CS */ \
- + "BOOT_ROM_CS", /* BOOT_ROM_CS */ \
- + "DEV_BOOTCS", /* DEV_BOOCS */ \
- + "CRYPT_ENG", /* CRYPT_ENG */ \
- + "SAGE_UNIT" /* SAGE_UNIT */ \
- +}
- +#endif /* MV_ASMLANGUAGE */
- +
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 2010-11-09 20:28:07.802495420 +0100
- @@ -0,0 +1,257 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvCtrlEnvSpech
- +#define __INCmvCtrlEnvSpech
- +
- +#include "mvDeviceId.h"
- +#include "mvSysHwConfig.h"
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +#define MV_ARM_SOC
- +#define SOC_NAME_PREFIX "MV88F"
- +
- +
- +/* units base and port numbers */
- +#ifdef MV_ASMLANGUAGE
- +#define XOR_UNIT_BASE(unit) 0x60800
- +#else
- +#define MV_XOR_REG_BASE 0x60000
- +#define XOR_UNIT_BASE(unit) ((unit)? 0x60900:0x60800)
- +#endif
- +
- +#define TDM_REG_BASE 0xD0000
- +#define USB_REG_BASE(dev) 0x50000
- +#define AUDIO_REG_BASE 0xA0000
- +#define SATA_REG_BASE 0x80000
- +#define MV_CESA_REG_BASE 0x3D000
- +#define MV_CESA_TDMA_REG_BASE 0x30000
- +#define MV_SDIO_REG_BASE 0x90000
- +#define MV_ETH_REG_BASE(port) (((port) == 0) ? 0x72000 : 0x76000)
- +#define MV_UART_CHAN_BASE(chanNum) (0x12000 + (chanNum * 0x100))
- +#define DRAM_BASE 0x0
- +#define CNTMR_BASE 0x20300
- +#define TWSI_SLAVE_BASE(chanNum) 0x11000
- +#define PEX_IF_BASE(pexIf) 0x40000
- +#define MPP_REG_BASE 0x10000
- +#define TSU_GLOBAL_REG_BASE 0xB4000
- +#define MAX_AHB_TO_MBUS_REG_BASE 0x20000
- +
- +#define INTER_REGS_SIZE _1M
- +/* This define describes the TWSI interrupt bit and location */
- +#define TWSI_CPU_MAIN_INT_CAUSE_REG 0x20200
- +#define TWSI0_CPU_MAIN_INT_BIT (1<<29)
- +#define TWSI_SPEED 100000
- +
- +#define MV_GPP_MAX_GROUP 2
- +#define MV_CNTMR_MAX_COUNTER 2
- +#define MV_UART_MAX_CHAN 2
- +#define MV_XOR_MAX_UNIT 2
- +#define MV_XOR_MAX_CHAN 4 /* total channels for all units together*/
- +#define MV_XOR_MAX_CHAN_PER_UNIT 2 /* channels for units */
- +#define MV_SATA_MAX_CHAN 2
- +
- +#define MV_6281_MPP_MAX_MODULE 2
- +#define MV_6192_MPP_MAX_MODULE 1
- +#define MV_6190_MPP_MAX_MODULE 1
- +#define MV_6180_MPP_MAX_MODULE 2
- +#define MV_6281_MPP_MAX_GROUP 7
- +#define MV_6192_MPP_MAX_GROUP 4
- +#define MV_6190_MPP_MAX_GROUP 4
- +#define MV_6180_MPP_MAX_GROUP 3
- +
- +#define MV_DRAM_MAX_CS 4
- +
- +/* This define describes the maximum number of supported PCI\PCIX Interfaces*/
- +#define MV_PCI_MAX_IF 0
- +#define MV_PCI_START_IF 0
- +
- +/* This define describes the maximum number of supported PEX Interfaces */
- +#define MV_INCLUDE_PEX0
- +#define MV_DISABLE_PEX_DEVICE_BAR
- +#define MV_PEX_MAX_IF 1
- +#define MV_PEX_START_IF MV_PCI_MAX_IF
- +
- +/* This define describes the maximum number of supported PCI Interfaces */
- +#define MV_PCI_IF_MAX_IF (MV_PEX_MAX_IF+MV_PCI_MAX_IF)
- +
- +#define MV_ETH_MAX_PORTS 2
- +#define MV_6281_ETH_MAX_PORTS 2
- +#define MV_6192_ETH_MAX_PORTS 2
- +#define MV_6190_ETH_MAX_PORTS 1
- +#define MV_6180_ETH_MAX_PORTS 1
- +
- +#define MV_IDMA_MAX_CHAN 0
- +
- +#define MV_USB_MAX_PORTS 1
- +
- +#define MV_USB_VERSION 1
- +
- +
- +#define MV_6281_NAND 1
- +#define MV_6192_NAND 1
- +#define MV_6190_NAND 1
- +#define MV_6180_NAND 0
- +
- +#define MV_6281_SDIO 1
- +#define MV_6192_SDIO 1
- +#define MV_6190_SDIO 1
- +#define MV_6180_SDIO 1
- +
- +#define MV_6281_TS 1
- +#define MV_6192_TS 1
- +#define MV_6190_TS 0
- +#define MV_6180_TS 0
- +
- +#define MV_6281_AUDIO 1
- +#define MV_6192_AUDIO 1
- +#define MV_6190_AUDIO 0
- +#define MV_6180_AUDIO 1
- +
- +#define MV_6281_TDM 1
- +#define MV_6192_TDM 1
- +#define MV_6190_TDM 0
- +#define MV_6180_TDM 0
- +
- +#define MV_DEVICE_MAX_CS 4
- +
- +/* Others */
- +#define PEX_HOST_BUS_NUM(pciIf) (pciIf)
- +#define PEX_HOST_DEV_NUM(pciIf) 0
- +
- +#define PCI_IO(pciIf) (PEX0_IO)
- +#define PCI_MEM(pciIf, memNum) (PEX0_MEM0)
- +/* CESA version #2: One channel, 2KB SRAM, TDMA */
- +#if defined(MV_CESA_CHAIN_MODE_SUPPORT)
- + #define MV_CESA_VERSION 3
- +#else
- +#define MV_CESA_VERSION 2
- +#endif
- +#define MV_CESA_SRAM_SIZE 2*1024
- +/* This define describes the maximum number of supported Ethernet ports */
- +#define MV_ETH_VERSION 4
- +#define MV_ETH_MAX_RXQ 8
- +#define MV_ETH_MAX_TXQ 8
- +#define MV_ETH_PORT_SGMII { MV_FALSE, MV_FALSE }
- +/* This define describes the the support of USB */
- +#define MV_USB_VERSION 1
- +
- +#define MV_INCLUDE_SDRAM_CS0
- +#define MV_INCLUDE_SDRAM_CS1
- +#define MV_INCLUDE_SDRAM_CS2
- +#define MV_INCLUDE_SDRAM_CS3
- +
- +#define MV_INCLUDE_DEVICE_CS0
- +#define MV_INCLUDE_DEVICE_CS1
- +#define MV_INCLUDE_DEVICE_CS2
- +#define MV_INCLUDE_DEVICE_CS3
- +
- +#define MPP_GROUP_1_TYPE {\
- + {0, 0, 0}, /* Reserved for AUTO */ \
- + {0x22220000, 0x22222222, 0x2222}, /* TDM */ \
- + {0x44440000, 0x00044444, 0x0000}, /* AUDIO */ \
- + {0x33330000, 0x33003333, 0x0033}, /* RGMII */ \
- + {0x33330000, 0x03333333, 0x0033}, /* GMII */ \
- + {0x11110000, 0x11111111, 0x0001}, /* TS */ \
- + {0x33330000, 0x33333333, 0x3333} /* MII */ \
- +}
- +
- +#define MPP_GROUP_2_TYPE {\
- + {0, 0, 0}, /* Reserved for AUTO */ \
- + {0x22220000, 0x22222222, 0x22}, /* TDM */ \
- + {0x44440000, 0x00044444, 0x0}, /* AUDIO */ \
- + {0, 0, 0}, /* N_A */ \
- + {0, 0, 0}, /* N_A */ \
- + {0x11110000, 0x11111111, 0x01} /* TS */ \
- +}
- +
- +#ifndef MV_ASMLANGUAGE
- +
- +/* This enumerator defines the Marvell Units ID */
- +typedef enum _mvUnitId
- +{
- + DRAM_UNIT_ID,
- + PEX_UNIT_ID,
- + ETH_GIG_UNIT_ID,
- + USB_UNIT_ID,
- + IDMA_UNIT_ID,
- + XOR_UNIT_ID,
- + SATA_UNIT_ID,
- + TDM_UNIT_ID,
- + UART_UNIT_ID,
- + CESA_UNIT_ID,
- + SPI_UNIT_ID,
- + AUDIO_UNIT_ID,
- + SDIO_UNIT_ID,
- + TS_UNIT_ID,
- + MAX_UNITS_ID
- +
- +}MV_UNIT_ID;
- +
- +#endif
- +
- +#endif /* __INCmvCtrlEnvSpech */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 2010-11-09 20:28:07.842495395 +0100
- @@ -0,0 +1,1048 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +/* includes */
- +#include "ctrlEnv/sys/mvAhbToMbus.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +#undef MV_DEBUG
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +/* typedefs */
- +
- +
- +/* CPU address remap registers offsets are inconsecutive. This struct */
- +/* describes address remap register offsets */
- +typedef struct _ahbToMbusRemapRegOffs
- +{
- + MV_U32 lowRegOffs; /* Low 32-bit remap register offset */
- + MV_U32 highRegOffs; /* High 32 bit remap register offset */
- +}AHB_TO_MBUS_REMAP_REG_OFFS;
- +
- +/* locals */
- +static MV_STATUS ahbToMbusRemapRegOffsGet (MV_U32 winNum,
- + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs);
- +
- +/*******************************************************************************
- +* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map !
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK laways.
- +*
- +*******************************************************************************/
- +MV_STATUS mvAhbToMbusInit(void)
- +{
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
- +*
- +* DESCRIPTION:
- +* This function sets
- +* address window, also known as address decode window.
- +* A new address decode window is set for specified winNum address window.
- +* If address decode window parameter structure enables the window,
- +* the routine will also enable the winNum window, allowing CPU to access
- +* the winNum window.
- +*
- +* INPUT:
- +* winNum - Windows number.
- +* pAddrDecWin - CPU winNum window data structure.
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
- +* address window overlapps with other active CPU winNum window or
- +* trying to assign 36bit base address while CPU does not support that.
- +* The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
- +*
- +*******************************************************************************/
- +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_DEC_REGS decRegs;
- +
- + /* Parameter checking */
- + if (winNum >= MAX_AHB_TO_MBUS_WINS)
- + {
- + mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- +
- + /* read base register*/
- + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
- + }
- + else
- + {
- + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pAddrDecWin->target),
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + /* read control register*/
- + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
- + }
- +
- + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");
- + return MV_ERROR;
- + }
- +
- + /* enable\Disable */
- + if (MV_TRUE == pAddrDecWin->enable)
- + {
- + decRegs.sizeReg |= ATMWCR_WIN_ENABLE;
- + }
- + else
- + {
- + decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
- +
- + /* set attributes */
- + decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;
- + decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
- + /* set target ID */
- + decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;
- + decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;
- +
- +#if !defined(MV_RUN_FROM_FLASH)
- + /* To be on the safe side we disable the window before writing the */
- + /* new values. */
- + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + mvAhbToMbusWinEnable(winNum,MV_FALSE);
- + }
- +#endif
- +
- + /* 3) Write to address decode Base Address Register */
- + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
- + }
- + else
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);
- + }
- +
- +
- + /* Internal register space have no size */
- + /* register. Do not perform size register assigment for those targets */
- + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + /* Write to address decode Size Register */
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
- +*
- +* DESCRIPTION:
- +* Get the CPU peripheral winNum address window.
- +*
- +* INPUT:
- +* winNum - Peripheral winNum enumerator
- +*
- +* OUTPUT:
- +* pAddrDecWin - CPU winNum window information data structure.
- +*
- +* RETURN:
- +* MV_OK if winNum exist, MV_ERROR otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS decRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- +
- +
- + /* Parameter checking */
- + if (winNum >= MAX_AHB_TO_MBUS_WINS)
- + {
- + mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- +
- + /* Internal register space size have no size register*/
- + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
- + }
- + else
- + {
- + decRegs.sizeReg = 0;
- + }
- +
- +
- + /* Read base and size */
- + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
- + }
- + else
- + {
- + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
- + }
- +
- +
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
- + {
- + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
- + return MV_ERROR;
- + }
- +
- + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
- + pAddrDecWin->target = INTER_REGS;
- + pAddrDecWin->enable = MV_TRUE;
- +
- + return MV_OK;
- + }
- +
- +
- + if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- +
- + }
- +
- +
- +
- + if (-1 == pAddrDecWin->addrWin.size)
- + {
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>
- + ATMWCR_WIN_ATTR_OFFS;
- + targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>
- + ATMWCR_WIN_TARGET_OFFS;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvAhbToMbusWinTargetGet - Get Window number associated with target
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target)
- +{
- + MV_AHB_TO_MBUS_DEC_WIN decWin;
- + MV_U32 winNum;
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
- + return 0xffffffff;
- + }
- +
- + if (INTER_REGS == target)
- + {
- + return MV_AHB_TO_MBUS_INTREG_WIN;
- + }
- +
- + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
- + {
- + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
- + continue;
- +
- + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
- + return 0xffffffff;
- +
- + }
- +
- + if (decWin.enable == MV_TRUE)
- + {
- + if (decWin.target == target)
- + {
- + return winNum;
- + }
- +
- + }
- +
- + }
- +
- + return 0xFFFFFFFF;
- +
- +
- +}
- +
- +/*******************************************************************************
- +* mvAhbToMbusWinAvailGet - Get First Available window number.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID)
- +{
- + MV_AHB_TO_MBUS_DEC_WIN decWin;
- + MV_U32 winNum;
- +
- + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
- + {
- + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
- + continue;
- +
- + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
- + return 0xffffffff;
- +
- + }
- +
- + if (decWin.enable == MV_FALSE)
- + {
- + return winNum;
- + }
- +
- + }
- +
- + return 0xFFFFFFFF;
- +}
- +
- +
- +/*******************************************************************************
- +* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window
- +*
- +* DESCRIPTION:
- +* This function enable/disable a CPU address decode window.
- +* if parameter 'enable' == MV_TRUE the routine will enable the
- +* window, thus enabling CPU accesses (before enabling the window it is
- +* tested for overlapping). Otherwise, the window will be disabled.
- +*
- +* INPUT:
- +* winNum - Peripheral winNum enumerator.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_ERROR if protection window number was wrong, or the window
- +* overlapps other winNum window.
- +*
- +*******************************************************************************/
- +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)
- +{
- +
- + /* Parameter checking */
- + if (winNum >= MAX_AHB_TO_MBUS_WINS)
- + {
- + mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + /* Internal registers bar can't be disable or enabled */
- + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
- + {
- + return (enable ? MV_OK : MV_ERROR);
- + }
- +
- + if (enable == MV_TRUE)
- + {
- + /* enable the window */
- + MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
- + }
- + else
- + { /* Disable address decode winNum window */
- + MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvAhbToMbusWinRemap - Set CPU remap register for address windows.
- +*
- +* DESCRIPTION:
- +* After a CPU address hits one of PCI address decode windows there is an
- +* option to remap the address to a different one. For example, CPU
- +* executes a read from PCI winNum window address 0x1200.0000. This
- +* can be modified so the address on the PCI bus would be 0x1400.0000
- +* Using the PCI address remap mechanism.
- +*
- +* INPUT:
- +* winNum - Peripheral winNum enumerator. Must be a PCI winNum.
- +* pAddrDecWin - CPU winNum window information data structure.
- +* Note that caller has to fill in the base field only. The
- +* size field is ignored.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if winNum is not a PCI one, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 baseAddr;
- + AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;
- +
- + MV_U32 effectiveBaseAddress=0,
- + baseAddrValue=0,windowSizeValue=0;
- +
- +
- + /* Get registers offsets of given winNum */
- + if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))
- + {
- + return 0xffffffff;
- + }
- +
- + /* 1) Set address remap low */
- + baseAddr = pAddrWin->baseLow;
- +
- + /* Check base address aligment */
- + /*
- + if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))
- + {
- + mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",
- + baseAddr);
- + return MV_ERROR;
- + }
- + */
- +
- + /* BaseLow[31:16] => base register [31:16] */
- + baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;
- +
- + MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);
- +
- + MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);
- +
- +
- + baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
- + windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
- +
- + baseAddrValue &= ATMWBR_BASE_MASK;
- + windowSizeValue &=ATMWCR_WIN_SIZE_MASK;
- +
- + /* Start calculating the effective Base Address */
- + effectiveBaseAddress = baseAddrValue ;
- +
- + /* The effective base address will be combined from the chopped (if any)
- + remap value (according to the size value and remap mechanism) and the
- + window's base address */
- + effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);
- + /* If the effectiveBaseAddress exceed the window boundaries return an
- + invalid value. */
- +
- + if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff)))
- + {
- + mvOsPrintf("mvAhbToMbusPciRemap: Error\n");
- + return 0xffffffff;
- + }
- +
- + return effectiveBaseAddress;
- +
- +
- +}
- +/*******************************************************************************
- +* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* target1 - CPU Interface target 1
- +* target2 - CPU Interface target 2
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if targets are illigal, or if one of the targets is not
- +* associated to a valid window .
- +* MV_OK otherwise.
- +*
- +*******************************************************************************/
- +
- +
- +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2)
- +{
- + MV_U32 winNum1,winNum2;
- + MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp;
- + AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2;
- + MV_U32 remapBaseLow1=0,remapBaseLow2=0;
- + MV_U32 remapBaseHigh1=0,remapBaseHigh2=0;
- +
- +
- + /* Check parameters */
- + if (target1 >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
- + return MV_ERROR;
- + }
- +
- + if (target2 >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
- + return MV_ERROR;
- + }
- +
- +
- + /* get window associated with this target */
- + winNum1 = mvAhbToMbusWinTargetGet(target1);
- +
- + if (winNum1 == 0xffffffff)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
- + target1,winNum1);
- + return MV_ERROR;
- +
- + }
- +
- + /* get window associated with this target */
- + winNum2 = mvAhbToMbusWinTargetGet(target2);
- +
- + if (winNum2 == 0xffffffff)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
- + target2,winNum2);
- + return MV_ERROR;
- +
- + }
- +
- + /* now Get original values of both Windows */
- + if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1))
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
- + winNum1);
- + return MV_ERROR;
- +
- + }
- + if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2))
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
- + winNum2);
- + return MV_ERROR;
- +
- + }
- +
- +
- + /* disable both windows */
- + if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE))
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n",
- + winNum1);
- + return MV_ERROR;
- +
- + }
- + if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE))
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n",
- + winNum2);
- + return MV_ERROR;
- +
- + }
- +
- +
- + /* now swap targets */
- +
- + /* first save winDec2 values */
- + winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh;
- + winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow;
- + winDecTemp.addrWin.size = winDec2.addrWin.size;
- + winDecTemp.enable = winDec2.enable;
- + winDecTemp.target = winDec2.target;
- +
- + /* winDec2 = winDec1 */
- + winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh;
- + winDec2.addrWin.baseLow = winDec1.addrWin.baseLow;
- + winDec2.addrWin.size = winDec1.addrWin.size;
- + winDec2.enable = winDec1.enable;
- + winDec2.target = winDec1.target;
- +
- +
- + /* winDec1 = winDecTemp */
- + winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh;
- + winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow;
- + winDec1.addrWin.size = winDecTemp.addrWin.size;
- + winDec1.enable = winDecTemp.enable;
- + winDec1.target = winDecTemp.target;
- +
- +
- + /* now set the new values */
- +
- +
- + mvAhbToMbusWinSet(winNum1,&winDec1);
- + mvAhbToMbusWinSet(winNum2,&winDec2);
- +
- +
- +
- +
- +
- + /* now we will treat the remap windows if exist */
- +
- +
- + /* now check if one or both windows has a remap window
- + as well after the swap ! */
- +
- + /* if a window had a remap value differnt than the base value
- + before the swap , then after the swap the remap value will be
- + equal to the base value unless both windows has a remap windows*/
- +
- + /* first get old values */
- + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
- + {
- + remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs);
- + remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs);
- +
- + }
- + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
- + {
- + remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs);
- + remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs);
- +
- +
- + }
- +
- + /* now do the swap */
- + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
- + {
- + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
- + {
- + /* Two windows has a remap !!! so swap */
- +
- + MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1);
- + MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1);
- +
- + MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2);
- + MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2);
- +
- +
- +
- + }
- + else
- + {
- + /* remap == base */
- + MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh);
- + MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow);
- +
- + }
- +
- + }
- + else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
- + {
- + /* remap == base */
- + MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh);
- + MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow);
- +
- + }
- +
- +
- +
- + return MV_OK;
- +
- +
- +}
- +
- +
- +
- +#if defined(MV_88F1181)
- +
- +/*******************************************************************************
- +* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration.
- +*
- +* DESCRIPTION:
- +* This function sets CPU Mbus Arbiter
- +*
- +* INPUT:
- +* pPizzaArbArray - A priority Structure describing 16 "pizza slices". At
- +* each clock cycle, the crossbar arbiter samples all
- +* requests and gives the bus to the next agent according
- +* to the "pizza".
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_ERROR if paramers to function invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray)
- +{
- + MV_U32 sliceNum;
- + MV_U32 xbarCtrl = 0;
- + MV_MBUS_ARB_TARGET xbarTarget;
- +
- + /* 1) Set crossbar control low register */
- + for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++)
- + {
- + xbarTarget = pPizzaArbArray[sliceNum];
- +
- + /* sliceNum parameter check */
- + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
- + {
- + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
- + xbarTarget);
- + return MV_ERROR;
- + }
- + xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum));
- + }
- + /* Write to crossbar control low register */
- + MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl);
- +
- + xbarCtrl = 0;
- +
- + /* 2) Set crossbar control high register */
- + for (sliceNum = MRLR_SLICE_NUM;
- + sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM;
- + sliceNum++)
- + {
- +
- + xbarTarget = pPizzaArbArray[sliceNum];
- +
- + /* sliceNum parameter check */
- + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
- + {
- + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
- + xbarTarget);
- + return MV_ERROR;
- + }
- + xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum));
- + }
- + /* Write to crossbar control high register */
- + MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvMbusArbCtrlSet - Set MBus Arbiter control register
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* ctrl - pointer to MV_MBUS_ARB_CTRL register
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_ERROR if paramers to function invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl)
- +{
- +
- + if (ctrl->highPrio == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
- + }
- + else
- + {
- + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
- + }
- +
- + if (ctrl->fixedRoundRobin == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
- + }
- + else
- + {
- + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
- + }
- +
- + if (ctrl->starvEn == MV_FALSE)
- + {
- + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
- + }
- + else
- + {
- + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvMbusArbCtrlGet - Get MBus Arbiter control register
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* ctrl - pointer to MV_MBUS_ARB_CTRL register
- +*
- +* OUTPUT:
- +* ctrl - pointer to MV_MBUS_ARB_CTRL register
- +*
- +* RETURN:
- +* MV_ERROR if paramers to function invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl)
- +{
- +
- + MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG);
- +
- + if (ctrlReg & MACR_ARB_ARM_TOP)
- + {
- + ctrl->highPrio = MV_TRUE;
- + }
- + else
- + {
- + ctrl->highPrio = MV_FALSE;
- + }
- +
- + if (ctrlReg & MACR_ARB_TARGET_FIXED)
- + {
- + ctrl->fixedRoundRobin = MV_TRUE;
- + }
- + else
- + {
- + ctrl->fixedRoundRobin = MV_FALSE;
- + }
- +
- + if (ctrlReg & MACR_ARB_REQ_CTRL_EN)
- + {
- + ctrl->starvEn = MV_TRUE;
- + }
- + else
- + {
- + ctrl->starvEn = MV_FALSE;
- + }
- +
- +
- + return MV_OK;
- +}
- +
- +#endif /* #if defined(MV_88F1181) */
- +
- +
- +
- +/*******************************************************************************
- +* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets
- +*
- +* DESCRIPTION:
- +* CPU to PCI address remap registers offsets are inconsecutive.
- +* This function returns PCI address remap registers offsets.
- +*
- +* INPUT:
- +* winNum - Address decode window number. See MV_U32 enumerator.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if winNum is not a PCI one.
- +*
- +*******************************************************************************/
- +static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum,
- + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs)
- +{
- + switch (winNum)
- + {
- + case 0:
- + case 1:
- + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
- + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
- + break;
- + case 2:
- + case 3:
- + if((mvCtrlModelGet() == MV_5281_DEV_ID) ||
- + (mvCtrlModelGet() == MV_1281_DEV_ID) ||
- + (mvCtrlModelGet() == MV_6183_DEV_ID) ||
- + (mvCtrlModelGet() == MV_6183L_DEV_ID))
- + {
- + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
- + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
- + break;
- + }
- + else
- + {
- + pRemapRegs->lowRegOffs = 0;
- + pRemapRegs->highRegOffs = 0;
- +
- + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
- + winNum));
- + return MV_NO_SUCH;
- + }
- + default:
- + {
- + pRemapRegs->lowRegOffs = 0;
- + pRemapRegs->highRegOffs = 0;
- +
- + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
- + winNum));
- + return MV_NO_SUCH;
- + }
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the CPU address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvAhbToMbusAddDecShow(MV_VOID)
- +{
- + MV_AHB_TO_MBUS_DEC_WIN win;
- + MV_U32 winNum;
- + mvOsOutput( "\n" );
- + mvOsOutput( "AHB To MBUS Bridge:\n" );
- + mvOsOutput( "-------------------\n" );
- +
- + for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ )
- + {
- + memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", winNum );
- +
- + if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
- + mvOsOutput( "...." );
- + mvSizePrint( win.addrWin.size );
- +
- + mvOsOutput( "\n" );
- +
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- +
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 2010-11-09 20:28:07.872495394 +0100
- @@ -0,0 +1,130 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvAhbToMbush
- +#define __INCmvAhbToMbush
- +
- +/* includes */
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +/* defines */
- +
- +#if defined(MV_88F1181)
- +/* This enumerator defines the Marvell controller possible MBUS arbiter */
- +/* target ports. It is used to define crossbar priority scheame (pizza) */
- +typedef enum _mvMBusArbTargetId
- +{
- + DRAM_MBUS_ARB_TARGET = 0, /* Port 0 -> DRAM interface */
- + TWSI_MBUS_ARB_TARGET = 1, /* Port 1 -> TWSI */
- + ARM_MBUS_ARB_TARGET = 2, /* Port 2 -> ARM */
- + PEX1_MBUS_ARB_TARGET = 3, /* Port 3 -> PCI Express 1 */
- + PEX0_MBUS_ARB_TARGET = 4, /* Port 4 -> PCI Express0 */
- + MAX_MBUS_ARB_TARGETS
- +}MV_MBUS_ARB_TARGET;
- +
- +typedef struct _mvMBusArbCtrl
- +{
- + MV_BOOL starvEn;
- + MV_BOOL highPrio;
- + MV_BOOL fixedRoundRobin;
- +
- +}MV_MBUS_ARB_CTRL;
- +
- +#endif /* #if defined(MV_88F1181) */
- +
- +typedef struct _mvAhbtoMbusDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_AHB_TO_MBUS_DEC_WIN;
- +
- +/* mvAhbToMbus.h API list */
- +
- +MV_STATUS mvAhbToMbusInit(MV_VOID);
- +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum,MV_BOOL enable);
- +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrDecWin);
- +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target);
- +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID);
- +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2);
- +
- +#if defined(MV_88F1181)
- +
- +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray);
- +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl);
- +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl);
- +
- +#endif /* #if defined(MV_88F1181) */
- +
- +
- +MV_VOID mvAhbToMbusAddDecShow(MV_VOID);
- +
- +
- +#endif /* __INCmvAhbToMbush */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 2010-11-09 20:28:07.902495495 +0100
- @@ -0,0 +1,143 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvAhbToMbusRegsh
- +#define __INCmvAhbToMbusRegsh
- +
- +/******************************/
- +/* ARM Address Map Registers */
- +/******************************/
- +
- +#define MAX_AHB_TO_MBUS_WINS 9
- +#define MV_AHB_TO_MBUS_INTREG_WIN 8
- +
- +
- +#define AHB_TO_MBUS_WIN_CTRL_REG(winNum) (0x20000 + (winNum)*0x10)
- +#define AHB_TO_MBUS_WIN_BASE_REG(winNum) (0x20004 + (winNum)*0x10)
- +#define AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum) (0x20008 + (winNum)*0x10)
- +#define AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum) (0x2000C + (winNum)*0x10)
- +#define AHB_TO_MBUS_WIN_INTEREG_REG 0x20080
- +
- +/* Window Control Register */
- +/* AHB_TO_MBUS_WIN_CTRL_REG (ATMWCR)*/
- +#define ATMWCR_WIN_ENABLE BIT0 /* Window Enable */
- +
- +#define ATMWCR_WIN_TARGET_OFFS 4 /* The target interface associated
- + with this window*/
- +#define ATMWCR_WIN_TARGET_MASK (0xf << ATMWCR_WIN_TARGET_OFFS)
- +
- +#define ATMWCR_WIN_ATTR_OFFS 8 /* The target interface attributes
- + Associated with this window */
- +#define ATMWCR_WIN_ATTR_MASK (0xff << ATMWCR_WIN_ATTR_OFFS)
- +
- +
- +/*
- +Used with the Base register to set the address window size and location
- +Must be programed from LSB to MSB as sequence of 1’s followed
- +by sequence of 0’s. The number of 1’s specifies the size of the window
- +in 64 KB granularity (e.g. a value of 0x00FF specifies 256 = 16 MB).
- +
- +NOTE: A value of 0x0 specifies 64KB size.
- +*/
- +#define ATMWCR_WIN_SIZE_OFFS 16 /* Window Size */
- +#define ATMWCR_WIN_SIZE_MASK (0xffff << ATMWCR_WIN_SIZE_OFFS)
- +#define ATMWCR_WIN_SIZE_ALIGNMENT 0x10000
- +
- +/* Window Base Register */
- +/* AHB_TO_MBUS_WIN_BASE_REG (ATMWBR) */
- +
- +/*
- +Used with the size field to set the address window size and location.
- +Corresponds to transaction address[31:16]
- +*/
- +#define ATMWBR_BASE_OFFS 16 /* Base Address */
- +#define ATMWBR_BASE_MASK (0xffff << ATMWBR_BASE_OFFS)
- +#define ATMWBR_BASE_ALIGNMENT 0x10000
- +
- +/* Window Remap Low Register */
- +/* AHB_TO_MBUS_WIN_REMAP_LOW_REG (ATMWRLR) */
- +
- +/*
- +Used with the size field to specifies address bits[31:0] to be driven to
- +the target interface.:
- +target_addr[31:16] = (addr[31:16] & size[15:0]) | (remap[31:16] & ~size[15:0])
- +*/
- +#define ATMWRLR_REMAP_LOW_OFFS 16 /* Remap Address */
- +#define ATMWRLR_REMAP_LOW_MASK (0xffff << ATMWRLR_REMAP_LOW_OFFS)
- +#define ATMWRLR_REMAP_LOW_ALIGNMENT 0x10000
- +
- +/* Window Remap High Register */
- +/* AHB_TO_MBUS_WIN_REMAP_HIGH_REG (ATMWRHR) */
- +
- +/*
- +Specifies address bits[63:32] to be driven to the target interface.
- +target_addr[63:32] = (RemapHigh[31:0]
- +*/
- +#define ATMWRHR_REMAP_HIGH_OFFS 0 /* Remap Address */
- +#define ATMWRHR_REMAP_HIGH_MASK (0xffffffff << ATMWRHR_REMAP_HIGH_OFFS)
- +
- +
- +#endif /* __INCmvAhbToMbusRegsh */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 2010-11-09 20:28:07.942495425 +0100
- @@ -0,0 +1,1036 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +/* includes */
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
- +#include "cpu/mvCpu.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "mvSysHwConfig.h"
- +#include "mvSysDram.h"
- +
- +/*#define MV_DEBUG*/
- +/* defines */
- +
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +/* locals */
- +/* static functions */
- +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
- +
- +MV_TARGET * sampleAtResetTargetArray;
- +MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY;
- +MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180;
- +/*******************************************************************************
- +* mvCpuIfInit - Initialize Controller CPU interface
- +*
- +* DESCRIPTION:
- +* This function initialize Controller CPU interface:
- +* 1. Set CPU interface configuration registers.
- +* 2. Set CPU master Pizza arbiter control according to static
- +* configuration described in configuration file.
- +* 3. Opens CPU address decode windows. DRAM windows are assumed to be
- +* already set (auto detection).
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)
- +{
- + MV_U32 regVal;
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin;
- +
- + if (cpuAddrWinMap == NULL)
- + {
- + DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));
- + return MV_ERROR;
- + }
- +
- + /*Initialize the boot target array according to device type*/
- + if(mvCtrlModelGet() == MV_6180_DEV_ID)
- + sampleAtResetTargetArray = sampleAtResetTargetArray6180P;
- + else
- + sampleAtResetTargetArray = sampleAtResetTargetArrayP;
- +
- + /* Set ARM Configuration register */
- + regVal = MV_REG_READ(CPU_CONFIG_REG);
- + regVal &= ~CPU_CONFIG_DEFAULT_MASK;
- + regVal |= CPU_CONFIG_DEFAULT;
- + MV_REG_WRITE(CPU_CONFIG_REG,regVal);
- +
- + /* First disable all CPU target windows */
- + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
- + {
- + if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))
- + {
- + continue;
- + }
- +
- +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
- + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
- + if (MV_TARGET_IS_PCI(target))
- + {
- + continue;
- + }
- +#endif
- +
- +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
- + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
- + if (MV_TARGET_IS_PEX(target))
- + {
- + continue;
- + }
- +#endif
- +#if defined(MV_RUN_FROM_FLASH)
- + /* Don't disable the boot device. */
- + if (target == DEV_BOOCS)
- + {
- + continue;
- + }
- +#endif /* MV_RUN_FROM_FLASH */
- + mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);
- + }
- +
- +#if defined(MV_RUN_FROM_FLASH)
- + /* Resize the bootcs windows before other windows, because this */
- + /* window is enabled and will cause an overlap if not resized. */
- + target = DEV_BOOCS;
- +
- + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
- + {
- + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
- + return MV_ERROR;
- + }
- +
- + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
- + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
- + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
- + {
- + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
- + cpuAddrWinMap[target].winNum));
- + }
- +
- +#endif /* MV_RUN_FROM_FLASH */
- +
- + /* Go through all targets in user table until table terminator */
- + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
- + {
- +
- +#if defined(MV_RUN_FROM_FLASH)
- + if (target == DEV_BOOCS)
- + {
- + continue;
- + }
- +#endif /* MV_RUN_FROM_FLASH */
- +
- + /* if DRAM auto sizing is used do not initialized DRAM target windows, */
- + /* assuming this already has been done earlier. */
- +#ifdef MV_DRAM_AUTO_SIZE
- + if (MV_TARGET_IS_DRAM(target))
- + {
- + continue;
- + }
- +#endif
- +
- +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
- + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
- + if (MV_TARGET_IS_PCI(target))
- + {
- + continue;
- + }
- +#endif
- +
- +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
- + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
- + if (MV_TARGET_IS_PEX(target))
- + {
- + continue;
- + }
- +#endif
- + /* If the target attribute is the same as the boot device attribute */
- + /* then it's stays disable */
- + if (MV_TARGET_IS_AS_BOOT(target))
- + {
- + continue;
- + }
- +
- + if((0 == cpuAddrWinMap[target].addrWin.size) ||
- + (DIS == cpuAddrWinMap[target].enable))
- +
- + {
- + if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))
- + {
- + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));
- + return MV_ERROR;
- + }
- +
- + }
- + else
- + {
- + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
- + {
- + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
- + return MV_ERROR;
- + }
- +
- + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
- + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
- + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
- + {
- + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
- + cpuAddrWinMap[target].winNum));
- + }
- +
- +
- + }
- + }
- +
- + return MV_OK;
- +
- +
- +}
- +
- +
- +/*******************************************************************************
- +* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)
- +* address window, also known as address decode window.
- +* A new address decode window is set for specified target address window.
- +* If address decode window parameter structure enables the window,
- +* the routine will also enable the target window, allowing CPU to access
- +* the target window.
- +*
- +* INPUT:
- +* target - Peripheral target enumerator.
- +* pAddrDecWin - CPU target window data structure.
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_OK if CPU target window was set correctly, MV_ERROR in case of
- +* address window overlapps with other active CPU target window or
- +* trying to assign 36bit base address while CPU does not support that.
- +* The function returns MV_NOT_SUPPORTED, if the target is unsupported.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
- +{
- + MV_AHB_TO_MBUS_DEC_WIN decWin;
- + MV_U32 existingWinNum;
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + target = MV_CHANGE_BOOT_CS(target);
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + /* 2) Check if the requested window overlaps with current windows */
- + if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target);
- + return MV_BAD_PARAM;
- + }
- +
- + if (MV_TARGET_IS_DRAM(target))
- + {
- + /* copy relevant data to MV_DRAM_DEC_WIN structure */
- + addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
- + addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
- + addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;
- + addrDecWin.enable = pAddrDecWin->enable;
- +
- +
- + if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);
- + {
- + mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");
- + return MV_ERROR;
- + }
- +
- + }
- + else
- + {
- + /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */
- + decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
- + decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
- + decWin.addrWin.size = pAddrDecWin->addrWin.size;
- + decWin.enable = pAddrDecWin->enable;
- + decWin.target = target;
- +
- + existingWinNum = mvAhbToMbusWinTargetGet(target);
- +
- + /* check if there is already another Window configured
- + for this target */
- + if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&
- + (existingWinNum != pAddrDecWin->winNum))
- + {
- + /* if we want to enable the new winow number
- + passed by the user , then the old one should
- + be disabled */
- + if (MV_TRUE == pAddrDecWin->enable)
- + {
- + /* be sure it is disabled */
- + mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);
- + }
- + }
- +
- + if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)
- + {
- + mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");
- + return MV_ERROR;
- + }
- +
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window
- +*
- +* DESCRIPTION:
- +* Get the CPU peripheral target address window.
- +*
- +* INPUT:
- +* target - Peripheral target enumerator
- +*
- +* OUTPUT:
- +* pAddrDecWin - CPU target window information data structure.
- +*
- +* RETURN:
- +* MV_OK if target exist, MV_ERROR otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
- +{
- +
- + MV_U32 winNum=0xffffffff;
- + MV_AHB_TO_MBUS_DEC_WIN decWin;
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + target = MV_CHANGE_BOOT_CS(target);
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + if (MV_TARGET_IS_DRAM(target))
- + {
- + if (mvDramIfWinGet(target,&addrDecWin) != MV_OK)
- + {
- + mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n",
- + target);
- + return MV_ERROR;
- + }
- +
- + /* copy relevant data to MV_CPU_DEC_WIN structure */
- + pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow;
- + pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
- + pAddrDecWin->addrWin.size = addrDecWin.addrWin.size;
- + pAddrDecWin->enable = addrDecWin.enable;
- + pAddrDecWin->winNum = 0xffffffff;
- +
- + }
- + else
- + {
- + /* get the Window number associated with this target */
- +
- + winNum = mvAhbToMbusWinTargetGet(target);
- + if (winNum >= MAX_AHB_TO_MBUS_WINS)
- + {
- + return MV_NO_SUCH;
- +
- + }
- +
- + if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK)
- + {
- + mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n",
- + __FUNCTION__, winNum);
- + return MV_ERROR;
- +
- + }
- +
- + /* copy relevant data to MV_CPU_DEC_WIN structure */
- + pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow;
- + pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh;
- + pAddrDecWin->addrWin.size = decWin.addrWin.size;
- + pAddrDecWin->enable = decWin.enable;
- + pAddrDecWin->winNum = winNum;
- +
- + }
- +
- +
- +
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window
- +*
- +* DESCRIPTION:
- +* This function enable/disable a CPU address decode window.
- +* if parameter 'enable' == MV_TRUE the routine will enable the
- +* window, thus enabling CPU accesses (before enabling the window it is
- +* tested for overlapping). Otherwise, the window will be disabled.
- +*
- +* INPUT:
- +* target - Peripheral target enumerator.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_ERROR if protection window number was wrong, or the window
- +* overlapps other target window.
- +*
- +*******************************************************************************/
- +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable)
- +{
- + MV_U32 winNum, temp;
- + MV_CPU_DEC_WIN addrDecWin;
- +
- + target = MV_CHANGE_BOOT_CS(target);
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + /* get the window and check if it exist */
- + temp = mvCpuIfTargetWinGet(target, &addrDecWin);
- + if (MV_NO_SUCH == temp)
- + {
- + return (enable? MV_ERROR: MV_OK);
- + }
- + else if( MV_OK != temp)
- + {
- + mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target);
- + return MV_ERROR;
- + }
- +
- +
- + /* check overlap */
- +
- + if (MV_TRUE == enable)
- + {
- + if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin))
- + {
- + DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target));
- + return MV_ERROR;
- + }
- +
- + }
- +
- +
- + if (MV_TARGET_IS_DRAM(target))
- + {
- + if (mvDramIfWinEnable(target , enable) != MV_OK)
- + {
- + mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n");
- + return MV_ERROR;
- +
- + }
- +
- + }
- + else
- + {
- + /* get the Window number associated with this target */
- +
- + winNum = mvAhbToMbusWinTargetGet(target);
- +
- + if (winNum >= MAX_AHB_TO_MBUS_WINS)
- + {
- + return (enable? MV_ERROR: MV_OK);
- + }
- +
- + if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK)
- + {
- + mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n",
- + winNum);
- + return MV_ERROR;
- +
- + }
- +
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvCpuIfTargetWinSizeGet - Get CPU target address window size
- +*
- +* DESCRIPTION:
- +* Get the size of CPU-to-peripheral target window.
- +*
- +* INPUT:
- +* target - Peripheral target enumerator
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit size. Function also returns '0' if window is closed.
- +* Function returns 0xFFFFFFFF in case of an error.
- +*
- +*******************************************************************************/
- +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target)
- +{
- + MV_CPU_DEC_WIN addrDecWin;
- +
- + target = MV_CHANGE_BOOT_CS(target);
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target);
- + return 0;
- + }
- +
- + /* Get the winNum window */
- + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
- + {
- + mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n",
- + target);
- + return 0;
- + }
- +
- + /* Check if window is enabled */
- + if (addrDecWin.enable == MV_TRUE)
- + {
- + return (addrDecWin.addrWin.size);
- + }
- + else
- + {
- + return 0; /* Window disabled. return 0 */
- + }
- +}
- +
- +/*******************************************************************************
- +* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low
- +*
- +* DESCRIPTION:
- +* CPU-to-peripheral target address window base is constructed of
- +* two parts: Low and high.
- +* This function gets the CPU peripheral target low base address.
- +*
- +* INPUT:
- +* target - Peripheral target enumerator
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit low base address.
- +*
- +*******************************************************************************/
- +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target)
- +{
- + MV_CPU_DEC_WIN addrDecWin;
- +
- + target = MV_CHANGE_BOOT_CS(target);
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
- + return 0xffffffff;
- + }
- +
- + /* Get the target window */
- + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
- + {
- + mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n",
- + target);
- + return 0xffffffff;
- + }
- +
- + if (MV_FALSE == addrDecWin.enable)
- + {
- + return 0xffffffff;
- + }
- + return (addrDecWin.addrWin.baseLow);
- +}
- +
- +/*******************************************************************************
- +* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high
- +*
- +* DESCRIPTION:
- +* CPU-to-peripheral target address window base is constructed of
- +* two parts: Low and high.
- +* This function gets the CPU peripheral target high base address.
- +*
- +* INPUT:
- +* target - Peripheral target enumerator
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit high base address.
- +*
- +*******************************************************************************/
- +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target)
- +{
- + MV_CPU_DEC_WIN addrDecWin;
- +
- + target = MV_CHANGE_BOOT_CS(target);
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
- + return 0xffffffff;
- + }
- +
- + /* Get the target window */
- + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
- + {
- + mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n",
- + target);
- + return 0xffffffff;
- + }
- +
- + if (MV_FALSE == addrDecWin.enable)
- + {
- + return 0;
- + }
- +
- + return (addrDecWin.addrWin.baseHigh);
- +}
- +
- +#if defined(MV_INCLUDE_PEX)
- +/*******************************************************************************
- +* mvCpuIfPexRemap - Set CPU remap register for address windows.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* pexTarget - Peripheral target enumerator. Must be a PEX target.
- +* pAddrDecWin - CPU target window information data structure.
- +* Note that caller has to fill in the base field only. The
- +* size field is ignored.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if target is not a PEX one, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin)
- +{
- + MV_U32 winNum;
- +
- + /* Check parameters */
- +
- + if (mvCtrlPexMaxIfGet() > 1)
- + {
- + if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget)))
- + {
- + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
- + return 0xffffffff;
- + }
- +
- + }
- + else
- + {
- + if (!MV_TARGET_IS_PEX0(pexTarget))
- + {
- + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
- + return 0xffffffff;
- + }
- +
- + }
- +
- + /* get the Window number associated with this target */
- + winNum = mvAhbToMbusWinTargetGet(pexTarget);
- +
- + if (winNum >= MAX_AHB_TO_MBUS_WINS)
- + {
- + mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n");
- + return 0xffffffff;
- +
- + }
- +
- + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
- +}
- +
- +#endif
- +
- +#if defined(MV_INCLUDE_PCI)
- +/*******************************************************************************
- +* mvCpuIfPciRemap - Set CPU remap register for address windows.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* pciTarget - Peripheral target enumerator. Must be a PCI target.
- +* pAddrDecWin - CPU target window information data structure.
- +* Note that caller has to fill in the base field only. The
- +* size field is ignored.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin)
- +{
- + MV_U32 winNum;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_PCI(pciTarget))
- + {
- + mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget);
- + return 0xffffffff;
- + }
- +
- + /* get the Window number associated with this target */
- + winNum = mvAhbToMbusWinTargetGet(pciTarget);
- +
- + if (winNum >= MAX_AHB_TO_MBUS_WINS)
- + {
- + mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n");
- + return 0xffffffff;
- +
- + }
- +
- + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
- +}
- +#endif /* MV_INCLUDE_PCI */
- +
- +
- +/*******************************************************************************
- +* mvCpuIfPciIfRemap - Set CPU remap register for address windows.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* pciTarget - Peripheral target enumerator. Must be a PCI target.
- +* pAddrDecWin - CPU target window information data structure.
- +* Note that caller has to fill in the base field only. The
- +* size field is ignored.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin)
- +{
- +#if defined(MV_INCLUDE_PEX)
- + if (MV_TARGET_IS_PEX(pciIfTarget))
- + {
- + return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin);
- + }
- +#endif
- +#if defined(MV_INCLUDE_PCI)
- +
- + if (MV_TARGET_IS_PCI(pciIfTarget))
- + {
- + return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin);
- + }
- +#endif
- + return 0;
- +}
- +
- +
- +
- +/*******************************************************************************
- +* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* baseAddress - base address to be checked
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* the target number that baseAddress belongs to or MAX_TARGETS is not
- +* found
- +*
- +*******************************************************************************/
- +
- +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress)
- +{
- + MV_CPU_DEC_WIN win;
- + MV_U32 target;
- +
- + for( target = 0; target < MAX_TARGETS; target++ )
- + {
- + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + if ((baseAddress >= win.addrWin.baseLow) &&
- + (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break;
- + }
- + }
- + else return MAX_TARGETS;
- +
- + }
- +
- + return target;
- +}
- +/*******************************************************************************
- +* cpuTargetWinOverlap - Detect CPU address decode windows overlapping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviur is expected in case CPU address decode
- +* windows overlapps.
- +* This function detects CPU address decode windows overlapping of a
- +* specified target. The function does not check the target itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* target - Peripheral target enumerator.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlaps current address
- +* decode map, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 targetNum;
- + MV_CPU_DEC_WIN addrDecWin;
- + MV_STATUS status;
- +
- +
- + for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++)
- + {
- +#if defined(MV_RUN_FROM_FLASH)
- + if(MV_TARGET_IS_AS_BOOT(target))
- + {
- + if (MV_CHANGE_BOOT_CS(targetNum) == target)
- + continue;
- + }
- +#endif /* MV_RUN_FROM_FLASH */
- +
- + /* don't check our target or illegal targets */
- + if (targetNum == target)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + status = mvCpuIfTargetWinGet(targetNum, &addrDecWin);
- + if(MV_NO_SUCH == status)
- + {
- + continue;
- + }
- + if(MV_OK != status)
- + {
- + DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n"));
- + return MV_TRUE;
- + }
- +
- + /* Do not check disabled windows */
- + if (MV_FALSE == addrDecWin.enable)
- + {
- + continue;
- + }
- +
- + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
- + {
- + DB(mvOsPrintf(
- + "cpuTargetWinOverlap: Required target %d overlap current %d\n",
- + target, targetNum));
- + return MV_TRUE;
- + }
- + }
- +
- + return MV_FALSE;
- +
- +}
- +
- +/*******************************************************************************
- +* mvCpuIfAddDecShow - Print the CPU address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the CPU address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvCpuIfAddDecShow(MV_VOID)
- +{
- + MV_CPU_DEC_WIN win;
- + MV_U32 target;
- + mvOsOutput( "\n" );
- + mvOsOutput( "CPU Interface\n" );
- + mvOsOutput( "-------------\n" );
- +
- + for( target = 0; target < MAX_TARGETS; target++ )
- + {
- +
- + memset( &win, 0, sizeof(MV_CPU_DEC_WIN) );
- +
- + mvOsOutput( "%s ",mvCtrlTargetNameGet(target));
- + mvOsOutput( "...." );
- +
- + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "base %08x, ", win.addrWin.baseLow );
- + mvSizePrint( win.addrWin.size );
- + mvOsOutput( "\n" );
- +
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH )
- + {
- + mvOsOutput( "no such\n" );
- + }
- + }
- +}
- +
- +/*******************************************************************************
- +* mvCpuIfEnablePex - Enable PCI Express.
- +*
- +* DESCRIPTION:
- +* This function Enable PCI Express.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* pexType - MV_PEX_ROOT_COMPLEX - root complex device
- +* MV_PEX_END_POINT - end point device
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +#if defined(MV_INCLUDE_PEX)
- +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)
- +{
- + /* Set pex mode incase S@R not exist */
- + if( pexType == MV_PEX_END_POINT)
- + {
- + MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
- + /* Change pex mode in capability reg */
- + MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);
- + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);
- +
- + }
- + else
- + {
- + MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
- + }
- +
- + /* CPU config register Pex enable */
- + MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);
- +}
- +#endif
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 2010-11-09 20:28:07.982495689 +0100
- @@ -0,0 +1,120 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvCpuIfh
- +#define __INCmvCpuIfh
- +
- +/* includes */
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/sys/mvCpuIfRegs.h"
- +#include "ctrlEnv/sys/mvAhbToMbus.h"
- +#include "ddr2/mvDramIf.h"
- +#include "ctrlEnv/sys/mvSysDram.h"
- +#if defined(MV_INCLUDE_PEX)
- +#include "pex/mvPex.h"
- +#endif
- +
- +/* defines */
- +
- +/* typedefs */
- +/* This structure describes CPU interface address decode window */
- +typedef struct _mvCpuIfDecWin
- +{
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_U32 winNum; /* Window Number in the AHB To Mbus bridge */
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_CPU_DEC_WIN;
- +
- +
- +
- +/* mvCpuIfLib.h API list */
- +
- +/* mvCpuIfLib.h API list */
- +
- +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap);
- +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable);
- +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target);
- +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target);
- +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target);
- +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress);
- +#if defined(MV_INCLUDE_PEX)
- +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin);
- +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType);
- +#endif
- +#if defined(MV_INCLUDE_PCI)
- +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
- +#endif
- +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
- +
- +MV_VOID mvCpuIfAddDecShow(MV_VOID);
- +
- +#if defined(MV88F6281)
- +MV_STATUS mvCpuIfBridgeReorderWAInit(void);
- +#endif
- +
- +#endif /* __INCmvCpuIfh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 2010-11-09 20:28:08.012495399 +0100
- @@ -0,0 +1,304 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvCpuIfRegsh
- +#define __INCmvCpuIfRegsh
- +
- +/****************************************/
- +/* ARM Control and Status Registers Map */
- +/****************************************/
- +
- +#define CPU_CONFIG_REG 0x20100
- +#define CPU_CTRL_STAT_REG 0x20104
- +#define CPU_RSTOUTN_MASK_REG 0x20108
- +#define CPU_SYS_SOFT_RST_REG 0x2010C
- +#define CPU_AHB_MBUS_CAUSE_INT_REG 0x20110
- +#define CPU_AHB_MBUS_MASK_INT_REG 0x20114
- +#define CPU_FTDLL_CONFIG_REG 0x20120
- +#define CPU_L2_CONFIG_REG 0x20128
- +
- +
- +
- +/* ARM Configuration register */
- +/* CPU_CONFIG_REG (CCR) */
- +
- +
- +/* Reset vector location */
- +#define CCR_VEC_INIT_LOC_OFFS 1
- +#define CCR_VEC_INIT_LOC_MASK BIT1
- +/* reset at 0x00000000 */
- +#define CCR_VEC_INIT_LOC_0000 (0 << CCR_VEC_INIT_LOC_OFFS)
- +/* reset at 0xFFFF0000 */
- +#define CCR_VEC_INIT_LOC_FF00 (1 << CCR_VEC_INIT_LOC_OFFS)
- +
- +
- +#define CCR_AHB_ERROR_PROP_OFFS 2
- +#define CCR_AHB_ERROR_PROP_MASK BIT2
- +/* Erros are not propogated to AHB */
- +#define CCR_AHB_ERROR_PROP_NO_INDICATE (0 << CCR_AHB_ERROR_PROP_OFFS)
- +/* Erros are propogated to AHB */
- +#define CCR_AHB_ERROR_PROP_INDICATE (1 << CCR_AHB_ERROR_PROP_OFFS)
- +
- +
- +#define CCR_ENDIAN_INIT_OFFS 3
- +#define CCR_ENDIAN_INIT_MASK BIT3
- +#define CCR_ENDIAN_INIT_LITTLE (0 << CCR_ENDIAN_INIT_OFFS)
- +#define CCR_ENDIAN_INIT_BIG (1 << CCR_ENDIAN_INIT_OFFS)
- +
- +
- +#define CCR_INCR_EN_OFFS 4
- +#define CCR_INCR_EN_MASK BIT4
- +#define CCR_INCR_EN BIT4
- +
- +
- +#define CCR_NCB_BLOCKING_OFFS 5
- +#define CCR_NCB_BLOCKING_MASK (1 << CCR_NCB_BLOCKING_OFFS)
- +#define CCR_NCB_BLOCKING_NON (0 << CCR_NCB_BLOCKING_OFFS)
- +#define CCR_NCB_BLOCKING_EN (1 << CCR_NCB_BLOCKING_OFFS)
- +
- +#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
- +#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
- +#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
- +#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
- +#define CCR_ICACH_PREF_BUF_ENABLE BIT16
- +#define CCR_DCACH_PREF_BUF_ENABLE BIT17
- +
- +/* Ratio options for CPU to DDR for 6281/6192/6190 */
- +#define CPU_2_DDR_CLK_1x3 4
- +#define CPU_2_DDR_CLK_1x4 6
- +
- +/* Ratio options for CPU to DDR for 6281 only */
- +#define CPU_2_DDR_CLK_2x9 7
- +#define CPU_2_DDR_CLK_1x5 8
- +#define CPU_2_DDR_CLK_1x6 9
- +
- +/* Ratio options for CPU to DDR for 6180 only */
- +#define CPU_2_DDR_CLK_1x3_1 0x5
- +#define CPU_2_DDR_CLK_1x4_1 0x6
- +
- +/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
- +/* CPU to Mbus-L Tick Sample fields in CPU config register */
- +
- +#define TICK_DRV_1x1 0
- +#define TICK_DRV_1x2 0
- +#define TICK_DRV_1x3 1
- +#define TICK_DRV_1x4 2
- +#define TICK_SMPL_1x1 0
- +#define TICK_SMPL_1x2 1
- +#define TICK_SMPL_1x3 0
- +#define TICK_SMPL_1x4 0
- +
- +#define CPU_2_MBUSL_DDR_CLK_1x2 \
- + ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
- + (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
- +#define CPU_2_MBUSL_DDR_CLK_1x3 \
- + ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
- + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
- +#define CPU_2_MBUSL_DDR_CLK_1x4 \
- + ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
- + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
- +
- +/* ARM Control and Status register */
- +/* CPU_CTRL_STAT_REG (CCSR) */
- +
- +
- +/*
- +This is used to block PCI express\PCI from access Socrates/Feroceon GP
- +while ARM boot is still in progress
- +*/
- +
- +#define CCSR_PCI_ACCESS_OFFS 0
- +#define CCSR_PCI_ACCESS_MASK BIT0
- +#define CCSR_PCI_ACCESS_ENABLE (0 << CCSR_PCI_ACCESS_OFFS)
- +#define CCSR_PCI_ACCESS_DISBALE (1 << CCSR_PCI_ACCESS_OFFS)
- +
- +#define CCSR_ARM_RESET BIT1
- +#define CCSR_SELF_INT BIT2
- +#define CCSR_BIG_ENDIAN BIT15
- +
- +
- +/* RSTOUTn Mask Register */
- +/* CPU_RSTOUTN_MASK_REG (CRMR) */
- +
- +#define CRMR_PEX_RST_OUT_OFFS 0
- +#define CRMR_PEX_RST_OUT_MASK BIT0
- +#define CRMR_PEX_RST_OUT_ENABLE (1 << CRMR_PEX_RST_OUT_OFFS)
- +#define CRMR_PEX_RST_OUT_DISABLE (0 << CRMR_PEX_RST_OUT_OFFS)
- +
- +#define CRMR_WD_RST_OUT_OFFS 1
- +#define CRMR_WD_RST_OUT_MASK BIT1
- +#define CRMR_WD_RST_OUT_ENABLE (1 << CRMR_WD_RST_OUT_OFFS)
- +#define CRMR_WD_RST_OUT_DISBALE (0 << CRMR_WD_RST_OUT_OFFS)
- +
- +#define CRMR_SOFT_RST_OUT_OFFS 2
- +#define CRMR_SOFT_RST_OUT_MASK BIT2
- +#define CRMR_SOFT_RST_OUT_ENABLE (1 << CRMR_SOFT_RST_OUT_OFFS)
- +#define CRMR_SOFT_RST_OUT_DISBALE (0 << CRMR_SOFT_RST_OUT_OFFS)
- +
- +/* System Software Reset Register */
- +/* CPU_SYS_SOFT_RST_REG (CSSRR) */
- +
- +#define CSSRR_SYSTEM_SOFT_RST BIT0
- +
- +/* AHB to Mbus Bridge Interrupt Cause Register*/
- +/* CPU_AHB_MBUS_CAUSE_INT_REG (CAMCIR) */
- +
- +#define CAMCIR_ARM_SELF_INT BIT0
- +#define CAMCIR_ARM_TIMER0_INT_REQ BIT1
- +#define CAMCIR_ARM_TIMER1_INT_REQ BIT2
- +#define CAMCIR_ARM_WD_TIMER_INT_REQ BIT3
- +
- +
- +/* AHB to Mbus Bridge Interrupt Mask Register*/
- +/* CPU_AHB_MBUS_MASK_INT_REG (CAMMIR) */
- +
- +#define CAMCIR_ARM_SELF_INT_OFFS 0
- +#define CAMCIR_ARM_SELF_INT_MASK BIT0
- +#define CAMCIR_ARM_SELF_INT_EN (1 << CAMCIR_ARM_SELF_INT_OFFS)
- +#define CAMCIR_ARM_SELF_INT_DIS (0 << CAMCIR_ARM_SELF_INT_OFFS)
- +
- +
- +#define CAMCIR_ARM_TIMER0_INT_REQ_OFFS 1
- +#define CAMCIR_ARM_TIMER0_INT_REQ_MASK BIT1
- +#define CAMCIR_ARM_TIMER0_INT_REQ_EN (1 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
- +#define CAMCIR_ARM_TIMER0_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
- +
- +#define CAMCIR_ARM_TIMER1_INT_REQ_OFFS 2
- +#define CAMCIR_ARM_TIMER1_INT_REQ_MASK BIT2
- +#define CAMCIR_ARM_TIMER1_INT_REQ_EN (1 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
- +#define CAMCIR_ARM_TIMER1_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
- +
- +#define CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS 3
- +#define CAMCIR_ARM_WD_TIMER_INT_REQ_MASK BIT3
- +#define CAMCIR_ARM_WD_TIMER_INT_REQ_EN (1 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
- +#define CAMCIR_ARM_WD_TIMER_INT_REQ_DIS (0 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
- +
- +/* CPU FTDLL Config register (CFCR) fields */
- +#define CFCR_FTDLL_ICACHE_TAG_OFFS 0
- +#define CFCR_FTDLL_ICACHE_TAG_MASK (0x7F << CFCR_FTDLL_ICACHE_TAG_OFFS)
- +#define CFCR_FTDLL_DCACHE_TAG_OFFS 8
- +#define CFCR_FTDLL_DCACHE_TAG_MASK (0x7F << CFCR_FTDLL_DCACHE_TAG_OFFS)
- +#define CFCR_FTDLL_OVERWRITE_ENABLE (1 << 15)
- +/* For Orion 2 D2 only */
- +#define CFCR_MRVL_CPU_ID_OFFS 16
- +#define CFCR_MRVL_CPU_ID_MASK (0x1 << CFCR_MRVL_CPU_ID_OFFS)
- +#define CFCR_ARM_CPU_ID (0x0 << CFCR_MRVL_CPU_ID_OFFS)
- +#define CFCR_MRVL_CPU_ID (0x1 << CFCR_MRVL_CPU_ID_OFFS)
- +#define CFCR_VFP_SUB_ARC_NUM_OFFS 7
- +#define CFCR_VFP_SUB_ARC_NUM_MASK (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
- +#define CFCR_VFP_SUB_ARC_NUM_1 (0x0 << CFCR_VFP_SUB_ARC_NUM_OFFS)
- +#define CFCR_VFP_SUB_ARC_NUM_2 (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
- +
- +/* CPU_L2_CONFIG_REG fields */
- +#ifdef MV_CPU_LE
- +#define CL2CR_L2_ECC_EN_OFFS 2
- +#define CL2CR_L2_WT_MODE_OFFS 4
- +#else
- +#define CL2CR_L2_ECC_EN_OFFS 26
- +#define CL2CR_L2_WT_MODE_OFFS 28
- +#endif
- +
- +#define CL2CR_L2_ECC_EN_MASK (1 << CL2CR_L2_ECC_EN_OFFS)
- +#define CL2CR_L2_WT_MODE_MASK (1 << CL2CR_L2_WT_MODE_OFFS)
- +
- +/*******************************************/
- +/* Main Interrupt Controller Registers Map */
- +/*******************************************/
- +
- +#define CPU_MAIN_INT_CAUSE_REG 0x20200
- +#define CPU_MAIN_IRQ_MASK_REG 0x20204
- +#define CPU_MAIN_FIQ_MASK_REG 0x20208
- +#define CPU_ENPOINT_MASK_REG 0x2020C
- +#define CPU_MAIN_INT_CAUSE_HIGH_REG 0x20210
- +#define CPU_MAIN_IRQ_MASK_HIGH_REG 0x20214
- +#define CPU_MAIN_FIQ_MASK_HIGH_REG 0x20218
- +#define CPU_ENPOINT_MASK_HIGH_REG 0x2021C
- +
- +
- +/*******************************************/
- +/* ARM Doorbell Registers Map */
- +/*******************************************/
- +
- +#define CPU_HOST_TO_ARM_DRBL_REG 0x20400
- +#define CPU_HOST_TO_ARM_MASK_REG 0x20404
- +#define CPU_ARM_TO_HOST_DRBL_REG 0x20408
- +#define CPU_ARM_TO_HOST_MASK_REG 0x2040C
- +
- +
- +
- +/* CPU control register map */
- +/* Set bits means value is about to change according to new value */
- +#define CPU_CONFIG_DEFAULT_MASK (CCR_VEC_INIT_LOC_MASK | CCR_AHB_ERROR_PROP_MASK)
- +
- +#define CPU_CONFIG_DEFAULT (CCR_VEC_INIT_LOC_FF00)
- +
- +/* CPU Control and status defaults */
- +#define CPU_CTRL_STAT_DEFAULT_MASK (CCSR_PCI_ACCESS_MASK)
- +
- +
- +#define CPU_CTRL_STAT_DEFAULT (CCSR_PCI_ACCESS_ENABLE)
- +
- +#endif /* __INCmvCpuIfRegsh */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 2010-11-09 20:28:08.042495347 +0100
- @@ -0,0 +1,324 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#include "mvSysAudio.h"
- +
- +/*******************************************************************************
- +* mvAudioWinSet - Set AUDIO target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the AUDIO will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - AUDIO target address decode window number.
- +* pAddrDecWin - AUDIO target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if address window overlapps with other address decode windows.
- +* MV_BAD_PARAM if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_DEC_REGS decRegs;
- +
- + /* Parameter checking */
- + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvAudioWinSet:Error setting AUDIO window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pAddrDecWin->target),
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + decRegs.baseReg = 0;
- + decRegs.sizeReg = 0;
- +
- + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
- +
- + /* set attributes */
- + decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;
- + decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);
- +
- + /* set target ID */
- + decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;
- + decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);
- +
- + if (pAddrDecWin->enable == MV_TRUE)
- + {
- + decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;
- + }
- + else
- + {
- + decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;
- + }
- +
- + MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(winNum), decRegs.sizeReg);
- + MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(winNum), decRegs.baseReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvAudioWinGet - Get AUDIO peripheral target address window.
- +*
- +* DESCRIPTION:
- +* Get AUDIO peripheral target address window.
- +*
- +* INPUT:
- +* winNum - AUDIO target address decode window number.
- +*
- +* OUTPUT:
- +* pAddrDecWin - AUDIO target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS decRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- +
- + /* Parameter checking */
- + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
- + __FUNCTION__, winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + decRegs.baseReg = MV_REG_READ( MV_AUDIO_WIN_BASE_REG(winNum) );
- + decRegs.sizeReg = MV_REG_READ( MV_AUDIO_WIN_CTRL_REG(winNum) );
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
- + {
- + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib = (decRegs.sizeReg & MV_AUDIO_WIN_ATTR_MASK) >>
- + MV_AUDIO_WIN_ATTR_OFFSET;
- + targetAttrib.targetId = (decRegs.sizeReg & MV_AUDIO_WIN_TARGET_MASK) >>
- + MV_AUDIO_WIN_TARGET_OFFSET;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + /* Check if window is enabled */
- + if(decRegs.sizeReg & MV_AUDIO_WIN_ENABLE_MASK)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- + return MV_OK;
- +}
- +/*******************************************************************************
- +* mvAudioAddrDecShow - Print the AUDIO address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the AUDIO address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvAudioAddrDecShow(MV_VOID)
- +{
- +
- + MV_AUDIO_DEC_WIN win;
- + int i;
- +
- + if (MV_FALSE == mvCtrlPwrClckGet(AUDIO_UNIT_ID, 0))
- + return;
- +
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "AUDIO:\n" );
- + mvOsOutput( "----\n" );
- +
- + for( i = 0; i < MV_AUDIO_MAX_ADDR_DECODE_WIN; i++ )
- + {
- + memset( &win, 0, sizeof(MV_AUDIO_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", i );
- +
- + if( mvAudioWinGet( i, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
- + mvOsOutput( "...." );
- +
- + mvSizePrint( win.addrWin.size );
- +
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- +}
- +
- +
- +/*******************************************************************************
- +* mvAudioWinInit - Initialize the integrated AUDIO target address window.
- +*
- +* DESCRIPTION:
- +* Initialize the AUDIO peripheral target address window.
- +*
- +* INPUT:
- +*
- +*
- +* OUTPUT:
- +*
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvAudioInit(MV_VOID)
- +{
- + int winNum;
- + MV_AUDIO_DEC_WIN audioWin;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + MV_U32 status;
- +
- + mvAudioHalInit();
- +
- + /* Initiate Audio address decode */
- +
- + /* First disable all address decode windows */
- + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
- + {
- + MV_U32 regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(winNum));
- + regVal &= ~MV_AUDIO_WIN_ENABLE_MASK;
- + MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(winNum), regVal);
- + }
- +
- + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
- + {
- +
- + /* We will set the Window to DRAM_CS0 in default */
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(SDRAM_CS0,
- + &cpuAddrDecWin);
- +
- + if (MV_OK != status)
- + {
- + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + audioWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + audioWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + audioWin.enable = MV_TRUE;
- + audioWin.target = SDRAM_CS0;
- +
- + if(MV_OK != mvAudioWinSet(winNum, &audioWin))
- + {
- + return MV_ERROR;
- + }
- + }
- + }
- +
- + return MV_OK;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 2010-11-09 20:28:08.082495466 +0100
- @@ -0,0 +1,123 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#ifndef __INCMVSysAudioH
- +#define __INCMVSysAudioH
- +
- +#include "mvCommon.h"
- +#include "audio/mvAudio.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +/***********************************/
- +/* Audio Address Decoding registers*/
- +/***********************************/
- +
- +#define MV_AUDIO_MAX_ADDR_DECODE_WIN 2
- +#define MV_AUDIO_RECORD_WIN_NUM 0
- +#define MV_AUDIO_PLAYBACK_WIN_NUM 1
- +
- +#define MV_AUDIO_WIN_CTRL_REG(win) (AUDIO_REG_BASE + 0xA04 + ((win)<<3))
- +#define MV_AUDIO_WIN_BASE_REG(win) (AUDIO_REG_BASE + 0xA00 + ((win)<<3))
- +
- +#define MV_AUDIO_RECORD_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_RECORD_WIN_NUM)
- +#define MV_AUDIO_RECORD_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_RECORD_WIN_NUM)
- +#define MV_AUDIO_PLAYBACK_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
- +#define MV_AUDIO_PLAYBACK_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
- +
- +
- +/* BITs in Windows 0-3 Control and Base Registers */
- +#define MV_AUDIO_WIN_ENABLE_BIT 0
- +#define MV_AUDIO_WIN_ENABLE_MASK (1<<MV_AUDIO_WIN_ENABLE_BIT)
- +
- +#define MV_AUDIO_WIN_TARGET_OFFSET 4
- +#define MV_AUDIO_WIN_TARGET_MASK (0xF<<MV_AUDIO_WIN_TARGET_OFFSET)
- +
- +#define MV_AUDIO_WIN_ATTR_OFFSET 8
- +#define MV_AUDIO_WIN_ATTR_MASK (0xFF<<MV_AUDIO_WIN_ATTR_OFFSET)
- +
- +#define MV_AUDIO_WIN_SIZE_OFFSET 16
- +#define MV_AUDIO_WIN_SIZE_MASK (0xFFFF<<MV_AUDIO_WIN_SIZE_OFFSET)
- +
- +#define MV_AUDIO_WIN_BASE_OFFSET 16
- +#define MV_AUDIO_WIN_BASE_MASK (0xFFFF<<MV_AUDIO_WIN_BASE_OFFSET)
- +
- +
- +typedef struct _mvAudioDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +} MV_AUDIO_DEC_WIN;
- +
- +
- +MV_STATUS mvAudioInit(MV_VOID);
- +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvAudioWinInit(MV_VOID);
- +MV_VOID mvAudioAddrDecShow(MV_VOID);
- +
- +
- +#endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 2010-11-09 20:28:08.121241788 +0100
- @@ -0,0 +1,382 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvSysCesa.h"
- +
- +#if (MV_CESA_VERSION >= 2)
- +MV_TARGET tdmaAddrDecPrioTable[] =
- +{
- +#if defined(MV_INCLUDE_SDRAM_CS0)
- + SDRAM_CS0,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + SDRAM_CS1,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS2)
- + SDRAM_CS2,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS3)
- + SDRAM_CS3,
- +#endif
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_MEM,
- +#endif
- +
- + TBL_TERM
- +};
- +
- +/*******************************************************************************
- +* mvCesaWinGet - Get TDMA target address window.
- +*
- +* DESCRIPTION:
- +* Get TDMA target address window.
- +*
- +* INPUT:
- +* winNum - TDMA target address decode window number.
- +*
- +* OUTPUT:
- +* pDecWin - TDMA target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaWinGet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
- +{
- + MV_DEC_WIN_PARAMS winParam;
- + MV_U32 sizeReg, baseReg;
- +
- + /* Parameter checking */
- + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
- + {
- + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
- + __FUNCTION__, winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + baseReg = MV_REG_READ( MV_CESA_TDMA_BASE_ADDR_REG(winNum) );
- + sizeReg = MV_REG_READ( MV_CESA_TDMA_WIN_CTRL_REG(winNum) );
- +
- + /* Check if window is enabled */
- + if(sizeReg & MV_CESA_TDMA_WIN_ENABLE_MASK)
- + {
- + pDecWin->enable = MV_TRUE;
- +
- + /* Extract window parameters from registers */
- + winParam.targetId = (sizeReg & MV_CESA_TDMA_WIN_TARGET_MASK) >> MV_CESA_TDMA_WIN_TARGET_OFFSET;
- + winParam.attrib = (sizeReg & MV_CESA_TDMA_WIN_ATTR_MASK) >> MV_CESA_TDMA_WIN_ATTR_OFFSET;
- + winParam.size = (sizeReg & MV_CESA_TDMA_WIN_SIZE_MASK) >> MV_CESA_TDMA_WIN_SIZE_OFFSET;
- + winParam.baseAddr = (baseReg & MV_CESA_TDMA_WIN_BASE_MASK);
- +
- + /* Translate the decode window parameters to address decode struct */
- + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
- + {
- + mvOsPrintf("Failed to translate register parameters to CESA address" \
- + " decode window structure\n");
- + return MV_ERROR;
- + }
- + }
- + else
- + {
- + pDecWin->enable = MV_FALSE;
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* cesaWinOverlapDetect - Detect CESA TDMA address windows overlapping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviur is expected in case TDMA address decode
- +* windows overlapps.
- +* This function detects TDMA address decode windows overlapping of a
- +* specified window. The function does not check the window itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE - if the given address window overlap current address
- +* decode map,
- +* MV_FALSE - otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS cesaWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 winNumIndex;
- + MV_DEC_WIN addrDecWin;
- +
- + for(winNumIndex=0; winNumIndex<MV_CESA_TDMA_ADDR_DEC_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if (winNumIndex == winNum)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvCesaWinGet(winNumIndex, &addrDecWin))
- + {
- + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled windows */
- + if(addrDecWin.enable == MV_FALSE)
- + {
- + continue;
- + }
- +
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* mvCesaTdmaWinSet - Set CESA TDMA target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the CESA TDMA will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - CESA TDMA target address decode window number.
- +* pAddrDecWin - CESA TDMA target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR - if address window overlapps with other address decode windows.
- +* MV_BAD_PARAM - if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +static MV_STATUS mvCesaTdmaWinSet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
- +{
- + MV_DEC_WIN_PARAMS winParams;
- + MV_U32 sizeReg, baseReg;
- +
- + /* Parameter checking */
- + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
- + {
- + mvOsPrintf("mvCesaTdmaWinSet: ERR. Invalid win num %d\n",winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlapps with current windows */
- + if (MV_TRUE == cesaWinOverlapDetect(winNum, &pDecWin->addrWin))
- + {
- + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
- + return MV_ERROR;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvCesaTdmaWinSet: Error setting CESA TDMA window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pDecWin->target),
- + pDecWin->addrWin.baseLow,
- + pDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
- + {
- + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* set Size, Attributes and TargetID */
- + sizeReg = (((winParams.targetId << MV_CESA_TDMA_WIN_TARGET_OFFSET) & MV_CESA_TDMA_WIN_TARGET_MASK) |
- + ((winParams.attrib << MV_CESA_TDMA_WIN_ATTR_OFFSET) & MV_CESA_TDMA_WIN_ATTR_MASK) |
- + ((winParams.size << MV_CESA_TDMA_WIN_SIZE_OFFSET) & MV_CESA_TDMA_WIN_SIZE_MASK));
- +
- + if (pDecWin->enable == MV_TRUE)
- + {
- + sizeReg |= MV_CESA_TDMA_WIN_ENABLE_MASK;
- + }
- + else
- + {
- + sizeReg &= ~MV_CESA_TDMA_WIN_ENABLE_MASK;
- + }
- +
- + /* Update Base value */
- + baseReg = (winParams.baseAddr & MV_CESA_TDMA_WIN_BASE_MASK);
- +
- + MV_REG_WRITE( MV_CESA_TDMA_WIN_CTRL_REG(winNum), sizeReg);
- + MV_REG_WRITE( MV_CESA_TDMA_BASE_ADDR_REG(winNum), baseReg);
- +
- + return MV_OK;
- +}
- +
- +
- +static MV_STATUS mvCesaTdmaAddrDecInit (void)
- +{
- + MV_U32 winNum;
- + MV_STATUS status;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + MV_DEC_WIN cesaWin;
- + MV_U32 winPrioIndex = 0;
- +
- + /* First disable all address decode windows */
- + for(winNum=0; winNum<MV_CESA_TDMA_ADDR_DEC_WIN; winNum++)
- + {
- + MV_REG_BIT_RESET(MV_CESA_TDMA_WIN_CTRL_REG(winNum), MV_CESA_TDMA_WIN_ENABLE_MASK);
- + }
- +
- + /* Go through all windows in user table until table terminator */
- + winNum = 0;
- + while( (tdmaAddrDecPrioTable[winPrioIndex] != TBL_TERM) &&
- + (winNum < MV_CESA_TDMA_ADDR_DEC_WIN) ) {
- +
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(tdmaAddrDecPrioTable[winPrioIndex],
- + &cpuAddrDecWin);
- + if(MV_NO_SUCH == status){
- + winPrioIndex++;
- + continue;
- + }
- +
- + if (MV_OK != status)
- + {
- + mvOsPrintf("cesaInit: TargetWinGet failed. winNum=%d, winIdx=%d, target=%d, status=0x%x\n",
- + winNum, winPrioIndex, tdmaAddrDecPrioTable[winPrioIndex], status);
- + return MV_ERROR;
- + }
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + cesaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + cesaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + cesaWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + cesaWin.enable = MV_TRUE;
- + cesaWin.target = tdmaAddrDecPrioTable[winPrioIndex];
- +
- +#if defined(MV646xx)
- + /* Get the default attributes for that target window */
- + mvCtrlDefAttribGet(cesaWin.target, &cesaWin.addrWinAttr);
- +#endif /* MV646xx */
- +
- + if(MV_OK != mvCesaTdmaWinSet(winNum, &cesaWin))
- + {
- + mvOsPrintf("mvCesaTdmaWinSet FAILED: winNum=%d\n",
- + winNum);
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex++;
- + }
- + return MV_OK;
- +}
- +#endif /* MV_CESA_VERSION >= 2 */
- +
- +
- +
- +
- +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle)
- +{
- + MV_U32 cesaCryptEngBase;
- + MV_CPU_DEC_WIN addrDecWin;
- +
- + if(sizeof(MV_CESA_SRAM_MAP) > MV_CESA_SRAM_SIZE)
- + {
- + mvOsPrintf("mvCesaInit: Wrong SRAM map - %ld > %d\n",
- + sizeof(MV_CESA_SRAM_MAP), MV_CESA_SRAM_SIZE);
- + return MV_FAIL;
- + }
- +#if 0
- + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
- + cesaCryptEngBase = addrDecWin.addrWin.baseLow;
- + else
- + {
- + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +#else
- + cesaCryptEngBase = (MV_U32)pSramBase;
- +#endif
- +
- +#if 0 /* Already done in the platform init */
- +#if (MV_CESA_VERSION >= 2)
- + mvCesaTdmaAddrDecInit();
- +#endif /* MV_CESA_VERSION >= 2 */
- +#endif
- + return mvCesaHalInit(numOfSession, queueDepth, pSramBase, cesaCryptEngBase,
- + osHandle);
- +
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 2010-11-09 20:28:08.152495441 +0100
- @@ -0,0 +1,100 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __mvSysCesa_h__
- +#define __mvSysCesa_h__
- +
- +
- +#include "mvCommon.h"
- +#include "cesa/mvCesa.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +/***************************** TDMA Registers *************************************/
- +
- +#define MV_CESA_TDMA_ADDR_DEC_WIN 4
- +
- +#define MV_CESA_TDMA_BASE_ADDR_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa00 + (win<<3))
- +
- +#define MV_CESA_TDMA_WIN_CTRL_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa04 + (win<<3))
- +
- +#define MV_CESA_TDMA_WIN_ENABLE_BIT 0
- +#define MV_CESA_TDMA_WIN_ENABLE_MASK (1 << MV_CESA_TDMA_WIN_ENABLE_BIT)
- +
- +#define MV_CESA_TDMA_WIN_TARGET_OFFSET 4
- +#define MV_CESA_TDMA_WIN_TARGET_MASK (0xf << MV_CESA_TDMA_WIN_TARGET_OFFSET)
- +
- +#define MV_CESA_TDMA_WIN_ATTR_OFFSET 8
- +#define MV_CESA_TDMA_WIN_ATTR_MASK (0xff << MV_CESA_TDMA_WIN_ATTR_OFFSET)
- +
- +#define MV_CESA_TDMA_WIN_SIZE_OFFSET 16
- +#define MV_CESA_TDMA_WIN_SIZE_MASK (0xFFFF << MV_CESA_TDMA_WIN_SIZE_OFFSET)
- +
- +#define MV_CESA_TDMA_WIN_BASE_OFFSET 16
- +#define MV_CESA_TDMA_WIN_BASE_MASK (0xFFFF << MV_CESA_TDMA_WIN_BASE_OFFSET)
- +
- +
- +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle);
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 2010-11-09 20:28:08.192500699 +0100
- @@ -0,0 +1,348 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +/* includes */
- +
- +#include "ddr2/mvDramIf.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "ctrlEnv/sys/mvSysDram.h"
- +
- +/* #define MV_DEBUG */
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
- +
- +/*******************************************************************************
- +* mvDramIfWinSet - Set DRAM interface address decode window
- +*
- +* DESCRIPTION:
- +* This function sets DRAM interface address decode window.
- +*
- +* INPUT:
- +* target - System target. Use only SDRAM targets.
- +* pAddrDecWin - SDRAM address window structure.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
- +* otherwise.
- +*******************************************************************************/
- +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
- +{
- + MV_U32 baseReg=0,sizeReg=0;
- + MV_U32 baseToReg=0 , sizeToReg=0;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(target))
- + {
- + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlaps with current enabled windows */
- + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
- + return MV_BAD_PARAM;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
- + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + target,
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + /* read base register*/
- + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
- +
- + /* read size register */
- + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
- +
- + /* BaseLow[31:16] => base register [31:16] */
- + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
- +
- + /* Write to address decode Base Address Register */
- + baseReg &= ~SCBAR_BASE_MASK;
- + baseReg |= baseToReg;
- +
- + /* Translate the given window size to register format */
- + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
- +
- + /* Size parameter validity check. */
- + if (-1 == sizeToReg)
- + {
- + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
- + return MV_BAD_PARAM;
- + }
- +
- + /* set size */
- + sizeReg &= ~SCSR_SIZE_MASK;
- + /* Size is located at upper 16 bits */
- + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
- +
- + /* enable/Disable */
- + if (MV_TRUE == pAddrDecWin->enable)
- + {
- + sizeReg |= SCSR_WIN_EN;
- + }
- + else
- + {
- + sizeReg &= ~SCSR_WIN_EN;
- + }
- +
- + /* 3) Write to address decode Base Address Register */
- + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(0,target), baseReg);
- +
- + /* Write to address decode Size Register */
- + MV_REG_WRITE(SDRAM_SIZE_REG(0,target), sizeReg);
- +
- + return MV_OK;
- +}
- +/*******************************************************************************
- +* mvDramIfWinGet - Get DRAM interface address decode window
- +*
- +* DESCRIPTION:
- +* This function gets DRAM interface address decode window.
- +*
- +* INPUT:
- +* target - System target. Use only SDRAM targets.
- +*
- +* OUTPUT:
- +* pAddrDecWin - SDRAM address window structure.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
- +* otherwise.
- +*******************************************************************************/
- +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
- +{
- + MV_U32 baseReg,sizeReg;
- + MV_U32 sizeRegVal;
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(target))
- + {
- + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + /* Read base and size registers */
- + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
- + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
- +
- + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
- +
- + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
- + SCSR_SIZE_ALIGNMENT);
- +
- + /* Check if ctrlRegToSize returned OK */
- + if (-1 == pAddrDecWin->addrWin.size)
- + {
- + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + /* Extract base address */
- + /* Base register [31:16] ==> baseLow[31:16] */
- + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
- +
- + pAddrDecWin->addrWin.baseHigh = 0;
- +
- +
- + if (sizeReg & SCSR_WIN_EN)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- +
- + return MV_OK;
- +}
- +/*******************************************************************************
- +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
- +*
- +* DESCRIPTION:
- +* This function enable/Disable SDRAM address decode window.
- +*
- +* INPUT:
- +* target - System target. Use only SDRAM targets.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable)
- +{
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(target))
- + {
- + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + if (enable == MV_TRUE)
- + { /* First check for overlap with other enabled windows */
- + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
- + {
- + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
- + target);
- + return MV_ERROR;
- + }
- + /* Check for overlapping */
- + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
- + {
- + /* No Overlap. Enable address decode winNum window */
- + MV_REG_BIT_SET(SDRAM_SIZE_REG(0,target), SCSR_WIN_EN);
- + }
- + else
- + { /* Overlap detected */
- + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
- + target);
- + return MV_ERROR;
- + }
- + }
- + else
- + { /* Disable address decode winNum window */
- + MV_REG_BIT_RESET(SDRAM_SIZE_REG(0, target), SCSR_WIN_EN);
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
- +*
- +* DESCRIPTION:
- +* This function scan each SDRAM address decode window to test if it
- +* overlapps the given address windoow
- +*
- +* INPUT:
- +* target - SDRAM target where the function skips checking.
- +* pAddrDecWin - The tested address window for overlapping with
- +* SDRAM windows.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlaps any enabled address
- +* decode map, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_TARGET targetNum;
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
- + {
- + /* don't check our winNum or illegal targets */
- + if (targetNum == target)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
- + {
- + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled windows */
- + if (MV_FALSE == addrDecWin.enable)
- + {
- + continue;
- + }
- +
- + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
- + {
- + mvOsPrintf(
- + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
- + target, targetNum);
- + return MV_TRUE;
- + }
- + }
- +
- + return MV_FALSE;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 2010-11-09 20:28:08.232495451 +0100
- @@ -0,0 +1,80 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __sysDram
- +#define __sysDram
- +
- +/* This structure describes CPU interface address decode window */
- +typedef struct _mvDramIfDecWin
- +{
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +}MV_DRAM_DEC_WIN;
- +
- +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable);
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 2010-11-09 20:28:08.262495451 +0100
- @@ -0,0 +1,658 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#include "ctrlEnv/sys/mvSysGbe.h"
- +
- +
- +
- +typedef struct _mvEthDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_ETH_DEC_WIN;
- +
- +MV_TARGET ethAddrDecPrioTap[] =
- +{
- +#if defined(MV_INCLUDE_SDRAM_CS0)
- + SDRAM_CS0,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + SDRAM_CS1,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS2)
- + SDRAM_CS2,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS3)
- + SDRAM_CS3,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS0)
- + DEVICE_CS0,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS1)
- + DEVICE_CS1,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS2)
- + DEVICE_CS2,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS3)
- + DEVICE_CS3,
- +#endif
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_IO,
- +#endif
- + TBL_TERM
- +};
- +
- +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
- +static MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
- +static MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
- +
- +
- +/*******************************************************************************
- +* mvEthWinInit - Initialize ETH address decode windows
- +*
- +* DESCRIPTION:
- +* This function initialize ETH window decode unit. It set the
- +* default address decode windows of the unit.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if setting fail.
- +*******************************************************************************/
- +/* Configure EthDrv memory map registes. */
- +MV_STATUS mvEthWinInit (int port)
- +{
- + MV_U32 winNum, status, winPrioIndex=0, i, regVal=0;
- + MV_ETH_DEC_WIN ethWin;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + static MV_U32 accessProtReg = 0;
- +
- +#if (MV_ETH_VERSION <= 1)
- + static MV_BOOL isFirst = MV_TRUE;
- +
- + if(isFirst == MV_FALSE)
- + {
- + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
- + return MV_OK;
- + }
- + isFirst = MV_FALSE;
- +#endif /* MV_GIGA_ETH_VERSION */
- +
- + /* Initiate Ethernet address decode */
- +
- + /* First disable all address decode windows */
- + for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
- + {
- + regVal |= MV_BIT_MASK(winNum);
- + }
- + MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal);
- +
- + /* Go through all windows in user table until table terminator */
- + for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
- + (winNum < ETH_MAX_DECODE_WIN)); )
- + {
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex],
- + &cpuAddrDecWin);
- +
- + if(MV_NO_SUCH == status)
- + {
- + winPrioIndex++;
- + continue;
- + }
- + if (MV_OK != status)
- + {
- + mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + ethWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + ethWin.enable = MV_TRUE;
- + ethWin.target = ethAddrDecPrioTap[winPrioIndex];
- +
- + if(MV_OK != mvEthWinSet(port, winNum, ðWin))
- + {
- + mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n",
- + winNum);
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex ++;
- + }
- +
- + /* set full access to all windows. */
- + for(i=0; i<winNum; i++)
- + {
- + accessProtReg |= (FULL_ACCESS << (i*2));
- + }
- + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthWinSet - Set ETH target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the ETH will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - ETH to target address decode window number.
- +* pAddrDecWin - ETH target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if address window overlapps with other address decode windows.
- +* MV_BAD_PARAM if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_DEC_REGS decRegs;
- +
- + /* Parameter checking */
- + if (winNum >= ETH_MAX_DECODE_WIN)
- + {
- + mvOsPrintf("mvEthWinSet: ERR. Invalid win num %d\n",winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlapps with current windows */
- + if (MV_TRUE == ethWinOverlapDetect(port, winNum, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvEthWinSet: ERR. Window %d overlap\n", winNum);
- + return MV_ERROR;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvEthWinSet: Error setting Ethernet window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pAddrDecWin->target),
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- +
- + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
- + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
- +
- + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("mvEthWinSet:mvCtrlAddrDecToReg Failed\n");
- + return MV_ERROR;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
- +
- + /* set attributes */
- + decRegs.baseReg &= ~ETH_WIN_ATTR_MASK;
- + decRegs.baseReg |= targetAttribs.attrib << ETH_WIN_ATTR_OFFS;
- + /* set target ID */
- + decRegs.baseReg &= ~ETH_WIN_TARGET_MASK;
- + decRegs.baseReg |= targetAttribs.targetId << ETH_WIN_TARGET_OFFS;
- +
- + /* for the safe side we disable the window before writing the new
- + values */
- + mvEthWinEnable(port, winNum, MV_FALSE);
- + MV_REG_WRITE(ETH_WIN_BASE_REG(port, winNum), decRegs.baseReg);
- +
- + /* Write to address decode Size Register */
- + MV_REG_WRITE(ETH_WIN_SIZE_REG(port, winNum), decRegs.sizeReg);
- +
- + /* Enable address decode target window */
- + if (pAddrDecWin->enable == MV_TRUE)
- + {
- + mvEthWinEnable(port, winNum, MV_TRUE);
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvETHWinGet - Get dma peripheral target address window.
- +*
- +* DESCRIPTION:
- +* Get ETH peripheral target address window.
- +*
- +* INPUT:
- +* winNum - ETH to target address decode window number.
- +*
- +* OUTPUT:
- +* pAddrDecWin - ETH target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS decRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- +
- + /* Parameter checking */
- + if (winNum >= ETH_MAX_DECODE_WIN)
- + {
- + mvOsPrintf("mvEthWinGet: ERR. Invalid winNum %d\n", winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
- + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
- + {
- + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib =
- + (decRegs.baseReg & ETH_WIN_ATTR_MASK) >> ETH_WIN_ATTR_OFFS;
- + targetAttrib.targetId =
- + (decRegs.baseReg & ETH_WIN_TARGET_MASK) >> ETH_WIN_TARGET_OFFS;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + /* Check if window is enabled */
- + if (~(MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port))) & (1 << winNum) )
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthWinEnable - Enable/disable a ETH to target address window
- +*
- +* DESCRIPTION:
- +* This function enable/disable a ETH to target address window.
- +* According to parameter 'enable' the routine will enable the
- +* window, thus enabling ETH accesses (before enabling the window it is
- +* tested for overlapping). Otherwise, the window will be disabled.
- +*
- +* INPUT:
- +* winNum - ETH to target address decode window number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_ERROR if decode window number was wrong or enabled window overlapps.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum,MV_BOOL enable)
- +{
- + MV_ETH_DEC_WIN addrDecWin;
- +
- + /* Parameter checking */
- + if (winNum >= ETH_MAX_DECODE_WIN)
- + {
- + mvOsPrintf("mvEthTargetWinEnable:ERR. Invalid winNum%d\n",winNum);
- + return MV_ERROR;
- + }
- +
- + if (enable == MV_TRUE)
- + { /* First check for overlap with other enabled windows */
- + /* Get current window */
- + if (MV_OK != mvEthWinGet(port, winNum, &addrDecWin))
- + {
- + mvOsPrintf("mvEthTargetWinEnable:ERR. targetWinGet fail\n");
- + return MV_ERROR;
- + }
- + /* Check for overlapping */
- + if (MV_FALSE == ethWinOverlapDetect(port, winNum, &(addrDecWin.addrWin)))
- + {
- + /* No Overlap. Enable address decode target window */
- + MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
- + }
- + else
- + { /* Overlap detected */
- + mvOsPrintf("mvEthTargetWinEnable:ERR. Overlap detected\n");
- + return MV_ERROR;
- + }
- + }
- + else
- + { /* Disable address decode target window */
- + MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthWinTargetGet - Get Window number associated with target
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +* window number
- +*
- +*******************************************************************************/
- +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target)
- +{
- + MV_ETH_DEC_WIN decWin;
- + MV_U32 winNum;
- +
- + /* Check parameters */
- + if (target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
- + return 0xffffffff;
- + }
- +
- + for (winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
- + {
- + if (mvEthWinGet(port, winNum,&decWin) != MV_OK)
- + {
- + mvOsPrintf("mvAhbToMbusWinTargetGet: window returned error\n");
- + return 0xffffffff;
- + }
- +
- + if (decWin.enable == MV_TRUE)
- + {
- + if (decWin.target == target)
- + {
- + return winNum;
- + }
- + }
- + }
- + return 0xFFFFFFFF;
- +}
- +
- +/*******************************************************************************
- +* mvEthProtWinSet - Set access protection of Ethernet to target window.
- +*
- +* DESCRIPTION:
- +* Each Ethernet port can be configured with access attributes for each
- +* of the Ethenret to target windows (address decode windows). This
- +* function sets access attributes to a given window for the given channel.
- +*
- +* INPUTS:
- +* ethPort - ETH channel number. See MV_ETH_CHANNEL enumerator.
- +* winNum - IETH to target address decode window number.
- +* access - IETH access rights. See MV_ACCESS_RIGHTS enumerator.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR in case window number is invalid or access right reserved.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS access)
- +{
- + MV_U32 protReg;
- +
- + /* Parameter checking */
- + if(portNo >= mvCtrlEthMaxPortGet())
- + {
- + mvOsPrintf("mvEthProtWinSet:ERR. Invalid port number %d\n", portNo);
- + return MV_ERROR;
- + }
- +
- + if (winNum >= ETH_MAX_DECODE_WIN)
- + {
- + mvOsPrintf("mvEthProtWinSet:ERR. Invalid winNum%d\n",winNum);
- + return MV_ERROR;
- + }
- +
- + if((access == ACC_RESERVED) || (access >= MAX_ACC_RIGHTS))
- + {
- + mvOsPrintf("mvEthProtWinSet:ERR. Inv access param %d\n", access);
- + return MV_ERROR;
- + }
- + /* Read current protection register */
- + protReg = MV_REG_READ(ETH_ACCESS_PROTECT_REG(portNo));
- +
- + /* Clear protection window field */
- + protReg &= ~(ETH_PROT_WIN_MASK(winNum));
- +
- + /* Set new protection field value */
- + protReg |= (access << (ETH_PROT_WIN_OFFS(winNum)));
- +
- + /* Write protection register back */
- + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(portNo), protReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* ethWinOverlapDetect - Detect ETH address windows overlapping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviur is expected in case ETH address decode
- +* windows overlapps.
- +* This function detects ETH address decode windows overlapping of a
- +* specified window. The function does not check the window itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 baseAddrEnableReg;
- + MV_U32 winNumIndex;
- + MV_ETH_DEC_WIN addrDecWin;
- +
- + /* Read base address enable register. Do not check disabled windows */
- + baseAddrEnableReg = MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port));
- +
- + for (winNumIndex=0; winNumIndex<ETH_MAX_DECODE_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if (winNumIndex == winNum)
- + {
- + continue;
- + }
- +
- + /* Do not check disabled windows */
- + if (baseAddrEnableReg & (1 << winNumIndex))
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvEthWinGet(port, winNumIndex, &addrDecWin))
- + {
- + mvOsPrintf("ethWinOverlapDetect: ERR. TargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +/*
- + mvOsPrintf("ethWinOverlapDetect:\n
- + winNumIndex =%d baseHigh =0x%x baseLow=0x%x size=0x%x enable=0x%x\n",
- + winNumIndex,
- + addrDecWin.addrWin.baseHigh,
- + addrDecWin.addrWin.baseLow,
- + addrDecWin.addrWin.size,
- + addrDecWin.enable);
- +*/
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* mvEthAddrDecShow - Print the Etherent address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the Etherent address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +void mvEthPortAddrDecShow(int port)
- +{
- + MV_ETH_DEC_WIN win;
- + int i;
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "ETH %d:\n", port );
- + mvOsOutput( "----\n" );
- +
- + for( i = 0; i < ETH_MAX_DECODE_WIN; i++ )
- + {
- + memset( &win, 0, sizeof(ETH_MAX_DECODE_WIN) );
- +
- + mvOsOutput( "win%d - ", i );
- +
- + if( mvEthWinGet(port, i, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
- + mvOsOutput( "...." );
- + mvSizePrint( win.addrWin.size );
- +
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- + return;
- +}
- +
- +void mvEthAddrDecShow(void)
- +{
- + int port;
- +
- + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
- + {
- + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
- +
- + mvEthPortAddrDecShow(port);
- + }
- +}
- +
- +
- +void mvEthInit(void)
- +{
- + MV_U32 port;
- +
- + /* Power down all existing ports */
- + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
- + {
- + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port))
- + continue;
- +
- + mvEthPortPowerUp(port);
- + mvEthWinInit(port);
- + }
- + mvEthHalInit();
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 2010-11-09 20:28:08.292495558 +0100
- @@ -0,0 +1,113 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSysGbeh
- +#define __INCmvSysGbeh
- +
- +#include "mvCommon.h"
- +#include "eth/mvEth.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +#define ETH_WIN_BASE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x200 + ((win)<<3))
- +#define ETH_WIN_SIZE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x204 + ((win)<<3))
- +#define ETH_WIN_REMAP_REG(port, win) (MV_ETH_REG_BASE(port) + 0x280 + ((win)<<2))
- +#define ETH_BASE_ADDR_ENABLE_REG(port) (MV_ETH_REG_BASE(port) + 0x290)
- +#define ETH_ACCESS_PROTECT_REG(port) (MV_ETH_REG_BASE(port) + 0x294)
- +
- +/**** Address decode parameters ****/
- +
- +/* Ethernet Base Address Register bits */
- +#define ETH_MAX_DECODE_WIN 6
- +#define ETH_MAX_HIGH_ADDR_REMAP_WIN 4
- +
- +/* Ethernet Port Access Protect (EPAP) register */
- +
- +/* The target associated with this window*/
- +#define ETH_WIN_TARGET_OFFS 0
- +#define ETH_WIN_TARGET_MASK (0xf << ETH_WIN_TARGET_OFFS)
- +/* The target attributes Associated with window */
- +#define ETH_WIN_ATTR_OFFS 8
- +#define ETH_WIN_ATTR_MASK (0xff << ETH_WIN_ATTR_OFFS)
- +
- +/* Ethernet Port Access Protect Register (EPAPR) */
- +#define ETH_PROT_NO_ACCESS NO_ACCESS_ALLOWED
- +#define ETH_PROT_READ_ONLY READ_ONLY
- +#define ETH_PROT_FULL_ACCESS FULL_ACCESS
- +#define ETH_PROT_WIN_OFFS(winNum) (2 * (winNum))
- +#define ETH_PROT_WIN_MASK(winNum) (0x3 << ETH_PROT_WIN_OFFS(winNum))
- +
- +MV_STATUS mvEthWinInit (int port);
- +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum, MV_BOOL enable);
- +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target);
- +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS
- + access);
- +
- +void mvEthPortAddrDecShow(int port);
- +
- +MV_VOID mvEthAddrDecShow(MV_VOID);
- +
- +void mvEthInit(void);
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 2010-11-09 20:28:08.332495446 +0100
- @@ -0,0 +1,1697 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "ctrlEnv/sys/mvSysPex.h"
- +
- +/* this structure describes the mapping between a Pex Window and a CPU target*/
- +typedef struct _pexWinToTarget
- +{
- + MV_TARGET target;
- + MV_BOOL enable;
- +
- +}PEX_WIN_TO_TARGET;
- +
- +/* this array is a priority array that define How Pex windows should be
- +configured , We have only 6 Pex Windows that can be configured , but we
- +have maximum of 9 CPU target windows ! the following array is a priority
- +array where the lowest index has the highest priotiy and the highest
- +index has the lowest priority of being cnfigured */
- +
- +MV_U32 pexDevBarPrioTable[] =
- +{
- +#if defined(MV_INCLUDE_DEVICE_CS0)
- + DEVICE_CS0,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS1)
- + DEVICE_CS1,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS2)
- + DEVICE_CS2,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS3)
- + DEVICE_CS3,
- +#endif
- +/*
- +#if defined(MV_INCLUDE_DEVICE_CS4)
- + DEVICE_CS4,
- +#endif
- +*/
- + TBL_TERM
- +};
- +
- +
- +/* PEX Wins registers offsets are inconsecutive. This struct describes WIN */
- +/* register offsets and its function where its is located. */
- +/* Also, PEX address remap registers offsets are inconsecutive. This struct */
- +/* describes address remap register offsets */
- +typedef struct _pexWinRegInfo
- +{
- + MV_U32 baseLowRegOffs;
- + MV_U32 baseHighRegOffs;
- + MV_U32 sizeRegOffs;
- + MV_U32 remapLowRegOffs;
- + MV_U32 remapHighRegOffs;
- +
- +}PEX_WIN_REG_INFO;
- +
- +static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,
- + MV_ADDR_WIN *pAddrWin);
- +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,
- + PEX_WIN_REG_INFO *pWinRegInfo);
- +
- +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);
- +
- +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);
- +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,
- + MV_ADDR_WIN *pAddrWin);
- +const MV_8* pexBarNameGet( MV_U32 bar );
- +
- +
- +/*******************************************************************************
- +* mvPexInit - Initialize PEX interfaces
- +*
- +* DESCRIPTION:
- +*
- +* This function is responsible of intialization of the Pex Interface , It
- +* configure the Pex Bars and Windows in the following manner:
- +*
- +* Assumptions :
- +* Bar0 is always internal registers bar
- +* Bar1 is always the DRAM bar
- +* Bar2 is always the Device bar
- +*
- +* 1) Sets the Internal registers bar base by obtaining the base from
- +* the CPU Interface
- +* 2) Sets the DRAM bar base and size by getting the base and size from
- +* the CPU Interface when the size is the sum of all enabled DRAM
- +* chip selects and the base is the base of CS0 .
- +* 3) Sets the Device bar base and size by getting these values from the
- +* CPU Interface when the base is the base of the lowest base of the
- +* Device chip selects, and the
- +*
- +*
- +* INPUT:
- +*
- +* pexIf - PEX interface number.
- +*
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
- +{
- + MV_U32 bar;
- + MV_U32 winNum;
- + MV_PEX_BAR pexBar;
- + MV_PEX_DEC_WIN pexWin;
- + MV_CPU_DEC_WIN addrDecWin;
- + MV_TARGET target;
- + MV_U32 pexCurrWin=0;
- + MV_U32 status;
- + /* default and exapntion rom
- + are always configured */
- +
- +#ifndef MV_DISABLE_PEX_DEVICE_BAR
- + MV_U32 winIndex;
- + MV_U32 maxBase=0, sizeOfMaxBase=0;
- + MV_U32 pexStartWindow;
- +#endif
- +
- + /* Parameter checking */
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Enabled CPU access to PCI-Express */
- + mvCpuIfEnablePex(pexIf, pexType);
- +
- + /* Start with bars */
- + /* First disable all PEX bars*/
- + for (bar = 0; bar < PEX_MAX_BARS; bar++)
- + {
- + if (PEX_INTER_REGS_BAR != bar)
- + {
- + if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
- + {
- + mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
- + return MV_ERROR;
- + }
- +
- + }
- +
- + }
- +
- + /* and disable all PEX target windows */
- + for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
- + {
- + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
- + {
- + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
- + winNum);
- + return MV_ERROR;
- +
- + }
- + }
- +
- + /* Now, go through all bars*/
- +
- +
- +
- +/******************************************************************************/
- +/* Internal registers bar */
- +/******************************************************************************/
- + bar = PEX_INTER_REGS_BAR;
- +
- + /* we only open the bar , no need to open windows for this bar */
- +
- + /* first get the CS attribute from the CPU Interface */
- + if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
- + {
- + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
- + return MV_ERROR;
- + }
- +
- + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
- + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
- + pexBar.addrWin.size = addrDecWin.addrWin.size;
- + pexBar.enable = MV_TRUE;
- +
- + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
- + {
- + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
- + return MV_ERROR;
- + }
- +
- +/******************************************************************************/
- +/* DRAM bar */
- +/******************************************************************************/
- +
- + bar = PEX_DRAM_BAR;
- +
- + pexBar.addrWin.size = 0;
- +
- + for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
- + {
- +
- + status = mvCpuIfTargetWinGet(target,&addrDecWin);
- +
- + if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
- + {
- + continue;
- + }
- +
- + /* first get attributes from CPU If */
- + if (MV_OK != status)
- + {
- + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
- + return MV_ERROR;
- + }
- + if (addrDecWin.enable == MV_TRUE)
- + {
- + /* the base is the base of DRAM CS0 always */
- + if (SDRAM_CS0 == target )
- + {
- + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
- + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
- +
- + }
- +
- + /* increment the bar size to be the sum of the size of all
- + DRAM chips selecs */
- + pexBar.addrWin.size += addrDecWin.addrWin.size;
- +
- + /* set a Pex window for this target !
- + DRAM CS always will have a Pex Window , and is not a
- + part of the priority table */
- + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
- + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
- + pexWin.addrWin.size = addrDecWin.addrWin.size;
- +
- + /* we disable the windows at first because we are not
- + sure that it is witihin bar boundries */
- + pexWin.enable =MV_FALSE;
- + pexWin.target = target;
- + pexWin.targetBar = bar;
- +
- + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
- + {
- + mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
- + return MV_ERROR;
- + }
- + }
- + }
- +
- + /* check if the size of the bar is illeggal */
- + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
- + {
- + /* try to get a good size */
- + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
- + PXBCR_BAR_SIZE_ALIGNMENT);
- + }
- +
- + /* check if the size and base are valid */
- + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
- + {
- + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
- + mvOsPrintf("it will be disabled\n");
- + mvOsPrintf("please check Pex and CPU windows configuration\n");
- + }
- + else
- + {
- + pexBar.enable = MV_TRUE;
- +
- + /* configure the bar */
- + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
- + {
- + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
- + return MV_ERROR;
- + }
- +
- + /* after the bar was configured then we enable the Pex windows*/
- + for (winNum = 0;winNum < pexCurrWin ;winNum++)
- + {
- + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
- + {
- + mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
- + return MV_ERROR;
- + }
- +
- + }
- + }
- +
- +/******************************************************************************/
- +/* DEVICE bar */
- +/******************************************************************************/
- +
- +/* Open the Device BAR for non linux only */
- +#ifndef MV_DISABLE_PEX_DEVICE_BAR
- +
- + /* then device bar*/
- + bar = PEX_DEVICE_BAR;
- +
- + /* save the starting window */
- + pexStartWindow = pexCurrWin;
- + pexBar.addrWin.size = 0;
- + pexBar.addrWin.baseLow = 0xffffffff;
- + pexBar.addrWin.baseHigh = 0;
- + maxBase = 0;
- +
- + for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
- + {
- + status = mvCpuIfTargetWinGet(target,&addrDecWin);
- +
- + if (MV_NO_SUCH == status)
- + {
- + continue;
- + }
- +
- + if (MV_OK != status)
- + {
- + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
- + return MV_ERROR;
- + }
- +
- + if (addrDecWin.enable == MV_TRUE)
- + {
- + /* get the minimum base */
- + if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
- + {
- + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
- + }
- +
- + /* get the maximum base */
- + if (addrDecWin.addrWin.baseLow > maxBase)
- + {
- + maxBase = addrDecWin.addrWin.baseLow;
- + sizeOfMaxBase = addrDecWin.addrWin.size;
- + }
- +
- + /* search in the priority table for this target */
- + for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
- + winIndex++)
- + {
- + if (pexDevBarPrioTable[winIndex] != target)
- + {
- + continue;
- + }
- + else if (pexDevBarPrioTable[winIndex] == target)
- + {
- + /*found it */
- +
- + /* if the index of this target in the prio table is valid
- + then we set the Pex window for this target, a valid index is
- + an index that is lower than the number of the windows that
- + was not configured yet */
- +
- + /* we subtract 2 always because the default and expantion
- + rom windows are always configured */
- + if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2)
- + {
- + /* set a Pex window for this target ! */
- + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
- + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
- + pexWin.addrWin.size = addrDecWin.addrWin.size;
- +
- + /* we disable the windows at first because we are not
- + sure that it is witihin bar boundries */
- + pexWin.enable = MV_FALSE;
- + pexWin.target = target;
- + pexWin.targetBar = bar;
- +
- + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
- + &pexWin))
- + {
- + mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
- + return MV_ERROR;
- + }
- + }
- + }
- + }
- + }
- + }
- +
- + pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
- + pexBar.enable = MV_TRUE;
- +
- + /* check if the size of the bar is illegal */
- + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
- + {
- + /* try to get a good size */
- + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
- + PXBCR_BAR_SIZE_ALIGNMENT);
- + }
- +
- + /* check if the size and base are valid */
- + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
- + {
- + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
- + mvOsPrintf("it will be disabled\n");
- + mvOsPrintf("please check Pex and CPU windows configuration\n");
- + }
- + else
- + {
- + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
- + {
- + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
- + return MV_ERROR;
- + }
- +
- + /* now enable the windows */
- + for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
- + {
- + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
- + {
- + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
- + winNum);
- + return MV_ERROR;
- + }
- + }
- + }
- +
- +#endif
- +
- + return mvPexHalInit(pexIf, pexType);
- +
- +}
- +
- +/*******************************************************************************
- +* mvPexTargetWinSet - Set PEX to peripheral target address window BAR
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_OK if PEX BAR target window was set correctly,
- +* MV_BAD_PARAM on bad params
- +* MV_ERROR otherwise
- +* (e.g. address window overlapps with other active PEX target window).
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
- + MV_PEX_DEC_WIN *pAddrDecWin)
- +{
- +
- + MV_DEC_REGS decRegs;
- + PEX_WIN_REG_INFO winRegInfo;
- + MV_TARGET_ATTRIB targetAttribs;
- +
- + /* Parameter checking */
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- + if (winNum >= PEX_MAX_TARGET_WIN)
- + {
- + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + /* get the pex Window registers offsets */
- + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
- +
- +
- + if (MV_TRUE == pAddrDecWin->enable)
- + {
- +
- + /* 2) Check if the requested window overlaps with current windows */
- + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* 2) Check if the requested window overlaps with current windows */
- + if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
- + winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + }
- +
- +
- +
- + /* read base register*/
- +
- + if (winRegInfo.baseLowRegOffs)
- + {
- + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
- + }
- + else
- + {
- + decRegs.baseReg = 0;
- + }
- +
- + if (winRegInfo.sizeRegOffs)
- + {
- + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
- + }
- + else
- + {
- + decRegs.sizeReg =0;
- + }
- +
- + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
- + return MV_ERROR;
- + }
- +
- + /* enable\Disable */
- + if (MV_TRUE == pAddrDecWin->enable)
- + {
- + decRegs.sizeReg |= PXWCR_WIN_EN;
- + }
- + else
- + {
- + decRegs.sizeReg &= ~PXWCR_WIN_EN;
- + }
- +
- +
- + /* clear bit location */
- + decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;
- +
- + /* set bar Mapping */
- + if (pAddrDecWin->targetBar == 1)
- + {
- + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
- + }
- + else if (pAddrDecWin->targetBar == 2)
- + {
- + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
- +
- + /* set attributes */
- + decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
- + decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
- + /* set target ID */
- + decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
- + decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;
- +
- +
- + /* 3) Write to address decode Base Address Register */
- +
- + if (winRegInfo.baseLowRegOffs)
- + {
- + MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
- + }
- +
- + /* write size reg */
- + if (winRegInfo.sizeRegOffs)
- + {
- + if ((MV_PEX_WIN_DEFAULT == winNum)||
- + (MV_PEX_WIN_EXP_ROM == winNum))
- + {
- + /* clear size because there is no size field*/
- + decRegs.sizeReg &= ~PXWCR_SIZE_MASK;
- +
- + /* clear enable because there is no enable field*/
- + decRegs.sizeReg &= ~PXWCR_WIN_EN;
- +
- + }
- +
- + MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
- + }
- +
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPexTargetWinGet - Get PEX to peripheral target address window
- +*
- +* DESCRIPTION:
- +* Get the PEX to peripheral target address window BAR.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* bar - BAR to be accessed by slave.
- +*
- +* OUTPUT:
- +* pAddrBarWin - PEX target window information data structure.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
- + MV_PEX_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttrib;
- + MV_DEC_REGS decRegs;
- +
- + PEX_WIN_REG_INFO winRegInfo;
- +
- + /* Parameter checking */
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- + if (winNum >= PEX_MAX_TARGET_WIN)
- + {
- + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + /* get the pex Window registers offsets */
- + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
- +
- + /* read base register*/
- + if (winRegInfo.baseLowRegOffs)
- + {
- + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
- + }
- + else
- + {
- + decRegs.baseReg = 0;
- + }
- +
- + /* read size reg */
- + if (winRegInfo.sizeRegOffs)
- + {
- + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
- + }
- + else
- + {
- + decRegs.sizeReg =0;
- + }
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
- + {
- + mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");
- + return MV_ERROR;
- +
- + }
- +
- + if (decRegs.sizeReg & PXWCR_WIN_EN)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- +
- + }
- +
- +
- + #if 0
- + if (-1 == pAddrDecWin->addrWin.size)
- + {
- + return MV_ERROR;
- + }
- + #endif
- +
- +
- + /* get target bar */
- + if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )
- + {
- + pAddrDecWin->targetBar = 1;
- + }
- + else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) ==
- + PXWCR_WIN_BAR_MAP_BAR2 )
- + {
- + pAddrDecWin->targetBar = 2;
- + }
- +
- + /* attrib and targetId */
- + pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >>
- + PXWCR_ATTRIB_OFFS;
- + pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >>
- + PXWCR_TARGET_OFFS;
- +
- + targetAttrib.attrib = pAddrDecWin->attrib;
- + targetAttrib.targetId = pAddrDecWin->targetId;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + return MV_OK;
- +
- +}
- +
- +
- +/*******************************************************************************
- +* mvPexTargetWinEnable - Enable/disable a PEX BAR window
- +*
- +* DESCRIPTION:
- +* This function enable/disable a PEX BAR window.
- +* if parameter 'enable' == MV_TRUE the routine will enable the
- +* window, thus enabling PEX accesses for that BAR (before enabling the
- +* window it is tested for overlapping). Otherwise, the window will
- +* be disabled.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* bar - BAR to be accessed by slave.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
- +{
- + PEX_WIN_REG_INFO winRegInfo;
- + MV_PEX_DEC_WIN addrDecWin;
- +
- + /* Parameter checking */
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- + if (winNum >= PEX_MAX_TARGET_WIN)
- + {
- + mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);
- + return MV_BAD_PARAM;
- +
- + }
- +
- +
- + /* get the pex Window registers offsets */
- + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
- +
- +
- + /* if the address windows is disabled , we only disable the appropriare
- + pex window and ignore other settings */
- +
- + if (MV_FALSE == enable)
- + {
- +
- + /* this is not relevant to default and expantion rom
- + windows */
- + if (winRegInfo.sizeRegOffs)
- + {
- + if ((MV_PEX_WIN_DEFAULT != winNum)&&
- + (MV_PEX_WIN_EXP_ROM != winNum))
- + {
- + MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
- + }
- + }
- +
- + }
- + else
- + {
- + if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
- + {
- + mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
- + return MV_ERROR;
- + }
- +
- + /* Check if the requested window overlaps with current windows */
- + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
- + {
- + mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
- + {
- + mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
- + winNum);
- + return MV_BAD_PARAM;
- + }
- +
- +
- + /* this is not relevant to default and expantion rom
- + windows */
- + if (winRegInfo.sizeRegOffs)
- + {
- + if ((MV_PEX_WIN_DEFAULT != winNum)&&
- + (MV_PEX_WIN_EXP_ROM != winNum))
- + {
- + MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
- + }
- + }
- +
- +
- + }
- +
- + return MV_OK;
- +
- +}
- +
- +
- +
- +/*******************************************************************************
- +* mvPexTargetWinRemap - Set PEX to target address window remap.
- +*
- +* DESCRIPTION:
- +* The PEX interface supports remap of the BAR original address window.
- +* For each BAR it is possible to define a remap address. For example
- +* an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified
- +* according to remap register but will also be targeted to the
- +* SDRAM CS[0].
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* bar - Peripheral target enumerator accessed by slave.
- +* pAddrWin - Address window to be checked.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
- + MV_PEX_REMAP_WIN *pAddrWin)
- +{
- +
- + PEX_WIN_REG_INFO winRegInfo;
- +
- + /* Parameter checking */
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
- + pexIf);
- + return MV_BAD_PARAM;
- + }
- + if (MV_PEX_WIN_DEFAULT == winNum)
- + {
- + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
- + winNum);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))
- + {
- + mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\
- + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + pexIf,
- + winNum,
- + pAddrWin->addrWin.baseLow,
- + pAddrWin->addrWin.size);
- +
- + return MV_ERROR;
- + }
- +
- + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
- +
- + /* Set remap low register value */
- + MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);
- +
- + /* Skip base high settings if the BAR has only base low (32-bit) */
- + if (0 != winRegInfo.remapHighRegOffs)
- + {
- + MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);
- + }
- +
- +
- + if (pAddrWin->enable == MV_TRUE)
- + {
- + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
- + }
- + else
- + {
- + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPexTargetWinRemapEnable -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +
- +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
- + MV_BOOL enable)
- +{
- + PEX_WIN_REG_INFO winRegInfo;
- +
- + /* Parameter checking */
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
- + pexIf);
- + return MV_BAD_PARAM;
- + }
- + if (MV_PEX_WIN_DEFAULT == winNum)
- + {
- + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
- + winNum);
- + return MV_BAD_PARAM;
- +
- + }
- +
- +
- + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
- +
- + if (enable == MV_TRUE)
- + {
- + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
- + }
- + else
- + {
- + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
- + }
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPexBarSet - Set PEX bar address and size
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexBarSet(MV_U32 pexIf,
- + MV_U32 barNum,
- + MV_PEX_BAR *pAddrWin)
- +{
- + MV_U32 regBaseLow;
- + MV_U32 regSize,sizeToReg;
- +
- +
- + /* check parameters */
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- + if(barNum >= PEX_MAX_BARS)
- + {
- + mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
- + return MV_BAD_PARAM;
- + }
- +
- +
- + if (pAddrWin->addrWin.size == 0)
- + {
- + mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
- + return MV_BAD_PARAM;
- + }
- +
- +
- + /* Check if the window complies with PEX spec */
- + if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
- + pAddrWin->addrWin.size))
- + {
- + mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* 2) Check if the requested bar overlaps with current bars */
- + if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
- + {
- + mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Get size register value according to window size */
- + sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
- +
- + /* Read bar size */
- + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
- + {
- + regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
- +
- + /* Size parameter validity check. */
- + if (-1 == sizeToReg)
- + {
- + mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
- + return MV_BAD_PARAM;
- + }
- +
- + regSize &= ~PXBCR_BAR_SIZE_MASK;
- + regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
- +
- + MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);
- +
- + }
- +
- + /* set size */
- +
- +
- +
- + /* Read base address low */
- + regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
- + PEX_MV_BAR_BASE(barNum)));
- +
- + /* clear current base */
- + if (PEX_INTER_REGS_BAR == barNum)
- + {
- + regBaseLow &= ~PXBIR_BASE_MASK;
- + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
- + }
- + else
- + {
- + regBaseLow &= ~PXBR_BASE_MASK;
- + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
- + }
- +
- + /* if we had a previous value that contain the bar type (MeM\IO), we want to
- + restore it */
- + regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;
- +
- +
- +
- + /* write base low */
- + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
- + regBaseLow);
- +
- + if (pAddrWin->addrWin.baseHigh != 0)
- + {
- + /* Read base address high */
- + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
- + pAddrWin->addrWin.baseHigh);
- +
- + }
- +
- + /* lastly enable the Bar */
- + if (pAddrWin->enable == MV_TRUE)
- + {
- + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
- + are enabled always */
- + {
- + MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
- + }
- + }
- + else if (MV_FALSE == pAddrWin->enable)
- + {
- + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
- + are enabled always */
- + {
- + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
- + }
- +
- + }
- +
- +
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPexBarGet - Get PEX bar address and size
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +
- +MV_STATUS mvPexBarGet(MV_U32 pexIf,
- + MV_U32 barNum,
- + MV_PEX_BAR *pAddrWin)
- +{
- + /* check parameters */
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- + if(barNum >= PEX_MAX_BARS)
- + {
- + mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* read base low */
- + pAddrWin->addrWin.baseLow =
- + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));
- +
- +
- + if (PEX_INTER_REGS_BAR == barNum)
- + {
- + pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
- + }
- + else
- + {
- + pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
- + }
- +
- +
- + /* read base high */
- + pAddrWin->addrWin.baseHigh =
- + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));
- +
- +
- + /* Read bar size */
- + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
- + {
- + pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
- +
- + /* check if enable or not */
- + if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
- + {
- + pAddrWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrWin->enable = MV_FALSE;
- + }
- +
- + /* now get the size */
- + pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
- + pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;
- +
- + pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
- + PXBCR_BAR_SIZE_ALIGNMENT);
- +
- + }
- + else /* PEX_INTER_REGS_BAR */
- + {
- + pAddrWin->addrWin.size = INTER_REGS_SIZE;
- + pAddrWin->enable = MV_TRUE;
- + }
- +
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPexBarEnable -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +
- +
- +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)
- +{
- +
- + MV_PEX_BAR pexBar;
- +
- + /* check parameters */
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- +
- + if(barNum >= PEX_MAX_BARS)
- + {
- + mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);
- + return MV_BAD_PARAM;
- + }
- +
- + if (PEX_INTER_REGS_BAR == barNum)
- + {
- + if (MV_TRUE == enable)
- + {
- + return MV_OK;
- + }
- + else
- + {
- + return MV_ERROR;
- + }
- + }
- +
- +
- + if (MV_FALSE == enable)
- + {
- + /* disable bar and quit */
- + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
- + return MV_OK;
- + }
- +
- + /* else */
- +
- + if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)
- + {
- + mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");
- + return MV_ERROR;
- +
- + }
- +
- + if (MV_TRUE == pexBar.enable)
- + {
- + /* it is already enabled !!! */
- + return MV_OK;
- + }
- +
- + /* else enable the bar*/
- +
- + pexBar.enable = MV_TRUE;
- +
- + if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)
- + {
- + mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");
- + return MV_ERROR;
- +
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* pexWinOverlapDetect - Detect address windows overlapping
- +*
- +* DESCRIPTION:
- +* This function detects address window overlapping of a given address
- +* window in PEX BARs.
- +*
- +* INPUT:
- +* pAddrWin - Address window to be checked.
- +* bar - BAR to be accessed by slave.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,
- + MV_U32 winNum,
- + MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 win;
- + MV_PEX_DEC_WIN addrDecWin;
- +
- +
- + for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)
- + {
- + /* don't check our target or illegal targets */
- + if (winNum == win)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))
- + {
- + mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",
- + win);
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled windows */
- + if (MV_FALSE == addrDecWin.enable)
- + {
- + continue;
- + }
- +
- +
- + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
- + {
- + mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n",
- + winNum, win);
- + return MV_TRUE;
- + }
- + }
- +
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* pexIsWinWithinBar - Detect if address is within PEX bar boundries
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,
- + MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 bar;
- + MV_PEX_BAR addrDecWin;
- +
- + for(bar = 0; bar < PEX_MAX_BARS; bar++)
- + {
- +
- + /* Get window parameters */
- + if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))
- + {
- + mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled bars */
- + if (MV_FALSE == addrDecWin.enable)
- + {
- + continue;
- + }
- +
- +
- + if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))
- + {
- + return MV_TRUE;
- + }
- + }
- +
- + return MV_FALSE;
- +
- +}
- +
- +/*******************************************************************************
- +* pexBarOverlapDetect - Detect address windows overlapping
- +*
- +* DESCRIPTION:
- +* This function detects address window overlapping of a given address
- +* window in PEX BARs.
- +*
- +* INPUT:
- +* pAddrWin - Address window to be checked.
- +* bar - BAR to be accessed by slave.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,
- + MV_U32 barNum,
- + MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 bar;
- + MV_PEX_BAR barDecWin;
- +
- +
- + for(bar = 0; bar < PEX_MAX_BARS; bar++)
- + {
- + /* don't check our target or illegal targets */
- + if (barNum == bar)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))
- + {
- + mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +
- + /* don'nt check disabled bars */
- + if (barDecWin.enable == MV_FALSE)
- + {
- + continue;
- + }
- +
- +
- + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))
- + {
- + mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n",
- + barNum, bar);
- + return MV_TRUE;
- + }
- + }
- +
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* pexBarIsValid - Check if the given address window is valid
- +*
- +* DESCRIPTION:
- +* PEX spec restrict BAR base to be aligned to BAR size.
- +* This function checks if the given address window is valid.
- +*
- +* INPUT:
- +* baseLow - 32bit low base address.
- +* size - Window size.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the address window is valid, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)
- +{
- +
- + /* PCI spec restrict BAR base to be aligned to BAR size */
- + if(MV_IS_NOT_ALIGN(baseLow, size))
- + {
- + return MV_ERROR;
- + }
- + else
- + {
- + return MV_TRUE;
- + }
- +
- + return MV_TRUE;
- +}
- +
- +/*******************************************************************************
- +* pexBarRegInfoGet - Get BAR register information
- +*
- +* DESCRIPTION:
- +* PEX BARs registers offsets are inconsecutive.
- +* This function gets a PEX BAR register information like register offsets
- +* and function location of the BAR.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* bar - The PEX BAR in question.
- +*
- +* OUTPUT:
- +* pBarRegInfo - BAR register info struct.
- +*
- +* RETURN:
- +* MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK
- +*
- +*******************************************************************************/
- +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf,
- + MV_U32 winNum,
- + PEX_WIN_REG_INFO *pWinRegInfo)
- +{
- +
- + if ((winNum >= 0)&&(winNum <=3))
- + {
- + pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum);
- + pWinRegInfo->baseHighRegOffs = 0;
- + pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum);
- + pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum);
- + pWinRegInfo->remapHighRegOffs = 0;
- + }
- + else if ((winNum >= 4)&&(winNum <=5))
- + {
- + pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum);
- + pWinRegInfo->baseHighRegOffs = 0;
- + pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum);
- + pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum);
- + pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);
- +
- + }
- + else if (MV_PEX_WIN_DEFAULT == winNum)
- + {
- + pWinRegInfo->baseLowRegOffs = 0;
- + pWinRegInfo->baseHighRegOffs = 0;
- + pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf);
- + pWinRegInfo->remapLowRegOffs = 0;
- + pWinRegInfo->remapHighRegOffs = 0;
- + }
- + else if (MV_PEX_WIN_EXP_ROM == winNum)
- + {
- + pWinRegInfo->baseLowRegOffs = 0;
- + pWinRegInfo->baseHighRegOffs = 0;
- + pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);
- + pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);
- + pWinRegInfo->remapHighRegOffs = 0;
- +
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* pexBarNameGet - Get the string name of PEX BAR.
- +*
- +* DESCRIPTION:
- +* This function get the string name of PEX BAR.
- +*
- +* INPUT:
- +* bar - PEX bar number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* pointer to the string name of PEX BAR.
- +*
- +*******************************************************************************/
- +const MV_8* pexBarNameGet( MV_U32 bar )
- +{
- + switch( bar )
- + {
- + case PEX_INTER_REGS_BAR:
- + return "Internal Regs Bar0....";
- + case PEX_DRAM_BAR:
- + return "DRAM Bar1.............";
- + case PEX_DEVICE_BAR:
- + return "Devices Bar2..........";
- + default:
- + return "Bar unknown";
- + }
- +}
- +/*******************************************************************************
- +* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).
- +*
- +* DESCRIPTION:
- +* This function print the PEX address decode map (BARs and windows).
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvPexAddrDecShow(MV_VOID)
- +{
- + MV_PEX_BAR pexBar;
- + MV_PEX_DEC_WIN win;
- + MV_U32 pexIf;
- + MV_U32 bar,winNum;
- +
- + for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )
- + {
- + if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;
- + mvOsOutput( "\n" );
- + mvOsOutput( "PEX%d:\n", pexIf );
- + mvOsOutput( "-----\n" );
- +
- + mvOsOutput( "\nPex Bars \n\n");
- +
- + for( bar = 0; bar < PEX_MAX_BARS; bar++ )
- + {
- + memset( &pexBar, 0, sizeof(MV_PEX_BAR) );
- +
- + mvOsOutput( "%s ", pexBarNameGet(bar) );
- +
- + if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )
- + {
- + if( pexBar.enable )
- + {
- + mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );
- + mvSizePrint( pexBar.addrWin.size );
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- + mvOsOutput( "\nPex Decode Windows\n\n");
- +
- + for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
- + {
- + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", winNum );
- +
- + if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)
- + {
- + if (win.enable)
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
- + mvOsOutput( "...." );
- + mvSizePrint( win.addrWin.size );
- +
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- +
- +
- + }
- + }
- +
- + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
- +
- + mvOsOutput( "default win - " );
- +
- + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)
- + {
- + mvOsOutput( "%s ",
- + mvCtrlTargetNameGet(win.target) );
- + mvOsOutput( "\n" );
- + }
- + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
- +
- + mvOsOutput( "Expansion ROM - " );
- +
- + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)
- + {
- + mvOsOutput( "%s ",
- + mvCtrlTargetNameGet(win.target) );
- + mvOsOutput( "\n" );
- + }
- +
- + }
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 2010-11-09 20:28:08.372495456 +0100
- @@ -0,0 +1,348 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCSysPEXH
- +#define __INCSysPEXH
- +
- +#include "mvCommon.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +/* 4KB granularity */
- +#define MINIMUM_WINDOW_SIZE 0x1000
- +#define MINIMUM_BAR_SIZE 0x1000
- +#define MINIMUM_BAR_SIZE_MASK 0xFFFFF000
- +#define BAR_SIZE_OFFS 12
- +#define BAR_SIZE_MASK (0xFFFFF << BAR_SIZE_OFFS)
- +
- +
- +
- +#define MV_PEX_WIN_DEFAULT 6
- +#define MV_PEX_WIN_EXP_ROM 7
- +#define PEX_MAX_TARGET_WIN 8
- +
- +
- +#define PEX_MAX_BARS 3
- +#define PEX_INTER_REGS_BAR 0
- +#define PEX_DRAM_BAR 1
- +#define PEX_DEVICE_BAR 2
- +
- +/*************************************/
- +/* PCI Express BAR Control Registers */
- +/*************************************/
- +#define PEX_BAR_CTRL_REG(pexIf,bar) (0x41804 + (bar-1)*4- (pexIf)*0x10000)
- +#define PEX_EXP_ROM_BAR_CTRL_REG(pexIf) (0x4180C - (pexIf)*0x10000)
- +
- +
- +/* PCI Express BAR Control Register */
- +/* PEX_BAR_CTRL_REG (PXBCR) */
- +
- +#define PXBCR_BAR_EN BIT0
- +#define PXBCR_BAR_SIZE_OFFS 16
- +#define PXBCR_BAR_SIZE_MASK (0xffff << PXBCR_BAR_SIZE_OFFS)
- +#define PXBCR_BAR_SIZE_ALIGNMENT 0x10000
- +
- +
- +
- +/* PCI Express Expansion ROM BAR Control Register */
- +/* PEX_EXP_ROM_BAR_CTRL_REG (PXERBCR) */
- +
- +#define PXERBCR_EXPROM_EN BIT0
- +#define PXERBCR_EXPROMSZ_OFFS 19
- +#define PXERBCR_EXPROMSZ_MASK (0xf << PXERBCR_EXPROMSZ_OFFS)
- +#define PXERBCR_EXPROMSZ_512KB (0x0 << PXERBCR_EXPROMSZ_OFFS)
- +#define PXERBCR_EXPROMSZ_1024KB (0x1 << PXERBCR_EXPROMSZ_OFFS)
- +#define PXERBCR_EXPROMSZ_2048KB (0x3 << PXERBCR_EXPROMSZ_OFFS)
- +#define PXERBCR_EXPROMSZ_4096KB (0x7 << PXERBCR_EXPROMSZ_OFFS)
- +
- +/************************************************/
- +/* PCI Express Address Window Control Registers */
- +/************************************************/
- +#define PEX_WIN0_3_CTRL_REG(pexIf,winNum) \
- + (0x41820 + (winNum) * 0x10 - (pexIf) * 0x10000)
- +#define PEX_WIN0_3_BASE_REG(pexIf,winNum) \
- + (0x41824 + (winNum) * 0x10 - (pexIf) * 0x10000)
- +#define PEX_WIN0_3_REMAP_REG(pexIf,winNum) \
- + (0x4182C + (winNum) * 0x10 - (pexIf) * 0x10000)
- +#define PEX_WIN4_5_CTRL_REG(pexIf,winNum) \
- + (0x41860 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
- +#define PEX_WIN4_5_BASE_REG(pexIf,winNum) \
- + (0x41864 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
- +#define PEX_WIN4_5_REMAP_REG(pexIf,winNum) \
- + (0x4186C + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
- +#define PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum) \
- + (0x41870 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
- +
- +#define PEX_WIN_DEFAULT_CTRL_REG(pexIf) (0x418B0 - (pexIf) * 0x10000)
- +#define PEX_WIN_EXP_ROM_CTRL_REG(pexIf) (0x418C0 - (pexIf) * 0x10000)
- +#define PEX_WIN_EXP_ROM_REMAP_REG(pexIf) (0x418C4 - (pexIf) * 0x10000)
- +
- +/* PCI Express Window Control Register */
- +/* PEX_WIN_CTRL_REG (PXWCR) */
- +
- +#define PXWCR_WIN_EN BIT0 /* Window Enable.*/
- +
- +#define PXWCR_WIN_BAR_MAP_OFFS 1 /* Mapping to BAR.*/
- +#define PXWCR_WIN_BAR_MAP_MASK BIT1
- +#define PXWCR_WIN_BAR_MAP_BAR1 (0 << PXWCR_WIN_BAR_MAP_OFFS)
- +#define PXWCR_WIN_BAR_MAP_BAR2 (1 << PXWCR_WIN_BAR_MAP_OFFS)
- +
- +#define PXWCR_TARGET_OFFS 4 /*Unit ID */
- +#define PXWCR_TARGET_MASK (0xf << PXWCR_TARGET_OFFS)
- +
- +#define PXWCR_ATTRIB_OFFS 8 /* target attributes */
- +#define PXWCR_ATTRIB_MASK (0xff << PXWCR_ATTRIB_OFFS)
- +
- +#define PXWCR_SIZE_OFFS 16 /* size */
- +#define PXWCR_SIZE_MASK (0xffff << PXWCR_SIZE_OFFS)
- +#define PXWCR_SIZE_ALIGNMENT 0x10000
- +
- +/* PCI Express Window Base Register */
- +/* PEX_WIN_BASE_REG (PXWBR)*/
- +
- +#define PXWBR_BASE_OFFS 16 /* address[31:16] */
- +#define PXWBR_BASE_MASK (0xffff << PXWBR_BASE_OFFS)
- +#define PXWBR_BASE_ALIGNMENT 0x10000
- +
- +/* PCI Express Window Remap Register */
- +/* PEX_WIN_REMAP_REG (PXWRR)*/
- +
- +#define PXWRR_REMAP_EN BIT0
- +#define PXWRR_REMAP_OFFS 16
- +#define PXWRR_REMAP_MASK (0xffff << PXWRR_REMAP_OFFS)
- +#define PXWRR_REMAP_ALIGNMENT 0x10000
- +
- +/* PCI Express Window Remap (High) Register */
- +/* PEX_WIN_REMAP_HIGH_REG (PXWRHR)*/
- +
- +#define PXWRHR_REMAP_HIGH_OFFS 0
- +#define PXWRHR_REMAP_HIGH_MASK (0xffffffff << PXWRHR_REMAP_HIGH_OFFS)
- +
- +/* PCI Express Default Window Control Register */
- +/* PEX_WIN_DEFAULT_CTRL_REG (PXWDCR) */
- +
- +#define PXWDCR_TARGET_OFFS 4 /*Unit ID */
- +#define PXWDCR_TARGET_MASK (0xf << PXWDCR_TARGET_OFFS)
- +#define PXWDCR_ATTRIB_OFFS 8 /* target attributes */
- +#define PXWDCR_ATTRIB_MASK (0xff << PXWDCR_ATTRIB_OFFS)
- +
- +/* PCI Express Expansion ROM Window Control Register */
- +/* PEX_WIN_EXP_ROM_CTRL_REG (PXWERCR)*/
- +
- +#define PXWERCR_TARGET_OFFS 4 /*Unit ID */
- +#define PXWERCR_TARGET_MASK (0xf << PXWERCR_TARGET_OFFS)
- +#define PXWERCR_ATTRIB_OFFS 8 /* target attributes */
- +#define PXWERCR_ATTRIB_MASK (0xff << PXWERCR_ATTRIB_OFFS)
- +
- +/* PCI Express Expansion ROM Window Remap Register */
- +/* PEX_WIN_EXP_ROM_REMAP_REG (PXWERRR)*/
- +
- +#define PXWERRR_REMAP_EN BIT0
- +#define PXWERRR_REMAP_OFFS 16
- +#define PXWERRR_REMAP_MASK (0xffff << PXWERRR_REMAP_OFFS)
- +#define PXWERRR_REMAP_ALIGNMENT 0x10000
- +
- +
- +
- +/*PEX_MEMORY_BAR_BASE_ADDR(barNum) (PXMBBA)*/
- +/* PCI Express BAR0 Internal Register*/
- +/*PEX BAR0_INTER_REG (PXBIR)*/
- +
- +#define PXBIR_IOSPACE BIT0 /* Memory Space Indicator */
- +
- +#define PXBIR_TYPE_OFFS 1 /* BAR Type/Init Val. */
- +#define PXBIR_TYPE_MASK (0x3 << PXBIR_TYPE_OFFS)
- +#define PXBIR_TYPE_32BIT_ADDR (0x0 << PXBIR_TYPE_OFFS)
- +#define PXBIR_TYPE_64BIT_ADDR (0x2 << PXBIR_TYPE_OFFS)
- +
- +#define PXBIR_PREFETCH_EN BIT3 /* Prefetch Enable */
- +
- +#define PXBIR_BASE_OFFS 20 /* Base address. Address bits [31:20] */
- +#define PXBIR_BASE_MASK (0xfff << PXBIR_BASE_OFFS)
- +#define PXBIR_BASE_ALIGNMET (1 << PXBIR_BASE_OFFS)
- +
- +
- +/* PCI Express BAR0 Internal (High) Register*/
- +/*PEX BAR0_INTER_REG_HIGH (PXBIRH)*/
- +
- +#define PXBIRH_BASE_OFFS 0 /* Base address. Bits [63:32] */
- +#define PXBIRH_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
- +
- +
- +#define PEX_BAR_DEFAULT_ATTRIB 0xc /* Memory - Prefetch - 64 bit address */
- +#define PEX_BAR0_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
- +#define PEX_BAR1_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
- +#define PEX_BAR2_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
- +
- +
- +/* PCI Express BAR1 Register */
- +/* PCI Express BAR2 Register*/
- +/*PEX BAR1_REG (PXBR)*/
- +/*PEX BAR2_REG (PXBR)*/
- +
- +#define PXBR_IOSPACE BIT0 /* Memory Space Indicator */
- +
- +#define PXBR_TYPE_OFFS 1 /* BAR Type/Init Val. */
- +#define PXBR_TYPE_MASK (0x3 << PXBR_TYPE_OFFS)
- +#define PXBR_TYPE_32BIT_ADDR (0x0 << PXBR_TYPE_OFFS)
- +#define PXBR_TYPE_64BIT_ADDR (0x2 << PXBR_TYPE_OFFS)
- +
- +#define PXBR_PREFETCH_EN BIT3 /* Prefetch Enable */
- +
- +#define PXBR_BASE_OFFS 16 /* Base address. Address bits [31:16] */
- +#define PXBR_BASE_MASK (0xffff << PXBR_BASE_OFFS)
- +#define PXBR_BASE_ALIGNMET (1 << PXBR_BASE_OFFS)
- +
- +
- +/* PCI Express BAR1 (High) Register*/
- +/* PCI Express BAR2 (High) Register*/
- +/*PEX BAR1_REG_HIGH (PXBRH)*/
- +/*PEX BAR2_REG_HIGH (PXBRH)*/
- +
- +#define PXBRH_BASE_OFFS 0 /* Base address. Address bits [63:32] */
- +#define PXBRH_BASE_MASK (0xffffffff << PXBRH_BASE_OFFS)
- +
- +/* PCI Express Expansion ROM BAR Register*/
- +/*PEX_EXPANSION_ROM_BASE_ADDR_REG (PXERBAR)*/
- +
- +#define PXERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
- +
- +#define PXERBAR_BASE_512K_OFFS 19 /* Expansion ROM Base Address */
- +#define PXERBAR_BASE_512K_MASK (0x1fff << PXERBAR_BASE_512K_OFFS)
- +
- +#define PXERBAR_BASE_1MB_OFFS 20 /* Expansion ROM Base Address */
- +#define PXERBAR_BASE_1MB_MASK (0xfff << PXERBAR_BASE_1MB_OFFS)
- +
- +#define PXERBAR_BASE_2MB_OFFS 21 /* Expansion ROM Base Address */
- +#define PXERBAR_BASE_2MB_MASK (0x7ff << PXERBAR_BASE_2MB_OFFS)
- +
- +#define PXERBAR_BASE_4MB_OFFS 22 /* Expansion ROM Base Address */
- +#define PXERBAR_BASE_4MB_MASK (0x3ff << PXERBAR_BASE_4MB_OFFS)
- +
- +/* PEX Bar attributes */
- +typedef struct _mvPexBar
- +{
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_PEX_BAR;
- +
- +/* PEX Remap Window attributes */
- +typedef struct _mvPexRemapWin
- +{
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_PEX_REMAP_WIN;
- +
- +/* PEX Remap Window attributes */
- +typedef struct _mvPexDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_U32 targetBar;
- + MV_U8 attrib; /* chip select attributes */
- + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_PEX_DEC_WIN;
- +
- +/* Global Functions prototypes */
- +/* mvPexHalInit - Initialize PEX interfaces*/
- +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
- +
- +
- +/* mvPexTargetWinSet - Set PEX to peripheral target address window BAR*/
- +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
- + MV_PEX_DEC_WIN *pAddrDecWin);
- +
- +/* mvPexTargetWinGet - Get PEX to peripheral target address window*/
- +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
- + MV_PEX_DEC_WIN *pAddrDecWin);
- +
- +/* mvPexTargetWinEnable - Enable/disable a PEX BAR window*/
- +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable);
- +
- +/* mvPexTargetWinRemap - Set PEX to target address window remap.*/
- +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
- + MV_PEX_REMAP_WIN *pAddrWin);
- +
- +/* mvPexTargetWinRemapEnable -enable\disable a PEX Window remap.*/
- +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
- + MV_BOOL enable);
- +
- +/* mvPexBarSet - Set PEX bar address and size */
- +MV_STATUS mvPexBarSet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
- +
- +/* mvPexBarGet - Get PEX bar address and size */
- +MV_STATUS mvPexBarGet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
- +
- +/* mvPexBarEnable - enable\disable a PEX bar*/
- +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable);
- +
- +/* mvPexAddrDecShow - Display address decode windows attributes */
- +MV_VOID mvPexAddrDecShow(MV_VOID);
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 2010-11-09 20:28:08.402495399 +0100
- @@ -0,0 +1,430 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#include "mvTypes.h"
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "cpu/mvCpu.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "sata/CoreDriver/mvRegs.h"
- +#include "ctrlEnv/sys/mvSysSata.h"
- +
- +MV_TARGET sataAddrDecPrioTab[] =
- +{
- +#if defined(MV_INCLUDE_SDRAM_CS0)
- + SDRAM_CS0,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + SDRAM_CS1,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS2)
- + SDRAM_CS2,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS3)
- + SDRAM_CS3,
- +#endif
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_MEM,
- +#endif
- + TBL_TERM
- +};
- +
- +
- +/*******************************************************************************
- +* sataWinOverlapDetect - Detect SATA address windows overlapping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviur is expected in case SATA address decode
- +* windows overlapps.
- +* This function detects SATA address decode windows overlapping of a
- +* specified window. The function does not check the window itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS sataWinOverlapDetect(int dev, MV_U32 winNum,
- + MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 winNumIndex;
- + MV_SATA_DEC_WIN addrDecWin;
- +
- + for(winNumIndex=0; winNumIndex<MV_SATA_MAX_ADDR_DECODE_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if (winNumIndex == winNum)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvSataWinGet(dev, winNumIndex, &addrDecWin))
- + {
- + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled windows */
- + if(addrDecWin.enable == MV_FALSE)
- + {
- + continue;
- + }
- +
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + return MV_FALSE;
- +}
- +
- +
- +/*******************************************************************************
- +* mvSataWinSet - Set SATA target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the SATA will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - SATA target address decode window number.
- +* pAddrDecWin - SATA target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if address window overlapps with other address decode windows.
- +* MV_BAD_PARAM if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_DEC_REGS decRegs;
- +
- + /* Parameter checking */
- + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlapps with current windows */
- + if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
- + return MV_ERROR;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvSataWinSet:Error setting SATA window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pAddrDecWin->target),
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + decRegs.baseReg = 0;
- + decRegs.sizeReg = 0;
- +
- + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
- +
- + /* set attributes */
- + decRegs.sizeReg &= ~MV_SATA_WIN_ATTR_MASK;
- + decRegs.sizeReg |= (targetAttribs.attrib << MV_SATA_WIN_ATTR_OFFSET);
- +
- + /* set target ID */
- + decRegs.sizeReg &= ~MV_SATA_WIN_TARGET_MASK;
- + decRegs.sizeReg |= (targetAttribs.targetId << MV_SATA_WIN_TARGET_OFFSET);
- +
- + if (pAddrDecWin->enable == MV_TRUE)
- + {
- + decRegs.sizeReg |= MV_SATA_WIN_ENABLE_MASK;
- + }
- + else
- + {
- + decRegs.sizeReg &= ~MV_SATA_WIN_ENABLE_MASK;
- + }
- +
- + MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
- + MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSataWinGet - Get SATA peripheral target address window.
- +*
- +* DESCRIPTION:
- +* Get SATA peripheral target address window.
- +*
- +* INPUT:
- +* winNum - SATA target address decode window number.
- +*
- +* OUTPUT:
- +* pAddrDecWin - SATA target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS decRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- +
- + /* Parameter checking */
- + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
- + __FUNCTION__, dev, winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + decRegs.baseReg = MV_REG_READ( MV_SATA_WIN_BASE_REG(dev, winNum) );
- + decRegs.sizeReg = MV_REG_READ( MV_SATA_WIN_CTRL_REG(dev, winNum) );
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
- + {
- + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib = (decRegs.sizeReg & MV_SATA_WIN_ATTR_MASK) >>
- + MV_SATA_WIN_ATTR_OFFSET;
- + targetAttrib.targetId = (decRegs.sizeReg & MV_SATA_WIN_TARGET_MASK) >>
- + MV_SATA_WIN_TARGET_OFFSET;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + /* Check if window is enabled */
- + if(decRegs.sizeReg & MV_SATA_WIN_ENABLE_MASK)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- + return MV_OK;
- +}
- +/*******************************************************************************
- +* mvSataAddrDecShow - Print the SATA address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the SATA address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvSataAddrDecShow(MV_VOID)
- +{
- +
- + MV_SATA_DEC_WIN win;
- + int i,j;
- +
- +
- +
- + for( j = 0; j < MV_SATA_MAX_CHAN; j++ )
- + {
- + if (MV_FALSE == mvCtrlPwrClckGet(SATA_UNIT_ID, j))
- + return;
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "SATA %d:\n", j );
- + mvOsOutput( "----\n" );
- +
- + for( i = 0; i < MV_SATA_MAX_ADDR_DECODE_WIN; i++ )
- + {
- + memset( &win, 0, sizeof(MV_SATA_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", i );
- +
- + if( mvSataWinGet(j, i, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
- + mvOsOutput( "...." );
- +
- + mvSizePrint( win.addrWin.size );
- +
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- + }
- +}
- +
- +
- +/*******************************************************************************
- +* mvSataWinInit - Initialize the integrated SATA target address window.
- +*
- +* DESCRIPTION:
- +* Initialize the SATA peripheral target address window.
- +*
- +* INPUT:
- +*
- +*
- +* OUTPUT:
- +*
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvSataWinInit(MV_VOID)
- +{
- + int winNum;
- + MV_SATA_DEC_WIN sataWin;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + MV_U32 status, winPrioIndex = 0;
- +
- + /* Initiate Sata address decode */
- +
- + /* First disable all address decode windows */
- + for(winNum = 0; winNum < MV_SATA_MAX_ADDR_DECODE_WIN; winNum++)
- + {
- + MV_U32 regVal = MV_REG_READ(MV_SATA_WIN_CTRL_REG(0, winNum));
- + regVal &= ~MV_SATA_WIN_ENABLE_MASK;
- + MV_REG_WRITE(MV_SATA_WIN_CTRL_REG(0, winNum), regVal);
- + }
- +
- + winNum = 0;
- + while( (sataAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
- + (winNum < MV_SATA_MAX_ADDR_DECODE_WIN) )
- + {
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(sataAddrDecPrioTab[winPrioIndex],
- + &cpuAddrDecWin);
- +
- + if(MV_NO_SUCH == status)
- + {
- + winPrioIndex++;
- + continue;
- + }
- + if (MV_OK != status)
- + {
- + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + sataWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + sataWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + sataWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + sataWin.enable = MV_TRUE;
- + sataWin.target = sataAddrDecPrioTab[winPrioIndex];
- +
- + if(MV_OK != mvSataWinSet(0/*dev*/, winNum, &sataWin))
- + {
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex++;
- + }
- + return MV_OK;
- +}
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 2010-11-09 20:28:08.526524216 +0100
- @@ -0,0 +1,128 @@
- +
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#ifndef __INCMVSysSataAddrDech
- +#define __INCMVSysSataAddrDech
- +
- +#include "mvCommon.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif
- +
- +typedef struct _mvSataDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +} MV_SATA_DEC_WIN;
- +
- +
- +#define MV_SATA_MAX_ADDR_DECODE_WIN 4
- +
- +#define MV_SATA_WIN_CTRL_REG(dev, win) (SATA_REG_BASE + 0x30 + ((win)<<4))
- +#define MV_SATA_WIN_BASE_REG(dev, win) (SATA_REG_BASE + 0x34 + ((win)<<4))
- +
- +/* BITs in Bridge Interrupt Cause and Mask registers */
- +#define MV_SATA_ADDR_DECODE_ERROR_BIT 0
- +#define MV_SATA_ADDR_DECODE_ERROR_MASK (1<<MV_SATA_ADDR_DECODE_ERROR_BIT)
- +
- +/* BITs in Windows 0-3 Control and Base Registers */
- +#define MV_SATA_WIN_ENABLE_BIT 0
- +#define MV_SATA_WIN_ENABLE_MASK (1<<MV_SATA_WIN_ENABLE_BIT)
- +
- +#define MV_SATA_WIN_TARGET_OFFSET 4
- +#define MV_SATA_WIN_TARGET_MASK (0xF<<MV_SATA_WIN_TARGET_OFFSET)
- +
- +#define MV_SATA_WIN_ATTR_OFFSET 8
- +#define MV_SATA_WIN_ATTR_MASK (0xFF<<MV_SATA_WIN_ATTR_OFFSET)
- +
- +#define MV_SATA_WIN_SIZE_OFFSET 16
- +#define MV_SATA_WIN_SIZE_MASK (0xFFFF<<MV_SATA_WIN_SIZE_OFFSET)
- +
- +#define MV_SATA_WIN_BASE_OFFSET 16
- +#define MV_SATA_WIN_BASE_MASK (0xFFFF<<MV_SATA_WIN_BASE_OFFSET)
- +
- +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvSataWinByTargetGet(MV_TARGET target, MV_SATA_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvSataWinInit(MV_VOID);
- +MV_VOID mvSataAddrDecShow(MV_VOID);
- +
- +
- +#ifdef __cplusplus
- +}
- +#endif
- +
- +
- +#endif
- +
- +
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 2010-11-09 20:28:08.633445891 +0100
- @@ -0,0 +1,427 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#include "mvTypes.h"
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "cpu/mvCpu.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "mvRegs.h"
- +#include "ctrlEnv/sys/mvSysSdmmc.h"
- +
- +MV_TARGET sdmmcAddrDecPrioTab[] =
- +{
- +#if defined(MV_INCLUDE_SDRAM_CS0)
- + SDRAM_CS0,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + SDRAM_CS1,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS2)
- + SDRAM_CS2,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS3)
- + SDRAM_CS3,
- +#endif
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_MEM,
- +#endif
- + TBL_TERM
- +};
- +
- +
- +/*******************************************************************************
- +* sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviur is expected in case SDMMC address decode
- +* windows overlapps.
- +* This function detects SDMMC address decode windows overlapping of a
- +* specified window. The function does not check the window itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum,
- + MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 winNumIndex;
- + MV_SDMMC_DEC_WIN addrDecWin;
- +
- + for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if (winNumIndex == winNum)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))
- + {
- + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled windows */
- + if(addrDecWin.enable == MV_FALSE)
- + {
- + continue;
- + }
- +
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + return MV_FALSE;
- +}
- +
- +
- +/*******************************************************************************
- +* mvSdmmcWinSet - Set SDMMC target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the SDMMC will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - SDMMC target address decode window number.
- +* pAddrDecWin - SDMMC target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if address window overlapps with other address decode windows.
- +* MV_BAD_PARAM if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_DEC_REGS decRegs;
- +
- + /* Parameter checking */
- + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlapps with current windows */
- + if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
- + return MV_ERROR;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pAddrDecWin->target),
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + decRegs.baseReg = 0;
- + decRegs.sizeReg = 0;
- +
- + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
- +
- + /* set attributes */
- + decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;
- + decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);
- +
- + /* set target ID */
- + decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;
- + decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);
- +
- + if (pAddrDecWin->enable == MV_TRUE)
- + {
- + decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;
- + }
- + else
- + {
- + decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;
- + }
- +
- + MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
- + MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSdmmcWinGet - Get SDMMC peripheral target address window.
- +*
- +* DESCRIPTION:
- +* Get SDMMC peripheral target address window.
- +*
- +* INPUT:
- +* winNum - SDMMC target address decode window number.
- +*d
- +* OUTPUT:
- +* pAddrDecWin - SDMMC target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS decRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- +
- + /* Parameter checking */
- + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
- + __FUNCTION__, dev, winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );
- + decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
- + {
- + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >>
- + MV_SDMMC_WIN_ATTR_OFFSET;
- + targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >>
- + MV_SDMMC_WIN_TARGET_OFFSET;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + /* Check if window is enabled */
- + if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- + return MV_OK;
- +}
- +/*******************************************************************************
- +* mvSdmmcAddrDecShow - Print the SDMMC address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the SDMMC address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvSdmmcAddrDecShow(MV_VOID)
- +{
- +
- + MV_SDMMC_DEC_WIN win;
- + int i,j=0;
- +
- +
- +
- + if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0))
- + return;
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "SDMMC %d:\n", j );
- + mvOsOutput( "----\n" );
- +
- + for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )
- + {
- + memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", i );
- +
- + if( mvSdmmcWinGet(j, i, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
- + mvOsOutput( "...." );
- +
- + mvSizePrint( win.addrWin.size );
- +
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- +}
- +
- +
- +/*******************************************************************************
- +* mvSdmmcWinInit - Initialize the integrated SDMMC target address window.
- +*
- +* DESCRIPTION:
- +* Initialize the SDMMC peripheral target address window.
- +*
- +* INPUT:
- +*
- +*
- +* OUTPUT:
- +*
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvSdmmcWinInit(MV_VOID)
- +{
- + int winNum;
- + MV_SDMMC_DEC_WIN sdmmcWin;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + MV_U32 status, winPrioIndex = 0;
- +
- + /* Initiate Sdmmc address decode */
- +
- + /* First disable all address decode windows */
- + for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)
- + {
- + MV_U32 regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));
- + regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;
- + MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);
- + }
- +
- + winNum = 0;
- + while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
- + (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )
- + {
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],
- + &cpuAddrDecWin);
- +
- + if(MV_NO_SUCH == status)
- + {
- + winPrioIndex++;
- + continue;
- + }
- + if (MV_OK != status)
- + {
- + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + sdmmcWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + sdmmcWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + sdmmcWin.enable = MV_TRUE;
- + sdmmcWin.target = sdmmcAddrDecPrioTab[winPrioIndex];
- +
- + if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))
- + {
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex++;
- + }
- + return MV_OK;
- +}
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 2010-11-09 20:28:08.891243103 +0100
- @@ -0,0 +1,125 @@
- +
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#ifndef __INCMVSysSdmmcAddrDech
- +#define __INCMVSysSdmmcAddrDech
- +
- +#include "mvCommon.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif
- +
- +typedef struct _mvSdmmcDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +} MV_SDMMC_DEC_WIN;
- +
- +
- +#define MV_SDMMC_MAX_ADDR_DECODE_WIN 4
- +
- +#define MV_SDMMC_WIN_CTRL_REG(dev, win) (MV_SDIO_REG_BASE + 0x108 + ((win)<<3))
- +#define MV_SDMMC_WIN_BASE_REG(dev, win) (MV_SDIO_REG_BASE + 0x10c + ((win)<<3))
- +
- +
- +/* BITs in Windows 0-3 Control and Base Registers */
- +#define MV_SDMMC_WIN_ENABLE_BIT 0
- +#define MV_SDMMC_WIN_ENABLE_MASK (1<<MV_SDMMC_WIN_ENABLE_BIT)
- +
- +#define MV_SDMMC_WIN_TARGET_OFFSET 4
- +#define MV_SDMMC_WIN_TARGET_MASK (0xF<<MV_SDMMC_WIN_TARGET_OFFSET)
- +
- +#define MV_SDMMC_WIN_ATTR_OFFSET 8
- +#define MV_SDMMC_WIN_ATTR_MASK (0xFF<<MV_SDMMC_WIN_ATTR_OFFSET)
- +
- +#define MV_SDMMC_WIN_SIZE_OFFSET 16
- +#define MV_SDMMC_WIN_SIZE_MASK (0xFFFF<<MV_SDMMC_WIN_SIZE_OFFSET)
- +
- +#define MV_SDMMC_WIN_BASE_OFFSET 16
- +#define MV_SDMMC_WIN_BASE_MASK (0xFFFF<<MV_SDMMC_WIN_BASE_OFFSET)
- +
- +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvSdmmcWinByTargetGet(MV_TARGET target, MV_SDMMC_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvSdmmcWinInit(MV_VOID);
- +MV_VOID mvSdmmcAddrDecShow(MV_VOID);
- +
- +
- +#ifdef __cplusplus
- +}
- +#endif
- +
- +
- +#endif
- +
- +
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 2010-11-09 20:28:09.164485759 +0100
- @@ -0,0 +1,462 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvSysTdm.h"
- +
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +static MV_TARGET tdmAddrDecPrioTap[] =
- +{
- + PEX0_MEM,
- + SDRAM_CS0,
- + SDRAM_CS1,
- + SDRAM_CS2,
- + SDRAM_CS3,
- + DEVICE_CS0,
- + DEVICE_CS1,
- + DEVICE_CS2,
- + DEV_BOOCS,
- + PEX0_IO,
- + TBL_TERM
- +};
- +
- +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
- +
- +/*******************************************************************************
- +* mvTdmWinInit - Initialize TDM address decode windows
- +*
- +* DESCRIPTION:
- +* This function initialize TDM window decode unit. It set the
- +* default address decode
- +* windows of the unit.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if setting fail.
- +*******************************************************************************/
- +
- +MV_STATUS mvTdmWinInit(void)
- +{
- + MV_U32 winNum;
- + MV_U32 winPrioIndex = 0;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + MV_TDM_DEC_WIN tdmWin;
- + MV_STATUS status;
- +
- + /*Disable all windows*/
- + for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
- + {
- + mvTdmWinEnable(winNum, MV_FALSE);
- + }
- +
- + for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
- + (winNum < TDM_MBUS_MAX_WIN)); )
- + {
- + status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex],
- + &cpuAddrDecWin);
- + if (MV_NO_SUCH == status)
- + {
- + winPrioIndex++;
- + continue;
- + }
- + if (MV_OK != status)
- + {
- + mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + tdmWin.enable = MV_TRUE;
- + tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
- + if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
- + {
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex++;
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvTdmWinSet - Set TDM target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the TDM will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - TDM to target address decode window number.
- +* pAddrDecWin - TDM target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if address window overlapps with other address decode windows.
- +* MV_BAD_PARAM if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +
- +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_DEC_REGS decRegs;
- + MV_U32 ctrlReg = 0;
- +
- + /* Parameter checking */
- + if (winNum >= TDM_MBUS_MAX_WIN)
- + {
- + mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlapps with current windows */
- + if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
- + return MV_ERROR;
- + }
- +
- + /* check if address is aligned to the size */
- + if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pAddrDecWin->target),
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
- + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
- +
- + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
- + return MV_ERROR;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
- +
- + /* for the safe side we disable the window before writing the new
- + values */
- + mvTdmWinEnable(winNum, MV_FALSE);
- +
- + ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
- + ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
- + ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);
- +
- + /* Write to address base and control registers */
- + MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
- + MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);
- + /* Enable address decode target window */
- + if (pAddrDecWin->enable == MV_TRUE)
- + {
- + mvTdmWinEnable(winNum, MV_TRUE);
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvTdmWinGet - Get peripheral target address window.
- +*
- +* DESCRIPTION:
- +* Get TDM peripheral target address window.
- +*
- +* INPUT:
- +* winNum - TDM to target address decode window number.
- +*
- +* OUTPUT:
- +* pAddrDecWin - TDM target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +
- +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
- +{
- +
- + MV_DEC_REGS decRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- +
- + /* Parameter checking */
- + if (winNum >= TDM_MBUS_MAX_WIN)
- + {
- + mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
- + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
- + {
- + mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib =
- + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >> TDM_WIN_ATTRIB_OFFS;
- + targetAttrib.targetId =
- + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >> TDM_WIN_TARGET_OFFS;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + /* Check if window is enabled */
- + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvTdmWinEnable - Enable/disable a TDM to target address window
- +*
- +* DESCRIPTION:
- +* This function enable/disable a TDM to target address window.
- +* According to parameter 'enable' the routine will enable the
- +* window, thus enabling TDM accesses (before enabling the window it is
- +* tested for overlapping). Otherwise, the window will be disabled.
- +*
- +* INPUT:
- +* winNum - TDM to target address decode window number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_ERROR if decode window number was wrong or enabled window overlapps.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
- +{
- + MV_TDM_DEC_WIN addrDecWin;
- +
- + if (MV_TRUE == enable)
- + {
- + if (winNum >= TDM_MBUS_MAX_WIN)
- + {
- + mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
- + return MV_ERROR;
- + }
- +
- + /* First check for overlap with other enabled windows */
- + /* Get current window */
- + if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
- + {
- + mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
- + return MV_ERROR;
- + }
- + /* Check for overlapping */
- + if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
- + {
- + /* No Overlap. Enable address decode target window */
- + MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
- + }
- + else
- + { /* Overlap detected */
- + mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
- + return MV_ERROR;
- + }
- + }
- + else
- + {
- + MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
- + }
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* tdmWinOverlapDetect - Detect TDM address windows overlapping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviour is expected in case TDM address decode
- +* windows overlapps.
- +* This function detects TDM address decode windows overlapping of a
- +* specified window. The function does not check the window itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 winNumIndex;
- + MV_TDM_DEC_WIN addrDecWin;
- +
- + for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if (winNumIndex == winNum)
- + {
- + continue;
- + }
- + /* Do not check disabled windows */
- + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
- + {
- + /* Get window parameters */
- + if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
- + {
- + DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
- + return MV_ERROR;
- + }
- +
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + }
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* mvTdmAddrDecShow - Print the TDM address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the TDM address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvTdmAddrDecShow(MV_VOID)
- +{
- + MV_TDM_DEC_WIN win;
- + int i;
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "TDM:\n" );
- + mvOsOutput( "----\n" );
- +
- + for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
- + {
- + memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", i );
- +
- + if (mvTdmWinGet(i, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
- + mvOsOutput( "...." );
- + mvSizePrint( win.addrWin.size );
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 2010-11-09 20:28:09.471497270 +0100
- @@ -0,0 +1,106 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSysTdmh
- +#define __INCmvSysTdmh
- +
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +typedef struct _mvTdmDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +} MV_TDM_DEC_WIN;
- +
- +MV_STATUS mvTdmWinInit(MV_VOID);
- +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable);
- +MV_VOID mvTdmAddrDecShow(MV_VOID);
- +
- +
- +#define TDM_MBUS_MAX_WIN 4
- +#define TDM_WIN_CTRL_REG(win) ((TDM_REG_BASE + 0x4030) + (win<<4))
- +#define TDM_WIN_BASE_REG(win) ((TDM_REG_BASE +0x4034) + (win<<4))
- +
- +/* TDM_WIN_CTRL_REG bits */
- +#define TDM_WIN_ENABLE_OFFS 0
- +#define TDM_WIN_ENABLE_MASK (1<<TDM_WIN_ENABLE_OFFS)
- +#define TDM_WIN_ENABLE 1
- +#define TDM_WIN_TARGET_OFFS 4
- +#define TDM_WIN_TARGET_MASK (0xf<<TDM_WIN_TARGET_OFFS)
- +#define TDM_WIN_ATTRIB_OFFS 8
- +#define TDM_WIN_ATTRIB_MASK (0xff<<TDM_WIN_ATTRIB_OFFS)
- +#define TDM_WIN_SIZE_OFFS 16
- +#define TDM_WIN_SIZE_MASK (0xffff<<TDM_WIN_SIZE_OFFS)
- +
- +/* TDM_WIN_BASE_REG bits */
- +#define TDM_BASE_OFFS 16
- +#define TDM_BASE_MASK (0xffff<<TDM_BASE_OFFS)
- +
- +#endif /*__INCmvSysTdmh*/
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 2010-11-09 20:28:09.721570932 +0100
- @@ -0,0 +1,591 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#include "ctrlEnv/sys/mvSysTs.h"
- +
- +
- +typedef struct _mvTsuDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_TSU_DEC_WIN;
- +
- +
- +MV_TARGET tsuAddrDecPrioTap[] =
- +{
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_MEM,
- +#endif
- +#if defined(MV_INCLUDE_PCI)
- + PCI0_MEM,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS0)
- + SDRAM_CS0,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + SDRAM_CS1,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS2)
- + SDRAM_CS2,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS3)
- + SDRAM_CS3,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS0)
- + DEVICE_CS0,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS1)
- + DEVICE_CS1,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS2)
- + DEVICE_CS2,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS3)
- + DEVICE_CS3,
- +#endif
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_IO,
- +#endif
- +#if defined(MV_INCLUDE_PCI)
- + PCI0_IO,
- +#endif
- + TBL_TERM
- +};
- +
- +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
- +static MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
- +static MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable);
- +
- +/*******************************************************************************
- +* mvTsuWinInit
- +*
- +* DESCRIPTION:
- +* Initialize the TSU unit address decode windows.
- +*
- +* INPUT:
- +* None.
- +* OUTPUT:
- +* None.
- +* RETURN:
- +* MV_OK - on success,
- +*
- +*******************************************************************************/
- +MV_STATUS mvTsuWinInit(void)
- +{
- + MV_U32 winNum, status, winPrioIndex=0;
- + MV_TSU_DEC_WIN tsuWin;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- +
- + /* First disable all address decode windows */
- + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
- + {
- + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
- + TSU_WIN_CTRL_EN_MASK);
- + }
- +
- + /* Go through all windows in user table until table terminator */
- + for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
- + (winNum < TSU_MAX_DECODE_WIN));)
- + {
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex],
- + &cpuAddrDecWin);
- +
- + if(MV_NO_SUCH == status)
- + {
- + winPrioIndex++;
- + continue;
- + }
- + if(MV_OK != status)
- + {
- + mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + tsuWin.enable = MV_TRUE;
- + tsuWin.target = tsuAddrDecPrioTap[winPrioIndex];
- +
- + if(MV_OK != mvTsuWinSet(winNum, &tsuWin))
- + {
- + mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n",
- + winNum);
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex ++;
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvTsuWinSet
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the TSU will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - TSU to target address decode window number.
- +* pAddrDecWin - TSU target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR - if address window overlapps with other address decode
- +* windows.
- +* MV_BAD_PARAM - if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
- +{
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_DEC_REGS decRegs;
- +
- + /* Parameter checking */
- + if(winNum >= TSU_MAX_DECODE_WIN)
- + {
- + mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlapps with current windows */
- + if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);
- + return MV_ERROR;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target "
- + "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum, mvCtrlTargetNameGet(pAddrDecWin->target),
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
- + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
- +
- + if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
- + {
- + mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n");
- + return MV_ERROR;
- + }
- +
- + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
- +
- + /* set attributes */
- + decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;
- + decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;
- + /* set target ID */
- + decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;
- + decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;
- +
- + /* for the safe side we disable the window before writing the new */
- + /* values */
- + mvTsuWinEnable(winNum, MV_FALSE);
- + MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);
- +
- + /* Write to address decode Size Register */
- + MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);
- +
- + /* Enable address decode target window */
- + if(pAddrDecWin->enable == MV_TRUE)
- + {
- + mvTsuWinEnable(winNum,MV_TRUE);
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvTsuWinGet
- +*
- +* DESCRIPTION:
- +* Get TSU peripheral target address window.
- +*
- +* INPUT:
- +* winNum - TSU to target address decode window number.
- +*
- +* OUTPUT:
- +* pAddrDecWin - TSU target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS decRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- +
- + /* Parameter checking */
- + if(winNum >= TSU_MAX_DECODE_WIN)
- + {
- + mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
- + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
- +
- + if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
- + {
- + mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n");
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib =
- + (decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS;
- + targetAttrib.targetId =
- + (decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS;
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + /* Check if window is enabled */
- + if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK))
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvTsuWinEnable
- +*
- +* DESCRIPTION:
- +* This function enable/disable a TSU to target address window.
- +* According to parameter 'enable' the routine will enable the
- +* window, thus enabling TSU accesses (before enabling the window it is
- +* tested for overlapping). Otherwise, the window will be disabled.
- +*
- +* INPUT:
- +* winNum - TSU to target address decode window number.
- +* enable - Enable / disable parameter.
- +*
- +* OUTPUT:
- +* N/A
- +*
- +* RETURN:
- +* MV_ERROR if decode window number was wrong or enabled window overlapps.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)
- +{
- + MV_TSU_DEC_WIN addrDecWin;
- +
- + /* Parameter checking */
- + if(winNum >= TSU_MAX_DECODE_WIN)
- + {
- + mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum);
- + return MV_ERROR;
- + }
- +
- + if(enable == MV_TRUE)
- + {
- + /* First check for overlap with other enabled windows */
- + /* Get current window. */
- + if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))
- + {
- + mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");
- + return MV_ERROR;
- + }
- + /* Check for overlapping. */
- + if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))
- + {
- + /* No Overlap. Enable address decode target window */
- + MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),
- + TSU_WIN_CTRL_EN_MASK);
- + }
- + else
- + {
- + /* Overlap detected */
- + mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");
- + return MV_ERROR;
- + }
- + }
- + else
- + {
- + /* Disable address decode target window */
- + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
- + TSU_WIN_CTRL_EN_MASK);
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvTsuWinTargetGet
- +*
- +* DESCRIPTION:
- +* Get Window number associated with target
- +*
- +* INPUT:
- +* target - Target ID to get the window number for.
- +* OUTPUT:
- +*
- +* RETURN:
- +* window number or 0xFFFFFFFF on error.
- +*
- +*******************************************************************************/
- +MV_U32 mvTsuWinTargetGet(MV_TARGET target)
- +{
- + MV_TSU_DEC_WIN decWin;
- + MV_U32 winNum;
- +
- + /* Check parameters */
- + if(target >= MAX_TARGETS)
- + {
- + mvOsPrintf("mvTsuWinTargetGet: target %d is Illigal\n", target);
- + return 0xffffffff;
- + }
- +
- + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
- + {
- + if(mvTsuWinGet(winNum,&decWin) != MV_OK)
- + {
- + mvOsPrintf("mvTsuWinGet: window returned error\n");
- + return 0xffffffff;
- + }
- +
- + if (decWin.enable == MV_TRUE)
- + {
- + if(decWin.target == target)
- + {
- + return winNum;
- + }
- + }
- + }
- + return 0xFFFFFFFF;
- +}
- +
- +
- +/*******************************************************************************
- +* tsuWinOverlapDetect
- +*
- +* DESCRIPTION:
- +* Detect TSU address windows overlapping
- +* An unpredicted behaviur is expected in case TSU address decode
- +* windows overlapps.
- +* This function detects TSU address decode windows overlapping of a
- +* specified window. The function does not check the window itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 ctrlReg;
- + MV_U32 winNumIndex;
- + MV_TSU_DEC_WIN addrDecWin;
- +
- + for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if(winNumIndex == winNum)
- + {
- + continue;
- + }
- +
- + /* Do not check disabled windows */
- + ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex));
- + if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin))
- + {
- + mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n");
- + return MV_ERROR;
- + }
- +
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + return MV_FALSE;
- +}
- +
- +
- +/*******************************************************************************
- +* mvTsuAddrDecShow
- +*
- +* DESCRIPTION:
- +* Print the TSU address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +void mvTsuAddrDecShow(void)
- +{
- + MV_TSU_DEC_WIN win;
- + int i;
- +
- + if (MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0))
- + return;
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "TSU:\n");
- + mvOsOutput( "----\n" );
- +
- + for(i = 0; i < TSU_MAX_DECODE_WIN; i++)
- + {
- + memset(&win, 0, sizeof(TSU_MAX_DECODE_WIN));
- + mvOsOutput( "win%d - ", i );
- +
- + if(mvTsuWinGet(i, &win ) == MV_OK )
- + {
- + if(win.enable == MV_TRUE)
- + {
- + mvOsOutput("%s base %08x, ",
- + mvCtrlTargetNameGet(win.target),
- + win.addrWin.baseLow);
- + mvOsOutput( "...." );
- + mvSizePrint(win.addrWin.size );
- + mvOsOutput( "\n" );
- + }
- + else
- + {
- + mvOsOutput( "disable\n" );
- + }
- + }
- + }
- + return;
- +}
- +
- +
- +/*******************************************************************************
- +* mvTsuInit
- +*
- +* DESCRIPTION:
- +* Initialize the TSU unit, and get unit out of reset.
- +*
- +* INPUT:
- +* coreClock - The core clock at which the TSU should operate.
- +* mode - The mode on configure the unit into (serial/parallel).
- +* memHandle - Memory handle used for memory allocations.
- +* OUTPUT:
- +* None.
- +* RETURN:
- +* MV_OK - on success,
- +*
- +*******************************************************************************/
- +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
- + void *osHandle)
- +{
- + MV_STATUS status;
- +
- + status = mvTsuWinInit();
- + if(status == MV_OK)
- + status = mvTsuHalInit(coreClock,mode,osHandle);
- +
- + return status;
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 2010-11-09 20:28:09.894776606 +0100
- @@ -0,0 +1,110 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSysTsh
- +#define __INCmvSysTsh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* includes */
- +#include "ts/mvTsu.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +#define TSU_MAX_DECODE_WIN 4
- +
- +
- +/*******************************************/
- +/* TSU Windows Registers */
- +/*******************************************/
- +#define MV_TSU_WIN_CTRL_REG(win) (TSU_GLOBAL_REG_BASE +0x30 + 0x10 * win)
- +#define MV_TSU_WIN_BASE_REG(win) (TSU_GLOBAL_REG_BASE +0x34 + 0x10 * win)
- +
- +/* TSU windows control register. */
- +#define TSU_WIN_CTRL_EN_MASK (0x1 << 0)
- +#define TSU_WIN_CTRL_TARGET_OFFS 4
- +#define TSU_WIN_CTRL_TARGET_MASK (0xF << TSU_WIN_CTRL_TARGET_OFFS)
- +#define TSU_WIN_CTRL_ATTR_OFFS 8
- +#define TSU_WIN_CTRL_ATTR_MASK (0xFF << TSU_WIN_CTRL_ATTR_OFFS)
- +#define TSU_WIN_CTRL_SIZE_OFFS 16
- +#define TSU_WIN_CTRL_SIZE_MASK (0xFFFF << TSU_WIN_CTRL_SIZE_OFFS)
- +
- +/* TSU windows base register. */
- +#define TSU_WIN_BASE_OFFS 16
- +#define TSU_WIN_BASE_MASK (0xFFFF << TSU_WIN_BASE_OFFS)
- +
- +MV_STATUS mvTsuWinInit(void);
- +
- +void mvTsuAddrDecShow(void);
- +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
- + void *osHandle);
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvTsh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 2010-11-09 20:28:09.932495382 +0100
- @@ -0,0 +1,497 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "ctrlEnv/sys/mvSysUsb.h"
- +
- +MV_TARGET usbAddrDecPrioTab[] =
- +{
- +#if defined(MV_INCLUDE_SDRAM_CS0)
- + SDRAM_CS0,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + SDRAM_CS1,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS2)
- + SDRAM_CS2,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS3)
- + SDRAM_CS3,
- +#endif
- +#if defined(MV_INCLUDE_CESA) && defined(USB_UNDERRUN_WA)
- + CRYPT_ENG,
- +#endif
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_MEM,
- +#endif
- + TBL_TERM
- +};
- +
- +
- +
- +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost)
- +{
- + MV_STATUS status;
- +
- + status = mvUsbWinInit(dev);
- + if(status != MV_OK)
- + return status;
- +
- + return mvUsbHalInit(dev, isHost);
- +}
- +
- +
- +/*******************************************************************************
- +* usbWinOverlapDetect - Detect USB address windows overlapping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviur is expected in case USB address decode
- +* windows overlapps.
- +* This function detects USB address decode windows overlapping of a
- +* specified window. The function does not check the window itself for
- +* overlapping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS usbWinOverlapDetect(int dev, MV_U32 winNum,
- + MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 winNumIndex;
- + MV_DEC_WIN addrDecWin;
- +
- + for(winNumIndex=0; winNumIndex<MV_USB_MAX_ADDR_DECODE_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if (winNumIndex == winNum)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvUsbWinGet(dev, winNumIndex, &addrDecWin))
- + {
- + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled windows */
- + if(addrDecWin.enable == MV_FALSE)
- + {
- + continue;
- + }
- +
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* mvUsbWinSet - Set USB target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window, also known as address decode window.
- +* After setting this target window, the USB will be able to access the
- +* target within the address window.
- +*
- +* INPUT:
- +* winNum - USB target address decode window number.
- +* pAddrDecWin - USB target window data structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR if address window overlapps with other address decode windows.
- +* MV_BAD_PARAM if base address is invalid parameter or target is
- +* unknown.
- +*
- +*******************************************************************************/
- +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
- +{
- + MV_DEC_WIN_PARAMS winParams;
- + MV_U32 sizeReg, baseReg;
- +
- + /* Parameter checking */
- + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlapps with current windows */
- + if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin))
- + {
- + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
- + return MV_ERROR;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\
- + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + winNum,
- + mvCtrlTargetNameGet(pDecWin->target),
- + pDecWin->addrWin.baseLow,
- + pDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
- + {
- + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* set Size, Attributes and TargetID */
- + sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) |
- + ((winParams.attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) |
- + ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK));
- +
- +#if defined(MV645xx) || defined(MV646xx)
- + /* If window is DRAM with HW cache coherency, make sure bit2 is set */
- + sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK;
- +
- + if((MV_TARGET_IS_DRAM(pDecWin->target)) &&
- + (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY))
- + {
- + sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT;
- + }
- + else
- + {
- + sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT;
- + }
- +#endif /* MV645xx || MV646xx */
- +
- + if (pDecWin->enable == MV_TRUE)
- + {
- + sizeReg |= MV_USB_WIN_ENABLE_MASK;
- + }
- + else
- + {
- + sizeReg &= ~MV_USB_WIN_ENABLE_MASK;
- + }
- +
- + /* Update Base value */
- + baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK);
- +
- + MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg);
- + MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvUsbWinGet - Get USB peripheral target address window.
- +*
- +* DESCRIPTION:
- +* Get USB peripheral target address window.
- +*
- +* INPUT:
- +* winNum - USB target address decode window number.
- +*
- +* OUTPUT:
- +* pDecWin - USB target window data structure.
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
- +{
- + MV_DEC_WIN_PARAMS winParam;
- + MV_U32 sizeReg, baseReg;
- +
- + /* Parameter checking */
- + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
- + {
- + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
- + __FUNCTION__, dev, winNum);
- + return MV_NOT_SUPPORTED;
- + }
- +
- + baseReg = MV_REG_READ( MV_USB_WIN_BASE_REG(dev, winNum) );
- + sizeReg = MV_REG_READ( MV_USB_WIN_CTRL_REG(dev, winNum) );
- +
- + /* Check if window is enabled */
- + if(sizeReg & MV_USB_WIN_ENABLE_MASK)
- + {
- + pDecWin->enable = MV_TRUE;
- +
- + /* Extract window parameters from registers */
- + winParam.targetId = (sizeReg & MV_USB_WIN_TARGET_MASK) >> MV_USB_WIN_TARGET_OFFSET;
- + winParam.attrib = (sizeReg & MV_USB_WIN_ATTR_MASK) >> MV_USB_WIN_ATTR_OFFSET;
- + winParam.size = (sizeReg & MV_USB_WIN_SIZE_MASK) >> MV_USB_WIN_SIZE_OFFSET;
- + winParam.baseAddr = (baseReg & MV_USB_WIN_BASE_MASK);
- +
- + /* Translate the decode window parameters to address decode struct */
- + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
- + {
- + mvOsPrintf("Failed to translate register parameters to USB address" \
- + " decode window structure\n");
- + return MV_ERROR;
- + }
- + }
- + else
- + {
- + pDecWin->enable = MV_FALSE;
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvUsbWinInit -
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +*
- +* RETURN:
- +* MV_ERROR if register parameters are invalid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvUsbWinInit(int dev)
- +{
- + MV_STATUS status;
- + MV_DEC_WIN usbWin;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + int winNum;
- + MV_U32 winPrioIndex = 0;
- +
- + /* First disable all address decode windows */
- + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
- + {
- + MV_REG_BIT_RESET(MV_USB_WIN_CTRL_REG(dev, winNum), MV_USB_WIN_ENABLE_MASK);
- + }
- +
- + /* Go through all windows in user table until table terminator */
- + winNum = 0;
- + while( (usbAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
- + (winNum < MV_USB_MAX_ADDR_DECODE_WIN) )
- + {
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(usbAddrDecPrioTab[winPrioIndex],
- + &cpuAddrDecWin);
- +
- + if(MV_NO_SUCH == status)
- + {
- + winPrioIndex++;
- + continue;
- + }
- + if (MV_OK != status)
- + {
- + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- + usbWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + usbWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + usbWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + usbWin.enable = MV_TRUE;
- + usbWin.target = usbAddrDecPrioTab[winPrioIndex];
- +
- +#if defined(MV645xx) || defined(MV646xx)
- + /* Get the default attributes for that target window */
- + mvCtrlDefAttribGet(usbWin.target, &usbWin.addrWinAttr);
- +#endif /* MV645xx || MV646xx */
- +
- + if(MV_OK != mvUsbWinSet(dev, winNum, &usbWin))
- + {
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex++;
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvUsbAddrDecShow - Print the USB address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the USB address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvUsbAddrDecShow(MV_VOID)
- +{
- + MV_DEC_WIN addrDecWin;
- + int i, winNum;
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "USB:\n" );
- + mvOsOutput( "----\n" );
- +
- + for(i=0; i<mvCtrlUsbMaxGet(); i++)
- + {
- + mvOsOutput( "Device %d:\n", i);
- +
- + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
- + {
- + memset(&addrDecWin, 0, sizeof(MV_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", winNum );
- +
- + if( mvUsbWinGet(i, winNum, &addrDecWin ) == MV_OK )
- + {
- + if( addrDecWin.enable )
- + {
- + mvOsOutput( "%s base %08x, ",
- + mvCtrlTargetNameGet(addrDecWin.target), addrDecWin.addrWin.baseLow );
- +
- + mvSizePrint( addrDecWin.addrWin.size );
- +
- +#if defined(MV645xx) || defined(MV646xx)
- + switch( addrDecWin.addrWinAttr.swapType)
- + {
- + case MV_BYTE_SWAP:
- + mvOsOutput( "BYTE_SWAP, " );
- + break;
- + case MV_NO_SWAP:
- + mvOsOutput( "NO_SWAP , " );
- + break;
- + case MV_BYTE_WORD_SWAP:
- + mvOsOutput( "BYTE_WORD_SWAP, " );
- + break;
- + case MV_WORD_SWAP:
- + mvOsOutput( "WORD_SWAP, " );
- + break;
- + default:
- + mvOsOutput( "SWAP N/A , " );
- + }
- +
- + switch( addrDecWin.addrWinAttr.cachePolicy )
- + {
- + case NO_COHERENCY:
- + mvOsOutput( "NO_COHERENCY , " );
- + break;
- + case WT_COHERENCY:
- + mvOsOutput( "WT_COHERENCY , " );
- + break;
- + case WB_COHERENCY:
- + mvOsOutput( "WB_COHERENCY , " );
- + break;
- + default:
- + mvOsOutput( "COHERENCY N/A, " );
- + }
- +
- + switch( addrDecWin.addrWinAttr.pcixNoSnoop )
- + {
- + case 0:
- + mvOsOutput( "PCI-X NS inactive, " );
- + break;
- + case 1:
- + mvOsOutput( "PCI-X NS active , " );
- + break;
- + default:
- + mvOsOutput( "PCI-X NS N/A , " );
- + }
- +
- + switch( addrDecWin.addrWinAttr.p2pReq64 )
- + {
- + case 0:
- + mvOsOutput( "REQ64 force" );
- + break;
- + case 1:
- + mvOsOutput( "REQ64 detect" );
- + break;
- + default:
- + mvOsOutput( "REQ64 N/A" );
- + }
- +#endif /* MV645xx || MV646xx */
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- + }
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 2010-11-09 20:28:09.972495420 +0100
- @@ -0,0 +1,125 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSysUsbh
- +#define __INCmvSysUsbh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* includes */
- +#include "usb/mvUsb.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +#define MV_USB_MAX_ADDR_DECODE_WIN 4
- +
- +/*******************************************/
- +/* USB Bridge Registers */
- +/*******************************************/
- +#define MV_USB_BRIDGE_CTRL_REG(dev) (USB_REG_BASE(dev) + 0x300)
- +
- +#define MV_USB_WIN_CTRL_REG(dev, win) (USB_REG_BASE(dev) + 0x320 + ((win)<<4))
- +#define MV_USB_WIN_BASE_REG(dev, win) (USB_REG_BASE(dev) + 0x324 + ((win)<<4))
- +
- +/* BITs in Windows 0-3 Control and Base Registers */
- +#define MV_USB_WIN_ENABLE_BIT 0
- +#define MV_USB_WIN_ENABLE_MASK (1 << MV_USB_WIN_ENABLE_BIT)
- +
- +#define MV_USB_WIN_BURST_WR_LIMIT_BIT 1
- +#define MV_USB_WIN_BURST_WR_LIMIT_MASK (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
- +#define MV_USB_WIN_BURST_WR_NO_LIMIT (0 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
- +#define MV_USB_WIN_BURST_WR_32BIT_LIMIT (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
- +
- +#define MV_USB_WIN_TARGET_OFFSET 4
- +#define MV_USB_WIN_TARGET_MASK (0xF << MV_USB_WIN_TARGET_OFFSET)
- +
- +#define MV_USB_WIN_ATTR_OFFSET 8
- +#define MV_USB_WIN_ATTR_MASK (0xFF << MV_USB_WIN_ATTR_OFFSET)
- +
- +#define MV_USB_WIN_SIZE_OFFSET 16
- +#define MV_USB_WIN_SIZE_MASK (0xFFFF << MV_USB_WIN_SIZE_OFFSET)
- +
- +#define MV_USB_WIN_BASE_OFFSET 16
- +#define MV_USB_WIN_BASE_MASK (0xFFFF << MV_USB_WIN_BASE_OFFSET)
- +
- +
- +#define MV_USB_BRIDGE_IPG_REG(dev) (USB_REG_BASE(dev) + 0x360)
- +
- +
- +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost);
- +
- +MV_STATUS mvUsbWinInit(int dev);
- +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
- +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
- +
- +void mvUsbAddrDecShow(void);
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvUsbh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 2010-11-09 20:28:10.022500031 +0100
- @@ -0,0 +1,662 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "xor/mvXor.h"
- +#include "mvSysXor.h"
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +
- +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
- +
- +MV_TARGET xorAddrDecPrioTap[] =
- +{
- +#if defined(MV_INCLUDE_DEVICE_CS0)
- + DEVICE_CS0,
- +#endif
- +#if defined(MV_INCLUDE_PEX)
- + PEX0_MEM,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS0)
- + SDRAM_CS0,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + SDRAM_CS1,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS2)
- + SDRAM_CS2,
- +#endif
- +#if defined(MV_INCLUDE_SDRAM_CS3)
- + SDRAM_CS3,
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS1)
- + DEVICE_CS1,
- +#endif
- +#if defined(MV_INCLUDE_CESA)
- + CRYPT_ENG,
- +#endif
- + TBL_TERM
- +};
- +static MV_STATUS mvXorInitWinsUnit (MV_U32 unit)
- +{
- + MV_U32 winNum;
- + MV_XOR_DEC_WIN addrDecWin;
- + MV_CPU_DEC_WIN cpuAddrDecWin;
- + MV_U32 status;
- + MV_U32 winPrioIndex=0;
- +
- + /* Initiate XOR address decode */
- +
- + /* First disable all address decode windows */
- + for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++)
- + {
- + mvXorTargetWinEnable(unit,winNum, MV_FALSE);
- + }
- +
- + /* Go through all windows in user table until table terminator */
- + for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
- + (winNum < XOR_MAX_ADDR_DEC_WIN));)
- + {
- + /* first get attributes from CPU If */
- + status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex],
- + &cpuAddrDecWin);
- +
- + if(MV_NO_SUCH == status)
- + {
- + winPrioIndex++;
- + continue;
- + }
- + if (MV_OK != status)
- + {
- + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- +
- + if (cpuAddrDecWin.enable == MV_TRUE)
- + {
- +
- + addrDecWin.target = xorAddrDecPrioTap[winPrioIndex];
- + addrDecWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
- + addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
- + addrDecWin.addrWin.size = cpuAddrDecWin.addrWin.size;
- + addrDecWin.enable = MV_TRUE;
- +
- + if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin))
- + {
- + DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n"));
- + return MV_ERROR;
- + }
- + winNum++;
- + }
- + winPrioIndex++;
- +
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvXorInit - Initialize XOR engine
- +*
- +* DESCRIPTION:
- +* This function initialize XOR unit. It set the default address decode
- +* windows of the unit.
- +* Note that if the address window is disabled in xorAddrDecMap, the
- +* window parameters will be set but the window will remain disabled.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
- +*******************************************************************************/
- +MV_STATUS mvXorInit (MV_VOID)
- +{
- + MV_U32 i;
- +
- + /* Initiate XOR address decode */
- + for(i = 0; i < MV_XOR_MAX_UNIT; i++)
- + mvXorInitWinsUnit(i);
- +
- + mvXorHalInit(MV_XOR_MAX_CHAN);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvXorTargetWinSet - Set XOR target address window
- +*
- +* DESCRIPTION:
- +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
- +* address window. After setting this target window, the XOR will be
- +* able to access the target within the address window.
- +*
- +* INPUT:
- +* winNum - One of the possible XOR memory decode windows.
- +* target - Peripheral target enumerator.
- +* base - Window base address.
- +* size - Window size.
- +* enable - Window enable/disable.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS xorDecRegs;
- + MV_TARGET_ATTRIB targetAttribs;
- + MV_U32 chan;
- +
- + /* Parameter checking */
- + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
- + {
- + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));
- + return MV_BAD_PARAM;
- + }
- + if (pAddrDecWin == NULL)
- + {
- + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
- + return MV_BAD_PTR;
- + }
- + /* Check if the requested window overlaps with current windows */
- + if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))
- + {
- + DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));
- + return MV_ERROR;
- + }
- +
- + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
- + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
- +
- + /* Get Base Address and size registers values */
- + if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))
- + {
- + DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));
- + return MV_BAD_PARAM;
- + }
- +
- +
- + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
- +
- + /* set attributes */
- + xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;
- + xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;
- + /* set target ID */
- + xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;
- + xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;
- +
- +
- + /* Write to address decode Base Address Register */
- + MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);
- +
- + /* Write to Size Register */
- + MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);
- +
- + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
- + {
- + if (pAddrDecWin->enable)
- + {
- + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
- + XEXWCR_WIN_EN_MASK(winNum));
- + }
- + else
- + {
- + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
- + XEXWCR_WIN_EN_MASK(winNum));
- + }
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvXorTargetWinGet - Get xor peripheral target address window.
- +*
- +* DESCRIPTION:
- +* Get xor peripheral target address window.
- +*
- +* INPUT:
- +* winNum - One of the possible XOR memory decode windows.
- +*
- +* OUTPUT:
- +* base - Window base address.
- +* size - Window size.
- +* enable - window enable/disable.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
- +{
- + MV_DEC_REGS xorDecRegs;
- + MV_TARGET_ATTRIB targetAttrib;
- + MV_U32 chan=0,chanWinEn;
- +
- + /* Parameter checking */
- + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
- + {
- + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum));
- + return MV_ERROR;
- + }
- +
- + if (NULL == pAddrDecWin)
- + {
- + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
- + return MV_BAD_PTR;
- + }
- +
- + chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum);
- +
- + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) /* we should scan here all channels per unit */
- + {
- + /* Check if enable bit is equal for all channels */
- + if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
- + XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn)
- + {
- + mvOsPrintf("%s: ERR. Window enable field must be equal in "
- + "all channels(chan=%d)\n",__FUNCTION__, chan);
- + return MV_ERROR;
- + }
- + }
- +
- +
- +
- + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
- + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
- +
- + if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__);
- + return MV_ERROR;
- + }
- +
- + /* attrib and targetId */
- + targetAttrib.attrib =
- + (xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS;
- + targetAttrib.targetId =
- + (xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS;
- +
- +
- + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
- +
- + if(chanWinEn)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else pAddrDecWin->enable = MV_FALSE;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvXorTargetWinEnable - Enable/disable a Xor address decode window
- +*
- +* DESCRIPTION:
- +* This function enable/disable a XOR address decode window.
- +* if parameter 'enable' == MV_TRUE the routine will enable the
- +* window, thus enabling XOR accesses (before enabling the window it is
- +* tested for overlapping). Otherwise, the window will be disabled.
- +*
- +* INPUT:
- +* winNum - Decode window number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)
- +{
- + MV_XOR_DEC_WIN addrDecWin;
- + MV_U32 chan;
- +
- + /* Parameter checking */
- + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
- + {
- + DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));
- + return MV_ERROR;
- + }
- +
- + if (enable == MV_TRUE)
- + {
- + /* Get current window */
- + if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))
- + {
- + DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));
- + return MV_ERROR;
- + }
- +
- + /* Check for overlapping */
- + if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))
- + {
- + /* Overlap detected */
- + DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));
- + return MV_ERROR;
- + }
- +
- + /* No Overlap. Enable address decode target window */
- + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
- + {
- + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
- + XEXWCR_WIN_EN_MASK(winNum));
- + }
- +
- + }
- + else
- + {
- + /* Disable address decode target window */
- +
- + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
- + {
- + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
- + XEXWCR_WIN_EN_MASK(winNum));
- + }
- +
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvXorSetProtWinSet - Configure access attributes of a XOR engine
- +* to one of the XOR memory windows.
- +*
- +* DESCRIPTION:
- +* Each engine can be configured with access attributes for each of the
- +* memory spaces. This function sets access attributes
- +* to a given window for the given engine
- +*
- +* INPUTS:
- +* chan - One of the possible engines.
- +* winNum - One of the possible XOR memory spaces.
- +* access - Protection access rights.
- +* write - Write rights.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
- + MV_BOOL write)
- +{
- + MV_U32 temp;
- +
- + /* Parameter checking */
- + if (chan >= MV_XOR_MAX_CHAN_PER_UNIT)
- + {
- + DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __FUNCTION__ , chan));
- + return MV_BAD_PARAM;
- + }
- + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
- + {
- + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
- + return MV_BAD_PARAM;
- + }
- +
- + temp = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
- + (~XEXWCR_WIN_ACC_MASK(winNum));
- +
- + /* if access is disable */
- + if (!access)
- + {
- + /* disable access */
- + temp |= XEXWCR_WIN_ACC_NO_ACC(winNum);
- + }
- + /* if access is enable */
- + else
- + {
- + /* if write is enable */
- + if (write)
- + {
- + /* enable write */
- + temp |= XEXWCR_WIN_ACC_RW(winNum);
- + }
- + /* if write is disable */
- + else
- + {
- + /* disable write */
- + temp |= XEXWCR_WIN_ACC_RO(winNum);
- + }
- + }
- + MV_REG_WRITE(XOR_WINDOW_CTRL_REG(unit,chan),temp);
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvXorPciRemap - Set XOR remap register for PCI address windows.
- +*
- +* DESCRIPTION:
- +* only Windows 0-3 can be remapped.
- +*
- +* INPUT:
- +* winNum - window number
- +* pAddrDecWin - pointer to address space window structure
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvXorPciRemap(MV_U32 unit,MV_U32 winNum, MV_U32 addrHigh)
- +{
- + /* Parameter checking */
- + if (winNum >= XOR_MAX_REMAP_WIN)
- + {
- + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
- + return MV_BAD_PARAM;
- + }
- +
- + MV_REG_WRITE(XOR_HIGH_ADDR_REMAP_REG(unit,winNum), addrHigh);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* xorWinOverlapDetect - Detect XOR address windows overlaping
- +*
- +* DESCRIPTION:
- +* An unpredicted behaviour is expected in case XOR address decode
- +* windows overlaps.
- +* This function detects XOR address decode windows overlaping of a
- +* specified window. The function does not check the window itself for
- +* overlaping. The function also skipps disabled address decode windows.
- +*
- +* INPUT:
- +* winNum - address decode window number.
- +* pAddrDecWin - An address decode window struct.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlap current address
- +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
- +* from registers.
- +*
- +*******************************************************************************/
- +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_U32 baseAddrEnableReg;
- + MV_U32 winNumIndex,chan;
- + MV_XOR_DEC_WIN addrDecWin;
- +
- + if (pAddrWin == NULL)
- + {
- + DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ ));
- + return MV_BAD_PTR;
- + }
- +
- + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
- + {
- + /* Read base address enable register. Do not check disabled windows */
- + baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan));
- +
- + for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++)
- + {
- + /* Do not check window itself */
- + if (winNumIndex == winNum)
- + {
- + continue;
- + }
- +
- + /* Do not check disabled windows */
- + if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin))
- + {
- + DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ ));
- + return MV_ERROR;
- + }
- +
- + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
- + {
- + return MV_TRUE;
- + }
- + }
- + }
- +
- + return MV_FALSE;
- +}
- +
- +static MV_VOID mvXorAddrDecShowUnit(MV_U32 unit)
- +{
- + MV_XOR_DEC_WIN win;
- + int i;
- +
- + mvOsOutput( "\n" );
- + mvOsOutput( "XOR %d:\n", unit );
- + mvOsOutput( "----\n" );
- +
- + for( i = 0; i < XOR_MAX_ADDR_DEC_WIN; i++ )
- + {
- + memset( &win, 0, sizeof(MV_XOR_DEC_WIN) );
- +
- + mvOsOutput( "win%d - ", i );
- +
- + if( mvXorTargetWinGet(unit, i, &win ) == MV_OK )
- + {
- + if( win.enable )
- + {
- + mvOsOutput( "%s base %x, ",
- + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
- +
- + mvSizePrint( win.addrWin.size );
- +
- + mvOsOutput( "\n" );
- + }
- + else
- + mvOsOutput( "disable\n" );
- + }
- + }
- +}
- +
- +/*******************************************************************************
- +* mvXorAddrDecShow - Print the XOR address decode map.
- +*
- +* DESCRIPTION:
- +* This function print the XOR address decode map.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID mvXorAddrDecShow(MV_VOID)
- +{
- + int i;
- +
- + for( i = 0; i < MV_XOR_MAX_UNIT; i++ )
- + mvXorAddrDecShowUnit(i);
- +
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 2010-11-09 20:28:10.062495382 +0100
- @@ -0,0 +1,140 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCMVSysXorh
- +#define __INCMVSysXorh
- +
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif
- +
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +#define XOR_MAX_ADDR_DEC_WIN 8 /* Maximum address decode windows */
- +#define XOR_MAX_REMAP_WIN 4 /* Maximum address arbiter windows */
- +
- +/* XOR Engine Address Decoding Register Map */
- +#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))
- +#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))
- +#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))
- +#define XOR_HIGH_ADDR_REMAP_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x290 + ((winNum) * 4)))
- +
- +/* XOR Engine [0..1] Window Control Registers (XExWCR) */
- +#define XEXWCR_WIN_EN_OFFS(winNum) (winNum)
- +#define XEXWCR_WIN_EN_MASK(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
- +#define XEXWCR_WIN_EN_ENABLE(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
- +#define XEXWCR_WIN_EN_DISABLE(winNum) (0 << (XEXWCR_WIN_EN_OFFS(winNum)))
- +
- +#define XEXWCR_WIN_ACC_OFFS(winNum) ((2 * winNum) + 16)
- +#define XEXWCR_WIN_ACC_MASK(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
- +#define XEXWCR_WIN_ACC_NO_ACC(winNum) (0 << (XEXWCR_WIN_ACC_OFFS(winNum)))
- +#define XEXWCR_WIN_ACC_RO(winNum) (1 << (XEXWCR_WIN_ACC_OFFS(winNum)))
- +#define XEXWCR_WIN_ACC_RW(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
- +
- +/* XOR Engine Base Address Registers (XEBARx) */
- +#define XEBARX_TARGET_OFFS (0)
- +#define XEBARX_TARGET_MASK (0xF << XEBARX_TARGET_OFFS)
- +#define XEBARX_ATTR_OFFS (8)
- +#define XEBARX_ATTR_MASK (0xFF << XEBARX_ATTR_OFFS)
- +#define XEBARX_BASE_OFFS (16)
- +#define XEBARX_BASE_MASK (0xFFFF << XEBARX_BASE_OFFS)
- +
- +/* XOR Engine Size Mask Registers (XESMRx) */
- +#define XESMRX_SIZE_MASK_OFFS (16)
- +#define XESMRX_SIZE_MASK_MASK (0xFFFF << XESMRX_SIZE_MASK_OFFS)
- +
- +/* XOR Engine High Address Remap Register (XEHARRx1) */
- +#define XEHARRX_REMAP_OFFS (0)
- +#define XEHARRX_REMAP_MASK (0xFFFFFFFF << XEHARRX_REMAP_OFFS)
- +
- +typedef struct _mvXorDecWin
- +{
- + MV_TARGET target;
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +
- +}MV_XOR_DEC_WIN;
- +
- +MV_STATUS mvXorInit (MV_VOID);
- +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum,
- + MV_XOR_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvXorTargetWinGet(MV_U32 unit, MV_U32 winNum,
- + MV_XOR_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,
- + MV_U32 winNum, MV_BOOL enable);
- +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
- + MV_BOOL write);
- +MV_STATUS mvXorPciRemap(MV_U32 unit, MV_U32 winNum, MV_U32 addrHigh);
- +
- +MV_VOID mvXorAddrDecShow(MV_VOID);
- +
- +#ifdef __cplusplus
- +}
- +#endif
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 2010-11-09 20:28:10.101392611 +0100
- @@ -0,0 +1,75 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "device/mvDevice.h"
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 2010-11-09 20:28:10.141918633 +0100
- @@ -0,0 +1,74 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvDeviceH
- +#define __INCmvDeviceH
- +
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +#include "device/mvDeviceRegs.h"
- +
- +
- +#endif /* #ifndef __INCmvDeviceH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 2010-11-09 20:28:10.181250318 +0100
- @@ -0,0 +1,101 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvDeviceRegsH
- +#define __INCmvDeviceRegsH
- +
- +#ifndef MV_ASMLANGUAGE
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +/* This enumerator describes the Marvell controller possible devices that */
- +/* can be connected to its device interface. */
- +typedef enum _mvDevice
- +{
- +#if defined(MV_INCLUDE_DEVICE_CS0)
- + DEV_CS0 = 0, /* Device connected to dev CS[0] */
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS1)
- + DEV_CS1 = 1, /* Device connected to dev CS[1] */
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS2)
- + DEV_CS2 = 2, /* Device connected to dev CS[2] */
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS3)
- + DEV_CS3 = 3, /* Device connected to dev CS[2] */
- +#endif
- +#if defined(MV_INCLUDE_DEVICE_CS4)
- + DEV_CS4 = 4, /* Device connected to BOOT dev */
- +#endif
- + MV_DEV_MAX_CS = MV_DEVICE_MAX_CS
- +}MV_DEVICE;
- +
- +
- +#endif /* MV_ASMLANGUAGE */
- +
- +
- +#define NAND_CTRL_REG 0x10470
- +
- +#define NAND_ACTCEBOOT_BIT BIT1
- +
- +
- +#endif /* #ifndef __INCmvDeviceRegsH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 2010-11-09 20:28:10.222495542 +0100
- @@ -0,0 +1,211 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +*******************************************************************************/
- +/*******************************************************************************
- +* mvOsCpuArchLib.c - Marvell CPU architecture library
- +*
- +* DESCRIPTION:
- +* This library introduce Marvell API for OS dependent CPU architecture
- +* APIs. This library introduce single CPU architecture services APKI
- +* cross OS.
- +*
- +* DEPENDENCIES:
- +* None.
- +*
- +*******************************************************************************/
- +
- +/* includes */
- +#include <asm/processor.h>
- +#include "mvOs.h"
- +
- +static MV_U32 read_p15_c0 (void);
- +
- +/* defines */
- +#define ARM_ID_REVISION_OFFS 0
- +#define ARM_ID_REVISION_MASK (0xf << ARM_ID_REVISION_OFFS)
- +
- +#define ARM_ID_PART_NUM_OFFS 4
- +#define ARM_ID_PART_NUM_MASK (0xfff << ARM_ID_PART_NUM_OFFS)
- +
- +#define ARM_ID_ARCH_OFFS 16
- +#define ARM_ID_ARCH_MASK (0xf << ARM_ID_ARCH_OFFS)
- +
- +#define ARM_ID_VAR_OFFS 20
- +#define ARM_ID_VAR_MASK (0xf << ARM_ID_VAR_OFFS)
- +
- +#define ARM_ID_ASCII_OFFS 24
- +#define ARM_ID_ASCII_MASK (0xff << ARM_ID_ASCII_OFFS)
- +
- +
- +
- +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
- + MV_U32 *memHandle)
- +{
- + void *p = kmalloc( size, GFP_KERNEL );
- + *pPhyAddr = pci_map_single( osHandle, p, 0, PCI_DMA_BIDIRECTIONAL );
- + return p;
- +}
- +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
- + MV_U32 *memHandle)
- +{
- + return pci_alloc_consistent( osHandle, size, (dma_addr_t *)pPhyAddr );
- +}
- +
- +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
- + MV_U32 memHandle)
- +{
- + return pci_free_consistent( osHandle, size, pVirtAddr, (dma_addr_t)phyAddr );
- +}
- +
- +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
- + MV_U32 memHandle )
- +{
- + return kfree( pVirtAddr );
- +}
- +
- +int mvOsRand(void)
- +{
- + int rand;
- + get_random_bytes(&rand, sizeof(rand) );
- + return rand;
- +}
- +
- +/*******************************************************************************
- +* mvOsCpuVerGet() -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit CPU Revision
- +*
- +*******************************************************************************/
- +MV_U32 mvOsCpuRevGet( MV_VOID )
- +{
- + return ((read_p15_c0() & ARM_ID_REVISION_MASK ) >> ARM_ID_REVISION_OFFS);
- +}
- +/*******************************************************************************
- +* mvOsCpuPartGet() -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit CPU Part number
- +*
- +*******************************************************************************/
- +MV_U32 mvOsCpuPartGet( MV_VOID )
- +{
- + return ((read_p15_c0() & ARM_ID_PART_NUM_MASK ) >> ARM_ID_PART_NUM_OFFS);
- +}
- +/*******************************************************************************
- +* mvOsCpuArchGet() -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit CPU Architicture number
- +*
- +*******************************************************************************/
- +MV_U32 mvOsCpuArchGet( MV_VOID )
- +{
- + return ((read_p15_c0() & ARM_ID_ARCH_MASK ) >> ARM_ID_ARCH_OFFS);
- +}
- +/*******************************************************************************
- +* mvOsCpuVarGet() -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit CPU Variant number
- +*
- +*******************************************************************************/
- +MV_U32 mvOsCpuVarGet( MV_VOID )
- +{
- + return ((read_p15_c0() & ARM_ID_VAR_MASK ) >> ARM_ID_VAR_OFFS);
- +}
- +/*******************************************************************************
- +* mvOsCpuAsciiGet() -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit CPU Variant number
- +*
- +*******************************************************************************/
- +MV_U32 mvOsCpuAsciiGet( MV_VOID )
- +{
- + return ((read_p15_c0() & ARM_ID_ASCII_MASK ) >> ARM_ID_ASCII_OFFS);
- +}
- +
- +
- +
- +/*
- +static unsigned long read_p15_c0 (void)
- +*/
- +/* read co-processor 15, register #0 (ID register) */
- +static MV_U32 read_p15_c0 (void)
- +{
- + MV_U32 value;
- +
- + __asm__ __volatile__(
- + "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
- + : "=r" (value)
- + :
- + : "memory");
- +
- + return value;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 2010-11-09 20:28:10.262495482 +0100
- @@ -0,0 +1,423 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +*******************************************************************************/
- +#ifndef _MV_OS_LNX_H_
- +#define _MV_OS_LNX_H_
- +
- +
- +#ifdef __KERNEL__
- +/* for kernel space */
- +#include <linux/autoconf.h>
- +#include <linux/interrupt.h>
- +#include <linux/stddef.h>
- +#include <linux/kernel.h>
- +#include <linux/init.h>
- +#include <linux/errno.h>
- +#include <linux/reboot.h>
- +#include <linux/pci.h>
- +#include <linux/kdev_t.h>
- +#include <linux/major.h>
- +#include <linux/blkdev.h>
- +#include <linux/console.h>
- +#include <linux/delay.h>
- +#include <linux/seq_file.h>
- +#include <linux/string.h>
- +#include <linux/slab.h>
- +#include <linux/kernel.h>
- +#include <linux/string.h>
- +#include <linux/slab.h>
- +#include <linux/mm.h>
- +
- +#include <asm/system.h>
- +#include <asm/pgtable.h>
- +#include <asm/page.h>
- +#include <asm/hardirq.h>
- +#include <asm/dma.h>
- +#include <asm/io.h>
- +
- +#include <linux/random.h>
- +
- +#include "dbg-trace.h"
- +
- +extern void mv_early_printk(char *fmt,...);
- +
- +#define MV_ASM __asm__ __volatile__
- +#define INLINE inline
- +#define MV_TRC_REC TRC_REC
- +#define mvOsPrintf printk
- +#define mvOsEarlyPrintf mv_early_printk
- +#define mvOsOutput printk
- +#define mvOsSPrintf sprintf
- +#define mvOsMalloc(_size_) kmalloc(_size_,GFP_ATOMIC)
- +#define mvOsFree kfree
- +#define mvOsMemcpy memcpy
- +#define mvOsSleep(_mils_) mdelay(_mils_)
- +#define mvOsTaskLock()
- +#define mvOsTaskUnlock()
- +#define strtol simple_strtoul
- +#define mvOsDelay(x) mdelay(x)
- +#define mvOsUDelay(x) udelay(x)
- +#define mvCopyFromOs copy_from_user
- +#define mvCopyToOs copy_to_user
- +
- +
- +#include "mvTypes.h"
- +#include "mvCommon.h"
- +
- +#ifdef MV_NDEBUG
- +#define mvOsAssert(cond)
- +#else
- +#define mvOsAssert(cond) { do { if(!(cond)) { BUG(); } }while(0); }
- +#endif /* MV_NDEBUG */
- +
- +#else /* __KERNEL__ */
- +
- +/* for user space applications */
- +#include <stdlib.h>
- +#include <stdio.h>
- +#include <assert.h>
- +#include <string.h>
- +
- +#define INLINE inline
- +#define mvOsPrintf printf
- +#define mvOsOutput printf
- +#define mvOsMalloc(_size_) malloc(_size_)
- +#define mvOsFree free
- +#define mvOsAssert(cond) assert(cond)
- +
- +#endif /* __KERNEL__ */
- +#define mvOsIoVirtToPhy(pDev, pVirtAddr) \
- + pci_map_single( (pDev), (pVirtAddr), 0, PCI_DMA_BIDIRECTIONAL )
- +
- +#define mvOsCacheClear(pDev, p, size ) \
- + pci_map_single( (pDev), (p), (size), PCI_DMA_BIDIRECTIONAL)
- +
- +#define mvOsCacheFlush(pDev, p, size ) \
- + pci_map_single( (pDev), (p), (size), PCI_DMA_TODEVICE)
- +
- +#define mvOsCacheInvalidate(pDev, p, size) \
- + pci_map_single( (pDev), (p), (size), PCI_DMA_FROMDEVICE )
- +
- +#define mvOsCacheUnmap(pDev, phys, size) \
- + pci_unmap_single( (pDev), (dma_addr_t)(phys), (size), PCI_DMA_FROMDEVICE )
- +
- +
- +#define CPU_PHY_MEM(x) (MV_U32)x
- +#define CPU_MEMIO_CACHED_ADDR(x) (void*)x
- +#define CPU_MEMIO_UNCACHED_ADDR(x) (void*)x
- +
- +
- +/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */
- +#define MV_MEMIO32_WRITE(addr, data) \
- + ((*((volatile unsigned int*)(addr))) = ((unsigned int)(data)))
- +
- +#define MV_MEMIO32_READ(addr) \
- + ((*((volatile unsigned int*)(addr))))
- +
- +#define MV_MEMIO16_WRITE(addr, data) \
- + ((*((volatile unsigned short*)(addr))) = ((unsigned short)(data)))
- +
- +#define MV_MEMIO16_READ(addr) \
- + ((*((volatile unsigned short*)(addr))))
- +
- +#define MV_MEMIO8_WRITE(addr, data) \
- + ((*((volatile unsigned char*)(addr))) = ((unsigned char)(data)))
- +
- +#define MV_MEMIO8_READ(addr) \
- + ((*((volatile unsigned char*)(addr))))
- +
- +
- +/* No Fast Swap implementation (in assembler) for ARM */
- +#define MV_32BIT_LE_FAST(val) MV_32BIT_LE(val)
- +#define MV_16BIT_LE_FAST(val) MV_16BIT_LE(val)
- +#define MV_32BIT_BE_FAST(val) MV_32BIT_BE(val)
- +#define MV_16BIT_BE_FAST(val) MV_16BIT_BE(val)
- +
- +/* 32 and 16 bit read/write in big/little endian mode */
- +
- +/* 16bit write in little endian mode */
- +#define MV_MEMIO_LE16_WRITE(addr, data) \
- + MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))
- +
- +/* 16bit read in little endian mode */
- +static __inline MV_U16 MV_MEMIO_LE16_READ(MV_U32 addr)
- +{
- + MV_U16 data;
- +
- + data= (MV_U16)MV_MEMIO16_READ(addr);
- +
- + return (MV_U16)MV_16BIT_LE_FAST(data);
- +}
- +
- +/* 32bit write in little endian mode */
- +#define MV_MEMIO_LE32_WRITE(addr, data) \
- + MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
- +
- +/* 32bit read in little endian mode */
- +static __inline MV_U32 MV_MEMIO_LE32_READ(MV_U32 addr)
- +{
- + MV_U32 data;
- +
- + data= (MV_U32)MV_MEMIO32_READ(addr);
- +
- + return (MV_U32)MV_32BIT_LE_FAST(data);
- +}
- +
- +static __inline void mvOsBCopy(char* srcAddr, char* dstAddr, int byteCount)
- +{
- + while(byteCount != 0)
- + {
- + *dstAddr = *srcAddr;
- + dstAddr++;
- + srcAddr++;
- + byteCount--;
- + }
- +}
- +
- +static INLINE MV_U64 mvOsDivMod64(MV_U64 divided, MV_U64 divisor, MV_U64* modulu)
- +{
- + MV_U64 division = 0;
- +
- + if(divisor == 1)
- + return divided;
- +
- + while(divided >= divisor)
- + {
- + division++;
- + divided -= divisor;
- + }
- + if (modulu != NULL)
- + *modulu = divided;
- +
- + return division;
- +}
- +
- +#if defined(MV_BRIDGE_SYNC_REORDER)
- +extern MV_U32 *mvUncachedParam;
- +
- +static __inline void mvOsBridgeReorderWA(void)
- +{
- + volatile MV_U32 val = 0;
- +
- + val = mvUncachedParam[0];
- +}
- +#endif
- +
- +
- +/* Flash APIs */
- +#define MV_FL_8_READ MV_MEMIO8_READ
- +#define MV_FL_16_READ MV_MEMIO_LE16_READ
- +#define MV_FL_32_READ MV_MEMIO_LE32_READ
- +#define MV_FL_8_DATA_READ MV_MEMIO8_READ
- +#define MV_FL_16_DATA_READ MV_MEMIO16_READ
- +#define MV_FL_32_DATA_READ MV_MEMIO32_READ
- +#define MV_FL_8_WRITE MV_MEMIO8_WRITE
- +#define MV_FL_16_WRITE MV_MEMIO_LE16_WRITE
- +#define MV_FL_32_WRITE MV_MEMIO_LE32_WRITE
- +#define MV_FL_8_DATA_WRITE MV_MEMIO8_WRITE
- +#define MV_FL_16_DATA_WRITE MV_MEMIO16_WRITE
- +#define MV_FL_32_DATA_WRITE MV_MEMIO32_WRITE
- +
- +
- +/* CPU cache information */
- +#define CPU_I_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
- +#define CPU_D_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
- +
- +#ifdef CONFIG_L2_CACHE_ENABLE
- +/* Data cache flush one line */
- +#define mvOsCacheLineFlushInv(handle, addr) \
- +{ \
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
- + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c10, 1" : : "r" (addr));\
- + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
- +}
- +
- +#else
- +
- +/* Data cache flush one line */
- +#define mvOsCacheLineFlushInv(handle, addr) \
- +{ \
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
- +}
- +#endif
- +
- +#ifdef CONFIG_L2_CACHE_ENABLE
- +#define mvOsCacheLineInv(handle,addr) \
- +{ \
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
- + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c11, 1" : : "r" (addr)); \
- +}
- +#else
- +#define mvOsCacheLineInv(handle,addr) \
- +{ \
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
- +}
- +#endif
- +
- +#ifdef CONFIG_L2_CACHE_ENABLE
- +/* Data cache flush one line */
- +#define mvOsCacheLineFlush(handle, addr) \
- +{ \
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
- + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c9, 1" : : "r" (addr));\
- + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
- +}
- +
- +#else
- +/* Data cache flush one line */
- +#define mvOsCacheLineFlush(handle, addr) \
- +{ \
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
- + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
- +}
- +#endif
- +
- +static __inline void mvOsPrefetch(const void *ptr)
- +{
- +#ifdef CONFIG_USE_DSP
- + __asm__ __volatile__(
- + "pld\t%0"
- + :
- + : "o" (*(char *)ptr)
- + : "cc");
- +#else
- + return;
- +#endif
- +}
- +
- +
- +/* Flush CPU pipe */
- +#define CPU_PIPE_FLUSH
- +
- +
- +
- +
- +
- +/* register manipulations */
- +
- +/******************************************************************************
- +* This debug function enable the write of each register that u-boot access to
- +* to an array in the DRAM, the function record only MV_REG_WRITE access.
- +* The function could not be operate when booting from flash.
- +* In order to print the array we use the printreg command.
- +******************************************************************************/
- +/* #define REG_DEBUG */
- +#if defined(REG_DEBUG)
- +extern int reg_arry[2048][2];
- +extern int reg_arry_index;
- +#endif
- +
- +/* Marvell controller register read/write macros */
- +#define MV_REG_VALUE(offset) \
- + (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))
- +
- +#define MV_REG_READ(offset) \
- + (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))
- +
- +#if defined(REG_DEBUG)
- +#define MV_REG_WRITE(offset, val) \
- + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val)); \
- + { \
- + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
- + reg_arry[reg_arry_index][1] = (val);\
- + reg_arry_index++;\
- + }
- +#else
- +#define MV_REG_WRITE(offset, val) \
- + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val));
- +#endif
- +
- +#define MV_REG_BYTE_READ(offset) \
- + (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))
- +
- +#if defined(REG_DEBUG)
- +#define MV_REG_BYTE_WRITE(offset, val) \
- + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val)); \
- + { \
- + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
- + reg_arry[reg_arry_index][1] = (val);\
- + reg_arry_index++;\
- + }
- +#else
- +#define MV_REG_BYTE_WRITE(offset, val) \
- + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))
- +#endif
- +
- +#if defined(REG_DEBUG)
- +#define MV_REG_BIT_SET(offset, bitMask) \
- + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
- + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
- + MV_32BIT_LE_FAST(bitMask)))); \
- + { \
- + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
- + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
- + reg_arry_index++;\
- + }
- +#else
- +#define MV_REG_BIT_SET(offset, bitMask) \
- + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
- + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
- + MV_32BIT_LE_FAST(bitMask))))
- +#endif
- +
- +#if defined(REG_DEBUG)
- +#define MV_REG_BIT_RESET(offset,bitMask) \
- + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
- + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
- + MV_32BIT_LE_FAST(~bitMask)))); \
- + { \
- + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
- + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
- + reg_arry_index++;\
- + }
- +#else
- +#define MV_REG_BIT_RESET(offset,bitMask) \
- + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
- + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
- + MV_32BIT_LE_FAST(~bitMask))))
- +#endif
- +
- +
- +
- +/* ARM architecture APIs */
- +MV_U32 mvOsCpuRevGet (MV_VOID);
- +MV_U32 mvOsCpuPartGet (MV_VOID);
- +MV_U32 mvOsCpuArchGet (MV_VOID);
- +MV_U32 mvOsCpuVarGet (MV_VOID);
- +MV_U32 mvOsCpuAsciiGet (MV_VOID);
- +
- +/* Other APIs */
- +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle);
- +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle );
- +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
- +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
- +int mvOsRand(void);
- +
- +#endif /* _MV_OS_LNX_H_ */
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 2010-11-09 20:28:10.302495426 +0100
- @@ -0,0 +1,158 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +*******************************************************************************/
- +/*******************************************************************************
- +* mvOsLinux.h - O.S. interface header file for Linux
- +*
- +* DESCRIPTION:
- +* This header file contains OS dependent definition under Linux
- +*
- +* DEPENDENCIES:
- +* Linux kernel header files.
- +*
- +* FILE REVISION NUMBER:
- +* $Revision: 1.1 $
- +*******************************************************************************/
- +
- +#ifndef __INCmvOsLinuxh
- +#define __INCmvOsLinuxh
- +
- +/* Includes */
- +#include <linux/autoconf.h>
- +#include <linux/module.h>
- +#include <linux/types.h>
- +#include <linux/string.h>
- +#include <linux/kernel.h>
- +#include <linux/timer.h>
- +#include <linux/mm.h>
- +#include <linux/interrupt.h>
- +#include <linux/major.h>
- +#include <linux/errno.h>
- +#include <linux/genhd.h>
- +#include <linux/slab.h>
- +#include <linux/delay.h>
- +#include <linux/ide.h>
- +#include <linux/pci.h>
- +
- +#include <asm/byteorder.h>
- +#include <asm/irq.h>
- +#include <asm/uaccess.h>
- +#include <asm/io.h>
- +#include "mvOs.h"
- +
- +
- +/* Definitions */
- +#define MV_DEFAULT_QUEUE_DEPTH 2
- +#define MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
- +#define MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
- +
- +#ifdef CONFIG_MV88F6082
- + #define MV_SATA_OVERRIDE_SW_QUEUE_SIZE
- + #define MV_SATA_REQUESTED_SW_QUEUE_SIZE 2
- + #undef MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
- +#endif
- +
- +/* System dependent macro for flushing CPU write cache */
- +#if defined (MV_BRIDGE_SYNC_REORDER)
- +#define MV_CPU_WRITE_BUFFER_FLUSH() do { \
- + wmb(); \
- + mvOsBridgeReorderWA(); \
- + } while (0)
- +#else
- +#define MV_CPU_WRITE_BUFFER_FLUSH() wmb()
- +#endif /* CONFIG_MV78XX0 */
- +
- +/* System dependent little endian from / to CPU conversions */
- +#define MV_CPU_TO_LE16(x) cpu_to_le16(x)
- +#define MV_CPU_TO_LE32(x) cpu_to_le32(x)
- +
- +#define MV_LE16_TO_CPU(x) le16_to_cpu(x)
- +#define MV_LE32_TO_CPU(x) le32_to_cpu(x)
- +
- +#ifdef __BIG_ENDIAN_BITFIELD
- +#define MV_BIG_ENDIAN_BITFIELD
- +#endif
- +
- +/* System dependent register read / write in byte/word/dword variants */
- +#define MV_REG_WRITE_BYTE(base, offset, val) writeb(val, base + offset)
- +#define MV_REG_WRITE_WORD(base, offset, val) writew(val, base + offset)
- +#define MV_REG_WRITE_DWORD(base, offset, val) writel(val, base + offset)
- +#define MV_REG_READ_BYTE(base, offset) readb(base + offset)
- +#define MV_REG_READ_WORD(base, offset) readw(base + offset)
- +#define MV_REG_READ_DWORD(base, offset) readl(base + offset)
- +
- +
- +/* Typedefs */
- +
- +/* System dependant typedefs */
- +typedef void *MV_VOID_PTR;
- +typedef u32 *MV_U32_PTR;
- +typedef u16 *MV_U16_PTR;
- +typedef u8 *MV_U8_PTR;
- +typedef char *MV_CHAR_PTR;
- +typedef void *MV_BUS_ADDR_T;
- +typedef unsigned long MV_CPU_FLAGS;
- +
- +
- +/* Structures */
- +/* System dependent structure */
- +typedef struct mvOsSemaphore
- +{
- + int notUsed;
- +} MV_OS_SEMAPHORE;
- +
- +
- +/* Functions (User implemented)*/
- +
- +/* Semaphore init, take and release */
- +#define mvOsSemInit(x) MV_TRUE
- +#define mvOsSemTake(x)
- +#define mvOsSemRelease(x)
- +
- +/* Interrupt masking and unmasking functions */
- +MV_CPU_FLAGS mvOsSaveFlagsAndMaskCPUInterrupts(MV_VOID);
- +MV_VOID mvOsRestoreFlags(MV_CPU_FLAGS);
- +
- +/* Delay function in micro seconds resolution */
- +void mvMicroSecondsDelay(MV_VOID_PTR, MV_U32);
- +
- +/* Typedefs */
- +typedef enum mvBoolean
- +{
- + MV_SFALSE, MV_STRUE
- +} MV_BOOLEAN;
- +
- +/* System logging function */
- +#include "mvLog.h"
- +/* Enable READ/WRITE Long SCSI command only when driver is compiled for debugging */
- +#ifdef MV_LOGGER
- +#define MV_SATA_SUPPORT_READ_WRITE_LONG
- +#endif
- +
- +#define MV_IAL_LOG_ID 3
- +
- +#endif /* __INCmvOsLinuxh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 2010-11-09 20:28:10.342495568 +0100
- @@ -0,0 +1,376 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvCntmr.h"
- +#include "cpu/mvCpu.h"
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +extern unsigned int whoAmI(void);
- +
- +/*******************************************************************************
- +* mvCntmrLoad -
- +*
- +* DESCRIPTION:
- +* Load an init Value to a given counter/timer
- +*
- +* INPUT:
- +* countNum - counter number
- +* value - value to be loaded
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
- +*******************************************************************************/
- +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)
- +{
- + if (countNum >= MV_CNTMR_MAX_COUNTER )
- + {
- +
- + mvOsPrintf(("mvCntmrLoad: Err. Illigal counter number \n"));
- + return MV_BAD_PARAM;;
- +
- + }
- +
- + MV_REG_WRITE(CNTMR_RELOAD_REG(countNum),value);
- + MV_REG_WRITE(CNTMR_VAL_REG(countNum),value);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCntmrRead -
- +*
- +* DESCRIPTION:
- +* Returns the value of the given Counter/Timer
- +*
- +* INPUT:
- +* countNum - counter number
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_U32 counter value
- +*******************************************************************************/
- +MV_U32 mvCntmrRead(MV_U32 countNum)
- +{
- + return MV_REG_READ(CNTMR_VAL_REG(countNum));
- +}
- +
- +/*******************************************************************************
- +* mvCntmrWrite -
- +*
- +* DESCRIPTION:
- +* Returns the value of the given Counter/Timer
- +*
- +* INPUT:
- +* countNum - counter number
- +* countVal - value to write
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None
- +*******************************************************************************/
- +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal)
- +{
- + MV_REG_WRITE(CNTMR_VAL_REG(countNum),countVal);
- +}
- +
- +/*******************************************************************************
- +* mvCntmrCtrlSet -
- +*
- +* DESCRIPTION:
- +* Set the Control to a given counter/timer
- +*
- +* INPUT:
- +* countNum - counter number
- +* pCtrl - pointer to MV_CNTMR_CTRL structure
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
- +*******************************************************************************/
- +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
- +{
- + MV_U32 cntmrCtrl;
- +
- + if (countNum >= MV_CNTMR_MAX_COUNTER )
- + {
- +
- + DB(mvOsPrintf(("mvCntmrCtrlSet: Err. Illigal counter number \n")));
- + return MV_BAD_PARAM;;
- +
- + }
- +
- + /* read control register */
- + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
- +
- +
- + if (pCtrl->enable) /* enable counter\timer */
- + {
- + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
- + }
- + else /* disable counter\timer */
- + {
- + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
- + }
- +
- + if ( pCtrl->autoEnable ) /* Auto mode */
- + {
- + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(countNum);
- +
- + }
- + else /* no auto mode */
- + {
- + cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(countNum);
- + }
- +
- + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvCntmrCtrlGet -
- +*
- +* DESCRIPTION:
- +* Get the Control value of a given counter/timer
- +*
- +* INPUT:
- +* countNum - counter number
- +* pCtrl - pointer to MV_CNTMR_CTRL structure
- +*
- +* OUTPUT:
- +* Counter\Timer control value
- +*
- +* RETURN:
- +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
- +*******************************************************************************/
- +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
- +{
- + MV_U32 cntmrCtrl;
- +
- + if (countNum >= MV_CNTMR_MAX_COUNTER )
- + {
- + DB(mvOsPrintf(("mvCntmrCtrlGet: Err. Illigal counter number \n")));
- + return MV_BAD_PARAM;;
- + }
- +
- + /* read control register */
- + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
- +
- + /* enable counter\timer */
- + if (cntmrCtrl & CTCR_ARM_TIMER_EN(countNum))
- + {
- + pCtrl->enable = MV_TRUE;
- + }
- + else
- + {
- + pCtrl->enable = MV_FALSE;
- + }
- +
- + /* counter mode */
- + if (cntmrCtrl & CTCR_ARM_TIMER_AUTO_EN(countNum))
- + {
- + pCtrl->autoEnable = MV_TRUE;
- + }
- + else
- + {
- + pCtrl->autoEnable = MV_FALSE;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCntmrEnable -
- +*
- +* DESCRIPTION:
- +* Set the Enable-Bit to logic '1' ==> starting the counter
- +*
- +* INPUT:
- +* countNum - counter number
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
- +*******************************************************************************/
- +MV_STATUS mvCntmrEnable(MV_U32 countNum)
- +{
- + MV_U32 cntmrCtrl;
- +
- + if (countNum >= MV_CNTMR_MAX_COUNTER )
- + {
- +
- + DB(mvOsPrintf(("mvCntmrEnable: Err. Illigal counter number \n")));
- + return MV_BAD_PARAM;;
- +
- + }
- +
- + /* read control register */
- + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
- +
- + /* enable counter\timer */
- + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
- +
- +
- + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCntmrDisable -
- +*
- +* DESCRIPTION:
- +* Stop the counter/timer running, and returns its Value
- +*
- +* INPUT:
- +* countNum - counter number
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_U32 counter\timer value
- +*******************************************************************************/
- +MV_STATUS mvCntmrDisable(MV_U32 countNum)
- +{
- + MV_U32 cntmrCtrl;
- +
- + if (countNum >= MV_CNTMR_MAX_COUNTER )
- + {
- +
- + DB(mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n")));
- + return MV_BAD_PARAM;;
- +
- + }
- +
- + /* read control register */
- + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
- +
- + /* disable counter\timer */
- + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
- +
- + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvCntmrStart -
- +*
- +* DESCRIPTION:
- +* Combined all the sub-operations above to one function: Load,setMode,Enable
- +*
- +* INPUT:
- +* countNum - counter number
- +* value - value of the counter\timer to be set
- +* pCtrl - pointer to MV_CNTMR_CTRL structure
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
- +*******************************************************************************/
- +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
- + MV_CNTMR_CTRL *pCtrl)
- +{
- +
- + if (countNum >= MV_CNTMR_MAX_COUNTER )
- + {
- +
- + mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n"));
- + return MV_BAD_PARAM;;
- +
- + }
- +
- + /* load value onto counter\timer */
- + mvCntmrLoad(countNum,value);
- +
- + /* set the counter to load in the first time */
- + mvCntmrWrite(countNum,value);
- +
- + /* set control for timer \ cunter and enable */
- + mvCntmrCtrlSet(countNum,pCtrl);
- +
- + return MV_OK;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 2010-11-09 20:28:10.381238003 +0100
- @@ -0,0 +1,121 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvTmrWtdgh
- +#define __INCmvTmrWtdgh
- +
- +/* includes */
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "cntmr/mvCntmrRegs.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +
- +
- +/* This enumerator describe counters\watchdog numbers */
- +typedef enum _mvCntmrID
- +{
- + TIMER0 = 0,
- + TIMER1,
- + WATCHDOG,
- + TIMER2,
- + TIMER3,
- +}MV_CNTMR_ID;
- +
- +
- +/* Counter / Timer control structure */
- +typedef struct _mvCntmrCtrl
- +{
- + MV_BOOL enable; /* enable */
- + MV_BOOL autoEnable; /* counter/Timer */
- +}MV_CNTMR_CTRL;
- +
- +
- +/* Functions */
- +
- +/* Load an init Value to a given counter/timer */
- +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value);
- +
- +/* Returns the value of the given Counter/Timer */
- +MV_U32 mvCntmrRead(MV_U32 countNum);
- +
- +/* Write a value of the given Counter/Timer */
- +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal);
- +
- +/* Set the Control to a given counter/timer */
- +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
- +
- +/* Get the value of a given counter/timer */
- +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
- +
- +/* Set the Enable-Bit to logic '1' ==> starting the counter. */
- +MV_STATUS mvCntmrEnable(MV_U32 countNum);
- +
- +/* Stop the counter/timer running, and returns its Value. */
- +MV_STATUS mvCntmrDisable(MV_U32 countNum);
- +
- +/* Combined all the sub-operations above to one function: Load,setMode,Enable */
- +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
- + MV_CNTMR_CTRL *pCtrl);
- +
- +#endif /* __INCmvTmrWtdgh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 2010-11-09 20:28:10.422495568 +0100
- @@ -0,0 +1,121 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvTmrwtdgRegsh
- +#define __INCmvTmrwtdgRegsh
- +
- +/*******************************************/
- +/* ARM Timers Registers Map */
- +/*******************************************/
- +
- +#define CNTMR_RELOAD_REG(tmrNum) (CNTMR_BASE + 0x10 + (tmrNum)*8 + \
- + (((tmrNum) <= 3)?0:8))
- +#define CNTMR_VAL_REG(tmrNum) (CNTMR_BASE + 0x14 + (tmrNum)*8 + \
- + (((tmrNum) <= 3)?0:8))
- +#define CNTMR_CTRL_REG (CNTMR_BASE)
- +
- +/*For MV78XX0*/
- +#define CNTMR_CAUSE_REG (CPU_AHB_MBUS_CAUSE_INT_REG(whoAmI()))
- +#define CNTMR_MASK_REG (CPU_AHB_MBUS_MASK_INT_REG(whoAmI()))
- +
- +/* ARM Timers Registers Map */
- +/*******************************************/
- +
- +
- +/* ARM Timers Control Register */
- +/* CPU_TIMERS_CTRL_REG (CTCR) */
- +
- +#define TIMER0_NUM 0
- +#define TIMER1_NUM 1
- +#define WATCHDOG_NUM 2
- +#define TIMER2_NUM 3
- +#define TIMER3_NUM 4
- +
- +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2)
- +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS)
- +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
- +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
- +
- +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
- +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) BIT1
- +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
- +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
- +
- +
- +/* ARM Timer\Watchdog Reload Register */
- +/* CNTMR_RELOAD_REG (TRR) */
- +
- +#define TRG_ARM_TIMER_REL_OFFS 0
- +#define TRG_ARM_TIMER_REL_MASK 0xffffffff
- +
- +/* ARM Timer\Watchdog Register */
- +/* CNTMR_VAL_REG (TVRG) */
- +
- +#define TVR_ARM_TIMER_OFFS 0
- +#define TVR_ARM_TIMER_MASK 0xffffffff
- +#define TVR_ARM_TIMER_MAX 0xffffffff
- +
- +
- +
- +#endif /* __INCmvTmrwtdgRegsh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 2010-11-09 20:28:10.462495409 +0100
- @@ -0,0 +1,207 @@
- +/*
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- + */
- +
- +#include "mvOs.h"
- +#include "mvCpuCntrs.h"
- +
- +
- +const static MV_CPU_CNTRS_OPS mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =
- +{
- + /*0*/
- + {
- + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_HIT, MV_CPU_CNTRS_DCACHE_READ_MISS,
- + MV_CPU_CNTRS_DCACHE_WRITE_HIT, MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_INSTRUCTIONS,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_MMU_READ_LATENCY, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_LATENCY,
- + MV_CPU_CNTRS_LDM_STM_HOLD, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
- + },
- + /*1*/
- + {
- + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_ICACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_READ_MISS,
- + MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS, MV_CPU_CNTRS_SINGLE_ISSUE,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_RETIRED, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_MMU_READ_BEAT, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_BEAT,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_IS_HOLD, MV_CPU_CNTRS_DATA_READ_ACCESS,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_INVALID,
- + },
- + /*2*/
- + {
- + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_ACCESS,
- + MV_CPU_CNTRS_DTLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_PREDICT_MISS, MV_CPU_CNTRS_WB_WRITE_BEAT,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_LATENCY, MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_INVALID,
- + },
- + /*3*/
- + {
- + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_WRITE_MISS,
- + MV_CPU_CNTRS_TLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_TAKEN, MV_CPU_CNTRS_WB_FULL_CYCLES,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_BEAT, MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_ANY_ACCESS,
- + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DATA_WRITE_ACCESS,
- + MV_CPU_CNTRS_INVALID,
- + }
- +};
- +
- +MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
- +
- +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventTbl[128];
- +
- +void mvCpuCntrsReset(void)
- +{
- + MV_U32 reg = 0;
- +
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));
- + MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));
- +}
- +
- +void program_counter(int counter, int op)
- +{
- + MV_U32 reg = (1 << op) | 0x1; /*enable*/
- +
- + switch(counter)
- + {
- + case 0:
- + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));
- + return;
- +
- + case 1:
- + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));
- + return;
- +
- + case 2:
- + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));
- + return;
- +
- + case 3:
- + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));
- + return;
- +
- + default:
- + mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);
- + }
- + return;
- +}
- +
- +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)
- +{
- + int i;
- +
- + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
- + {
- + pEvent->counters_sum[i] = 0;
- + }
- + pEvent->num_of_measurements = 0;
- +}
- +
- +
- +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)
- +{
- + int i;
- + MV_CPU_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));
- +
- + if(event)
- + {
- + strncpy(event->name, name, sizeof(event->name));
- + event->num_of_measurements = 0;
- + event->avg_sample_count = print_threshold;
- + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
- + {
- + event->counters_before[i] = 0;
- + event->counters_after[i] = 0;
- + event->counters_sum[i] = 0;
- + }
- + }
- + return event;
- +}
- +
- +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)
- +{
- + if(event != NULL)
- + mvOsFree(event);
- +}
- +
- +
- +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
- + char* name, MV_U32 overhead)
- +{
- + int i;
- +
- + /* Find required operations */
- + for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)
- + {
- + if( mvCpuCntrsOpsTbl[counter][i] == op)
- + {
- + strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));
- + mvCpuCntrsTbl[counter].operation = op;
- + mvCpuCntrsTbl[counter].opIdx = i+1;
- + mvCpuCntrsTbl[counter].overhead = overhead;
- + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
- + mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",
- + counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);
- + return MV_OK;
- + }
- + }
- + return MV_NOT_FOUND;
- +}
- +
- +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)
- +{
- + int i;
- + MV_U64 counters_avg;
- +
- + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
- + return;
- +
- + mvOsPrintf("%16s: ", pEvent->name);
- + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
- + {
- + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
- + pEvent->num_of_measurements, NULL);
- + if(counters_avg >= mvCpuCntrsTbl[i].overhead)
- + counters_avg -= mvCpuCntrsTbl[i].overhead;
- + else
- + counters_avg = 0;
- +
- + mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);
- + }
- + mvOsPrintf("\n");
- + mvCpuCntrsEventClear(pEvent);
- + mvCpuCntrsReset();
- +}
- +
- +void mvCpuCntrsStatus(void)
- +{
- + int i;
- +
- + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
- + {
- + mvOsPrintf("#%d: %s, overhead=%d\n",
- + i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);
- + }
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 2010-11-09 20:28:10.492495484 +0100
- @@ -0,0 +1,213 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +*******************************************************************************/
- +#ifndef __mvCpuCntrs_h__
- +#define __mvCpuCntrs_h__
- +
- +#include "mvTypes.h"
- +#include "mvOs.h"
- +
- +
- +#define MV_CPU_CNTRS_NUM 4
- +#define MV_CPU_CNTRS_OPS_NUM 32
- +
- +typedef enum
- +{
- + MV_CPU_CNTRS_INVALID = 0,
- + MV_CPU_CNTRS_CYCLES,
- + MV_CPU_CNTRS_ICACHE_READ_MISS,
- + MV_CPU_CNTRS_DCACHE_ACCESS,
- + MV_CPU_CNTRS_DCACHE_READ_MISS,
- + MV_CPU_CNTRS_DCACHE_READ_HIT,
- + MV_CPU_CNTRS_DCACHE_WRITE_MISS,
- + MV_CPU_CNTRS_DCACHE_WRITE_HIT,
- + MV_CPU_CNTRS_DTLB_MISS,
- + MV_CPU_CNTRS_TLB_MISS,
- + MV_CPU_CNTRS_ITLB_MISS,
- + MV_CPU_CNTRS_INSTRUCTIONS,
- + MV_CPU_CNTRS_SINGLE_ISSUE,
- + MV_CPU_CNTRS_MMU_READ_LATENCY,
- + MV_CPU_CNTRS_MMU_READ_BEAT,
- + MV_CPU_CNTRS_BRANCH_RETIRED,
- + MV_CPU_CNTRS_BRANCH_TAKEN,
- + MV_CPU_CNTRS_BRANCH_PREDICT_MISS,
- + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
- + MV_CPU_CNTRS_WB_FULL_CYCLES,
- + MV_CPU_CNTRS_WB_WRITE_LATENCY,
- + MV_CPU_CNTRS_WB_WRITE_BEAT,
- + MV_CPU_CNTRS_ICACHE_READ_LATENCY,
- + MV_CPU_CNTRS_ICACHE_READ_BEAT,
- + MV_CPU_CNTRS_DCACHE_READ_LATENCY,
- + MV_CPU_CNTRS_DCACHE_READ_BEAT,
- + MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
- + MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
- + MV_CPU_CNTRS_LDM_STM_HOLD,
- + MV_CPU_CNTRS_IS_HOLD,
- + MV_CPU_CNTRS_DATA_WRITE_ACCESS,
- + MV_CPU_CNTRS_DATA_READ_ACCESS,
- + MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
- + MV_CPU_CNTRS_BIU_ANY_ACCESS,
- +
- +} MV_CPU_CNTRS_OPS;
- +
- +typedef struct
- +{
- + char name[16];
- + MV_CPU_CNTRS_OPS operation;
- + int opIdx;
- + MV_U32 overhead;
- +
- +} MV_CPU_CNTRS_ENTRY;
- +
- +
- +typedef struct
- +{
- + char name[16];
- + MV_U32 num_of_measurements;
- + MV_U32 avg_sample_count;
- + MV_U64 counters_before[MV_CPU_CNTRS_NUM];
- + MV_U64 counters_after[MV_CPU_CNTRS_NUM];
- + MV_U64 counters_sum[MV_CPU_CNTRS_NUM];
- +
- +} MV_CPU_CNTRS_EVENT;
- +
- +extern MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
- +
- +
- +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
- + char* name, MV_U32 overhead);
- +void mvCpuCntrsInit(void);
- +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold);
- +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event);
- +void mvCpuCntrsReset(void);
- +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent);
- +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent);
- +
- +/* internal */
- +void program_counter(int counter, int op);
- +
- +static INLINE MV_U64 mvCpuCntrsRead(const int counter)
- +{
- + MV_U32 low = 0, high = 0;
- + MV_U32 ll = 0;
- +
- + switch(counter)
- + {
- + case 0:
- + MV_ASM ("mcr p15, 0, %0, c15, c12, 0" : : "r" (ll));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 0" : "=r" (low));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 1" : "=r" (high));
- + break;
- +
- + case 1:
- + MV_ASM ("mcr p15, 0, %0, c15, c12, 1" : : "r" (ll));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 2" : "=r" (low));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 3" : "=r" (high));
- + break;
- +
- + case 2:
- + MV_ASM ("mcr p15, 0, %0, c15, c12, 2" : : "r" (ll));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 4" : "=r" (low));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 5" : "=r" (high));
- + break;
- +
- + case 3:
- + MV_ASM ("mcr p15, 0, %0, c15, c12, 3" : : "r" (ll));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 6" : "=r" (low));
- + MV_ASM ("mrc p15, 0, %0, c15, c13, 7" : "=r" (high));
- + break;
- +
- + default:
- + mvOsPrintf("mv_cpu_cntrs_read: bad counter number (%d)\n", counter);
- + }
- + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
- + return (((MV_U64)high << 32 ) | low);
- +
- +}
- +
- +
- +static INLINE void mvCpuCntrsReadBefore(MV_CPU_CNTRS_EVENT* pEvent)
- +{
- +#if 0
- + int i;
- +
- + /* order is important - we want to measure the cycle count last here! */
- + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
- + pEvent->counters_before[i] = mvCpuCntrsRead(i);
- +#else
- + pEvent->counters_before[1] = mvCpuCntrsRead(1);
- + pEvent->counters_before[3] = mvCpuCntrsRead(3);
- + pEvent->counters_before[0] = mvCpuCntrsRead(0);
- + pEvent->counters_before[2] = mvCpuCntrsRead(2);
- +#endif
- +}
- +
- +static INLINE void mvCpuCntrsReadAfter(MV_CPU_CNTRS_EVENT* pEvent)
- +{
- + int i;
- +
- +#if 0
- + /* order is important - we want to measure the cycle count first here! */
- + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
- + pEvent->counters_after[i] = mvCpuCntrsRead(i);
- +#else
- + pEvent->counters_after[2] = mvCpuCntrsRead(2);
- + pEvent->counters_after[0] = mvCpuCntrsRead(0);
- + pEvent->counters_after[3] = mvCpuCntrsRead(3);
- + pEvent->counters_after[1] = mvCpuCntrsRead(1);
- +#endif
- +
- + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
- + {
- + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
- + }
- + pEvent->num_of_measurements++;
- +}
- +
- +
- +#ifdef CONFIG_MV_CPU_PERF_CNTRS
- +
- +#define MV_CPU_CNTRS_READ(counter) mvCpuCntrsRead(counter)
- +
- +#define MV_CPU_CNTRS_START(event) mvCpuCntrsReadBefore(event)
- +
- +#define MV_CPU_CNTRS_STOP(event) mvCpuCntrsReadAfter(event)
- +
- +#define MV_CPU_CNTRS_SHOW(event) mvCpuCntrsShow(event)
- +
- +#else
- +
- +#define MV_CPU_CNTRS_READ(counter)
- +#define MV_CPU_CNTRS_START(event)
- +#define MV_CPU_CNTRS_STOP(event)
- +#define MV_CPU_CNTRS_SHOW(event)
- +
- +#endif /* CONFIG_MV_CPU_PERF_CNTRS */
- +
- +
- +#endif /* __mvCpuCntrs_h__ */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 2010-11-09 20:28:10.522495411 +0100
- @@ -0,0 +1,143 @@
- +/*
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- + */
- +
- +#include "mvOs.h"
- +#include "mvCpuL2Cntrs.h"
- +
- +
- +
- +MV_CPU_L2_CNTRS_ENTRY mvCpuL2CntrsTbl[MV_CPU_L2_CNTRS_NUM];
- +
- +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventTbl[128];
- +
- +void mvCpuL2CntrsReset(void)
- +{
- + MV_U32 reg = 0;
- +
- + MV_ASM ("mcr p15, 6, %0, c15, c13, 0" : : "r" (reg));
- + MV_ASM ("mcr p15, 6, %0, c15, c13, 1" : : "r" (reg));
- + MV_ASM ("mcr p15, 6, %0, c15, c13, 2" : : "r" (reg));
- + MV_ASM ("mcr p15, 6, %0, c15, c13, 3" : : "r" (reg));
- +}
- +
- +static void mvCpuL2CntrConfig(int counter, int op)
- +{
- + MV_U32 reg = (1 << op) | 0x1; /*enable*/
- +
- + switch(counter)
- + {
- + case 0:
- + MV_ASM ("mcr p15, 6, %0, c15, c12, 0" : : "r" (reg));
- + return;
- +
- + case 1:
- + MV_ASM ("mcr p15, 6, %0, c15, c12, 1" : : "r" (reg));
- + return;
- +
- + default:
- + mvOsPrintf("mvCpuL2CntrConfig: bad counter number (%d)\n", counter);
- + }
- + return;
- +}
- +
- +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent)
- +{
- + int i;
- +
- + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
- + {
- + pEvent->counters_sum[i] = 0;
- + }
- + pEvent->num_of_measurements = 0;
- +}
- +
- +
- +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold)
- +{
- + int i;
- + MV_CPU_L2_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_L2_CNTRS_EVENT));
- +
- + if(event)
- + {
- + strncpy(event->name, name, sizeof(event->name));
- + event->num_of_measurements = 0;
- + event->avg_sample_count = print_threshold;
- + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
- + {
- + event->counters_before[i] = 0;
- + event->counters_after[i] = 0;
- + event->counters_sum[i] = 0;
- + }
- + }
- + return event;
- +}
- +
- +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event)
- +{
- + if(event != NULL)
- + mvOsFree(event);
- +}
- +
- +
- +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
- + char* name, MV_U32 overhead)
- +{
- + strncpy(mvCpuL2CntrsTbl[counter].name, name, sizeof(mvCpuL2CntrsTbl[counter].name));
- + mvCpuL2CntrsTbl[counter].operation = op;
- + mvCpuL2CntrsTbl[counter].opIdx = op;
- + mvCpuL2CntrsTbl[counter].overhead = overhead;
- + mvCpuL2CntrConfig(counter, op);
- + mvOsPrintf("CPU L2 Counter %d: operation=%d, overhead=%d\n",
- + counter, op, overhead);
- + return MV_OK;
- +}
- +
- +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent)
- +{
- + int i;
- + MV_U64 counters_avg;
- +
- + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
- + return;
- +
- + mvOsPrintf("%16s: ", pEvent->name);
- + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
- + {
- + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
- + pEvent->num_of_measurements, NULL);
- +
- + if(counters_avg >= mvCpuL2CntrsTbl[i].overhead)
- + counters_avg -= mvCpuL2CntrsTbl[i].overhead;
- + else
- + counters_avg = 0;
- +
- + mvOsPrintf("%s=%5llu, ", mvCpuL2CntrsTbl[i].name, counters_avg);
- + }
- + mvOsPrintf("\n");
- + mvCpuL2CntrsEventClear(pEvent);
- + mvCpuL2CntrsReset();
- +}
- +
- +void mvCpuL2CntrsStatus(void)
- +{
- + int i;
- +
- + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
- + {
- + mvOsPrintf("#%d: %s, overhead=%d\n",
- + i, mvCpuL2CntrsTbl[i].name, mvCpuL2CntrsTbl[i].overhead);
- + }
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 2010-11-09 20:28:10.562495466 +0100
- @@ -0,0 +1,151 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +*******************************************************************************/
- +#ifndef __mvCpuL2Cntrs_h__
- +#define __mvCpuL2Cntrs_h__
- +
- +#include "mvTypes.h"
- +#include "mvOs.h"
- +
- +
- +#define MV_CPU_L2_CNTRS_NUM 2
- +
- +typedef enum
- +{
- + MV_CPU_L2_CNTRS_ENABLE = 0,
- + MV_CPU_L2_CNTRS_DATA_REQ,
- + MV_CPU_L2_CNTRS_DATA_MISS_REQ,
- + MV_CPU_L2_CNTRS_INST_REQ,
- + MV_CPU_L2_CNTRS_INST_MISS_REQ,
- + MV_CPU_L2_CNTRS_DATA_READ_REQ,
- + MV_CPU_L2_CNTRS_DATA_READ_MISS_REQ,
- + MV_CPU_L2_CNTRS_DATA_WRITE_REQ,
- + MV_CPU_L2_CNTRS_DATA_WRITE_MISS_REQ,
- + MV_CPU_L2_CNTRS_RESERVED,
- + MV_CPU_L2_CNTRS_DIRTY_EVICT_REQ,
- + MV_CPU_L2_CNTRS_EVICT_BUFF_STALL,
- + MV_CPU_L2_CNTRS_ACTIVE_CYCLES,
- +
- +} MV_CPU_L2_CNTRS_OPS;
- +
- +typedef struct
- +{
- + char name[16];
- + MV_CPU_L2_CNTRS_OPS operation;
- + int opIdx;
- + MV_U32 overhead;
- +
- +} MV_CPU_L2_CNTRS_ENTRY;
- +
- +
- +typedef struct
- +{
- + char name[16];
- + MV_U32 num_of_measurements;
- + MV_U32 avg_sample_count;
- + MV_U64 counters_before[MV_CPU_L2_CNTRS_NUM];
- + MV_U64 counters_after[MV_CPU_L2_CNTRS_NUM];
- + MV_U64 counters_sum[MV_CPU_L2_CNTRS_NUM];
- +
- +} MV_CPU_L2_CNTRS_EVENT;
- +
- +
- +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
- + char* name, MV_U32 overhead);
- +void mvCpuL2CntrsInit(void);
- +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold);
- +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event);
- +void mvCpuL2CntrsReset(void);
- +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent);
- +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent);
- +
- +static INLINE MV_U64 mvCpuL2CntrsRead(const int counter)
- +{
- + MV_U32 low = 0, high = 0;
- +
- + switch(counter)
- + {
- + case 0:
- + MV_ASM ("mrc p15, 6, %0, c15, c13, 0" : "=r" (low));
- + MV_ASM ("mrc p15, 6, %0, c15, c13, 1" : "=r" (high));
- + break;
- +
- + case 1:
- + MV_ASM ("mrc p15, 6, %0, c15, c13, 2" : "=r" (low));
- + MV_ASM ("mrc p15, 6, %0, c15, c13, 3" : "=r" (high));
- + break;
- +
- + default:
- + mvOsPrintf("mvCpuL2CntrsRead: bad counter number (%d)\n", counter);
- + }
- + return (((MV_U64)high << 32 ) | low);
- +
- +}
- +
- +static INLINE void mvCpuL2CntrsReadBefore(MV_CPU_L2_CNTRS_EVENT* pEvent)
- +{
- + int i;
- +
- + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
- + pEvent->counters_before[i] = mvCpuL2CntrsRead(i);
- +}
- +
- +static INLINE void mvCpuL2CntrsReadAfter(MV_CPU_L2_CNTRS_EVENT* pEvent)
- +{
- + int i;
- +
- + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
- + {
- + pEvent->counters_after[i] = mvCpuL2CntrsRead(i);
- + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
- + }
- + pEvent->num_of_measurements++;
- +}
- +
- +
- +#ifdef CONFIG_MV_CPU_L2_PERF_CNTRS
- +
- +#define MV_CPU_L2_CNTRS_READ(counter) mvCpuL2CntrsRead(counter)
- +
- +#define MV_CPU_L2_CNTRS_START(event) mvCpuL2CntrsReadBefore(event)
- +
- +#define MV_CPU_L2_CNTRS_STOP(event) mvCpuL2CntrsReadAfter(event)
- +
- +#define MV_CPU_L2_CNTRS_SHOW(event) mvCpuL2CntrsShow(event)
- +
- +#else
- +
- +#define MV_CPU_L2_CNTRS_READ(counter)
- +#define MV_CPU_L2_CNTRS_START(event)
- +#define MV_CPU_L2_CNTRS_STOP(event)
- +#define MV_CPU_L2_CNTRS_SHOW(event)
- +
- +#endif /* CONFIG_MV_CPU_L2_PERF_CNTRS */
- +
- +
- +#endif /* __mvCpuL2Cntrs_h__ */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 2010-11-09 20:28:10.592495381 +0100
- @@ -0,0 +1,1479 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "ddr1_2/mvDram.h"
- +#include "boardEnv/mvBoardEnvLib.h"
- +
- +#undef MV_DEBUG
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
- + MV_DRAM_BANK_INFO *pBankInfo);
- +static MV_U32 cas2ps(MV_U8 spd_byte);
- +/*******************************************************************************
- +* mvDramBankGet - Get the DRAM bank paramters.
- +*
- +* DESCRIPTION:
- +* This function retrieves DRAM bank parameters as described in
- +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
- +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
- +* from it. Otherwise, if the DRAM is soldered on board, the function
- +* should insert its bank information into MV_DRAM_BANK_INFO struct.
- +*
- +* INPUT:
- +* bankNum - Board DRAM bank number.
- +*
- +* OUTPUT:
- +* pBankInfo - DRAM bank information struct.
- +*
- +* RETURN:
- +* MV_FAIL - Bank parameters could not be read.
- +*
- +*******************************************************************************/
- +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + MV_DIMM_INFO dimmInfo;
- +
- + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
- + /* zero pBankInfo structure */
- + memset(pBankInfo, 0, sizeof(*pBankInfo));
- +
- + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
- + {
- + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
- + return MV_BAD_PARAM;
- + }
- + if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
- + {
- + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
- + return MV_FAIL;
- + }
- + if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
- + {
- + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
- + return MV_FAIL;
- + }
- +
- + /* convert Dimm info to Bank info */
- + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
- +*
- +* DESCRIPTION:
- +* Convert a Dimm info struct into a bank info struct.
- +*
- +* INPUT:
- +* pDimmInfo - DIMM information structure.
- +*
- +* OUTPUT:
- +* pBankInfo - DRAM bank information struct.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
- + MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + pBankInfo->memoryType = pDimmInfo->memoryType;
- +
- + /* DIMM dimensions */
- + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
- + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
- + pBankInfo->dataWidth = pDimmInfo->dataWidth;
- + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
- + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
- + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
- + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
- + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
- + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
- +
- + /* DIMM timing parameters */
- + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
- + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
- + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
- +
- + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
- + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
- + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
- + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
- + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
- + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
- + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
- + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
- +
- + /* Parameters calculated from the extracted DIMM information */
- + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
- + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
- + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
- + pDimmInfo->numOfModuleBanks;
- +
- + /* DIMM attributes (MV_TRUE for yes) */
- +
- + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
- + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
- + {
- + if (pDimmInfo->dimmAttributes & BIT1)
- + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
- + else
- + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
- + }
- + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
- + {
- + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
- + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
- + else
- + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
- + }
- +
- + return;
- +}
- +
- +/*******************************************************************************
- +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
- +*
- +* DESCRIPTION:
- +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS dimmSpdCpy(MV_VOID)
- +{
- + MV_U32 i;
- + MV_U32 spdChecksum;
- +
- + MV_TWSI_SLAVE twsiSlave;
- + MV_U8 data[SPD_SIZE];
- +
- + /* zero dimmInfo structure */
- + memset(data, 0, SPD_SIZE);
- +
- + /* read the dimm eeprom */
- + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
- + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + twsiSlave.offset = 0;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
- + &twsiSlave, data, SPD_SIZE) )
- + {
- + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
- + return MV_FAIL;
- + }
- + DB(puts("DRAM: Reading dimm info succeded.\n"));
- +
- + /* calculate SPD checksum */
- + spdChecksum = 0;
- +
- + for(i = 0 ; i <= 62 ; i++)
- + {
- + spdChecksum += data[i];
- + }
- +
- + if ((spdChecksum & 0xff) != data[63])
- + {
- + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
- + (MV_U32)(spdChecksum & 0xff), data[63]));
- + }
- + else
- + {
- + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
- + }
- +
- + /* copy the SPD content 1:1 into the DIMM 1 SPD */
- + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + twsiSlave.offset = 0;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + for(i = 0 ; i < SPD_SIZE ; i++)
- + {
- + twsiSlave.offset = i;
- + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,
- + &twsiSlave, &data[i], 1) )
- + {
- + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
- + return MV_FAIL;
- + }
- + mvOsDelay(5);
- + }
- +
- + DB(puts("DRAM: Reading dimm info succeded.\n"));
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* dimmSpdGet - Get the SPD parameters.
- +*
- +* DESCRIPTION:
- +* Read the DIMM SPD parameters into given struct parameter.
- +*
- +* INPUT:
- +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
- +*
- +* OUTPUT:
- +* pDimmInfo - DIMM information structure.
- +*
- +* RETURN:
- +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
- +{
- + MV_U32 i;
- + MV_U32 density = 1;
- + MV_U32 spdChecksum;
- +
- + MV_TWSI_SLAVE twsiSlave;
- + MV_U8 data[SPD_SIZE];
- +
- + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
- + {
- + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
- + return MV_BAD_PARAM;
- + }
- +
- + /* zero dimmInfo structure */
- + memset(data, 0, SPD_SIZE);
- +
- + /* read the dimm eeprom */
- + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
- + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
- + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + twsiSlave.offset = 0;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
- + &twsiSlave, data, SPD_SIZE) )
- + {
- + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
- + return MV_FAIL;
- + }
- + DB(puts("DRAM: Reading dimm info succeded.\n"));
- +
- + /* calculate SPD checksum */
- + spdChecksum = 0;
- +
- + for(i = 0 ; i <= 62 ; i++)
- + {
- + spdChecksum += data[i];
- + }
- +
- + if ((spdChecksum & 0xff) != data[63])
- + {
- + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
- + (MV_U32)(spdChecksum & 0xff), data[63]));
- + }
- + else
- + {
- + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
- + }
- +
- + /* copy the SPD content 1:1 into the dimmInfo structure*/
- + for(i = 0 ; i < SPD_SIZE ; i++)
- + {
- + pDimmInfo->spdRawData[i] = data[i];
- + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
- + }
- +
- + DB(mvOsPrintf("DRAM SPD Information:\n"));
- +
- + /* Memory type (DDR / SDRAM) */
- + switch (data[DIMM_MEM_TYPE])
- + {
- + case (DIMM_MEM_TYPE_SDRAM):
- + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
- + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
- + break;
- + case (DIMM_MEM_TYPE_DDR1):
- + pDimmInfo->memoryType = MEM_TYPE_DDR1;
- + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
- + break;
- + case (DIMM_MEM_TYPE_DDR2):
- + pDimmInfo->memoryType = MEM_TYPE_DDR2;
- + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
- + break;
- + default:
- + mvOsPrintf("ERROR: Undefined memory type!\n");
- + return MV_ERROR;
- + }
- +
- +
- + /* Number Of Row Addresses */
- + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
- + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
- +
- + /* Number Of Column Addresses */
- + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
- + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
- +
- + /* Number Of Module Banks */
- + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
- + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
- + pDimmInfo->numOfModuleBanks));
- +
- + /* Number of module banks encoded differently for DDR2 */
- + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
- + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
- +
- + /* Data Width */
- + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
- + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
- +
- + /* Minimum Cycle Time At Max CasLatancy */
- + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
- +
- + /* Error Check Type */
- + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
- + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
- + pDimmInfo->errorCheckType));
- +
- + /* Refresh Interval */
- + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
- + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
- + pDimmInfo->refreshInterval));
- +
- + /* Sdram Width */
- + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
- + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
- +
- + /* Error Check Data Width */
- + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
- + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
- + pDimmInfo->errorCheckDataWidth));
- +
- + /* Burst Length Supported */
- + /* SDRAM/DDR1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
- + *********************************************************/
- + /* DDR2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
- + *********************************************************/
- +
- + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
- + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
- + pDimmInfo->burstLengthSupported));
- +
- + /* Number Of Banks On Each Device */
- + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
- + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
- + pDimmInfo->numOfBanksOnEachDevice));
- +
- + /* Suported Cas Latencies */
- +
- + /* SDRAM:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
- + ********************************************************/
- +
- + /* DDR 1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
- + *********************************************************/
- +
- + /* DDR 2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
- + *********************************************************/
- +
- + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
- + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
- + pDimmInfo->suportedCasLatencies));
- +
- + /* For DDR2 only, get the DIMM type information */
- + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
- + {
- + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
- + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
- + pDimmInfo->dimmTypeInfo));
- + }
- +
- + /* SDRAM Modules Attributes */
- + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
- + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
- + pDimmInfo->dimmAttributes));
- +
- + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
- + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
- +
- + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
- + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
- +
- + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
- + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
- + pDimmInfo->minRowPrechargeTime));
- + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
- + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
- + pDimmInfo->minRowActiveToRowActive));
- + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
- + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
- + pDimmInfo->minRasToCasDelay));
- + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
- + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
- + pDimmInfo->minRasPulseWidth));
- +
- + /* DIMM Bank Density */
- + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
- + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
- + pDimmInfo->dimmBankDensity));
- +
- + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
- + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
- + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
- + pDimmInfo->minWriteRecoveryTime));
- +
- + /* Only DDR2 includes Internal Write To Read Command Delay field. */
- + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
- + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
- + pDimmInfo->minWriteToReadCmdDelay));
- +
- + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
- + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
- + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
- + pDimmInfo->minReadToPrechCmdDelay));
- +
- + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
- + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
- + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
- + pDimmInfo->minRefreshToActiveCmd));
- +
- + /* calculating the sdram density. Representing device density from */
- + /* bit 20 to allow representation of 4GB and above. */
- + /* For example, if density is 512Mbit 0x20000000, will be represent in */
- + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
- + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
- + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
- + pDimmInfo->deviceDensity = density *
- + pDimmInfo->numOfBanksOnEachDevice *
- + pDimmInfo->sdramWidth;
- + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
- +
- + /* Number of devices includeing Error correction */
- + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
- + pDimmInfo->numOfModuleBanks;
- + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
- + pDimmInfo->numberOfDevices));
- +
- + pDimmInfo->size = 0;
- +
- + /* Note that pDimmInfo->size is in MB units */
- + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
- + {
- + if (pDimmInfo->dimmBankDensity & BIT0)
- + pDimmInfo->size += 1024; /* Equal to 1GB */
- + else if (pDimmInfo->dimmBankDensity & BIT1)
- + pDimmInfo->size += 8; /* Equal to 8MB */
- + else if (pDimmInfo->dimmBankDensity & BIT2)
- + pDimmInfo->size += 16; /* Equal to 16MB */
- + else if (pDimmInfo->dimmBankDensity & BIT3)
- + pDimmInfo->size += 32; /* Equal to 32MB */
- + else if (pDimmInfo->dimmBankDensity & BIT4)
- + pDimmInfo->size += 64; /* Equal to 64MB */
- + else if (pDimmInfo->dimmBankDensity & BIT5)
- + pDimmInfo->size += 128; /* Equal to 128MB */
- + else if (pDimmInfo->dimmBankDensity & BIT6)
- + pDimmInfo->size += 256; /* Equal to 256MB */
- + else if (pDimmInfo->dimmBankDensity & BIT7)
- + pDimmInfo->size += 512; /* Equal to 512MB */
- + }
- + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
- + {
- + if (pDimmInfo->dimmBankDensity & BIT0)
- + pDimmInfo->size += 1024; /* Equal to 1GB */
- + else if (pDimmInfo->dimmBankDensity & BIT1)
- + pDimmInfo->size += 2048; /* Equal to 2GB */
- + else if (pDimmInfo->dimmBankDensity & BIT2)
- + pDimmInfo->size += 16; /* Equal to 16MB */
- + else if (pDimmInfo->dimmBankDensity & BIT3)
- + pDimmInfo->size += 32; /* Equal to 32MB */
- + else if (pDimmInfo->dimmBankDensity & BIT4)
- + pDimmInfo->size += 64; /* Equal to 64MB */
- + else if (pDimmInfo->dimmBankDensity & BIT5)
- + pDimmInfo->size += 128; /* Equal to 128MB */
- + else if (pDimmInfo->dimmBankDensity & BIT6)
- + pDimmInfo->size += 256; /* Equal to 256MB */
- + else if (pDimmInfo->dimmBankDensity & BIT7)
- + pDimmInfo->size += 512; /* Equal to 512MB */
- + }
- + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
- + {
- + if (pDimmInfo->dimmBankDensity & BIT0)
- + pDimmInfo->size += 1024; /* Equal to 1GB */
- + else if (pDimmInfo->dimmBankDensity & BIT1)
- + pDimmInfo->size += 2048; /* Equal to 2GB */
- + else if (pDimmInfo->dimmBankDensity & BIT2)
- + pDimmInfo->size += 4096; /* Equal to 4GB */
- + else if (pDimmInfo->dimmBankDensity & BIT3)
- + pDimmInfo->size += 8192; /* Equal to 8GB */
- + else if (pDimmInfo->dimmBankDensity & BIT4)
- + pDimmInfo->size += 16384; /* Equal to 16GB */
- + else if (pDimmInfo->dimmBankDensity & BIT5)
- + pDimmInfo->size += 128; /* Equal to 128MB */
- + else if (pDimmInfo->dimmBankDensity & BIT6)
- + pDimmInfo->size += 256; /* Equal to 256MB */
- + else if (pDimmInfo->dimmBankDensity & BIT7)
- + pDimmInfo->size += 512; /* Equal to 512MB */
- + }
- +
- + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
- +
- + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* dimmSpdPrint - Print the SPD parameters.
- +*
- +* DESCRIPTION:
- +* Print the Dimm SPD parameters.
- +*
- +* INPUT:
- +* pDimmInfo - DIMM information structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
- +{
- + MV_DIMM_INFO dimmInfo;
- + MV_U32 i, temp = 0;
- + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
- + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
- + MV_U32 busClkPs;
- + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
- + temp_buf[40], *spdRawData;
- +
- + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
- +
- + spdRawData = dimmInfo.spdRawData;
- +
- + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
- + {
- + mvOsOutput("ERROR: Could not read SPD information!\n");
- + return;
- + }
- +
- + /* find Manufactura of Dimm Module */
- + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
- + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
- + {
- + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
- + }
- + mvOsOutput("\n");
- +
- + /* Manufacturer's Specific Data */
- + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
- + {
- + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
- + }
- + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
- +
- + /* Module Part Number */
- + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
- + {
- + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
- + }
- + mvOsOutput("Module Part Number: %s\n", temp_buf);
- +
- + /* Module Serial Number */
- + for(i = 0; i < sizeof(MV_U32); i++)
- + {
- + temp |= spdRawData[95+i] << 8*i;
- + }
- + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
- + (long)temp);
- +
- + /* find Manufac-Data of Dimm Module */
- + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
- + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
- + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
- + /* find modul_revision of Dimm Module */
- + mvOsOutput("Module Revision: %d.%d\n",
- + spdRawData[91], spdRawData[92]);
- +
- + /* find manufac_place of Dimm Module */
- + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
- +
- + /* go over the first 35 I2C data bytes */
- + for(i = 2 ; i <= 35 ; i++)
- + switch(i)
- + {
- + case 2: /* Memory type (DDR1/2 / SDRAM) */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + mvOsOutput("Dram Type is: SDRAM\n");
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + mvOsOutput("Dram Type is: SDRAM DDR1\n");
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + mvOsOutput("Dram Type is: SDRAM DDR2\n");
- + else
- + mvOsOutput("Dram Type unknown\n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 3: /* Number Of Row Addresses */
- + mvOsOutput("Module Number of row addresses: %d\n",
- + dimmInfo.numOfRowAddr);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 4: /* Number Of Column Addresses */
- + mvOsOutput("Module Number of col addresses: %d\n",
- + dimmInfo.numOfColAddr);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 5: /* Number Of Module Banks */
- + mvOsOutput("Number of Banks on Mod.: %d\n",
- + dimmInfo.numOfModuleBanks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 6: /* Data Width */
- + mvOsOutput("Module Data Width: %d bit\n",
- + dimmInfo.dataWidth);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 8: /* Voltage Interface */
- + switch(spdRawData[i])
- + {
- + case 0x0:
- + mvOsOutput("Module is TTL_5V_TOLERANT\n");
- + break;
- + case 0x1:
- + mvOsOutput("Module is LVTTL\n");
- + break;
- + case 0x2:
- + mvOsOutput("Module is HSTL_1_5V\n");
- + break;
- + case 0x3:
- + mvOsOutput("Module is SSTL_3_3V\n");
- + break;
- + case 0x4:
- + mvOsOutput("Module is SSTL_2_5V\n");
- + break;
- + case 0x5:
- + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
- + {
- + mvOsOutput("Module is SSTL_1_8V\n");
- + break;
- + }
- + default:
- + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
- + break;
- + }
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 9: /* Minimum Cycle Time At Max CasLatancy */
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
- +
- + /* DDR2 addition of right of point */
- + if ((spdRawData[i] & 0x0f) == 0xA)
- + {
- + rightOfPoint = 25;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xB)
- + {
- + rightOfPoint = 33;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xC)
- + {
- + rightOfPoint = 66;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xD)
- + {
- + rightOfPoint = 75;
- + }
- + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 10: /* Clock To Data Out */
- + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / div;
- + rightOfPoint = time_tmp % div;
- + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 11: /* Error Check Type */
- + mvOsOutput("Error Check Type (0=NONE): %d\n",
- + dimmInfo.errorCheckType);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 12: /* Refresh Interval */
- + mvOsOutput("Refresh Rate: %x\n",
- + dimmInfo.refreshInterval);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 13: /* Sdram Width */
- + mvOsOutput("Sdram Width: %d bits\n",
- + dimmInfo.sdramWidth);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 14: /* Error Check Data Width */
- + mvOsOutput("Error Check Data Width: %d bits\n",
- + dimmInfo.errorCheckDataWidth);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 15: /* Minimum Clock Delay is unsupported */
- + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
- + (dimmInfo.memoryType == MEM_TYPE_DDR1))
- + {
- + mvOsOutput("Minimum Clk Delay back to back: %d\n",
- + spdRawData[i]);
- + }
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 16: /* Burst Length Supported */
- + /* SDRAM/DDR1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
- + *********************************************************/
- + /* DDR2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
- + *********************************************************/
- + mvOsOutput("Burst Length Supported: ");
- + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
- + (dimmInfo.memoryType == MEM_TYPE_DDR1))
- + {
- + if (dimmInfo.burstLengthSupported & BIT0)
- + mvOsOutput("1, ");
- + if (dimmInfo.burstLengthSupported & BIT1)
- + mvOsOutput("2, ");
- + }
- + if (dimmInfo.burstLengthSupported & BIT2)
- + mvOsOutput("4, ");
- + if (dimmInfo.burstLengthSupported & BIT3)
- + mvOsOutput("8, ");
- +
- + mvOsOutput(" Bit \n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 17: /* Number Of Banks On Each Device */
- + mvOsOutput("Number Of Banks On Each Chip: %d\n",
- + dimmInfo.numOfBanksOnEachDevice);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 18: /* Suported Cas Latencies */
- +
- + /* SDRAM:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
- + ********************************************************/
- +
- + /* DDR 1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
- + *********************************************************/
- +
- + /* DDR 2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
- + *********************************************************/
- +
- + mvOsOutput("Suported Cas Latencies: (CL) ");
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + for (k = 0; k <=7; k++)
- + {
- + if (dimmInfo.suportedCasLatencies & (1 << k))
- + mvOsOutput("%d, ", k+1);
- + }
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if (dimmInfo.suportedCasLatencies & BIT0)
- + mvOsOutput("1, ");
- + if (dimmInfo.suportedCasLatencies & BIT1)
- + mvOsOutput("1.5, ");
- + if (dimmInfo.suportedCasLatencies & BIT2)
- + mvOsOutput("2, ");
- + if (dimmInfo.suportedCasLatencies & BIT3)
- + mvOsOutput("2.5, ");
- + if (dimmInfo.suportedCasLatencies & BIT4)
- + mvOsOutput("3, ");
- + if (dimmInfo.suportedCasLatencies & BIT5)
- + mvOsOutput("3.5, ");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + {
- + if (dimmInfo.suportedCasLatencies & BIT2)
- + mvOsOutput("2, ");
- + if (dimmInfo.suportedCasLatencies & BIT3)
- + mvOsOutput("3, ");
- + if (dimmInfo.suportedCasLatencies & BIT4)
- + mvOsOutput("4, ");
- + if (dimmInfo.suportedCasLatencies & BIT5)
- + mvOsOutput("5, ");
- + }
- + else
- + mvOsOutput("?.?, ");
- + mvOsOutput("\n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 20: /* DDR2 DIMM type info */
- + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + {
- + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
- + mvOsOutput("Registered DIMM (RDIMM)\n");
- + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
- + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
- + else
- + mvOsOutput("Unknown DIMM type.\n");
- + }
- +
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 21: /* SDRAM Modules Attributes */
- + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
- +
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + if (dimmInfo.dimmAttributes & BIT0)
- + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Buffered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT1)
- + mvOsOutput(" Registered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Registered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT2)
- + mvOsOutput(" On-Card PLL (clock): Yes \n");
- + else
- + mvOsOutput(" On-Card PLL (clock): No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT3)
- + mvOsOutput(" Bufferd DQMB Input: Yes \n");
- + else
- + mvOsOutput(" Bufferd DQMB Inputs: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT4)
- + mvOsOutput(" Registered DQMB Inputs: Yes \n");
- + else
- + mvOsOutput(" Registered DQMB Inputs: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT5)
- + mvOsOutput(" Differential Clock Input: Yes \n");
- + else
- + mvOsOutput(" Differential Clock Input: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT6)
- + mvOsOutput(" redundant Row Addressing: Yes \n");
- + else
- + mvOsOutput(" redundant Row Addressing: No \n");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if (dimmInfo.dimmAttributes & BIT0)
- + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Buffered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT1)
- + mvOsOutput(" Registered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Registered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT2)
- + mvOsOutput(" On-Card PLL (clock): Yes \n");
- + else
- + mvOsOutput(" On-Card PLL (clock): No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT3)
- + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
- + else
- + mvOsOutput(" FET Switch On-Card Enabled: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT4)
- + mvOsOutput(" FET Switch External Enabled: Yes \n");
- + else
- + mvOsOutput(" FET Switch External Enabled: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT5)
- + mvOsOutput(" Differential Clock Input: Yes \n");
- + else
- + mvOsOutput(" Differential Clock Input: No \n");
- + }
- + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
- + {
- + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
- + (dimmInfo.dimmAttributes & 0x3) + 1);
- +
- + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
- + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
- +
- + if (dimmInfo.dimmAttributes & BIT4)
- + mvOsOutput(" FET Switch External Enabled: Yes \n");
- + else
- + mvOsOutput(" FET Switch External Enabled: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT6)
- + mvOsOutput(" Analysis probe installed: Yes \n");
- + else
- + mvOsOutput(" Analysis probe installed: No \n");
- + }
- +
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 22: /* Suported AutoPreCharge */
- + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + if ( spdRawData[i] & BIT0 )
- + mvOsOutput(" Early Ras Precharge: Yes \n");
- + else
- + mvOsOutput(" Early Ras Precharge: No \n");
- +
- + if ( spdRawData[i] & BIT1 )
- + mvOsOutput(" AutoPreCharge: Yes \n");
- + else
- + mvOsOutput(" AutoPreCharge: No \n");
- +
- + if ( spdRawData[i] & BIT2 )
- + mvOsOutput(" Precharge All: Yes \n");
- + else
- + mvOsOutput(" Precharge All: No \n");
- +
- + if ( spdRawData[i] & BIT3 )
- + mvOsOutput(" Write 1/ReadBurst: Yes \n");
- + else
- + mvOsOutput(" Write 1/ReadBurst: No \n");
- +
- + if ( spdRawData[i] & BIT4 )
- + mvOsOutput(" lower VCC tolerance: 5%%\n");
- + else
- + mvOsOutput(" lower VCC tolerance: 10%%\n");
- +
- + if ( spdRawData[i] & BIT5 )
- + mvOsOutput(" upper VCC tolerance: 5%%\n");
- + else
- + mvOsOutput(" upper VCC tolerance: 10%%\n");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if ( spdRawData[i] & BIT0 )
- + mvOsOutput(" Supports Weak Driver: Yes \n");
- + else
- + mvOsOutput(" Supports Weak Driver: No \n");
- +
- + if ( !(spdRawData[i] & BIT4) )
- + mvOsOutput(" lower VCC tolerance: 0.2V\n");
- +
- + if ( !(spdRawData[i] & BIT5) )
- + mvOsOutput(" upper VCC tolerance: 0.2V\n");
- +
- + if ( spdRawData[i] & BIT6 )
- + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
- + else
- + mvOsOutput(" Concurrent Auto Preharge: No \n");
- +
- + if ( spdRawData[i] & BIT7 )
- + mvOsOutput(" Supports Fast AP: Yes \n");
- + else
- + mvOsOutput(" Supports Fast AP: No \n");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + {
- + if ( spdRawData[i] & BIT0 )
- + mvOsOutput(" Supports Weak Driver: Yes \n");
- + else
- + mvOsOutput(" Supports Weak Driver: No \n");
- + }
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 23:
- + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
- +
- + /* DDR2 addition of right of point */
- + if ((spdRawData[i] & 0x0f) == 0xA)
- + {
- + rightOfPoint = 25;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xB)
- + {
- + rightOfPoint = 33;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xC)
- + {
- + rightOfPoint = 66;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xD)
- + {
- + rightOfPoint = 75;
- + }
- +
- + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
- + "(0 = Not supported): %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint );
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
- + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / div;
- + rightOfPoint = time_tmp % div;
- + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 25:
- + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
- + rightOfPoint = (spdRawData[i] & 0x3) * 25;
- + }
- + else /* DDR1 or DDR2 */
- + {
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
- +
- + /* DDR2 addition of right of point */
- + if ((spdRawData[i] & 0x0f) == 0xA)
- + {
- + rightOfPoint = 25;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xB)
- + {
- + rightOfPoint = 33;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xC)
- + {
- + rightOfPoint = 66;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xD)
- + {
- + rightOfPoint = 75;
- + }
- + }
- + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
- + "(0 = Not supported): %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint );
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
- + rightOfPoint = (spdRawData[i] & 0x3) * 25;
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = 0;
- + rightOfPoint = time_tmp;
- + }
- + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
- + leftOfPoint, rightOfPoint );
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 27: /* Minimum Row Precharge Time */
- + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
- + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0xff : 0xfc;
- + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0x00 : 0x03;
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
- + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
- + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
- + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
- + "in Clk cycles %d\n",
- + leftOfPoint, rightOfPoint, trp_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 28: /* Minimum Row Active to Row Active Time */
- + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
- + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0xff : 0xfc;
- + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0x00 : 0x03;
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
- + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
- + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
- + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
- + "%d.%d = in Clk cycles %d\n",
- + leftOfPoint, rightOfPoint, trp_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 29: /* Minimum Ras-To-Cas Delay */
- + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
- + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0xff : 0xfc;
- + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0x00 : 0x03;
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
- + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
- + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
- + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
- + "in Clk cycles %d\n",
- + leftOfPoint, rightOfPoint, trp_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 30: /* Minimum Ras Pulse Width */
- + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
- + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
- + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 31: /* Module Bank Density */
- + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
- +
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + if (dimmInfo.dimmBankDensity & BIT0)
- + mvOsOutput("1GB, ");
- + if (dimmInfo.dimmBankDensity & BIT1)
- + mvOsOutput("8MB, ");
- + if (dimmInfo.dimmBankDensity & BIT2)
- + mvOsOutput("16MB, ");
- + if (dimmInfo.dimmBankDensity & BIT3)
- + mvOsOutput("32MB, ");
- + if (dimmInfo.dimmBankDensity & BIT4)
- + mvOsOutput("64MB, ");
- + if (dimmInfo.dimmBankDensity & BIT5)
- + mvOsOutput("128MB, ");
- + if (dimmInfo.dimmBankDensity & BIT6)
- + mvOsOutput("256MB, ");
- + if (dimmInfo.dimmBankDensity & BIT7)
- + mvOsOutput("512MB, ");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if (dimmInfo.dimmBankDensity & BIT0)
- + mvOsOutput("1GB, ");
- + if (dimmInfo.dimmBankDensity & BIT1)
- + mvOsOutput("2GB, ");
- + if (dimmInfo.dimmBankDensity & BIT2)
- + mvOsOutput("16MB, ");
- + if (dimmInfo.dimmBankDensity & BIT3)
- + mvOsOutput("32MB, ");
- + if (dimmInfo.dimmBankDensity & BIT4)
- + mvOsOutput("64MB, ");
- + if (dimmInfo.dimmBankDensity & BIT5)
- + mvOsOutput("128MB, ");
- + if (dimmInfo.dimmBankDensity & BIT6)
- + mvOsOutput("256MB, ");
- + if (dimmInfo.dimmBankDensity & BIT7)
- + mvOsOutput("512MB, ");
- + }
- + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
- + {
- + if (dimmInfo.dimmBankDensity & BIT0)
- + mvOsOutput("1GB, ");
- + if (dimmInfo.dimmBankDensity & BIT1)
- + mvOsOutput("2GB, ");
- + if (dimmInfo.dimmBankDensity & BIT2)
- + mvOsOutput("4GB, ");
- + if (dimmInfo.dimmBankDensity & BIT3)
- + mvOsOutput("8GB, ");
- + if (dimmInfo.dimmBankDensity & BIT4)
- + mvOsOutput("16GB, ");
- + if (dimmInfo.dimmBankDensity & BIT5)
- + mvOsOutput("128MB, ");
- + if (dimmInfo.dimmBankDensity & BIT6)
- + mvOsOutput("256MB, ");
- + if (dimmInfo.dimmBankDensity & BIT7)
- + mvOsOutput("512MB, ");
- + }
- + mvOsOutput("\n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 32: /* Address And Command Setup Time (measured in ns/1000) */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 33: /* Address And Command Hold Time */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 34: /* Data Input Setup Time */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 35: /* Data Input Hold Time */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 36: /* Relevant for DDR2 only: Write Recovery Time */
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
- + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- + }
- +
- +}
- +
- +
- +/*
- + * translate ns.ns/10 coding of SPD timing values
- + * into ps unit values
- + */
- +/*******************************************************************************
- +* cas2ps - Translate x.y ns parameter to pico-seconds values
- +*
- +* DESCRIPTION:
- +* This function translates x.y nano seconds to its value in pico seconds.
- +* For example 3.75ns will return 3750.
- +*
- +* INPUT:
- +* spd_byte - DIMM SPD byte.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* value in pico seconds.
- +*
- +*******************************************************************************/
- +static MV_U32 cas2ps(MV_U8 spd_byte)
- +{
- + MV_U32 ns, ns10;
- +
- + /* isolate upper nibble */
- + ns = (spd_byte >> 4) & 0x0F;
- + /* isolate lower nibble */
- + ns10 = (spd_byte & 0x0F);
- +
- + if( ns10 < 10 ) {
- + ns10 *= 10;
- + }
- + else if( ns10 == 10 )
- + ns10 = 25;
- + else if( ns10 == 11 )
- + ns10 = 33;
- + else if( ns10 == 12 )
- + ns10 = 66;
- + else if( ns10 == 13 )
- + ns10 = 75;
- + else
- + {
- + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
- + }
- +
- + return (ns*1000 + ns10*10);
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 2010-11-09 20:28:10.622495522 +0100
- @@ -0,0 +1,191 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvDram
- +#define __INCmvDram
- +
- +#include "ddr1_2/mvDramIf.h"
- +#include "twsi/mvTwsi.h"
- +
- +#define MAX_DIMM_NUM 2
- +#define SPD_SIZE 128
- +
- +/* Dimm spd offsets */
- +#define DIMM_MEM_TYPE 2
- +#define DIMM_ROW_NUM 3
- +#define DIMM_COL_NUM 4
- +#define DIMM_MODULE_BANK_NUM 5
- +#define DIMM_DATA_WIDTH 6
- +#define DIMM_VOLT_IF 8
- +#define DIMM_MIN_CC_AT_MAX_CAS 9
- +#define DIMM_ERR_CHECK_TYPE 11
- +#define DIMM_REFRESH_INTERVAL 12
- +#define DIMM_SDRAM_WIDTH 13
- +#define DIMM_ERR_CHECK_DATA_WIDTH 14
- +#define DIMM_MIN_CLK_DEL 15
- +#define DIMM_BURST_LEN_SUP 16
- +#define DIMM_DEV_BANK_NUM 17
- +#define DIMM_SUP_CAL 18
- +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
- +#define DIMM_BUF_ADDR_CONT_IN 21
- +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
- +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
- +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
- +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
- +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
- +#define DIMM_MIN_RAS_PULSE_WIDTH 30
- +#define DIMM_BANK_DENSITY 31
- +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
- +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
- +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
- +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
- +
- +/* Dimm Memory Type values */
- +#define DIMM_MEM_TYPE_SDRAM 0x4
- +#define DIMM_MEM_TYPE_DDR1 0x7
- +#define DIMM_MEM_TYPE_DDR2 0x8
- +
- +#define DIMM_MODULE_MANU_OFFS 64
- +#define DIMM_MODULE_MANU_SIZE 8
- +#define DIMM_MODULE_VEN_OFFS 73
- +#define DIMM_MODULE_VEN_SIZE 25
- +#define DIMM_MODULE_ID_OFFS 99
- +#define DIMM_MODULE_ID_SIZE 18
- +
- +/* enumeration for voltage levels. */
- +typedef enum _mvDimmVoltageIf
- +{
- + TTL_5V_TOLERANT,
- + LVTTL,
- + HSTL_1_5V,
- + SSTL_3_3V,
- + SSTL_2_5V,
- + VOLTAGE_UNKNOWN,
- +} MV_DIMM_VOLTAGE_IF;
- +
- +
- +/* enumaration for SDRAM CAS Latencies. */
- +typedef enum _mvDimmSdramCas
- +{
- + SD_CL_1 =1,
- + SD_CL_2,
- + SD_CL_3,
- + SD_CL_4,
- + SD_CL_5,
- + SD_CL_6,
- + SD_CL_7,
- + SD_FAULT
- +}MV_DIMM_SDRAM_CAS;
- +
- +
- +/* DIMM information structure */
- +typedef struct _mvDimmInfo
- +{
- + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
- +
- + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
- +
- + /* DIMM dimensions */
- + MV_U32 numOfRowAddr;
- + MV_U32 numOfColAddr;
- + MV_U32 numOfModuleBanks;
- + MV_U32 dataWidth;
- + MV_U32 errorCheckType; /* ECC , PARITY..*/
- + MV_U32 sdramWidth; /* 4,8,16 or 32 */
- + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
- + MV_U32 burstLengthSupported;
- + MV_U32 numOfBanksOnEachDevice;
- + MV_U32 suportedCasLatencies;
- + MV_U32 refreshInterval;
- + MV_U32 dimmBankDensity;
- + MV_U32 dimmTypeInfo; /* DDR2 only */
- + MV_U32 dimmAttributes;
- +
- + /* DIMM timing parameters */
- + MV_U32 minCycleTimeAtMaxCasLatPs;
- + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
- + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
- + MV_U32 minRowPrechargeTime;
- + MV_U32 minRowActiveToRowActive;
- + MV_U32 minRasToCasDelay;
- + MV_U32 minRasPulseWidth;
- + MV_U32 minWriteRecoveryTime; /* DDR2 only */
- + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
- + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
- + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
- +
- + /* Parameters calculated from the extracted DIMM information */
- + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
- + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
- + MV_U32 numberOfDevices;
- +
- +} MV_DIMM_INFO;
- +
- +
- +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
- +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
- +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
- +MV_STATUS dimmSpdCpy(MV_VOID);
- +
- +#endif /* __INCmvDram */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 2010-11-09 20:28:10.662495471 +0100
- @@ -0,0 +1,1599 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +/* includes */
- +#include "ddr1_2/mvDramIf.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +
- +
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +/* DRAM bank presence encoding */
- +#define BANK_PRESENT_CS0 0x1
- +#define BANK_PRESENT_CS0_CS1 0x3
- +#define BANK_PRESENT_CS0_CS2 0x5
- +#define BANK_PRESENT_CS0_CS1_CS2 0x7
- +#define BANK_PRESENT_CS0_CS2_CS3 0xd
- +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
- +
- +/* locals */
- +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
- +#if defined(MV_INC_BOARD_DDIM)
- +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
- +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
- +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
- +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
- +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
- +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
- +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
- + MV_U32 forcedCl);
- +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
- + MV_U32 minCas, MV_U32 busClk);
- +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
- + MV_U32 busClk);
- +
- +/*******************************************************************************
- +* mvDramIfDetect - Prepare DRAM interface configuration values.
- +*
- +* DESCRIPTION:
- +* This function implements the full DRAM detection and timing
- +* configuration for best system performance.
- +* Since this routine runs from a ROM device (Boot Flash), its stack
- +* resides on RAM, that might be the system DRAM. Changing DRAM
- +* configuration values while keeping vital data in DRAM is risky. That
- +* is why the function does not preform the configuration setting but
- +* prepare those in predefined 32bit registers (in this case IDMA
- +* registers are used) for other routine to perform the settings.
- +* The function will call for board DRAM SPD information for each DRAM
- +* chip select. The function will then analyze those SPD parameters of
- +* all DRAM banks in order to decide on DRAM configuration compatible
- +* for all DRAM banks.
- +* The function will set the CPU DRAM address decode registers.
- +* Note: This routine prepares values that will overide configuration of
- +* mvDramBasicAsmInit().
- +*
- +* INPUT:
- +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
- +{
- + MV_U32 retVal = MV_OK; /* return value */
- + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
- + MV_U32 busClk, size, base = 0, i, temp, deviceW, dimmW;
- + MV_U8 minCas;
- + MV_DRAM_DEC_WIN dramDecWin;
- +
- + dramDecWin.addrWin.baseHigh = 0;
- +
- + busClk = mvBoardSysClkGet();
- +
- + if (0 == busClk)
- + {
- + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
- + return MV_ERROR;
- + }
- +
- + /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
- +#if defined(MV_INCLUDE_SDRAM_CS1)
- + for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)
- + mvCpuIfTargetWinEnable(i, MV_FALSE);
- +#endif
- +
- + /* we will use bank 0 as the representative of the all the DRAM banks, */
- + /* since bank 0 must exist. */
- + for(i = 0; i < MV_DRAM_MAX_CS; i++)
- + {
- + /* if Bank exist */
- + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
- + {
- + /* check it isn't SDRAM */
- + if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
- + {
- + mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
- + return MV_ERROR;
- + }
- + /* All banks must support registry in order to activate it */
- + if(bankInfo[i].registeredAddrAndControlInputs !=
- + bankInfo[0].registeredAddrAndControlInputs)
- + {
- + mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
- + return MV_ERROR;
- + }
- +
- + /* Init the CPU window decode */
- + /* Note that the size in Bank info is in MB units */
- + /* Note that the Dimm width might be different then the device DRAM width */
- + temp = MV_REG_READ(SDRAM_CONFIG_REG);
- +
- + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
- + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
- + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
- +
- + /* We can not change DRAM window settings while excecuting */
- + /* code from it. That is why we skip the DRAM CS[0], saving */
- + /* it to the ROM configuration routine */
- + if(i == SDRAM_CS0)
- + {
- + MV_U32 sizeToReg;
- +
- + /* Translate the given window size to register format */
- + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
- +
- + /* Size parameter validity check. */
- + if (-1 == sizeToReg)
- + {
- + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
- + ,i);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Size is located at upper 16 bits */
- + sizeToReg <<= SCSR_SIZE_OFFS;
- +
- + /* enable it */
- + sizeToReg |= SCSR_WIN_EN;
- +
- + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
- + }
- + else
- + {
- + dramDecWin.addrWin.baseLow = base;
- + dramDecWin.addrWin.size = size;
- + dramDecWin.enable = MV_TRUE;
- +
- + if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
- + {
- + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n",
- + SDRAM_CS0 + i);
- + return MV_ERROR;
- + }
- + }
- +
- + base += size;
- +
- + /* update the suportedCasLatencies mask */
- + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
- +
- + }
- + else
- + {
- + if( i == 0 ) /* bank 0 doesn't exist */
- + {
- + mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
- + return MV_ERROR;
- + }
- + else
- + {
- + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
- + bankInfo[i].size = 0; /* Mark this bank as non exist */
- + }
- + }
- + }
- +
- + /* calculate minimum CAS */
- + minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
- + if (0 == minCas)
- + {
- + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
- + (busClk / 1000000));
- +
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + minCas = DDR2_CL_4; /* Continue with this CAS */
- + mvOsPrintf("Set default CAS latency 4\n");
- + }
- + else
- + {
- + minCas = DDR1_CL_3; /* Continue with this CAS */
- + mvOsPrintf("Set default CAS latency 3\n");
- + }
- + }
- +
- + /* calc SDRAM_CONFIG_REG and save it to temp register */
- + temp = sdramConfigRegCalc(&bankInfo[0], busClk);
- + if(-1 == temp)
- + {
- + mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG1, temp);
- +
- + /* calc SDRAM_MODE_REG and save it to temp register */
- + temp = sdramModeRegCalc(minCas);
- + if(-1 == temp)
- + {
- + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG2, temp);
- +
- + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
- + temp = sdramExtModeRegCalc(&bankInfo[0]);
- + if(-1 == temp)
- + {
- + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG10, temp);
- +
- + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
- + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas);
- + if(-1 == temp)
- + {
- + mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG3, temp);
- +
- + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
- + temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
- + if(-1 == temp)
- + {
- + mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG4, temp);
- +
- + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
- + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
- + if(-1 == temp)
- + {
- + mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG5, temp);
- +
- + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
- + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
- + if(-1 == temp)
- + {
- + mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG6, temp);
- +
- + /* Config DDR2 On Die Termination (ODT) registers */
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + sdramDDr2OdtConfig(bankInfo);
- + }
- +
- + /* Note that DDR SDRAM Address/Control and Data pad calibration */
- + /* settings is done in mvSdramIfConfig.s */
- +
- + return retVal;
- +}
- +
- +/*******************************************************************************
- +* minCasCalc - Calculate the Minimum CAS latency which can be used.
- +*
- +* DESCRIPTION:
- +* Calculate the minimum CAS latency that can be used, base on the DRAM
- +* parameters and the SDRAM bus Clock freq.
- +*
- +* INPUT:
- +* busClk - the DRAM bus Clock.
- +* pBankInfo - bank info parameters.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* The minimum CAS Latency. The function returns 0 if max CAS latency
- +* supported by banks is incompatible with system bus clock frequancy.
- +*
- +*******************************************************************************/
- +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
- + MV_U32 forcedCl)
- +{
- + MV_U32 count = 1, j;
- + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
- + MV_U32 startBit, stopBit;
- +
- + /* DDR 1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
- + *********************************************************/
- +
- + /* DDR 2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
- + *********************************************************/
- +
- +
- + /* If we are asked to use the forced CAL */
- + if (forcedCl)
- + {
- + mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10),
- + (forcedCl % 10));
- +
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + if (forcedCl == 30)
- + pBankInfo->suportedCasLatencies = 0x08;
- + else if (forcedCl == 40)
- + pBankInfo->suportedCasLatencies = 0x10;
- + else
- + {
- + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
- + (forcedCl / 10), (forcedCl % 10));
- + pBankInfo->suportedCasLatencies = 0x10;
- + }
- + }
- + else
- + {
- + if (forcedCl == 15)
- + pBankInfo->suportedCasLatencies = 0x02;
- + else if (forcedCl == 20)
- + pBankInfo->suportedCasLatencies = 0x04;
- + else if (forcedCl == 25)
- + pBankInfo->suportedCasLatencies = 0x08;
- + else if (forcedCl == 30)
- + pBankInfo->suportedCasLatencies = 0x10;
- + else if (forcedCl == 40)
- + pBankInfo->suportedCasLatencies = 0x40;
- + else
- + {
- + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n",
- + (forcedCl / 10), (forcedCl % 10));
- + pBankInfo->suportedCasLatencies = 0x10;
- + }
- + }
- +
- + return pBankInfo->suportedCasLatencies;
- + }
- +
- + /* go over the supported cas mask from Max Cas down and check if the */
- + /* SysClk stands in its time requirments. */
- +
- +
- + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
- + pBankInfo->suportedCasLatencies,busClkPs ));
- + for(j = 7; j > 0; j--)
- + {
- + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
- + {
- + /* Reset the bits for CL incompatible for the sysClk */
- + switch (count)
- + {
- + case 1:
- + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + case 2:
- + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + case 3:
- + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + default:
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + break;
- + }
- + }
- + }
- +
- + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
- + pBankInfo->suportedCasLatencies ));
- +
- + /* SDRAM DDR1 controller supports CL 1.5 to 3.5 */
- + /* SDRAM DDR2 controller supports CL 3 to 5 */
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
- + stopBit = 5; /* DDR2 support CL stops with CL5 (bit 5) */
- + }
- + else
- + {
- + startBit = 1; /* DDR1 support CL start with CL1.5 (bit 3) */
- + stopBit = 4; /* DDR1 support CL stops with CL3 (bit 4) */
- + }
- +
- + for(j = startBit; j <= stopBit ; j++)
- + {
- + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
- + {
- + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
- + return (BIT0 << j);
- + }
- + }
- +
- + return 0;
- +}
- +
- +/*******************************************************************************
- +* sdramConfigRegCalc - Calculate sdram config register
- +*
- +* DESCRIPTION: Calculate sdram config register optimized value based
- +* on the bank info parameters.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram config reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
- +{
- + MV_U32 sdramConfig = 0;
- + MV_U32 refreshPeriod;
- +
- + busClk /= 1000000; /* we work with busClk in MHz */
- +
- + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
- +
- + /* figure out the memory refresh internal */
- + switch (pBankInfo->refreshInterval & 0xf)
- + {
- + case 0x0: /* refresh period is 15.625 usec */
- + refreshPeriod = 15625;
- + break;
- + case 0x1: /* refresh period is 3.9 usec */
- + refreshPeriod = 3900;
- + break;
- + case 0x2: /* refresh period is 7.8 usec */
- + refreshPeriod = 7800;
- + break;
- + case 0x3: /* refresh period is 31.3 usec */
- + refreshPeriod = 31300;
- + break;
- + case 0x4: /* refresh period is 62.5 usec */
- + refreshPeriod = 62500;
- + break;
- + case 0x5: /* refresh period is 125 usec */
- + refreshPeriod = 125000;
- + break;
- + default: /* refresh period undefined */
- + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
- + return -1;
- + }
- +
- + /* Now the refreshPeriod is in register format value */
- + refreshPeriod = (busClk * refreshPeriod) / 1000;
- +
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
- + refreshPeriod));
- +
- + /* make sure the refresh value is only 14 bits */
- + if(refreshPeriod > SDRAM_REFRESH_MAX)
- + {
- + refreshPeriod = SDRAM_REFRESH_MAX;
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
- + refreshPeriod));
- + }
- +
- + /* Clear the refresh field */
- + sdramConfig &= ~SDRAM_REFRESH_MASK;
- +
- + /* Set new value to refresh field */
- + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
- +
- + /* registered DRAM ? */
- + if ( pBankInfo->registeredAddrAndControlInputs )
- + {
- + /* it's registered DRAM, so set the reg. DRAM bit */
- + sdramConfig |= SDRAM_REGISTERED;
- + mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");
- + }
- +
- + /* set DDR SDRAM devices configuration */
- + sdramConfig &= ~SDRAM_DCFG_MASK; /* Clear Dcfg field */
- +
- + switch (pBankInfo->sdramWidth)
- + {
- + case 8: /* memory is x8 */
- + sdramConfig |= SDRAM_DCFG_X8_DEV;
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));
- + break;
- + case 16:
- + sdramConfig |= SDRAM_DCFG_X16_DEV;
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));
- + break;
- + default: /* memory width unsupported */
- + mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");
- + return -1;
- + }
- +
- + /* Set static default settings */
- + sdramConfig |= SDRAM_CONFIG_DV;
- +
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
- + sdramConfig));
- +
- + return sdramConfig;
- +}
- +
- +/*******************************************************************************
- +* sdramModeRegCalc - Calculate sdram mode register
- +*
- +* DESCRIPTION: Calculate sdram mode register optimized value based
- +* on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* minCas - minimum CAS supported.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram mode reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
- +{
- + MV_U32 sdramMode;
- +
- + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
- +
- + /* Clear CAS Latency field */
- + sdramMode &= ~SDRAM_CL_MASK;
- +
- + mvOsPrintf("DRAM CAS Latency ");
- +
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + switch (minCas)
- + {
- + case DDR2_CL_3:
- + sdramMode |= SDRAM_DDR2_CL_3;
- + mvOsPrintf("3.\n");
- + break;
- + case DDR2_CL_4:
- + sdramMode |= SDRAM_DDR2_CL_4;
- + mvOsPrintf("4.\n");
- + break;
- + case DDR2_CL_5:
- + sdramMode |= SDRAM_DDR2_CL_5;
- + mvOsPrintf("5.\n");
- + break;
- + default:
- + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
- + return -1;
- + }
- + sdramMode |= DDR2_MODE_REG_DV;
- + }
- + else /* DDR1 */
- + {
- + switch (minCas)
- + {
- + case DDR1_CL_1_5:
- + sdramMode |= SDRAM_DDR1_CL_1_5;
- + mvOsPrintf("1.5\n");
- + break;
- + case DDR1_CL_2:
- + sdramMode |= SDRAM_DDR1_CL_2;
- + mvOsPrintf("2\n");
- + break;
- + case DDR1_CL_2_5:
- + sdramMode |= SDRAM_DDR1_CL_2_5;
- + mvOsPrintf("2.5\n");
- + break;
- + case DDR1_CL_3:
- + sdramMode |= SDRAM_DDR1_CL_3;
- + mvOsPrintf("3\n");
- + break;
- + case DDR1_CL_4:
- + sdramMode |= SDRAM_DDR1_CL_4;
- + mvOsPrintf("4\n");
- + break;
- + default:
- + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
- + return -1;
- + }
- + sdramMode |= DDR1_MODE_REG_DV;
- + }
- +
- + DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));
- +
- + return sdramMode;
- +}
- +
- +/*******************************************************************************
- +* sdramExtModeRegCalc - Calculate sdram Extended mode register
- +*
- +* DESCRIPTION:
- +* Return sdram Extended mode register value based
- +* on the bank info parameters and bank presence.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram Extended mode reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + MV_U32 populateBanks = 0;
- + int bankNum;
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + /* Represent the populate banks in binary form */
- + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + if (0 != pBankInfo[bankNum].size)
- + {
- + populateBanks |= (1 << bankNum);
- + }
- + }
- +
- + switch(populateBanks)
- + {
- + case(BANK_PRESENT_CS0):
- + return DDR_SDRAM_EXT_MODE_CS0_DV;
- +
- + case(BANK_PRESENT_CS0_CS1):
- + return DDR_SDRAM_EXT_MODE_CS0_DV;
- +
- + case(BANK_PRESENT_CS0_CS2):
- + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
- +
- + case(BANK_PRESENT_CS0_CS1_CS2):
- + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
- +
- + case(BANK_PRESENT_CS0_CS2_CS3):
- + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
- +
- + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
- + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
- +
- + default:
- + mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
- + return -1;
- + }
- + }
- + return 0;
- +}
- +
- +/*******************************************************************************
- +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
- +*
- +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
- +* on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +* minCas - minimum CAS supported.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram dunit control low reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)
- +{
- + MV_U32 dunitCtrlLow;
- +
- + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
- +
- + /* Clear StBurstDel field */
- + dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;
- +
- +#ifdef MV_88W8660
- + /* Clear address/control output timing field */
- + dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;
- +#endif /* MV_88W8660 */
- +
- + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
- +
- + /* For proper sample of read data set the Dunit Control register's */
- + /* stBurstDel bits [27:24] */
- + /********-********-********-********-********-*********
- + * CL=1.5 | CL=2 | CL=2.5 | CL=3 | CL=4 | CL=5 *
- + *********-********-********-********-********-*********
- +Not Reg. * 0011 | 0011 | 0100 | 0100 | 0101 | TBD *
- + *********-********-********-********-********-*********
- +Registered * 0100 | 0100 | 0101 | 0101 | 0110 | TBD *
- + *********-********-********-********-********-*********/
- +
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + switch (minCas)
- + {
- + case DDR2_CL_3:
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
- + else
- + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
- + break;
- + case DDR2_CL_4:
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
- + else
- + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
- + break;
- + default:
- + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
- + minCas);
- + return -1;
- + }
- + }
- + else /* DDR1 */
- + {
- + switch (minCas)
- + {
- + case DDR1_CL_1_5:
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
- + else
- + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
- + break;
- + case DDR1_CL_2:
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
- + else
- + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
- + break;
- + case DDR1_CL_2_5:
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
- + else
- + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
- + break;
- + case DDR1_CL_3:
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
- + else
- + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
- + break;
- + case DDR1_CL_4:
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
- + else
- + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
- + break;
- + default:
- + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
- + minCas);
- + return -1;
- + }
- +
- + }
- + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
- +
- + return dunitCtrlLow;
- +}
- +
- +/*******************************************************************************
- +* sdramAddrCtrlRegCalc - Calculate sdram address control register
- +*
- +* DESCRIPTION: Calculate sdram address control register optimized value based
- +* on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram address control reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + MV_U32 addrCtrl = 0;
- +
- + /* Set Address Control register static configuration bits */
- + addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);
- +
- + /* Set address control default value */
- + addrCtrl |= SDRAM_ADDR_CTRL_DV;
- +
- + /* Clear DSize field */
- + addrCtrl &= ~SDRAM_DSIZE_MASK;
- +
- + /* Note that density is in MB units */
- + switch (pBankInfo->deviceDensity)
- + {
- + case 128: /* 128 Mbit */
- + DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));
- + addrCtrl |= SDRAM_DSIZE_128Mb;
- + break;
- + case 256: /* 256 Mbit */
- + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
- + addrCtrl |= SDRAM_DSIZE_256Mb;
- + break;
- + case 512: /* 512 Mbit */
- + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
- + addrCtrl |= SDRAM_DSIZE_512Mb;
- + break;
- + default:
- + mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
- + pBankInfo->deviceDensity);
- + return -1;
- + }
- +
- + /* SDRAM address control */
- + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
- +
- + return addrCtrl;
- +}
- +
- +/*******************************************************************************
- +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
- +*
- +* DESCRIPTION:
- +* This function calculates sdram timing control low register
- +* optimized value based on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +* busClk - Bus clock
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram timinf control low reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
- + MV_U32 minCas, MV_U32 busClk)
- +{
- + MV_U32 tRp = 0;
- + MV_U32 tRrd = 0;
- + MV_U32 tRcd = 0;
- + MV_U32 tRas = 0;
- + MV_U32 tWr = 0;
- + MV_U32 tWtr = 0;
- + MV_U32 tRtp = 0;
- +
- + MV_U32 bankNum;
- +
- + busClk = busClk / 1000000; /* In MHz */
- +
- + /* Scan all DRAM banks to find maximum timing values */
- + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
- + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
- + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
- + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
- + }
- +
- + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
- + /* by shifting the data two bits right. */
- + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
- + tRrd = tRrd >> 2;
- + tRcd = tRcd >> 2;
- +
- + /* Extract clock cycles from time parameter. We need to round up */
- + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
- + /* Micron work around for 133MHz */
- + if (busClk == 133)
- + tRp += 1;
- + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
- + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
- + /* JEDEC min reqeirments tRrd = 2 */
- + if (tRrd < 2)
- + tRrd = 2;
- + DB(mvOsPrintf("tRrd = %d ", tRrd));
- + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
- + DB(mvOsPrintf("tRcd = %d ", tRcd));
- + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
- + DB(mvOsPrintf("tRas = %d ", tRas));
- +
- + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + /* Scan all DRAM banks to find maximum timing values */
- + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
- + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
- + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
- + }
- +
- + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
- + /* part by shifting the data two bits right. */
- + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
- + tWtr = tWtr >> 2;
- + tRtp = tRtp >> 2;
- +
- + /* Extract clock cycles from time parameter. We need to round up */
- + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
- + DB(mvOsPrintf("tWr = %d ", tWr));
- + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
- + /* JEDEC min reqeirments tWtr = 2 */
- + if (tWtr < 2)
- + tWtr = 2;
- + DB(mvOsPrintf("tWtr = %d ", tWtr));
- + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
- + /* JEDEC min reqeirments tRtp = 2 */
- + if (tRtp < 2)
- + tRtp = 2;
- + DB(mvOsPrintf("tRtp = %d ", tRtp));
- + }
- + else
- + {
- + tWr = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);
- +
- + if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))
- + {
- + tWtr = 2;
- + }
- + else
- + {
- + tWtr = 1;
- + }
- +
- + tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */
- + }
- +
- + DB(mvOsPrintf("tWtr = %d\n", tWtr));
- +
- + /* Note: value of 0 in register means one cycle, 1 means two and so on */
- + return (((tRp - 1) << SDRAM_TRP_OFFS) |
- + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
- + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
- + ((tRas - 1) << SDRAM_TRAS_OFFS) |
- + ((tWr - 1) << SDRAM_TWR_OFFS) |
- + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
- + ((tRtp - 1) << SDRAM_TRTP_OFFS));
- +}
- +
- +/*******************************************************************************
- +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
- +*
- +* DESCRIPTION:
- +* This function calculates sdram timing control high register
- +* optimized value based on the bank info parameters and the bus clock.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +* busClk - Bus clock
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram timinf control high reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
- + MV_U32 busClk)
- +{
- + MV_U32 tRfc;
- + MV_U32 timeNs = 0;
- + int bankNum;
- + MV_U32 sdramTw2wCyc = 0;
- +
- + busClk = busClk / 1000000; /* In MHz */
- +
- + /* tRfc is different for DDR1 and DDR2. */
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
- + {
- + MV_U32 bankNum;
- +
- + /* Scan all DRAM banks to find maximum timing values */
- + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
- + }
- + else
- + {
- + if (pBankInfo[0].deviceDensity == _1G)
- + {
- + timeNs = SDRAM_TRFC_1G;
- + }
- + else
- + {
- + if (200 == busClk)
- + {
- + timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;
- + }
- + else
- + {
- + timeNs = SDRAM_TRFC_64_512M;
- + }
- + }
- + }
- +
- + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
- +
- + DB(mvOsPrintf("Dram Timing High: tRfc = %d\n", tRfc));
- +
- +
- + /* Represent the populate banks in binary form */
- + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + if (0 != pBankInfo[bankNum].size)
- + sdramTw2wCyc++;
- + }
- +
- + /* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */
- + if (sdramTw2wCyc > 1)
- + sdramTw2wCyc = 1;
- + else
- + sdramTw2wCyc = 0;
- +
- + /* Note: value of 0 in register means one cycle, 1 means two and so on */
- + return ((((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS) |
- + ((SDRAM_TR2R_CYC - 1) << SDRAM_TR2R_OFFS) |
- + ((SDRAM_TR2WW2R_CYC - 1) << SDRAM_TR2W_W2R_OFFS) |
- + (((tRfc - 1) >> 4) << SDRAM_TRFC_EXT_OFFS) |
- + (sdramTw2wCyc << SDRAM_TW2W_OFFS));
- +
- +}
- +
- +/*******************************************************************************
- +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
- +*
- +* DESCRIPTION:
- +* This function config DDR2 On Die Termination (ODT) registers.
- +* ODT configuration is done according to DIMM presence:
- +*
- +* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode
- +* CS0 0x84210000 0x00000000 0x0000780F 0x00000440
- +* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440
- +* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
- +* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
- +* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
- +* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
- +*
- +* INPUT:
- +* pBankInfo - bank info parameters.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* None
- +*******************************************************************************/
- +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + MV_U32 populateBanks = 0;
- + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
- + int bankNum;
- +
- + /* Represent the populate banks in binary form */
- + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + if (0 != pBankInfo[bankNum].size)
- + {
- + populateBanks |= (1 << bankNum);
- + }
- + }
- +
- + switch(populateBanks)
- + {
- + case(BANK_PRESENT_CS0):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
- + break;
- + case(BANK_PRESENT_CS0_CS1):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
- + break;
- + case(BANK_PRESENT_CS0_CS2):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
- + break;
- + case(BANK_PRESENT_CS0_CS1_CS2):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
- + break;
- + case(BANK_PRESENT_CS0_CS2_CS3):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
- + break;
- + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
- + break;
- + default:
- + mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");
- + return;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
- + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
- + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
- + return;
- +}
- +#endif /* defined(MV_INC_BOARD_DDIM) */
- +
- +/*******************************************************************************
- +* mvDramIfWinSet - Set DRAM interface address decode window
- +*
- +* DESCRIPTION:
- +* This function sets DRAM interface address decode window.
- +*
- +* INPUT:
- +* target - System target. Use only SDRAM targets.
- +* pAddrDecWin - SDRAM address window structure.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
- +* otherwise.
- +*******************************************************************************/
- +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
- +{
- + MV_U32 baseReg=0,sizeReg=0;
- + MV_U32 baseToReg=0 , sizeToReg=0;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(target))
- + {
- + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the requested window overlaps with current enabled windows */
- + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
- + {
- + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
- + return MV_BAD_PARAM;
- + }
- +
- + /* check if address is aligned to the size */
- + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
- + {
- + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
- + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
- + target,
- + pAddrDecWin->addrWin.baseLow,
- + pAddrDecWin->addrWin.size);
- + return MV_ERROR;
- + }
- +
- + /* read base register*/
- + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
- +
- + /* read size register */
- + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
- +
- + /* BaseLow[31:16] => base register [31:16] */
- + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
- +
- + /* Write to address decode Base Address Register */
- + baseReg &= ~SCBAR_BASE_MASK;
- + baseReg |= baseToReg;
- +
- + /* Translate the given window size to register format */
- + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
- +
- + /* Size parameter validity check. */
- + if (-1 == sizeToReg)
- + {
- + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
- + return MV_BAD_PARAM;
- + }
- +
- + /* set size */
- + sizeReg &= ~SCSR_SIZE_MASK;
- + /* Size is located at upper 16 bits */
- + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
- +
- + /* enable/Disable */
- + if (MV_TRUE == pAddrDecWin->enable)
- + {
- + sizeReg |= SCSR_WIN_EN;
- + }
- + else
- + {
- + sizeReg &= ~SCSR_WIN_EN;
- + }
- +
- + /* 3) Write to address decode Base Address Register */
- + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);
- +
- + /* Write to address decode Size Register */
- + MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
- +
- + return MV_OK;
- +}
- +/*******************************************************************************
- +* mvDramIfWinGet - Get DRAM interface address decode window
- +*
- +* DESCRIPTION:
- +* This function gets DRAM interface address decode window.
- +*
- +* INPUT:
- +* target - System target. Use only SDRAM targets.
- +*
- +* OUTPUT:
- +* pAddrDecWin - SDRAM address window structure.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
- +* otherwise.
- +*******************************************************************************/
- +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
- +{
- + MV_U32 baseReg,sizeReg;
- + MV_U32 sizeRegVal;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(target))
- + {
- + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + /* Read base and size registers */
- + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
- + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
- +
- + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
- +
- + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
- + SCSR_SIZE_ALIGNMENT);
- +
- + /* Check if ctrlRegToSize returned OK */
- + if (-1 == pAddrDecWin->addrWin.size)
- + {
- + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + /* Extract base address */
- + /* Base register [31:16] ==> baseLow[31:16] */
- + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
- +
- + pAddrDecWin->addrWin.baseHigh = 0;
- +
- +
- + if (sizeReg & SCSR_WIN_EN)
- + {
- + pAddrDecWin->enable = MV_TRUE;
- + }
- + else
- + {
- + pAddrDecWin->enable = MV_FALSE;
- + }
- +
- + return MV_OK;
- +}
- +/*******************************************************************************
- +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
- +*
- +* DESCRIPTION:
- +* This function enable/Disable SDRAM address decode window.
- +*
- +* INPUT:
- +* target - System target. Use only SDRAM targets.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
- +{
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(target))
- + {
- + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
- + return MV_ERROR;
- + }
- +
- + if (enable == MV_TRUE)
- + { /* First check for overlap with other enabled windows */
- + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
- + {
- + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
- + target);
- + return MV_ERROR;
- + }
- + /* Check for overlapping */
- + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
- + {
- + /* No Overlap. Enable address decode winNum window */
- + MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
- + }
- + else
- + { /* Overlap detected */
- + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
- + target);
- + return MV_ERROR;
- + }
- + }
- + else
- + { /* Disable address decode winNum window */
- + MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
- +*
- +* DESCRIPTION:
- +* This function scan each SDRAM address decode window to test if it
- +* overlapps the given address windoow
- +*
- +* INPUT:
- +* target - SDRAM target where the function skips checking.
- +* pAddrDecWin - The tested address window for overlapping with
- +* SDRAM windows.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if the given address window overlaps any enabled address
- +* decode map, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
- +{
- + MV_TARGET targetNum;
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
- + {
- + /* don't check our winNum or illegal targets */
- + if (targetNum == target)
- + {
- + continue;
- + }
- +
- + /* Get window parameters */
- + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
- + {
- + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
- + return MV_ERROR;
- + }
- +
- + /* Do not check disabled windows */
- + if (MV_FALSE == addrDecWin.enable)
- + {
- + continue;
- + }
- +
- + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
- + {
- + mvOsPrintf(
- + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
- + target, targetNum);
- + return MV_TRUE;
- + }
- + }
- +
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* mvDramIfBankSizeGet - Get DRAM interface bank size.
- +*
- +* DESCRIPTION:
- +* This function returns the size of a given DRAM bank.
- +*
- +* INPUT:
- +* bankNum - Bank number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* DRAM bank size. If bank is disabled the function return '0'. In case
- +* or paramter is invalid, the function returns -1.
- +*
- +*******************************************************************************/
- +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)
- +{
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(bankNum))
- + {
- + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
- + return -1;
- + }
- + /* Get window parameters */
- + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
- + {
- + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
- + return -1;
- + }
- +
- + if (MV_TRUE == addrDecWin.enable)
- + {
- + return addrDecWin.addrWin.size;
- + }
- + else
- + {
- + return 0;
- + }
- +}
- +
- +
- +/*******************************************************************************
- +* mvDramIfSizeGet - Get DRAM interface total size.
- +*
- +* DESCRIPTION:
- +* This function get the DRAM total size.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* DRAM total size. In case or paramter is invalid, the function
- +* returns -1.
- +*
- +*******************************************************************************/
- +MV_32 mvDramIfSizeGet(MV_VOID)
- +{
- + MV_U32 totalSize = 0, bankSize = 0, bankNum;
- +
- + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + bankSize = mvDramIfBankSizeGet(bankNum);
- +
- + if (-1 == bankSize)
- + {
- + mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);
- + return -1;
- + }
- + else
- + {
- + totalSize += bankSize;
- + }
- + }
- +
- + DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));
- +
- + return totalSize;
- +}
- +
- +/*******************************************************************************
- +* mvDramIfBankBaseGet - Get DRAM interface bank base.
- +*
- +* DESCRIPTION:
- +* This function returns the 32 bit base address of a given DRAM bank.
- +*
- +* INPUT:
- +* bankNum - Bank number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* DRAM bank size. If bank is disabled or paramter is invalid, the
- +* function returns -1.
- +*
- +*******************************************************************************/
- +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)
- +{
- + MV_DRAM_DEC_WIN addrDecWin;
- +
- + /* Check parameters */
- + if (!MV_TARGET_IS_DRAM(bankNum))
- + {
- + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
- + return -1;
- + }
- + /* Get window parameters */
- + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
- + {
- + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
- + return -1;
- + }
- +
- + if (MV_TRUE == addrDecWin.enable)
- + {
- + return addrDecWin.addrWin.baseLow;
- + }
- + else
- + {
- + return -1;
- + }
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 2010-11-09 20:28:10.692495407 +0100
- @@ -0,0 +1,192 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvDramIfConfigh
- +#define __INCmvDramIfConfigh
- +
- +/* includes */
- +
- +/* defines */
- +
- +/* registers defaults values */
- +
- +#define SDRAM_CONFIG_DV \
- + (SDRAM_PERR_WRITE | \
- + SDRAM_SRMODE | \
- + SDRAM_SRCLK_GATED)
- +
- +#define SDRAM_DUNIT_CTRL_LOW_DV \
- + (SDRAM_CTRL_POS_RISE | \
- + SDRAM_CLK1DRV_NORMAL | \
- + SDRAM_LOCKEN_ENABLE)
- +
- +#define SDRAM_ADDR_CTRL_DV 0
- +
- +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
- + ((0x2 << SDRAM_TRCD_OFFS) | \
- + (0x2 << SDRAM_TRP_OFFS) | \
- + (0x1 << SDRAM_TWR_OFFS) | \
- + (0x0 << SDRAM_TWTR_OFFS) | \
- + (0x5 << SDRAM_TRAS_OFFS) | \
- + (0x1 << SDRAM_TRRD_OFFS))
- +/* TRFC 0x27, TW2W 0x1 */
- +#define SDRAM_TIMING_CTRL_HIGH_REG_DV (( 0x7 << SDRAM_TRFC_OFFS ) |\
- + ( 0x2 << SDRAM_TRFC_EXT_OFFS) |\
- + ( 0x1 << SDRAM_TW2W_OFFS))
- +
- +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
- +
- +/* DDR2 ODT default register values */
- +
- +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
- +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
- +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
- +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +
- +#define DDR2_ODT_CTRL_LOW_CS0_DV 0x84210000
- +#define DDR2_ODT_CTRL_HIGH_CS0_DV 0x00000000
- +#define DDR2_DUNIT_ODT_CTRL_CS0_DV 0x0000780F
- +#define DDR_SDRAM_EXT_MODE_CS0_DV 0x00000440
- +
- +#define DDR2_ODT_CTRL_LOW_CS0_CS2_DV 0x030C030C
- +#define DDR2_ODT_CTRL_HIGH_CS0_CS2_DV 0x00000000
- +#define DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV 0x0000740F
- +#define DDR_SDRAM_EXT_MODE_CS0_CS2_DV 0x00000404
- +
- +
- +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
- +#define DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
- + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
- + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +
- +
- +#define DDR1_DATA_PAD_STRENGTH_TYPICAL_DV \
- + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
- + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +
- +/* DDR SDRAM Mode Register default value */
- +#define DDR1_MODE_REG_DV 0x00000000
- +#define DDR2_MODE_REG_DV 0x00000400
- +
- +/* DDR SDRAM Timing parameter default values */
- +#define DDR1_TIMING_LOW_DV 0x11602220
- +#define DDR1_TIMING_HIGH_DV 0x0000000d
- +
- +#define DDR2_TIMING_LOW_DV 0x11812220
- +#define DDR2_TIMING_HIGH_DV 0x0000030f
- +
- +/* For Guideline (GL# MEM-4) DQS Reference Delay Tuning */
- +#define FTDLL_DDR1_166MHZ ((0x1 << 0) | \
- + (0x7F<< 12) | \
- + (0x1 << 22))
- +
- +#define FTDLL_DDR1_133MHZ FTDLL_DDR1_166MHZ
- +
- +#define FTDLL_DDR1_200MHZ ((0x1 << 0) | \
- + (0x1 << 12) | \
- + (0x3 << 14) | \
- + (0x1 << 18) | \
- + (0x1 << 22))
- +
- +
- +#define FTDLL_DDR2_166MHZ ((0x1 << 0) | \
- + (0x1 << 12) | \
- + (0x1 << 14) | \
- + (0x1 << 16) | \
- + (0x1 << 19) | \
- + (0xF << 20))
- +
- +#define FTDLL_DDR2_133MHZ FTDLL_DDR2_166MHZ
- +
- +#define FTDLL_DDR2_200MHZ ((0x1 << 0) | \
- + (0x1 << 12) | \
- + (0x1 << 14) | \
- + (0x1 << 16) | \
- + (0x1 << 19) | \
- + (0xF << 20))
- +
- +#define FTDLL_DDR2_250MHZ 0x445001
- +
- +/* Orion 1 B1 and above */
- +#define FTDLL_DDR1_166MHZ_5181_B1 0x45D001
- +
- +/* Orion nas */
- +#define FTDLL_DDR2_166MHZ_5182 0x597001
- +
- +/* Orion 2 D0 and above */
- +#define FTDLL_DDR1_166MHZ_5281_D0 0x8D0001
- +#define FTDLL_DDR1_200MHZ_5281_D0 0x8D0001
- +#define FTDLL_DDR2_166MHZ_5281_D0 0x485001
- +#define FTDLL_DDR2_200MHZ_5281_D0 0x485001
- +#define FTDLL_DDR2_250MHZ_5281_D0 0x445001
- +#define FTDLL_DDR2_200MHZ_5281_D1 0x995001
- +#define FTDLL_DDR2_250MHZ_5281_D1 0x984801
- +
- +#endif /* __INCmvDramIfh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 2010-11-09 20:28:10.747105889 +0100
- @@ -0,0 +1,179 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvDramIfh
- +#define __INCmvDramIfh
- +
- +/* includes */
- +#include "ddr1_2/mvDramIfRegs.h"
- +#include "ddr1_2/mvDramIfConfig.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +/* defines */
- +/* DRAM Timing parameters */
- +#define SDRAM_TWR 15 /* ns tWr */
- +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
- +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
- +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
- +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
- +#define SDRAM_TR2WW2R_CYC 1 /* cycle for tR2wW2r */
- +
- +/* typedefs */
- +
- +/* enumeration for memory types */
- +typedef enum _mvMemoryType
- +{
- + MEM_TYPE_SDRAM,
- + MEM_TYPE_DDR1,
- + MEM_TYPE_DDR2
- +}MV_MEMORY_TYPE;
- +
- +/* enumeration for DDR1 supported CAS Latencies */
- +typedef enum _mvDimmDdr1Cas
- +{
- + DDR1_CL_1_5 = 0x02,
- + DDR1_CL_2 = 0x04,
- + DDR1_CL_2_5 = 0x08,
- + DDR1_CL_3 = 0x10,
- + DDR1_CL_4 = 0x40,
- + DDR1_CL_FAULT
- +} MV_DIMM_DDR1_CAS;
- +
- +/* enumeration for DDR2 supported CAS Latencies */
- +typedef enum _mvDimmDdr2Cas
- +{
- + DDR2_CL_3 = 0x08,
- + DDR2_CL_4 = 0x10,
- + DDR2_CL_5 = 0x20,
- + DDR2_CL_FAULT
- +} MV_DIMM_DDR2_CAS;
- +
- +
- +typedef struct _mvDramBankInfo
- +{
- + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
- +
- + /* DIMM dimensions */
- + MV_U32 numOfRowAddr;
- + MV_U32 numOfColAddr;
- + MV_U32 dataWidth;
- + MV_U32 errorCheckType; /* ECC , PARITY..*/
- + MV_U32 sdramWidth; /* 4,8,16 or 32 */
- + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
- + MV_U32 burstLengthSupported;
- + MV_U32 numOfBanksOnEachDevice;
- + MV_U32 suportedCasLatencies;
- + MV_U32 refreshInterval;
- +
- + /* DIMM timing parameters */
- + MV_U32 minCycleTimeAtMaxCasLatPs;
- + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
- + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
- + MV_U32 minRowPrechargeTime;
- + MV_U32 minRowActiveToRowActive;
- + MV_U32 minRasToCasDelay;
- + MV_U32 minRasPulseWidth;
- + MV_U32 minWriteRecoveryTime; /* DDR2 only */
- + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
- + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
- + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
- +
- + /* Parameters calculated from the extracted DIMM information */
- + MV_U32 size;
- + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
- + MV_U32 numberOfDevices;
- +
- + /* DIMM attributes (MV_TRUE for yes) */
- + MV_BOOL registeredAddrAndControlInputs;
- +
- +}MV_DRAM_BANK_INFO;
- +
- +/* This structure describes CPU interface address decode window */
- +typedef struct _mvDramIfDecWin
- +{
- + MV_ADDR_WIN addrWin; /* An address window*/
- + MV_BOOL enable; /* Address decode window is enabled/disabled */
- +}MV_DRAM_DEC_WIN;
- +
- +#include "ddr1_2/mvDram.h"
- +
- +/* mvDramIf.h API list */
- +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
- +MV_STATUS mvDramIfDetect(MV_U32 forcedCl);
- +MV_VOID _mvDramIfConfig(MV_VOID);
- +
- +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
- +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable);
- +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum);
- +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum);
- +MV_32 mvDramIfSizeGet(MV_VOID);
- +
- +#if 0
- +MV_STATUS mvDramIfMbusCtrlSet(MV_XBAR_TARGET *pPizzaArbArray);
- +MV_STATUS mvDramIfMbusToutSet(MV_U32 timeout, MV_BOOL enable);
- +#endif
- +
- +#endif /* __INCmvDramIfh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 2010-11-09 20:28:10.772495655 +0100
- @@ -0,0 +1,306 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvDramIfRegsh
- +#define __INCmvDramIfRegsh
- +
- +
- +/* DDR SDRAM Controller Address Decode Registers */
- +/* SDRAM CSn Base Address Register (SCBAR) */
- +#define SDRAM_BASE_ADDR_REG(csNum) (0x1500 + (csNum * 8))
- +#define SCBAR_BASE_OFFS 16
- +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
- +#define SCBAR_BASE_ALIGNMENT 0x10000
- +
- +/* SDRAM CSn Size Register (SCSR) */
- +#define SDRAM_SIZE_REG(csNum) (0x1504 + (csNum * 8))
- +#define SCSR_WIN_EN BIT0
- +#define SCSR_SIZE_OFFS 16
- +#define SCSR_SIZE_MASK (0xffff << SCSR_SIZE_OFFS)
- +#define SCSR_SIZE_ALIGNMENT 0x10000
- +
- +/* configuration register */
- +#define SDRAM_CONFIG_REG 0x1400
- +#define SDRAM_REFRESH_OFFS 0
- +#define SDRAM_REFRESH_MAX 0x3000
- +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
- +#define SDRAM_DWIDTH_OFFS 14
- +#define SDRAM_DWIDTH_MASK (3 << SDRAM_DWIDTH_OFFS)
- +#define SDRAM_DWIDTH_16BIT (1 << SDRAM_DWIDTH_OFFS)
- +#define SDRAM_DWIDTH_32BIT (2 << SDRAM_DWIDTH_OFFS)
- +#define SDRAM_DTYPE_OFFS 16
- +#define SDRAM_DTYPE_MASK (1 << SDRAM_DTYPE_OFFS)
- +#define SDRAM_DTYPE_DDR1 (0 << SDRAM_DTYPE_OFFS)
- +#define SDRAM_DTYPE_DDR2 (1 << SDRAM_DTYPE_OFFS)
- +#define SDRAM_REGISTERED (1 << 17)
- +#define SDRAM_PERR_OFFS 18
- +#define SDRAM_PERR_MASK (1 << SDRAM_PERR_OFFS)
- +#define SDRAM_PERR_NO_WRITE (0 << SDRAM_PERR_OFFS)
- +#define SDRAM_PERR_WRITE (1 << SDRAM_PERR_OFFS)
- +#define SDRAM_DCFG_OFFS 20
- +#define SDRAM_DCFG_MASK (0x3 << SDRAM_DCFG_OFFS)
- +#define SDRAM_DCFG_X16_DEV (1 << SDRAM_DCFG_OFFS)
- +#define SDRAM_DCFG_X8_DEV (2 << SDRAM_DCFG_OFFS)
- +#define SDRAM_SRMODE (1 << 24)
- +#define SDRAM_SRCLK_OFFS 25
- +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
- +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
- +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
- +#define SDRAM_CATTH_OFFS 26
- +#define SDRAM_CATTHR_EN (1 << SDRAM_CATTH_OFFS)
- +
- +
- +/* dunit control register */
- +#define SDRAM_DUNIT_CTRL_REG 0x1404
- +#define SDRAM_CTRL_POS_OFFS 6
- +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
- +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
- +#define SDRAM_CLK1DRV_OFFS 12
- +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
- +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
- +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
- +#define SDRAM_LOCKEN_OFFS 18
- +#define SDRAM_LOCKEN_MASK (1 << SDRAM_LOCKEN_OFFS)
- +#define SDRAM_LOCKEN_DISABLE (0 << SDRAM_LOCKEN_OFFS)
- +#define SDRAM_LOCKEN_ENABLE (1 << SDRAM_LOCKEN_OFFS)
- +#define SDRAM_ST_BURST_DEL_OFFS 24
- +#define SDRAM_ST_BURST_DEL_MAX 0xf
- +#define SDRAM_ST_BURST_DEL_MASK (SDRAM_ST_BURST_DEL_MAX<<SDRAM_ST_BURST_DEL_OFFS)
- +
- +/* sdram timing control low register */
- +#define SDRAM_TIMING_CTRL_LOW_REG 0x1408
- +#define SDRAM_TRCD_OFFS 4
- +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
- +#define SDRAM_TRP_OFFS 8
- +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
- +#define SDRAM_TWR_OFFS 12
- +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
- +#define SDRAM_TWTR_OFFS 16
- +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
- +#define SDRAM_TRAS_OFFS 20
- +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
- +#define SDRAM_TRRD_OFFS 24
- +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
- +#define SDRAM_TRTP_OFFS 28
- +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
- +
- +/* sdram timing control high register */
- +#define SDRAM_TIMING_CTRL_HIGH_REG 0x140c
- +#define SDRAM_TRFC_OFFS 0
- +#define SDRAM_TRFC_MASK (0xF << SDRAM_TRFC_OFFS)
- +#define SDRAM_TR2R_OFFS 4
- +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
- +#define SDRAM_TR2W_W2R_OFFS 6
- +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
- +#define SDRAM_TRFC_EXT_OFFS 8
- +#define SDRAM_TRFC_EXT_MASK (0x1 << SDRAM_TRFC_EXT_OFFS)
- +#define SDRAM_TW2W_OFFS 10
- +#define SDRAM_TW2W_MASK (0x1 << SDRAM_TW2W_OFFS)
- +
- +/* address control register */
- +#define SDRAM_ADDR_CTRL_REG 0x1410
- +#define SDRAM_DSIZE_OFFS 4
- +#define SDRAM_DSIZE_MASK (0x3 << SDRAM_DSIZE_OFFS)
- +#define SDRAM_DSIZE_128Mb (0x0 << SDRAM_DSIZE_OFFS)
- +#define SDRAM_DSIZE_256Mb (0x1 << SDRAM_DSIZE_OFFS)
- +#define SDRAM_DSIZE_512Mb (0x2 << SDRAM_DSIZE_OFFS)
- +
- +/* SDRAM Open Pages Control registers */
- +#define SDRAM_OPEN_PAGE_CTRL_REG 0x1414
- +#define SDRAM_OPEN_PAGE_EN (0 << 0)
- +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
- +
- +/* sdram opertion register */
- +#define SDRAM_OPERATION_REG 0x1418
- +#define SDRAM_CMD_OFFS 0
- +#define SDRAM_CMD_MASK (0x7 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
- +
- +/* sdram mode register */
- +#define SDRAM_MODE_REG 0x141c
- +#define SDRAM_BURST_LEN_OFFS 0
- +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
- +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
- +#define SDRAM_CL_OFFS 4
- +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR1_CL_2 (0x2 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR1_CL_3 (0x3 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR1_CL_4 (0x4 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR1_CL_1_5 (0x5 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR1_CL_2_5 (0x6 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
- +#define SDRAM_TM_OFFS 7
- +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
- +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
- +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
- +#define SDRAM_DLL_OFFS 8
- +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
- +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
- +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
- +#define SDRAM_WR_OFFS 11
- +#define SDRAM_WR_MAX 7
- +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
- +#define SDRAM_PD_OFFS 12
- +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
- +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
- +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
- +
- +/* DDR SDRAM Extended Mode register (DSEMR) */
- +#define SDRAM_EXTENDED_MODE_REG 0x1420
- +#define DSEMR_DLL_ENABLE (1 << 0)
- +#define DSEMR_DS_OFFS 1
- +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
- +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
- +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
- +#define DSEMR_RTT0_OFFS 2
- +#define DSEMR_RTT1_OFFS 6
- +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
- +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
- +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
- +#define DSEMR_OCD_OFFS 7
- +#define DSEMR_OCD_MASK (0x7 << DSEMR_OCD_OFFS)
- +#define DSEMR_OCD_EXIT_CALIB (0 << DSEMR_OCD_OFFS)
- +#define DSEMR_OCD_DRIVE1 (1 << DSEMR_OCD_OFFS)
- +#define DSEMR_OCD_DRIVE0 (2 << DSEMR_OCD_OFFS)
- +#define DSEMR_OCD_ADJUST_MODE (4 << DSEMR_OCD_OFFS)
- +#define DSEMR_OCD_CALIB_DEFAULT (7 << DSEMR_OCD_OFFS)
- +#define DSEMR_DQS_OFFS 10
- +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
- +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
- +#define DSEMR_DQS_SINGLE_ENDED (0 << DSEMR_DQS_OFFS)
- +#define DSEMR_RDQS_ENABLE (1 << 11)
- +#define DSEMR_QOFF_OUTPUT_BUFF_EN (1 << 12)
- +
- +/* DDR SDRAM Operation Control Register */
- +#define SDRAM_OPERATION_CTRL_REG 0x142c
- +
- +/* Dunit FTDLL Configuration Register */
- +#define SDRAM_FTDLL_CONFIG_REG 0x1484
- +
- +/* Pads Calibration register */
- +#define SDRAM_ADDR_CTRL_PADS_CAL_REG 0x14c0
- +#define SDRAM_DATA_PADS_CAL_REG 0x14c4
- +#define SDRAM_DRVN_OFFS 0
- +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
- +#define SDRAM_DRVP_OFFS 6
- +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
- +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
- +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +#define SDRAM_TUNE_EN BIT16
- +#define SDRAM_LOCK_OFFS 17
- +#define SDRAM_LOCK_MAKS (0x1F << SDRAM_LOCK_OFFS)
- +#define SDRAM_LOCKN_OFFS 17
- +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
- +#define SDRAM_LOCKP_OFFS 23
- +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
- +#define SDRAM_WR_EN (1 << 31)
- +
- +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
- +#define DDR2_SDRAM_ODT_CTRL_LOW_REG 0x1494
- +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
- +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
- +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
- +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
- +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
- +#define DSOCLR_ODT_WD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
- +
- +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
- +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG 0x1498
- +/* Optional control values to DSOCHR_ODT_EN macro */
- +#define DDR2_ODT_CTRL_DUNIT 0
- +#define DDR2_ODT_CTRL_NEVER 1
- +#define DDR2_ODT_CTRL_ALWAYS 3
- +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
- +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
- +#define DSOCHR_ODT_EN(odtNum, ctrl) ((1 << ctrl) << DSOCHR_ODT_RD_OFFS(odtNum))
- +
- +/* DDR2 Dunit ODT Control Register (DDOCR)*/
- +#define DDR2_DUNIT_ODT_CONTROL_REG 0x149c
- +#define DDOCR_ODT_RD_OFFS 0
- +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
- +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
- +#define DDOCR_ODT_WR_OFFS 4
- +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
- +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
- +#define DSOCR_ODT_EN_OFFS 8
- +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
- +#define DSOCR_ODT_EN(ctrl) ((1 << ctrl) << DSOCR_ODT_EN_OFFS)
- +#define DSOCR_ODT_SEL_OFFS 10
- +#define DSOCR_ODT_SEL_MASK (0x3 << DSOCR_ODT_SEL_OFFS)
- +
- +/* DDR SDRAM Initialization Control Register (DSICR) */
- +#define DDR_SDRAM_INIT_CTRL_REG 0x1480
- +#define DSICR_INIT_EN (1 << 0)
- +
- +#endif /* __INCmvDramIfRegsh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 2010-11-09 20:28:10.812495401 +0100
- @@ -0,0 +1,1855 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +/* includes */
- +#include "ddr2/mvDramIf.h"
- +#include "ctrlEnv/sys/mvCpuIf.h"
- +
- +#include "ddr2/mvDramIfStaticInit.h"
- +
- +/* #define MV_DEBUG */
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +/* DRAM bank presence encoding */
- +#define BANK_PRESENT_CS0 0x1
- +#define BANK_PRESENT_CS0_CS1 0x3
- +#define BANK_PRESENT_CS0_CS2 0x5
- +#define BANK_PRESENT_CS0_CS1_CS2 0x7
- +#define BANK_PRESENT_CS0_CS2_CS3 0xd
- +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
- +
- +/* locals */
- +#ifndef MV_STATIC_DRAM_ON_BOARD
- +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
- +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTmode );
- +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
- +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
- +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
- +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);
- +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);
- +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);
- +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);
- +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
- +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);
- +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);
- +#endif
- +MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A
- +
- +#ifdef MV_INCLUDE_SDRAM_CS1
- + ,N_A
- +#endif
- +#ifdef MV_INCLUDE_SDRAM_CS2
- + ,N_A
- +#endif
- +#ifdef MV_INCLUDE_SDRAM_CS3
- + ,N_A
- +#endif
- + };
- +/* Get DRAM size of CS num */
- +MV_U32 mvDramCsSizeGet(MV_U32 csNum)
- +{
- + MV_DRAM_BANK_INFO bankInfo;
- + MV_U32 size, deviceW, dimmW;
- +#ifdef MV78XX0
- + MV_U32 temp;
- +#endif
- +
- + if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))
- + {
- + if (0 == bankInfo.size)
- + return 0;
- +
- + /* Note that the Dimm width might be different then the device DRAM width */
- +#ifdef MV78XX0
- + temp = MV_REG_READ(SDRAM_CONFIG_REG);
- + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
- +#else
- + deviceW = 16 /* KW family */;
- +#endif
- + dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);
- + size = ((bankInfo.size << 20) / (dimmW/deviceW));
- + return size;
- + }
- + else
- + return 0;
- +}
- +/*******************************************************************************
- +* mvDramIfDetect - Prepare DRAM interface configuration values.
- +*
- +* DESCRIPTION:
- +* This function implements the full DRAM detection and timing
- +* configuration for best system performance.
- +* Since this routine runs from a ROM device (Boot Flash), its stack
- +* resides on RAM, that might be the system DRAM. Changing DRAM
- +* configuration values while keeping vital data in DRAM is risky. That
- +* is why the function does not preform the configuration setting but
- +* prepare those in predefined 32bit registers (in this case IDMA
- +* registers are used) for other routine to perform the settings.
- +* The function will call for board DRAM SPD information for each DRAM
- +* chip select. The function will then analyze those SPD parameters of
- +* all DRAM banks in order to decide on DRAM configuration compatible
- +* for all DRAM banks.
- +* The function will set the CPU DRAM address decode registers.
- +* Note: This routine prepares values that will overide configuration of
- +* mvDramBasicAsmInit().
- +*
- +* INPUT:
- +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
- +* eccDisable - Force down the ECC.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)
- +{
- + MV_32 MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {
- + SDRAM_CS0
- +#ifdef MV_INCLUDE_SDRAM_CS1
- + ,SDRAM_CS1
- +#endif
- +#ifdef MV_INCLUDE_SDRAM_CS2
- + ,SDRAM_CS2
- +#endif
- +#ifdef MV_INCLUDE_SDRAM_CS3
- + ,SDRAM_CS3
- +#endif
- + };
- + MV_U32 busClk, deviceW, dimmW;
- + MV_U32 numOfAllDevices = 0;
- + MV_STATUS TTMode;
- +#ifndef MV_STATIC_DRAM_ON_BOARD
- + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
- + MV_U32 size, base = 0, i, j, temp, busClkPs;
- + MV_U8 minCas;
- + MV_CPU_DEC_WIN dramDecWin;
- + dramDecWin.addrWin.baseHigh = 0;
- +#endif
- +
- + busClk = mvBoardSysClkGet();
- +
- + if (0 == busClk)
- + {
- + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
- + return MV_ERROR;
- + }
- +
- +#ifndef MV_STATIC_DRAM_ON_BOARD
- +
- + busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
- + /* we will use bank 0 as the representative of the all the DRAM banks, */
- + /* since bank 0 must exist. */
- + for(i = 0; i < MV_DRAM_MAX_CS; i++)
- + {
- + /* if Bank exist */
- + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
- + {
- + DB(mvOsPrintf("Dram: Find bank %d\n", i));
- + /* check it isn't SDRAM */
- + if(bankInfo[i].memoryType != MEM_TYPE_DDR2)
- + {
- + mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");
- + return MV_ERROR;
- + }
- +
- + /* All banks must support the Mclk freqency */
- + if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)
- + {
- + mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);
- + return MV_ERROR;
- + }
- +
- + /* All banks must support registry in order to activate it */
- + if(bankInfo[i].registeredAddrAndControlInputs !=
- + bankInfo[0].registeredAddrAndControlInputs)
- + {
- + mvOsOutput("Dram: ERR. different Registered settings !!!\n");
- + return MV_ERROR;
- + }
- +
- + /* All banks must support same ECC mode */
- + if(bankInfo[i].errorCheckType !=
- + bankInfo[0].errorCheckType)
- + {
- + mvOsOutput("Dram: ERR. different ECC settings !!!\n");
- + return MV_ERROR;
- + }
- +
- + }
- + else
- + {
- + if( i == 0 ) /* bank 0 doesn't exist */
- + {
- + mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");
- + return MV_ERROR;
- + }
- + else
- + {
- + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
- + bankInfo[i].size = 0; /* Mark this bank as non exist */
- + }
- + }
- + }
- +
- +#ifdef MV_INCLUDE_SDRAM_CS2
- + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
- + {
- + MV_DRAM_CS_order[0] = SDRAM_CS2;
- + MV_DRAM_CS_order[1] = SDRAM_CS3;
- + MV_DRAM_CS_order[2] = SDRAM_CS0;
- + MV_DRAM_CS_order[3] = SDRAM_CS1;
- + DRAM_CS_Order[0] = SDRAM_CS2;
- + DRAM_CS_Order[1] = SDRAM_CS3;
- + DRAM_CS_Order[2] = SDRAM_CS0;
- + DRAM_CS_Order[3] = SDRAM_CS1;
- +
- + }
- + else
- +#endif
- + {
- + MV_DRAM_CS_order[0] = SDRAM_CS0;
- + MV_DRAM_CS_order[1] = SDRAM_CS1;
- + DRAM_CS_Order[0] = SDRAM_CS0;
- + DRAM_CS_Order[1] = SDRAM_CS1;
- +#ifdef MV_INCLUDE_SDRAM_CS2
- + MV_DRAM_CS_order[2] = SDRAM_CS2;
- + MV_DRAM_CS_order[3] = SDRAM_CS3;
- + DRAM_CS_Order[2] = SDRAM_CS2;
- + DRAM_CS_Order[3] = SDRAM_CS3;
- +#endif
- + }
- +
- + for(j = 0; j < MV_DRAM_MAX_CS; j++)
- + {
- + i = MV_DRAM_CS_order[j];
- +
- + if (0 == bankInfo[i].size)
- + continue;
- +
- + /* Init the CPU window decode */
- + /* Note that the Dimm width might be different then the device DRAM width */
- +#ifdef MV78XX0
- + temp = MV_REG_READ(SDRAM_CONFIG_REG);
- + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
- +#else
- + deviceW = 16 /* KW family */;
- +#endif
- + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
- + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
- +
- + /* We can not change DRAM window settings while excecuting */
- + /* code from it. That is why we skip the DRAM CS[0], saving */
- + /* it to the ROM configuration routine */
- +
- + numOfAllDevices += bankInfo[i].numberOfDevices;
- + if (i == MV_DRAM_CS_order[0])
- + {
- + MV_U32 sizeToReg;
- + /* Translate the given window size to register format */
- + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
- + /* Size parameter validity check. */
- + if (-1 == sizeToReg)
- + {
- + mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
- + ,i);
- + return MV_BAD_PARAM;
- + }
- +
- + DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)
- + sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);
- + sizeToReg |= SCSR_WIN_EN;
- + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
- + }
- + else
- + {
- + dramDecWin.addrWin.baseLow = base;
- + dramDecWin.addrWin.size = size;
- + dramDecWin.enable = MV_TRUE;
- + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
- +
- + /* Check if the DRAM size is more then 3GByte */
- + if (base < 0xC0000000)
- + {
- + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
- + if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))
- + {
- + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);
- + return MV_ERROR;
- + }
- + }
- + }
- +
- + base += size;
- +
- + /* update the suportedCasLatencies mask */
- + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
- + }
- +
- + /* calculate minimum CAS */
- + minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);
- + if (0 == minCas)
- + {
- + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
- + (busClk / 1000000));
- +
- + minCas = DDR2_CL_4; /* Continue with this CAS */
- + mvOsOutput("Set default CAS latency 4\n");
- + }
- +
- + /* calc SDRAM_CONFIG_REG and save it to temp register */
- + temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- +
- + /* check if ECC is enabled by the user */
- + if(eccDisable)
- + {
- + /* turn off ECC*/
- + temp &= ~BIT18;
- + }
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG1, temp);
- +
- + /* calc SDRAM_MODE_REG and save it to temp register */
- + temp = sdramModeRegCalc(minCas);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG2, temp);
- +
- + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
- + temp = sdramExtModeRegCalc(&bankInfo[0], busClk);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG10, temp);
- +
- + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
- + TTMode = MV_FALSE;
- + DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)
- + if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )
- + {
- + if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||
- + (numOfAllDevices > 18) )
- + {
- + mvOsOutput("Enable 2T ");
- + TTMode = MV_TRUE;
- + }
- + }
- +
- + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode );
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG3, temp);
- +
- + /* calc D_UNIT_CONTROL_HIGH and save it to temp register */
- + temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)
- + /* check if ECC is enabled by the user */
- + if(eccDisable)
- + {
- + /* turn off sample stage if no ecc */
- + temp &= ~SDRAM__D2P_EN;;
- + }
- + MV_REG_WRITE(DRAM_BUF_REG13, temp);
- +
- + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
- + temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG4, temp);
- +
- + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
- + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG5, temp);
- +
- + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
- + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG6, temp);
- +
- + sdramDDr2OdtConfig(bankInfo);
- +
- + /* calc DDR2_SDRAM_TIMING_LOW_REG and save it to temp register */
- + temp = sdramDdr2TimeLoRegCalc(minCas);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG11, temp);
- +
- + /* calc DDR2_SDRAM_TIMING_HIGH_REG and save it to temp register */
- + temp = sdramDdr2TimeHiRegCalc(minCas);
- + if(-1 == temp)
- + {
- + mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");
- + return MV_ERROR;
- + }
- + DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)
- + MV_REG_WRITE(DRAM_BUF_REG12, temp);
- +#endif
- +
- + /* Note that DDR SDRAM Address/Control and Data pad calibration */
- + /* settings is done in mvSdramIfConfig.s */
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvDramIfBankBaseGet - Get DRAM interface bank base.
- +*
- +* DESCRIPTION:
- +* This function returns the 32 bit base address of a given DRAM bank.
- +*
- +* INPUT:
- +* bankNum - Bank number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* DRAM bank size. If bank is disabled or paramter is invalid, the
- +* function returns -1.
- +*
- +*******************************************************************************/
- +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)
- +{
- + DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",
- + bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));
- + return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);
- +}
- +
- +/*******************************************************************************
- +* mvDramIfBankSizeGet - Get DRAM interface bank size.
- +*
- +* DESCRIPTION:
- +* This function returns the size of a given DRAM bank.
- +*
- +* INPUT:
- +* bankNum - Bank number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* DRAM bank size. If bank is disabled the function return '0'. In case
- +* or paramter is invalid, the function returns -1.
- +*
- +*******************************************************************************/
- +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)
- +{
- + DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",
- + bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));
- + return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);
- +}
- +
- +
- +/*******************************************************************************
- +* mvDramIfSizeGet - Get DRAM interface total size.
- +*
- +* DESCRIPTION:
- +* This function get the DRAM total size.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* DRAM total size. In case or paramter is invalid, the function
- +* returns -1.
- +*
- +*******************************************************************************/
- +MV_U32 mvDramIfSizeGet(MV_VOID)
- +{
- + MV_U32 size = 0, i;
- +
- + for(i = 0; i < MV_DRAM_MAX_CS; i++)
- + size += mvDramIfBankSizeGet(i);
- +
- + DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));
- + return size;
- +}
- +
- +/*******************************************************************************
- +* mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.
- +*
- +* DESCRIPTION:
- +* The ECC single bit error threshold is the number of single bit
- +* errors to happen before the Dunit generates an interrupt.
- +* This function set single bit ECC threshold.
- +*
- +* INPUT:
- +* threshold - threshold.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if threshold is to big, MV_OK otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)
- +{
- + MV_U32 regVal;
- +
- + if (threshold > SECR_THRECC_MAX)
- + {
- + return MV_BAD_PARAM;
- + }
- +
- + regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);
- + regVal &= ~SECR_THRECC_MASK;
- + regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));
- + MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);
- +
- + return MV_OK;
- +}
- +
- +#ifndef MV_STATIC_DRAM_ON_BOARD
- +/*******************************************************************************
- +* minCasCalc - Calculate the Minimum CAS latency which can be used.
- +*
- +* DESCRIPTION:
- +* Calculate the minimum CAS latency that can be used, base on the DRAM
- +* parameters and the SDRAM bus Clock freq.
- +*
- +* INPUT:
- +* busClk - the DRAM bus Clock.
- +* pBankInfo - bank info parameters.
- +* forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* The minimum CAS Latency. The function returns 0 if max CAS latency
- +* supported by banks is incompatible with system bus clock frequancy.
- +*
- +*******************************************************************************/
- +
- +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)
- +{
- + MV_U32 count = 1, j;
- + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
- + MV_U32 startBit, stopBit;
- + MV_U32 minCas0 = 0, minCas2 = 0;
- +
- +
- + /* DDR 2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
- + Disco VI= * TBD | TBD | 5 | 4 | 3 | TBD | TBD | TBD *
- + Disco Duo= * TBD | 6 | 5 | 4 | 3 | TBD | TBD | TBD *
- + *********************************************************/
- +
- +
- + /* If we are asked to use the forced CAL we change the suported CAL to be forcedCl only */
- + if (forcedCl)
- + {
- + mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));
- +
- + if (forcedCl == 30)
- + pBankInfo->suportedCasLatencies = 0x08;
- + else if (forcedCl == 40)
- + pBankInfo->suportedCasLatencies = 0x10;
- + else if (forcedCl == 50)
- + pBankInfo->suportedCasLatencies = 0x20;
- + else if (forcedCl == 60)
- + pBankInfo->suportedCasLatencies = 0x40;
- + else
- + {
- + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
- + (forcedCl / 10), (forcedCl % 10));
- + pBankInfo->suportedCasLatencies = 0x10;
- + }
- +
- + return pBankInfo->suportedCasLatencies;
- + }
- +
- + /* go over the supported cas mask from Max Cas down and check if the */
- + /* SysClk stands in its time requirments. */
- +
- + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
- + pBankInfo->suportedCasLatencies,busClkPs ));
- + count = 1;
- + for(j = 7; j > 0; j--)
- + {
- + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
- + {
- + /* Reset the bits for CL incompatible for the sysClk */
- + switch (count)
- + {
- + case 1:
- + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + case 2:
- + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + case 3:
- + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + default:
- + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
- + break;
- + }
- + }
- + }
- +
- + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
- + pBankInfo->suportedCasLatencies ));
- +
- + count = 1;
- + DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",
- + pBankInfo2->suportedCasLatencies,busClkPs ));
- + for(j = 7; j > 0; j--)
- + {
- + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
- + {
- + /* Reset the bits for CL incompatible for the sysClk */
- + switch (count)
- + {
- + case 1:
- + if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs)
- + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + case 2:
- + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
- + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + case 3:
- + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
- + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
- + count++;
- + break;
- + default:
- + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
- + break;
- + }
- + }
- + }
- +
- + DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",
- + pBankInfo2->suportedCasLatencies ));
- +
- + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
- + stopBit = 6; /* DDR2 support CL stops with CL6 (bit 6) */
- +
- + for(j = startBit; j <= stopBit ; j++)
- + {
- + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
- + {
- + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
- + minCas0 = (BIT0 << j);
- + break;
- + }
- + }
- +
- + for(j = startBit; j <= stopBit ; j++)
- + {
- + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
- + {
- + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
- + minCas2 = (BIT0 << j);
- + break;
- + }
- + }
- +
- + if (minCas2 > minCas0)
- + return minCas2;
- + else
- + return minCas0;
- +
- + return 0;
- +}
- +
- +/*******************************************************************************
- +* sdramConfigRegCalc - Calculate sdram config register
- +*
- +* DESCRIPTION: Calculate sdram config register optimized value based
- +* on the bank info parameters.
- +*
- +* INPUT:
- +* busClk - the DRAM bus Clock.
- +* pBankInfo - sdram bank parameters
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram config reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)
- +{
- + MV_U32 sdramConfig = 0;
- + MV_U32 refreshPeriod;
- +
- + busClk /= 1000000; /* we work with busClk in MHz */
- +
- + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
- +
- + /* figure out the memory refresh internal */
- + switch (pBankInfo->refreshInterval & 0xf)
- + {
- + case 0x0: /* refresh period is 15.625 usec */
- + refreshPeriod = 15625;
- + break;
- + case 0x1: /* refresh period is 3.9 usec */
- + refreshPeriod = 3900;
- + break;
- + case 0x2: /* refresh period is 7.8 usec */
- + refreshPeriod = 7800;
- + break;
- + case 0x3: /* refresh period is 31.3 usec */
- + refreshPeriod = 31300;
- + break;
- + case 0x4: /* refresh period is 62.5 usec */
- + refreshPeriod = 62500;
- + break;
- + case 0x5: /* refresh period is 125 usec */
- + refreshPeriod = 125000;
- + break;
- + default: /* refresh period undefined */
- + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
- + return -1;
- + }
- +
- + /* Now the refreshPeriod is in register format value */
- + refreshPeriod = (busClk * refreshPeriod) / 1000;
- +
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
- + refreshPeriod));
- +
- + /* make sure the refresh value is only 14 bits */
- + if(refreshPeriod > SDRAM_REFRESH_MAX)
- + {
- + refreshPeriod = SDRAM_REFRESH_MAX;
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
- + refreshPeriod));
- + }
- +
- + /* Clear the refresh field */
- + sdramConfig &= ~SDRAM_REFRESH_MASK;
- +
- + /* Set new value to refresh field */
- + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
- +
- + /* registered DRAM ? */
- + if ( pBankInfo->registeredAddrAndControlInputs )
- + {
- + /* it's registered DRAM, so set the reg. DRAM bit */
- + sdramConfig |= SDRAM_REGISTERED;
- + DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)
- + }
- +
- + /* ECC and IERR support */
- + sdramConfig &= ~SDRAM_ECC_MASK; /* Clear ECC field */
- + sdramConfig &= ~SDRAM_IERR_MASK; /* Clear IErr field */
- +
- + if ( pBankInfo->errorCheckType )
- + {
- + sdramConfig |= SDRAM_ECC_EN;
- + sdramConfig |= SDRAM_IERR_REPORTE;
- + DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));
- + }
- + else
- + {
- + sdramConfig |= SDRAM_ECC_DIS;
- + sdramConfig |= SDRAM_IERR_IGNORE;
- + DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));
- + }
- + /* Set static default settings */
- + sdramConfig |= SDRAM_CONFIG_DV;
- +
- + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
- + sdramConfig));
- +
- + return sdramConfig;
- +}
- +
- +/*******************************************************************************
- +* sdramModeRegCalc - Calculate sdram mode register
- +*
- +* DESCRIPTION: Calculate sdram mode register optimized value based
- +* on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* minCas - minimum CAS supported.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram mode reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
- +{
- + MV_U32 sdramMode;
- +
- + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
- +
- + /* Clear CAS Latency field */
- + sdramMode &= ~SDRAM_CL_MASK;
- +
- + DB(mvOsPrintf("DRAM CAS Latency ");)
- +
- + switch (minCas)
- + {
- + case DDR2_CL_3:
- + sdramMode |= SDRAM_DDR2_CL_3;
- + DB(mvOsPrintf("3.\n");)
- + break;
- + case DDR2_CL_4:
- + sdramMode |= SDRAM_DDR2_CL_4;
- + DB(mvOsPrintf("4.\n");)
- + break;
- + case DDR2_CL_5:
- + sdramMode |= SDRAM_DDR2_CL_5;
- + DB(mvOsPrintf("5.\n");)
- + break;
- + case DDR2_CL_6:
- + sdramMode |= SDRAM_DDR2_CL_6;
- + DB(mvOsPrintf("6.\n");)
- + break;
- + default:
- + mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
- + return -1;
- + }
- +
- + DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));
- +
- + return sdramMode;
- +}
- +/*******************************************************************************
- +* sdramExtModeRegCalc - Calculate sdram Extended mode register
- +*
- +* DESCRIPTION:
- +* Return sdram Extended mode register value based
- +* on the bank info parameters and bank presence.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +* busClk - DRAM frequency
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram Extended mode reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
- +{
- + MV_U32 populateBanks = 0;
- + int bankNum;
- +
- + /* Represent the populate banks in binary form */
- + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + if (0 != pBankInfo[bankNum].size)
- + {
- + populateBanks |= (1 << bankNum);
- + }
- + }
- +
- + switch(populateBanks)
- + {
- + case(BANK_PRESENT_CS0):
- + case(BANK_PRESENT_CS0_CS1):
- + return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;
- +
- + case(BANK_PRESENT_CS0_CS2):
- + case(BANK_PRESENT_CS0_CS1_CS2):
- + case(BANK_PRESENT_CS0_CS2_CS3):
- + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
- + if (busClk >= MV_BOARD_SYSCLK_267MHZ)
- + return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;
- + else
- + return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;
- +
- + default:
- + mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
- + return -1;
- + }
- + return 0;
- +}
- +
- +/*******************************************************************************
- +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
- +*
- +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
- +* on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +* minCas - minimum CAS supported.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram dunit control low reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTMode)
- +{
- + MV_U32 dunitCtrlLow, cl;
- + MV_U32 sbOutR[4]={3,5,7,9} ;
- + MV_U32 sbOutU[4]={1,3,5,7} ;
- +
- + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
- +
- + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
- +
- + /* Clear StBurstOutDel field */
- + dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;
- +
- + /* Clear StBurstInDel field */
- + dunitCtrlLow &= ~SDRAM_SB_IN_MASK;
- +
- + /* Clear CtrlPos field */
- + dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;
- +
- + /* Clear 2T field */
- + dunitCtrlLow &= ~SDRAM_2T_MASK;
- + if (TTMode == MV_TRUE)
- + {
- + dunitCtrlLow |= SDRAM_2T_MODE;
- + }
- +
- + /* For proper sample of read data set the Dunit Control register's */
- + /* stBurstInDel bits [27:24] */
- + /* 200MHz - 267MHz None reg = CL + 1 */
- + /* 200MHz - 267MHz reg = CL + 2 */
- + /* > 267MHz None reg = CL + 2 */
- + /* > 267MHz reg = CL + 3 */
- +
- + /* For proper sample of read data set the Dunit Control register's */
- + /* stBurstOutDel bits [23:20] */
- + /********-********-********-********-
- + * CL=3 | CL=4 | CL=5 | CL=6 |
- + *********-********-********-********-
- + Not Reg. * 0001 | 0011 | 0101 | 0111 |
- + *********-********-********-********-
- + Registered * 0011 | 0101 | 0111 | 1001 |
- + *********-********-********-********/
- +
- + /* Set Dunit Control low default value */
- + dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV;
- +
- + switch (minCas)
- + {
- + case DDR2_CL_3: cl = 3; break;
- + case DDR2_CL_4: cl = 4; break;
- + case DDR2_CL_5: cl = 5; break;
- + case DDR2_CL_6: cl = 6; break;
- + default:
- + mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);
- + return -1;
- + }
- +
- + /* registerd DDR SDRAM? */
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + {
- + dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
- + }
- + else
- + {
- + dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
- + }
- +
- + DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));
- +
- + if (busClk <= MV_BOARD_SYSCLK_267MHZ)
- + {
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + cl = cl + 2;
- + else
- + cl = cl + 1;
- + }
- + else
- + {
- + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
- + cl = cl + 3;
- + else
- + cl = cl + 2;
- + }
- +
- + DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));
- + dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;
- +
- + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
- +
- + return dunitCtrlLow;
- +}
- +
- +/*******************************************************************************
- +* dunitCtrlHighRegCalc - Calculate sdram dunit control high register
- +*
- +* DESCRIPTION: Calculate sdram dunit control high register optimized value based
- +* on the bus clock.
- +*
- +* INPUT:
- +* busClk - DRAM frequency.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram dunit control high reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
- +{
- + MV_U32 dunitCtrlHigh;
- + dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);
- + if(busClk > MV_BOARD_SYSCLK_300MHZ)
- + dunitCtrlHigh |= SDRAM__P2D_EN;
- + else
- + dunitCtrlHigh &= ~SDRAM__P2D_EN;
- +
- + if(busClk > MV_BOARD_SYSCLK_267MHZ)
- + dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);
- +
- + /* If ECC support we turn on D2P sample */
- + dunitCtrlHigh &= ~SDRAM__D2P_EN; /* Clear D2P bit */
- + if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))
- + dunitCtrlHigh |= SDRAM__D2P_EN;
- +
- + return dunitCtrlHigh;
- +}
- +
- +/*******************************************************************************
- +* sdramAddrCtrlRegCalc - Calculate sdram address control register
- +*
- +* DESCRIPTION: Calculate sdram address control register optimized value based
- +* on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram address control reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)
- +{
- + MV_U32 addrCtrl = 0;
- +
- + if (pBankInfoDIMM1->size)
- + {
- + switch (pBankInfoDIMM1->sdramWidth)
- + {
- + case 4: /* memory is x4 */
- + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
- + return -1;
- + break;
- + case 8: /* memory is x8 */
- + addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);
- + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));
- + break;
- + case 16:
- + addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);
- + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));
- + break;
- + default: /* memory width unsupported */
- + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
- + return -1;
- + }
- + }
- +
- + switch (pBankInfo->sdramWidth)
- + {
- + case 4: /* memory is x4 */
- + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
- + return -1;
- + break;
- + case 8: /* memory is x8 */
- + addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);
- + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));
- + break;
- + case 16:
- + addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);
- + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));
- + break;
- + default: /* memory width unsupported */
- + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
- + return -1;
- + }
- +
- + /* Note that density is in MB units */
- + switch (pBankInfo->deviceDensity)
- + {
- + case 256: /* 256 Mbit */
- + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
- + addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);
- + break;
- + case 512: /* 512 Mbit */
- + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
- + addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);
- + break;
- + case 1024: /* 1 Gbit */
- + DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));
- + addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);
- + break;
- + case 2048: /* 2 Gbit */
- + DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));
- + addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);
- + break;
- + default:
- + mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
- + pBankInfo->deviceDensity);
- + return -1;
- + }
- +
- + if (pBankInfoDIMM1->size)
- + {
- + switch (pBankInfoDIMM1->deviceDensity)
- + {
- + case 256: /* 256 Mbit */
- + DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));
- + addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);
- + break;
- + case 512: /* 512 Mbit */
- + DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));
- + addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);
- + break;
- + case 1024: /* 1 Gbit */
- + DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));
- + addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);
- + break;
- + case 2048: /* 2 Gbit */
- + DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));
- + addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);
- + break;
- + default:
- + mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
- + pBankInfoDIMM1->deviceDensity);
- + return -1;
- + }
- + }
- + /* SDRAM address control */
- + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
- +
- + return addrCtrl;
- +}
- +
- +/*******************************************************************************
- +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
- +*
- +* DESCRIPTION:
- +* This function calculates sdram timing control low register
- +* optimized value based on the bank info parameters and the minCas.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +* minCas - minimum CAS supported.
- +* busClk - Bus clock
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram timing control low reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)
- +{
- + MV_U32 tRp = 0;
- + MV_U32 tRrd = 0;
- + MV_U32 tRcd = 0;
- + MV_U32 tRas = 0;
- + MV_U32 tWr = 0;
- + MV_U32 tWtr = 0;
- + MV_U32 tRtp = 0;
- + MV_U32 timeCtrlLow = 0;
- +
- + MV_U32 bankNum;
- +
- + busClk = busClk / 1000000; /* In MHz */
- +
- + /* Scan all DRAM banks to find maximum timing values */
- + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
- + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
- + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
- + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
- + }
- +
- + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
- + /* by shifting the data two bits right. */
- + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
- + tRrd = tRrd >> 2;
- + tRcd = tRcd >> 2;
- +
- + /* Extract clock cycles from time parameter. We need to round up */
- + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
- + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
- + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
- + /* JEDEC min reqeirments tRrd = 2 */
- + if (tRrd < 2)
- + tRrd = 2;
- + DB(mvOsPrintf("tRrd = %d ", tRrd));
- + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
- + DB(mvOsPrintf("tRcd = %d ", tRcd));
- + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
- + DB(mvOsPrintf("tRas = %d ", tRas));
- +
- + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
- + /* Scan all DRAM banks to find maximum timing values */
- + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
- + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
- + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
- + }
- +
- + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
- + /* part by shifting the data two bits right. */
- + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
- + tWtr = tWtr >> 2;
- + tRtp = tRtp >> 2;
- + /* Extract clock cycles from time parameter. We need to round up */
- + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
- + DB(mvOsPrintf("tWr = %d ", tWr));
- + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
- + /* JEDEC min reqeirments tWtr = 2 */
- + if (tWtr < 2)
- + tWtr = 2;
- + DB(mvOsPrintf("tWtr = %d ", tWtr));
- + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
- + /* JEDEC min reqeirments tRtp = 2 */
- + if (tRtp < 2)
- + tRtp = 2;
- + DB(mvOsPrintf("tRtp = %d ", tRtp));
- +
- + /* Note: value of 0 in register means one cycle, 1 means two and so on */
- + timeCtrlLow = (((tRp - 1) << SDRAM_TRP_OFFS) |
- + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
- + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
- + (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|
- + ((tWr - 1) << SDRAM_TWR_OFFS) |
- + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
- + ((tRtp - 1) << SDRAM_TRTP_OFFS));
- +
- + /* Check extended tRas bit */
- + if ((tRas - 1) & BIT4)
- + timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);
- +
- + return timeCtrlLow;
- +}
- +
- +/*******************************************************************************
- +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
- +*
- +* DESCRIPTION:
- +* This function calculates sdram timing control high register
- +* optimized value based on the bank info parameters and the bus clock.
- +*
- +* INPUT:
- +* pBankInfo - sdram bank parameters
- +* busClk - Bus clock
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* sdram timing control high reg value.
- +*
- +*******************************************************************************/
- +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
- +{
- + MV_U32 tRfc;
- + MV_U32 timingHigh;
- + MV_U32 timeNs = 0;
- + MV_U32 bankNum;
- +
- + busClk = busClk / 1000000; /* In MHz */
- +
- + /* Set DDR timing high register static configuration bits */
- + timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);
- +
- + /* Set DDR timing high register default value */
- + timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;
- +
- + /* Clear tRfc field */
- + timingHigh &= ~SDRAM_TRFC_MASK;
- +
- + /* Scan all DRAM banks to find maximum timing values */
- + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
- + DB(mvOsPrintf("Dram: Timing High: minRefreshToActiveCmd = %d\n",
- + pBankInfo[bankNum].minRefreshToActiveCmd));
- + }
- + if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)
- + {
- + timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;
- + }
- +
- + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
- + /* Note: value of 0 in register means one cycle, 1 means two and so on */
- + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
- + timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);
- + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
- +
- + /* SDRAM timing high */
- + DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));
- +
- + return timingHigh;
- +}
- +/*******************************************************************************
- +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
- +*
- +* DESCRIPTION:
- +* This function config DDR2 On Die Termination (ODT) registers.
- +*
- +* INPUT:
- +* pBankInfo - bank info parameters.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* None
- +*******************************************************************************/
- +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + MV_U32 populateBanks = 0;
- + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
- + int bankNum;
- +
- + /* Represent the populate banks in binary form */
- + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
- + {
- + if (0 != pBankInfo[bankNum].size)
- + {
- + populateBanks |= (1 << bankNum);
- + }
- + }
- +
- + switch(populateBanks)
- + {
- + case(BANK_PRESENT_CS0):
- + case(BANK_PRESENT_CS0_CS1):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;
- + break;
- + case(BANK_PRESENT_CS0_CS2):
- + case(BANK_PRESENT_CS0_CS1_CS2):
- + case(BANK_PRESENT_CS0_CS2_CS3):
- + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
- + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;
- + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;
- + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;
- + break;
- + default:
- + DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));
- + return;
- + }
- + /* DDR2 SDRAM ODT ctrl low */
- + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));
- + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
- +
- + /* DDR2 SDRAM ODT ctrl high */
- + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));
- + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
- +
- + /* DDR2 DUNIT ODT ctrl */
- + if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||
- + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
- + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
- + (mvCtrlModelGet() == MV_78200_DEV_ID) )
- + dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */
- +
- + DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));
- + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
- + return;
- +}
- +/*******************************************************************************
- +* sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.
- +*
- +* DESCRIPTION:
- +* This function config DDR2 DRAM Timing low registers.
- +*
- +* INPUT:
- +* minCas - minimum CAS supported.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* DDR2 sdram timing low reg value.
- +*******************************************************************************/
- +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)
- +{
- + MV_U8 cl = -1;
- + MV_U32 ddr2TimeLoReg;
- +
- + /* read and clear the feilds we are going to set */
- + ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);
- + ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK |
- + SD2TLR_TODT_OFF_RD_MASK |
- + SD2TLR_TODT_ON_CTRL_RD_MASK |
- + SD2TLR_TODT_OFF_CTRL_RD_MASK);
- +
- + if( minCas == DDR2_CL_3 )
- + {
- + cl = 3;
- + }
- + else if( minCas == DDR2_CL_4 )
- + {
- + cl = 4;
- + }
- + else if( minCas == DDR2_CL_5 )
- + {
- + cl = 5;
- + }
- + else if( minCas == DDR2_CL_6 )
- + {
- + cl = 6;
- + }
- + else
- + {
- + DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
- + minCas));
- + cl = 4;
- + }
- +
- + ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);
- + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);
- + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);
- + ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);
- +
- + /* DDR2 SDRAM timing low */
- + DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));
- +
- + return ddr2TimeLoReg;
- +}
- +
- +/*******************************************************************************
- +* sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.
- +*
- +* DESCRIPTION:
- +* This function config DDR2 DRAM Timing high registers.
- +*
- +* INPUT:
- +* minCas - minimum CAS supported.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* DDR2 sdram timing high reg value.
- +*******************************************************************************/
- +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)
- +{
- + MV_U8 cl = -1;
- + MV_U32 ddr2TimeHiReg;
- +
- + /* read and clear the feilds we are going to set */
- + ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);
- + ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK |
- + SD2THR_TODT_OFF_WR_MASK |
- + SD2THR_TODT_ON_CTRL_WR_MASK |
- + SD2THR_TODT_OFF_CTRL_WR_MASK);
- +
- + if( minCas == DDR2_CL_3 )
- + {
- + cl = 3;
- + }
- + else if( minCas == DDR2_CL_4 )
- + {
- + cl = 4;
- + }
- + else if( minCas == DDR2_CL_5 )
- + {
- + cl = 5;
- + }
- + else if( minCas == DDR2_CL_6 )
- + {
- + cl = 6;
- + }
- + else
- + {
- + mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
- + minCas);
- + cl = 4;
- + }
- +
- + ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);
- + ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);
- + ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);
- + ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);
- +
- + /* DDR2 SDRAM timin high */
- + DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));
- +
- + return ddr2TimeHiReg;
- +}
- +#endif
- +
- +/*******************************************************************************
- +* mvDramIfCalGet - Get CAS Latency
- +*
- +* DESCRIPTION:
- +* This function get the CAS Latency.
- +*
- +* INPUT:
- +* None
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* CAS latency times 10 (to avoid using floating point).
- +*
- +*******************************************************************************/
- +MV_U32 mvDramIfCalGet(void)
- +{
- + MV_U32 sdramCasLat, casLatMask;
- +
- + casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);
- +
- + switch (casLatMask)
- + {
- + case SDRAM_DDR2_CL_3:
- + sdramCasLat = 30;
- + break;
- + case SDRAM_DDR2_CL_4:
- + sdramCasLat = 40;
- + break;
- + case SDRAM_DDR2_CL_5:
- + sdramCasLat = 50;
- + break;
- + case SDRAM_DDR2_CL_6:
- + sdramCasLat = 60;
- + break;
- + default:
- + mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");
- + return -1;
- + }
- +
- + return sdramCasLat;
- +}
- +
- +
- +/*******************************************************************************
- +* mvDramIfSelfRefreshSet - Put the dram in self refresh mode -
- +*
- +* DESCRIPTION:
- +* add support in power management.
- +*
- +*
- +* INPUT:
- +* None
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* None
- +*
- +*******************************************************************************/
- +
- +MV_VOID mvDramIfSelfRefreshSet()
- +{
- + MV_U32 operReg;
- +
- + operReg = MV_REG_READ(SDRAM_OPERATION_REG);
- + MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);
- + /* Read until register is reset to 0 */
- + while(MV_REG_READ(SDRAM_OPERATION_REG));
- +}
- +/*******************************************************************************
- +* mvDramIfDimGetSPDversion - return DIMM SPD version.
- +*
- +* DESCRIPTION:
- +* This function prints the DRAM controller information.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)
- +{
- + MV_DIMM_INFO dimmInfo;
- + if (bankNum >= MV_DRAM_MAX_CS )
- + {
- + DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n"));
- + return ;
- + }
- + memset(&dimmInfo,0,sizeof(dimmInfo));
- + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
- + {
- + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
- + return ;
- + }
- + *pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;
- + *pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;
- +}
- +/*******************************************************************************
- +* mvDramIfShow - Show DRAM controller information.
- +*
- +* DESCRIPTION:
- +* This function prints the DRAM controller information.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +void mvDramIfShow(void)
- +{
- + int i, sdramCasLat, sdramCsSize;
- + MV_U32 Major=0, Minor=0;
- +
- + mvOsOutput("DRAM Controller info:\n");
- +
- + mvOsOutput("Total DRAM ");
- + mvSizePrint(mvDramIfSizeGet());
- + mvOsOutput("\n");
- +
- + for(i = 0; i < MV_DRAM_MAX_CS; i++)
- + {
- + sdramCsSize = mvDramIfBankSizeGet(i);
- + if (sdramCsSize)
- + {
- + if (0 == (i & 1))
- + {
- + mvDramIfDimGetSPDversion(&Major, &Minor,i);
- + mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);
- + }
- + mvOsOutput("\tDRAM CS[%d] ", i);
- + mvSizePrint(sdramCsSize);
- + mvOsOutput("\n");
- + }
- + }
- + sdramCasLat = mvDramIfCalGet();
- +
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)
- + {
- + mvOsOutput("ECC enabled, ");
- + }
- + else
- + {
- + mvOsOutput("ECC Disabled, ");
- + }
- +
- + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)
- + {
- + mvOsOutput("Registered DIMM\n");
- + }
- + else
- + {
- + mvOsOutput("Non registered DIMM\n");
- + }
- +
- + mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);
- +}
- +/*******************************************************************************
- +* mvDramIfGetFirstCS - find the DRAM bank on the lower address
- +*
- +*
- +* DESCRIPTION:
- +* This function return the fisrt CS on address 0
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* SDRAM_CS0 or SDRAM_CS2
- +*
- +*******************************************************************************/
- +MV_U32 mvDramIfGetFirstCS(void)
- +{
- + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
- +
- + if (DRAM_CS_Order[0] == N_A)
- + {
- + mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);
- +#ifdef MV_INCLUDE_SDRAM_CS2
- + mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);
- +#endif
- +
- +#ifdef MV_INCLUDE_SDRAM_CS2
- + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
- + {
- + DRAM_CS_Order[0] = SDRAM_CS2;
- + DRAM_CS_Order[1] = SDRAM_CS3;
- + DRAM_CS_Order[2] = SDRAM_CS0;
- + DRAM_CS_Order[3] = SDRAM_CS1;
- +
- + return SDRAM_CS2;
- + }
- +#endif
- + DRAM_CS_Order[0] = SDRAM_CS0;
- + DRAM_CS_Order[1] = SDRAM_CS1;
- +#ifdef MV_INCLUDE_SDRAM_CS2
- + DRAM_CS_Order[2] = SDRAM_CS2;
- + DRAM_CS_Order[3] = SDRAM_CS3;
- +#endif
- + return SDRAM_CS0;
- + }
- + return DRAM_CS_Order[0];
- +}
- +/*******************************************************************************
- +* mvDramIfGetCSorder -
- +*
- +*
- +* DESCRIPTION:
- +* This function return the fisrt CS on address 0
- +*
- +* INPUT:
- +* CS number.
- +*
- +* OUTPUT:
- +* CS order.
- +*
- +* RETURN:
- +* SDRAM_CS0 or SDRAM_CS2
- +*
- +* NOTE: mvDramIfGetFirstCS must be caled before this subroutine
- +*******************************************************************************/
- +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )
- +{
- + return DRAM_CS_Order[csOrder];
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 2010-11-09 20:28:10.852495382 +0100
- @@ -0,0 +1,157 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvDramIfConfigh
- +#define __INCmvDramIfConfigh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* includes */
- +
- +/* defines */
- +
- +/* registers defaults values */
- +
- +#define SDRAM_CONFIG_DV (SDRAM_SRMODE_DRAM | BIT25 | BIT30)
- +
- +#define SDRAM_DUNIT_CTRL_LOW_DDR2_DV \
- + (SDRAM_SRCLK_KEPT | \
- + SDRAM_CLK1DRV_NORMAL | \
- + (BIT28 | BIT29))
- +
- +#define SDRAM_ADDR_CTRL_DV 2
- +
- +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
- + ((0x2 << SDRAM_TRCD_OFFS) | \
- + (0x2 << SDRAM_TRP_OFFS) | \
- + (0x1 << SDRAM_TWR_OFFS) | \
- + (0x0 << SDRAM_TWTR_OFFS) | \
- + (0x5 << SDRAM_TRAS_OFFS) | \
- + (0x1 << SDRAM_TRRD_OFFS))
- +
- +/* Note: value of 0 in register means one cycle, 1 means two and so on */
- +#define SDRAM_TIMING_CTRL_HIGH_REG_DV \
- + ((0x0 << SDRAM_TR2R_OFFS) | \
- + (0x0 << SDRAM_TR2W_W2R_OFFS) | \
- + (0x1 << SDRAM_TW2W_OFFS))
- +
- +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
- +
- +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
- +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
- +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
- +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
- +
- +#define DDR2_ODT_CTRL_LOW_CS0_CS1_DV 0x84210000
- +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_DV 0x00000000
- +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV 0x0000E80F
- +#ifdef MV78XX0
- +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000040
- +#else
- +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000440
- +#endif
- +
- +#define DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV 0x030C030C
- +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV 0x00000000
- +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV 0x0000F40F
- +#ifdef MV78XX0
- +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000004
- +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000044
- +#else
- +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000404
- +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000444
- +#endif
- +
- +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
- +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
- + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +
- +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
- + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +
- +/* DDR SDRAM Mode Register default value */
- +#define DDR2_MODE_REG_DV (SDRAM_BURST_LEN_4 | SDRAM_WR_3_CYC)
- +/* DDR SDRAM Timing parameter default values */
- +#define SDRAM_TIMING_CTRL_LOW_REG_DEFAULT 0x33136552
- +#define SDRAM_TRFC_DEFAULT_VALUE 0x34
- +#define SDRAM_TRFC_DEFAULT SDRAM_TRFC_DEFAULT_VALUE
- +#define SDRAM_TW2W_DEFALT (0x1 << SDRAM_TW2W_OFFS)
- +
- +#define SDRAM_TIMING_CTRL_HIGH_REG_DEFAULT (SDRAM_TRFC_DEFAULT | SDRAM_TW2W_DEFALT)
- +
- +#define SDRAM_FTDLL_REG_DEFAULT_LEFT 0x88C800
- +#define SDRAM_FTDLL_REG_DEFAULT_RIGHT 0x88C800
- +#define SDRAM_FTDLL_REG_DEFAULT_UP 0x88C800
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvDramIfh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 2010-11-09 20:28:10.882495421 +0100
- @@ -0,0 +1,172 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvDramIfh
- +#define __INCmvDramIfh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* includes */
- +#include "ddr2/mvDramIfRegs.h"
- +#include "ddr2/mvDramIfConfig.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +/* defines */
- +/* DRAM Timing parameters */
- +#define SDRAM_TWR 15 /* ns tWr */
- +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
- +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
- +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
- +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
- +
- +#define CAL_AUTO_DETECT 0 /* Do not force CAS latancy (mvDramIfDetect) */
- +#define ECC_DISABLE 1 /* Force ECC to Disable */
- +#define ECC_ENABLE 0 /* Force ECC to ENABLE */
- +/* typedefs */
- +
- +/* enumeration for memory types */
- +typedef enum _mvMemoryType
- +{
- + MEM_TYPE_SDRAM,
- + MEM_TYPE_DDR1,
- + MEM_TYPE_DDR2
- +}MV_MEMORY_TYPE;
- +
- +/* enumeration for DDR2 supported CAS Latencies */
- +typedef enum _mvDimmDdr2Cas
- +{
- + DDR2_CL_3 = 0x08,
- + DDR2_CL_4 = 0x10,
- + DDR2_CL_5 = 0x20,
- + DDR2_CL_6 = 0x40,
- + DDR2_CL_FAULT
- +} MV_DIMM_DDR2_CAS;
- +
- +
- +typedef struct _mvDramBankInfo
- +{
- + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
- +
- + /* DIMM dimensions */
- + MV_U32 numOfRowAddr;
- + MV_U32 numOfColAddr;
- + MV_U32 dataWidth;
- + MV_U32 errorCheckType; /* ECC , PARITY..*/
- + MV_U32 sdramWidth; /* 4,8,16 or 32 */
- + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
- + MV_U32 burstLengthSupported;
- + MV_U32 numOfBanksOnEachDevice;
- + MV_U32 suportedCasLatencies;
- + MV_U32 refreshInterval;
- +
- + /* DIMM timing parameters */
- + MV_U32 minCycleTimeAtMaxCasLatPs;
- + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
- + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
- + MV_U32 minRowPrechargeTime;
- + MV_U32 minRowActiveToRowActive;
- + MV_U32 minRasToCasDelay;
- + MV_U32 minRasPulseWidth;
- + MV_U32 minWriteRecoveryTime; /* DDR2 only */
- + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
- + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
- + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
- +
- + /* Parameters calculated from the extracted DIMM information */
- + MV_U32 size;
- + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
- + MV_U32 numberOfDevices;
- +
- + /* DIMM attributes (MV_TRUE for yes) */
- + MV_BOOL registeredAddrAndControlInputs;
- + MV_BOOL registeredDQMBinputs;
- +
- +}MV_DRAM_BANK_INFO;
- +
- +#include "ddr2/spd/mvSpd.h"
- +
- +/* mvDramIf.h API list */
- +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
- +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable);
- +MV_VOID _mvDramIfConfig(int entryNum);
- +
- +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum);
- +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum);
- +MV_U32 mvDramIfSizeGet(MV_VOID);
- +MV_U32 mvDramIfCalGet(void);
- +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold);
- +MV_VOID mvDramIfSelfRefreshSet(void);
- +void mvDramIfShow(void);
- +MV_U32 mvDramIfGetFirstCS(void);
- +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder );
- +MV_U32 mvDramCsSizeGet(MV_U32 csNum);
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvDramIfh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 2010-11-09 20:28:10.921244571 +0100
- @@ -0,0 +1,423 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvDramIfRegsh
- +#define __INCmvDramIfRegsh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* DDR SDRAM Controller Address Decode Registers */
- + /* SDRAM CSn Base Address Register (SCBAR) */
- +#define SDRAM_BASE_ADDR_REG(cpu,csNum) (0x1500 + ((csNum) * 8) + ((cpu) * 0x70))
- +#define SCBAR_BASE_OFFS 16
- +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
- +#define SCBAR_BASE_ALIGNMENT 0x10000
- +
- +/* SDRAM CSn Size Register (SCSR) */
- +#define SDRAM_SIZE_REG(cpu,csNum) (0x1504 + ((csNum) * 8) + ((cpu) * 0x70))
- +#define SCSR_SIZE_OFFS 24
- +#define SCSR_SIZE_MASK (0xff << SCSR_SIZE_OFFS)
- +#define SCSR_SIZE_ALIGNMENT 0x1000000
- +#define SCSR_WIN_EN BIT0
- +
- +/* configuration register */
- +#define SDRAM_CONFIG_REG (DRAM_BASE + 0x1400)
- +#define SDRAM_REFRESH_OFFS 0
- +#define SDRAM_REFRESH_MAX 0x3FFF
- +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
- +#define SDRAM_DWIDTH_OFFS 15
- +#define SDRAM_DWIDTH_MASK (1 << SDRAM_DWIDTH_OFFS)
- +#define SDRAM_DWIDTH_32BIT (0 << SDRAM_DWIDTH_OFFS)
- +#define SDRAM_DWIDTH_64BIT (1 << SDRAM_DWIDTH_OFFS)
- +#define SDRAM_REGISTERED (1 << 17)
- +#define SDRAM_ECC_OFFS 18
- +#define SDRAM_ECC_MASK (1 << SDRAM_ECC_OFFS)
- +#define SDRAM_ECC_DIS (0 << SDRAM_ECC_OFFS)
- +#define SDRAM_ECC_EN (1 << SDRAM_ECC_OFFS)
- +#define SDRAM_IERR_OFFS 19
- +#define SDRAM_IERR_MASK (1 << SDRAM_IERR_OFFS)
- +#define SDRAM_IERR_REPORTE (0 << SDRAM_IERR_OFFS)
- +#define SDRAM_IERR_IGNORE (1 << SDRAM_IERR_OFFS)
- +#define SDRAM_SRMODE_OFFS 24
- +#define SDRAM_SRMODE_MASK (1 << SDRAM_SRMODE_OFFS)
- +#define SDRAM_SRMODE_POWER (0 << SDRAM_SRMODE_OFFS)
- +#define SDRAM_SRMODE_DRAM (1 << SDRAM_SRMODE_OFFS)
- +
- +/* dunit control low register */
- +#define SDRAM_DUNIT_CTRL_REG (DRAM_BASE + 0x1404)
- +#define SDRAM_2T_OFFS 4
- +#define SDRAM_2T_MASK (1 << SDRAM_2T_OFFS)
- +#define SDRAM_2T_MODE (1 << SDRAM_2T_OFFS)
- +
- +#define SDRAM_SRCLK_OFFS 5
- +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
- +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
- +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
- +#define SDRAM_CTRL_POS_OFFS 6
- +#define SDRAM_CTRL_POS_MASK (1 << SDRAM_CTRL_POS_OFFS)
- +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
- +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
- +#define SDRAM_CLK1DRV_OFFS 12
- +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
- +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
- +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
- +#define SDRAM_CLK2DRV_OFFS 13
- +#define SDRAM_CLK2DRV_MASK (1 << SDRAM_CLK2DRV_OFFS)
- +#define SDRAM_CLK2DRV_HIGH_Z (0 << SDRAM_CLK2DRV_OFFS)
- +#define SDRAM_CLK2DRV_NORMAL (1 << SDRAM_CLK2DRV_OFFS)
- +#define SDRAM_SB_OUT_DEL_OFFS 20
- +#define SDRAM_SB_OUT_DEL_MAX 0xf
- +#define SDRAM_SB_OUT_MASK (SDRAM_SB_OUT_DEL_MAX<<SDRAM_SB_OUT_DEL_OFFS)
- +#define SDRAM_SB_IN_DEL_OFFS 24
- +#define SDRAM_SB_IN_DEL_MAX 0xf
- +#define SDRAM_SB_IN_MASK (SDRAM_SB_IN_DEL_MAX<<SDRAM_SB_IN_DEL_OFFS)
- +
- +/* dunit control hight register */
- +#define SDRAM_DUNIT_CTRL_HI_REG (DRAM_BASE + 0x1424)
- +#define SDRAM__D2P_OFFS 7
- +#define SDRAM__D2P_EN (1 << SDRAM__D2P_OFFS)
- +#define SDRAM__P2D_OFFS 8
- +#define SDRAM__P2D_EN (1 << SDRAM__P2D_OFFS)
- +#define SDRAM__ADD_HALF_FCC_OFFS 9
- +#define SDRAM__ADD_HALF_FCC_EN (1 << SDRAM__ADD_HALF_FCC_OFFS)
- +#define SDRAM__PUP_ZERO_SKEW_OFFS 10
- +#define SDRAM__PUP_ZERO_SKEW_EN (1 << SDRAM__PUP_ZERO_SKEW_OFFS)
- +#define SDRAM__WR_MESH_DELAY_OFFS 11
- +#define SDRAM__WR_MESH_DELAY_EN (1 << SDRAM__WR_MESH_DELAY_OFFS)
- +
- +/* sdram timing control low register */
- +#define SDRAM_TIMING_CTRL_LOW_REG (DRAM_BASE + 0x1408)
- +#define SDRAM_TRCD_OFFS 4
- +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
- +#define SDRAM_TRP_OFFS 8
- +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
- +#define SDRAM_TWR_OFFS 12
- +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
- +#define SDRAM_TWTR_OFFS 16
- +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
- +#define SDRAM_TRAS_OFFS 0
- +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
- +#define SDRAM_EXT_TRAS_OFFS 20
- +#define SDRAM_EXT_TRAS_MASK (0x1 << SDRAM_EXT_TRAS_OFFS)
- +#define SDRAM_TRRD_OFFS 24
- +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
- +#define SDRAM_TRTP_OFFS 28
- +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
- +#define SDRAM_TRTP_DDR1 (0x1 << SDRAM_TRTP_OFFS)
- +
- +/* sdram timing control high register */
- +#define SDRAM_TIMING_CTRL_HIGH_REG (DRAM_BASE + 0x140c)
- +#define SDRAM_TRFC_OFFS 0
- +#define SDRAM_TRFC_MASK (0x3F << SDRAM_TRFC_OFFS)
- +#define SDRAM_TR2R_OFFS 7
- +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
- +#define SDRAM_TR2W_W2R_OFFS 9
- +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
- +#define SDRAM_TW2W_OFFS 11
- +#define SDRAM_TW2W_MASK (0x3 << SDRAM_TW2W_OFFS)
- +
- +/* sdram DDR2 timing low register (SD2TLR) */
- +#define SDRAM_DDR2_TIMING_LO_REG (DRAM_BASE + 0x1428)
- +#define SD2TLR_TODT_ON_RD_OFFS 4
- +#define SD2TLR_TODT_ON_RD_MASK (0xF << SD2TLR_TODT_ON_RD_OFFS)
- +#define SD2TLR_TODT_OFF_RD_OFFS 8
- +#define SD2TLR_TODT_OFF_RD_MASK (0xF << SD2TLR_TODT_OFF_RD_OFFS)
- +#define SD2TLR_TODT_ON_CTRL_RD_OFFS 12
- +#define SD2TLR_TODT_ON_CTRL_RD_MASK (0xF << SD2TLR_TODT_ON_CTRL_RD_OFFS)
- +#define SD2TLR_TODT_OFF_CTRL_RD_OFFS 16
- +#define SD2TLR_TODT_OFF_CTRL_RD_MASK (0xF << SD2TLR_TODT_OFF_CTRL_RD_OFFS)
- +
- +/* sdram DDR2 timing high register (SD2TLR) */
- +#define SDRAM_DDR2_TIMING_HI_REG (DRAM_BASE + 0x147C)
- +#define SD2THR_TODT_ON_WR_OFFS 0
- +#define SD2THR_TODT_ON_WR_MASK (0xF << SD2THR_TODT_ON_WR_OFFS)
- +#define SD2THR_TODT_OFF_WR_OFFS 4
- +#define SD2THR_TODT_OFF_WR_MASK (0xF << SD2THR_TODT_OFF_WR_OFFS)
- +#define SD2THR_TODT_ON_CTRL_WR_OFFS 8
- +#define SD2THR_TODT_ON_CTRL_WR_MASK (0xF << SD2THR_TODT_ON_CTRL_WR_OFFS)
- +#define SD2THR_TODT_OFF_CTRL_WR_OFFS 12
- +#define SD2THR_TODT_OFF_CTRL_WR_MASK (0xF << SD2THR_TODT_OFF_CTRL_WR_OFFS)
- +
- +/* address control register */
- +#define SDRAM_ADDR_CTRL_REG (DRAM_BASE + 0x1410)
- +#define SDRAM_ADDRSEL_OFFS(cs) (4 * (cs))
- +#define SDRAM_ADDRSEL_MASK(cs) (0x3 << SDRAM_ADDRSEL_OFFS(cs))
- +#define SDRAM_ADDRSEL_X8(cs) (0x0 << SDRAM_ADDRSEL_OFFS(cs))
- +#define SDRAM_ADDRSEL_X16(cs) (0x1 << SDRAM_ADDRSEL_OFFS(cs))
- +#define SDRAM_DSIZE_OFFS(cs) (2 + 4 * (cs))
- +#define SDRAM_DSIZE_MASK(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
- +#define SDRAM_DSIZE_256Mb(cs) (0x1 << SDRAM_DSIZE_OFFS(cs))
- +#define SDRAM_DSIZE_512Mb(cs) (0x2 << SDRAM_DSIZE_OFFS(cs))
- +#define SDRAM_DSIZE_1Gb(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
- +#define SDRAM_DSIZE_2Gb(cs) (0x0 << SDRAM_DSIZE_OFFS(cs))
- +
- +/* SDRAM Open Pages Control registers */
- +#define SDRAM_OPEN_PAGE_CTRL_REG (DRAM_BASE + 0x1414)
- +#define SDRAM_OPEN_PAGE_EN (0 << 0)
- +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
- +
- +/* sdram opertion register */
- +#define SDRAM_OPERATION_REG (DRAM_BASE + 0x1418)
- +#define SDRAM_CMD_OFFS 0
- +#define SDRAM_CMD_MASK (0xF << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
- +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
- +
- +/* sdram mode register */
- +#define SDRAM_MODE_REG (DRAM_BASE + 0x141c)
- +#define SDRAM_BURST_LEN_OFFS 0
- +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
- +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
- +#define SDRAM_CL_OFFS 4
- +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
- +#define SDRAM_DDR2_CL_6 (0x6 << SDRAM_CL_OFFS)
- +
- +#define SDRAM_TM_OFFS 7
- +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
- +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
- +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
- +#define SDRAM_DLL_OFFS 8
- +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
- +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
- +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
- +#define SDRAM_WR_OFFS 9
- +#define SDRAM_WR_MAX 7
- +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
- +#define SDRAM_WR_2_CYC (1 << SDRAM_WR_OFFS)
- +#define SDRAM_WR_3_CYC (2 << SDRAM_WR_OFFS)
- +#define SDRAM_WR_4_CYC (3 << SDRAM_WR_OFFS)
- +#define SDRAM_WR_5_CYC (4 << SDRAM_WR_OFFS)
- +#define SDRAM_WR_6_CYC (5 << SDRAM_WR_OFFS)
- +#define SDRAM_PD_OFFS 12
- +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
- +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
- +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
- +
- +/* DDR SDRAM Extended Mode register (DSEMR) */
- +#define SDRAM_EXTENDED_MODE_REG (DRAM_BASE + 0x1420)
- +#define DSEMR_DLL_ENABLE 0
- +#define DSEMR_DLL_DISABLE 1
- +#define DSEMR_DS_OFFS 1
- +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
- +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
- +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
- +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
- +#define DSEMR_RTT0_OFFS 2
- +#define DSEMR_RTT1_OFFS 6
- +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
- +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
- +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
- +#define DSEMR_RTT_ODT_50_OHM ((1 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
- +#define DSEMR_DQS_OFFS 10
- +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
- +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
- +#define DSEMR_DQS_SINGLE_ENDED (1 << DSEMR_DQS_OFFS)
- +#define DSEMR_RDQS_ENABLE (1 << 11)
- +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
- +#define DSEMR_QOFF_OUTPUT_BUFF_DIS (1 << 12)
- +
- +/* DDR SDRAM Operation Control Register */
- +#define SDRAM_OPERATION_CTRL_REG (DRAM_BASE + 0x142c)
- +
- +/* Dunit FTDLL Configuration Register */
- +#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE + 0x1484)
- +#define SDRAM_FTDLL_CONFIG_RIGHT_REG (DRAM_BASE + 0x161C)
- +#define SDRAM_FTDLL_CONFIG_UP_REG (DRAM_BASE + 0x1620)
- +
- +/* Pads Calibration register */
- +#define SDRAM_ADDR_CTRL_PADS_CAL_REG (DRAM_BASE + 0x14c0)
- +#define SDRAM_DATA_PADS_CAL_REG (DRAM_BASE + 0x14c4)
- +#define SDRAM_DRVN_OFFS 0
- +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
- +#define SDRAM_DRVP_OFFS 6
- +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
- +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
- +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
- +#define SDRAM_TUNE_EN BIT16
- +#define SDRAM_LOCKN_OFFS 17
- +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
- +#define SDRAM_LOCKP_OFFS 23
- +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
- +#define SDRAM_WR_EN (1 << 31)
- +
- +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
- +#define DDR2_SDRAM_ODT_CTRL_LOW_REG (DRAM_BASE + 0x1494)
- +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
- +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
- +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
- +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
- +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
- +#define DSOCLR_ODT_WR(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
- +
- +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
- +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG (DRAM_BASE + 0x1498)
- +/* Optional control values to DSOCHR_ODT_EN macro */
- +#define DDR2_ODT_CTRL_DUNIT 0
- +#define DDR2_ODT_CTRL_NEVER 1
- +#define DDR2_ODT_CTRL_ALWAYS 3
- +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
- +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
- +#define DSOCHR_ODT_EN(odtNum, ctrl) (ctrl << DSOCHR_ODT_EN_OFFS(odtNum))
- +
- +/* DDR2 Dunit ODT Control Register (DDOCR)*/
- +#define DDR2_DUNIT_ODT_CONTROL_REG (DRAM_BASE + 0x149c)
- +#define DDOCR_ODT_RD_OFFS 0
- +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
- +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
- +#define DDOCR_ODT_WR_OFFS 4
- +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
- +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
- +#define DSOCR_ODT_EN_OFFS 8
- +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
- +/* For ctrl parameters see DDR2 SDRAM ODT Control (High) Register (0x1498) above. */
- +#define DSOCR_ODT_EN(ctrl) (ctrl << DSOCR_ODT_EN_OFFS)
- +#define DSOCR_ODT_SEL_DISABLE 0
- +#define DSOCR_ODT_SEL_75_OHM 2
- +#define DSOCR_ODT_SEL_150_OHM 1
- +#define DSOCR_ODT_SEL_50_OHM 3
- +#define DSOCR_DQ_ODT_SEL_OFFS 10
- +#define DSOCR_DQ_ODT_SEL_MASK (0x3 << DSOCR_DQ_ODT_SEL_OFFS)
- +#define DSOCR_DQ_ODT_SEL(odtSel) (odtSel << DSOCR_DQ_ODT_SEL_OFFS)
- +#define DSOCR_ST_ODT_SEL_OFFS 12
- +#define DSOCR_ST_ODT_SEL_MASK (0x3 << DSOCR_ST_ODT_SEL_OFFS)
- +#define DSOCR_ST_ODT_SEL(odtSel) (odtSel << DSOCR_ST_ODT_SEL_OFFS)
- +#define DSOCR_ST_ODT_EN (1 << 14)
- +
- +/* DDR SDRAM Initialization Control Register (DSICR) */
- +#define DDR_SDRAM_INIT_CTRL_REG (DRAM_BASE + 0x1480)
- +#define DSICR_INIT_EN (1 << 0)
- +#define DSICR_T200_SET (1 << 8)
- +
- +/* sdram extended mode2 register (SEM2R) */
- +#define SDRAM_EXTENDED_MODE2_REG (DRAM_BASE + 0x148C)
- +#define SEM2R_EMRS2_DDR2_OFFS 0
- +#define SEM2R_EMRS2_DDR2_MASK (0x7FFF << SEM2R_EMRS2_DDR2_OFFS)
- +
- +/* sdram extended mode3 register (SEM3R) */
- +#define SDRAM_EXTENDED_MODE3_REG (DRAM_BASE + 0x1490)
- +#define SEM3R_EMRS3_DDR2_OFFS 0
- +#define SEM3R_EMRS3_DDR2_MASK (0x7FFF << SEM3R_EMRS3_DDR2_OFFS)
- +
- +/* sdram error registers */
- +#define SDRAM_ERROR_CAUSE_REG (DRAM_BASE + 0x14d0)
- +#define SDRAM_ERROR_MASK_REG (DRAM_BASE + 0x14d4)
- +#define SDRAM_ERROR_DATA_LOW_REG (DRAM_BASE + 0x1444)
- +#define SDRAM_ERROR_DATA_HIGH_REG (DRAM_BASE + 0x1440)
- +#define SDRAM_ERROR_ADDR_REG (DRAM_BASE + 0x1450)
- +#define SDRAM_ERROR_ECC_REG (DRAM_BASE + 0x1448)
- +#define SDRAM_CALC_ECC_REG (DRAM_BASE + 0x144c)
- +#define SDRAM_ECC_CONTROL_REG (DRAM_BASE + 0x1454)
- +#define SDRAM_SINGLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x1458)
- +#define SDRAM_DOUBLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x145c)
- +
- +/* SDRAM Error Cause Register (SECR) */
- +#define SECR_SINGLE_BIT_ERR BIT0
- +#define SECR_DOUBLE_BIT_ERR BIT1
- +#define SECR_DATA_PATH_PARITY_ERR BIT2
- +/* SDRAM Error Address Register (SEAR) */
- +#define SEAR_ERR_TYPE_OFFS 0
- +#define SEAR_ERR_TYPE_MASK (1 << SEAR_ERR_TYPE_OFFS)
- +#define SEAR_ERR_TYPE_SINGLE 0
- +#define SEAR_ERR_TYPE_DOUBLE (1 << SEAR_ERR_TYPE_OFFS)
- +#define SEAR_ERR_CS_OFFS 1
- +#define SEAR_ERR_CS_MASK (3 << SEAR_ERR_CS_OFFS)
- +#define SEAR_ERR_CS(csNum) (csNum << SEAR_ERR_CS_OFFS)
- +#define SEAR_ERR_ADDR_OFFS 3
- +#define SEAR_ERR_ADDR_MASK (0x1FFFFFFF << SEAR_ERR_ADDR_OFFS)
- +
- +/* SDRAM ECC Control Register (SECR) */
- +#define SECR_FORCEECC_OFFS 0
- +#define SECR_FORCEECC_MASK (0xFF << SECR_FORCEECC_OFFS)
- +#define SECR_FORCEEN_OFFS 8
- +#define SECR_FORCEEN_MASK (1 << SECR_FORCEEN_OFFS)
- +#define SECR_ECC_CALC_MASK (0 << SECR_FORCEEN_OFFS)
- +#define SECR_ECC_USER_MASK (1 << SECR_FORCEEN_OFFS)
- +#define SECR_PERRPROP_EN BIT9
- +#define SECR_CNTMODE_OFFS 10
- +#define SECR_CNTMODE_MASK (1 << SECR_CNTMODE_OFFS)
- +#define SECR_ALL_IN_CS0 (0 << SECR_CNTMODE_OFFS)
- +#define SECR_NORMAL_COUNTER (1 << SECR_CNTMODE_OFFS)
- +#define SECR_THRECC_OFFS 16
- +#define SECR_THRECC_MAX 0xFF
- +#define SECR_THRECC_MASK (SECR_THRECC_MAX << SECR_THRECC_OFFS)
- +#define SECR_THRECC(threshold) (threshold << SECR_THRECC_OFFS)
- +
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvDramIfRegsh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 2010-11-09 20:28:10.962495352 +0100
- @@ -0,0 +1,179 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvDramIfStaticInith
- +#define __INCmvDramIfStaticInith
- +
- +#ifdef MV_STATIC_DRAM_ON_BOARD
- +#define STATIC_DRAM_BANK_1
- +#undef STATIC_DRAM_BANK_2
- +#undef STATIC_DRAM_BANK_3
- +#undef STATIC_DRAM_BANK_4
- +
- +
- +#ifdef MV_DIMM_TS256MLQ72V5U
- +#define STATIC_DRAM_BANK_2
- +#define STATIC_DRAM_BANK_3
- +#undef STATIC_DRAM_BANK_4
- +
- +#define STATIC_SDRAM_CONFIG_REG 0x4724481A /* offset 0x1400 - DMA reg-0xf1000814 */
- +#define STATIC_SDRAM_DUNIT_CTRL_REG 0x37707450 /* offset 0x1404 - DMA reg-0xf100081c */
- +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11A13330 /* offset 0x1408 - DMA reg-0xf1000824 */
- +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000601 /* offset 0x140c - DMA reg-0xf1000828 */
- +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00001CB2 /* offset 0x1410 - DMA reg-0xf1000820 */
- +#define STATIC_SDRAM_MODE_REG 0x00000642 /* offset 0x141c - DMA reg-0xf1000818 */
- +#define STATIC_SDRAM_ODT_CTRL_LOW 0x030C030C /* 0x1494 */
- +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
- +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000740F /* 0x149c */
- +#define STATIC_SDRAM_EXT_MODE 0x00000404 /* 0x1420 */
- +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00074410 /* 0x1428 */
- +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00007441 /* 0x147C */
- +
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x3FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
- +#define STATIC_SDRAM_RANK1_SIZE_DIMM0 0x3FFF /* size bank1 dimm0 */
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x3FFF /* size bank0 dimm1 */
- +#define STATIC_SDRAM_RANK1_SIZE_DIMM1 0x0 /* size bank1 dimm1 */
- +
- +#endif /* TS256MLQ72V5U */
- +
- +
- +#ifdef MV_MT9VDDT3272AG
- +/* one DIMM 256M */
- +#define STATIC_SDRAM_CONFIG_REG 0x5820040d /* offset 0x1400 - DMA reg-0xf1000814 */
- +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC4000540 /* offset 0x1404 - DMA reg-0xf100081c */
- +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01602220 /* offset 0x1408 - DMA reg-0xf1000824 */
- +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x0000000b /* offset 0x140c - DMA reg-0xf1000828 */
- +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
- +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0 /* size bank0 dimm1 */
- +
- +#endif /* MV_MT9VDDT3272AG */
- +
- +
- +
- +#ifdef MV_D27RB12P
- +/*
- +Two DIMM 512M + ECC enabled, Registered DIMM CAS Latency 2.5
- +*/
- +
- +#define STATIC_SDRAM_CONFIG_REG 0x6826081E /* offset 0x1400 - DMA reg-0xf1000814 */
- +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC5000540 /* offset 0x1404 - DMA reg-0xf100081c */
- +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01501220 /* offset 0x1408 - DMA reg-0xf1000824 */
- +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000009 /* offset 0x140c - DMA reg-0xf1000828 */
- +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
- +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0FFF /* size bank0 dimm1 */
- +
- +#define STATIC_DRAM_BANK_2
- +
- +#define STATIC_DRAM_BANK_3
- +#define STATIC_DRAM_BANK_4
- +
- +#endif /* mv_D27RB12P */
- +
- +#ifdef RD_MV645XX
- +
- +#define STATIC_MEM_TYPE MEM_TYPE_DDR2
- +#define STATIC_DIMM_INFO_BANK0_SIZE 256
- +/* DDR2 boards 256 MB*/
- +
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
- +#define STATIC_SDRAM_CONFIG_REG 0x07190618
- +#define STATIC_SDRAM_MODE_REG 0x00000432
- +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440
- +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022
- +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220
- +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504
- +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000
- +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000
- +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f
- +#define STATIC_SDRAM_EXT_MODE 0x00000440
- +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300
- +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330
- +#endif /* RD_MV645XX */
- +
- +#if MV_DIMM_M3783354CZ3_CE6
- +
- +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000FFF /* 0x2010 size bank0 dimm0 - DMA reg-0xf1000810 */
- +#define STATIC_SDRAM_CONFIG_REG 0x07190618 /* 0x1400 */
- +#define STATIC_SDRAM_MODE_REG 0x00000432 /* 0x141c */
- +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440 /* 0x1404 */
- +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022 /* 0x1410 */
- +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220 /* 0x1408 */
- +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504 /* 0x140c */
- +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000 /* 0x1494 */
- +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
- +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f /* 0x149c */
- +#define STATIC_SDRAM_EXT_MODE 0x00000440 /* 0x1420 */
- +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300 /* 0x1428 */
- +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330 /* 0x147C */
- +
- +#endif /* MV_DIMM_M3783354CZ3_CE6 */
- +
- +#endif /* MV_STATIC_DRAM_ON_BOARD */
- +#endif /* __INCmvDramIfStaticInith */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 2010-11-09 20:28:11.002495540 +0100
- @@ -0,0 +1,1474 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "ddr2/spd/mvSpd.h"
- +#include "boardEnv/mvBoardEnvLib.h"
- +
- +/* #define MV_DEBUG */
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
- + MV_DRAM_BANK_INFO *pBankInfo);
- +static MV_U32 cas2ps(MV_U8 spd_byte);
- +/*******************************************************************************
- +* mvDramBankGet - Get the DRAM bank paramters.
- +*
- +* DESCRIPTION:
- +* This function retrieves DRAM bank parameters as described in
- +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
- +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
- +* from it. Otherwise, if the DRAM is soldered on board, the function
- +* should insert its bank information into MV_DRAM_BANK_INFO struct.
- +*
- +* INPUT:
- +* bankNum - Board DRAM bank number.
- +*
- +* OUTPUT:
- +* pBankInfo - DRAM bank information struct.
- +*
- +* RETURN:
- +* MV_FAIL - Bank parameters could not be read.
- +*
- +*******************************************************************************/
- +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + MV_DIMM_INFO dimmInfo;
- +
- + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
- + /* zero pBankInfo structure */
- +
- + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
- + {
- + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
- + return MV_BAD_PARAM;
- + }
- + memset(pBankInfo, 0, sizeof(*pBankInfo));
- +
- + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
- + {
- + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
- + return MV_FAIL;
- + }
- + if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
- + {
- + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
- + return MV_FAIL;
- + }
- + /* convert Dimm info to Bank info */
- + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
- +*
- +* DESCRIPTION:
- +* Convert a Dimm info struct into a bank info struct.
- +*
- +* INPUT:
- +* pDimmInfo - DIMM information structure.
- +*
- +* OUTPUT:
- +* pBankInfo - DRAM bank information struct.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
- + MV_DRAM_BANK_INFO *pBankInfo)
- +{
- + pBankInfo->memoryType = pDimmInfo->memoryType;
- +
- + /* DIMM dimensions */
- + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
- + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
- + pBankInfo->dataWidth = pDimmInfo->dataWidth;
- + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
- + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
- + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
- + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
- + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
- + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
- +
- + /* DIMM timing parameters */
- + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
- + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
- + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
- +
- + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
- + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
- + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
- + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
- + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
- + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
- + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
- + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
- +
- + /* Parameters calculated from the extracted DIMM information */
- + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
- + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
- + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
- + pDimmInfo->numOfModuleBanks;
- +
- + /* DIMM attributes (MV_TRUE for yes) */
- +
- + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
- + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
- + {
- + if (pDimmInfo->dimmAttributes & BIT1)
- + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
- + else
- + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
- + }
- + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
- + {
- + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
- + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
- + else
- + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
- + }
- +
- + return;
- +}
- +/*******************************************************************************
- +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
- +*
- +* DESCRIPTION:
- +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS dimmSpdCpy(MV_VOID)
- +{
- + MV_U32 i;
- + MV_U32 spdChecksum;
- +
- + MV_TWSI_SLAVE twsiSlave;
- + MV_U8 data[SPD_SIZE];
- +
- + /* zero dimmInfo structure */
- + memset(data, 0, SPD_SIZE);
- +
- + /* read the dimm eeprom */
- + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
- + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + twsiSlave.offset = 0;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
- + {
- + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
- + return MV_FAIL;
- + }
- + DB(puts("DRAM: Reading dimm info succeded.\n"));
- +
- + /* calculate SPD checksum */
- + spdChecksum = 0;
- +
- + for(i = 0 ; i <= 62 ; i++)
- + {
- + spdChecksum += data[i];
- + }
- +
- + if ((spdChecksum & 0xff) != data[63])
- + {
- + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
- + (MV_U32)(spdChecksum & 0xff), data[63]));
- + }
- + else
- + {
- + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
- + }
- +
- + /* copy the SPD content 1:1 into the DIMM 1 SPD */
- + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + twsiSlave.offset = 0;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + for(i = 0 ; i < SPD_SIZE ; i++)
- + {
- + twsiSlave.offset = i;
- + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
- + {
- + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
- + return MV_FAIL;
- + }
- + mvOsDelay(5);
- + }
- +
- + DB(puts("DRAM: Reading dimm info succeded.\n"));
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* dimmSpdGet - Get the SPD parameters.
- +*
- +* DESCRIPTION:
- +* Read the DIMM SPD parameters into given struct parameter.
- +*
- +* INPUT:
- +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
- +*
- +* OUTPUT:
- +* pDimmInfo - DIMM information structure.
- +*
- +* RETURN:
- +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
- +{
- + MV_U32 i;
- + MV_U32 density = 1;
- + MV_U32 spdChecksum;
- +
- + MV_TWSI_SLAVE twsiSlave;
- + MV_U8 data[SPD_SIZE];
- +
- + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
- + {
- + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
- + return MV_BAD_PARAM;
- + }
- +
- + /* zero dimmInfo structure */
- + memset(data, 0, SPD_SIZE);
- +
- + /* read the dimm eeprom */
- + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
- + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
- + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
- + twsiSlave.slaveAddr.type = ADDR7_BIT;
- + twsiSlave.validOffset = MV_TRUE;
- + twsiSlave.offset = 0;
- + twsiSlave.moreThen256 = MV_FALSE;
- +
- + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
- + {
- + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
- + return MV_FAIL;
- + }
- + DB(puts("DRAM: Reading dimm info succeded.\n"));
- +
- + /* calculate SPD checksum */
- + spdChecksum = 0;
- +
- + for(i = 0 ; i <= 62 ; i++)
- + {
- + spdChecksum += data[i];
- + }
- +
- + if ((spdChecksum & 0xff) != data[63])
- + {
- + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
- + (MV_U32)(spdChecksum & 0xff), data[63]));
- + }
- + else
- + {
- + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
- + }
- +
- + /* copy the SPD content 1:1 into the dimmInfo structure*/
- + for(i = 0 ; i < SPD_SIZE ; i++)
- + {
- + pDimmInfo->spdRawData[i] = data[i];
- + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
- + }
- +
- + DB(mvOsPrintf("DRAM SPD Information:\n"));
- +
- + /* Memory type (DDR / SDRAM) */
- + switch (data[DIMM_MEM_TYPE])
- + {
- + case (DIMM_MEM_TYPE_SDRAM):
- + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
- + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
- + break;
- + case (DIMM_MEM_TYPE_DDR1):
- + pDimmInfo->memoryType = MEM_TYPE_DDR1;
- + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
- + break;
- + case (DIMM_MEM_TYPE_DDR2):
- + pDimmInfo->memoryType = MEM_TYPE_DDR2;
- + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
- + break;
- + default:
- + mvOsPrintf("ERROR: Undefined memory type!\n");
- + return MV_ERROR;
- + }
- +
- +
- + /* Number Of Row Addresses */
- + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
- + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
- +
- + /* Number Of Column Addresses */
- + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
- + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
- +
- + /* Number Of Module Banks */
- + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
- + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
- + pDimmInfo->numOfModuleBanks));
- +
- + /* Number of module banks encoded differently for DDR2 */
- + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
- + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
- +
- + /* Data Width */
- + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
- + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
- +
- + /* Minimum Cycle Time At Max CasLatancy */
- + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
- +
- + /* Error Check Type */
- + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
- + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
- + pDimmInfo->errorCheckType));
- +
- + /* Refresh Interval */
- + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
- + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
- + pDimmInfo->refreshInterval));
- +
- + /* Sdram Width */
- + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
- + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
- +
- + /* Error Check Data Width */
- + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
- + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
- + pDimmInfo->errorCheckDataWidth));
- +
- + /* Burst Length Supported */
- + /* SDRAM/DDR1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
- + *********************************************************/
- + /* DDR2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
- + *********************************************************/
- +
- + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
- + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
- + pDimmInfo->burstLengthSupported));
- +
- + /* Number Of Banks On Each Device */
- + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
- + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
- + pDimmInfo->numOfBanksOnEachDevice));
- +
- + /* Suported Cas Latencies */
- +
- + /* SDRAM:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
- + ********************************************************/
- +
- + /* DDR 1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
- + *********************************************************/
- +
- + /* DDR 2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
- + *********************************************************/
- +
- + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
- + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
- + pDimmInfo->suportedCasLatencies));
- +
- + /* For DDR2 only, get the DIMM type information */
- + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
- + {
- + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
- + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
- + pDimmInfo->dimmTypeInfo));
- + }
- +
- + /* SDRAM Modules Attributes */
- + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
- + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
- + pDimmInfo->dimmAttributes));
- +
- + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
- + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
- +
- + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
- + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
- + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
- +
- + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
- + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
- + pDimmInfo->minRowPrechargeTime));
- + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
- + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
- + pDimmInfo->minRowActiveToRowActive));
- + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
- + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
- + pDimmInfo->minRasToCasDelay));
- + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
- + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
- + pDimmInfo->minRasPulseWidth));
- +
- + /* DIMM Bank Density */
- + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
- + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
- + pDimmInfo->dimmBankDensity));
- +
- + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
- + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
- + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
- + pDimmInfo->minWriteRecoveryTime));
- +
- + /* Only DDR2 includes Internal Write To Read Command Delay field. */
- + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
- + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
- + pDimmInfo->minWriteToReadCmdDelay));
- +
- + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
- + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
- + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
- + pDimmInfo->minReadToPrechCmdDelay));
- +
- + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
- + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
- + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
- + pDimmInfo->minRefreshToActiveCmd));
- +
- + /* calculating the sdram density. Representing device density from */
- + /* bit 20 to allow representation of 4GB and above. */
- + /* For example, if density is 512Mbit 0x20000000, will be represent in */
- + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
- + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
- + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
- + pDimmInfo->deviceDensity = density *
- + pDimmInfo->numOfBanksOnEachDevice *
- + pDimmInfo->sdramWidth;
- + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
- +
- + /* Number of devices includeing Error correction */
- + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
- + pDimmInfo->numOfModuleBanks;
- + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
- + pDimmInfo->numberOfDevices));
- +
- + pDimmInfo->size = 0;
- +
- + /* Note that pDimmInfo->size is in MB units */
- + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
- + {
- + if (pDimmInfo->dimmBankDensity & BIT0)
- + pDimmInfo->size += 1024; /* Equal to 1GB */
- + else if (pDimmInfo->dimmBankDensity & BIT1)
- + pDimmInfo->size += 8; /* Equal to 8MB */
- + else if (pDimmInfo->dimmBankDensity & BIT2)
- + pDimmInfo->size += 16; /* Equal to 16MB */
- + else if (pDimmInfo->dimmBankDensity & BIT3)
- + pDimmInfo->size += 32; /* Equal to 32MB */
- + else if (pDimmInfo->dimmBankDensity & BIT4)
- + pDimmInfo->size += 64; /* Equal to 64MB */
- + else if (pDimmInfo->dimmBankDensity & BIT5)
- + pDimmInfo->size += 128; /* Equal to 128MB */
- + else if (pDimmInfo->dimmBankDensity & BIT6)
- + pDimmInfo->size += 256; /* Equal to 256MB */
- + else if (pDimmInfo->dimmBankDensity & BIT7)
- + pDimmInfo->size += 512; /* Equal to 512MB */
- + }
- + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
- + {
- + if (pDimmInfo->dimmBankDensity & BIT0)
- + pDimmInfo->size += 1024; /* Equal to 1GB */
- + else if (pDimmInfo->dimmBankDensity & BIT1)
- + pDimmInfo->size += 2048; /* Equal to 2GB */
- + else if (pDimmInfo->dimmBankDensity & BIT2)
- + pDimmInfo->size += 16; /* Equal to 16MB */
- + else if (pDimmInfo->dimmBankDensity & BIT3)
- + pDimmInfo->size += 32; /* Equal to 32MB */
- + else if (pDimmInfo->dimmBankDensity & BIT4)
- + pDimmInfo->size += 64; /* Equal to 64MB */
- + else if (pDimmInfo->dimmBankDensity & BIT5)
- + pDimmInfo->size += 128; /* Equal to 128MB */
- + else if (pDimmInfo->dimmBankDensity & BIT6)
- + pDimmInfo->size += 256; /* Equal to 256MB */
- + else if (pDimmInfo->dimmBankDensity & BIT7)
- + pDimmInfo->size += 512; /* Equal to 512MB */
- + }
- + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
- + {
- + if (pDimmInfo->dimmBankDensity & BIT0)
- + pDimmInfo->size += 1024; /* Equal to 1GB */
- + else if (pDimmInfo->dimmBankDensity & BIT1)
- + pDimmInfo->size += 2048; /* Equal to 2GB */
- + else if (pDimmInfo->dimmBankDensity & BIT2)
- + pDimmInfo->size += 4096; /* Equal to 4GB */
- + else if (pDimmInfo->dimmBankDensity & BIT3)
- + pDimmInfo->size += 8192; /* Equal to 8GB */
- + else if (pDimmInfo->dimmBankDensity & BIT4)
- + pDimmInfo->size += 16384; /* Equal to 16GB */
- + else if (pDimmInfo->dimmBankDensity & BIT5)
- + pDimmInfo->size += 128; /* Equal to 128MB */
- + else if (pDimmInfo->dimmBankDensity & BIT6)
- + pDimmInfo->size += 256; /* Equal to 256MB */
- + else if (pDimmInfo->dimmBankDensity & BIT7)
- + pDimmInfo->size += 512; /* Equal to 512MB */
- + }
- +
- + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
- +
- + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* dimmSpdPrint - Print the SPD parameters.
- +*
- +* DESCRIPTION:
- +* Print the Dimm SPD parameters.
- +*
- +* INPUT:
- +* pDimmInfo - DIMM information structure.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
- +{
- + MV_DIMM_INFO dimmInfo;
- + MV_U32 i, temp = 0;
- + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
- + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
- + MV_U32 busClkPs;
- + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
- + temp_buf[40], *spdRawData;
- +
- + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
- +
- + spdRawData = dimmInfo.spdRawData;
- +
- + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
- + {
- + mvOsOutput("ERROR: Could not read SPD information!\n");
- + return;
- + }
- +
- + /* find Manufactura of Dimm Module */
- + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
- + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
- + {
- + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
- + }
- + mvOsOutput("\n");
- +
- + /* Manufacturer's Specific Data */
- + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
- + {
- + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
- + }
- + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
- +
- + /* Module Part Number */
- + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
- + {
- + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
- + }
- + mvOsOutput("Module Part Number: %s\n", temp_buf);
- +
- + /* Module Serial Number */
- + for(i = 0; i < sizeof(MV_U32); i++)
- + {
- + temp |= spdRawData[95+i] << 8*i;
- + }
- + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
- + (long)temp);
- +
- + /* find Manufac-Data of Dimm Module */
- + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
- + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
- + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
- + /* find modul_revision of Dimm Module */
- + mvOsOutput("Module Revision: %d.%d\n",
- + spdRawData[62]/10, spdRawData[62]%10);
- +
- + /* find manufac_place of Dimm Module */
- + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
- +
- + /* go over the first 35 I2C data bytes */
- + for(i = 2 ; i <= 35 ; i++)
- + switch(i)
- + {
- + case 2: /* Memory type (DDR1/2 / SDRAM) */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + mvOsOutput("Dram Type is: SDRAM\n");
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + mvOsOutput("Dram Type is: SDRAM DDR1\n");
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + mvOsOutput("Dram Type is: SDRAM DDR2\n");
- + else
- + mvOsOutput("Dram Type unknown\n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 3: /* Number Of Row Addresses */
- + mvOsOutput("Module Number of row addresses: %d\n",
- + dimmInfo.numOfRowAddr);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 4: /* Number Of Column Addresses */
- + mvOsOutput("Module Number of col addresses: %d\n",
- + dimmInfo.numOfColAddr);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 5: /* Number Of Module Banks */
- + mvOsOutput("Number of Banks on Mod.: %d\n",
- + dimmInfo.numOfModuleBanks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 6: /* Data Width */
- + mvOsOutput("Module Data Width: %d bit\n",
- + dimmInfo.dataWidth);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 8: /* Voltage Interface */
- + switch(spdRawData[i])
- + {
- + case 0x0:
- + mvOsOutput("Module is TTL_5V_TOLERANT\n");
- + break;
- + case 0x1:
- + mvOsOutput("Module is LVTTL\n");
- + break;
- + case 0x2:
- + mvOsOutput("Module is HSTL_1_5V\n");
- + break;
- + case 0x3:
- + mvOsOutput("Module is SSTL_3_3V\n");
- + break;
- + case 0x4:
- + mvOsOutput("Module is SSTL_2_5V\n");
- + break;
- + case 0x5:
- + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
- + {
- + mvOsOutput("Module is SSTL_1_8V\n");
- + break;
- + }
- + default:
- + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
- + break;
- + }
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 9: /* Minimum Cycle Time At Max CasLatancy */
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
- +
- + /* DDR2 addition of right of point */
- + if ((spdRawData[i] & 0x0f) == 0xA)
- + {
- + rightOfPoint = 25;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xB)
- + {
- + rightOfPoint = 33;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xC)
- + {
- + rightOfPoint = 66;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xD)
- + {
- + rightOfPoint = 75;
- + }
- + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 10: /* Clock To Data Out */
- + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / div;
- + rightOfPoint = time_tmp % div;
- + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 11: /* Error Check Type */
- + mvOsOutput("Error Check Type (0=NONE): %d\n",
- + dimmInfo.errorCheckType);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 12: /* Refresh Interval */
- + mvOsOutput("Refresh Rate: %x\n",
- + dimmInfo.refreshInterval);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 13: /* Sdram Width */
- + mvOsOutput("Sdram Width: %d bits\n",
- + dimmInfo.sdramWidth);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 14: /* Error Check Data Width */
- + mvOsOutput("Error Check Data Width: %d bits\n",
- + dimmInfo.errorCheckDataWidth);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 15: /* Minimum Clock Delay is unsupported */
- + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
- + (dimmInfo.memoryType == MEM_TYPE_DDR1))
- + {
- + mvOsOutput("Minimum Clk Delay back to back: %d\n",
- + spdRawData[i]);
- + }
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 16: /* Burst Length Supported */
- + /* SDRAM/DDR1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
- + *********************************************************/
- + /* DDR2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
- + *********************************************************/
- + mvOsOutput("Burst Length Supported: ");
- + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
- + (dimmInfo.memoryType == MEM_TYPE_DDR1))
- + {
- + if (dimmInfo.burstLengthSupported & BIT0)
- + mvOsOutput("1, ");
- + if (dimmInfo.burstLengthSupported & BIT1)
- + mvOsOutput("2, ");
- + }
- + if (dimmInfo.burstLengthSupported & BIT2)
- + mvOsOutput("4, ");
- + if (dimmInfo.burstLengthSupported & BIT3)
- + mvOsOutput("8, ");
- +
- + mvOsOutput(" Bit \n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 17: /* Number Of Banks On Each Device */
- + mvOsOutput("Number Of Banks On Each Chip: %d\n",
- + dimmInfo.numOfBanksOnEachDevice);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 18: /* Suported Cas Latencies */
- +
- + /* SDRAM:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
- + ********************************************************/
- +
- + /* DDR 1:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
- + *********************************************************/
- +
- + /* DDR 2:
- + *******-******-******-******-******-******-******-*******
- + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- + *******-******-******-******-******-******-******-*******
- + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
- + *********************************************************/
- +
- + mvOsOutput("Suported Cas Latencies: (CL) ");
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + for (k = 0; k <=7; k++)
- + {
- + if (dimmInfo.suportedCasLatencies & (1 << k))
- + mvOsOutput("%d, ", k+1);
- + }
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if (dimmInfo.suportedCasLatencies & BIT0)
- + mvOsOutput("1, ");
- + if (dimmInfo.suportedCasLatencies & BIT1)
- + mvOsOutput("1.5, ");
- + if (dimmInfo.suportedCasLatencies & BIT2)
- + mvOsOutput("2, ");
- + if (dimmInfo.suportedCasLatencies & BIT3)
- + mvOsOutput("2.5, ");
- + if (dimmInfo.suportedCasLatencies & BIT4)
- + mvOsOutput("3, ");
- + if (dimmInfo.suportedCasLatencies & BIT5)
- + mvOsOutput("3.5, ");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + {
- + if (dimmInfo.suportedCasLatencies & BIT2)
- + mvOsOutput("2, ");
- + if (dimmInfo.suportedCasLatencies & BIT3)
- + mvOsOutput("3, ");
- + if (dimmInfo.suportedCasLatencies & BIT4)
- + mvOsOutput("4, ");
- + if (dimmInfo.suportedCasLatencies & BIT5)
- + mvOsOutput("5, ");
- + }
- + else
- + mvOsOutput("?.?, ");
- + mvOsOutput("\n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 20: /* DDR2 DIMM type info */
- + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + {
- + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
- + mvOsOutput("Registered DIMM (RDIMM)\n");
- + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
- + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
- + else
- + mvOsOutput("Unknown DIMM type.\n");
- + }
- +
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 21: /* SDRAM Modules Attributes */
- + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
- +
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + if (dimmInfo.dimmAttributes & BIT0)
- + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Buffered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT1)
- + mvOsOutput(" Registered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Registered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT2)
- + mvOsOutput(" On-Card PLL (clock): Yes \n");
- + else
- + mvOsOutput(" On-Card PLL (clock): No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT3)
- + mvOsOutput(" Bufferd DQMB Input: Yes \n");
- + else
- + mvOsOutput(" Bufferd DQMB Inputs: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT4)
- + mvOsOutput(" Registered DQMB Inputs: Yes \n");
- + else
- + mvOsOutput(" Registered DQMB Inputs: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT5)
- + mvOsOutput(" Differential Clock Input: Yes \n");
- + else
- + mvOsOutput(" Differential Clock Input: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT6)
- + mvOsOutput(" redundant Row Addressing: Yes \n");
- + else
- + mvOsOutput(" redundant Row Addressing: No \n");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if (dimmInfo.dimmAttributes & BIT0)
- + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Buffered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT1)
- + mvOsOutput(" Registered Addr/Control Input: Yes\n");
- + else
- + mvOsOutput(" Registered Addr/Control Input: No\n");
- +
- + if (dimmInfo.dimmAttributes & BIT2)
- + mvOsOutput(" On-Card PLL (clock): Yes \n");
- + else
- + mvOsOutput(" On-Card PLL (clock): No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT3)
- + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
- + else
- + mvOsOutput(" FET Switch On-Card Enabled: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT4)
- + mvOsOutput(" FET Switch External Enabled: Yes \n");
- + else
- + mvOsOutput(" FET Switch External Enabled: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT5)
- + mvOsOutput(" Differential Clock Input: Yes \n");
- + else
- + mvOsOutput(" Differential Clock Input: No \n");
- + }
- + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
- + {
- + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
- + (dimmInfo.dimmAttributes & 0x3) + 1);
- +
- + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
- + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
- +
- + if (dimmInfo.dimmAttributes & BIT4)
- + mvOsOutput(" FET Switch External Enabled: Yes \n");
- + else
- + mvOsOutput(" FET Switch External Enabled: No \n");
- +
- + if (dimmInfo.dimmAttributes & BIT6)
- + mvOsOutput(" Analysis probe installed: Yes \n");
- + else
- + mvOsOutput(" Analysis probe installed: No \n");
- + }
- +
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 22: /* Suported AutoPreCharge */
- + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + if ( spdRawData[i] & BIT0 )
- + mvOsOutput(" Early Ras Precharge: Yes \n");
- + else
- + mvOsOutput(" Early Ras Precharge: No \n");
- +
- + if ( spdRawData[i] & BIT1 )
- + mvOsOutput(" AutoPreCharge: Yes \n");
- + else
- + mvOsOutput(" AutoPreCharge: No \n");
- +
- + if ( spdRawData[i] & BIT2 )
- + mvOsOutput(" Precharge All: Yes \n");
- + else
- + mvOsOutput(" Precharge All: No \n");
- +
- + if ( spdRawData[i] & BIT3 )
- + mvOsOutput(" Write 1/ReadBurst: Yes \n");
- + else
- + mvOsOutput(" Write 1/ReadBurst: No \n");
- +
- + if ( spdRawData[i] & BIT4 )
- + mvOsOutput(" lower VCC tolerance: 5%%\n");
- + else
- + mvOsOutput(" lower VCC tolerance: 10%%\n");
- +
- + if ( spdRawData[i] & BIT5 )
- + mvOsOutput(" upper VCC tolerance: 5%%\n");
- + else
- + mvOsOutput(" upper VCC tolerance: 10%%\n");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if ( spdRawData[i] & BIT0 )
- + mvOsOutput(" Supports Weak Driver: Yes \n");
- + else
- + mvOsOutput(" Supports Weak Driver: No \n");
- +
- + if ( !(spdRawData[i] & BIT4) )
- + mvOsOutput(" lower VCC tolerance: 0.2V\n");
- +
- + if ( !(spdRawData[i] & BIT5) )
- + mvOsOutput(" upper VCC tolerance: 0.2V\n");
- +
- + if ( spdRawData[i] & BIT6 )
- + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
- + else
- + mvOsOutput(" Concurrent Auto Preharge: No \n");
- +
- + if ( spdRawData[i] & BIT7 )
- + mvOsOutput(" Supports Fast AP: Yes \n");
- + else
- + mvOsOutput(" Supports Fast AP: No \n");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
- + {
- + if ( spdRawData[i] & BIT0 )
- + mvOsOutput(" Supports Weak Driver: Yes \n");
- + else
- + mvOsOutput(" Supports Weak Driver: No \n");
- + }
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 23:
- + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
- +
- + /* DDR2 addition of right of point */
- + if ((spdRawData[i] & 0x0f) == 0xA)
- + {
- + rightOfPoint = 25;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xB)
- + {
- + rightOfPoint = 33;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xC)
- + {
- + rightOfPoint = 66;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xD)
- + {
- + rightOfPoint = 75;
- + }
- +
- + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
- + "(0 = Not supported): %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint );
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
- + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / div;
- + rightOfPoint = time_tmp % div;
- + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 25:
- + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
- + rightOfPoint = (spdRawData[i] & 0x3) * 25;
- + }
- + else /* DDR1 or DDR2 */
- + {
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
- +
- + /* DDR2 addition of right of point */
- + if ((spdRawData[i] & 0x0f) == 0xA)
- + {
- + rightOfPoint = 25;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xB)
- + {
- + rightOfPoint = 33;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xC)
- + {
- + rightOfPoint = 66;
- + }
- + if ((spdRawData[i] & 0x0f) == 0xD)
- + {
- + rightOfPoint = 75;
- + }
- + }
- + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
- + "(0 = Not supported): %d.%d [ns]\n",
- + leftOfPoint, rightOfPoint );
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
- + rightOfPoint = (spdRawData[i] & 0x3) * 25;
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = 0;
- + rightOfPoint = time_tmp;
- + }
- + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
- + leftOfPoint, rightOfPoint );
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 27: /* Minimum Row Precharge Time */
- + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
- + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0xff : 0xfc;
- + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0x00 : 0x03;
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
- + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
- + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
- + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
- + "in Clk cycles %d\n",
- + leftOfPoint, rightOfPoint, trp_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 28: /* Minimum Row Active to Row Active Time */
- + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
- + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0xff : 0xfc;
- + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0x00 : 0x03;
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
- + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
- + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
- + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
- + "%d.%d = in Clk cycles %d\n",
- + leftOfPoint, rightOfPoint, trp_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 29: /* Minimum Ras-To-Cas Delay */
- + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
- + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0xff : 0xfc;
- + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
- + 0x00 : 0x03;
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
- + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
- + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
- + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
- + "in Clk cycles %d\n",
- + leftOfPoint, rightOfPoint, trp_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 30: /* Minimum Ras Pulse Width */
- + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
- + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
- + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 31: /* Module Bank Density */
- + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
- +
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + if (dimmInfo.dimmBankDensity & BIT0)
- + mvOsOutput("1GB, ");
- + if (dimmInfo.dimmBankDensity & BIT1)
- + mvOsOutput("8MB, ");
- + if (dimmInfo.dimmBankDensity & BIT2)
- + mvOsOutput("16MB, ");
- + if (dimmInfo.dimmBankDensity & BIT3)
- + mvOsOutput("32MB, ");
- + if (dimmInfo.dimmBankDensity & BIT4)
- + mvOsOutput("64MB, ");
- + if (dimmInfo.dimmBankDensity & BIT5)
- + mvOsOutput("128MB, ");
- + if (dimmInfo.dimmBankDensity & BIT6)
- + mvOsOutput("256MB, ");
- + if (dimmInfo.dimmBankDensity & BIT7)
- + mvOsOutput("512MB, ");
- + }
- + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
- + {
- + if (dimmInfo.dimmBankDensity & BIT0)
- + mvOsOutput("1GB, ");
- + if (dimmInfo.dimmBankDensity & BIT1)
- + mvOsOutput("2GB, ");
- + if (dimmInfo.dimmBankDensity & BIT2)
- + mvOsOutput("16MB, ");
- + if (dimmInfo.dimmBankDensity & BIT3)
- + mvOsOutput("32MB, ");
- + if (dimmInfo.dimmBankDensity & BIT4)
- + mvOsOutput("64MB, ");
- + if (dimmInfo.dimmBankDensity & BIT5)
- + mvOsOutput("128MB, ");
- + if (dimmInfo.dimmBankDensity & BIT6)
- + mvOsOutput("256MB, ");
- + if (dimmInfo.dimmBankDensity & BIT7)
- + mvOsOutput("512MB, ");
- + }
- + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
- + {
- + if (dimmInfo.dimmBankDensity & BIT0)
- + mvOsOutput("1GB, ");
- + if (dimmInfo.dimmBankDensity & BIT1)
- + mvOsOutput("2GB, ");
- + if (dimmInfo.dimmBankDensity & BIT2)
- + mvOsOutput("4GB, ");
- + if (dimmInfo.dimmBankDensity & BIT3)
- + mvOsOutput("8GB, ");
- + if (dimmInfo.dimmBankDensity & BIT4)
- + mvOsOutput("16GB, ");
- + if (dimmInfo.dimmBankDensity & BIT5)
- + mvOsOutput("128MB, ");
- + if (dimmInfo.dimmBankDensity & BIT6)
- + mvOsOutput("256MB, ");
- + if (dimmInfo.dimmBankDensity & BIT7)
- + mvOsOutput("512MB, ");
- + }
- + mvOsOutput("\n");
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 32: /* Address And Command Setup Time (measured in ns/1000) */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 33: /* Address And Command Hold Time */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 34: /* Data Input Setup Time */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 35: /* Data Input Hold Time */
- + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
- + {
- + rightOfPoint = (spdRawData[i] & 0x0f);
- + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
- + if(leftOfPoint > 7)
- + {
- + leftOfPoint *= -1;
- + }
- + }
- + else /* DDR1 or DDR2 */
- + {
- + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
- + ((spdRawData[i] & 0x0f));
- + leftOfPoint = time_tmp / 100;
- + rightOfPoint = time_tmp % 100;
- + }
- + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- +
- + case 36: /* Relevant for DDR2 only: Write Recovery Time */
- + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
- + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
- + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
- + leftOfPoint, rightOfPoint);
- + break;
- +/*----------------------------------------------------------------------------*/
- + }
- +
- +}
- +
- +
- +/*
- + * translate ns.ns/10 coding of SPD timing values
- + * into ps unit values
- + */
- +/*******************************************************************************
- +* cas2ps - Translate x.y ns parameter to pico-seconds values
- +*
- +* DESCRIPTION:
- +* This function translates x.y nano seconds to its value in pico seconds.
- +* For example 3.75ns will return 3750.
- +*
- +* INPUT:
- +* spd_byte - DIMM SPD byte.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* value in pico seconds.
- +*
- +*******************************************************************************/
- +static MV_U32 cas2ps(MV_U8 spd_byte)
- +{
- + MV_U32 ns, ns10;
- +
- + /* isolate upper nibble */
- + ns = (spd_byte >> 4) & 0x0F;
- + /* isolate lower nibble */
- + ns10 = (spd_byte & 0x0F);
- +
- + if( ns10 < 10 ) {
- + ns10 *= 10;
- + }
- + else if( ns10 == 10 )
- + ns10 = 25;
- + else if( ns10 == 11 )
- + ns10 = 33;
- + else if( ns10 == 12 )
- + ns10 = 66;
- + else if( ns10 == 13 )
- + ns10 = 75;
- + else
- + {
- + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
- + }
- +
- + return (ns*1000 + ns10*10);
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 2010-11-09 20:28:11.032495447 +0100
- @@ -0,0 +1,192 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvDram
- +#define __INCmvDram
- +
- +#include "ddr2/mvDramIf.h"
- +#include "twsi/mvTwsi.h"
- +
- +#define MAX_DIMM_NUM 2
- +#define SPD_SIZE 128
- +
- +/* Dimm spd offsets */
- +#define DIMM_MEM_TYPE 2
- +#define DIMM_ROW_NUM 3
- +#define DIMM_COL_NUM 4
- +#define DIMM_MODULE_BANK_NUM 5
- +#define DIMM_DATA_WIDTH 6
- +#define DIMM_VOLT_IF 8
- +#define DIMM_MIN_CC_AT_MAX_CAS 9
- +#define DIMM_ERR_CHECK_TYPE 11
- +#define DIMM_REFRESH_INTERVAL 12
- +#define DIMM_SDRAM_WIDTH 13
- +#define DIMM_ERR_CHECK_DATA_WIDTH 14
- +#define DIMM_MIN_CLK_DEL 15
- +#define DIMM_BURST_LEN_SUP 16
- +#define DIMM_DEV_BANK_NUM 17
- +#define DIMM_SUP_CAL 18
- +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
- +#define DIMM_BUF_ADDR_CONT_IN 21
- +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
- +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
- +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
- +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
- +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
- +#define DIMM_MIN_RAS_PULSE_WIDTH 30
- +#define DIMM_BANK_DENSITY 31
- +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
- +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
- +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
- +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
- +#define DIMM_SPD_VERSION 62
- +
- +/* Dimm Memory Type values */
- +#define DIMM_MEM_TYPE_SDRAM 0x4
- +#define DIMM_MEM_TYPE_DDR1 0x7
- +#define DIMM_MEM_TYPE_DDR2 0x8
- +
- +#define DIMM_MODULE_MANU_OFFS 64
- +#define DIMM_MODULE_MANU_SIZE 8
- +#define DIMM_MODULE_VEN_OFFS 73
- +#define DIMM_MODULE_VEN_SIZE 25
- +#define DIMM_MODULE_ID_OFFS 99
- +#define DIMM_MODULE_ID_SIZE 18
- +
- +/* enumeration for voltage levels. */
- +typedef enum _mvDimmVoltageIf
- +{
- + TTL_5V_TOLERANT,
- + LVTTL,
- + HSTL_1_5V,
- + SSTL_3_3V,
- + SSTL_2_5V,
- + VOLTAGE_UNKNOWN,
- +} MV_DIMM_VOLTAGE_IF;
- +
- +
- +/* enumaration for SDRAM CAS Latencies. */
- +typedef enum _mvDimmSdramCas
- +{
- + SD_CL_1 =1,
- + SD_CL_2,
- + SD_CL_3,
- + SD_CL_4,
- + SD_CL_5,
- + SD_CL_6,
- + SD_CL_7,
- + SD_FAULT
- +}MV_DIMM_SDRAM_CAS;
- +
- +
- +/* DIMM information structure */
- +typedef struct _mvDimmInfo
- +{
- + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
- +
- + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
- +
- + /* DIMM dimensions */
- + MV_U32 numOfRowAddr;
- + MV_U32 numOfColAddr;
- + MV_U32 numOfModuleBanks;
- + MV_U32 dataWidth;
- + MV_U32 errorCheckType; /* ECC , PARITY..*/
- + MV_U32 sdramWidth; /* 4,8,16 or 32 */
- + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
- + MV_U32 burstLengthSupported;
- + MV_U32 numOfBanksOnEachDevice;
- + MV_U32 suportedCasLatencies;
- + MV_U32 refreshInterval;
- + MV_U32 dimmBankDensity;
- + MV_U32 dimmTypeInfo; /* DDR2 only */
- + MV_U32 dimmAttributes;
- +
- + /* DIMM timing parameters */
- + MV_U32 minCycleTimeAtMaxCasLatPs;
- + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
- + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
- + MV_U32 minRowPrechargeTime;
- + MV_U32 minRowActiveToRowActive;
- + MV_U32 minRasToCasDelay;
- + MV_U32 minRasPulseWidth;
- + MV_U32 minWriteRecoveryTime; /* DDR2 only */
- + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
- + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
- + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
- +
- + /* Parameters calculated from the extracted DIMM information */
- + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
- + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
- + MV_U32 numberOfDevices;
- +
- +} MV_DIMM_INFO;
- +
- +
- +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
- +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
- +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
- +MV_STATUS dimmSpdCpy(MV_VOID);
- +
- +#endif /* __INCmvDram */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 2010-11-09 20:28:11.042495489 +0100
- @@ -0,0 +1,2952 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEth.c - Marvell's Gigabit Ethernet controller low level driver
- +*
- +* DESCRIPTION:
- +* This file introduce OS independent APIs to Marvell's Gigabit Ethernet
- +* controller. This Gigabit Ethernet Controller driver API controls
- +* 1) Operations (i.e. port Init, Finish, Up, Down, PhyReset etc').
- +* 2) Data flow (i.e. port Send, Receive etc').
- +* 3) MAC Filtering functions (ethSetMcastAddr, ethSetRxFilterMode, etc.)
- +* 4) MIB counters support (ethReadMibCounter)
- +* 5) Debug functions (ethPortRegs, ethPortCounters, ethPortQueues, etc.)
- +* Each Gigabit Ethernet port is controlled via ETH_PORT_CTRL struct.
- +* This struct includes configuration information as well as driver
- +* internal data needed for its operations.
- +*
- +* Supported Features:
- +* - OS independent. All required OS services are implemented via external
- +* OS dependent components (like osLayer or ethOsg)
- +* - The user is free from Rx/Tx queue managing.
- +* - Simple Gigabit Ethernet port operation API.
- +* - Simple Gigabit Ethernet port data flow API.
- +* - Data flow and operation API support per queue functionality.
- +* - Support cached descriptors for better performance.
- +* - PHY access and control API.
- +* - Port Configuration API.
- +* - Full control over Special and Other Multicast MAC tables.
- +*
- +*******************************************************************************/
- +/* includes */
- +#include "mvTypes.h"
- +#include "mv802_3.h"
- +#include "mvDebug.h"
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "eth-phy/mvEthPhy.h"
- +#include "eth/mvEth.h"
- +#include "eth/gbe/mvEthGbe.h"
- +#include "cpu/mvCpu.h"
- +
- +#ifdef INCLUDE_SYNC_BARR
- +#include "sys/mvCpuIf.h"
- +#endif
- +
- +#ifdef MV_RT_DEBUG
- +# define ETH_DEBUG
- +#endif
- +
- +
- +/* locals */
- +MV_BOOL ethDescInSram;
- +MV_BOOL ethDescSwCoher;
- +
- +/* This array holds the control structure of each port */
- +ETH_PORT_CTRL* ethPortCtrl[MV_ETH_MAX_PORTS];
- +
- +/* Ethernet Port Local routines */
- +
- +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
- +
- +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
- +
- +static void ethSetUcastTable(int portNo, int queue);
- +
- +static MV_BOOL ethSetUcastAddr (int ethPortNum, MV_U8 lastNibble, int queue);
- +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue);
- +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue);
- +
- +static void ethFreeDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, MV_BUF_INFO* pDescBuf);
- +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, int size,
- + MV_ULONG* pPhysAddr, MV_U32 *memHandle);
- +
- +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize);
- +
- +static void mvEthPortSgmiiConfig(int port);
- +
- +
- +
- +/******************************************************************************/
- +/* EthDrv Initialization functions */
- +/******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEthHalInit - Initialize the Giga Ethernet unit
- +*
- +* DESCRIPTION:
- +* This function initialize the Giga Ethernet unit.
- +* 1) Configure Address decode windows of the unit
- +* 2) Set registers to HW default values.
- +* 3) Clear and Disable interrupts
- +*
- +* INPUT: NONE
- +*
- +* RETURN: NONE
- +*
- +* NOTE: this function is called once in the boot process.
- +*******************************************************************************/
- +void mvEthHalInit(void)
- +{
- + int port;
- +
- + /* Init static data structures */
- + for (port=0; port<MV_ETH_MAX_PORTS; port++)
- + {
- + ethPortCtrl[port] = NULL;
- + }
- + /* Power down all existing ports */
- + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
- + {
- +
- +#if defined (MV78200)
- + /* Skip ports mapped to another CPU*/
- + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(GIGA0+port))
- + {
- + continue;
- + }
- +#endif
- +
- + /* Skip power down ports */
- + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
- +
- + /* Disable Giga Ethernet Unit interrupts */
- + MV_REG_WRITE(ETH_UNIT_INTR_MASK_REG(port), 0);
- +
- + /* Clear ETH_UNIT_INTR_CAUSE_REG register */
- + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
- +
- + }
- +
- + mvEthMemAttrGet(ðDescInSram, ðDescSwCoher);
- +
- +#if defined(ETH_DESCR_IN_SRAM)
- + if(ethDescInSram == MV_FALSE)
- + {
- + mvOsPrintf("ethDrv: WARNING! Descriptors will be allocated in DRAM instead of SRAM.\n");
- + }
- +#endif /* ETH_DESCR_IN_SRAM */
- +}
- +
- +/*******************************************************************************
- +* mvEthMemAttrGet - Define properties (SRAM/DRAM, SW_COHER / HW_COHER / UNCACHED)
- +* of of memory location for RX and TX descriptors.
- +*
- +* DESCRIPTION:
- +* This function allocates memory for RX and TX descriptors.
- +* - If ETH_DESCR_IN_SRAM defined, allocate from SRAM memory.
- +* - If ETH_DESCR_IN_SDRAM defined, allocate from SDRAM memory.
- +*
- +* INPUT:
- +* MV_BOOL* pIsSram - place of descriptors:
- +* MV_TRUE - in SRAM
- +* MV_FALSE - in DRAM
- +* MV_BOOL* pIsSwCoher - cache coherency of descriptors:
- +* MV_TRUE - driver is responsible for cache coherency
- +* MV_FALSE - driver is not responsible for cache coherency
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher)
- +{
- + MV_BOOL isSram, isSwCoher;
- +
- + isSram = MV_FALSE;
- +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
- + isSwCoher = MV_TRUE;
- +#else
- + isSwCoher = MV_FALSE;
- +#endif
- +
- +#if defined(ETH_DESCR_IN_SRAM)
- + if( mvCtrlSramSizeGet() > 0)
- + {
- + isSram = MV_TRUE;
- + #if (INTEG_SRAM_COHER == MV_CACHE_COHER_SW)
- + isSwCoher = MV_TRUE;
- + #else
- + isSwCoher = MV_FALSE;
- + #endif
- + }
- +#endif /* ETH_DESCR_IN_SRAM */
- +
- + if(pIsSram != NULL)
- + *pIsSram = isSram;
- +
- + if(pIsSwCoher != NULL)
- + *pIsSwCoher = isSwCoher;
- +}
- +
- +
- +
- +/******************************************************************************/
- +/* Port Initialization functions */
- +/******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEthPortInit - Initialize the Ethernet port driver
- +*
- +* DESCRIPTION:
- +* This function initialize the ethernet port.
- +* 1) Allocate and initialize internal port Control structure.
- +* 2) Create RX and TX descriptor rings for default RX and TX queues
- +* 3) Disable RX and TX operations, clear cause registers and
- +* mask all interrupts.
- +* 4) Set all registers to default values and clean all MAC tables.
- +*
- +* INPUT:
- +* int portNo - Ethernet port number
- +* ETH_PORT_INIT *pEthPortInit - Ethernet port init structure
- +*
- +* RETURN:
- +* void* - ethernet port handler, that should be passed to the most other
- +* functions dealing with this port.
- +*
- +* NOTE: This function is called once per port when loading the eth module.
- +*******************************************************************************/
- +void* mvEthPortInit(int portNo, MV_ETH_PORT_INIT *pEthPortInit)
- +{
- + int queue, descSize;
- + ETH_PORT_CTRL* pPortCtrl;
- +
- + /* Check validity of parameters */
- + if( (portNo >= (int)mvCtrlEthMaxPortGet()) ||
- + (pEthPortInit->rxDefQ >= MV_ETH_RX_Q_NUM) ||
- + (pEthPortInit->maxRxPktSize < 1518) )
- + {
- + mvOsPrintf("EthPort #%d: Bad initialization parameters\n", portNo);
- + return NULL;
- + }
- + if( (pEthPortInit->rxDescrNum[pEthPortInit->rxDefQ]) == 0)
- + {
- + mvOsPrintf("EthPort #%d: rxDefQ (%d) must be created\n",
- + portNo, pEthPortInit->rxDefQ);
- + return NULL;
- + }
- +
- + pPortCtrl = (ETH_PORT_CTRL*)mvOsMalloc( sizeof(ETH_PORT_CTRL) );
- + if(pPortCtrl == NULL)
- + {
- + mvOsPrintf("EthDrv: Can't allocate %dB for port #%d control structure!\n",
- + (int)sizeof(ETH_PORT_CTRL), portNo);
- + return NULL;
- + }
- +
- + memset(pPortCtrl, 0, sizeof(ETH_PORT_CTRL) );
- + ethPortCtrl[portNo] = pPortCtrl;
- +
- + pPortCtrl->portState = MV_UNDEFINED_STATE;
- +
- + pPortCtrl->portNo = portNo;
- +
- + pPortCtrl->osHandle = pEthPortInit->osHandle;
- +
- + /* Copy Configuration parameters */
- + pPortCtrl->portConfig.maxRxPktSize = pEthPortInit->maxRxPktSize;
- + pPortCtrl->portConfig.rxDefQ = pEthPortInit->rxDefQ;
- + pPortCtrl->portConfig.ejpMode = 0;
- +
- + for( queue=0; queue<MV_ETH_RX_Q_NUM; queue++ )
- + {
- + pPortCtrl->rxQueueConfig[queue].descrNum = pEthPortInit->rxDescrNum[queue];
- + }
- + for( queue=0; queue<MV_ETH_TX_Q_NUM; queue++ )
- + {
- + pPortCtrl->txQueueConfig[queue].descrNum = pEthPortInit->txDescrNum[queue];
- + }
- +
- + mvEthPortDisable(pPortCtrl);
- +
- + /* Set the board information regarding PHY address */
- + mvEthPhyAddrSet(pPortCtrl, mvBoardPhyAddrGet(portNo) );
- +
- + /* Create all requested RX queues */
- + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
- + {
- + if(pPortCtrl->rxQueueConfig[queue].descrNum == 0)
- + continue;
- +
- + /* Allocate memory for RX descriptors */
- + descSize = ((pPortCtrl->rxQueueConfig[queue].descrNum * ETH_RX_DESC_ALIGNED_SIZE) +
- + CPU_D_CACHE_LINE_SIZE);
- +
- + pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr =
- + ethAllocDescrMemory(pPortCtrl, descSize,
- + &pPortCtrl->rxQueue[queue].descBuf.bufPhysAddr,
- + &pPortCtrl->rxQueue[queue].descBuf.memHandle);
- + pPortCtrl->rxQueue[queue].descBuf.bufSize = descSize;
- + if(pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr == NULL)
- + {
- + mvOsPrintf("EthPort #%d, rxQ=%d: Can't allocate %d bytes in %s for %d RX descr\n",
- + pPortCtrl->portNo, queue, descSize,
- + ethDescInSram ? "SRAM" : "DRAM",
- + pPortCtrl->rxQueueConfig[queue].descrNum);
- + return NULL;
- + }
- +
- + ethInitRxDescRing(pPortCtrl, queue);
- + }
- + /* Create TX queues */
- + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
- + {
- + if(pPortCtrl->txQueueConfig[queue].descrNum == 0)
- + continue;
- +
- + /* Allocate memory for TX descriptors */
- + descSize = ((pPortCtrl->txQueueConfig[queue].descrNum * ETH_TX_DESC_ALIGNED_SIZE) +
- + CPU_D_CACHE_LINE_SIZE);
- +
- + pPortCtrl->txQueue[queue].descBuf.bufVirtPtr =
- + ethAllocDescrMemory(pPortCtrl, descSize,
- + &pPortCtrl->txQueue[queue].descBuf.bufPhysAddr,
- + &pPortCtrl->txQueue[queue].descBuf.memHandle);
- + pPortCtrl->txQueue[queue].descBuf.bufSize = descSize;
- + if(pPortCtrl->txQueue[queue].descBuf.bufVirtPtr == NULL)
- + {
- + mvOsPrintf("EthPort #%d, txQ=%d: Can't allocate %d bytes in %s for %d TX descr\n",
- + pPortCtrl->portNo, queue, descSize, ethDescInSram ? "SRAM" : "DRAM",
- + pPortCtrl->txQueueConfig[queue].descrNum);
- + return NULL;
- + }
- +
- + ethInitTxDescRing(pPortCtrl, queue);
- + }
- + mvEthDefaultsSet(pPortCtrl);
- +
- + pPortCtrl->portState = MV_IDLE;
- + return pPortCtrl;
- +}
- +
- +/*******************************************************************************
- +* ethPortFinish - Finish the Ethernet port driver
- +*
- +* DESCRIPTION:
- +* This function finish the ethernet port.
- +* 1) Down ethernet port if needed.
- +* 2) Delete RX and TX descriptor rings for all created RX and TX queues
- +* 3) Free internal port Control structure.
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler
- +*
- +* RETURN: NONE.
- +*
- +*******************************************************************************/
- +void mvEthPortFinish(void* pPortHndl)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + int queue, portNo = pPortCtrl->portNo;
- +
- + if(pPortCtrl->portState == MV_ACTIVE)
- + {
- + mvOsPrintf("ethPort #%d: Warning !!! Finish port in Active state\n",
- + portNo);
- + mvEthPortDisable(pPortHndl);
- + }
- +
- + /* Free all allocated RX queues */
- + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
- + {
- + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->rxQueue[queue].descBuf);
- + }
- +
- + /* Free all allocated TX queues */
- + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
- + {
- + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->txQueue[queue].descBuf);
- + }
- +
- + /* Free port control structure */
- + mvOsFree(pPortCtrl);
- +
- + ethPortCtrl[portNo] = NULL;
- +}
- +
- +/*******************************************************************************
- +* mvEthDefaultsSet - Set defaults to the ethernet port
- +*
- +* DESCRIPTION:
- +* This function set default values to the ethernet port.
- +* 1) Clear Cause registers and Mask all interrupts
- +* 2) Clear all MAC tables
- +* 3) Set defaults to all registers
- +* 4) Reset all created RX and TX descriptors ring
- +* 5) Reset PHY
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success, Others - Failure
- +* NOTE:
- +* This function update all the port configuration except those set
- +* Initialy by the OsGlue by MV_ETH_PORT_INIT.
- +* This function can be called after portDown to return the port setting
- +* to defaults.
- +*******************************************************************************/
- +MV_STATUS mvEthDefaultsSet(void* pPortHndl)
- +{
- + int ethPortNo, queue;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + MV_U32 txPrio;
- + MV_U32 portCfgReg, portCfgExtReg, portSerialCtrlReg, portSerialCtrl1Reg, portSdmaCfgReg;
- + MV_BOARD_MAC_SPEED boardMacCfg;
- +
- + ethPortNo = pPortCtrl->portNo;
- +
- + /* Clear Cause registers */
- + MV_REG_WRITE(ETH_INTR_CAUSE_REG(ethPortNo),0);
- + MV_REG_WRITE(ETH_INTR_CAUSE_EXT_REG(ethPortNo),0);
- +
- + /* Mask all interrupts */
- + MV_REG_WRITE(ETH_INTR_MASK_REG(ethPortNo),0);
- + MV_REG_WRITE(ETH_INTR_MASK_EXT_REG(ethPortNo),0);
- +
- + portCfgReg = PORT_CONFIG_VALUE;
- + portCfgExtReg = PORT_CONFIG_EXTEND_VALUE;
- +
- + boardMacCfg = mvBoardMacSpeedGet(ethPortNo);
- +
- + if(boardMacCfg == BOARD_MAC_SPEED_100M)
- + {
- + portSerialCtrlReg = PORT_SERIAL_CONTROL_100MB_FORCE_VALUE;
- + }
- + else if(boardMacCfg == BOARD_MAC_SPEED_1000M)
- + {
- + portSerialCtrlReg = PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE;
- + }
- + else
- + {
- + portSerialCtrlReg = PORT_SERIAL_CONTROL_VALUE;
- + }
- +
- + /* build PORT_SDMA_CONFIG_REG */
- + portSdmaCfgReg = ETH_TX_INTR_COAL_MASK(0);
- + portSdmaCfgReg |= ETH_TX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
- +
- +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB) || \
- + (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT) )
- + /* some devices have restricted RX burst size when using HW coherency */
- + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_4_64BIT_VALUE);
- +#else
- + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
- +#endif
- +
- +#if defined(MV_CPU_BE)
- + /* big endian */
- +# if defined(MV_ARM)
- + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
- + ETH_TX_NO_DATA_SWAP_MASK |
- + ETH_DESC_SWAP_MASK);
- +# elif defined(MV_PPC)
- + portSdmaCfgReg |= (ETH_RX_DATA_SWAP_MASK |
- + ETH_TX_DATA_SWAP_MASK |
- + ETH_NO_DESC_SWAP_MASK);
- +# else
- +# error "Giga Ethernet Swap policy is not defined for the CPU_ARCH"
- +# endif /* MV_ARM / MV_PPC */
- +
- +#else /* MV_CPU_LE */
- + /* little endian */
- + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
- + ETH_TX_NO_DATA_SWAP_MASK |
- + ETH_NO_DESC_SWAP_MASK);
- +#endif /* MV_CPU_BE / MV_CPU_LE */
- +
- + pPortCtrl->portRxQueueCmdReg = 0;
- + pPortCtrl->portTxQueueCmdReg = 0;
- +
- +#if (MV_ETH_VERSION >= 4)
- + if(pPortCtrl->portConfig.ejpMode == MV_TRUE)
- + {
- + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), ETH_TX_EJP_ENABLE_MASK);
- + }
- + else
- + {
- + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), 0)
- + }
- +#endif /* (MV_ETH_VERSION >= 4) */
- +
- + ethSetUcastTable(ethPortNo, -1);
- + mvEthSetSpecialMcastTable(ethPortNo, -1);
- + mvEthSetOtherMcastTable(ethPortNo, -1);
- +
- + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
- +
- + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
- +
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
- +
- + /* Update value of PortConfig register accordingly with all RxQueue types */
- + pPortCtrl->portConfig.rxArpQ = pPortCtrl->portConfig.rxDefQ;
- + pPortCtrl->portConfig.rxBpduQ = pPortCtrl->portConfig.rxDefQ;
- + pPortCtrl->portConfig.rxTcpQ = pPortCtrl->portConfig.rxDefQ;
- + pPortCtrl->portConfig.rxUdpQ = pPortCtrl->portConfig.rxDefQ;
- +
- + portCfgReg &= ~ETH_DEF_RX_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_QUEUE_MASK(pPortCtrl->portConfig.rxDefQ);
- +
- + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
- +
- + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
- +
- + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
- +
- + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
- +
- + /* Assignment of Tx CTRP of given queue */
- + txPrio = 0;
- +
- + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
- + {
- + pQueueCtrl = &pPortCtrl->txQueue[queue];
- +
- + if(pQueueCtrl->pFirstDescr != NULL)
- + {
- + ethResetTxDescRing(pPortCtrl, queue);
- +
- + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),
- + 0x3fffffff);
- + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue),
- + 0x03ffffff);
- + }
- + else
- + {
- + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue), 0x0);
- + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), 0x0);
- + }
- + }
- +
- + /* Assignment of Rx CRDP of given queue */
- + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
- + {
- + ethResetRxDescRing(pPortCtrl, queue);
- + }
- +
- + /* Allow receiving packes with odd number of preamble nibbles */
- + portSerialCtrl1Reg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo));
- + portSerialCtrl1Reg |= ETH_EN_MII_ODD_PRE_MASK;
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo), portSerialCtrl1Reg);
- +
- + /* Assign port configuration and command. */
- + MV_REG_WRITE(ETH_PORT_CONFIG_REG(ethPortNo), portCfgReg);
- +
- + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(ethPortNo), portCfgExtReg);
- +
- + /* Assign port SDMA configuration */
- + MV_REG_WRITE(ETH_SDMA_CONFIG_REG(ethPortNo), portSdmaCfgReg);
- +
- + /* Turn off the port/queue bandwidth limitation */
- + MV_REG_WRITE(ETH_MAX_TRANSMIT_UNIT_REG(ethPortNo), 0x0);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* ethPortUp - Start the Ethernet port RX and TX activity.
- +*
- +* DESCRIPTION:
- +* This routine start Rx and Tx activity:
- +*
- +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
- +* to calling this function (use etherInitTxDescRing for Tx queues and
- +* etherInitRxDescRing for Rx queues).
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success, Others - Failure.
- +*
- +* NOTE : used for port link up.
- +*******************************************************************************/
- +MV_STATUS mvEthPortUp(void* pEthPortHndl)
- +{
- + int ethPortNo;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- +
- + ethPortNo = pPortCtrl->portNo;
- +
- + if( (pPortCtrl->portState != MV_ACTIVE) &&
- + (pPortCtrl->portState != MV_PAUSED) )
- + {
- + mvOsPrintf("ethDrv port%d: Unexpected port state %d\n",
- + ethPortNo, pPortCtrl->portState);
- + return MV_BAD_STATE;
- + }
- +
- + ethPortNo = pPortCtrl->portNo;
- +
- + /* Enable port RX. */
- + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNo), pPortCtrl->portRxQueueCmdReg);
- +
- + /* Enable port TX. */
- + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(ethPortNo)) = pPortCtrl->portTxQueueCmdReg;
- +
- + pPortCtrl->portState = MV_ACTIVE;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* ethPortDown - Stop the Ethernet port activity.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success, Others - Failure.
- +*
- +* NOTE : used for port link down.
- +*******************************************************************************/
- +MV_STATUS mvEthPortDown(void* pEthPortHndl)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + int ethPortNum = pPortCtrl->portNo;
- + unsigned int regData;
- + volatile int uDelay, mDelay;
- +
- + /* Stop Rx port activity. Check port Rx activity. */
- + regData = (MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_RXQ_ENABLE_MASK;
- + if(regData != 0)
- + {
- + /* Issue stop command for active channels only */
- + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNum), (regData << ETH_RXQ_DISABLE_OFFSET));
- + }
- +
- + /* Stop Tx port activity. Check port Tx activity. */
- + regData = (MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_TXQ_ENABLE_MASK;
- + if(regData != 0)
- + {
- + /* Issue stop command for active channels only */
- + MV_REG_WRITE(ETH_TX_QUEUE_COMMAND_REG(ethPortNum),
- + (regData << ETH_TXQ_DISABLE_OFFSET) );
- + }
- +
- + /* Force link down */
- +/*
- + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
- + regData &= ~(ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
- +*/
- + /* Wait for all Rx activity to terminate. */
- + mDelay = 0;
- + do
- + {
- + if(mDelay >= RX_DISABLE_TIMEOUT_MSEC)
- + {
- + mvOsPrintf("ethPort_%d: TIMEOUT for RX stopped !!! rxQueueCmd - 0x08%x\n",
- + ethPortNum, regData);
- + break;
- + }
- + mvOsDelay(1);
- + mDelay++;
- +
- + /* Check port RX Command register that all Rx queues are stopped */
- + regData = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum));
- + }
- + while(regData & 0xFF);
- +
- + /* Wait for all Tx activity to terminate. */
- + mDelay = 0;
- + do
- + {
- + if(mDelay >= TX_DISABLE_TIMEOUT_MSEC)
- + {
- + mvOsPrintf("ethPort_%d: TIMEOUT for TX stoped !!! txQueueCmd - 0x08%x\n",
- + ethPortNum, regData);
- + break;
- + }
- + mvOsDelay(1);
- + mDelay++;
- +
- + /* Check port TX Command register that all Tx queues are stopped */
- + regData = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum));
- + }
- + while(regData & 0xFF);
- +
- + /* Double check to Verify that TX FIFO is Empty */
- + mDelay = 0;
- + while(MV_TRUE)
- + {
- + do
- + {
- + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
- + {
- + mvOsPrintf("\n ethPort_%d: TIMEOUT for TX FIFO empty !!! portStatus - 0x08%x\n",
- + ethPortNum, regData);
- + break;
- + }
- + mvOsDelay(1);
- + mDelay++;
- +
- + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
- + }
- + while( ((regData & ETH_TX_FIFO_EMPTY_MASK) == 0) ||
- + ((regData & ETH_TX_IN_PROGRESS_MASK) != 0) );
- +
- + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
- + break;
- +
- + /* Double check */
- + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
- + if( ((regData & ETH_TX_FIFO_EMPTY_MASK) != 0) &&
- + ((regData & ETH_TX_IN_PROGRESS_MASK) == 0) )
- + {
- + break;
- + }
- + else
- + mvOsPrintf("ethPort_%d: TX FIFO Empty double check failed. %d msec, portStatus=0x%x\n",
- + ethPortNum, mDelay, regData);
- + }
- +
- + /* Do NOT force link down */
- +/*
- + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
- + regData |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
- +*/
- + /* Wait about 2500 tclk cycles */
- + uDelay = (PORT_DISABLE_WAIT_TCLOCKS/(mvBoardTclkGet()/1000000));
- + mvOsUDelay(uDelay);
- +
- + pPortCtrl->portState = MV_PAUSED;
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* ethPortEnable - Enable the Ethernet port and Start RX and TX.
- +*
- +* DESCRIPTION:
- +* This routine enable the Ethernet port and Rx and Tx activity:
- +*
- +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
- +* to calling this function (use etherInitTxDescRing for Tx queues and
- +* etherInitRxDescRing for Rx queues).
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success, Others - Failure.
- +*
- +* NOTE: main usage is to enable the port after ifconfig up.
- +*******************************************************************************/
- +MV_STATUS mvEthPortEnable(void* pEthPortHndl)
- +{
- + int ethPortNo;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + MV_U32 portSerialCtrlReg;
- +
- + ethPortNo = pPortCtrl->portNo;
- +
- + /* Enable port */
- + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNo));
- + portSerialCtrlReg |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK | ETH_PORT_ENABLE_MASK);
- +
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
- +
- + mvEthMibCountersClear(pEthPortHndl);
- +
- + pPortCtrl->portState = MV_PAUSED;
- +
- + /* If Link is UP, Start RX and TX traffic */
- + if( MV_REG_READ( ETH_PORT_STATUS_REG(ethPortNo) ) & ETH_LINK_UP_MASK)
- + return( mvEthPortUp(pEthPortHndl) );
- +
- + return MV_NOT_READY;
- +}
- +
- +
- +/*******************************************************************************
- +* mvEthPortDisable - Stop RX and TX activities and Disable the Ethernet port.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success, Others - Failure.
- +*
- +* NOTE: main usage is to disable the port after ifconfig down.
- +*******************************************************************************/
- +MV_STATUS mvEthPortDisable(void* pEthPortHndl)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + int ethPortNum = pPortCtrl->portNo;
- + unsigned int regData;
- + volatile int mvDelay;
- +
- + if(pPortCtrl->portState == MV_ACTIVE)
- + {
- + /* Stop RX and TX activities */
- + mvEthPortDown(pEthPortHndl);
- + }
- +
- + /* Reset the Enable bit in the Serial Control Register */
- + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
- + regData &= ~(ETH_PORT_ENABLE_MASK);
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
- +
- + /* Wait about 2500 tclk cycles */
- + mvDelay = (PORT_DISABLE_WAIT_TCLOCKS*(mvCpuPclkGet()/mvBoardTclkGet()));
- + for(mvDelay; mvDelay>0; mvDelay--);
- +
- + pPortCtrl->portState = MV_IDLE;
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthPortForceTxDone - Get next buffer from TX queue in spite of buffer ownership.
- +*
- +* DESCRIPTION:
- +* This routine used to free buffers attached to the Tx ring and should
- +* be called only when Giga Ethernet port is Down
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* int txQueue - Number of TX queue.
- +*
- +* OUTPUT:
- +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
- +*
- +* RETURN:
- +* MV_EMPTY - There is no more buffers in this queue.
- +* MV_OK - Buffer detached from the queue and pPktInfo structure
- +* filled with relevant information.
- +*
- +*******************************************************************************/
- +MV_PKT_INFO* mvEthPortForceTxDone(void* pEthPortHndl, int txQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + MV_PKT_INFO* pPktInfo;
- + ETH_TX_DESC* pTxDesc;
- + int port = pPortCtrl->portNo;
- +
- + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
- +
- + while( (pQueueCtrl->pUsedDescr != pQueueCtrl->pCurrentDescr) ||
- + (pQueueCtrl->resource == 0) )
- + {
- + /* Free next descriptor */
- + pQueueCtrl->resource++;
- + pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pUsedDescr;
- +
- + /* pPktInfo is available only in descriptors which are last descriptors */
- + pPktInfo = (MV_PKT_INFO*)pTxDesc->returnInfo;
- + if (pPktInfo)
- + pPktInfo->status = pTxDesc->cmdSts;
- +
- + pTxDesc->cmdSts = 0x0;
- + pTxDesc->returnInfo = 0x0;
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
- +
- + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
- +
- + if (pPktInfo)
- + if (pPktInfo->status & ETH_TX_LAST_DESC_MASK)
- + return pPktInfo;
- + }
- + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(port, txQueue),
- + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
- + return NULL;
- +}
- +
- +
- +
- +/*******************************************************************************
- +* mvEthPortForceRx - Get next buffer from RX queue in spite of buffer ownership.
- +*
- +* DESCRIPTION:
- +* This routine used to free buffers attached to the Rx ring and should
- +* be called only when Giga Ethernet port is Down
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* int rxQueue - Number of Rx queue.
- +*
- +* OUTPUT:
- +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
- +*
- +* RETURN:
- +* MV_EMPTY - There is no more buffers in this queue.
- +* MV_OK - Buffer detached from the queue and pBufInfo structure
- +* filled with relevant information.
- +*
- +*******************************************************************************/
- +MV_PKT_INFO* mvEthPortForceRx(void* pEthPortHndl, int rxQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + ETH_RX_DESC* pRxDesc;
- + MV_PKT_INFO* pPktInfo;
- + int port = pPortCtrl->portNo;
- +
- + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
- +
- + if(pQueueCtrl->resource == 0)
- + {
- + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
- + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
- +
- + return NULL;
- + }
- + /* Free next descriptor */
- + pQueueCtrl->resource--;
- + pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pCurrentDescr;
- + pPktInfo = (MV_PKT_INFO*)pRxDesc->returnInfo;
- +
- + pPktInfo->status = pRxDesc->cmdSts;
- + pRxDesc->cmdSts = 0x0;
- + pRxDesc->returnInfo = 0x0;
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
- +
- + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
- + return pPktInfo;
- +}
- +
- +
- +/******************************************************************************/
- +/* Port Configuration functions */
- +/******************************************************************************/
- +/*******************************************************************************
- +* mvEthMruGet - Get MRU configuration for Max Rx packet size.
- +*
- +* INPUT:
- +* MV_U32 maxRxPktSize - max packet size.
- +*
- +* RETURN: MV_U32 - MRU configuration.
- +*
- +*******************************************************************************/
- +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize)
- +{
- + MV_U32 portSerialCtrlReg = 0;
- +
- + if(maxRxPktSize > 9192)
- + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9700BYTE;
- + else if(maxRxPktSize > 9022)
- + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9192BYTE;
- + else if(maxRxPktSize > 1552)
- + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9022BYTE;
- + else if(maxRxPktSize > 1522)
- + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1552BYTE;
- + else if(maxRxPktSize > 1518)
- + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1522BYTE;
- + else
- + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1518BYTE;
- +
- + return portSerialCtrlReg;
- +}
- +
- +/*******************************************************************************
- +* mvEthRxCoalSet - Sets coalescing interrupt mechanism on RX path
- +*
- +* DESCRIPTION:
- +* This routine sets the RX coalescing interrupt mechanism parameter.
- +* This parameter is a timeout counter, that counts in 64 tClk
- +* chunks, that when timeout event occurs a maskable interrupt occurs.
- +* The parameter is calculated using the tCLK frequency of the
- +* MV-64xxx chip, and the required number is in micro seconds.
- +*
- +* INPUT:
- +* void* pPortHndl - Ethernet Port handler.
- +* MV_U32 uSec - Number of micro seconds between
- +* RX interrupts
- +*
- +* RETURN:
- +* None.
- +*
- +* COMMENT:
- +* 1 sec - TCLK_RATE clocks
- +* 1 uSec - TCLK_RATE / 1,000,000 clocks
- +*
- +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_U32 mvEthRxCoalSet (void* pPortHndl, MV_U32 uSec)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
- + MV_U32 portSdmaCfgReg;
- +
- + portSdmaCfgReg = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
- + portSdmaCfgReg &= ~ETH_RX_INTR_COAL_ALL_MASK;
- +
- + portSdmaCfgReg |= ETH_RX_INTR_COAL_MASK(coal);
- +
- +#if (MV_ETH_VERSION >= 2)
- + /* Set additional bit if needed ETH_RX_INTR_COAL_MSB_BIT (25) */
- + if(ETH_RX_INTR_COAL_MASK(coal) > ETH_RX_INTR_COAL_ALL_MASK)
- + portSdmaCfgReg |= ETH_RX_INTR_COAL_MSB_MASK;
- +#endif /* MV_ETH_VERSION >= 2 */
- +
- + MV_REG_WRITE (ETH_SDMA_CONFIG_REG(pPortCtrl->portNo), portSdmaCfgReg);
- + return coal;
- +}
- +
- +/*******************************************************************************
- +* mvEthTxCoalSet - Sets coalescing interrupt mechanism on TX path
- +*
- +* DESCRIPTION:
- +* This routine sets the TX coalescing interrupt mechanism parameter.
- +* This parameter is a timeout counter, that counts in 64 tClk
- +* chunks, that when timeout event occurs a maskable interrupt
- +* occurs.
- +* The parameter is calculated using the tCLK frequency of the
- +* MV-64xxx chip, and the required number is in micro seconds.
- +*
- +* INPUT:
- +* void* pPortHndl - Ethernet Port handler.
- +* MV_U32 uSec - Number of micro seconds between
- +* RX interrupts
- +*
- +* RETURN:
- +* None.
- +*
- +* COMMENT:
- +* 1 sec - TCLK_RATE clocks
- +* 1 uSec - TCLK_RATE / 1,000,000 clocks
- +*
- +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
- +*
- +*******************************************************************************/
- +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
- + MV_U32 regVal;
- +
- + regVal = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
- + regVal &= ~ETH_TX_INTR_COAL_ALL_MASK;
- + regVal |= ETH_TX_INTR_COAL_MASK(coal);
- +
- + /* Set TX Coalescing mechanism */
- + MV_REG_WRITE (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo), regVal);
- + return coal;
- +}
- +
- +/*******************************************************************************
- +* mvEthCoalGet - Gets RX and TX coalescing values in micro seconds
- +*
- +* DESCRIPTION:
- +* This routine gets the RX and TX coalescing interrupt values.
- +* The parameter is calculated using the tCLK frequency of the
- +* MV-64xxx chip, and the returned numbers are in micro seconds.
- +*
- +* INPUTs:
- +* void* pPortHndl - Ethernet Port handler.
- +*
- +* OUTPUTs:
- +* MV_U32* pRxCoal - Number of micro seconds between RX interrupts
- +* MV_U32* pTxCoal - Number of micro seconds between TX interrupts
- +*
- +* RETURN:
- +* MV_STATUS MV_OK - success
- +* Others - failure.
- +*
- +* COMMENT:
- +* 1 sec - TCLK_RATE clocks
- +* 1 uSec - TCLK_RATE / 1,000,000 clocks
- +*
- +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal)
- +{
- + MV_U32 regVal, coal, usec;
- +
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- +
- + /* get TX Coalescing */
- + regVal = MV_REG_READ (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
- + coal = ((regVal & ETH_TX_INTR_COAL_ALL_MASK) >> ETH_TX_INTR_COAL_OFFSET);
- +
- + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
- + if(pTxCoal != NULL)
- + *pTxCoal = usec;
- +
- + /* Get RX Coalescing */
- + regVal = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
- + coal = ((regVal & ETH_RX_INTR_COAL_ALL_MASK) >> ETH_RX_INTR_COAL_OFFSET);
- +
- +#if (MV_ETH_VERSION >= 2)
- + if(regVal & ETH_RX_INTR_COAL_MSB_MASK)
- + {
- + /* Add MSB */
- + coal |= (ETH_RX_INTR_COAL_ALL_MASK + 1);
- + }
- +#endif /* MV_ETH_VERSION >= 2 */
- +
- + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
- + if(pRxCoal != NULL)
- + *pRxCoal = usec;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthMaxRxSizeSet -
- +*
- +* DESCRIPTION:
- +* Change maximum receive size of the port. This configuration will take place
- +* after next call of ethPortSetDefaults() function.
- +*
- +* INPUT:
- +*
- +* RETURN:
- +*******************************************************************************/
- +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + MV_U32 portSerialCtrlReg;
- +
- + if((maxRxSize < 1518) || (maxRxSize & ~ETH_RX_BUFFER_MASK))
- + return MV_BAD_PARAM;
- +
- + pPortCtrl->portConfig.maxRxPktSize = maxRxSize;
- +
- + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo));
- + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
- + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo), portSerialCtrlReg);
- +
- + return MV_OK;
- +}
- +
- +
- +/******************************************************************************/
- +/* MAC Filtering functions */
- +/******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEthRxFilterModeSet - Configure Fitering mode of Ethernet port
- +*
- +* DESCRIPTION:
- +* This routine used to free buffers attached to the Rx ring and should
- +* be called only when Giga Ethernet port is Down
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* MV_BOOL isPromisc - Promiscous mode
- +* MV_TRUE - accept all Broadcast, Multicast
- +* and Unicast packets
- +* MV_FALSE - accept all Broadcast,
- +* specially added Multicast and
- +* single Unicast packets
- +*
- +* RETURN: MV_STATUS MV_OK - Success, Other - Failure
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthRxFilterModeSet(void* pEthPortHndl, MV_BOOL isPromisc)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + int queue;
- + MV_U32 portCfgReg;
- +
- + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
- + /* Set / Clear UPM bit in port configuration register */
- + if(isPromisc)
- + {
- + /* Accept all multicast packets to RX default queue */
- + queue = pPortCtrl->portConfig.rxDefQ;
- + portCfgReg |= ETH_UNICAST_PROMISCUOUS_MODE_MASK;
- + memset(pPortCtrl->mcastCount, 1, sizeof(pPortCtrl->mcastCount));
- + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),0xFFFF);
- + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo),0xFFFFFFFF);
- + }
- + else
- + {
- + /* Reject all Multicast addresses */
- + queue = -1;
- + portCfgReg &= ~ETH_UNICAST_PROMISCUOUS_MODE_MASK;
- + /* Clear all mcastCount */
- + memset(pPortCtrl->mcastCount, 0, sizeof(pPortCtrl->mcastCount));
- + }
- + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
- +
- + /* Set Special Multicast and Other Multicast tables */
- + mvEthSetSpecialMcastTable(pPortCtrl->portNo, queue);
- + mvEthSetOtherMcastTable(pPortCtrl->portNo, queue);
- + ethSetUcastTable(pPortCtrl->portNo, queue);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthMacAddrSet - This function Set the port Unicast address.
- +*
- +* DESCRIPTION:
- +* This function Set the port Ethernet MAC address. This address
- +* will be used to send Pause frames if enabled. Packets with this
- +* address will be accepted and dispatched to default RX queue
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler.
- +* char* pAddr - Address to be set
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success, Other - Faulure
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthMacAddrSet(void* pPortHndl, unsigned char *pAddr, int queue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + unsigned int macH;
- + unsigned int macL;
- +
- + if(queue >= MV_ETH_RX_Q_NUM)
- + {
- + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", queue);
- + return MV_BAD_PARAM;
- + }
- +
- + if(queue != -1)
- + {
- + macL = (pAddr[4] << 8) | (pAddr[5]);
- + macH = (pAddr[0] << 24)| (pAddr[1] << 16) |
- + (pAddr[2] << 8) | (pAddr[3] << 0);
- +
- + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo), macL);
- + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo), macH);
- + }
- +
- + /* Accept frames of this address */
- + ethSetUcastAddr(pPortCtrl->portNo, pAddr[5], queue);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthMacAddrGet - This function returns the port Unicast address.
- +*
- +* DESCRIPTION:
- +* This function returns the port Ethernet MAC address.
- +*
- +* INPUT:
- +* int portNo - Ethernet port number.
- +* char* pAddr - Pointer where address will be written to
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success, Other - Faulure
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr)
- +{
- + unsigned int macH;
- + unsigned int macL;
- +
- + if(pAddr == NULL)
- + {
- + mvOsPrintf("mvEthMacAddrGet: NULL pointer.\n");
- + return MV_BAD_PARAM;
- + }
- +
- + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(portNo));
- + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(portNo));
- + pAddr[0] = (macH >> 24) & 0xff;
- + pAddr[1] = (macH >> 16) & 0xff;
- + pAddr[2] = (macH >> 8) & 0xff;
- + pAddr[3] = macH & 0xff;
- + pAddr[4] = (macL >> 8) & 0xff;
- + pAddr[5] = macL & 0xff;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthMcastCrc8Get - Calculate CRC8 of MAC address.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* MV_U8* pAddr - Address to calculate CRC-8
- +*
- +* RETURN: MV_U8 - CRC-8 of this MAC address
- +*
- +*******************************************************************************/
- +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr)
- +{
- + unsigned int macH;
- + unsigned int macL;
- + int macArray[48];
- + int crc[8];
- + int i;
- + unsigned char crcResult = 0;
- +
- + /* Calculate CRC-8 out of the given address */
- + macH = (pAddr[0] << 8) | (pAddr[1]);
- + macL = (pAddr[2] << 24)| (pAddr[3] << 16) |
- + (pAddr[4] << 8) | (pAddr[5] << 0);
- +
- + for(i=0; i<32; i++)
- + macArray[i] = (macL >> i) & 0x1;
- +
- + for(i=32; i<48; i++)
- + macArray[i] = (macH >> (i - 32)) & 0x1;
- +
- + crc[0] = macArray[45] ^ macArray[43] ^ macArray[40] ^ macArray[39] ^
- + macArray[35] ^ macArray[34] ^ macArray[31] ^ macArray[30] ^
- + macArray[28] ^ macArray[23] ^ macArray[21] ^ macArray[19] ^
- + macArray[18] ^ macArray[16] ^ macArray[14] ^ macArray[12] ^
- + macArray[8] ^ macArray[7] ^ macArray[6] ^ macArray[0];
- +
- + crc[1] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
- + macArray[41] ^ macArray[39] ^ macArray[36] ^ macArray[34] ^
- + macArray[32] ^ macArray[30] ^ macArray[29] ^ macArray[28] ^
- + macArray[24] ^ macArray[23] ^ macArray[22] ^ macArray[21] ^
- + macArray[20] ^ macArray[18] ^ macArray[17] ^ macArray[16] ^
- + macArray[15] ^ macArray[14] ^ macArray[13] ^ macArray[12] ^
- + macArray[9] ^ macArray[6] ^ macArray[1] ^ macArray[0];
- +
- + crc[2] = macArray[47] ^ macArray[46] ^ macArray[44] ^ macArray[43] ^
- + macArray[42] ^ macArray[39] ^ macArray[37] ^ macArray[34] ^
- + macArray[33] ^ macArray[29] ^ macArray[28] ^ macArray[25] ^
- + macArray[24] ^ macArray[22] ^ macArray[17] ^ macArray[15] ^
- + macArray[13] ^ macArray[12] ^ macArray[10] ^ macArray[8] ^
- + macArray[6] ^ macArray[2] ^ macArray[1] ^ macArray[0];
- +
- + crc[3] = macArray[47] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
- + macArray[40] ^ macArray[38] ^ macArray[35] ^ macArray[34] ^
- + macArray[30] ^ macArray[29] ^ macArray[26] ^ macArray[25] ^
- + macArray[23] ^ macArray[18] ^ macArray[16] ^ macArray[14] ^
- + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[7] ^
- + macArray[3] ^ macArray[2] ^ macArray[1];
- +
- + crc[4] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[41] ^
- + macArray[39] ^ macArray[36] ^ macArray[35] ^ macArray[31] ^
- + macArray[30] ^ macArray[27] ^ macArray[26] ^ macArray[24] ^
- + macArray[19] ^ macArray[17] ^ macArray[15] ^ macArray[14] ^
- + macArray[12] ^ macArray[10] ^ macArray[8] ^ macArray[4] ^
- + macArray[3] ^ macArray[2];
- +
- + crc[5] = macArray[47] ^ macArray[46] ^ macArray[45] ^ macArray[42] ^
- + macArray[40] ^ macArray[37] ^ macArray[36] ^ macArray[32] ^
- + macArray[31] ^ macArray[28] ^ macArray[27] ^ macArray[25] ^
- + macArray[20] ^ macArray[18] ^ macArray[16] ^ macArray[15] ^
- + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[5] ^
- + macArray[4] ^ macArray[3];
- +
- + crc[6] = macArray[47] ^ macArray[46] ^ macArray[43] ^ macArray[41] ^
- + macArray[38] ^ macArray[37] ^ macArray[33] ^ macArray[32] ^
- + macArray[29] ^ macArray[28] ^ macArray[26] ^ macArray[21] ^
- + macArray[19] ^ macArray[17] ^ macArray[16] ^ macArray[14] ^
- + macArray[12] ^ macArray[10] ^ macArray[6] ^ macArray[5] ^
- + macArray[4];
- +
- + crc[7] = macArray[47] ^ macArray[44] ^ macArray[42] ^ macArray[39] ^
- + macArray[38] ^ macArray[34] ^ macArray[33] ^ macArray[30] ^
- + macArray[29] ^ macArray[27] ^ macArray[22] ^ macArray[20] ^
- + macArray[18] ^ macArray[17] ^ macArray[15] ^ macArray[13] ^
- + macArray[11] ^ macArray[7] ^ macArray[6] ^ macArray[5];
- +
- + for(i=0; i<8; i++)
- + crcResult = crcResult | (crc[i] << i);
- +
- + return crcResult;
- +}
- +/*******************************************************************************
- +* mvEthMcastAddrSet - Multicast address settings.
- +*
- +* DESCRIPTION:
- +* This API controls the MV device MAC multicast support.
- +* The MV device supports multicast using two tables:
- +* 1) Special Multicast Table for MAC addresses of the form
- +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
- +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
- +* Table entries in the DA-Filter table.
- +* In this case, the function calls ethPortSmcAddr() routine to set the
- +* Special Multicast Table.
- +* 2) Other Multicast Table for multicast of another type. A CRC-8bit
- +* is used as an index to the Other Multicast Table entries in the
- +* DA-Filter table.
- +* In this case, the function calculates the CRC-8bit value and calls
- +* ethPortOmcAddr() routine to set the Other Multicast Table.
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet port handler.
- +* MV_U8* pAddr - Address to be set
- +* int queue - RX queue to capture all packets with this
- +* Multicast MAC address.
- +* -1 means delete this Multicast address.
- +*
- +* RETURN: MV_STATUS
- +* MV_TRUE - Success, Other - Failure
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthMcastAddrSet(void* pPortHndl, MV_U8 *pAddr, int queue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + unsigned char crcResult = 0;
- +
- + if(queue >= MV_ETH_RX_Q_NUM)
- + {
- + mvOsPrintf("ethPort %d: RX queue #%d is out of range\n",
- + pPortCtrl->portNo, queue);
- + return MV_BAD_PARAM;
- + }
- +
- + if((pAddr[0] == 0x01) &&
- + (pAddr[1] == 0x00) &&
- + (pAddr[2] == 0x5E) &&
- + (pAddr[3] == 0x00) &&
- + (pAddr[4] == 0x00))
- + {
- + ethSetSpecialMcastAddr(pPortCtrl->portNo, pAddr[5], queue);
- + }
- + else
- + {
- + crcResult = mvEthMcastCrc8Get(pAddr);
- +
- + /* Check Add counter for this CRC value */
- + if(queue == -1)
- + {
- + if(pPortCtrl->mcastCount[crcResult] == 0)
- + {
- + mvOsPrintf("ethPort #%d: No valid Mcast for crc8=0x%02x\n",
- + pPortCtrl->portNo, (unsigned)crcResult);
- + return MV_NO_SUCH;
- + }
- +
- + pPortCtrl->mcastCount[crcResult]--;
- + if(pPortCtrl->mcastCount[crcResult] != 0)
- + {
- + mvOsPrintf("ethPort #%d: After delete there are %d valid Mcast for crc8=0x%02x\n",
- + pPortCtrl->portNo, pPortCtrl->mcastCount[crcResult],
- + (unsigned)crcResult);
- + return MV_NO_CHANGE;
- + }
- + }
- + else
- + {
- + pPortCtrl->mcastCount[crcResult]++;
- + if(pPortCtrl->mcastCount[crcResult] > 1)
- + {
- + mvOsPrintf("ethPort #%d: Valid Mcast for crc8=0x%02x already exists\n",
- + pPortCtrl->portNo, (unsigned)crcResult);
- + return MV_NO_CHANGE;
- + }
- + }
- + ethSetOtherMcastAddr(pPortCtrl->portNo, crcResult, queue);
- + }
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* ethSetUcastTable - Unicast address settings.
- +*
- +* DESCRIPTION:
- +* Set all entries in the Unicast MAC Table queue==-1 means reject all
- +* INPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +static void ethSetUcastTable(int portNo, int queue)
- +{
- + int offset;
- + MV_U32 regValue;
- +
- + if(queue == -1)
- + {
- + regValue = 0;
- + }
- + else
- + {
- + regValue = (((0x01 | (queue<<1)) << 0) |
- + ((0x01 | (queue<<1)) << 8) |
- + ((0x01 | (queue<<1)) << 16) |
- + ((0x01 | (queue<<1)) << 24));
- + }
- +
- + for (offset=0; offset<=0xC; offset+=4)
- + MV_REG_WRITE((ETH_DA_FILTER_UCAST_BASE(portNo) + offset), regValue);
- +}
- +
- +/*******************************************************************************
- +* mvEthSetSpecialMcastTable - Special Multicast address settings.
- +*
- +* DESCRIPTION:
- +* Set all entries to the Special Multicast MAC Table. queue==-1 means reject all
- +* INPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue)
- +{
- + int offset;
- + MV_U32 regValue;
- +
- + if(queue == -1)
- + {
- + regValue = 0;
- + }
- + else
- + {
- + regValue = (((0x01 | (queue<<1)) << 0) |
- + ((0x01 | (queue<<1)) << 8) |
- + ((0x01 | (queue<<1)) << 16) |
- + ((0x01 | (queue<<1)) << 24));
- + }
- +
- + for (offset=0; offset<=0xFC; offset+=4)
- + {
- + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(portNo) +
- + offset), regValue);
- + }
- +}
- +
- +/*******************************************************************************
- +* mvEthSetOtherMcastTable - Other Multicast address settings.
- +*
- +* DESCRIPTION:
- +* Set all entries to the Other Multicast MAC Table. queue==-1 means reject all
- +* INPUT:
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue)
- +{
- + int offset;
- + MV_U32 regValue;
- +
- + if(queue == -1)
- + {
- + regValue = 0;
- + }
- + else
- + {
- + regValue = (((0x01 | (queue<<1)) << 0) |
- + ((0x01 | (queue<<1)) << 8) |
- + ((0x01 | (queue<<1)) << 16) |
- + ((0x01 | (queue<<1)) << 24));
- + }
- +
- + for (offset=0; offset<=0xFC; offset+=4)
- + {
- + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(portNo) +
- + offset), regValue);
- + }
- +}
- +
- +/*******************************************************************************
- +* ethSetUcastAddr - This function Set the port unicast address table
- +*
- +* DESCRIPTION:
- +* This function locates the proper entry in the Unicast table for the
- +* specified MAC nibble and sets its properties according to function
- +* parameters.
- +*
- +* INPUT:
- +* int ethPortNum - Port number.
- +* MV_U8 lastNibble - Unicast MAC Address last nibble.
- +* int queue - Rx queue number for this MAC address.
- +* value "-1" means remove address
- +*
- +* OUTPUT:
- +* This function add/removes MAC addresses from the port unicast address
- +* table.
- +*
- +* RETURN:
- +* MV_TRUE is output succeeded.
- +* MV_FALSE if option parameter is invalid.
- +*
- +*******************************************************************************/
- +static MV_BOOL ethSetUcastAddr(int portNo, MV_U8 lastNibble, int queue)
- +{
- + unsigned int unicastReg;
- + unsigned int tblOffset;
- + unsigned int regOffset;
- +
- + /* Locate the Unicast table entry */
- + lastNibble = (0xf & lastNibble);
- + tblOffset = (lastNibble / 4) * 4; /* Register offset from unicast table base*/
- + regOffset = lastNibble % 4; /* Entry offset within the above register */
- +
- +
- + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(portNo) +
- + tblOffset));
- +
- +
- + if(queue == -1)
- + {
- + /* Clear accepts frame bit at specified unicast DA table entry */
- + unicastReg &= ~(0xFF << (8*regOffset));
- + }
- + else
- + {
- + unicastReg &= ~(0xFF << (8*regOffset));
- + unicastReg |= ((0x01 | (queue<<1)) << (8*regOffset));
- + }
- + MV_REG_WRITE( (ETH_DA_FILTER_UCAST_BASE(portNo) + tblOffset),
- + unicastReg);
- +
- + return MV_TRUE;
- +}
- +
- +/*******************************************************************************
- +* ethSetSpecialMcastAddr - Special Multicast address settings.
- +*
- +* DESCRIPTION:
- +* This routine controls the MV device special MAC multicast support.
- +* The Special Multicast Table for MAC addresses supports MAC of the form
- +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
- +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
- +* Table entries in the DA-Filter table.
- +* This function set the Special Multicast Table appropriate entry
- +* according to the argument given.
- +*
- +* INPUT:
- +* int ethPortNum Port number.
- +* unsigned char mcByte Multicast addr last byte (MAC DA[7:0] bits).
- +* int queue Rx queue number for this MAC address.
- +* int option 0 = Add, 1 = remove address.
- +*
- +* OUTPUT:
- +* See description.
- +*
- +* RETURN:
- +* MV_TRUE is output succeeded.
- +* MV_FALSE if option parameter is invalid.
- +*
- +*******************************************************************************/
- +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue)
- +{
- + unsigned int smcTableReg;
- + unsigned int tblOffset;
- + unsigned int regOffset;
- +
- + /* Locate the SMC table entry */
- + tblOffset = (lastByte / 4); /* Register offset from SMC table base */
- + regOffset = lastByte % 4; /* Entry offset within the above register */
- +
- + smcTableReg = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + tblOffset*4));
- +
- + if(queue == -1)
- + {
- + /* Clear accepts frame bit at specified Special DA table entry */
- + smcTableReg &= ~(0xFF << (8 * regOffset));
- + }
- + else
- + {
- + smcTableReg &= ~(0xFF << (8 * regOffset));
- + smcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
- + }
- + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) +
- + tblOffset*4), smcTableReg);
- +
- + return MV_TRUE;
- +}
- +
- +/*******************************************************************************
- +* ethSetOtherMcastAddr - Multicast address settings.
- +*
- +* DESCRIPTION:
- +* This routine controls the MV device Other MAC multicast support.
- +* The Other Multicast Table is used for multicast of another type.
- +* A CRC-8bit is used as an index to the Other Multicast Table entries
- +* in the DA-Filter table.
- +* The function gets the CRC-8bit value from the calling routine and
- +* set the Other Multicast Table appropriate entry according to the
- +* CRC-8 argument given.
- +*
- +* INPUT:
- +* int ethPortNum Port number.
- +* MV_U8 crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
- +* int queue Rx queue number for this MAC address.
- +*
- +* OUTPUT:
- +* See description.
- +*
- +* RETURN:
- +* MV_TRUE is output succeeded.
- +* MV_FALSE if option parameter is invalid.
- +*
- +*******************************************************************************/
- +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue)
- +{
- + unsigned int omcTableReg;
- + unsigned int tblOffset;
- + unsigned int regOffset;
- +
- + /* Locate the OMC table entry */
- + tblOffset = (crc8 / 4) * 4; /* Register offset from OMC table base */
- + regOffset = crc8 % 4; /* Entry offset within the above register */
- +
- + omcTableReg = MV_REG_READ(
- + (ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset));
- +
- + if(queue == -1)
- + {
- + /* Clear accepts frame bit at specified Other DA table entry */
- + omcTableReg &= ~(0xFF << (8 * regOffset));
- + }
- + else
- + {
- + omcTableReg &= ~(0xFF << (8 * regOffset));
- + omcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
- + }
- +
- + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset),
- + omcTableReg);
- +
- + return MV_TRUE;
- +}
- +
- +
- +/******************************************************************************/
- +/* MIB Counters functions */
- +/******************************************************************************/
- +
- +
- +/*******************************************************************************
- +* mvEthMibCounterRead - Read a MIB counter
- +*
- +* DESCRIPTION:
- +* This function reads a MIB counter of a specific ethernet port.
- +* NOTE - Read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW or
- +* ETH_MIB_GOOD_OCTETS_SENT_LOW counters will return 64 bits value,
- +* so pHigh32 pointer should not be NULL in this case.
- +*
- +* INPUT:
- +* int ethPortNum - Ethernet Port number.
- +* unsigned int mibOffset - MIB counter offset.
- +*
- +* OUTPUT:
- +* MV_U32* pHigh32 - pointer to place where 32 most significant bits
- +* of the counter will be stored.
- +*
- +* RETURN:
- +* 32 low sgnificant bits of MIB counter value.
- +*
- +*******************************************************************************/
- +MV_U32 mvEthMibCounterRead(void* pPortHandle, unsigned int mibOffset,
- + MV_U32* pHigh32)
- +{
- + int portNo;
- + MV_U32 valLow32, valHigh32;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- +
- + portNo = pPortCtrl->portNo;
- +
- + valLow32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset);
- +
- + /* Implement FEr ETH. Erroneous Value when Reading the Upper 32-bits */
- + /* of a 64-bit MIB Counter. */
- + if( (mibOffset == ETH_MIB_GOOD_OCTETS_RECEIVED_LOW) ||
- + (mibOffset == ETH_MIB_GOOD_OCTETS_SENT_LOW) )
- + {
- + valHigh32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset + 4);
- + if(pHigh32 != NULL)
- + *pHigh32 = valHigh32;
- + }
- + return valLow32;
- +}
- +
- +/*******************************************************************************
- +* mvEthMibCountersClear - Clear all MIB counters
- +*
- +* DESCRIPTION:
- +* This function clears all MIB counters
- +*
- +* INPUT:
- +* int ethPortNum - Ethernet Port number.
- +*
- +*
- +* RETURN: void
- +*
- +*******************************************************************************/
- +void mvEthMibCountersClear(void* pPortHandle)
- +{
- + int i, portNo;
- + unsigned int dummy;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- +
- + portNo = pPortCtrl->portNo;
- +
- + /* Perform dummy reads from MIB counters */
- + for(i=ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i<ETH_MIB_LATE_COLLISION; i+=4)
- + dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(portNo) + i));
- +}
- +
- +
- +/******************************************************************************/
- +/* RX Dispatching configuration routines */
- +/******************************************************************************/
- +
- +int mvEthTosToRxqGet(void* pPortHandle, int tos)
- +{
- + MV_U32 regValue;
- + int regIdx, regOffs, rxq;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- +
- + if(tos > 0xFF)
- + {
- + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
- + return -1;
- + }
- + regIdx = mvOsDivide(tos>>2, 10);
- + regOffs = mvOsReminder(tos>>2, 10);
- +
- + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
- + rxq = (regValue >> (regOffs*3));
- + rxq &= 0x7;
- +
- + return rxq;
- +}
- +
- +/*******************************************************************************
- +* mvEthTosToRxqSet - Map packets with special TOS value to special RX queue
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* int tos - TOS value in the IP header of the packet
- +* int rxq - RX Queue for packets with the configured TOS value
- +* Negative value (-1) means no special processing for these packets,
- +* so they will be processed as regular packets.
- +*
- +* RETURN: MV_STATUS
- +*******************************************************************************/
- +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq)
- +{
- + MV_U32 regValue;
- + int regIdx, regOffs;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- +
- + if( (rxq < 0) || (rxq >= MV_ETH_RX_Q_NUM) )
- + {
- + mvOsPrintf("eth_%d: RX queue #%d is out of range\n", pPortCtrl->portNo, rxq);
- + return MV_BAD_PARAM;
- + }
- + if(tos > 0xFF)
- + {
- + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
- + return MV_BAD_PARAM;
- + }
- + regIdx = mvOsDivide(tos>>2, 10);
- + regOffs = mvOsReminder(tos>>2, 10);
- +
- + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
- + regValue &= ~(0x7 << (regOffs*3));
- + regValue |= (rxq << (regOffs*3));
- +
- + MV_REG_WRITE(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx), regValue);
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthVlanPrioRxQueue - Configure RX queue to capture VLAN tagged packets with
- +* special priority bits [0-2]
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* int bpduQueue - Special queue to capture VLAN tagged packets with special
- +* priority.
- +* Negative value (-1) means no special processing for these packets,
- +* so they will be processed as regular packets.
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_FAIL - Failed.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + MV_U32 vlanPrioReg;
- +
- + if(vlanPrioQueue >= MV_ETH_RX_Q_NUM)
- + {
- + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", vlanPrioQueue);
- + return MV_BAD_PARAM;
- + }
- + if(vlanPrio >= 8)
- + {
- + mvOsPrintf("ethDrv: vlanPrio=%d is out of range\n", vlanPrio);
- + return MV_BAD_PARAM;
- + }
- +
- + vlanPrioReg = MV_REG_READ(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo));
- + vlanPrioReg &= ~(0x7 << (vlanPrio*3));
- + vlanPrioReg |= (vlanPrioQueue << (vlanPrio*3));
- + MV_REG_WRITE(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo), vlanPrioReg);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvEthBpduRxQueue - Configure RX queue to capture BPDU packets.
- +*
- +* DESCRIPTION:
- +* This function defines processing of BPDU packets.
- +* BPDU packets can be accepted and captured to one of RX queues
- +* or can be processing as regular Multicast packets.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* int bpduQueue - Special queue to capture BPDU packets (DA is equal to
- +* 01-80-C2-00-00-00 through 01-80-C2-00-00-FF,
- +* except for the Flow-Control Pause packets).
- +* Negative value (-1) means no special processing for BPDU,
- +* packets so they will be processed as regular Multicast packets.
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_FAIL - Failed.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + MV_U32 portCfgReg;
- + MV_U32 portCfgExtReg;
- +
- + if(bpduQueue >= MV_ETH_RX_Q_NUM)
- + {
- + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", bpduQueue);
- + return MV_BAD_PARAM;
- + }
- +
- + portCfgExtReg = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo));
- +
- + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
- + if(bpduQueue >= 0)
- + {
- + pPortCtrl->portConfig.rxBpduQ = bpduQueue;
- +
- + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
- +
- + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
- +
- + portCfgExtReg |= ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK;
- + }
- + else
- + {
- + pPortCtrl->portConfig.rxBpduQ = -1;
- + /* no special processing for BPDU packets */
- + portCfgExtReg &= (~ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK);
- + }
- +
- + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo), portCfgExtReg);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvEthArpRxQueue - Configure RX queue to capture ARP packets.
- +*
- +* DESCRIPTION:
- +* This function defines processing of ARP (type=0x0806) packets.
- +* ARP packets can be accepted and captured to one of RX queues
- +* or can be processed as other Broadcast packets.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* int arpQueue - Special queue to capture ARP packets (type=0x806).
- +* Negative value (-1) means discard ARP packets
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_FAIL - Failed.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + MV_U32 portCfgReg;
- +
- + if(arpQueue >= MV_ETH_RX_Q_NUM)
- + {
- + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", arpQueue);
- + return MV_BAD_PARAM;
- + }
- +
- + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
- +
- + if(arpQueue >= 0)
- + {
- + pPortCtrl->portConfig.rxArpQ = arpQueue;
- + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
- +
- + portCfgReg &= (~ETH_REJECT_ARP_BCAST_MASK);
- + }
- + else
- + {
- + pPortCtrl->portConfig.rxArpQ = -1;
- + portCfgReg |= ETH_REJECT_ARP_BCAST_MASK;
- + }
- +
- + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvEthTcpRxQueue - Configure RX queue to capture TCP packets.
- +*
- +* DESCRIPTION:
- +* This function defines processing of TCP packets.
- +* TCP packets can be accepted and captured to one of RX queues
- +* or can be processed as regular Unicast packets.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* int tcpQueue - Special queue to capture TCP packets. Value "-1"
- +* means no special processing for TCP packets,
- +* so they will be processed as regular
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_FAIL - Failed.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + MV_U32 portCfgReg;
- +
- + if(tcpQueue >= MV_ETH_RX_Q_NUM)
- + {
- + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", tcpQueue);
- + return MV_BAD_PARAM;
- + }
- + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
- +
- + if(tcpQueue >= 0)
- + {
- + pPortCtrl->portConfig.rxTcpQ = tcpQueue;
- + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
- +
- + portCfgReg |= ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK;
- + }
- + else
- + {
- + pPortCtrl->portConfig.rxTcpQ = -1;
- + portCfgReg &= (~ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK);
- + }
- +
- + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvEthUdpRxQueue - Configure RX queue to capture UDP packets.
- +*
- +* DESCRIPTION:
- +* This function defines processing of UDP packets.
- +* TCP packets can be accepted and captured to one of RX queues
- +* or can be processed as regular Unicast packets.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* int udpQueue - Special queue to capture UDP packets. Value "-1"
- +* means no special processing for UDP packets,
- +* so they will be processed as regular
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_FAIL - Failed.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + MV_U32 portCfgReg;
- +
- + if(udpQueue >= MV_ETH_RX_Q_NUM)
- + {
- + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", udpQueue);
- + return MV_BAD_PARAM;
- + }
- +
- + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
- +
- + if(udpQueue >= 0)
- + {
- + pPortCtrl->portConfig.rxUdpQ = udpQueue;
- + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
- + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
- +
- + portCfgReg |= ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
- + }
- + else
- + {
- + pPortCtrl->portConfig.rxUdpQ = -1;
- + portCfgReg &= ~ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
- + }
- +
- + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
- +
- + return MV_OK;
- +}
- +
- +
- +/******************************************************************************/
- +/* Speed, Duplex, FlowControl routines */
- +/******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEthSpeedDuplexSet - Set Speed and Duplex of the port.
- +*
- +* DESCRIPTION:
- +* This function configure the port to work with desirable Duplex and Speed.
- +* Changing of these parameters are allowed only when port is disabled.
- +* This function disable the port if was enabled, change duplex and speed
- +* and, enable the port back if needed.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* ETH_PORT_SPEED speed - Speed of the port.
- +* ETH_PORT_SPEED duplex - Duplex of the port.
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
- +* MV_NOT_FOUND - Failed. Port is not initialized.
- +* MV_BAD_PARAM - Input parameters (speed/duplex) in conflict.
- +* MV_BAD_VALUE - Value of one of input parameters (speed, duplex)
- +* is not valid
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
- + MV_ETH_PORT_DUPLEX duplex)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + int port = pPortCtrl->portNo;
- + MV_U32 portSerialCtrlReg;
- +
- + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet()) )
- + return MV_OUT_OF_RANGE;
- +
- + pPortCtrl = ethPortCtrl[port];
- + if(pPortCtrl == NULL)
- + return MV_NOT_FOUND;
- +
- + /* Check validity */
- + if( (speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF) )
- + return MV_BAD_PARAM;
- +
- + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
- + /* Set Speed */
- + switch(speed)
- + {
- + case MV_ETH_SPEED_AN:
- + portSerialCtrlReg &= ~ETH_DISABLE_SPEED_AUTO_NEG_MASK;
- + break;
- +
- + case MV_ETH_SPEED_10:
- + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
- + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
- + portSerialCtrlReg &= ~ETH_SET_MII_SPEED_100_MASK;
- + break;
- +
- + case MV_ETH_SPEED_100:
- + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
- + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
- + portSerialCtrlReg |= ETH_SET_MII_SPEED_100_MASK;
- + break;
- +
- + case MV_ETH_SPEED_1000:
- + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
- + portSerialCtrlReg |= ETH_SET_GMII_SPEED_1000_MASK;
- + break;
- +
- + default:
- + mvOsPrintf("ethDrv: Unexpected Speed value %d\n", speed);
- + return MV_BAD_VALUE;
- + }
- + /* Set duplex */
- + switch(duplex)
- + {
- + case MV_ETH_DUPLEX_AN:
- + portSerialCtrlReg &= ~ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
- + break;
- +
- + case MV_ETH_DUPLEX_HALF:
- + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
- + portSerialCtrlReg &= ~ETH_SET_FULL_DUPLEX_MASK;
- + break;
- +
- + case MV_ETH_DUPLEX_FULL:
- + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
- + portSerialCtrlReg |= ETH_SET_FULL_DUPLEX_MASK;
- + break;
- +
- + default:
- + mvOsPrintf("ethDrv: Unexpected Duplex value %d\n", duplex);
- + return MV_BAD_VALUE;
- + }
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthFlowCtrlSet - Set Flow Control of the port.
- +*
- +* DESCRIPTION:
- +* This function configure the port to work with desirable Duplex and
- +* Speed. Changing of these parameters are allowed only when port is
- +* disabled. This function disable the port if was enabled, change
- +* duplex and speed and, enable the port back if needed.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* MV_ETH_PORT_FC flowControl - Flow control of the port.
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
- +* MV_NOT_FOUND - Failed. Port is not initialized.
- +* MV_BAD_VALUE - Value flowControl parameters is not valid
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + int port = pPortCtrl->portNo;
- + MV_U32 portSerialCtrlReg;
- +
- + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet() ) )
- + return MV_OUT_OF_RANGE;
- +
- + pPortCtrl = ethPortCtrl[port];
- + if(pPortCtrl == NULL)
- + return MV_NOT_FOUND;
- +
- + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
- + switch(flowControl)
- + {
- + case MV_ETH_FC_AN_ADV_DIS:
- + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
- + portSerialCtrlReg &= ~ETH_ADVERTISE_SYM_FC_MASK;
- + break;
- +
- + case MV_ETH_FC_AN_ADV_SYM:
- + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
- + portSerialCtrlReg |= ETH_ADVERTISE_SYM_FC_MASK;
- + break;
- +
- + case MV_ETH_FC_DISABLE:
- + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
- + portSerialCtrlReg &= ~ETH_SET_FLOW_CTRL_MASK;
- + break;
- +
- + case MV_ETH_FC_ENABLE:
- + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
- + portSerialCtrlReg |= ETH_SET_FLOW_CTRL_MASK;
- + break;
- +
- + default:
- + mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl);
- + return MV_BAD_VALUE;
- + }
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthHeaderModeSet - Set port header mode.
- +*
- +* DESCRIPTION:
- +* This function configures the port to work in Marvell-Header mode.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* MV_ETH_HEADER_MODE headerMode - The header mode to set the port in.
- +*
- +* RETURN: MV_STATUS
- +* MV_OK - Success
- +* MV_NOT_SUPPORTED- Feature not supported.
- +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
- +* MV_NOT_FOUND - Failed. Port is not initialized.
- +* MV_BAD_VALUE - Value of headerMode or numRxQueue parameter is not valid.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + int port = pPortCtrl->portNo;
- + MV_U32 mvHeaderReg;
- + MV_U32 numRxQ = MV_ETH_RX_Q_NUM;
- +
- + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
- + return MV_OUT_OF_RANGE;
- +
- + pPortCtrl = ethPortCtrl[port];
- + if(pPortCtrl == NULL)
- + return MV_NOT_FOUND;
- +
- + mvHeaderReg = MV_REG_READ(ETH_PORT_MARVELL_HEADER_REG(port));
- + /* Disable header mode. */
- + mvHeaderReg &= ~ETH_MVHDR_EN_MASK;
- +
- + if(headerMode != MV_ETH_DISABLE_HEADER_MODE)
- + {
- + /* Enable Header mode. */
- + mvHeaderReg |= ETH_MVHDR_EN_MASK;
- +
- + /* Clear DA-Prefix & MHMask fields.*/
- + mvHeaderReg &= ~(ETH_MVHDR_DAPREFIX_MASK | ETH_MVHDR_MHMASK_MASK);
- +
- + if(numRxQ > 1)
- + {
- + switch (headerMode)
- + {
- + case(MV_ETH_ENABLE_HEADER_MODE_PRI_2_1):
- + mvHeaderReg |= ETH_MVHDR_DAPREFIX_PRI_1_2;
- + break;
- + case(MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM):
- + mvHeaderReg |= ETH_MVHDR_DAPREFIX_DBNUM_PRI;
- + break;
- + case(MV_ETH_ENABLE_HEADER_MODE_PRI_SPID):
- + mvHeaderReg |= ETH_MVHDR_DAPREFIX_SPID_PRI;
- + break;
- + default:
- + break;
- + }
- +
- + switch (numRxQ)
- + {
- + case (4):
- + mvHeaderReg |= ETH_MVHDR_MHMASK_4_QUEUE;
- + break;
- + case (8):
- + mvHeaderReg |= ETH_MVHDR_MHMASK_8_QUEUE;
- + break;
- + default:
- + break;
- + }
- + }
- + }
- +
- + MV_REG_WRITE(ETH_PORT_MARVELL_HEADER_REG(port), mvHeaderReg);
- +
- + return MV_OK;
- +}
- +
- +#if (MV_ETH_VERSION >= 4)
- +/*******************************************************************************
- +* mvEthEjpModeSet - Enable / Disable EJP policy for TX.
- +*
- +* DESCRIPTION:
- +* This function
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* MV_BOOL TRUE - enable EJP mode
- +* FALSE - disable EJP mode
- +*
- +* OUTPUT: MV_STATUS
- +* MV_OK - Success
- +* Other - Failure
- +*
- +* RETURN: None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + int port = pPortCtrl->portNo;
- +
- + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
- + return MV_OUT_OF_RANGE;
- +
- + pPortCtrl = ethPortCtrl[port];
- + if(pPortCtrl == NULL)
- + return MV_NOT_FOUND;
- +
- + pPortCtrl->portConfig.ejpMode = mode;
- + if(mode)
- + {
- + /* EJP enabled */
- + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), ETH_TX_EJP_ENABLE_MASK);
- + }
- + else
- + {
- + /* EJP disabled */
- + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), 0);
- + }
- + mvOsPrintf("eth_%d: EJP %s - ETH_TXQ_CMD_1_REG: 0x%x = 0x%08x\n",
- + port, mode ? "Enabled" : "Disabled", ETH_TXQ_CMD_1_REG(port),
- + MV_REG_READ(ETH_TXQ_CMD_1_REG(port)));
- +
- + return MV_OK;
- +}
- +#endif /* MV_ETH_VERSION >= 4 */
- +
- +/*******************************************************************************
- +* mvEthStatusGet - Get major properties of the port .
- +*
- +* DESCRIPTION:
- +* This function get major properties of the port (link, speed, duplex,
- +* flowControl, etc) and return them using the single structure.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +*
- +* OUTPUT:
- +* MV_ETH_PORT_STATUS* pStatus - Pointer to structure, were port status
- +* will be placed.
- +*
- +* RETURN: None.
- +*
- +*******************************************************************************/
- +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + int port = pPortCtrl->portNo;
- +
- + MV_U32 regValue;
- +
- + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
- +
- + if(regValue & ETH_GMII_SPEED_1000_MASK)
- + pStatus->speed = MV_ETH_SPEED_1000;
- + else if(regValue & ETH_MII_SPEED_100_MASK)
- + pStatus->speed = MV_ETH_SPEED_100;
- + else
- + pStatus->speed = MV_ETH_SPEED_10;
- +
- + if(regValue & ETH_LINK_UP_MASK)
- + pStatus->isLinkUp = MV_TRUE;
- + else
- + pStatus->isLinkUp = MV_FALSE;
- +
- + if(regValue & ETH_FULL_DUPLEX_MASK)
- + pStatus->duplex = MV_ETH_DUPLEX_FULL;
- + else
- + pStatus->duplex = MV_ETH_DUPLEX_HALF;
- +
- +
- + if(regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK)
- + pStatus->flowControl = MV_ETH_FC_ENABLE;
- + else
- + pStatus->flowControl = MV_ETH_FC_DISABLE;
- +}
- +
- +
- +/******************************************************************************/
- +/* PHY Control Functions */
- +/******************************************************************************/
- +
- +
- +/*******************************************************************************
- +* mvEthPhyAddrSet - Set the ethernet port PHY address.
- +*
- +* DESCRIPTION:
- +* This routine set the ethernet port PHY address according to given
- +* parameter.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +* int phyAddr - PHY address
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + int port = pPortCtrl->portNo;
- + unsigned int regData;
- +
- + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
- +
- + regData &= ~ETH_PHY_ADDR_MASK;
- + regData |= phyAddr;
- +
- + MV_REG_WRITE(ETH_PHY_ADDR_REG(port), regData);
- +
- + return;
- +}
- +
- +/*******************************************************************************
- +* mvEthPhyAddrGet - Get the ethernet port PHY address.
- +*
- +* DESCRIPTION:
- +* This routine returns the given ethernet port PHY address.
- +*
- +* INPUT:
- +* void* pPortHandle - Pointer to port specific handler;
- +*
- +*
- +* RETURN: int - PHY address.
- +*
- +*******************************************************************************/
- +int mvEthPhyAddrGet(void* pPortHandle)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
- + int port = pPortCtrl->portNo;
- + unsigned int regData;
- +
- + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
- +
- + return ((regData >> (5 * port)) & 0x1f);
- +}
- +
- +/******************************************************************************/
- +/* Descriptor handling Functions */
- +/******************************************************************************/
- +
- +/*******************************************************************************
- +* etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.
- +*
- +* DESCRIPTION:
- +* This function prepares a Rx chained list of descriptors and packet
- +* buffers in a form of a ring. The routine must be called after port
- +* initialization routine and before port start routine.
- +* The Ethernet SDMA engine uses CPU bus addresses to access the various
- +* devices in the system (i.e. DRAM). This function uses the ethernet
- +* struct 'virtual to physical' routine (set by the user) to set the ring
- +* with physical addresses.
- +*
- +* INPUT:
- +* ETH_QUEUE_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
- +* int rxQueue Number of Rx queue.
- +* int rxDescNum Number of Rx descriptors
- +* MV_U8* rxDescBaseAddr Rx descriptors memory area base addr.
- +*
- +* OUTPUT:
- +* The routine updates the Ethernet port control struct with information
- +* regarding the Rx descriptors and buffers.
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
- +{
- + ETH_RX_DESC *pRxDescBase, *pRxDesc, *pRxPrevDesc;
- + int ix, rxDescNum = pPortCtrl->rxQueueConfig[queue].descrNum;
- + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->rxQueue[queue];
- +
- + /* Make sure descriptor address is cache line size aligned */
- + pRxDescBase = (ETH_RX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
- + CPU_D_CACHE_LINE_SIZE);
- +
- + pRxDesc = (ETH_RX_DESC*)pRxDescBase;
- + pRxPrevDesc = pRxDesc;
- +
- + /* initialize the Rx descriptors ring */
- + for (ix=0; ix<rxDescNum; ix++)
- + {
- + pRxDesc->bufSize = 0x0;
- + pRxDesc->byteCnt = 0x0;
- + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
- + pRxDesc->bufPtr = 0x0;
- + pRxDesc->returnInfo = 0x0;
- + pRxPrevDesc = pRxDesc;
- + if(ix == (rxDescNum-1))
- + {
- + /* Closing Rx descriptors ring */
- + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDescBase);
- + }
- + else
- + {
- + pRxDesc = (ETH_RX_DESC*)((MV_ULONG)pRxDesc + ETH_RX_DESC_ALIGNED_SIZE);
- + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDesc);
- + }
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxPrevDesc);
- + }
- +
- + pQueueCtrl->pCurrentDescr = pRxDescBase;
- + pQueueCtrl->pUsedDescr = pRxDescBase;
- +
- + pQueueCtrl->pFirstDescr = pRxDescBase;
- + pQueueCtrl->pLastDescr = pRxDesc;
- + pQueueCtrl->resource = 0;
- +}
- +
- +void ethResetRxDescRing(void* pPortHndl, int queue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[queue];
- + ETH_RX_DESC* pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
- +
- + pQueueCtrl->resource = 0;
- + if(pQueueCtrl->pFirstDescr != NULL)
- + {
- + while(MV_TRUE)
- + {
- + pRxDesc->bufSize = 0x0;
- + pRxDesc->byteCnt = 0x0;
- + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
- + pRxDesc->bufPtr = 0x0;
- + pRxDesc->returnInfo = 0x0;
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
- + if( (void*)pRxDesc == pQueueCtrl->pLastDescr)
- + break;
- + pRxDesc = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
- + }
- + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
- + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
- +
- + /* Update RX Command register */
- + pPortCtrl->portRxQueueCmdReg |= (1 << queue);
- +
- + /* update HW */
- + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
- + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
- + }
- + else
- + {
- + /* Update RX Command register */
- + pPortCtrl->portRxQueueCmdReg &= ~(1 << queue);
- +
- + /* update HW */
- + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0);
- + }
- +}
- +
- +/*******************************************************************************
- +* etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.
- +*
- +* DESCRIPTION:
- +* This function prepares a Tx chained list of descriptors and packet
- +* buffers in a form of a ring. The routine must be called after port
- +* initialization routine and before port start routine.
- +* The Ethernet SDMA engine uses CPU bus addresses to access the various
- +* devices in the system (i.e. DRAM). This function uses the ethernet
- +* struct 'virtual to physical' routine (set by the user) to set the ring
- +* with physical addresses.
- +*
- +* INPUT:
- +* ETH_PORT_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
- +* int txQueue Number of Tx queue.
- +* int txDescNum Number of Tx descriptors
- +* int txBuffSize Size of Tx buffer
- +* MV_U8* pTxDescBase Tx descriptors memory area base addr.
- +*
- +* OUTPUT:
- +* The routine updates the Ethernet port control struct with information
- +* regarding the Tx descriptors and buffers.
- +*
- +* RETURN: None.
- +*
- +*******************************************************************************/
- +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
- +{
- + ETH_TX_DESC *pTxDescBase, *pTxDesc, *pTxPrevDesc;
- + int ix, txDescNum = pPortCtrl->txQueueConfig[queue].descrNum;
- + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->txQueue[queue];
- +
- + /* Make sure descriptor address is cache line size aligned */
- + pTxDescBase = (ETH_TX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
- + CPU_D_CACHE_LINE_SIZE);
- +
- + pTxDesc = (ETH_TX_DESC*)pTxDescBase;
- + pTxPrevDesc = pTxDesc;
- +
- + /* initialize the Tx descriptors ring */
- + for (ix=0; ix<txDescNum; ix++)
- + {
- + pTxDesc->byteCnt = 0x0000;
- + pTxDesc->L4iChk = 0x0000;
- + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
- + pTxDesc->bufPtr = 0x0;
- + pTxDesc->returnInfo = 0x0;
- +
- + pTxPrevDesc = pTxDesc;
- +
- + if(ix == (txDescNum-1))
- + {
- + /* Closing Tx descriptors ring */
- + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDescBase);
- + }
- + else
- + {
- + pTxDesc = (ETH_TX_DESC*)((MV_ULONG)pTxDesc + ETH_TX_DESC_ALIGNED_SIZE);
- + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDesc);
- + }
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxPrevDesc);
- + }
- +
- + pQueueCtrl->pCurrentDescr = pTxDescBase;
- + pQueueCtrl->pUsedDescr = pTxDescBase;
- +
- + pQueueCtrl->pFirstDescr = pTxDescBase;
- + pQueueCtrl->pLastDescr = pTxDesc;
- + /* Leave one TX descriptor out of use */
- + pQueueCtrl->resource = txDescNum - 1;
- +}
- +
- +void ethResetTxDescRing(void* pPortHndl, int queue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[queue];
- + ETH_TX_DESC* pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
- +
- + pQueueCtrl->resource = 0;
- + if(pQueueCtrl->pFirstDescr != NULL)
- + {
- + while(MV_TRUE)
- + {
- + pTxDesc->byteCnt = 0x0000;
- + pTxDesc->L4iChk = 0x0000;
- + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
- + pTxDesc->bufPtr = 0x0;
- + pTxDesc->returnInfo = 0x0;
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
- + pQueueCtrl->resource++;
- + if( (void*)pTxDesc == pQueueCtrl->pLastDescr)
- + break;
- + pTxDesc = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
- + }
- + /* Leave one TX descriptor out of use */
- + pQueueCtrl->resource--;
- + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
- + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
- +
- + /* Update TX Command register */
- + pPortCtrl->portTxQueueCmdReg |= MV_32BIT_LE_FAST(1 << queue);
- + /* update HW */
- + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
- + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
- + }
- + else
- + {
- + /* Update TX Command register */
- + pPortCtrl->portTxQueueCmdReg &= MV_32BIT_LE_FAST(~(1 << queue));
- + /* update HW */
- + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0 );
- + }
- +}
- +
- +/*******************************************************************************
- +* ethAllocDescrMemory - Free memory allocated for RX and TX descriptors.
- +*
- +* DESCRIPTION:
- +* This function allocates memory for RX and TX descriptors.
- +* - If ETH_DESCR_IN_SRAM defined, allocate memory from SRAM.
- +* - If ETH_DESCR_IN_SDRAM defined, allocate memory in SDRAM.
- +*
- +* INPUT:
- +* int size - size of memory should be allocated.
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pPortCtrl, int descSize,
- + MV_ULONG* pPhysAddr, MV_U32 *memHandle)
- +{
- + MV_U8* pVirt;
- +
- +#if defined(ETH_DESCR_IN_SRAM)
- + if(ethDescInSram == MV_TRUE)
- + pVirt = (char*)mvSramMalloc(descSize, pPhysAddr);
- + else
- +#endif /* ETH_DESCR_IN_SRAM */
- + {
- +#ifdef ETH_DESCR_UNCACHED
- + pVirt = (MV_U8*)mvOsIoUncachedMalloc(pPortCtrl->osHandle, descSize,
- + pPhysAddr,memHandle);
- +#else
- + pVirt = (MV_U8*)mvOsIoCachedMalloc(pPortCtrl->osHandle, descSize,
- + pPhysAddr, memHandle);
- +#endif /* ETH_DESCR_UNCACHED */
- + }
- + memset(pVirt, 0, descSize);
- +
- + return pVirt;
- +}
- +
- +/*******************************************************************************
- +* ethFreeDescrMemory - Free memory allocated for RX and TX descriptors.
- +*
- +* DESCRIPTION:
- +* This function frees memory allocated for RX and TX descriptors.
- +* - If ETH_DESCR_IN_SRAM defined, free memory using gtSramFree() function.
- +* - If ETH_DESCR_IN_SDRAM defined, free memory using mvOsFree() function.
- +*
- +* INPUT:
- +* void* pVirtAddr - virtual pointer to memory allocated for RX and TX
- +* desriptors.
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +void ethFreeDescrMemory(ETH_PORT_CTRL* pPortCtrl, MV_BUF_INFO* pDescBuf)
- +{
- + if( (pDescBuf == NULL) || (pDescBuf->bufVirtPtr == NULL) )
- + return;
- +
- +#if defined(ETH_DESCR_IN_SRAM)
- + if( ethDescInSram )
- + {
- + mvSramFree(pDescBuf->bufSize, pDescBuf->bufPhysAddr, pDescBuf->bufVirtPtr);
- + return;
- + }
- +#endif /* ETH_DESCR_IN_SRAM */
- +
- +#ifdef ETH_DESCR_UNCACHED
- + mvOsIoUncachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
- + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
- +#else
- + mvOsIoCachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
- + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
- +#endif /* ETH_DESCR_UNCACHED */
- +}
- +
- +/******************************************************************************/
- +/* Other Functions */
- +/******************************************************************************/
- +
- +void mvEthPortPowerUp(int port)
- +{
- + MV_U32 regVal;
- +
- + /* MAC Cause register should be cleared */
- + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
- +
- + if (mvBoardIsPortInSgmii(port))
- + mvEthPortSgmiiConfig(port);
- +
- + /* Cancel Port Reset */
- + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
- + regVal &= (~ETH_PORT_RESET_MASK);
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
- + while( (MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) != 0);
- +}
- +
- +void mvEthPortPowerDown(int port)
- +{
- + MV_U32 regVal;
- +
- + /* Port must be DISABLED */
- + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
- + if( (regVal & ETH_PORT_ENABLE_MASK) != 0)
- + {
- + mvOsPrintf("ethPort #%d: PowerDown - port must be Disabled (PSC=0x%x)\n",
- + port, regVal);
- + return;
- + }
- +
- + /* Port Reset (Read after write the register as a precaution) */
- + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal | ETH_PORT_RESET_MASK);
- + while((MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) == 0);
- +}
- +
- +static void mvEthPortSgmiiConfig(int port)
- +{
- + MV_U32 regVal;
- +
- + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
- +
- + regVal |= (ETH_SGMII_MODE_MASK /*| ETH_INBAND_AUTO_NEG_ENABLE_MASK */);
- + regVal &= (~ETH_INBAND_AUTO_NEG_BYPASS_MASK);
- +
- + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
- +}
- +
- +
- +
- +
- +
- +
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 2010-11-09 20:28:11.072495491 +0100
- @@ -0,0 +1,748 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEthDebug.c - Source file for user friendly debug functions
- +*
- +* DESCRIPTION:
- +*
- +* DEPENDENCIES:
- +* None.
- +*
- +*******************************************************************************/
- +
- +#include "mvOs.h"
- +#include "mvCommon.h"
- +#include "mvTypes.h"
- +#include "mv802_3.h"
- +#include "mvDebug.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "eth-phy/mvEthPhy.h"
- +#include "eth/mvEth.h"
- +#include "eth/gbe/mvEthDebug.h"
- +
- +/* #define mvOsPrintf printf */
- +
- +void mvEthPortShow(void* pHndl);
- +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
- +
- +/******************************************************************************/
- +/* Debug functions */
- +/******************************************************************************/
- +void ethRxCoal(int port, int usec)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthRxCoalSet(pHndl, usec);
- + }
- +}
- +
- +void ethTxCoal(int port, int usec)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthTxCoalSet(pHndl, usec);
- + }
- +}
- +
- +#if (MV_ETH_VERSION >= 4)
- +void ethEjpModeSet(int port, int mode)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthEjpModeSet(pHndl, mode);
- + }
- +}
- +#endif /* (MV_ETH_VERSION >= 4) */
- +
- +void ethBpduRxQ(int port, int bpduQueue)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthBpduRxQueue(pHndl, bpduQueue);
- + }
- +}
- +
- +void ethArpRxQ(int port, int arpQueue)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthArpRxQueue(pHndl, arpQueue);
- + }
- +}
- +
- +void ethTcpRxQ(int port, int tcpQueue)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthTcpRxQueue(pHndl, tcpQueue);
- + }
- +}
- +
- +void ethUdpRxQ(int port, int udpQueue)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthUdpRxQueue(pHndl, udpQueue);
- + }
- +}
- +
- +void ethTxPolicyRegs(int port)
- +{
- + int queue;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)mvEthPortHndlGet(port);
- +
- + if(pPortCtrl == NULL)
- + {
- + return;
- + }
- + mvOsPrintf("Port #%d TX Policy: EJP=%d, TXQs: ",
- + port, pPortCtrl->portConfig.ejpMode);
- + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
- + {
- + if(pPortCtrl->txQueueConfig[queue].descrNum > 0)
- + mvOsPrintf("%d, ", queue);
- + }
- + mvOsPrintf("\n");
- +
- + mvOsPrintf("\n\t TX policy Port #%d configuration registers\n", port);
- +
- + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
- + ETH_TX_QUEUE_COMMAND_REG(port),
- + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
- +
- + mvOsPrintf("ETH_TX_FIXED_PRIO_CFG_REG : 0x%X = 0x%08x\n",
- + ETH_TX_FIXED_PRIO_CFG_REG(port),
- + MV_REG_READ( ETH_TX_FIXED_PRIO_CFG_REG(port) ) );
- +
- + mvOsPrintf("ETH_TX_TOKEN_RATE_CFG_REG : 0x%X = 0x%08x\n",
- + ETH_TX_TOKEN_RATE_CFG_REG(port),
- + MV_REG_READ( ETH_TX_TOKEN_RATE_CFG_REG(port) ) );
- +
- + mvOsPrintf("ETH_MAX_TRANSMIT_UNIT_REG : 0x%X = 0x%08x\n",
- + ETH_MAX_TRANSMIT_UNIT_REG(port),
- + MV_REG_READ( ETH_MAX_TRANSMIT_UNIT_REG(port) ) );
- +
- + mvOsPrintf("ETH_TX_TOKEN_BUCKET_SIZE_REG : 0x%X = 0x%08x\n",
- + ETH_TX_TOKEN_BUCKET_SIZE_REG(port),
- + MV_REG_READ( ETH_TX_TOKEN_BUCKET_SIZE_REG(port) ) );
- +
- + mvOsPrintf("ETH_TX_TOKEN_BUCKET_COUNT_REG : 0x%X = 0x%08x\n",
- + ETH_TX_TOKEN_BUCKET_COUNT_REG(port),
- + MV_REG_READ( ETH_TX_TOKEN_BUCKET_COUNT_REG(port) ) );
- +
- + for(queue=0; queue<MV_ETH_MAX_TXQ; queue++)
- + {
- + mvOsPrintf("\n\t TX policy Port #%d, Queue #%d configuration registers\n", port, queue);
- +
- + mvOsPrintf("ETH_TXQ_TOKEN_COUNT_REG : 0x%X = 0x%08x\n",
- + ETH_TXQ_TOKEN_COUNT_REG(port, queue),
- + MV_REG_READ( ETH_TXQ_TOKEN_COUNT_REG(port, queue) ) );
- +
- + mvOsPrintf("ETH_TXQ_TOKEN_CFG_REG : 0x%X = 0x%08x\n",
- + ETH_TXQ_TOKEN_CFG_REG(port, queue),
- + MV_REG_READ( ETH_TXQ_TOKEN_CFG_REG(port, queue) ) );
- +
- + mvOsPrintf("ETH_TXQ_ARBITER_CFG_REG : 0x%X = 0x%08x\n",
- + ETH_TXQ_ARBITER_CFG_REG(port, queue),
- + MV_REG_READ( ETH_TXQ_ARBITER_CFG_REG(port, queue) ) );
- + }
- + mvOsPrintf("\n");
- +}
- +
- +/* Print important registers of Ethernet port */
- +void ethPortRegs(int port)
- +{
- + mvOsPrintf("\n\t ethGiga #%d port Registers:\n", port);
- +
- + mvOsPrintf("ETH_PORT_STATUS_REG : 0x%X = 0x%08x\n",
- + ETH_PORT_STATUS_REG(port),
- + MV_REG_READ( ETH_PORT_STATUS_REG(port) ) );
- +
- + mvOsPrintf("ETH_PORT_SERIAL_CTRL_REG : 0x%X = 0x%08x\n",
- + ETH_PORT_SERIAL_CTRL_REG(port),
- + MV_REG_READ( ETH_PORT_SERIAL_CTRL_REG(port) ) );
- +
- + mvOsPrintf("ETH_PORT_CONFIG_REG : 0x%X = 0x%08x\n",
- + ETH_PORT_CONFIG_REG(port),
- + MV_REG_READ( ETH_PORT_CONFIG_REG(port) ) );
- +
- + mvOsPrintf("ETH_PORT_CONFIG_EXTEND_REG : 0x%X = 0x%08x\n",
- + ETH_PORT_CONFIG_EXTEND_REG(port),
- + MV_REG_READ( ETH_PORT_CONFIG_EXTEND_REG(port) ) );
- +
- + mvOsPrintf("ETH_SDMA_CONFIG_REG : 0x%X = 0x%08x\n",
- + ETH_SDMA_CONFIG_REG(port),
- + MV_REG_READ( ETH_SDMA_CONFIG_REG(port) ) );
- +
- + mvOsPrintf("ETH_TX_FIFO_URGENT_THRESH_REG : 0x%X = 0x%08x\n",
- + ETH_TX_FIFO_URGENT_THRESH_REG(port),
- + MV_REG_READ( ETH_TX_FIFO_URGENT_THRESH_REG(port) ) );
- +
- + mvOsPrintf("ETH_RX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
- + ETH_RX_QUEUE_COMMAND_REG(port),
- + MV_REG_READ( ETH_RX_QUEUE_COMMAND_REG(port) ) );
- +
- + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
- + ETH_TX_QUEUE_COMMAND_REG(port),
- + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
- +
- + mvOsPrintf("ETH_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
- + ETH_INTR_CAUSE_REG(port),
- + MV_REG_READ( ETH_INTR_CAUSE_REG(port) ) );
- +
- + mvOsPrintf("ETH_INTR_EXTEND_CAUSE_REG : 0x%X = 0x%08x\n",
- + ETH_INTR_CAUSE_EXT_REG(port),
- + MV_REG_READ( ETH_INTR_CAUSE_EXT_REG(port) ) );
- +
- + mvOsPrintf("ETH_INTR_MASK_REG : 0x%X = 0x%08x\n",
- + ETH_INTR_MASK_REG(port),
- + MV_REG_READ( ETH_INTR_MASK_REG(port) ) );
- +
- + mvOsPrintf("ETH_INTR_EXTEND_MASK_REG : 0x%X = 0x%08x\n",
- + ETH_INTR_MASK_EXT_REG(port),
- + MV_REG_READ( ETH_INTR_MASK_EXT_REG(port) ) );
- +
- + mvOsPrintf("ETH_RX_DESCR_STAT_CMD_REG : 0x%X = 0x%08x\n",
- + ETH_RX_DESCR_STAT_CMD_REG(port, 0),
- + MV_REG_READ( ETH_RX_DESCR_STAT_CMD_REG(port, 0) ) );
- +
- + mvOsPrintf("ETH_RX_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
- + ETH_RX_BYTE_COUNT_REG(port, 0),
- + MV_REG_READ( ETH_RX_BYTE_COUNT_REG(port, 0) ) );
- +
- + mvOsPrintf("ETH_RX_BUF_PTR_REG : 0x%X = 0x%08x\n",
- + ETH_RX_BUF_PTR_REG(port, 0),
- + MV_REG_READ( ETH_RX_BUF_PTR_REG(port, 0) ) );
- +
- + mvOsPrintf("ETH_RX_CUR_DESC_PTR_REG : 0x%X = 0x%08x\n",
- + ETH_RX_CUR_DESC_PTR_REG(port, 0),
- + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, 0) ) );
- +}
- +
- +
- +/* Print Giga Ethernet UNIT registers */
- +void ethRegs(int port)
- +{
- + mvOsPrintf("ETH_PHY_ADDR_REG : 0x%X = 0x%08x\n",
- + ETH_PHY_ADDR_REG(port),
- + MV_REG_READ(ETH_PHY_ADDR_REG(port)) );
- +
- + mvOsPrintf("ETH_UNIT_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
- + ETH_UNIT_INTR_CAUSE_REG(port),
- + MV_REG_READ( ETH_UNIT_INTR_CAUSE_REG(port)) );
- +
- + mvOsPrintf("ETH_UNIT_INTR_MASK_REG : 0x%X = 0x%08x\n",
- + ETH_UNIT_INTR_MASK_REG(port),
- + MV_REG_READ( ETH_UNIT_INTR_MASK_REG(port)) );
- +
- + mvOsPrintf("ETH_UNIT_ERROR_ADDR_REG : 0x%X = 0x%08x\n",
- + ETH_UNIT_ERROR_ADDR_REG(port),
- + MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(port)) );
- +
- + mvOsPrintf("ETH_UNIT_INT_ADDR_ERROR_REG : 0x%X = 0x%08x\n",
- + ETH_UNIT_INT_ADDR_ERROR_REG(port),
- + MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(port)) );
- +
- +}
- +
- +/******************************************************************************/
- +/* MIB Counters functions */
- +/******************************************************************************/
- +
- +/*******************************************************************************
- +* ethClearMibCounters - Clear all MIB counters
- +*
- +* DESCRIPTION:
- +* This function clears all MIB counters of a specific ethernet port.
- +* A read from the MIB counter will reset the counter.
- +*
- +* INPUT:
- +* int port - Ethernet Port number.
- +*
- +* RETURN: None
- +*
- +*******************************************************************************/
- +void ethClearCounters(int port)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + mvEthMibCountersClear(pHndl);
- +
- + return;
- +}
- +
- +
- +/* Print counters of the Ethernet port */
- +void ethPortCounters(int port)
- +{
- + MV_U32 regValue, regValHigh;
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl == NULL)
- + return;
- +
- + mvOsPrintf("\n\t Port #%d MIB Counters\n\n", port);
- +
- + mvOsPrintf("GoodFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_RECEIVED, NULL));
- + mvOsPrintf("BadFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FRAMES_RECEIVED, NULL));
- + mvOsPrintf("BroadcastFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_RECEIVED, NULL));
- + mvOsPrintf("MulticastFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_RECEIVED, NULL));
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW,
- + ®ValHigh);
- + mvOsPrintf("GoodOctetsReceived = 0x%08x%08x\n",
- + regValHigh, regValue);
- +
- + mvOsPrintf("\n");
- + mvOsPrintf("GoodFramesSent = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_SENT, NULL));
- + mvOsPrintf("BroadcastFramesSent = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_SENT, NULL));
- + mvOsPrintf("MulticastFramesSent = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_SENT, NULL));
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_SENT_LOW,
- + ®ValHigh);
- + mvOsPrintf("GoodOctetsSent = 0x%08x%08x\n", regValHigh, regValue);
- +
- +
- + mvOsPrintf("\n\t FC Control Counters\n");
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, NULL);
- + mvOsPrintf("UnrecogMacControlReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FC_RECEIVED, NULL);
- + mvOsPrintf("GoodFCFramesReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FC_RECEIVED, NULL);
- + mvOsPrintf("BadFCFramesReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FC_SENT, NULL);
- + mvOsPrintf("FCFramesSent = %u\n", regValue);
- +
- +
- + mvOsPrintf("\n\t RX Errors\n");
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_OCTETS_RECEIVED, NULL);
- + mvOsPrintf("BadOctetsReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNDERSIZE_RECEIVED, NULL);
- + mvOsPrintf("UndersizeFramesReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FRAGMENTS_RECEIVED, NULL);
- + mvOsPrintf("FragmentsReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_OVERSIZE_RECEIVED, NULL);
- + mvOsPrintf("OversizeFramesReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_JABBER_RECEIVED, NULL);
- + mvOsPrintf("JabbersReceived = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_MAC_RECEIVE_ERROR, NULL);
- + mvOsPrintf("MacReceiveErrors = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_CRC_EVENT, NULL);
- + mvOsPrintf("BadCrcReceived = %u\n", regValue);
- +
- + mvOsPrintf("\n\t TX Errors\n");
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, NULL);
- + mvOsPrintf("TxMacErrors = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_EXCESSIVE_COLLISION, NULL);
- + mvOsPrintf("TxExcessiveCollisions = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_COLLISION, NULL);
- + mvOsPrintf("TxCollisions = %u\n", regValue);
- +
- + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_LATE_COLLISION, NULL);
- + mvOsPrintf("TxLateCollisions = %u\n", regValue);
- +
- +
- + mvOsPrintf("\n");
- + regValue = MV_REG_READ( ETH_RX_DISCARD_PKTS_CNTR_REG(port));
- + mvOsPrintf("Rx Discard packets counter = %u\n", regValue);
- +
- + regValue = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));
- + mvOsPrintf("Rx Overrun packets counter = %u\n", regValue);
- +}
- +
- +/* Print RMON counters of the Ethernet port */
- +void ethPortRmonCounters(int port)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl == NULL)
- + return;
- +
- + mvOsPrintf("\n\t Port #%d RMON MIB Counters\n\n", port);
- +
- + mvOsPrintf("64 ByteFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_64_OCTETS, NULL));
- + mvOsPrintf("65...127 ByteFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_65_TO_127_OCTETS, NULL));
- + mvOsPrintf("128...255 ByteFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_128_TO_255_OCTETS, NULL));
- + mvOsPrintf("256...511 ByteFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_256_TO_511_OCTETS, NULL));
- + mvOsPrintf("512...1023 ByteFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_512_TO_1023_OCTETS, NULL));
- + mvOsPrintf("1024...Max ByteFramesReceived = %u\n",
- + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, NULL));
- +}
- +
- +/* Print port information */
- +void ethPortStatus(int port)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthPortShow(pHndl);
- + }
- +}
- +
- +/* Print port queues information */
- +void ethPortQueues(int port, int rxQueue, int txQueue, int mode)
- +{
- + void* pHndl;
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvEthQueuesShow(pHndl, rxQueue, txQueue, mode);
- + }
- +}
- +
- +void ethUcastSet(int port, char* macStr, int queue)
- +{
- + void* pHndl;
- + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvMacStrToHex(macStr, macAddr);
- + mvEthMacAddrSet(pHndl, macAddr, queue);
- + }
- +}
- +
- +
- +void ethPortUcastShow(int port)
- +{
- + MV_U32 unicastReg, macL, macH;
- + int i, j;
- +
- + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(port));
- + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(port));
- +
- + mvOsPrintf("\n\t Port #%d Unicast MAC table: %02x:%02x:%02x:%02x:%02x:%02x\n\n",
- + port, ((macH >> 24) & 0xff), ((macH >> 16) & 0xff),
- + ((macH >> 8) & 0xff), (macH & 0xff),
- + ((macL >> 8) & 0xff), (macL & 0xff) );
- +
- + for (i=0; i<4; i++)
- + {
- + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(port) + i*4));
- + for(j=0; j<4; j++)
- + {
- + MV_U8 macEntry = (unicastReg >> (8*j)) & 0xFF;
- +
- + mvOsPrintf("%X: %8s, Q = %d\n", i*4+j,
- + (macEntry & BIT0) ? "Accept" : "Reject", (macEntry >> 1) & 0x7);
- + }
- + }
- +}
- +
- +void ethMcastAdd(int port, char* macStr, int queue)
- +{
- + void* pHndl;
- + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
- +
- + pHndl = mvEthPortHndlGet(port);
- + if(pHndl != NULL)
- + {
- + mvMacStrToHex(macStr, macAddr);
- + mvEthMcastAddrSet(pHndl, macAddr, queue);
- + }
- +}
- +
- +void ethPortMcast(int port)
- +{
- + int tblIdx, regIdx;
- + MV_U32 regVal;
- +
- + mvOsPrintf("\n\t Port #%d Special (IP) Multicast table: 01:00:5E:00:00:XX\n\n",
- + port);
- +
- + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
- + {
- + regVal = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(port) + tblIdx*4));
- + for(regIdx=0; regIdx<4; regIdx++)
- + {
- + if((regVal & (0x01 << (regIdx*8))) != 0)
- + {
- + mvOsPrintf("0x%02X: Accepted, rxQ = %d\n",
- + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
- + }
- + }
- + }
- + mvOsPrintf("\n\t Port #%d Other Multicast table\n\n", port);
- + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
- + {
- + regVal = MV_REG_READ((ETH_DA_FILTER_OTH_MCAST_BASE(port) + tblIdx*4));
- + for(regIdx=0; regIdx<4; regIdx++)
- + {
- + if((regVal & (0x01 << (regIdx*8))) != 0)
- + {
- + mvOsPrintf("Crc8=0x%02X: Accepted, rxQ = %d\n",
- + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
- + }
- + }
- + }
- +}
- +
- +
- +/* Print status of Ethernet port */
- +void mvEthPortShow(void* pHndl)
- +{
- + MV_U32 regValue, rxCoal, txCoal;
- + int speed, queue, port;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pHndl;
- +
- + port = pPortCtrl->portNo;
- +
- + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
- +
- + mvOsPrintf("\n\t ethGiga #%d port Status: 0x%04x = 0x%08x\n\n",
- + port, ETH_PORT_STATUS_REG(port), regValue);
- +
- + mvOsPrintf("descInSram=%d, descSwCoher=%d\n",
- + ethDescInSram, ethDescSwCoher);
- +
- + if(regValue & ETH_GMII_SPEED_1000_MASK)
- + speed = 1000;
- + else if(regValue & ETH_MII_SPEED_100_MASK)
- + speed = 100;
- + else
- + speed = 10;
- +
- + mvEthCoalGet(pPortCtrl, &rxCoal, &txCoal);
- +
- + /* Link, Speed, Duplex, FlowControl */
- + mvOsPrintf("Link=%s, Speed=%d, Duplex=%s, RxFlowControl=%s",
- + (regValue & ETH_LINK_UP_MASK) ? "UP" : "DOWN",
- + speed,
- + (regValue & ETH_FULL_DUPLEX_MASK) ? "FULL" : "HALF",
- + (regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) ? "ENABLE" : "DISABLE");
- +
- + mvOsPrintf("\n");
- +
- + mvOsPrintf("RxCoal = %d usec, TxCoal = %d usec\n",
- + rxCoal, txCoal);
- +
- + mvOsPrintf("rxDefQ=%d, arpQ=%d, bpduQ=%d, tcpQ=%d, udpQ=%d\n\n",
- + pPortCtrl->portConfig.rxDefQ, pPortCtrl->portConfig.rxArpQ,
- + pPortCtrl->portConfig.rxBpduQ,
- + pPortCtrl->portConfig.rxTcpQ, pPortCtrl->portConfig.rxUdpQ);
- +
- + /* Print all RX and TX queues */
- + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
- + {
- + mvOsPrintf("RX Queue #%d: base=0x%lx, free=%d\n",
- + queue, (MV_ULONG)pPortCtrl->rxQueue[queue].pFirstDescr,
- + mvEthRxResourceGet(pPortCtrl, queue) );
- + }
- + mvOsPrintf("\n");
- + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
- + {
- + mvOsPrintf("TX Queue #%d: base=0x%lx, free=%d\n",
- + queue, (MV_ULONG)pPortCtrl->txQueue[queue].pFirstDescr,
- + mvEthTxResourceGet(pPortCtrl, queue) );
- + }
- +}
- +
- +/* Print RX and TX queue of the Ethernet port */
- +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode)
- +{
- + ETH_PORT_CTRL *pPortCtrl = (ETH_PORT_CTRL*)pHndl;
- + ETH_QUEUE_CTRL *pQueueCtrl;
- + MV_U32 regValue;
- + ETH_RX_DESC *pRxDescr;
- + ETH_TX_DESC *pTxDescr;
- + int i, port = pPortCtrl->portNo;
- +
- + if( (rxQueue >=0) && (rxQueue < MV_ETH_RX_Q_NUM) )
- + {
- + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
- + mvOsPrintf("Port #%d, RX Queue #%d\n\n", port, rxQueue);
- +
- + mvOsPrintf("CURR_RX_DESC_PTR : 0x%X = 0x%08x\n",
- + ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
- + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue)));
- +
- +
- + if(pQueueCtrl->pFirstDescr != NULL)
- + {
- + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
- + (MV_ULONG)pQueueCtrl->pFirstDescr, (MV_ULONG)pQueueCtrl->pLastDescr,
- + pQueueCtrl->resource);
- + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
- + (MV_ULONG)pQueueCtrl->pCurrentDescr,
- + (MV_ULONG)pQueueCtrl->pUsedDescr);
- +
- + if(mode == 1)
- + {
- + pRxDescr = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
- + i = 0;
- + do
- + {
- + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%4d, buf=%08x, pkt=%lx, os=%lx\n",
- + i, (MV_U32)pRxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pRxDescr),
- + pRxDescr->cmdSts, pRxDescr->byteCnt, (MV_U32)pRxDescr->bufSize,
- + (unsigned int)pRxDescr->bufPtr, (MV_ULONG)pRxDescr->returnInfo,
- + ((MV_PKT_INFO*)pRxDescr->returnInfo)->osInfo);
- +
- + ETH_DESCR_INV(pPortCtrl, pRxDescr);
- + pRxDescr = RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl);
- + i++;
- + } while (pRxDescr != pQueueCtrl->pFirstDescr);
- + }
- + }
- + else
- + mvOsPrintf("RX Queue #%d is NOT CREATED\n", rxQueue);
- + }
- +
- + if( (txQueue >=0) && (txQueue < MV_ETH_TX_Q_NUM) )
- + {
- + pQueueCtrl = &(pPortCtrl->txQueue[txQueue]);
- + mvOsPrintf("Port #%d, TX Queue #%d\n\n", port, txQueue);
- +
- + regValue = MV_REG_READ( ETH_TX_CUR_DESC_PTR_REG(port, txQueue));
- + mvOsPrintf("CURR_TX_DESC_PTR : 0x%X = 0x%08x\n",
- + ETH_TX_CUR_DESC_PTR_REG(port, txQueue), regValue);
- +
- + if(pQueueCtrl->pFirstDescr != NULL)
- + {
- + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
- + (MV_ULONG)pQueueCtrl->pFirstDescr,
- + (MV_ULONG)pQueueCtrl->pLastDescr,
- + pQueueCtrl->resource);
- + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
- + (MV_ULONG)pQueueCtrl->pCurrentDescr,
- + (MV_ULONG)pQueueCtrl->pUsedDescr);
- +
- + if(mode == 1)
- + {
- + pTxDescr = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
- + i = 0;
- + do
- + {
- + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%08x, pkt=%lx, os=%lx\n",
- + i, (MV_U32)pTxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxDescr),
- + pTxDescr->cmdSts, pTxDescr->byteCnt,
- + (MV_U32)pTxDescr->bufPtr, (MV_ULONG)pTxDescr->returnInfo,
- + pTxDescr->returnInfo ? (((MV_PKT_INFO*)pTxDescr->returnInfo)->osInfo) : 0x0);
- +
- + ETH_DESCR_INV(pPortCtrl, pTxDescr);
- + pTxDescr = TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl);
- + i++;
- + } while (pTxDescr != pQueueCtrl->pFirstDescr);
- + }
- + }
- + else
- + mvOsPrintf("TX Queue #%d is NOT CREATED\n", txQueue);
- + }
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 2010-11-09 20:28:11.112495471 +0100
- @@ -0,0 +1,146 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#ifndef __MV_ETH_DEBUG_H__
- +#define __MV_ETH_DEBUG_H__
- +
- +#if 0
- +/*
- + ** Externs
- + */
- +void ethBpduRxQ(int port, int bpduQueue);
- +void ethArpRxQ(int port, int bpduQueue);
- +void ethTcpRxQ(int port, int bpduQueue);
- +void ethUdpRxQ(int port, int bpduQueue);
- +void ethMcastAdd(int port, char* macStr, int queue);
- +
- +#ifdef INCLUDE_MULTI_QUEUE
- +void ethRxPolicy( int port);
- +void ethTxPolicy( int port);
- +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
- +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
- +void ethRxPolQ(int port, int rxQueue, int rxQuota);
- +#endif /* INCLUDE_MULTI_QUEUE */
- +
- +void print_egiga_stat(void *sc, unsigned int port);
- +void ethPortStatus (int port);
- +void ethPortQueues( int port, int rxQueue, int txQueue, int mode);
- +void ethPortMcast(int port);
- +void ethPortRegs(int port);
- +void ethPortCounters(int port);
- +void ethPortRmonCounters(int port);
- +void ethRxCoal(int port, int usec);
- +void ethTxCoal(int port, int usec);
- +
- +void ethRegs(int port);
- +void ethClearCounters(int port);
- +void ethUcastSet(int port, char* macStr, int queue);
- +void ethPortUcastShow(int port);
- +
- +#ifdef CONFIG_MV_ETH_HEADER
- +void run_com_header(const char *buffer);
- +#endif
- +
- +#ifdef INCLUDE_MULTI_QUEUE
- +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
- +void ethRxPolQ(int port, int queue, int quota);
- +void ethRxPolicy(int port);
- +void ethTxPolDef(int port, int txQ, char* headerHexStr);
- +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
- +void ethTxPolicy(int port);
- +#endif /* INCLUDE_MULTI_QUEUE */
- +
- +#if (MV_ETH_VERSION >= 4)
- +void ethEjpModeSet(int port, int mode)
- +#endif
- +#endif /* 0 */
- +
- +
- +
- +
- +void ethRxCoal(int port, int usec);
- +void ethTxCoal(int port, int usec);
- +#if (MV_ETH_VERSION >= 4)
- +void ethEjpModeSet(int port, int mode);
- +#endif /* (MV_ETH_VERSION >= 4) */
- +
- +void ethBpduRxQ(int port, int bpduQueue);
- +void ethArpRxQ(int port, int arpQueue);
- +void ethTcpRxQ(int port, int tcpQueue);
- +void ethUdpRxQ(int port, int udpQueue);
- +void ethTxPolicyRegs(int port);
- +void ethPortRegs(int port);
- +void ethRegs(int port);
- +void ethClearCounters(int port);
- +void ethPortCounters(int port);
- +void ethPortRmonCounters(int port);
- +void ethPortStatus(int port);
- +void ethPortQueues(int port, int rxQueue, int txQueue, int mode);
- +void ethUcastSet(int port, char* macStr, int queue);
- +void ethPortUcastShow(int port);
- +void ethMcastAdd(int port, char* macStr, int queue);
- +void ethPortMcast(int port);
- +void mvEthPortShow(void* pHndl);
- +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
- +
- +#endif
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 2010-11-09 20:28:11.152495442 +0100
- @@ -0,0 +1,751 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEth.h - Header File for : Marvell Gigabit Ethernet Controller
- +*
- +* DESCRIPTION:
- +* This header file contains macros typedefs and function declaration specific to
- +* the Marvell Gigabit Ethernet Controller.
- +*
- +* DEPENDENCIES:
- +* None.
- +*
- +*******************************************************************************/
- +
- +#ifndef __mvEthGbe_h__
- +#define __mvEthGbe_h__
- +
- +extern MV_BOOL ethDescInSram;
- +extern MV_BOOL ethDescSwCoher;
- +extern ETH_PORT_CTRL* ethPortCtrl[];
- +
- +static INLINE MV_ULONG ethDescVirtToPhy(ETH_QUEUE_CTRL* pQueueCtrl, MV_U8* pDesc)
- +{
- +#if defined (ETH_DESCR_IN_SRAM)
- + if( ethDescInSram )
- + return mvSramVirtToPhy(pDesc);
- + else
- +#endif /* ETH_DESCR_IN_SRAM */
- + return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));
- +}
- +/* Return port handler */
- +#define mvEthPortHndlGet(port) ethPortCtrl[port]
- +
- +/* Used as WA for HW/SW race on TX */
- +static INLINE int mvEthPortTxEnable(void* pPortHndl, int queue, int max_deep)
- +{
- + int deep = 0;
- + MV_U32 txCurrReg, txEnReg;
- + ETH_TX_DESC* pTxLastDesc;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- +
- + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
- + if( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) == 0)
- + {
- + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
- + return 0;
- + }
- +
- + pQueueCtrl = &pPortCtrl->txQueue[queue];
- + pTxLastDesc = pQueueCtrl->pCurrentDescr;
- + txCurrReg = MV_REG_READ(ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue));
- + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
- + {
- + /* All descriptors are processed, no chance for race */
- + return 0;
- + }
- +
- + /* Check distance betwee HW and SW location: */
- + /* If distance between HW and SW pointers is less than max_deep descriptors */
- + /* Race condition is possible, so wait end of TX and restart TXQ */
- + while(deep < max_deep)
- + {
- + pTxLastDesc = TX_PREV_DESC_PTR(pTxLastDesc, pQueueCtrl);
- + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
- + {
- + int count = 0;
- +
- + while( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) != 0)
- + {
- + count++;
- + if(count > 10000)
- + {
- + mvOsPrintf("mvEthPortTxEnable: timeout - TXQ_CMD=0x%08x\n",
- + MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) );
- + break;
- + }
- + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
- + }
- +
- + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
- + return count;
- + }
- + deep++;
- + }
- + /* Distance between HW and SW pointers is more than max_deep descriptors, */
- + /* So NO race condition - do nothing */
- + return -1;
- +}
- +
- +
- +/* defines */
- +#define ETH_CSUM_MIN_BYTE_COUNT 72
- +
- +/* Tailgate and Kirwood have only 2K TX FIFO */
- +#if (MV_ETH_VERSION == 2) || (MV_ETH_VERSION == 4)
- +#define ETH_CSUM_MAX_BYTE_COUNT 1600
- +#else
- +#define ETH_CSUM_MAX_BYTE_COUNT 9*1024
- +#endif /* MV_ETH_VERSION */
- +
- +#define ETH_MV_HEADER_SIZE 2
- +#define ETH_MV_TX_EN
- +
- +/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
- +#define MIN_TX_BUFF_LOAD 8
- +#define TX_BUF_OFFSET_IN_DESC (ETH_TX_DESC_ALIGNED_SIZE - MIN_TX_BUFF_LOAD)
- +
- +/* Default port configuration value */
- +#define PORT_CONFIG_VALUE \
- + ETH_DEF_RX_QUEUE_MASK(0) | \
- + ETH_DEF_RX_ARP_QUEUE_MASK(0) | \
- + ETH_DEF_RX_TCP_QUEUE_MASK(0) | \
- + ETH_DEF_RX_UDP_QUEUE_MASK(0) | \
- + ETH_DEF_RX_BPDU_QUEUE_MASK(0) | \
- + ETH_RX_CHECKSUM_WITH_PSEUDO_HDR
- +
- +/* Default port extend configuration value */
- +#define PORT_CONFIG_EXTEND_VALUE 0
- +
- +#define PORT_SERIAL_CONTROL_VALUE \
- + ETH_DISABLE_FC_AUTO_NEG_MASK | \
- + BIT9 | \
- + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
- + ETH_MAX_RX_PACKET_1552BYTE | \
- + ETH_SET_FULL_DUPLEX_MASK
- +
- +#define PORT_SERIAL_CONTROL_100MB_FORCE_VALUE \
- + ETH_FORCE_LINK_PASS_MASK | \
- + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
- + ETH_DISABLE_FC_AUTO_NEG_MASK | \
- + BIT9 | \
- + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
- + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
- + ETH_SET_FULL_DUPLEX_MASK | \
- + ETH_SET_MII_SPEED_100_MASK | \
- + ETH_MAX_RX_PACKET_1552BYTE
- +
- +
- +#define PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE \
- + ETH_FORCE_LINK_PASS_MASK | \
- + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
- + ETH_DISABLE_FC_AUTO_NEG_MASK | \
- + BIT9 | \
- + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
- + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
- + ETH_SET_FULL_DUPLEX_MASK | \
- + ETH_SET_GMII_SPEED_1000_MASK | \
- + ETH_MAX_RX_PACKET_1552BYTE
- +
- +#define PORT_SERIAL_CONTROL_SGMII_IBAN_VALUE \
- + ETH_DISABLE_FC_AUTO_NEG_MASK | \
- + BIT9 | \
- + ETH_IN_BAND_AN_EN_MASK | \
- + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
- + ETH_MAX_RX_PACKET_1552BYTE
- +
- +/* Function headers: */
- +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue);
- +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue);
- +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue);
- +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue);
- +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr);
- +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue);
- +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
- +/* Interrupt Coalesting functions */
- +MV_U32 mvEthRxCoalSet(void* pPortHndl, MV_U32 uSec);
- +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec);
- +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal);
- +
- +/******************************************************************************/
- +/* Data Flow functions */
- +/******************************************************************************/
- +static INLINE void mvEthPortTxRestart(void* pPortHndl)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- +
- + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
- +}
- +
- +/* Get number of Free resources in specific TX queue */
- +static INLINE int mvEthTxResourceGet(void* pPortHndl, int txQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- +
- + return (pPortCtrl->txQueue[txQueue].resource);
- +}
- +
- +/* Get number of Free resources in specific RX queue */
- +static INLINE int mvEthRxResourceGet(void* pPortHndl, int rxQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- +
- + return (pPortCtrl->rxQueue[rxQueue].resource);
- +}
- +
- +static INLINE int mvEthTxQueueIsFull(void* pPortHndl, int txQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- +
- + if(pPortCtrl->txQueue[txQueue].resource == 0)
- + return MV_TRUE;
- +
- + return MV_FALSE;
- +}
- +
- +/* Get number of Free resources in specific RX queue */
- +static INLINE int mvEthRxQueueIsFull(void* pPortHndl, int rxQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
- +
- + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
- + (pQueueCtrl->resource != 0) )
- + return MV_TRUE;
- +
- + return MV_FALSE;
- +}
- +
- +static INLINE int mvEthTxQueueIsEmpty(void* pPortHndl, int txQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[txQueue];
- +
- + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
- + (pQueueCtrl->resource != 0) )
- + {
- + return MV_TRUE;
- + }
- + return MV_FALSE;
- +}
- +
- +/* Get number of Free resources in specific RX queue */
- +static INLINE int mvEthRxQueueIsEmpty(void* pPortHndl, int rxQueue)
- +{
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
- +
- + if(pPortCtrl->rxQueue[rxQueue].resource == 0)
- + return MV_TRUE;
- +
- + return MV_FALSE;
- +}
- +
- +/*******************************************************************************
- +* mvEthPortTx - Send an Ethernet packet
- +*
- +* DESCRIPTION:
- +* This routine send a given packet described by pPktInfo parameter.
- +* Single buffer only.
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* int txQueue - Number of Tx queue.
- +* MV_PKT_INFO *pPktInfo - User packet to send.
- +*
- +* RETURN:
- +* MV_NO_RESOURCE - No enough resources to send this packet.
- +* MV_ERROR - Unexpected Fatal error.
- +* MV_OK - Packet send successfully.
- +*
- +*******************************************************************************/
- +static INLINE MV_STATUS mvEthPortTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
- +{
- + ETH_TX_DESC* pTxCurrDesc;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + int portNo;
- + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
- +
- +#ifdef ETH_DEBUG
- + if(pPortCtrl->portState != MV_ACTIVE)
- + return MV_BAD_STATE;
- +#endif /* ETH_DEBUG */
- +
- + portNo = pPortCtrl->portNo;
- + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
- +
- + /* Get the Tx Desc ring indexes */
- + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
- +
- + /* Check if there is enough resources to send the packet */
- + if(pQueueCtrl->resource == 0)
- + return MV_NO_RESOURCE;
- +
- + pTxCurrDesc->byteCnt = pBufInfo->dataSize;
- +
- + /* Flash Buffer */
- + if(pPktInfo->pktSize != 0)
- + {
- +#ifdef MV_NETBSD
- + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
- + ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
- +#else
- + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
- +#endif
- + pPktInfo->pktSize = 0;
- + }
- + else
- + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
- +
- + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
- +
- + /* There is only one buffer in the packet */
- + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
- + pTxCurrDesc->cmdSts = pPktInfo->status |
- + ETH_BUFFER_OWNED_BY_DMA |
- + ETH_TX_GENERATE_CRC_MASK |
- + ETH_TX_ENABLE_INTERRUPT_MASK |
- + ETH_TX_ZERO_PADDING_MASK |
- + ETH_TX_FIRST_DESC_MASK |
- + ETH_TX_LAST_DESC_MASK;
- +
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
- +
- + pQueueCtrl->resource--;
- + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
- +
- + /* Apply send command */
- + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvEthPortSgTx - Send an Ethernet packet
- +*
- +* DESCRIPTION:
- +* This routine send a given packet described by pBufInfo parameter. It
- +* supports transmitting of a packet spaned over multiple buffers.
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* int txQueue - Number of Tx queue.
- +* MV_PKT_INFO *pPktInfo - User packet to send.
- +*
- +* RETURN:
- +* MV_NO_RESOURCE - No enough resources to send this packet.
- +* MV_ERROR - Unexpected Fatal error.
- +* MV_OK - Packet send successfully.
- +*
- +*******************************************************************************/
- +static INLINE MV_STATUS mvEthPortSgTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
- +{
- + ETH_TX_DESC* pTxFirstDesc;
- + ETH_TX_DESC* pTxCurrDesc;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + int portNo, bufCount;
- + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
- + MV_U8* pTxBuf;
- +
- +#ifdef ETH_DEBUG
- + if(pPortCtrl->portState != MV_ACTIVE)
- + return MV_BAD_STATE;
- +#endif /* ETH_DEBUG */
- +
- + portNo = pPortCtrl->portNo;
- + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
- +
- + /* Get the Tx Desc ring indexes */
- + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
- +
- + /* Check if there is enough resources to send the packet */
- + if(pQueueCtrl->resource < pPktInfo->numFrags)
- + return MV_NO_RESOURCE;
- +
- + /* Remember first desc */
- + pTxFirstDesc = pTxCurrDesc;
- +
- + bufCount = 0;
- + while(MV_TRUE)
- + {
- + if(pBufInfo[bufCount].dataSize <= MIN_TX_BUFF_LOAD)
- + {
- + /* Buffers with a payload smaller than MIN_TX_BUFF_LOAD (8 bytes) must be aligned */
- + /* to 64-bit boundary. Two options here: */
- + /* 1) Usually, copy the payload to the reserved 8 bytes inside descriptor. */
- + /* 2) In the Half duplex workaround, the reserved 8 bytes inside descriptor are used */
- + /* as a pointer to the aligned buffer, copy the small payload to this buffer. */
- + pTxBuf = ((MV_U8*)pTxCurrDesc)+TX_BUF_OFFSET_IN_DESC;
- + mvOsBCopy(pBufInfo[bufCount].bufVirtPtr, pTxBuf, pBufInfo[bufCount].dataSize);
- + pTxCurrDesc->bufPtr = ethDescVirtToPhy(pQueueCtrl, pTxBuf);
- + }
- + else
- + {
- + /* Flash Buffer */
- +#ifdef MV_NETBSD
- + pTxCurrDesc->bufPtr = pBufInfo[bufCount].bufPhysAddr;
- + ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
- +#else
- + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
- +#endif
- + }
- +
- + pTxCurrDesc->byteCnt = pBufInfo[bufCount].dataSize;
- + bufCount++;
- +
- + if(bufCount >= pPktInfo->numFrags)
- + break;
- +
- + if(bufCount > 1)
- + {
- + /* There is middle buffer of the packet Not First and Not Last */
- + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA;
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
- + }
- + /* Go to next descriptor and next buffer */
- + pTxCurrDesc = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
- + }
- + /* Set last desc with DMA ownership and interrupt enable. */
- + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
- + if(bufCount == 1)
- + {
- + /* There is only one buffer in the packet */
- + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
- + pTxCurrDesc->cmdSts = pPktInfo->status |
- + ETH_BUFFER_OWNED_BY_DMA |
- + ETH_TX_GENERATE_CRC_MASK |
- + ETH_TX_ENABLE_INTERRUPT_MASK |
- + ETH_TX_ZERO_PADDING_MASK |
- + ETH_TX_FIRST_DESC_MASK |
- + ETH_TX_LAST_DESC_MASK;
- +
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
- + }
- + else
- + {
- + /* Last but not First */
- + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
- + ETH_TX_ENABLE_INTERRUPT_MASK |
- + ETH_TX_ZERO_PADDING_MASK |
- + ETH_TX_LAST_DESC_MASK;
- +
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
- +
- + /* Update First when more than one buffer in the packet */
- + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
- + pTxFirstDesc->cmdSts = pPktInfo->status |
- + ETH_BUFFER_OWNED_BY_DMA |
- + ETH_TX_GENERATE_CRC_MASK |
- + ETH_TX_FIRST_DESC_MASK;
- +
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxFirstDesc);
- + }
- + /* Update txQueue state */
- + pQueueCtrl->resource -= bufCount;
- + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
- +
- + /* Apply send command */
- + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvEthPortTxDone - Free all used Tx descriptors and mBlks.
- +*
- +* DESCRIPTION:
- +* This routine returns the transmitted packet information to the caller.
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* int txQueue - Number of Tx queue.
- +*
- +* OUTPUT:
- +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
- +*
- +* RETURN:
- +* MV_NOT_FOUND - No transmitted packets to return. Transmit in progress.
- +* MV_EMPTY - No transmitted packets to return. TX Queue is empty.
- +* MV_ERROR - Unexpected Fatal error.
- +* MV_OK - There is transmitted packet in the queue,
- +* 'pPktInfo' filled with relevant information.
- +*
- +*******************************************************************************/
- +static INLINE MV_PKT_INFO* mvEthPortTxDone(void* pEthPortHndl, int txQueue)
- +{
- + ETH_TX_DESC* pTxCurrDesc;
- + ETH_TX_DESC* pTxUsedDesc;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + MV_PKT_INFO* pPktInfo;
- + MV_U32 commandStatus;
- +
- + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
- +
- + pTxUsedDesc = pQueueCtrl->pUsedDescr;
- + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
- +
- + while(MV_TRUE)
- + {
- + /* No more used descriptors */
- + commandStatus = pTxUsedDesc->cmdSts;
- + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
- + {
- + ETH_DESCR_INV(pPortCtrl, pTxUsedDesc);
- + return NULL;
- + }
- + if( (pTxUsedDesc == pTxCurrDesc) &&
- + (pQueueCtrl->resource != 0) )
- + {
- + return NULL;
- + }
- + pQueueCtrl->resource++;
- + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxUsedDesc, pQueueCtrl);
- + if(commandStatus & (ETH_TX_LAST_DESC_MASK))
- + {
- + pPktInfo = (MV_PKT_INFO*)pTxUsedDesc->returnInfo;
- + pPktInfo->status = commandStatus;
- + return pPktInfo;
- + }
- + pTxUsedDesc = pQueueCtrl->pUsedDescr;
- + }
- +}
- +
- +/*******************************************************************************
- +* mvEthPortRx - Get new received packets from Rx queue.
- +*
- +* DESCRIPTION:
- +* This routine returns the received data to the caller. There is no
- +* data copying during routine operation. All information is returned
- +* using pointer to packet information struct passed from the caller.
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* int rxQueue - Number of Rx queue.
- +*
- +* OUTPUT:
- +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
- +*
- +* RETURN:
- +* MV_NO_RESOURCE - No free resources in RX queue.
- +* MV_ERROR - Unexpected Fatal error.
- +* MV_OK - New packet received and 'pBufInfo' structure filled
- +* with relevant information.
- +*
- +*******************************************************************************/
- +static INLINE MV_PKT_INFO* mvEthPortRx(void* pEthPortHndl, int rxQueue)
- +{
- + ETH_RX_DESC *pRxCurrDesc;
- + MV_U32 commandStatus;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + MV_PKT_INFO* pPktInfo;
- +
- + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
- +
- + /* Check resources */
- + if(pQueueCtrl->resource == 0)
- + {
- + mvOsPrintf("ethPortRx: no more resources\n");
- + return NULL;
- + }
- + while(MV_TRUE)
- + {
- + /* Get the Rx Desc ring 'curr and 'used' indexes */
- + pRxCurrDesc = pQueueCtrl->pCurrentDescr;
- +
- + commandStatus = pRxCurrDesc->cmdSts;
- + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
- + {
- + /* Nothing to receive... */
- + ETH_DESCR_INV(pPortCtrl, pRxCurrDesc);
- + return NULL;
- + }
- +
- + /* Valid RX only if FIRST and LAST bits are set */
- + if( (commandStatus & (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK)) ==
- + (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK) )
- + {
- + pPktInfo = (MV_PKT_INFO*)pRxCurrDesc->returnInfo;
- + pPktInfo->pFrags->dataSize = pRxCurrDesc->byteCnt - 4;
- + pPktInfo->status = commandStatus;
- + pPktInfo->fragIP = pRxCurrDesc->bufSize & ETH_RX_IP_FRAGMENTED_FRAME_MASK;
- +
- + pQueueCtrl->resource--;
- + /* Update 'curr' in data structure */
- + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
- +
- +#ifdef INCLUDE_SYNC_BARR
- + mvCpuIfSyncBarr(DRAM_TARGET);
- +#endif
- + return pPktInfo;
- + }
- + else
- + {
- + ETH_RX_DESC* pRxUsedDesc = pQueueCtrl->pUsedDescr;
- +
- +#ifdef ETH_DEBUG
- + mvOsPrintf("ethDrv: Unexpected Jumbo frame: "
- + "status=0x%08x, byteCnt=%d, pData=0x%x\n",
- + commandStatus, pRxCurrDesc->byteCnt, pRxCurrDesc->bufPtr);
- +#endif /* ETH_DEBUG */
- +
- + /* move buffer from pCurrentDescr position to pUsedDescr position */
- + pRxUsedDesc->bufPtr = pRxCurrDesc->bufPtr;
- + pRxUsedDesc->returnInfo = pRxCurrDesc->returnInfo;
- + pRxUsedDesc->bufSize = pRxCurrDesc->bufSize & ETH_RX_BUFFER_MASK;
- +
- + /* Return the descriptor to DMA ownership */
- + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
- + ETH_RX_ENABLE_INTERRUPT_MASK;
- +
- + /* Flush descriptor and CPU pipe */
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
- +
- + /* Move the used descriptor pointer to the next descriptor */
- + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
- + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
- + }
- + }
- +}
- +
- +/*******************************************************************************
- +* mvEthPortRxDone - Returns a Rx buffer back to the Rx ring.
- +*
- +* DESCRIPTION:
- +* This routine returns a Rx buffer back to the Rx ring.
- +*
- +* INPUT:
- +* void* pEthPortHndl - Ethernet Port handler.
- +* int rxQueue - Number of Rx queue.
- +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
- +*
- +* RETURN:
- +* MV_ERROR - Unexpected Fatal error.
- +* MV_OUT_OF_RANGE - RX queue is already FULL, so this buffer can't be
- +* returned to this queue.
- +* MV_FULL - Buffer returned successfully and RX queue became full.
- +* More buffers should not be returned at the time.
- +* MV_OK - Buffer returned successfully and there are more free
- +* places in the queue.
- +*
- +*******************************************************************************/
- +static INLINE MV_STATUS mvEthPortRxDone(void* pEthPortHndl, int rxQueue, MV_PKT_INFO *pPktInfo)
- +{
- + ETH_RX_DESC* pRxUsedDesc;
- + ETH_QUEUE_CTRL* pQueueCtrl;
- + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
- +
- + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
- +
- + /* Get 'used' Rx descriptor */
- + pRxUsedDesc = pQueueCtrl->pUsedDescr;
- +
- + /* Check that ring is not FULL */
- + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
- + (pQueueCtrl->resource != 0) )
- + {
- + mvOsPrintf("%s %d: out of range Error resource=%d, curr=%p, used=%p\n",
- + __FUNCTION__, pPortCtrl->portNo, pQueueCtrl->resource,
- + pQueueCtrl->pCurrentDescr, pQueueCtrl->pUsedDescr);
- + return MV_OUT_OF_RANGE;
- + }
- +
- + pRxUsedDesc->bufPtr = pPktInfo->pFrags->bufPhysAddr;
- + pRxUsedDesc->returnInfo = (MV_ULONG)pPktInfo;
- + pRxUsedDesc->bufSize = pPktInfo->pFrags->bufSize & ETH_RX_BUFFER_MASK;
- +
- + /* Invalidate data buffer accordingly with pktSize */
- + if(pPktInfo->pktSize != 0)
- + {
- + ETH_PACKET_CACHE_INVALIDATE(pPktInfo->pFrags->bufVirtPtr, pPktInfo->pktSize);
- + pPktInfo->pktSize = 0;
- + }
- +
- + /* Return the descriptor to DMA ownership */
- + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT_MASK;
- +
- + /* Flush descriptor and CPU pipe */
- + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
- +
- + pQueueCtrl->resource++;
- +
- + /* Move the used descriptor pointer to the next descriptor */
- + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
- +
- + /* If ring became Full return MV_FULL */
- + if(pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr)
- + return MV_FULL;
- +
- + return MV_OK;
- +}
- +
- +
- +#endif /* __mvEthGbe_h__ */
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 2010-11-09 20:28:11.192495435 +0100
- @@ -0,0 +1,700 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCmvEthRegsh
- +#define __INCmvEthRegsh
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +
- +/****************************************/
- +/* Ethernet Unit Registers */
- +/****************************************/
- +#define ETH_REG_BASE MV_ETH_REG_BASE
- +
- +#define ETH_PHY_ADDR_REG(port) (ETH_REG_BASE(port) + 0x000)
- +#define ETH_SMI_REG(port) (ETH_REG_BASE(port) + 0x004)
- +#define ETH_UNIT_DEF_ADDR_REG(port) (ETH_REG_BASE(port) + 0x008)
- +#define ETH_UNIT_DEF_ID_REG(port) (ETH_REG_BASE(port) + 0x00c)
- +#define ETH_UNIT_RESERVED(port) (ETH_REG_BASE(port) + 0x014)
- +#define ETH_UNIT_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x080)
- +#define ETH_UNIT_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x084)
- +
- +
- +#define ETH_UNIT_ERROR_ADDR_REG(port) (ETH_REG_BASE(port) + 0x094)
- +#define ETH_UNIT_INT_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x098)
- +#define ETH_UNIT_CONTROL_REG(port) (ETH_REG_BASE(port) + 0x0B0)
- +
- +#define ETH_PORT_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x400)
- +#define ETH_PORT_CONFIG_EXTEND_REG(port) (ETH_REG_BASE(port) + 0x404)
- +#define ETH_MII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x408)
- +#define ETH_GMII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x40c)
- +#define ETH_VLAN_ETHER_TYPE_REG(port) (ETH_REG_BASE(port) + 0x410)
- +#define ETH_MAC_ADDR_LOW_REG(port) (ETH_REG_BASE(port) + 0x414)
- +#define ETH_MAC_ADDR_HIGH_REG(port) (ETH_REG_BASE(port) + 0x418)
- +#define ETH_SDMA_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x41c)
- +#define ETH_DIFF_SERV_PRIO_REG(port, code) (ETH_REG_BASE(port) + 0x420 + ((code)<<2))
- +#define ETH_PORT_SERIAL_CTRL_REG(port) (ETH_REG_BASE(port) + 0x43c)
- +#define ETH_VLAN_TAG_TO_PRIO_REG(port) (ETH_REG_BASE(port) + 0x440)
- +#define ETH_PORT_STATUS_REG(port) (ETH_REG_BASE(port) + 0x444)
- +
- +#define ETH_RX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x680)
- +#define ETH_TX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x448)
- +
- +#define ETH_PORT_SERIAL_CTRL_1_REG(port) (ETH_REG_BASE(port) + 0x44c)
- +#define ETH_PORT_STATUS_1_REG(port) (ETH_REG_BASE(port) + 0x450)
- +#define ETH_PORT_MARVELL_HEADER_REG(port) (ETH_REG_BASE(port) + 0x454)
- +#define ETH_PORT_FIFO_PARAMS_REG(port) (ETH_REG_BASE(port) + 0x458)
- +#define ETH_MAX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x45c)
- +#define ETH_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x460)
- +#define ETH_INTR_CAUSE_EXT_REG(port) (ETH_REG_BASE(port) + 0x464)
- +#define ETH_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x468)
- +#define ETH_INTR_MASK_EXT_REG(port) (ETH_REG_BASE(port) + 0x46c)
- +#define ETH_TX_FIFO_URGENT_THRESH_REG(port) (ETH_REG_BASE(port) + 0x474)
- +#define ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (ETH_REG_BASE(port) + 0x47c)
- +#define ETH_RX_DISCARD_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x484)
- +#define ETH_RX_OVERRUN_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x488)
- +#define ETH_INTERNAL_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x494)
- +#define ETH_TX_FIXED_PRIO_CFG_REG(port) (ETH_REG_BASE(port) + 0x4dc)
- +#define ETH_TX_TOKEN_RATE_CFG_REG(port) (ETH_REG_BASE(port) + 0x4e0)
- +#define ETH_TX_QUEUE_COMMAND1_REG(port) (ETH_REG_BASE(port) + 0x4e4)
- +#define ETH_MAX_TRANSMIT_UNIT_REG(port) (ETH_REG_BASE(port) + 0x4e8)
- +#define ETH_TX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x4ec)
- +#define ETH_TX_TOKEN_BUCKET_COUNT_REG(port) (ETH_REG_BASE(port) + 0x780)
- +#define ETH_RX_DESCR_STAT_CMD_REG(port, q) (ETH_REG_BASE(port) + 0x600 + ((q)<<4))
- +#define ETH_RX_BYTE_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x604 + ((q)<<4))
- +#define ETH_RX_BUF_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x608 + ((q)<<4))
- +#define ETH_RX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x60c + ((q)<<4))
- +#define ETH_TX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x6c0 + ((q)<<2))
- +
- +#define ETH_TXQ_TOKEN_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x700 + ((q)<<4))
- +#define ETH_TXQ_TOKEN_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x704 + ((q)<<4))
- +#define ETH_TXQ_ARBITER_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x708 + ((q)<<4))
- +
- +#if (MV_ETH_VERSION >= 4)
- +#define ETH_TXQ_CMD_1_REG(port) (ETH_REG_BASE(port) + 0x4E4)
- +#define ETH_EJP_TX_HI_IPG_REG(port) (ETH_REG_BASE(port) + 0x7A8)
- +#define ETH_EJP_TX_LO_IPG_REG(port) (ETH_REG_BASE(port) + 0x7B8)
- +#define ETH_EJP_HI_TKN_LO_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C0)
- +#define ETH_EJP_HI_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C4)
- +#define ETH_EJP_LO_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C8)
- +#define ETH_EJP_TX_SPEED_REG(port) (ETH_REG_BASE(port) + 0x7D0)
- +#endif /* MV_ETH_VERSION >= 4 */
- +
- +#define ETH_MIB_COUNTERS_BASE(port) (ETH_REG_BASE(port) + 0x1000)
- +#define ETH_DA_FILTER_SPEC_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1400)
- +#define ETH_DA_FILTER_OTH_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1500)
- +#define ETH_DA_FILTER_UCAST_BASE(port) (ETH_REG_BASE(port) + 0x1600)
- +
- +/* Phy address register definitions */
- +#define ETH_PHY_ADDR_OFFS 0
- +#define ETH_PHY_ADDR_MASK (0x1f <<ETH_PHY_ADDR_OFFS)
- +
- +/* MIB Counters register definitions */
- +#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
- +#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
- +#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
- +#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
- +#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
- +#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
- +#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
- +#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
- +#define ETH_MIB_FRAMES_64_OCTETS 0x20
- +#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
- +#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
- +#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
- +#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
- +#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
- +#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
- +#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
- +#define ETH_MIB_GOOD_FRAMES_SENT 0x40
- +#define ETH_MIB_EXCESSIVE_COLLISION 0x44
- +#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
- +#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
- +#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
- +#define ETH_MIB_FC_SENT 0x54
- +#define ETH_MIB_GOOD_FC_RECEIVED 0x58
- +#define ETH_MIB_BAD_FC_RECEIVED 0x5c
- +#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
- +#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
- +#define ETH_MIB_OVERSIZE_RECEIVED 0x68
- +#define ETH_MIB_JABBER_RECEIVED 0x6c
- +#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
- +#define ETH_MIB_BAD_CRC_EVENT 0x74
- +#define ETH_MIB_COLLISION 0x78
- +#define ETH_MIB_LATE_COLLISION 0x7c
- +
- +
- +/****************************************/
- +/* Ethernet Unit Register BITs */
- +/****************************************/
- +
- +#define ETH_RXQ_ENABLE_OFFSET 0
- +#define ETH_RXQ_ENABLE_MASK (0x000000FF << ETH_RXQ_ENABLE_OFFSET)
- +
- +#define ETH_RXQ_DISABLE_OFFSET 8
- +#define ETH_RXQ_DISABLE_MASK (0x000000FF << ETH_RXQ_DISABLE_OFFSET)
- +
- +/***** BITs of Transmit Queue Command (TQC) register *****/
- +#define ETH_TXQ_ENABLE_OFFSET 0
- +#define ETH_TXQ_ENABLE_MASK (0x000000FF << ETH_TXQ_ENABLE_OFFSET)
- +
- +#define ETH_TXQ_DISABLE_OFFSET 8
- +#define ETH_TXQ_DISABLE_MASK (0x000000FF << ETH_TXQ_DISABLE_OFFSET)
- +
- +#if (MV_ETH_VERSION >= 4)
- +#define ETH_TX_EJP_RESET_BIT 0
- +#define ETH_TX_EJP_RESET_MASK (1 << ETH_TX_EJP_RESET_BIT)
- +
- +#define ETH_TX_EJP_ENABLE_BIT 2
- +#define ETH_TX_EJP_ENABLE_MASK (1 << ETH_TX_EJP_ENABLE_BIT)
- +
- +#define ETH_TX_LEGACY_WRR_BIT 3
- +#define ETH_TX_LEGACY_WRR_MASK (1 << ETH_TX_LEGACY_WRR_BIT)
- +#endif /* (MV_ETH_VERSION >= 4) */
- +
- +/***** BITs of Ethernet Port Status reg (PSR) *****/
- +#define ETH_LINK_UP_BIT 1
- +#define ETH_LINK_UP_MASK (1<<ETH_LINK_UP_BIT)
- +
- +#define ETH_FULL_DUPLEX_BIT 2
- +#define ETH_FULL_DUPLEX_MASK (1<<ETH_FULL_DUPLEX_BIT)
- +
- +#define ETH_ENABLE_RCV_FLOW_CTRL_BIT 3
- +#define ETH_ENABLE_RCV_FLOW_CTRL_MASK (1<<ETH_ENABLE_RCV_FLOW_CTRL_BIT)
- +
- +#define ETH_GMII_SPEED_1000_BIT 4
- +#define ETH_GMII_SPEED_1000_MASK (1<<ETH_GMII_SPEED_1000_BIT)
- +
- +#define ETH_MII_SPEED_100_BIT 5
- +#define ETH_MII_SPEED_100_MASK (1<<ETH_MII_SPEED_100_BIT)
- +
- +#define ETH_TX_IN_PROGRESS_BIT 7
- +#define ETH_TX_IN_PROGRESS_MASK (1<<ETH_TX_IN_PROGRESS_BIT)
- +
- +#define ETH_TX_FIFO_EMPTY_BIT 10
- +#define ETH_TX_FIFO_EMPTY_MASK (1<<ETH_TX_FIFO_EMPTY_BIT)
- +
- +/***** BITs of Ethernet Port Status 1 reg (PS1R) *****/
- +#define ETH_AUTO_NEG_DONE_BIT 4
- +#define ETH_AUTO_NEG_DONE_MASK (1<<ETH_AUTO_NEG_DONE_BIT)
- +
- +#define ETH_SERDES_PLL_LOCKED_BIT 6
- +#define ETH_SERDES_PLL_LOCKED_MASK (1<<ETH_SERDES_PLL_LOCKED_BIT)
- +
- +/***** BITs of Port Configuration reg (PxCR) *****/
- +#define ETH_UNICAST_PROMISCUOUS_MODE_BIT 0
- +#define ETH_UNICAST_PROMISCUOUS_MODE_MASK (1<<ETH_UNICAST_PROMISCUOUS_MODE_BIT)
- +
- +#define ETH_DEF_RX_QUEUE_OFFSET 1
- +#define ETH_DEF_RX_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_QUEUE_OFFSET)
- +#define ETH_DEF_RX_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_QUEUE_OFFSET)
- +
- +#define ETH_DEF_RX_ARP_QUEUE_OFFSET 4
- +#define ETH_DEF_RX_ARP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
- +#define ETH_DEF_RX_ARP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
- +
- +#define ETH_REJECT_NOT_IP_ARP_BCAST_BIT 7
- +#define ETH_REJECT_NOT_IP_ARP_BCAST_MASK (1<<ETH_REJECT_NOT_IP_ARP_BCAST_BIT)
- +
- +#define ETH_REJECT_IP_BCAST_BIT 8
- +#define ETH_REJECT_IP_BCAST_MASK (1<<ETH_REJECT_IP_BCAST_BIT)
- +
- +#define ETH_REJECT_ARP_BCAST_BIT 9
- +#define ETH_REJECT_ARP_BCAST_MASK (1<<ETH_REJECT_ARP_BCAST_BIT)
- +
- +#define ETH_TX_NO_SET_ERROR_SUMMARY_BIT 12
- +#define ETH_TX_NO_SET_ERROR_SUMMARY_MASK (1<<ETH_TX_NO_SET_ERROR_SUMMARY_BIT)
- +
- +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT 14
- +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT)
- +
- +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT 15
- +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT)
- +
- +#define ETH_DEF_RX_TCP_QUEUE_OFFSET 16
- +#define ETH_DEF_RX_TCP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
- +#define ETH_DEF_RX_TCP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
- +
- +#define ETH_DEF_RX_UDP_QUEUE_OFFSET 19
- +#define ETH_DEF_RX_UDP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
- +#define ETH_DEF_RX_UDP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
- +
- +#define ETH_DEF_RX_BPDU_QUEUE_OFFSET 22
- +#define ETH_DEF_RX_BPDU_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
- +#define ETH_DEF_RX_BPDU_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
- +
- +#define ETH_RX_CHECKSUM_MODE_OFFSET 25
- +#define ETH_RX_CHECKSUM_NO_PSEUDO_HDR (0<<ETH_RX_CHECKSUM_MODE_OFFSET)
- +#define ETH_RX_CHECKSUM_WITH_PSEUDO_HDR (1<<ETH_RX_CHECKSUM_MODE_OFFSET)
- +
- +/***** BITs of Port Configuration Extend reg (PxCXR) *****/
- +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT 1
- +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK (1<<ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT)
- +
- +#define ETH_TX_DISABLE_GEN_CRC_BIT 3
- +#define ETH_TX_DISABLE_GEN_CRC_MASK (1<<ETH_TX_DISABLE_GEN_CRC_BIT)
- +
- +/***** BITs of Tx/Rx queue command reg (RQCR/TQCR) *****/
- +#define ETH_QUEUE_ENABLE_OFFSET 0
- +#define ETH_QUEUE_ENABLE_ALL_MASK (0xFF<<ETH_QUEUE_ENABLE_OFFSET)
- +#define ETH_QUEUE_ENABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_ENABLE_OFFSET))
- +
- +#define ETH_QUEUE_DISABLE_OFFSET 8
- +#define ETH_QUEUE_DISABLE_ALL_MASK (0xFF<<ETH_QUEUE_DISABLE_OFFSET)
- +#define ETH_QUEUE_DISABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_DISABLE_OFFSET))
- +
- +
- +/***** BITs of Port Sdma Configuration reg (SDCR) *****/
- +#define ETH_RX_FRAME_INTERRUPT_BIT 0
- +#define ETH_RX_FRAME_INTERRUPT_MASK (1<<ETH_RX_FRAME_INTERRUPT_BIT)
- +
- +#define ETH_BURST_SIZE_1_64BIT_VALUE 0
- +#define ETH_BURST_SIZE_2_64BIT_VALUE 1
- +#define ETH_BURST_SIZE_4_64BIT_VALUE 2
- +#define ETH_BURST_SIZE_8_64BIT_VALUE 3
- +#define ETH_BURST_SIZE_16_64BIT_VALUE 4
- +
- +#define ETH_RX_BURST_SIZE_OFFSET 1
- +#define ETH_RX_BURST_SIZE_ALL_MASK (0x7<<ETH_RX_BURST_SIZE_OFFSET)
- +#define ETH_RX_BURST_SIZE_MASK(burst) ((burst)<<ETH_RX_BURST_SIZE_OFFSET)
- +
- +#define ETH_RX_NO_DATA_SWAP_BIT 4
- +#define ETH_RX_NO_DATA_SWAP_MASK (1<<ETH_RX_NO_DATA_SWAP_BIT)
- +#define ETH_RX_DATA_SWAP_MASK (0<<ETH_RX_NO_DATA_SWAP_BIT)
- +
- +#define ETH_TX_NO_DATA_SWAP_BIT 5
- +#define ETH_TX_NO_DATA_SWAP_MASK (1<<ETH_TX_NO_DATA_SWAP_BIT)
- +#define ETH_TX_DATA_SWAP_MASK (0<<ETH_TX_NO_DATA_SWAP_BIT)
- +
- +#define ETH_DESC_SWAP_BIT 6
- +#define ETH_DESC_SWAP_MASK (1<<ETH_DESC_SWAP_BIT)
- +#define ETH_NO_DESC_SWAP_MASK (0<<ETH_DESC_SWAP_BIT)
- +
- +#define ETH_RX_INTR_COAL_OFFSET 7
- +#define ETH_RX_INTR_COAL_ALL_MASK (0x3fff<<ETH_RX_INTR_COAL_OFFSET)
- +#define ETH_RX_INTR_COAL_MASK(value) (((value)<<ETH_RX_INTR_COAL_OFFSET) \
- + & ETH_RX_INTR_COAL_ALL_MASK)
- +
- +#define ETH_TX_BURST_SIZE_OFFSET 22
- +#define ETH_TX_BURST_SIZE_ALL_MASK (0x7<<ETH_TX_BURST_SIZE_OFFSET)
- +#define ETH_TX_BURST_SIZE_MASK(burst) ((burst)<<ETH_TX_BURST_SIZE_OFFSET)
- +
- +#define ETH_RX_INTR_COAL_MSB_BIT 25
- +#define ETH_RX_INTR_COAL_MSB_MASK (1<<ETH_RX_INTR_COAL_MSB_BIT)
- +
- +/* BITs Port #x Tx FIFO Urgent Threshold (PxTFUT) */
- +#define ETH_TX_INTR_COAL_OFFSET 4
- +#define ETH_TX_INTR_COAL_ALL_MASK (0x3fff << ETH_TX_INTR_COAL_OFFSET)
- +#define ETH_TX_INTR_COAL_MASK(value) (((value) << ETH_TX_INTR_COAL_OFFSET) \
- + & ETH_TX_INTR_COAL_ALL_MASK)
- +
- +/* BITs of Port Serial Control reg (PSCR) */
- +#define ETH_PORT_ENABLE_BIT 0
- +#define ETH_PORT_ENABLE_MASK (1<<ETH_PORT_ENABLE_BIT)
- +
- +#define ETH_FORCE_LINK_PASS_BIT 1
- +#define ETH_FORCE_LINK_PASS_MASK (1<<ETH_FORCE_LINK_PASS_BIT)
- +
- +#define ETH_DISABLE_DUPLEX_AUTO_NEG_BIT 2
- +#define ETH_DISABLE_DUPLEX_AUTO_NEG_MASK (1<<ETH_DISABLE_DUPLEX_AUTO_NEG_BIT)
- +
- +#define ETH_DISABLE_FC_AUTO_NEG_BIT 3
- +#define ETH_DISABLE_FC_AUTO_NEG_MASK (1<<ETH_DISABLE_FC_AUTO_NEG_BIT)
- +
- +#define ETH_ADVERTISE_SYM_FC_BIT 4
- +#define ETH_ADVERTISE_SYM_FC_MASK (1<<ETH_ADVERTISE_SYM_FC_BIT)
- +
- +#define ETH_TX_FC_MODE_OFFSET 5
- +#define ETH_TX_FC_MODE_MASK (3<<ETH_TX_FC_MODE_OFFSET)
- +#define ETH_TX_FC_NO_PAUSE (0<<ETH_TX_FC_MODE_OFFSET)
- +#define ETH_TX_FC_SEND_PAUSE (1<<ETH_TX_FC_MODE_OFFSET)
- +
- +#define ETH_TX_BP_MODE_OFFSET 7
- +#define ETH_TX_BP_MODE_MASK (3<<ETH_TX_BP_MODE_OFFSET)
- +#define ETH_TX_BP_NO_JAM (0<<ETH_TX_BP_MODE_OFFSET)
- +#define ETH_TX_BP_SEND_JAM (1<<ETH_TX_BP_MODE_OFFSET)
- +
- +#define ETH_DO_NOT_FORCE_LINK_FAIL_BIT 10
- +#define ETH_DO_NOT_FORCE_LINK_FAIL_MASK (1<<ETH_DO_NOT_FORCE_LINK_FAIL_BIT)
- +
- +#define ETH_RETRANSMIT_FOREVER_BIT 11
- +#define ETH_RETRANSMIT_FOREVER_MASK (1<<ETH_RETRANSMIT_FOREVER_BIT)
- +
- +#define ETH_DISABLE_SPEED_AUTO_NEG_BIT 13
- +#define ETH_DISABLE_SPEED_AUTO_NEG_MASK (1<<ETH_DISABLE_SPEED_AUTO_NEG_BIT)
- +
- +#define ETH_DTE_ADVERT_BIT 14
- +#define ETH_DTE_ADVERT_MASK (1<<ETH_DTE_ADVERT_BIT)
- +
- +#define ETH_MII_PHY_MODE_BIT 15
- +#define ETH_MII_PHY_MODE_MAC (0<<ETH_MII_PHY_MODE_BIT)
- +#define ETH_MII_PHY_MODE_PHY (1<<ETH_MII_PHY_MODE_BIT)
- +
- +#define ETH_MII_SOURCE_SYNCH_BIT 16
- +#define ETH_MII_STANDARD_SYNCH (0<<ETH_MII_SOURCE_SYNCH_BIT)
- +#define ETH_MII_400Mbps_SYNCH (1<<ETH_MII_SOURCE_CLK_BIT)
- +
- +#define ETH_MAX_RX_PACKET_SIZE_OFFSET 17
- +#define ETH_MAX_RX_PACKET_SIZE_MASK (7<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
- +#define ETH_MAX_RX_PACKET_1518BYTE (0<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
- +#define ETH_MAX_RX_PACKET_1522BYTE (1<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
- +#define ETH_MAX_RX_PACKET_1552BYTE (2<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
- +#define ETH_MAX_RX_PACKET_9022BYTE (3<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
- +#define ETH_MAX_RX_PACKET_9192BYTE (4<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
- +#define ETH_MAX_RX_PACKET_9700BYTE (5<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
- +
- +#define ETH_SET_FULL_DUPLEX_BIT 21
- +#define ETH_SET_FULL_DUPLEX_MASK (1<<ETH_SET_FULL_DUPLEX_BIT)
- +
- +#define ETH_SET_FLOW_CTRL_BIT 22
- +#define ETH_SET_FLOW_CTRL_MASK (1<<ETH_SET_FLOW_CTRL_BIT)
- +
- +#define ETH_SET_GMII_SPEED_1000_BIT 23
- +#define ETH_SET_GMII_SPEED_1000_MASK (1<<ETH_SET_GMII_SPEED_1000_BIT)
- +
- +#define ETH_SET_MII_SPEED_100_BIT 24
- +#define ETH_SET_MII_SPEED_100_MASK (1<<ETH_SET_MII_SPEED_100_BIT)
- +
- +/* BITs of Port Serial Control 1 reg (PSC1R) */
- +#define ETH_PSC_ENABLE_BIT 2
- +#define ETH_PSC_ENABLE_MASK (1<<ETH_PSC_ENABLE_BIT)
- +
- +#define ETH_RGMII_ENABLE_BIT 3
- +#define ETH_RGMII_ENABLE_MASK (1<<ETH_RGMII_ENABLE_BIT)
- +
- +#define ETH_PORT_RESET_BIT 4
- +#define ETH_PORT_RESET_MASK (1<<ETH_PORT_RESET_BIT)
- +
- +#define ETH_INBAND_AUTO_NEG_ENABLE_BIT 6
- +#define ETH_INBAND_AUTO_NEG_ENABLE_MASK (1<<ETH_INBAND_AUTO_NEG_ENABLE_BIT)
- +
- +#define ETH_INBAND_AUTO_NEG_BYPASS_BIT 7
- +#define ETH_INBAND_AUTO_NEG_BYPASS_MASK (1<<ETH_INBAND_AUTO_NEG_BYPASS_BIT)
- +
- +#define ETH_INBAND_AUTO_NEG_START_BIT 8
- +#define ETH_INBAND_AUTO_NEG_START_MASK (1<<ETH_INBAND_AUTO_NEG_START_BIT)
- +
- +#define ETH_PORT_TYPE_BIT 11
- +#define ETH_PORT_TYPE_1000BasedX_MASK (1<<ETH_PORT_TYPE_BIT)
- +
- +#define ETH_SGMII_MODE_BIT 12
- +#define ETH_1000BaseX_MODE_MASK (0<<ETH_SGMII_MODE_BIT)
- +#define ETH_SGMII_MODE_MASK (1<<ETH_SGMII_MODE_BIT)
- +
- +#define ETH_MGMII_MODE_BIT 13
- +
- +#define ETH_EN_MII_ODD_PRE_BIT 22
- +#define ETH_EN_MII_ODD_PRE_MASK (1<<ETH_EN_MII_ODD_PRE_BIT)
- +
- +/* BITs of SDMA Descriptor Command/Status field */
- +#if defined(MV_CPU_BE)
- +typedef struct _ethRxDesc
- +{
- + MV_U16 byteCnt ; /* Descriptor buffer byte count */
- + MV_U16 bufSize ; /* Buffer size */
- + MV_U32 cmdSts ; /* Descriptor command status */
- + MV_U32 nextDescPtr; /* Next descriptor pointer */
- + MV_U32 bufPtr ; /* Descriptor buffer pointer */
- + MV_ULONG returnInfo ; /* User resource return information */
- +} ETH_RX_DESC;
- +
- +typedef struct _ethTxDesc
- +{
- + MV_U16 byteCnt ; /* Descriptor buffer byte count */
- + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
- + MV_U32 cmdSts ; /* Descriptor command status */
- + MV_U32 nextDescPtr; /* Next descriptor pointer */
- + MV_U32 bufPtr ; /* Descriptor buffer pointer */
- + MV_ULONG returnInfo ; /* User resource return information */
- + MV_U8* alignBufPtr; /* Pointer to 8 byte aligned buffer */
- +} ETH_TX_DESC;
- +
- +#elif defined(MV_CPU_LE)
- +
- +typedef struct _ethRxDesc
- +{
- + MV_U32 cmdSts ; /* Descriptor command status */
- + MV_U16 bufSize ; /* Buffer size */
- + MV_U16 byteCnt ; /* Descriptor buffer byte count */
- + MV_U32 bufPtr ; /* Descriptor buffer pointer */
- + MV_U32 nextDescPtr; /* Next descriptor pointer */
- + MV_ULONG returnInfo ; /* User resource return information */
- +} ETH_RX_DESC;
- +
- +typedef struct _ethTxDesc
- +{
- + MV_U32 cmdSts ; /* Descriptor command status */
- + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
- + MV_U16 byteCnt ; /* Descriptor buffer byte count */
- + MV_U32 bufPtr ; /* Descriptor buffer pointer */
- + MV_U32 nextDescPtr; /* Next descriptor pointer */
- + MV_ULONG returnInfo ; /* User resource return information */
- + MV_U8* alignBufPtr; /* Pointer to 32 byte aligned buffer */
- +} ETH_TX_DESC;
- +
- +#else
- +#error "MV_CPU_BE or MV_CPU_LE must be defined"
- +#endif /* MV_CPU_BE || MV_CPU_LE */
- +
- +/* Buffer offset from buffer pointer */
- +#define ETH_RX_BUF_OFFSET 0x2
- +
- +
- +/* Tx & Rx descriptor bits */
- +#define ETH_ERROR_SUMMARY_BIT 0
- +#define ETH_ERROR_SUMMARY_MASK (1<<ETH_ERROR_SUMMARY_BIT)
- +
- +#define ETH_BUFFER_OWNER_BIT 31
- +#define ETH_BUFFER_OWNED_BY_DMA (1<<ETH_BUFFER_OWNER_BIT)
- +#define ETH_BUFFER_OWNED_BY_HOST (0<<ETH_BUFFER_OWNER_BIT)
- +
- +/* Tx descriptor bits */
- +#define ETH_TX_ERROR_CODE_OFFSET 1
- +#define ETH_TX_ERROR_CODE_MASK (3<<ETH_TX_ERROR_CODE_OFFSET)
- +#define ETH_TX_LATE_COLLISION_ERROR (0<<ETH_TX_ERROR_CODE_OFFSET)
- +#define ETH_TX_UNDERRUN_ERROR (1<<ETH_TX_ERROR_CODE_OFFSET)
- +#define ETH_TX_EXCESSIVE_COLLISION_ERROR (2<<ETH_TX_ERROR_CODE_OFFSET)
- +
- +#define ETH_TX_LLC_SNAP_FORMAT_BIT 9
- +#define ETH_TX_LLC_SNAP_FORMAT_MASK (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)
- +
- +#define ETH_TX_IP_FRAG_BIT 10
- +#define ETH_TX_IP_FRAG_MASK (1<<ETH_TX_IP_FRAG_BIT)
- +#define ETH_TX_IP_FRAG (0<<ETH_TX_IP_FRAG_BIT)
- +#define ETH_TX_IP_NO_FRAG (1<<ETH_TX_IP_FRAG_BIT)
- +
- +#define ETH_TX_IP_HEADER_LEN_OFFSET 11
- +#define ETH_TX_IP_HEADER_LEN_ALL_MASK (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)
- +#define ETH_TX_IP_HEADER_LEN_MASK(len) ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)
- +
- +#define ETH_TX_VLAN_TAGGED_FRAME_BIT 15
- +#define ETH_TX_VLAN_TAGGED_FRAME_MASK (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)
- +
- +#define ETH_TX_L4_TYPE_BIT 16
- +#define ETH_TX_L4_TCP_TYPE (0<<ETH_TX_L4_TYPE_BIT)
- +#define ETH_TX_L4_UDP_TYPE (1<<ETH_TX_L4_TYPE_BIT)
- +
- +#define ETH_TX_GENERATE_L4_CHKSUM_BIT 17
- +#define ETH_TX_GENERATE_L4_CHKSUM_MASK (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)
- +
- +#define ETH_TX_GENERATE_IP_CHKSUM_BIT 18
- +#define ETH_TX_GENERATE_IP_CHKSUM_MASK (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)
- +
- +#define ETH_TX_ZERO_PADDING_BIT 19
- +#define ETH_TX_ZERO_PADDING_MASK (1<<ETH_TX_ZERO_PADDING_BIT)
- +
- +#define ETH_TX_LAST_DESC_BIT 20
- +#define ETH_TX_LAST_DESC_MASK (1<<ETH_TX_LAST_DESC_BIT)
- +
- +#define ETH_TX_FIRST_DESC_BIT 21
- +#define ETH_TX_FIRST_DESC_MASK (1<<ETH_TX_FIRST_DESC_BIT)
- +
- +#define ETH_TX_GENERATE_CRC_BIT 22
- +#define ETH_TX_GENERATE_CRC_MASK (1<<ETH_TX_GENERATE_CRC_BIT)
- +
- +#define ETH_TX_ENABLE_INTERRUPT_BIT 23
- +#define ETH_TX_ENABLE_INTERRUPT_MASK (1<<ETH_TX_ENABLE_INTERRUPT_BIT)
- +
- +#define ETH_TX_AUTO_MODE_BIT 30
- +#define ETH_TX_AUTO_MODE_MASK (1<<ETH_TX_AUTO_MODE_BIT)
- +
- +
- +/* Rx descriptor bits */
- +#define ETH_RX_ERROR_CODE_OFFSET 1
- +#define ETH_RX_ERROR_CODE_MASK (3<<ETH_RX_ERROR_CODE_OFFSET)
- +#define ETH_RX_CRC_ERROR (0<<ETH_RX_ERROR_CODE_OFFSET)
- +#define ETH_RX_OVERRUN_ERROR (1<<ETH_RX_ERROR_CODE_OFFSET)
- +#define ETH_RX_MAX_FRAME_LEN_ERROR (2<<ETH_RX_ERROR_CODE_OFFSET)
- +#define ETH_RX_RESOURCE_ERROR (3<<ETH_RX_ERROR_CODE_OFFSET)
- +
- +#define ETH_RX_L4_CHECKSUM_OFFSET 3
- +#define ETH_RX_L4_CHECKSUM_MASK (0xffff<<ETH_RX_L4_CHECKSUM_OFFSET)
- +
- +#define ETH_RX_VLAN_TAGGED_FRAME_BIT 19
- +#define ETH_RX_VLAN_TAGGED_FRAME_MASK (1<<ETH_RX_VLAN_TAGGED_FRAME_BIT)
- +
- +#define ETH_RX_BPDU_FRAME_BIT 20
- +#define ETH_RX_BPDU_FRAME_MASK (1<<ETH_RX_BPDU_FRAME_BIT)
- +
- +#define ETH_RX_L4_TYPE_OFFSET 21
- +#define ETH_RX_L4_TYPE_MASK (3<<ETH_RX_L4_TYPE_OFFSET)
- +#define ETH_RX_L4_TCP_TYPE (0<<ETH_RX_L4_TYPE_OFFSET)
- +#define ETH_RX_L4_UDP_TYPE (1<<ETH_RX_L4_TYPE_OFFSET)
- +#define ETH_RX_L4_OTHER_TYPE (2<<ETH_RX_L4_TYPE_OFFSET)
- +
- +#define ETH_RX_NOT_LLC_SNAP_FORMAT_BIT 23
- +#define ETH_RX_NOT_LLC_SNAP_FORMAT_MASK (1<<ETH_RX_NOT_LLC_SNAP_FORMAT_BIT)
- +
- +#define ETH_RX_IP_FRAME_TYPE_BIT 24
- +#define ETH_RX_IP_FRAME_TYPE_MASK (1<<ETH_RX_IP_FRAME_TYPE_BIT)
- +
- +#define ETH_RX_IP_HEADER_OK_BIT 25
- +#define ETH_RX_IP_HEADER_OK_MASK (1<<ETH_RX_IP_HEADER_OK_BIT)
- +
- +#define ETH_RX_LAST_DESC_BIT 26
- +#define ETH_RX_LAST_DESC_MASK (1<<ETH_RX_LAST_DESC_BIT)
- +
- +#define ETH_RX_FIRST_DESC_BIT 27
- +#define ETH_RX_FIRST_DESC_MASK (1<<ETH_RX_FIRST_DESC_BIT)
- +
- +#define ETH_RX_UNKNOWN_DA_BIT 28
- +#define ETH_RX_UNKNOWN_DA_MASK (1<<ETH_RX_UNKNOWN_DA_BIT)
- +
- +#define ETH_RX_ENABLE_INTERRUPT_BIT 29
- +#define ETH_RX_ENABLE_INTERRUPT_MASK (1<<ETH_RX_ENABLE_INTERRUPT_BIT)
- +
- +#define ETH_RX_L4_CHECKSUM_OK_BIT 30
- +#define ETH_RX_L4_CHECKSUM_OK_MASK (1<<ETH_RX_L4_CHECKSUM_OK_BIT)
- +
- +/* Rx descriptor bufSize field */
- +#define ETH_RX_IP_FRAGMENTED_FRAME_BIT 2
- +#define ETH_RX_IP_FRAGMENTED_FRAME_MASK (1<<ETH_RX_IP_FRAGMENTED_FRAME_BIT)
- +
- +#define ETH_RX_BUFFER_MASK 0xFFF8
- +
- +
- +/* Ethernet Cause Register BITs */
- +#define ETH_CAUSE_RX_READY_SUM_BIT 0
- +#define ETH_CAUSE_EXTEND_BIT 1
- +
- +#define ETH_CAUSE_RX_READY_OFFSET 2
- +#define ETH_CAUSE_RX_READY_BIT(queue) (ETH_CAUSE_RX_READY_OFFSET + (queue))
- +#define ETH_CAUSE_RX_READY_MASK(queue) (1 << (ETH_CAUSE_RX_READY_BIT(queue)))
- +
- +#define ETH_CAUSE_RX_ERROR_SUM_BIT 10
- +#define ETH_CAUSE_RX_ERROR_OFFSET 11
- +#define ETH_CAUSE_RX_ERROR_BIT(queue) (ETH_CAUSE_RX_ERROR_OFFSET + (queue))
- +#define ETH_CAUSE_RX_ERROR_MASK(queue) (1 << (ETH_CAUSE_RX_ERROR_BIT(queue)))
- +
- +#define ETH_CAUSE_TX_END_BIT 19
- +#define ETH_CAUSE_SUM_BIT 31
- +
- +/* Ethernet Cause Extended Register BITs */
- +#define ETH_CAUSE_TX_BUF_OFFSET 0
- +#define ETH_CAUSE_TX_BUF_BIT(queue) (ETH_CAUSE_TX_BUF_OFFSET + (queue))
- +#define ETH_CAUSE_TX_BUF_MASK(queue) (1 << (ETH_CAUSE_TX_BUF_BIT(queue)))
- +
- +#define ETH_CAUSE_TX_ERROR_OFFSET 8
- +#define ETH_CAUSE_TX_ERROR_BIT(queue) (ETH_CAUSE_TX_ERROR_OFFSET + (queue))
- +#define ETH_CAUSE_TX_ERROR_MASK(queue) (1 << (ETH_CAUSE_TX_ERROR_BIT(queue)))
- +
- +#define ETH_CAUSE_PHY_STATUS_CHANGE_BIT 16
- +#define ETH_CAUSE_RX_OVERRUN_BIT 18
- +#define ETH_CAUSE_TX_UNDERRUN_BIT 19
- +#define ETH_CAUSE_LINK_STATE_CHANGE_BIT 20
- +#define ETH_CAUSE_INTERNAL_ADDR_ERR_BIT 23
- +#define ETH_CAUSE_EXTEND_SUM_BIT 31
- +
- +/* Marvell Header Register */
- +/* Marvell Header register bits */
- +#define ETH_MVHDR_EN_BIT 0
- +#define ETH_MVHDR_EN_MASK (1 << ETH_MVHDR_EN_BIT)
- +
- +#define ETH_MVHDR_DAPREFIX_BIT 1
- +#define ETH_MVHDR_DAPREFIX_MASK (0x3 << ETH_MVHDR_DAPREFIX_BIT)
- +#define ETH_MVHDR_DAPREFIX_PRI_1_2 (0x1 << ETH_MVHDR_DAPREFIX_BIT)
- +#define ETH_MVHDR_DAPREFIX_DBNUM_PRI (0x2 << ETH_MVHDR_DAPREFIX_BIT)
- +#define ETH_MVHDR_DAPREFIX_SPID_PRI (0x3 << ETH_MVHDR_DAPREFIX_BIT)
- +
- +#define ETH_MVHDR_MHMASK_BIT 8
- +#define ETH_MVHDR_MHMASK_MASK (0x3 << ETH_MVHDR_MHMASK_BIT)
- +#define ETH_MVHDR_MHMASK_8_QUEUE (0x0 << ETH_MVHDR_MHMASK_BIT)
- +#define ETH_MVHDR_MHMASK_4_QUEUE (0x1 << ETH_MVHDR_MHMASK_BIT)
- +#define ETH_MVHDR_MHMASK_2_QUEUE (0x3 << ETH_MVHDR_MHMASK_BIT)
- +
- +
- +/* Relevant for 6183 ONLY */
- +#define ETH_UNIT_PORTS_PADS_CALIB_0_REG (MV_ETH_REG_BASE(0) + 0x0A0)
- +#define ETH_UNIT_PORTS_PADS_CALIB_1_REG (MV_ETH_REG_BASE(0) + 0x0A4)
- +#define ETH_UNIT_PORTS_PADS_CALIB_2_REG (MV_ETH_REG_BASE(0) + 0x0A8)
- +/* Ethernet Unit Ports Pads Calibration_REG (ETH_UNIT_PORTS_PADS_CALIB_x_REG) */
- +#define ETH_ETHERNET_PAD_CLIB_DRVN_OFFS 0
- +#define ETH_ETHERNET_PAD_CLIB_DRVN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVN_OFFS)
- +
- +#define ETH_ETHERNET_PAD_CLIB_DRVP_OFFS 5
- +#define ETH_ETHERNET_PAD_CLIB_DRVP_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVP_OFFS)
- +
- +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS 16
- +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS)
- +
- +#define ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS 17
- +#define ETH_ETHERNET_PAD_CLIB_LOCKN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS)
- +
- +#define ETH_ETHERNET_PAD_CLIB_OFFST_OFFS 24
- +#define ETH_ETHERNET_PAD_CLIB_OFFST_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_OFFST_OFFS)
- +
- +#define ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS 31
- +#define ETH_ETHERNET_PAD_CLIB_WR_EN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS)
- +
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvEthRegsh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 2010-11-09 20:28:11.222495438 +0100
- @@ -0,0 +1,356 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +/*******************************************************************************
- +* mvEth.h - Header File for : Ethernet Controller
- +*
- +* DESCRIPTION:
- +* This header file contains macros typedefs and function declaration for
- +* Marvell Gigabit Ethernet Controllers.
- +*
- +* DEPENDENCIES:
- +* None.
- +*
- +*******************************************************************************/
- +
- +#ifndef __mvEth_h__
- +#define __mvEth_h__
- +
- +/* includes */
- +#include "mvTypes.h"
- +#include "mv802_3.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +#include "eth/gbe/mvEthRegs.h"
- +#include "mvSysHwConfig.h"
- +
- +/* defines */
- +
- +#define MV_ETH_EXTRA_FRAGS_NUM 2
- +
- +
- +typedef enum
- +{
- + MV_ETH_SPEED_AN,
- + MV_ETH_SPEED_10,
- + MV_ETH_SPEED_100,
- + MV_ETH_SPEED_1000
- +
- +} MV_ETH_PORT_SPEED;
- +
- +typedef enum
- +{
- + MV_ETH_DUPLEX_AN,
- + MV_ETH_DUPLEX_HALF,
- + MV_ETH_DUPLEX_FULL
- +
- +} MV_ETH_PORT_DUPLEX;
- +
- +typedef enum
- +{
- + MV_ETH_FC_AN_ADV_DIS,
- + MV_ETH_FC_AN_ADV_SYM,
- + MV_ETH_FC_DISABLE,
- + MV_ETH_FC_ENABLE
- +
- +} MV_ETH_PORT_FC;
- +
- +typedef enum
- +{
- + MV_ETH_PRIO_FIXED = 0, /* Fixed priority mode */
- + MV_ETH_PRIO_WRR = 1 /* Weighted round robin priority mode */
- +} MV_ETH_PRIO_MODE;
- +
- +/* Ethernet port specific infomation */
- +typedef struct
- +{
- + int maxRxPktSize;
- + int rxDefQ;
- + int rxBpduQ;
- + int rxArpQ;
- + int rxTcpQ;
- + int rxUdpQ;
- + int ejpMode;
- +} MV_ETH_PORT_CFG;
- +
- +typedef struct
- +{
- + int descrNum;
- +} MV_ETH_RX_Q_CFG;
- +
- +typedef struct
- +{
- + int descrNum;
- + MV_ETH_PRIO_MODE prioMode;
- + int quota;
- +} MV_ETH_TX_Q_CFG;
- +
- +typedef struct
- +{
- + int maxRxPktSize;
- + int rxDefQ;
- + int txDescrNum[MV_ETH_TX_Q_NUM];
- + int rxDescrNum[MV_ETH_RX_Q_NUM];
- + void *osHandle;
- +} MV_ETH_PORT_INIT;
- +
- +typedef struct
- +{
- + MV_BOOL isLinkUp;
- + MV_ETH_PORT_SPEED speed;
- + MV_ETH_PORT_DUPLEX duplex;
- + MV_ETH_PORT_FC flowControl;
- +
- +} MV_ETH_PORT_STATUS;
- +
- +typedef enum
- +{
- + MV_ETH_DISABLE_HEADER_MODE = 0,
- + MV_ETH_ENABLE_HEADER_MODE_PRI_2_1 = 1,
- + MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM = 2,
- + MV_ETH_ENABLE_HEADER_MODE_PRI_SPID = 3
- +} MV_ETH_HEADER_MODE;
- +
- +
- +/* ethernet.h API list */
- +void mvEthHalInit(void);
- +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher);
- +
- +/* Port Initalization routines */
- +void* mvEthPortInit (int port, MV_ETH_PORT_INIT *pPortInit);
- +void ethResetTxDescRing(void* pPortHndl, int queue);
- +void ethResetRxDescRing(void* pPortHndl, int queue);
- +
- +void* mvEthPortHndlGet(int port);
- +
- +void mvEthPortFinish(void* pEthPortHndl);
- +MV_STATUS mvEthPortDown(void* pEthPortHndl);
- +MV_STATUS mvEthPortDisable(void* pEthPortHndl);
- +MV_STATUS mvEthPortUp(void* pEthPortHndl);
- +MV_STATUS mvEthPortEnable(void* pEthPortHndl);
- +
- +/* Port data flow routines */
- +MV_PKT_INFO *mvEthPortForceTxDone(void* pEthPortHndl, int txQueue);
- +MV_PKT_INFO *mvEthPortForceRx(void* pEthPortHndl, int rxQueue);
- +
- +/* Port Configuration routines */
- +MV_STATUS mvEthDefaultsSet(void* pEthPortHndl);
- +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize);
- +
- +/* Port RX MAC Filtering control routines */
- +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr);
- +MV_STATUS mvEthRxFilterModeSet(void* pPortHndl, MV_BOOL isPromisc);
- +MV_STATUS mvEthMacAddrSet(void* pPortHandle, MV_U8* pMacAddr, int queue);
- +MV_STATUS mvEthMcastAddrSet(void* pPortHandle, MV_U8 *pAddr, int queue);
- +
- +/* MIB Counters APIs */
- +MV_U32 mvEthMibCounterRead(void* pPortHndl, unsigned int mibOffset,
- + MV_U32* pHigh32);
- +void mvEthMibCountersClear(void* pPortHandle);
- +
- +/* TX Scheduling configuration routines */
- +MV_STATUS mvEthTxQueueConfig(void* pPortHandle, int txQueue,
- + MV_ETH_PRIO_MODE txPrioMode, int txQuota);
- +
- +/* RX Dispatching configuration routines */
- +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue);
- +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue);
- +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq);
- +int mvEthTosToRxqGet(void* pPortHandle, int tos);
- +
- +/* Speed, Duplex, FlowControl routines */
- +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
- + MV_ETH_PORT_DUPLEX duplex);
- +
- +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl);
- +
- +#if (MV_ETH_VERSION >= 4)
- +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode);
- +#endif /* (MV_ETH_VERSION >= 4) */
- +
- +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus);
- +
- +/* Marvell Header control */
- +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
- +
- +/* PHY routines */
- +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr);
- +int mvEthPhyAddrGet(void* pPortHandle);
- +
- +/* Power management routines */
- +void mvEthPortPowerDown(int port);
- +void mvEthPortPowerUp(int port);
- +
- +/******************** ETH PRIVATE ************************/
- +
- +/*#define UNCACHED_TX_BUFFERS*/
- +/*#define UNCACHED_RX_BUFFERS*/
- +
- +
- +/* Port attributes */
- +/* Size of a Tx/Rx descriptor used in chain list data structure */
- +#define ETH_RX_DESC_ALIGNED_SIZE 32
- +#define ETH_TX_DESC_ALIGNED_SIZE 32
- +
- +#define TX_DISABLE_TIMEOUT_MSEC 1000
- +#define RX_DISABLE_TIMEOUT_MSEC 1000
- +#define TX_FIFO_EMPTY_TIMEOUT_MSEC 10000
- +#define PORT_DISABLE_WAIT_TCLOCKS 5000
- +
- +/* Macros that save access to desc in order to find next desc pointer */
- +#define RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl) \
- + ((pRxDescr) == (pQueueCtrl)->pLastDescr) ? \
- + (ETH_RX_DESC*)((pQueueCtrl)->pFirstDescr) : \
- + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) + ETH_RX_DESC_ALIGNED_SIZE)
- +
- +#define TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl) \
- + ((pTxDescr) == (pQueueCtrl)->pLastDescr) ? \
- + (ETH_TX_DESC*)((pQueueCtrl)->pFirstDescr) : \
- + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) + ETH_TX_DESC_ALIGNED_SIZE)
- +
- +#define RX_PREV_DESC_PTR(pRxDescr, pQueueCtrl) \
- + ((pRxDescr) == (pQueueCtrl)->pFirstDescr) ? \
- + (ETH_RX_DESC*)((pQueueCtrl)->pLastDescr) : \
- + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) - ETH_RX_DESC_ALIGNED_SIZE)
- +
- +#define TX_PREV_DESC_PTR(pTxDescr, pQueueCtrl) \
- + ((pTxDescr) == (pQueueCtrl)->pFirstDescr) ? \
- + (ETH_TX_DESC*)((pQueueCtrl)->pLastDescr) : \
- + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) - ETH_TX_DESC_ALIGNED_SIZE)
- +
- +
- +/* Queue specific information */
- +typedef struct
- +{
- + void* pFirstDescr;
- + void* pLastDescr;
- + void* pCurrentDescr;
- + void* pUsedDescr;
- + int resource;
- + MV_BUF_INFO descBuf;
- +} ETH_QUEUE_CTRL;
- +
- +
- +/* Ethernet port specific infomation */
- +typedef struct _ethPortCtrl
- +{
- + int portNo;
- + ETH_QUEUE_CTRL rxQueue[MV_ETH_RX_Q_NUM]; /* Rx ring resource */
- + ETH_QUEUE_CTRL txQueue[MV_ETH_TX_Q_NUM]; /* Tx ring resource */
- +
- + MV_ETH_PORT_CFG portConfig;
- + MV_ETH_RX_Q_CFG rxQueueConfig[MV_ETH_RX_Q_NUM];
- + MV_ETH_TX_Q_CFG txQueueConfig[MV_ETH_TX_Q_NUM];
- +
- + /* Register images - For DP */
- + MV_U32 portTxQueueCmdReg; /* Port active Tx queues summary */
- + MV_U32 portRxQueueCmdReg; /* Port active Rx queues summary */
- +
- + MV_STATE portState;
- +
- + MV_U8 mcastCount[256];
- + MV_U32* hashPtr;
- + void *osHandle;
- +} ETH_PORT_CTRL;
- +
- +/************** MACROs ****************/
- +
- +/* MACROs to Flush / Invalidate TX / RX Buffers */
- +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_TX_BUFFERS)
- +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
- + mvOsCacheClear(NULL, (pAddr), (size)); \
- + /*CPU_PIPE_FLUSH;*/
- +#else
- +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
- + mvOsIoVirtToPhy(NULL, (pAddr));
- +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW */
- +
- +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_RX_BUFFERS) )
- +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size) \
- + mvOsCacheInvalidate (NULL, (pAddr), (size)); \
- + /*CPU_PIPE_FLUSH;*/
- +#else
- +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)
- +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW && !UNCACHED_RX_BUFFERS */
- +
- +#ifdef ETH_DESCR_UNCACHED
- +
- +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)
- +#define ETH_DESCR_INV(pPortCtrl, pDescr)
- +
- +#else
- +
- +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr) \
- + mvOsCacheLineFlushInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
- +
- +#define ETH_DESCR_INV(pPortCtrl, pDescr) \
- + mvOsCacheLineInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
- +
- +#endif /* ETH_DESCR_UNCACHED */
- +
- +#include "eth/gbe/mvEthGbe.h"
- +
- +#endif /* __mvEth_h__ */
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 2010-11-09 20:28:11.262495582 +0100
- @@ -0,0 +1,362 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "gpp/mvGpp.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value);
- +
- +/*******************************************************************************
- +* mvGppTypeSet - Enable a GPP (OUT) pin
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* group - GPP group number
- +* mask - 32bit mask value. Each set bit in the mask means that the type
- +* of corresponding GPP will be set. Other GPPs are ignored.
- +* value - 32bit value that describes GPP type per pin.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* EXAMPLE:
- +* Set GPP8 to input and GPP15 to output.
- +* mvGppTypeSet(0, (GPP8 | GPP15),
- +* ((MV_GPP_IN & GPP8) | (MV_GPP_OUT & GPP15)) );
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value)
- +{
- + if (group >= MV_GPP_MAX_GROUP)
- + {
- + DB(mvOsPrintf("mvGppTypeSet: ERR. invalid group number \n"));
- + return MV_BAD_PARAM;
- + }
- +
- + gppRegSet(group, GPP_DATA_OUT_EN_REG(group), mask, value);
- +
- + /* Workaround for Erratum FE-MISC-70*/
- + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
- + {
- + mask &= 0x2;
- + gppRegSet(0, GPP_DATA_OUT_EN_REG(0), mask, value);
- + } /*End of WA*/
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* group - GPP group number
- +* mask - 32bit mask value. Each set bit in the mask means that the type
- +* of corresponding GPP will be set. Other GPPs are ignored.
- +* value - 32bit value that describes GPP blink per pin.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* EXAMPLE:
- +* Set GPP8 to be static and GPP15 to be blinking.
- +* mvGppBlinkEn(0, (GPP8 | GPP15),
- +* ((MV_GPP_OUT_STATIC & GPP8) | (MV_GPP_OUT_BLINK & GPP15)) );
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value)
- +{
- + if (group >= MV_GPP_MAX_GROUP)
- + {
- + DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
- + return MV_BAD_PARAM;
- + }
- +
- + gppRegSet(group, GPP_BLINK_EN_REG(group), mask, value);
- +
- + return MV_OK;
- +
- +}
- +/*******************************************************************************
- +* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* group - GPP group number
- +* mask - 32bit mask value. Each set bit in the mask means that the type
- +* of corresponding GPP will be set. Other GPPs are ignored.
- +* value - 32bit value that describes GPP polarity per pin.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* EXAMPLE:
- +* Set GPP8 to the actual pin value and GPP15 to be inverted.
- +* mvGppPolaritySet(0, (GPP8 | GPP15),
- +* ((MV_GPP_IN_ORIGIN & GPP8) | (MV_GPP_IN_INVERT & GPP15)) );
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value)
- +{
- + if (group >= MV_GPP_MAX_GROUP)
- + {
- + DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));
- + return MV_BAD_PARAM;
- + }
- +
- + gppRegSet(group, GPP_DATA_IN_POL_REG(group), mask, value);
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvGppPolarityGet - Get a value of relevant bits from GPP Polarity register.
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* group - GPP group number
- +* mask - 32bit mask value. Each set bit in the mask means that the
- +* returned value is valid for it.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* EXAMPLE:
- +* Get GPP8 and GPP15 value.
- +* mvGppPolarityGet(0, (GPP8 | GPP15));
- +*
- +* RETURN:
- +* 32bit value that describes GPP polatity mode per pin.
- +*
- +*******************************************************************************/
- +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask)
- +{
- + MV_U32 regVal;
- +
- + if (group >= MV_GPP_MAX_GROUP)
- + {
- + DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
- + return MV_ERROR;
- + }
- + regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));
- +
- + return (regVal & mask);
- +}
- +
- +/*******************************************************************************
- +* mvGppValueGet - Get a GPP Pin list value.
- +*
- +* DESCRIPTION:
- +* This function get GPP value.
- +*
- +* INPUT:
- +* group - GPP group number
- +* mask - 32bit mask value. Each set bit in the mask means that the
- +* returned value is valid for it.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* EXAMPLE:
- +* Get GPP8 and GPP15 value.
- +* mvGppValueGet(0, (GPP8 | GPP15));
- +*
- +* RETURN:
- +* 32bit value that describes GPP activity mode per pin.
- +*
- +*******************************************************************************/
- +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask)
- +{
- + MV_U32 gppData;
- +
- + gppData = MV_REG_READ(GPP_DATA_IN_REG(group));
- +
- + gppData &= mask;
- +
- + return gppData;
- +
- +}
- +
- +/*******************************************************************************
- +* mvGppValueSet - Set a GPP Pin list value.
- +*
- +* DESCRIPTION:
- +* This function set value for given GPP pin list.
- +*
- +* INPUT:
- +* group - GPP group number
- +* mask - 32bit mask value. Each set bit in the mask means that the
- +* value of corresponding GPP will be set accordingly. Other GPP
- +* are not affected.
- +* value - 32bit value that describes GPP value per pin.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* EXAMPLE:
- +* Set GPP8 value of '0' and GPP15 value of '1'.
- +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (GPP15)) );
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value)
- +{
- + MV_U32 outEnable, tmp;
- + MV_U32 i;
- +
- + if (group >= MV_GPP_MAX_GROUP)
- + {
- + DB(mvOsPrintf("mvGppValueSet: Error invalid group number \n"));
- + return MV_BAD_PARAM;
- + }
- +
- + /* verify that the gpp pin is configured as output */
- + /* Note that in the register out enabled -> bit = '0'. */
- + outEnable = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(group));
- +
- + /* Workaround for Erratum FE-MISC-70*/
- + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
- + {
- + tmp = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(0));
- + outEnable &= 0xfffffffd;
- + outEnable |= (tmp & 0x2);
- + } /*End of WA*/
- +
- + for (i = 0 ; i < 32 ;i++)
- + {
- + if (((mask & (1 << i)) & (outEnable & (1 << i))) != (mask & (1 << i)))
- + {
- + mvOsPrintf("mvGppValueSet: Err. An attempt to set output "\
- + "value to GPP %d in input mode.\n", i);
- + return MV_ERROR;
- + }
- + }
- +
- + gppRegSet(group, GPP_DATA_OUT_REG(group), mask, value);
- +
- + return MV_OK;
- +
- +}
- +/*******************************************************************************
- +* gppRegSet - Set a specific GPP pin on a specific GPP register
- +*
- +* DESCRIPTION:
- +* This function set a specific GPP pin on a specific GPP register
- +*
- +* INPUT:
- +* regOffs - GPP Register offset
- +* group - GPP group number
- +* mask - 32bit mask value. Each set bit in the mask means that the
- +* value of corresponding GPP will be set accordingly. Other GPP
- +* are not affected.
- +* value - 32bit value that describes GPP value per pin.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* EXAMPLE:
- +* Set GPP8 value of '0' and GPP15 value of '1'.
- +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (1 & GPP15)) );
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +static MV_VOID gppRegSet (MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value)
- +{
- + MV_U32 gppData;
- +
- + gppData = MV_REG_READ(regOffs);
- +
- + gppData &= ~mask;
- +
- + gppData |= (value & mask);
- +
- + MV_REG_WRITE(regOffs, gppData);
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 2010-11-09 20:28:11.302495429 +0100
- @@ -0,0 +1,118 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvGppH
- +#define __INCmvGppH
- +
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +#include "gpp/mvGppRegs.h"
- +
- +/* These macros describes the GPP type. Each of the GPPs pins can */
- +/* be assigned to act as a general purpose input or output pin. */
- +#define MV_GPP_IN 0xFFFFFFFF /* GPP input */
- +#define MV_GPP_OUT 0 /* GPP output */
- +
- +
- +/* These macros describes the GPP Out Enable. */
- +#define MV_GPP_OUT_DIS 0xFFFFFFFF /* Out pin disabled*/
- +#define MV_GPP_OUT_EN 0 /* Out pin enabled*/
- +
- +/* These macros describes the GPP Out Blinking. */
- +/* When set and the corresponding bit in GPIO Data Out Enable Control */
- +/* Register is enabled, the GPIO pin blinks every ~100 ms (a period of */
- +/* 2^24 TCLK clocks). */
- +#define MV_GPP_OUT_BLINK 0xFFFFFFFF /* Out pin blinking*/
- +#define MV_GPP_OUT_STATIC 0 /* Out pin static*/
- +
- +
- +/* These macros describes the GPP Polarity. */
- +/* When set to 1 GPIO Data In Register reflects the inverted value of the */
- +/* corresponding pin. */
- +
- +#define MV_GPP_IN_INVERT 0xFFFFFFFF /* Inverted value is got*/
- +#define MV_GPP_IN_ORIGIN 0 /* original value is got*/
- +
- +/* mvGppTypeSet - Set PP pin mode (IN or OUT) */
- +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value);
- +
- +/* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms */
- +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value);
- +
- +/* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode. */
- +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value);
- +
- +/* mvGppPolarityGet - Get the Polarity of a GPP Pin */
- +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask);
- +
- +/* mvGppValueGet - Get a GPP Pin list value.*/
- +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask);
- +
- +
- +/* mvGppValueSet - Set a GPP Pin list value. */
- +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value);
- +
- +#endif /* #ifndef __INCmvGppH */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 2010-11-09 20:28:11.342495467 +0100
- @@ -0,0 +1,116 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvGppRegsH
- +#define __INCmvGppRegsH
- +
- +#define MV_GPP0 BIT0
- +#define MV_GPP1 BIT1
- +#define MV_GPP2 BIT2
- +#define MV_GPP3 BIT3
- +#define MV_GPP4 BIT4
- +#define MV_GPP5 BIT5
- +#define MV_GPP6 BIT6
- +#define MV_GPP7 BIT7
- +#define MV_GPP8 BIT8
- +#define MV_GPP9 BIT9
- +#define MV_GPP10 BIT10
- +#define MV_GPP11 BIT11
- +#define MV_GPP12 BIT12
- +#define MV_GPP13 BIT13
- +#define MV_GPP14 BIT14
- +#define MV_GPP15 BIT15
- +#define MV_GPP16 BIT16
- +#define MV_GPP17 BIT17
- +#define MV_GPP18 BIT18
- +#define MV_GPP19 BIT19
- +#define MV_GPP20 BIT20
- +#define MV_GPP21 BIT21
- +#define MV_GPP22 BIT22
- +#define MV_GPP23 BIT23
- +#define MV_GPP24 BIT24
- +#define MV_GPP25 BIT25
- +#define MV_GPP26 BIT26
- +#define MV_GPP27 BIT27
- +#define MV_GPP28 BIT28
- +#define MV_GPP29 BIT29
- +#define MV_GPP30 BIT30
- +#define MV_GPP31 BIT31
- +
- +
- +/* registers offsets */
- +
- +#define GPP_DATA_OUT_REG(grp) ((grp == 0) ? 0x10100 : 0x10140)
- +#define GPP_DATA_OUT_EN_REG(grp) ((grp == 0) ? 0x10104 : 0x10144)
- +#define GPP_BLINK_EN_REG(grp) ((grp == 0) ? 0x10108 : 0x10148)
- +#define GPP_DATA_IN_POL_REG(grp) ((grp == 0) ? 0x1010C : 0x1014c)
- +#define GPP_DATA_IN_REG(grp) ((grp == 0) ? 0x10110 : 0x10150)
- +#define GPP_INT_CAUSE_REG(grp) ((grp == 0) ? 0x10114 : 0x10154)
- +#define GPP_INT_MASK_REG(grp) ((grp == 0) ? 0x10118 : 0x10158)
- +#define GPP_INT_LVL_REG(grp) ((grp == 0) ? 0x1011c : 0x1015c)
- +
- +#define GPP_DATA_OUT_SET_REG 0x10120
- +#define GPP_DATA_OUT_CLEAR_REG 0x10124
- +
- +#endif /* #ifndef __INCmvGppRegsH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 2010-11-09 20:28:11.372495482 +0100
- @@ -0,0 +1,1047 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#include "pci/mvPci.h"
- +
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +
- +
- +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod)
- +{
- + if (MV_PCI_MOD_HOST == pciIfmod)
- + {
- +
- + mvPciLocalBusNumSet(pciIf, PCI_HOST_BUS_NUM(pciIf));
- + mvPciLocalDevNumSet(pciIf, PCI_HOST_DEV_NUM(pciIf));
- +
- + /* Local device master Enable */
- + mvPciMasterEnable(pciIf, MV_TRUE);
- +
- + /* Local device slave Enable */
- + mvPciSlaveEnable(pciIf, mvPciLocalBusNumGet(pciIf),
- + mvPciLocalDevNumGet(pciIf), MV_TRUE);
- + }
- + /* enable CPU-2-PCI ordering */
- + MV_REG_BIT_SET(PCI_CMD_REG(0), PCR_CPU_TO_PCI_ORDER_EN);
- +}
- +
- +/*******************************************************************************
- +* mvPciCommandSet - Set PCI comman register value.
- +*
- +* DESCRIPTION:
- +* This function sets a given PCI interface with its command register
- +* value.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* command - 32bit value to be written to comamnd register.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM if pciIf is not in range otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command)
- +{
- + MV_U32 locBusNum, locDevNum, regVal;
- +
- + locBusNum = mvPciLocalBusNumGet(pciIf);
- + locDevNum = mvPciLocalDevNumGet(pciIf);
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciCommandSet: ERR. Invalid PCI IF num %d\n", pciIf);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Set command register */
- + MV_REG_WRITE(PCI_CMD_REG(pciIf), command);
- +
- + /* Upodate device max outstanding split tarnsaction */
- + if ((command & PCR_CPU_TO_PCI_ORDER_EN) &&
- + (command & PCR_PCI_TO_CPU_ORDER_EN))
- + {
- + /* Read PCI-X command register */
- + regVal = mvPciConfigRead (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND);
- +
- + /* clear bits 22:20 */
- + regVal &= 0xff8fffff;
- +
- + /* set reset value */
- + regVal |= (0x3 << 20);
- +
- + /* Write back the value */
- + mvPciConfigWrite (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND, regVal);
- + }
- +
- + return MV_OK;
- +
- +
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciModeGet - Get PCI interface mode.
- +*
- +* DESCRIPTION:
- +* This function returns the given PCI interface mode.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +*
- +* OUTPUT:
- +* pPciMode - Pointer to PCI mode structure.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode)
- +{
- + MV_U32 pciMode;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciModeGet: ERR. Invalid PCI interface %d\n", pciIf);
- + return MV_BAD_PARAM;
- + }
- + if (NULL == pPciMode)
- + {
- + mvOsPrintf("mvPciModeGet: ERR. pPciMode = NULL \n");
- + return MV_BAD_PARAM;
- + }
- +
- + /* Read pci mode register */
- + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
- +
- + switch (pciMode & PMR_PCI_MODE_MASK)
- + {
- + case PMR_PCI_MODE_CONV:
- + pPciMode->pciType = MV_PCI_CONV;
- +
- + if (MV_REG_READ(PCI_DLL_CTRL_REG(pciIf)) & PDC_DLL_EN)
- + {
- + pPciMode->pciSpeed = 66000000; /* 66MHZ */
- + }
- + else
- + {
- + pPciMode->pciSpeed = 33000000; /* 33MHZ */
- + }
- +
- + break;
- +
- + case PMR_PCI_MODE_PCIX_66MHZ:
- + pPciMode->pciType = MV_PCIX;
- + pPciMode->pciSpeed = 66000000; /* 66MHZ */
- + break;
- +
- + case PMR_PCI_MODE_PCIX_100MHZ:
- + pPciMode->pciType = MV_PCIX;
- + pPciMode->pciSpeed = 100000000; /* 100MHZ */
- + break;
- +
- + case PMR_PCI_MODE_PCIX_133MHZ:
- + pPciMode->pciType = MV_PCIX;
- + pPciMode->pciSpeed = 133000000; /* 133MHZ */
- + break;
- +
- + default:
- + {
- + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
- + return MV_ERROR;
- + }
- + }
- +
- + switch (pciMode & PMR_PCI_64_MASK)
- + {
- + case PMR_PCI_64_64BIT:
- + pPciMode->pciWidth = MV_PCI_64;
- + break;
- +
- + case PMR_PCI_64_32BIT:
- + pPciMode->pciWidth = MV_PCI_32;
- + break;
- +
- + default:
- + {
- + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
- + return MV_ERROR;
- + }
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPciRetrySet - Set PCI retry counters
- +*
- +* DESCRIPTION:
- +* This function specifies the number of times the PCI controller
- +* retries a transaction before it quits.
- +* Applies to the PCI Master when acting as a requester.
- +* Applies to the PCI slave when acting as a completer (PCI-X mode).
- +* A 0x00 value means a "retry forever".
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* counter - Number of times PCI controller retry. Use counter value
- +* up to PRR_RETRY_CNTR_MAX.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter)
- +{
- + MV_U32 pciRetry;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciRetrySet: ERR. Invalid PCI interface %d\n", pciIf);
- + return MV_BAD_PARAM;
- + }
- +
- + if (counter >= PRR_RETRY_CNTR_MAX)
- + {
- + mvOsPrintf("mvPciRetrySet: ERR. Invalid counter: %d\n", counter);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + /* Reading PCI retry register */
- + pciRetry = MV_REG_READ(PCI_RETRY_REG(pciIf));
- +
- + pciRetry &= ~PRR_RETRY_CNTR_MASK;
- +
- + pciRetry |= (counter << PRR_RETRY_CNTR_OFFS);
- +
- + /* write new value */
- + MV_REG_WRITE(PCI_RETRY_REG(pciIf), pciRetry);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciDiscardTimerSet - Set PCI discard timer
- +*
- +* DESCRIPTION:
- +* This function set PCI discard timer.
- +* In conventional PCI mode:
- +* Specifies the number of PCLK cycles the PCI slave keeps a non-accessed
- +* read buffers (non-completed delayed read) before invalidate the buffer.
- +* Set to '0' to disable the timer. The PCI slave waits for delayed
- +* read completion forever.
- +* In PCI-X mode:
- +* Specifies the number of PCLK cycles the PCI master waits for split
- +* completion transaction, before it invalidates the pre-allocated read
- +* buffer.
- +* Set to '0' to disable the timer. The PCI master waits for split
- +* completion forever.
- +* NOTE: Must be set to a number greater than MV_PCI_MAX_DISCARD_CLK,
- +* unless using the "wait for ever" setting 0x0.
- +* NOTE: Must not be updated while there are pending read requests.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* pClkCycles - Number of PCI clock cycles.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles)
- +{
- + MV_U32 pciDiscardTimer;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid PCI interface %d\n",
- + pciIf);
- + return MV_BAD_PARAM;
- + }
- +
- + if (pClkCycles >= PDTR_TIMER_MIN)
- + {
- + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid Clk value: %d\n",
- + pClkCycles);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + /* Read PCI Discard Timer */
- + pciDiscardTimer = MV_REG_READ(PCI_DISCARD_TIMER_REG(pciIf));
- +
- + pciDiscardTimer &= ~PDTR_TIMER_MASK;
- +
- + pciDiscardTimer |= (pClkCycles << PDTR_TIMER_OFFS);
- +
- + /* Write new value */
- + MV_REG_WRITE(PCI_DISCARD_TIMER_REG(pciIf), pciDiscardTimer);
- +
- + return MV_OK;
- +
- +}
- +
- +/* PCI Arbiter routines */
- +
- +/*******************************************************************************
- +* mvPciArbEnable - PCI arbiter enable/disable
- +*
- +* DESCRIPTION:
- +* This fuction enable/disables a given PCI interface arbiter.
- +* NOTE: Arbiter setting can not be changed while in work. It should only
- +* be set once.
- +* INPUT:
- +* pciIf - PCI interface number.
- +* enable - Enable/disable parameter. If enable = MV_TRUE then enable.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable)
- +{
- + MV_U32 regVal;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciArbEnable: ERR. Invalid PCI interface %d\n", pciIf);
- + return MV_ERROR;
- + }
- +
- + /* Set PCI Arbiter Control register according to default configuration */
- + regVal = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
- +
- + /* Make sure arbiter disabled before changing its values */
- + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
- +
- + regVal &= ~PCI_ARBITER_CTRL_DEFAULT_MASK;
- +
- + regVal |= PCI_ARBITER_CTRL_DEFAULT; /* Set default configuration */
- +
- + if (MV_TRUE == enable)
- + {
- + regVal |= PACR_ARB_ENABLE;
- + }
- + else
- + {
- + regVal &= ~PACR_ARB_ENABLE;
- + }
- +
- + /* Write to register */
- + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), regVal);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciArbParkDis - Disable arbiter parking on agent
- +*
- +* DESCRIPTION:
- +* This function disables the PCI arbiter from parking on the given agent
- +* list.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* pciAgentMask - When a bit in the mask is set to '1', parking on
- +* the associated PCI master is disabled. Mask bit
- +* refers to bit 0 - 6. For example disable parking on PCI
- +* agent 3 set pciAgentMask 0x4 (bit 3 is set).
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask)
- +{
- + MV_U32 pciArbiterCtrl;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciArbParkDis: ERR. Invalid PCI interface %d\n", pciIf);
- + return MV_ERROR;
- + }
- +
- + /* Reading Arbiter Control register */
- + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
- +
- + /* Arbiter must be disabled before changing parking */
- + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
- +
- + /* do the change */
- + pciArbiterCtrl &= ~PACR_PARK_DIS_MASK;
- + pciArbiterCtrl |= (pciAgentMask << PACR_PARK_DIS_OFFS);
- +
- + /* writing new value ( if th earbiter was enabled before the change */
- + /* here it will be reenabled */
- + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciArbBrokDetectSet - Set PCI arbiter broken detection
- +*
- +* DESCRIPTION:
- +* This function sets the maximum number of cycles that the arbiter
- +* waits for a PCI master to respond to its grant assertion. If a
- +* PCI agent fails to respond within this time, the PCI arbiter aborts
- +* the transaction and performs a new arbitration cycle.
- +* NOTE: Value must be greater than '1' for conventional PCI and
- +* greater than '5' for PCI-X.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* pClkCycles - Number of PCI clock cycles. If equal to '0' the broken
- +* master detection is disabled.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)
- +{
- + MV_U32 pciArbiterCtrl;
- + MV_U32 pciMode;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciArbBrokDetectSet: ERR. Invalid PCI interface %d\n",
- + pciIf);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Checking PCI mode and if pClkCycles is legal value */
- + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
- + pciMode &= PMR_PCI_MODE_MASK;
- +
- + if (PMR_PCI_MODE_CONV == pciMode)
- + {
- + if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN)
- + return MV_ERROR;
- + }
- + else
- + {
- + if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN)
- + return MV_ERROR;
- + }
- +
- + pClkCycles <<= PACR_BROKEN_VAL_OFFS;
- +
- + /* Reading Arbiter Control register */
- + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
- + pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;
- + pciArbiterCtrl |= pClkCycles;
- +
- + /* Arbiter must be disabled before changing broken detection */
- + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
- +
- + /* writing new value ( if th earbiter was enabled before the change */
- + /* here it will be reenabled */
- +
- + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
- +
- + return MV_OK;
- +}
- +
- +/* PCI configuration space read write */
- +
- +/*******************************************************************************
- +* mvPciConfigRead - Read from configuration space
- +*
- +* DESCRIPTION:
- +* This function performs a 32 bit read from PCI configuration space.
- +* It supports both type 0 and type 1 of Configuration Transactions
- +* (local and over bridge). In order to read from local bus segment, use
- +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
- +* will result configuration transaction of type 1 (over bridge).
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* bus - PCI segment bus number.
- +* dev - PCI device number.
- +* func - Function number.
- +* regOffs - Register offset.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit register data, 0xffffffff on error
- +*
- +*******************************************************************************/
- +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
- + MV_U32 regOff)
- +{
- + MV_U32 pciData = 0;
- +
- + /* Parameter checking */
- + if (PCI_DEFAULT_IF != pciIf)
- + {
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciConfigRead: ERR. Invalid PCI interface %d\n",pciIf);
- + return 0xFFFFFFFF;
- + }
- + }
- +
- + if (dev >= MAX_PCI_DEVICES)
- + {
- + DB(mvOsPrintf("mvPciConfigRead: ERR. device number illigal %d\n", dev));
- + return 0xFFFFFFFF;
- + }
- +
- + if (func >= MAX_PCI_FUNCS)
- + {
- + DB(mvOsPrintf("mvPciConfigRead: ERR. function number illigal %d\n", func));
- + return 0xFFFFFFFF;
- + }
- +
- + if (bus >= MAX_PCI_BUSSES)
- + {
- + DB(mvOsPrintf("mvPciConfigRead: ERR. bus number illigal %d\n", bus));
- + return MV_ERROR;
- + }
- +
- +
- + /* Creating PCI address to be passed */
- + pciData |= (bus << PCAR_BUS_NUM_OFFS);
- + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
- + pciData |= (func << PCAR_FUNC_NUM_OFFS);
- + pciData |= (regOff & PCAR_REG_NUM_MASK);
- +
- + pciData |= PCAR_CONFIG_EN;
- +
- + /* Write the address to the PCI configuration address register */
- + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
- +
- + /* In order to let the PCI controller absorbed the address of the read */
- + /* transaction we perform a validity check that the address was written */
- + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
- + {
- + return MV_ERROR;
- + }
- + /* Read the Data returned in the PCI Data register */
- + pciData = MV_REG_READ(PCI_CONFIG_DATA_REG(pciIf));
- +
- + return pciData;
- +}
- +
- +/*******************************************************************************
- +* mvPciConfigWrite - Write to configuration space
- +*
- +* DESCRIPTION:
- +* This function performs a 32 bit write to PCI configuration space.
- +* It supports both type 0 and type 1 of Configuration Transactions
- +* (local and over bridge). In order to write to local bus segment, use
- +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
- +* will result configuration transaction of type 1 (over bridge).
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* bus - PCI segment bus number.
- +* dev - PCI device number.
- +* func - Function number.
- +* regOffs - Register offset.
- +* data - 32bit data.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data)
- +{
- + MV_U32 pciData = 0;
- +
- + /* Parameter checking */
- + if (PCI_DEFAULT_IF != pciIf)
- + {
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciConfigWrite: ERR. Invalid PCI interface %d\n",
- + pciIf);
- + return 0xFFFFFFFF;
- + }
- + }
- +
- + if (dev >= MAX_PCI_DEVICES)
- + {
- + mvOsPrintf("mvPciConfigWrite: ERR. device number illigal %d\n",dev);
- + return MV_BAD_PARAM;
- + }
- +
- + if (func >= MAX_PCI_FUNCS)
- + {
- + mvOsPrintf("mvPciConfigWrite: ERR. function number illigal %d\n", func);
- + return MV_ERROR;
- + }
- +
- + if (bus >= MAX_PCI_BUSSES)
- + {
- + mvOsPrintf("mvPciConfigWrite: ERR. bus number illigal %d\n", bus);
- + return MV_ERROR;
- + }
- +
- + /* Creating PCI address to be passed */
- + pciData |= (bus << PCAR_BUS_NUM_OFFS);
- + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
- + pciData |= (func << PCAR_FUNC_NUM_OFFS);
- + pciData |= (regOff & PCAR_REG_NUM_MASK);
- +
- + pciData |= PCAR_CONFIG_EN;
- +
- + /* Write the address to the PCI configuration address register */
- + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
- +
- + /* In order to let the PCI controller absorbed the address of the read */
- + /* transaction we perform a validity check that the address was written */
- + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
- + {
- + return MV_ERROR;
- + }
- +
- + /* Write the Data passed to the PCI Data register */
- + MV_REG_WRITE(PCI_CONFIG_DATA_REG(pciIf), data);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
- +*
- +* DESCRIPTION:
- +* This function performs read modified write to PCI command status
- +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
- +* master is allowed to gain ownership on the bus, otherwise it is
- +* incapable to do so.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable)
- +{
- + MV_U32 pciCommandStatus;
- + MV_U32 RegOffs;
- + MV_U32 localBus;
- + MV_U32 localDev;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciMasterEnable: ERR. Invalid PCI interface %d\n", pciIf);
- + return MV_ERROR;
- + }
- +
- + localBus = mvPciLocalBusNumGet(pciIf);
- + localDev = mvPciLocalDevNumGet(pciIf);
- +
- + RegOffs = PCI_STATUS_AND_COMMAND;
- +
- + pciCommandStatus = mvPciConfigRead(pciIf, localBus, localDev, 0, RegOffs);
- +
- + if (MV_TRUE == enable)
- + {
- + pciCommandStatus |= PSCR_MASTER_EN;
- + }
- + else
- + {
- + pciCommandStatus &= ~PSCR_MASTER_EN;
- + }
- +
- + mvPciConfigWrite(pciIf, localBus, localDev, 0, RegOffs, pciCommandStatus);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
- +*
- +* DESCRIPTION:
- +* This function performs read modified write to PCI command status
- +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
- +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
- +* and PCI memory space access (bit 1).
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* dev - PCI device number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_BOOL enable)
- +{
- + MV_U32 pciCommandStatus;
- + MV_U32 RegOffs;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciSlaveEnable: ERR. Invalid PCI interface %d\n", pciIf);
- + return MV_BAD_PARAM;
- + }
- + if (dev >= MAX_PCI_DEVICES)
- + {
- + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", dev);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + RegOffs = PCI_STATUS_AND_COMMAND;
- +
- + pciCommandStatus=mvPciConfigRead(pciIf, bus, dev, 0, RegOffs);
- +
- + if (MV_TRUE == enable)
- + {
- + pciCommandStatus |= (PSCR_IO_EN | PSCR_MEM_EN);
- + }
- + else
- + {
- + pciCommandStatus &= ~(PSCR_IO_EN | PSCR_MEM_EN);
- + }
- +
- + mvPciConfigWrite(pciIf, bus, dev, 0, RegOffs, pciCommandStatus);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPciLocalBusNumSet - Set PCI interface local bus number.
- +*
- +* DESCRIPTION:
- +* This function sets given PCI interface its local bus number.
- +* Note: In case the PCI interface is PCI-X, the information is read-only.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* busNum - Bus number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
- +* MV_BAD_PARAM on bad parameters ,
- +* otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
- +{
- + MV_U32 pciP2PConfig;
- + MV_PCI_MODE pciMode;
- + MV_U32 localBus;
- + MV_U32 localDev;
- +
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciLocalBusNumSet: ERR. Invalid PCI interface %d\n",pciIf);
- + return MV_BAD_PARAM;
- + }
- + if (busNum >= MAX_PCI_BUSSES)
- + {
- + mvOsPrintf("mvPciLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
- + return MV_ERROR;
- +
- + }
- +
- + localBus = mvPciLocalBusNumGet(pciIf);
- + localDev = mvPciLocalDevNumGet(pciIf);
- +
- +
- + /* PCI interface mode */
- + mvPciModeGet(pciIf, &pciMode);
- +
- + /* if PCI type is PCI-X then it is not allowed to change the dev number */
- + if (MV_PCIX == pciMode.pciType)
- + {
- + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
- +
- + pciP2PConfig &= ~PXS_BN_MASK;
- +
- + pciP2PConfig |= (busNum << PXS_BN_OFFS) & PXS_BN_MASK;
- +
- + mvPciConfigWrite(pciIf, localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
- +
- + }
- + else
- + {
- + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
- +
- + pciP2PConfig &= ~PPCR_BUS_NUM_MASK;
- +
- + pciP2PConfig |= (busNum << PPCR_BUS_NUM_OFFS) & PPCR_BUS_NUM_MASK;
- +
- + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
- +
- + }
- +
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciLocalBusNumGet - Get PCI interface local bus number.
- +*
- +* DESCRIPTION:
- +* This function gets the local bus number of a given PCI interface.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Local bus number.0xffffffff on Error
- +*
- +*******************************************************************************/
- +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf)
- +{
- + MV_U32 pciP2PConfig;
- +
- + /* Parameter checking */
- + if (PCI_DEFAULT_IF != pciIf)
- + {
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciLocalBusNumGet: ERR. Invalid PCI interface %d\n",
- + pciIf);
- + return 0xFFFFFFFF;
- + }
- + }
- +
- + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
- + pciP2PConfig &= PPCR_BUS_NUM_MASK;
- + return (pciP2PConfig >> PPCR_BUS_NUM_OFFS);
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciLocalDevNumSet - Set PCI interface local device number.
- +*
- +* DESCRIPTION:
- +* This function sets given PCI interface its local device number.
- +* Note: In case the PCI interface is PCI-X, the information is read-only.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* devNum - Device number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
- +* otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
- +{
- + MV_U32 pciP2PConfig;
- + MV_PCI_MODE pciMode;
- + MV_U32 localBus;
- + MV_U32 localDev;
- +
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciLocalDevNumSet: ERR. Invalid PCI interface %d\n",pciIf);
- + return MV_BAD_PARAM;
- + }
- + if (devNum >= MAX_PCI_DEVICES)
- + {
- + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n",
- + devNum);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + localBus = mvPciLocalBusNumGet(pciIf);
- + localDev = mvPciLocalDevNumGet(pciIf);
- +
- + /* PCI interface mode */
- + mvPciModeGet(pciIf, &pciMode);
- +
- + /* if PCI type is PCIX then it is not allowed to change the dev number */
- + if (MV_PCIX == pciMode.pciType)
- + {
- + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
- +
- + pciP2PConfig &= ~PXS_DN_MASK;
- +
- + pciP2PConfig |= (devNum << PXS_DN_OFFS) & PXS_DN_MASK;
- +
- + mvPciConfigWrite(pciIf,localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
- + }
- + else
- + {
- + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
- +
- + pciP2PConfig &= ~PPCR_DEV_NUM_MASK;
- +
- + pciP2PConfig |= (devNum << PPCR_DEV_NUM_OFFS) & PPCR_DEV_NUM_MASK;
- +
- + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPciLocalDevNumGet - Get PCI interface local device number.
- +*
- +* DESCRIPTION:
- +* This function gets the local device number of a given PCI interface.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Local device number. 0xffffffff on Error
- +*
- +*******************************************************************************/
- +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf)
- +{
- + MV_U32 pciP2PConfig;
- +
- + /* Parameter checking */
- +
- + if (PCI_DEFAULT_IF != pciIf)
- + {
- + if (pciIf >= mvCtrlPciMaxIfGet())
- + {
- + mvOsPrintf("mvPciLocalDevNumGet: ERR. Invalid PCI interface %d\n",
- + pciIf);
- + return 0xFFFFFFFF;
- + }
- + }
- +
- + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
- +
- + pciP2PConfig &= PPCR_DEV_NUM_MASK;
- +
- + return (pciP2PConfig >> PPCR_DEV_NUM_OFFS);
- +}
- +
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 2010-11-09 20:28:11.412495457 +0100
- @@ -0,0 +1,185 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#ifndef __INCPCIH
- +#define __INCPCIH
- +
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +#include "pci/mvPciRegs.h"
- +
- +
- +/* NOTE not supported in this driver:
- +
- + Built In Self Test (BIST)
- + Vital Product Data (VPD)
- + Message Signaled Interrupt (MSI)
- + Power Management
- + Compact PCI Hot Swap
- + Header retarget
- +
- +Registers not supported:
- +1) PCI DLL Status and Control (PCI0 0x1D20, PCI1 0x1DA0)
- +2) PCI/MPP Pads Calibration (CI0/MPP[31:16] 0x1D1C, PCI1/MPP[15:0] 0X1D9C)
- +*/
- +
- +/* defines */
- +/* The number of supported PCI interfaces depend on Marvell controller */
- +/* device number. This device number ID is located on the PCI unit */
- +/* configuration header. This creates a loop where calling PCI */
- +/* configuration read/write routine results a call to get PCI configuration */
- +/* information etc. This macro defines a default PCI interface. This PCI */
- +/* interface is sure to exist. */
- +#define PCI_DEFAULT_IF 0
- +
- +
- +/* typedefs */
- +/* The Marvell controller supports both conventional PCI and PCI-X. */
- +/* This enumeration describes the PCI type. */
- +typedef enum _mvPciType
- +{
- + MV_PCI_CONV, /* Conventional PCI */
- + MV_PCIX /* PCI-X */
- +}MV_PCI_TYPE;
- +
- +typedef enum _mvPciMod
- +{
- + MV_PCI_MOD_HOST,
- + MV_PCI_MOD_DEVICE
- +}MV_PCI_MOD;
- +
- +
- +/* The Marvell controller supports both PCI width of 32 and 64 bit. */
- +/* This enumerator describes PCI width */
- +typedef enum _mvPciWidth
- +{
- + MV_PCI_32, /* PCI width 32bit */
- + MV_PCI_64 /* PCI width 64bit */
- +}MV_PCI_WIDTH;
- +
- +/* This structure describes the PCI unit configured type, speed and width. */
- +typedef struct _mvPciMode
- +{
- + MV_PCI_TYPE pciType; /* PCI type */
- + MV_U32 pciSpeed; /* Assuming PCI base clock on board is 33MHz */
- + MV_PCI_WIDTH pciWidth; /* PCI bus width */
- +}MV_PCI_MODE;
- +
- +/* mvPciInit - Initialize PCI interfaces*/
- +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod);
- +
- +/* mvPciCommandSet - Set PCI comman register value.*/
- +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command);
- +
- +/* mvPciModeGet - Get PCI interface mode.*/
- +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode);
- +
- +/* mvPciRetrySet - Set PCI retry counters*/
- +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter);
- +
- +/* mvPciDiscardTimerSet - Set PCI discard timer*/
- +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles);
- +
- +/* mvPciArbEnable - PCI arbiter enable/disable*/
- +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable);
- +
- +/* mvPciArbParkDis - Disable arbiter parking on agent */
- +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask);
- +
- +/* mvPciArbBrokDetectSet - Set PCI arbiter broken detection */
- +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles);
- +
- +/* mvPciConfigRead - Read from configuration space */
- +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func,MV_U32 regOff);
- +
- +/* mvPciConfigWrite - Write to configuration space */
- +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data);
- +
- +/* mvPciMasterEnable - Enable/disale PCI interface master transactions.*/
- +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable);
- +
- +/* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.*/
- +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,MV_BOOL enable);
- +
- +/* mvPciLocalBusNumSet - Set PCI interface local bus number.*/
- +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
- +
- +/* mvPciLocalBusNumGet - Get PCI interface local bus number.*/
- +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf);
- +
- +/* mvPciLocalDevNumSet - Set PCI interface local device number.*/
- +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
- +
- +/* mvPciLocalDevNumGet - Get PCI interface local device number.*/
- +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf);
- +
- +
- +#endif /* #ifndef __INCPCIH */
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 2010-11-09 20:28:11.452495500 +0100
- @@ -0,0 +1,411 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCPCIREGSH
- +#define __INCPCIREGSH
- +
- +
- +#include "pci-if/mvPciIfRegs.h"
- +/* defines */
- +#define MAX_PCI_DEVICES 32
- +#define MAX_PCI_FUNCS 8
- +#define MAX_PCI_BUSSES 128
- +
- +/* enumerators */
- +
- +/* This enumerator described the possible PCI slave targets. */
- +/* PCI slave targets are designated memory/IO address spaces that the */
- +/* PCI slave targets can access. They are also refered as "targets" */
- +/* this enumeratoe order is determined by the content of :
- + PCI_BASE_ADDR_ENABLE_REG */
- +
- +
- +/* registers offsetes defines */
- +
- +
- +
- +/*************************/
- +/* PCI control registers */
- +/*************************/
- +/* maen : should add new registers */
- +#define PCI_CMD_REG(pciIf) (0x30c00 + ((pciIf) * 0x80))
- +#define PCI_MODE_REG(pciIf) (0x30d00 + ((pciIf) * 0x80))
- +#define PCI_RETRY_REG(pciIf) (0x30c04 + ((pciIf) * 0x80))
- +#define PCI_DISCARD_TIMER_REG(pciIf) (0x30d04 + ((pciIf) * 0x80))
- +#define PCI_ARBITER_CTRL_REG(pciIf) (0x31d00 + ((pciIf) * 0x80))
- +#define PCI_P2P_CONFIG_REG(pciIf) (0x31d14 + ((pciIf) * 0x80))
- +#define PCI_ACCESS_CTRL_BASEL_REG(pciIf, targetWin) \
- + (0x31e00 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
- +#define PCI_ACCESS_CTRL_BASEH_REG(pciIf, targetWin) \
- + (0x31e04 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
- +#define PCI_ACCESS_CTRL_SIZE_REG(pciIf, targetWin) \
- + (0x31e08 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
- +
- +#define PCI_DLL_CTRL_REG(pciIf) (0x31d20 + ((pciIf) * 0x80))
- +
- +/* PCI Dll Control (PDC)*/
- +#define PDC_DLL_EN BIT0
- +
- +
- +/* PCI Command Register (PCR) */
- +#define PCR_MASTER_BYTE_SWAP_EN BIT0
- +#define PCR_MASTER_WR_COMBINE_EN BIT4
- +#define PCR_MASTER_RD_COMBINE_EN BIT5
- +#define PCR_MASTER_WR_TRIG_WHOLE BIT6
- +#define PCR_MASTER_RD_TRIG_WHOLE BIT7
- +#define PCR_MASTER_MEM_RD_LINE_EN BIT8
- +#define PCR_MASTER_MEM_RD_MULT_EN BIT9
- +#define PCR_MASTER_WORD_SWAP_EN BIT10
- +#define PCR_SLAVE_WORD_SWAP_EN BIT11
- +#define PCR_NS_ACCORDING_RCV_TRANS BIT14
- +#define PCR_MASTER_PCIX_REQ64N_EN BIT15
- +#define PCR_SLAVE_BYTE_SWAP_EN BIT16
- +#define PCR_MASTER_DAC_EN BIT17
- +#define PCR_MASTER_M64_ALLIGN BIT18
- +#define PCR_ERRORS_PROPAGATION_EN BIT19
- +#define PCR_SLAVE_SWAP_ENABLE BIT20
- +#define PCR_MASTER_SWAP_ENABLE BIT21
- +#define PCR_MASTER_INT_SWAP_EN BIT22
- +#define PCR_LOOP_BACK_ENABLE BIT23
- +#define PCR_SLAVE_INTREG_SWAP_OFFS 24
- +#define PCR_SLAVE_INTREG_SWAP_MASK 0x3
- +#define PCR_SLAVE_INTREG_BYTE_SWAP \
- + (MV_BYTE_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
- +#define PCR_SLAVE_INTREG_NO_SWAP \
- + (MV_NO_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
- +#define PCR_SLAVE_INTREG_BYTE_WORD \
- + (MV_BYTE_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
- +#define PCR_SLAVE_INTREG_WORD_SWAP \
- + (MV_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
- +#define PCR_RESET_REASSERTION_EN BIT26
- +#define PCR_PCI_TO_CPU_REG_ORDER_EN BIT28
- +#define PCR_CPU_TO_PCI_ORDER_EN BIT29
- +#define PCR_PCI_TO_CPU_ORDER_EN BIT30
- +
- +/* PCI Mode Register (PMR) */
- +#define PMR_PCI_ID_OFFS 0 /* PCI Interface ID */
- +#define PMR_PCI_ID_MASK (0x1 << PMR_PCI_ID_OFFS)
- +#define PMR_PCI_ID_PCI(pciNum) ((pciNum) << PCI_MODE_PCIID_OFFS)
- +
- +#define PMR_PCI_64_OFFS 2 /* 64-bit PCI Interface */
- +#define PMR_PCI_64_MASK (0x1 << PMR_PCI_64_OFFS)
- +#define PMR_PCI_64_64BIT (0x1 << PMR_PCI_64_OFFS)
- +#define PMR_PCI_64_32BIT (0x0 << PMR_PCI_64_OFFS)
- +
- +#define PMR_PCI_MODE_OFFS 4 /* PCI interface mode of operation */
- +#define PMR_PCI_MODE_MASK (0x3 << PMR_PCI_MODE_OFFS)
- +#define PMR_PCI_MODE_CONV (0x0 << PMR_PCI_MODE_OFFS)
- +#define PMR_PCI_MODE_PCIX_66MHZ (0x1 << PMR_PCI_MODE_OFFS)
- +#define PMR_PCI_MODE_PCIX_100MHZ (0x2 << PMR_PCI_MODE_OFFS)
- +#define PMR_PCI_MODE_PCIX_133MHZ (0x3 << PMR_PCI_MODE_OFFS)
- +
- +#define PMR_EXP_ROM_SUPPORT BIT8 /* Expansion ROM Active */
- +
- +#define PMR_PCI_RESET_OFFS 31 /* PCI Interface Reset Indication */
- +#define PMR_PCI_RESET_MASK (0x1 << PMR_PCI_RESET_OFFS)
- +#define PMR_PCI_RESET_PCIXRST (0x0 << PMR_PCI_RESET_OFFS)
- +
- +
- +/* PCI Retry Register (PRR) */
- +#define PRR_RETRY_CNTR_OFFS 16 /* Retry Counter */
- +#define PRR_RETRY_CNTR_MAX 0xff
- +#define PRR_RETRY_CNTR_MASK (PRR_RETRY_CNTR_MAX << PRR_RETRY_CNTR_OFFS)
- +
- +
- +/* PCI Discard Timer Register (PDTR) */
- +#define PDTR_TIMER_OFFS 0 /* Timer */
- +#define PDTR_TIMER_MAX 0xffff
- +#define PDTR_TIMER_MIN 0x7F
- +#define PDTR_TIMER_MASK (PDTR_TIMER_MAX << PDTR_TIMER_OFFS)
- +
- +
- +/* PCI Arbiter Control Register (PACR) */
- +#define PACR_BROKEN_DETECT_EN BIT1 /* Broken Detection Enable */
- +
- +#define PACR_BROKEN_VAL_OFFS 3 /* Broken Value */
- +#define PACR_BROKEN_VAL_MASK (0xf << PACR_BROKEN_VAL_OFFS)
- +#define PACR_BROKEN_VAL_CONV_MIN 0x2
- +#define PACR_BROKEN_VAL_PCIX_MIN 0x6
- +
- +#define PACR_PARK_DIS_OFFS 14 /* Parking Disable */
- +#define PACR_PARK_DIS_MAX_AGENT 0x3f
- +#define PACR_PARK_DIS_MASK (PACR_PARK_DIS_MAX_AGENT<<PACR_PARK_DIS_OFFS)
- +#define PACR_PARK_DIS(agent) ((1 << (agent)) << PACR_PARK_DIS_OFFS)
- +
- +#define PACR_ARB_ENABLE BIT31 /* Enable Internal Arbiter */
- +
- +
- +/* PCI P2P Configuration Register (PPCR) */
- +#define PPCR_2ND_BUS_L_OFFS 0 /* 2nd PCI Interface Bus Range Lower */
- +#define PPCR_2ND_BUS_L_MASK (0xff << PPCR_2ND_BUS_L_OFFS)
- +
- +#define PPCR_2ND_BUS_H_OFFS 8 /* 2nd PCI Interface Bus Range Upper */
- +#define PPCR_2ND_BUS_H_MASK (0xff << PPCR_2ND_BUS_H_OFFS)
- +
- +#define PPCR_BUS_NUM_OFFS 16 /* The PCI interface's Bus number */
- +#define PPCR_BUS_NUM_MASK (0xff << PPCR_BUS_NUM_OFFS)
- +
- +#define PPCR_DEV_NUM_OFFS 24 /* The PCI interface’s Device number */
- +#define PPCR_DEV_NUM_MASK (0xff << PPCR_DEV_NUM_OFFS)
- +
- +
- +/* PCI Access Control Base Low Register (PACBLR) */
- +#define PACBLR_EN BIT0 /* Access control window enable */
- +
- +#define PACBLR_ACCPROT BIT4 /* Access Protect */
- +#define PACBLR_WRPROT BIT5 /* Write Protect */
- +
- +#define PACBLR_PCISWAP_OFFS 6 /* PCI slave Data Swap Control */
- +#define PACBLR_PCISWAP_MASK (0x3 << PACBLR_PCISWAP_OFFS)
- +#define PACBLR_PCISWAP_BYTE (0x0 << PACBLR_PCISWAP_OFFS)
- +#define PACBLR_PCISWAP_NO_SWAP (0x1 << PACBLR_PCISWAP_OFFS)
- +#define PACBLR_PCISWAP_BYTE_WORD (0x2 << PACBLR_PCISWAP_OFFS)
- +#define PACBLR_PCISWAP_WORD (0x3 << PACBLR_PCISWAP_OFFS)
- +
- +#define PACBLR_RDMBURST_OFFS 8 /* Read Max Burst */
- +#define PACBLR_RDMBURST_MASK (0x3 << PACBLR_RDMBURST_OFFS)
- +#define PACBLR_RDMBURST_32BYTE (0x0 << PACBLR_RDMBURST_OFFS)
- +#define PACBLR_RDMBURST_64BYTE (0x1 << PACBLR_RDMBURST_OFFS)
- +#define PACBLR_RDMBURST_128BYTE (0x2 << PACBLR_RDMBURST_OFFS)
- +
- +#define PACBLR_RDSIZE_OFFS 10 /* Typical PCI read transaction Size. */
- +#define PACBLR_RDSIZE_MASK (0x3 << PACBLR_RDSIZE_OFFS)
- +#define PACBLR_RDSIZE_32BYTE (0x0 << PACBLR_RDSIZE_OFFS)
- +#define PACBLR_RDSIZE_64BYTE (0x1 << PACBLR_RDSIZE_OFFS)
- +#define PACBLR_RDSIZE_128BYTE (0x2 << PACBLR_RDSIZE_OFFS)
- +#define PACBLR_RDSIZE_256BYTE (0x3 << PACBLR_RDSIZE_OFFS)
- +
- +#define PACBLR_BASE_L_OFFS 12 /* Corresponds to address bits [31:12] */
- +#define PACBLR_BASE_L_MASK (0xfffff << PACBLR_BASE_L_OFFS)
- +#define PACBLR_BASE_L_ALIGNMENT (1 << PACBLR_BASE_L_OFFS)
- +#define PACBLR_BASE_ALIGN_UP(base) \
- + ((base+PACBLR_BASE_L_ALIGNMENT)&PACBLR_BASE_L_MASK)
- +#define PACBLR_BASE_ALIGN_DOWN(base) (base & PACBLR_BASE_L_MASK)
- +
- +
- +/* PCI Access Control Base High Register (PACBHR) */
- +#define PACBHR_BASE_H_OFFS 0 /* Corresponds to address bits [63:32] */
- +#define PACBHR_CTRL_BASE_H_MASK (0xffffffff << PACBHR_BASE_H_OFFS)
- +
- +/* PCI Access Control Size Register (PACSR) */
- +#define PACSR_WRMBURST_OFFS 8 /* Write Max Burst */
- +#define PACSR_WRMBURST_MASK (0x3 << PACSR_WRMBURST_OFFS)
- +#define PACSR_WRMBURST_32BYTE (0x0 << PACSR_WRMBURST_OFFS)
- +#define PACSR_WRMBURST_64BYTE (0x1 << PACSR_WRMBURST_OFFS)
- +#define PACSR_WRMBURST_128BYTE (0x2 << PACSR_WRMBURST_OFFS)
- +
- +#define PACSR_PCI_ORDERING BIT11 /* PCI Ordering required */
- +
- +#define PACSR_SIZE_OFFS 12 /* PCI access window size */
- +#define PACSR_SIZE_MASK (0xfffff << PACSR_SIZE_OFFS)
- +#define PACSR_SIZE_ALIGNMENT (1 << PACSR_SIZE_OFFS)
- +#define PACSR_SIZE_ALIGN_UP(size) \
- + ((size+PACSR_SIZE_ALIGNMENT)&PACSR_SIZE_MASK)
- +#define PACSR_SIZE_ALIGN_DOWN(size) (size & PACSR_SIZE_MASK)
- +
- +
- +/***************************************/
- +/* PCI Configuration Access Registers */
- +/***************************************/
- +
- +#define PCI_CONFIG_ADDR_REG(pciIf) (0x30C78 - ((pciIf) * 0x80) )
- +#define PCI_CONFIG_DATA_REG(pciIf) (0x30C7C - ((pciIf) * 0x80) )
- +#define PCI_INT_ACK_REG(pciIf) (0x30C34 + ((pciIf) * 0x80) )
- +
- +/* PCI Configuration Address Register (PCAR) */
- +#define PCAR_REG_NUM_OFFS 2
- +#define PCAR_REG_NUM_MASK (0x3F << PCAR_REG_NUM_OFFS)
- +
- +#define PCAR_FUNC_NUM_OFFS 8
- +#define PCAR_FUNC_NUM_MASK (0x7 << PCAR_FUNC_NUM_OFFS)
- +
- +#define PCAR_DEVICE_NUM_OFFS 11
- +#define PCAR_DEVICE_NUM_MASK (0x1F << PCAR_DEVICE_NUM_OFFS)
- +
- +#define PCAR_BUS_NUM_OFFS 16
- +#define PCAR_BUS_NUM_MASK (0xFF << PCAR_BUS_NUM_OFFS)
- +
- +#define PCAR_CONFIG_EN BIT31
- +
- +
- +/***************************************/
- +/* PCI Configuration registers */
- +/***************************************/
- +
- +/*********************************************/
- +/* PCI Configuration, Function 0, Registers */
- +/*********************************************/
- +
- +/* Marvell Specific */
- +#define PCI_SCS0_BASE_ADDR_LOW 0x010
- +#define PCI_SCS0_BASE_ADDR_HIGH 0x014
- +#define PCI_SCS1_BASE_ADDR_LOW 0x018
- +#define PCI_SCS1_BASE_ADDR_HIGH 0x01C
- +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_L 0x020
- +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_H 0x024
- +
- +/* capability list */
- +#define PCI_POWER_MNG_CAPABILITY 0x040
- +#define PCI_POWER_MNG_STATUS_CONTROL 0x044
- +#define PCI_VPD_ADDRESS_REG 0x048
- +#define PCI_VPD_DATA_REG 0x04c
- +#define PCI_MSI_MESSAGE_CONTROL 0x050
- +#define PCI_MSI_MESSAGE_ADDR 0x054
- +#define PCI_MSI_MESSAGE_UPPER_ADDR 0x058
- +#define PCI_MSI_MESSAGE_DATA 0x05c
- +#define PCIX_COMMAND 0x060
- +#define PCIX_STATUS 0x064
- +#define PCI_COMPACT_PCI_HOT_SWAP 0x068
- +
- +
- +/*********************************************/
- +/* PCI Configuration, Function 1, Registers */
- +/*********************************************/
- +
- +#define PCI_SCS2_BASE_ADDR_LOW 0x10
- +#define PCI_SCS2_BASE_ADDR_HIGH 0x14
- +#define PCI_SCS3_BASE_ADDR_LOW 0x18
- +#define PCI_SCS3_BASE_ADDR_HIGH 0x1c
- +
- +
- +/***********************************************/
- +/* PCI Configuration, Function 2, Registers */
- +/***********************************************/
- +
- +#define PCI_DEVCS0_BASE_ADDR_LOW 0x10
- +#define PCI_DEVCS0_BASE_ADDR_HIGH 0x14
- +#define PCI_DEVCS1_BASE_ADDR_LOW 0x18
- +#define PCI_DEVCS1_BASE_ADDR_HIGH 0x1c
- +#define PCI_DEVCS2_BASE_ADDR_LOW 0x20
- +#define PCI_DEVCS2_BASE_ADDR_HIGH 0x24
- +
- +/***********************************************/
- +/* PCI Configuration, Function 3, Registers */
- +/***********************************************/
- +
- +#define PCI_BOOTCS_BASE_ADDR_LOW 0x18
- +#define PCI_BOOTCS_BASE_ADDR_HIGH 0x1c
- +
- +/***********************************************/
- +/* PCI Configuration, Function 4, Registers */
- +/***********************************************/
- +
- +#define PCI_P2P_MEM0_BASE_ADDR_LOW 0x10
- +#define PCI_P2P_MEM0_BASE_ADDR_HIGH 0x14
- +#define PCI_P2P_IO_BASE_ADDR 0x20
- +#define PCI_INTER_REGS_IO_MAPPED_BASE_ADDR 0x24
- +
- +/* PCIX_STATUS register fields (PXS) */
- +
- +#define PXS_FN_OFFS 0 /* Description Number */
- +#define PXS_FN_MASK (0x7 << PXS_FN_OFFS)
- +
- +#define PXS_DN_OFFS 3 /* Device Number */
- +#define PXS_DN_MASK (0x1f << PXS_DN_OFFS)
- +
- +#define PXS_BN_OFFS 8 /* Bus Number */
- +#define PXS_BN_MASK (0xff << PXS_BN_OFFS)
- +
- +
- +/* PCI Error Report Register Map */
- +#define PCI_SERRN_MASK_REG(pciIf) (0x30c28 + (pciIf * 0x80))
- +#define PCI_CAUSE_REG(pciIf) (0x31d58 + (pciIf * 0x80))
- +#define PCI_MASK_REG(pciIf) (0x31d5C + (pciIf * 0x80))
- +#define PCI_ERROR_ADDR_LOW_REG(pciIf) (0x31d40 + (pciIf * 0x80))
- +#define PCI_ERROR_ADDR_HIGH_REG(pciIf) (0x31d44 + (pciIf * 0x80))
- +#define PCI_ERROR_ATTRIBUTE_REG(pciIf) (0x31d48 + (pciIf * 0x80))
- +#define PCI_ERROR_COMMAND_REG(pciIf) (0x31d50 + (pciIf * 0x80))
- +
- +/* PCI Interrupt Cause Register (PICR) */
- +#define PICR_ERR_SEL_OFFS 27
- +#define PICR_ERR_SEL_MASK (0x1f << PICR_ERR_SEL_OFFS)
- +
- +/* PCI Error Command Register (PECR) */
- +#define PECR_ERR_CMD_OFFS 0
- +#define PECR_ERR_CMD_MASK (0xf << PECR_ERR_CMD_OFFS)
- +#define PECR_DAC BIT4
- +
- +
- +/* defaults */
- +/* Set bits means value is about to change according to new value */
- +#define PCI_COMMAND_DEFAULT_MASK 0xffffdff1
- +#define PCI_COMMAND_DEFAULT \
- + (PCR_MASTER_WR_TRIG_WHOLE | \
- + PCR_MASTER_RD_TRIG_WHOLE | \
- + PCR_MASTER_MEM_RD_LINE_EN | \
- + PCR_MASTER_MEM_RD_MULT_EN | \
- + PCR_NS_ACCORDING_RCV_TRANS | \
- + PCR_MASTER_PCIX_REQ64N_EN | \
- + PCR_MASTER_DAC_EN | \
- + PCR_MASTER_M64_ALLIGN | \
- + PCR_ERRORS_PROPAGATION_EN)
- +
- +
- +#define PCI_ARBITER_CTRL_DEFAULT_MASK 0x801fc07a
- +#define PCI_ARBITER_CTRL_DEFAULT \
- + (PACR_BROKEN_VAL_PCIX_MIN << PACR_BROKEN_VAL_OFFS)
- +
- +
- +#endif /* #ifndef __INCPCIREGSH */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 2010-11-09 20:28:11.512532816 +0100
- @@ -0,0 +1,669 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvPciIf.h"
- +#include "ctrlEnv/sys/mvSysPex.h"
- +
- +#if defined(MV_INCLUDE_PCI)
- +#include "ctrlEnv/sys/mvSysPci.h"
- +#endif
- +
- +
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +
- +/*******************************************************************************
- +* mvPciInit - Initialize PCI interfaces
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
- +*
- +*******************************************************************************/
- +
- +
- +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode)
- +{
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- +
- + MV_PCI_MOD pciMod;
- +
- + if (PCI_IF_MODE_HOST == pciIfmode)
- + {
- + pciMod = MV_PCI_MOD_HOST;
- + }
- + else if (PCI_IF_MODE_DEVICE == pciIfmode)
- + {
- + pciMod = MV_PCI_MOD_DEVICE;
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n",
- + __FUNCTION__, pciIf, pciIfmode);
- + return MV_FAIL;
- + }
- +
- + return mvPciInit(pciIf - MV_PCI_START_IF, pciMod);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- +
- + MV_PEX_TYPE pexType;
- +
- + if (PCI_IF_MODE_HOST == pciIfmode)
- + {
- + pexType = MV_PEX_ROOT_COMPLEX;
- + }
- + else if (PCI_IF_MODE_DEVICE == pciIfmode)
- + {
- + pexType = MV_PEX_END_POINT;
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" \
- + " end point\n", __FUNCTION__, pciIf, pciIfmode);
- + return MV_FAIL;
- + }
- + return mvPexInit(pciIf - MV_PEX_START_IF, pexType);
- +
- + #else
- + return MV_OK;
- + #endif
- +
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return MV_FAIL;
- +
- +}
- +
- +/* PCI configuration space read write */
- +
- +/*******************************************************************************
- +* mvPciConfigRead - Read from configuration space
- +*
- +* DESCRIPTION:
- +* This function performs a 32 bit read from PCI configuration space.
- +* It supports both type 0 and type 1 of Configuration Transactions
- +* (local and over bridge). In order to read from local bus segment, use
- +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
- +* will result configuration transaction of type 1 (over bridge).
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* bus - PCI segment bus number.
- +* dev - PCI device number.
- +* func - Function number.
- +* regOffs - Register offset.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit register data, 0xffffffff on error
- +*
- +*******************************************************************************/
- +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
- + MV_U32 regOff)
- +{
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciConfigRead(pciIf - MV_PCI_START_IF,
- + bus,
- + dev,
- + func,
- + regOff);
- + #else
- + return 0xffffffff;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexConfigRead(pciIf - MV_PEX_START_IF,
- + bus,
- + dev,
- + func,
- + regOff);
- + #else
- + return 0xffffffff;
- + #endif
- +
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return 0;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPciConfigWrite - Write to configuration space
- +*
- +* DESCRIPTION:
- +* This function performs a 32 bit write to PCI configuration space.
- +* It supports both type 0 and type 1 of Configuration Transactions
- +* (local and over bridge). In order to write to local bus segment, use
- +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
- +* will result configuration transaction of type 1 (over bridge).
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* bus - PCI segment bus number.
- +* dev - PCI device number.
- +* func - Function number.
- +* regOffs - Register offset.
- +* data - 32bit data.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data)
- +{
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciConfigWrite(pciIf - MV_PCI_START_IF,
- + bus,
- + dev,
- + func,
- + regOff,
- + data);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexConfigWrite(pciIf - MV_PEX_START_IF,
- + bus,
- + dev,
- + func,
- + regOff,
- + data);
- + #else
- + return MV_OK;
- + #endif
- +
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return MV_FAIL;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
- +*
- +* DESCRIPTION:
- +* This function performs read modified write to PCI command status
- +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
- +* master is allowed to gain ownership on the bus, otherwise it is
- +* incapable to do so.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable)
- +{
- +
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciMasterEnable(pciIf - MV_PCI_START_IF,
- + enable);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexMasterEnable(pciIf - MV_PEX_START_IF,
- + enable);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return MV_FAIL;
- +
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
- +*
- +* DESCRIPTION:
- +* This function performs read modified write to PCI command status
- +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
- +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
- +* and PCI memory space access (bit 1).
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* dev - PCI device number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable)
- +{
- +
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev,
- + enable);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev,
- + enable);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return MV_FAIL;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPciLocalBusNumSet - Set PCI interface local bus number.
- +*
- +* DESCRIPTION:
- +* This function sets given PCI interface its local bus number.
- +* Note: In case the PCI interface is PCI-X, the information is read-only.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* busNum - Bus number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
- +* MV_BAD_PARAM on bad parameters ,
- +* otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
- +{
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF,
- + busNum);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF,
- + busNum);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return MV_FAIL;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPciLocalBusNumGet - Get PCI interface local bus number.
- +*
- +* DESCRIPTION:
- +* This function gets the local bus number of a given PCI interface.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Local bus number.0xffffffff on Error
- +*
- +*******************************************************************************/
- +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf)
- +{
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciLocalBusNumGet(pciIf - MV_PCI_START_IF);
- + #else
- + return 0xFFFFFFFF;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexLocalBusNumGet(pciIf - MV_PEX_START_IF);
- + #else
- + return 0xFFFFFFFF;
- + #endif
- +
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n",__FUNCTION__, pciIf);
- + }
- +
- + return 0;
- +
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciLocalDevNumSet - Set PCI interface local device number.
- +*
- +* DESCRIPTION:
- +* This function sets given PCI interface its local device number.
- +* Note: In case the PCI interface is PCI-X, the information is read-only.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +* devNum - Device number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
- +* otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
- +{
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciLocalDevNumSet(pciIf - MV_PCI_START_IF,
- + devNum);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexLocalDevNumSet(pciIf - MV_PEX_START_IF,
- + devNum);
- + #else
- + return MV_OK;
- + #endif
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return MV_FAIL;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPciLocalDevNumGet - Get PCI interface local device number.
- +*
- +* DESCRIPTION:
- +* This function gets the local device number of a given PCI interface.
- +*
- +* INPUT:
- +* pciIf - PCI interface number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Local device number. 0xffffffff on Error
- +*
- +*******************************************************************************/
- +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf)
- +{
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PCI)
- + return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF);
- + #else
- + return 0xFFFFFFFF;
- + #endif
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + #if defined(MV_INCLUDE_PEX)
- + return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF);
- + #else
- + return 0xFFFFFFFF;
- + #endif
- +
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return 0;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPciIfTypeGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +
- +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf)
- +{
- +
- + if ((pciIf >= MV_PCI_START_IF)&&(pciIf < MV_PCI_MAX_IF + MV_PCI_START_IF))
- + {
- + return PCI_IF_TYPE_CONVEN_PCIX;
- + }
- + else if ((pciIf >= MV_PEX_START_IF) &&
- + (pciIf < MV_PEX_MAX_IF + MV_PEX_START_IF))
- + {
- + return PCI_IF_TYPE_PEX;
- +
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return 0xffffffff;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPciIfTypeGet -
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +*
- +*******************************************************************************/
- +
- +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf)
- +{
- +
- + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
- +
- + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
- + {
- + return (pciIf - MV_PCI_START_IF);
- + }
- + else if (PCI_IF_TYPE_PEX == pciIfType)
- + {
- + return (pciIf - MV_PEX_START_IF);
- +
- + }
- + else
- + {
- + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
- + }
- +
- + return 0xffffffff;
- +
- +}
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 2010-11-09 20:28:11.552495455 +0100
- @@ -0,0 +1,134 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCPCIIFH
- +#define __INCPCIIFH
- +
- +#include "mvSysHwConfig.h"
- +#include "pci-if/mvPciIfRegs.h"
- +#if defined(MV_INCLUDE_PEX)
- +#include "pex/mvPex.h"
- +#endif
- +#if defined(MV_INCLUDE_PCI)
- +#include "pci/mvPci.h"
- +#endif
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
- +
- +typedef enum _mvPCIIfType
- +{
- + PCI_IF_TYPE_CONVEN_PCIX,
- + PCI_IF_TYPE_PEX
- +
- +}PCI_IF_TYPE;
- +
- +typedef enum _mvPCIIfMode
- +{
- + PCI_IF_MODE_HOST,
- + PCI_IF_MODE_DEVICE
- +}PCI_IF_MODE;
- +
- +
- +/* Global Functions prototypes */
- +
- +/* mvPciIfInit - Initialize PCI interfaces*/
- +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode);
- +
- +/* mvPciIfConfigRead - Read from configuration space */
- +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func,MV_U32 regOff);
- +
- +/* mvPciIfConfigWrite - Write to configuration space */
- +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data);
- +
- +/* mvPciIfMasterEnable - Enable/disale PCI interface master transactions.*/
- +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable);
- +
- +/* mvPciIfSlaveEnable - Enable/disale PCI interface slave transactions.*/
- +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev,
- + MV_BOOL enable);
- +
- +/* mvPciIfLocalBusNumSet - Set PCI interface local bus number.*/
- +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
- +
- +/* mvPciIfLocalBusNumGet - Get PCI interface local bus number.*/
- +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf);
- +
- +/* mvPciIfLocalDevNumSet - Set PCI interface local device number.*/
- +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
- +
- +/* mvPciIfLocalDevNumGet - Get PCI interface local device number.*/
- +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf);
- +
- +/* mvPciIfTypeGet - Get PCI If type*/
- +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf);
- +
- +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf);
- +
- +/* mvPciIfAddrDecShow - Display address decode windows attributes */
- +MV_VOID mvPciIfAddrDecShow(MV_VOID);
- +
- +#endif /* #ifndef __INCPCIIFH */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 2010-11-09 20:28:11.592495403 +0100
- @@ -0,0 +1,245 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCPCIIFREGSH
- +#define __INCPCIIFREGSH
- +
- +
- +/* defines */
- +#define MAX_PCI_DEVICES 32
- +#define MAX_PCI_FUNCS 8
- +#define MAX_PCI_BUSSES 128
- +
- +/***************************************/
- +/* PCI Configuration registers */
- +/***************************************/
- +
- +/*********************************************/
- +/* PCI Configuration, Function 0, Registers */
- +/*********************************************/
- +
- +
- +/* Standard registers */
- +#define PCI_DEVICE_AND_VENDOR_ID 0x000
- +#define PCI_STATUS_AND_COMMAND 0x004
- +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
- +#define PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
- +#define PCI_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
- +#define PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
- +#define PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030
- +#define PCI_CAPABILTY_LIST_POINTER 0x034
- +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C
- +
- +
- +/* PCI Device and Vendor ID Register (PDVIR) */
- +#define PDVIR_VEN_ID_OFFS 0 /* Vendor ID */
- +#define PDVIR_VEN_ID_MASK (0xffff << PDVIR_VEN_ID_OFFS)
- +
- +#define PDVIR_DEV_ID_OFFS 16 /* Device ID */
- +#define PDVIR_DEV_ID_MASK (0xffff << PDVIR_DEV_ID_OFFS)
- +
- +/* PCI Status and Command Register (PSCR) */
- +#define PSCR_IO_EN BIT0 /* IO Enable */
- +#define PSCR_MEM_EN BIT1 /* Memory Enable */
- +#define PSCR_MASTER_EN BIT2 /* Master Enable */
- +#define PSCR_SPECIAL_EN BIT3 /* Special Cycle Enable */
- +#define PSCR_MEM_WRI_INV BIT4 /* Memory Write and Invalidate Enable */
- +#define PSCR_VGA BIT5 /* VGA Palette Snoops */
- +#define PSCR_PERR_EN BIT6 /* Parity Errors Respond Enable */
- +#define PSCR_ADDR_STEP BIT7 /* Address Stepping Enable (Wait Cycle En)*/
- +#define PSCR_SERR_EN BIT8 /* Ability to assert SERR# line */
- +#define PSCR_FAST_BTB_EN BIT9 /* generate fast back-to-back transactions*/
- +#define PSCR_CAP_LIST BIT20 /* Capability List Support */
- +#define PSCR_66MHZ_EN BIT21 /* 66 MHz Capable */
- +#define PSCR_UDF_EN BIT22 /* User definable features */
- +#define PSCR_TAR_FAST_BB BIT23 /* fast back-to-back transactions capable */
- +#define PSCR_DATA_PERR BIT24 /* Data Parity reported */
- +
- +#define PSCR_DEVSEL_TIM_OFFS 25 /* DEVSEL timing */
- +#define PSCR_DEVSEL_TIM_MASK (0x3 << PSCR_DEVSEL_TIM_OFFS)
- +#define PSCR_DEVSEL_TIM_FAST (0x0 << PSCR_DEVSEL_TIM_OFFS)
- +#define PSCR_DEVSEL_TIM_MED (0x1 << PSCR_DEVSEL_TIM_OFFS)
- +#define PSCR_DEVSEL_TIM_SLOW (0x2 << PSCR_DEVSEL_TIM_OFFS)
- +
- +#define PSCR_SLAVE_TABORT BIT27 /* Signalled Target Abort */
- +#define PSCR_MASTER_TABORT BIT28 /* Recieved Target Abort */
- +#define PSCR_MABORT BIT29 /* Recieved Master Abort */
- +#define PSCR_SYSERR BIT30 /* Signalled system error */
- +#define PSCR_DET_PARERR BIT31 /* Detect Parity Error */
- +
- +/* PCI configuration register offset=0x08 fields
- + (PCI_CLASS_CODE_AND_REVISION_ID)(PCCRI) */
- +
- +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
- +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
- +
- +#define PCCRIR_FULL_CLASS_OFFS 8 /* Full Class Code */
- +#define PCCRIR_FULL_CLASS_MASK (0xffffff << PCCRIR_FULL_CLASS_OFFS)
- +
- +#define PCCRIR_PROGIF_OFFS 8 /* Prog .I/F*/
- +#define PCCRIR_PROGIF_MASK (0xff << PCCRIR_PROGIF_OFFS)
- +
- +#define PCCRIR_SUB_CLASS_OFFS 16 /* Sub Class*/
- +#define PCCRIR_SUB_CLASS_MASK (0xff << PCCRIR_SUB_CLASS_OFFS)
- +
- +#define PCCRIR_BASE_CLASS_OFFS 24 /* Base Class*/
- +#define PCCRIR_BASE_CLASS_MASK (0xff << PCCRIR_BASE_CLASS_OFFS)
- +
- +/* PCI configuration register offset=0x0C fields
- + (PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE)(PBHTLTCL) */
- +
- +#define PBHTLTCLR_CACHELINE_OFFS 0 /* Specifies the cache line size */
- +#define PBHTLTCLR_CACHELINE_MASK (0xff << PBHTLTCLR_CACHELINE_OFFS)
- +
- +#define PBHTLTCLR_LATTIMER_OFFS 8 /* latency timer */
- +#define PBHTLTCLR_LATTIMER_MASK (0xff << PBHTLTCLR_LATTIMER_OFFS)
- +
- +#define PBHTLTCLR_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
- +#define PBHTLTCLR_HEADTYPE_FULL_MASK (0xff << PBHTLTCLR_HEADTYPE_FULL_OFFS)
- +
- +#define PBHTLTCLR_MULTI_FUNC BIT23 /* Multi/Single function */
- +
- +#define PBHTLTCLR_HEADER_OFFS 16 /* Header type */
- +#define PBHTLTCLR_HEADER_MASK (0x7f << PBHTLTCLR_HEADER_OFFS)
- +#define PBHTLTCLR_HEADER_STANDARD (0x0 << PBHTLTCLR_HEADER_OFFS)
- +#define PBHTLTCLR_HEADER_PCI2PCI_BRIDGE (0x1 << PBHTLTCLR_HEADER_OFFS)
- +
- +
- +#define PBHTLTCLR_BISTCOMP_OFFS 24 /* BIST Completion Code */
- +#define PBHTLTCLR_BISTCOMP_MASK (0xf << PBHTLTCLR_BISTCOMP_OFFS)
- +
- +#define PBHTLTCLR_BISTACT BIT30 /* BIST Activate bit */
- +#define PBHTLTCLR_BISTCAP BIT31 /* BIST Capable Bit */
- +
- +
- +/* PCI Bar Base Low Register (PBBLR) */
- +#define PBBLR_IOSPACE BIT0 /* Memory Space Indicator */
- +
- +#define PBBLR_TYPE_OFFS 1 /* BAR Type/Init Val. */
- +#define PBBLR_TYPE_MASK (0x3 << PBBLR_TYPE_OFFS)
- +#define PBBLR_TYPE_32BIT_ADDR (0x0 << PBBLR_TYPE_OFFS)
- +#define PBBLR_TYPE_64BIT_ADDR (0x2 << PBBLR_TYPE_OFFS)
- +
- +#define PBBLR_PREFETCH_EN BIT3 /* Prefetch Enable */
- +
- +
- +#define PBBLR_MEM_BASE_OFFS 4 /* Memory Bar Base address. Corresponds to
- + address bits [31:4] */
- +#define PBBLR_MEM_BASE_MASK (0xfffffff << PBBLR_MEM_BASE_OFFS)
- +
- +#define PBBLR_IO_BASE_OFFS 2 /* IO Bar Base address. Corresponds to
- + address bits [31:2] */
- +#define PBBLR_IO_BASE_MASK (0x3fffffff << PBBLR_IO_BASE_OFFS)
- +
- +
- +#define PBBLR_BASE_OFFS 12 /* Base address. Address bits [31:12] */
- +#define PBBLR_BASE_MASK (0xfffff << PBBLR_BASE_OFFS)
- +#define PBBLR_BASE_ALIGNMET (1 << PBBLR_BASE_OFFS)
- +
- +
- +/* PCI Bar Base High Fegister (PBBHR) */
- +#define PBBHR_BASE_OFFS 0 /* Base address. Address bits [31:12] */
- +#define PBBHR_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
- +
- +
- +/* PCI configuration register offset=0x2C fields
- + (PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID)(PSISVI) */
- +
- +#define PSISVIR_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
- +#define PSISVIR_VENID_MASK (0xffff << PSISVIR_VENID_OFFS)
- +
- +#define PSISVIR_DEVID_OFFS 16 /* Subsystem Device ID Number */
- +#define PSISVIR_DEVID_MASK (0xffff << PSISVIR_DEVID_OFFS)
- +
- +/* PCI configuration register offset=0x30 fields
- + (PCI_EXPANSION_ROM_BASE_ADDR_REG)(PERBA) */
- +
- +#define PERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
- +
- +#define PERBAR_BASE_OFFS 12 /* Expansion ROM Base Address */
- +#define PERBAR_BASE_MASK (0xfffff << PERBAR_BASE_OFFS)
- +
- +/* PCI configuration register offset=0x34 fields
- + (PCI_CAPABILTY_LIST_POINTER)(PCLP) */
- +
- +#define PCLPR_CAPPTR_OFFS 0 /* Capability List Pointer */
- +#define PCLPR_CAPPTR_MASK (0xff << PCLPR_CAPPTR_OFFS)
- +
- +/* PCI configuration register offset=0x3C fields
- + (PCI_INTERRUPT_PIN_AND_LINE)(PIPL) */
- +
- +#define PIPLR_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
- +#define PIPLR_INTLINE_MASK (0xff << PIPLR_INTLINE_OFFS)
- +
- +#define PIPLR_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
- +#define PIPLR_INTPIN_MASK (0xff << PIPLR_INTPIN_OFFS)
- +
- +#define PIPLR_MINGRANT_OFFS 16 /* Minimum Grant on 250 nano seconds units */
- +#define PIPLR_MINGRANT_MASK (0xff << PIPLR_MINGRANT_OFFS)
- +
- +#define PIPLR_MAXLATEN_OFFS 24 /* Maximum latency on 250 nano seconds units */
- +#define PIPLR_MAXLATEN_MASK (0xff << PIPLR_MAXLATEN_OFFS)
- +
- +#endif /* #ifndef __INCPCIIFREGSH */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 2010-11-09 20:28:11.632495445 +0100
- @@ -0,0 +1,1006 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +/* includes */
- +#include "mvPciUtils.h"
- +
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +/* #define MV_DEBUG */
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- + #define mvOsPrintf printf
- +#else
- + #define DB(x)
- +#endif
- +
- +/*
- +This module only support scanning of Header type 00h of pci devices
- +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
- +*/
- +
- +
- +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
- + MV_U32 bus,
- + MV_U32 dev,
- + MV_U32 func,
- + MV_PCI_DEVICE *pPciAgent);
- +
- +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
- + MV_U32 bus,
- + MV_U32 dev,
- + MV_U32 func,
- + MV_PCI_DEVICE *pPciAgent);
- +
- +
- +
- +
- +
- +
- +/*******************************************************************************
- +* mvPciScan - Scan a PCI interface bus
- +*
- +* DESCRIPTION:
- +* Performs a full scan on a PCI interface and returns all possible details
- +* on the agents found on the bus.
- +*
- +* INPUT:
- +* pciIf - PCI Interface
- +* pPciAgents - Pointer to an Array of the pci agents to be detected
- +* pPciAgentsNum - pPciAgents array maximum number of elements
- +*
- +* OUTPUT:
- +* pPciAgents - Array of the pci agents detected on the bus
- +* pPciAgentsNum - Number of pci agents detected on the bus
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +
- +MV_STATUS mvPciScan(MV_U32 pciIf,
- + MV_PCI_DEVICE *pPciAgents,
- + MV_U32 *pPciAgentsNum)
- +{
- +
- + MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;
- + MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);
- + MV_PCI_DEVICE *pPciDevice;
- + MV_PCI_DEVICE *pMainDevice;
- +
- + DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));
- + /* Parameter checking */
- + if (pciIf >= mvCtrlPexMaxIfGet())
- + {
- + DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));
- + return MV_BAD_PARAM;
- + }
- + if (NULL == pPciAgents)
- + {
- + DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));
- + return MV_BAD_PARAM;
- + }
- + if (NULL == pPciAgentsNum)
- + {
- + DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));
- + return MV_BAD_PARAM;
- + }
- +
- +
- + DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));
- + /* Master enable the MV PCI master */
- + if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))
- + {
- + DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed \n"));
- + return MV_ERROR;
- +
- + }
- +
- + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));
- +
- + /* go through all busses */
- + for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)
- + {
- + /* go through all possible devices on the local bus */
- + for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)
- + {
- + /* always start with function equal to zero */
- + funcIndex=0;
- +
- + pPciDevice=&pPciAgents[detectedDevNum];
- + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));
- +
- + if (MV_ERROR == pciDetectDevice(pciIf,
- + busIndex,
- + devIndex,
- + funcIndex,
- + pPciDevice))
- + {
- + /* no device detected , try the next address */
- + continue;
- + }
- +
- + /* We are here ! means we have detected a device*/
- + /* always we start with only one function per device */
- + pMainDevice = pPciDevice;
- + pPciDevice->funtionsNum = 1;
- +
- +
- + /* move on */
- + detectedDevNum++;
- +
- +
- + /* check if we have no more room for a new device */
- + if (detectedDevNum == *pPciAgentsNum)
- + {
- + DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));
- + return MV_ERROR;
- + }
- +
- + /* check the detected device if it is a multi functional device then
- + scan all device functions*/
- + if (pPciDevice->isMultiFunction == MV_TRUE)
- + {
- + /* start with function number 1 because we have already detected
- + function 0 */
- + for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)
- + {
- + pPciDevice=&pPciAgents[detectedDevNum];
- +
- + if (MV_ERROR == pciDetectDevice(pciIf,
- + busIndex,
- + devIndex,
- + funcIndex,
- + pPciDevice))
- + {
- + /* no device detected means no more functions !*/
- + continue;
- + }
- + /* We are here ! means we have detected a device */
- +
- + /* move on */
- + pMainDevice->funtionsNum++;
- + detectedDevNum++;
- +
- + /* check if we have no more room for a new device */
- + if (detectedDevNum == *pPciAgentsNum)
- + {
- + DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));
- + return MV_ERROR;
- + }
- +
- +
- + }
- + }
- +
- + }
- +
- + }
- +
- + /* return the number of devices actually detected on the bus ! */
- + *pPciAgentsNum = detectedDevNum;
- +
- + return MV_OK;
- +
- +}
- +
- +
- +/*******************************************************************************
- +* pciDetectDevice - Detect a pci device parameters
- +*
- +* DESCRIPTION:
- +* This function detect if a pci agent exist on certain address !
- +* and if exists then it fills all possible information on the
- +* agent
- +*
- +* INPUT:
- +* pciIf - PCI Interface
- +* bus - Bus number
- +* dev - Device number
- +* func - Function number
- +*
- +*
- +*
- +* OUTPUT:
- +* pPciAgent - pointer to the pci agent filled with its information
- +*
- +* RETURN:
- +* MV_ERROR if no device , MV_OK otherwise
- +*
- +*******************************************************************************/
- +
- +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
- + MV_U32 bus,
- + MV_U32 dev,
- + MV_U32 func,
- + MV_PCI_DEVICE *pPciAgent)
- +{
- + MV_U32 pciData;
- +
- + /* no Parameters checking ! because it is static function and it is assumed
- + that all parameters were checked in the calling function */
- +
- +
- + /* Try read the PCI Vendor ID and Device ID */
- +
- + /* We will scan only ourselves and the PCI slots that exist on the
- + board, because we may have a case that we have one slot that has
- + a Cardbus connector, and because CardBus answers all IDsels we want
- + to scan only this slot and ourseleves.
- +
- + */
- + #if defined(MV_INCLUDE_PCI)
- + if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&
- + (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&
- + (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&
- + (DB_88F5181_DDR1_MNG != mvBoardIdGet()))
- + {
- +
- + if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)
- + {
- + return MV_ERROR;
- + }
- + }
- + #endif /* defined(MV_INCLUDE_PCI) */
- +
- + pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);
- +
- + if (PCI_ERROR_CODE == pciData)
- + {
- + /* no device exist */
- + return MV_ERROR;
- + }
- +
- + /* we are here ! means a device is detected */
- +
- + /* fill basic information */
- + pPciAgent->busNumber=bus;
- + pPciAgent->deviceNum=dev;
- + pPciAgent->function=func;
- +
- + /* Fill the PCI Vendor ID and Device ID */
- +
- + pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;
- + pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;
- +
- + /* Read Status and command */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_STATUS_AND_COMMAND);
- +
- +
- + /* Fill related Status and Command information*/
- +
- + if (pciData & PSCR_TAR_FAST_BB)
- + {
- + pPciAgent->isFastB2BCapable = MV_TRUE;
- + }
- + else
- + {
- + pPciAgent->isFastB2BCapable = MV_FALSE;
- + }
- +
- + if (pciData & PSCR_CAP_LIST)
- + {
- + pPciAgent->isCapListSupport=MV_TRUE;
- + }
- + else
- + {
- + pPciAgent->isCapListSupport=MV_FALSE;
- + }
- +
- + if (pciData & PSCR_66MHZ_EN)
- + {
- + pPciAgent->is66MHZCapable=MV_TRUE;
- + }
- + else
- + {
- + pPciAgent->is66MHZCapable=MV_FALSE;
- + }
- +
- + /* Read Class Code and Revision */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_CLASS_CODE_AND_REVISION_ID);
- +
- +
- + pPciAgent->baseClassCode =
- + (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;
- +
- + pPciAgent->subClassCode =
- + (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;
- +
- + pPciAgent->progIf =
- + (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;
- +
- + pPciAgent->revisionID =
- + (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
- +
- + /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);
- +
- +
- +
- + pPciAgent->pciCacheLine=
- + (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;
- + pPciAgent->pciLatencyTimer=
- + (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;
- +
- + switch (pciData & PBHTLTCLR_HEADER_MASK)
- + {
- + case PBHTLTCLR_HEADER_STANDARD:
- +
- + pPciAgent->pciHeader=MV_PCI_STANDARD;
- + break;
- + case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:
- +
- + pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;
- + break;
- +
- + }
- +
- + if (pciData & PBHTLTCLR_MULTI_FUNC)
- + {
- + pPciAgent->isMultiFunction=MV_TRUE;
- + }
- + else
- + {
- + pPciAgent->isMultiFunction=MV_FALSE;
- + }
- +
- + if (pciData & PBHTLTCLR_BISTCAP)
- + {
- + pPciAgent->isBISTCapable=MV_TRUE;
- + }
- + else
- + {
- + pPciAgent->isBISTCapable=MV_FALSE;
- + }
- +
- +
- + /* read this device pci bars */
- +
- + pciDetectDeviceBars(pciIf,
- + bus,dev,func,
- + pPciAgent);
- +
- +
- + /* check if we are bridge*/
- + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
- + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
- + {
- +
- + /* Read P2P_BUSSES_NUM */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + P2P_BUSSES_NUM);
- +
- + pPciAgent->p2pPrimBusNum =
- + (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;
- +
- + pPciAgent->p2pSecBusNum =
- + (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;
- +
- + pPciAgent->p2pSubBusNum =
- + (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;
- +
- + pPciAgent->p2pSecLatencyTimer =
- + (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;
- +
- + /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + P2P_IO_BASE_LIMIT_SEC_STATUS);
- +
- + pPciAgent->p2pSecStatus =
- + (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;
- +
- +
- + pPciAgent->p2pIObase =
- + (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;
- +
- + /* clear low address (should be zero)*/
- + pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;
- +
- + pPciAgent->p2pIOLimit =
- + (pciData & PIBLSS_IO_LIMIT_MASK);
- +
- + /* fill low address with 0xfff */
- + pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;
- +
- +
- + switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)
- + {
- + case PIBLSS_ADD_CAP_16BIT:
- +
- + pPciAgent->bIO32 = MV_FALSE;
- +
- + break;
- + case PIBLSS_ADD_CAP_32BIT:
- +
- + pPciAgent->bIO32 = MV_TRUE;
- +
- + /* Read P2P_IO_BASE_LIMIT_UPPER_16 */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + P2P_IO_BASE_LIMIT_UPPER_16);
- +
- + pPciAgent->p2pIObase |=
- + (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;
- +
- +
- + pPciAgent->p2pIOLimit |=
- + (pciData & PRBU_IO_UPP_LIMIT_MASK);
- +
- + break;
- +
- + }
- +
- +
- + /* Read P2P_MEM_BASE_LIMIT */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + P2P_MEM_BASE_LIMIT);
- +
- + pPciAgent->p2pMemBase =
- + (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;
- +
- + /* clear low address */
- + pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;
- +
- + pPciAgent->p2pMemLimit =
- + (pciData & PMBL_MEM_LIMIT_MASK);
- +
- + /* add 0xfffff */
- + pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;
- +
- +
- + /* Read P2P_PREF_MEM_BASE_LIMIT */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + P2P_PREF_MEM_BASE_LIMIT);
- +
- +
- + pPciAgent->p2pPrefMemBase =
- + (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;
- +
- + /* get high address only */
- + pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;
- +
- +
- +
- + pPciAgent->p2pPrefMemLimit =
- + (pciData & PRMBL_PREF_MEM_LIMIT_MASK);
- +
- + /* add 0xfffff */
- + pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;
- +
- + switch (pciData & PRMBL_ADD_CAP_MASK)
- + {
- + case PRMBL_ADD_CAP_32BIT:
- +
- + pPciAgent->bPrefMem64 = MV_FALSE;
- +
- + /* Read P2P_PREF_BASE_UPPER_32 */
- + pPciAgent->p2pPrefBaseUpper32Bits = 0;
- +
- + /* Read P2P_PREF_LIMIT_UPPER_32 */
- + pPciAgent->p2pPrefLimitUpper32Bits = 0;
- +
- + break;
- + case PRMBL_ADD_CAP_64BIT:
- +
- + pPciAgent->bPrefMem64 = MV_TRUE;
- +
- + /* Read P2P_PREF_BASE_UPPER_32 */
- + pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + P2P_PREF_BASE_UPPER_32);
- +
- + /* Read P2P_PREF_LIMIT_UPPER_32 */
- + pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + P2P_PREF_LIMIT_UPPER_32);
- +
- + break;
- +
- + }
- +
- + }
- + else /* no bridge */
- + {
- + /* Read PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);
- +
- +
- + pPciAgent->subSysVenID =
- + (pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;
- + pPciAgent->subSysID =
- + (pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;
- +
- +
- + /* Read PCI_EXPANSION_ROM_BASE_ADDR_REG */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_EXPANSION_ROM_BASE_ADDR_REG);
- +
- +
- + if (pciData & PERBAR_EXPROMEN)
- + {
- + pPciAgent->isExpRom = MV_TRUE;
- + }
- + else
- + {
- + pPciAgent->isExpRom = MV_FALSE;
- + }
- +
- + pPciAgent->expRomAddr =
- + (pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;
- +
- + }
- +
- +
- + if (MV_TRUE == pPciAgent->isCapListSupport)
- + {
- + /* Read PCI_CAPABILTY_LIST_POINTER */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_CAPABILTY_LIST_POINTER);
- +
- + pPciAgent->capListPointer =
- + (pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;
- +
- + }
- +
- + /* Read PCI_INTERRUPT_PIN_AND_LINE */
- + pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_INTERRUPT_PIN_AND_LINE);
- +
- +
- + pPciAgent->irqLine=
- + (pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;
- +
- + pPciAgent->intPin=
- + (MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;
- +
- + pPciAgent->minGrant=
- + (pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;
- + pPciAgent->maxLatency=
- + (pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;
- +
- + mvPciClassNameGet(pPciAgent->baseClassCode,
- + (MV_8 *)pPciAgent->type);
- +
- + return MV_OK;
- +
- +
- +}
- +
- +/*******************************************************************************
- +* pciDetectDeviceBars - Detect a pci device bars
- +*
- +* DESCRIPTION:
- +* This function detects all pci agent bars
- +*
- +* INPUT:
- +* pciIf - PCI Interface
- +* bus - Bus number
- +* dev - Device number
- +* func - Function number
- +*
- +*
- +*
- +* OUTPUT:
- +* pPciAgent - pointer to the pci agent filled with its information
- +*
- +* RETURN:
- +* detected bars number
- +*
- +*******************************************************************************/
- +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
- + MV_U32 bus,
- + MV_U32 dev,
- + MV_U32 func,
- + MV_PCI_DEVICE *pPciAgent)
- +{
- + MV_U32 pciData,barIndex,detectedBar=0;
- + MV_U32 tmpBaseHigh=0,tmpBaseLow=0;
- + MV_U32 pciMaxBars=0;
- +
- + pPciAgent->barsNum=0;
- +
- + /* check if we are bridge*/
- + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
- + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
- + {
- + pciMaxBars = 2;
- + }
- + else /* no bridge */
- + {
- + pciMaxBars = 6;
- + }
- +
- + /* read this device pci bars */
- + for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )
- + {
- + /* Read PCI_MEMORY_BAR_BASE_ADDR */
- + tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
- +
- + pPciAgent->pciBar[detectedBar].barOffset =
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex);
- +
- + /* check if the bar is 32bit or 64bit bar */
- + switch (pciData & PBBLR_TYPE_MASK)
- + {
- + case PBBLR_TYPE_32BIT_ADDR:
- + pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;
- + break;
- + case PBBLR_TYPE_64BIT_ADDR:
- + pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;
- + break;
- +
- + }
- +
- + /* check if it is memory or IO bar */
- + if (pciData & PBBLR_IOSPACE)
- + {
- + pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;
- + }
- + else
- + {
- + pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;
- + }
- +
- + /* if it is memory bar then check if it is prefetchable */
- + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
- + {
- + if (pciData & PBBLR_PREFETCH_EN)
- + {
- + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;
- + }
- + else
- + {
- + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;
- + }
- +
- + pPciAgent->pciBar[detectedBar].barBaseLow =
- + pciData & PBBLR_MEM_BASE_MASK;
- +
- +
- + }
- + else /* IO Bar */
- + {
- + pPciAgent->pciBar[detectedBar].barBaseLow =
- + pciData & PBBLR_IO_BASE_MASK;
- +
- + }
- +
- + pPciAgent->pciBar[detectedBar].barBaseHigh=0;
- +
- + if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)
- + {
- + barIndex++;
- +
- + tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =
- + mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
- +
- +
- + }
- +
- + /* calculating full base address (64bit) */
- + pPciAgent->pciBar[detectedBar].barBaseAddr =
- + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;
- +
- + pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;
- +
- + pPciAgent->pciBar[detectedBar].barBaseAddr |=
- + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;
- +
- +
- +
- + /* get the sizes of the the bar */
- +
- + pPciAgent->pciBar[detectedBar].barSizeHigh=0;
- +
- + if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&
- + (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))
- +
- + {
- + /* write oxffffffff to the bar to get the size */
- + /* start with sizelow ( original value was saved in tmpBaseLow ) */
- + mvPciIfConfigWrite(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
- + 0xffffffff);
- +
- + /* read size */
- + pPciAgent->pciBar[detectedBar].barSizeLow =
- + mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));
- +
- +
- +
- + /* restore original value */
- + mvPciIfConfigWrite(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
- + tmpBaseLow);
- +
- +
- + /* now do the same for BaseHigh */
- +
- + /* write oxffffffff to the bar to get the size */
- + mvPciIfConfigWrite(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
- + 0xffffffff);
- +
- + /* read size */
- + pPciAgent->pciBar[detectedBar].barSizeHigh =
- + mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
- +
- + /* restore original value */
- + mvPciIfConfigWrite(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
- + tmpBaseHigh);
- +
- + if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&
- + (0 == pPciAgent->pciBar[detectedBar].barSizeHigh))
- + {
- + /* this bar is not applicable for this device,
- + ignore all previous settings and check the next bar*/
- +
- + /* we though this was a 64bit bar , and it seems this
- + was wrong ! so decrement barIndex */
- + barIndex--;
- + continue;
- + }
- +
- + /* calculate the full 64 bit size */
- +
- + if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)
- + {
- + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
- +
- + pPciAgent->pciBar[detectedBar].barSizeLow =
- + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
- +
- + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
- +
- + }
- + else
- + {
- +
- + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
- +
- + pPciAgent->pciBar[detectedBar].barSizeLow =
- + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
- +
- + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
- +
- + }
- +
- +
- +
- + }
- + else /* 32bit bar */
- + {
- + /* write oxffffffff to the bar to get the size */
- + mvPciIfConfigWrite(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
- + 0xffffffff);
- +
- + /* read size */
- + pPciAgent->pciBar[detectedBar].barSizeLow =
- + mvPciIfConfigRead(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
- +
- + if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)
- + {
- + /* this bar is not applicable for this device,
- + ignore all previous settings and check the next bar*/
- + continue;
- + }
- +
- +
- + /* restore original value */
- + mvPciIfConfigWrite(pciIf,
- + bus,dev,func,
- + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
- + tmpBaseLow);
- +
- + /* calculate size low */
- +
- + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
- + {
- + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
- + }
- + else
- + {
- + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;
- + }
- +
- + pPciAgent->pciBar[detectedBar].barSizeLow =
- + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
- +
- + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
- + pPciAgent->pciBar[detectedBar].barSize =
- + (MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;
- +
- +
- + }
- +
- + /* we are here ! this means we have already detected a bar for
- + this device , now move on */
- +
- + detectedBar++;
- + pPciAgent->barsNum++;
- + }
- +
- + return detectedBar;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPciClassNameGet - get PCI class name
- +*
- +* DESCRIPTION:
- +* This function returns the PCI class name
- +*
- +* INPUT:
- +* baseClassCode - Base Class Code.
- +*
- +* OUTPUT:
- +* pType - the class name
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)
- +{
- +
- + switch(baseClassCode)
- + {
- + case 0x0:
- + strcpy(pType,"Old generation device");
- + break;
- + case 0x1:
- + strcpy(pType,"Mass storage controller");
- + break;
- + case 0x2:
- + strcpy(pType,"Network controller");
- + break;
- + case 0x3:
- + strcpy(pType,"Display controller");
- + break;
- + case 0x4:
- + strcpy(pType,"Multimedia device");
- + break;
- + case 0x5:
- + strcpy(pType,"Memory controller");
- + break;
- + case 0x6:
- + strcpy(pType,"Bridge Device");
- + break;
- + case 0x7:
- + strcpy(pType,"Simple Communication controllers");
- + break;
- + case 0x8:
- + strcpy(pType,"Base system peripherals");
- + break;
- + case 0x9:
- + strcpy(pType,"Input Devices");
- + break;
- + case 0xa:
- + strcpy(pType,"Docking stations");
- + break;
- + case 0xb:
- + strcpy(pType,"Processors");
- + break;
- + case 0xc:
- + strcpy(pType,"Serial bus controllers");
- + break;
- + case 0xd:
- + strcpy(pType,"Wireless controllers");
- + break;
- + case 0xe:
- + strcpy(pType,"Intelligent I/O controllers");
- + break;
- + case 0xf:
- + strcpy(pType,"Satellite communication controllers");
- + break;
- + case 0x10:
- + strcpy(pType,"Encryption/Decryption controllers");
- + break;
- + case 0x11:
- + strcpy(pType,"Data acquisition and signal processing controllers");
- + break;
- + default:
- + strcpy(pType,"Unknown device");
- + break;
- + }
- +
- + return MV_OK;
- +
- +}
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 2010-11-09 20:28:11.662495451 +0100
- @@ -0,0 +1,323 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvPciUtilsh
- +#define __INCmvPciUtilsh
- +
- +/*
- +This module only support scanning of Header type 00h of pci devices
- +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
- +*/
- +
- +/* includes */
- +#include "mvSysHwConfig.h"
- +#include "pci-if/mvPciIf.h"
- +#include "pci/mvPciRegs.h"
- +
- +
- +
- +/* PCI base address low bar mask */
- +#define PCI_ERROR_CODE 0xffffffff
- +
- +#define PCI_BRIDGE_CLASS 0x6
- +#define P2P_BRIDGE_SUB_CLASS_CODE 0x4
- +
- +
- +#define P2P_BUSSES_NUM 0x18
- +#define P2P_IO_BASE_LIMIT_SEC_STATUS 0x1C
- +#define P2P_MEM_BASE_LIMIT 0x20
- +#define P2P_PREF_MEM_BASE_LIMIT 0x24
- +#define P2P_PREF_BASE_UPPER_32 0x28
- +#define P2P_PREF_LIMIT_UPPER_32 0x2C
- +#define P2P_IO_BASE_LIMIT_UPPER_16 0x30
- +#define P2P_EXP_ROM 0x38
- +
- +/* P2P_BUSSES_NUM (PBM) */
- +
- +#define PBM_PRIME_BUS_NUM_OFFS 0
- +#define PBM_PRIME_BUS_NUM_MASK (0xff << PBM_PRIME_BUS_NUM_OFFS)
- +
- +#define PBM_SEC_BUS_NUM_OFFS 8
- +#define PBM_SEC_BUS_NUM_MASK (0xff << PBM_SEC_BUS_NUM_OFFS)
- +
- +#define PBM_SUB_BUS_NUM_OFFS 16
- +#define PBM_SUB_BUS_NUM_MASK (0xff << PBM_SUB_BUS_NUM_OFFS)
- +
- +#define PBM_SEC_LAT_TMR_OFFS 24
- +#define PBM_SEC_LAT_TMR_MASK (0xff << PBM_SEC_LAT_TMR_OFFS)
- +
- +/* P2P_IO_BASE_LIMIT_SEC_STATUS (PIBLSS) */
- +
- +#define PIBLSS_IO_BASE_OFFS 0
- +#define PIBLSS_IO_BASE_MASK (0xff << PIBLSS_IO_BASE_OFFS)
- +
- +#define PIBLSS_ADD_CAP_OFFS 0
- +#define PIBLSS_ADD_CAP_MASK (0x3 << PIBLSS_ADD_CAP_OFFS)
- +#define PIBLSS_ADD_CAP_16BIT (0x0 << PIBLSS_ADD_CAP_OFFS)
- +#define PIBLSS_ADD_CAP_32BIT (0x1 << PIBLSS_ADD_CAP_OFFS)
- +
- +#define PIBLSS_LOW_ADDR_OFFS 0
- +#define PIBLSS_LOW_ADDR_MASK (0xFFF << PIBLSS_LOW_ADDR_OFFS)
- +
- +#define PIBLSS_HIGH_ADDR_OFFS 12
- +#define PIBLSS_HIGH_ADDR_MASK (0xF << PIBLSS_HIGH_ADDR_OFFS)
- +
- +#define PIBLSS_IO_LIMIT_OFFS 8
- +#define PIBLSS_IO_LIMIT_MASK (0xff << PIBLSS_IO_LIMIT_OFFS)
- +
- +#define PIBLSS_SEC_STATUS_OFFS 16
- +#define PIBLSS_SEC_STATUS_MASK (0xffff << PIBLSS_SEC_STATUS_OFFS)
- +
- +
- +/* P2P_MEM_BASE_LIMIT (PMBL)*/
- +
- +#define PMBL_MEM_BASE_OFFS 0
- +#define PMBL_MEM_BASE_MASK (0xffff << PMBL_MEM_BASE_OFFS)
- +
- +#define PMBL_MEM_LIMIT_OFFS 16
- +#define PMBL_MEM_LIMIT_MASK (0xffff << PMBL_MEM_LIMIT_OFFS)
- +
- +
- +#define PMBL_LOW_ADDR_OFFS 0
- +#define PMBL_LOW_ADDR_MASK (0xFFFFF << PMBL_LOW_ADDR_OFFS)
- +
- +#define PMBL_HIGH_ADDR_OFFS 20
- +#define PMBL_HIGH_ADDR_MASK (0xFFF << PMBL_HIGH_ADDR_OFFS)
- +
- +
- +/* P2P_PREF_MEM_BASE_LIMIT (PRMBL) */
- +
- +#define PRMBL_PREF_MEM_BASE_OFFS 0
- +#define PRMBL_PREF_MEM_BASE_MASK (0xffff << PRMBL_PREF_MEM_BASE_OFFS)
- +
- +#define PRMBL_PREF_MEM_LIMIT_OFFS 16
- +#define PRMBL_PREF_MEM_LIMIT_MASK (0xffff<<PRMBL_PREF_MEM_LIMIT_OFFS)
- +
- +#define PRMBL_LOW_ADDR_OFFS 0
- +#define PRMBL_LOW_ADDR_MASK (0xFFFFF << PRMBL_LOW_ADDR_OFFS)
- +
- +#define PRMBL_HIGH_ADDR_OFFS 20
- +#define PRMBL_HIGH_ADDR_MASK (0xFFF << PRMBL_HIGH_ADDR_OFFS)
- +
- +#define PRMBL_ADD_CAP_OFFS 0
- +#define PRMBL_ADD_CAP_MASK (0xf << PRMBL_ADD_CAP_OFFS)
- +#define PRMBL_ADD_CAP_32BIT (0x0 << PRMBL_ADD_CAP_OFFS)
- +#define PRMBL_ADD_CAP_64BIT (0x1 << PRMBL_ADD_CAP_OFFS)
- +
- +/* P2P_IO_BASE_LIMIT_UPPER_16 (PIBLU) */
- +
- +#define PRBU_IO_UPP_BASE_OFFS 0
- +#define PRBU_IO_UPP_BASE_MASK (0xffff << PRBU_IO_UPP_BASE_OFFS)
- +
- +#define PRBU_IO_UPP_LIMIT_OFFS 16
- +#define PRBU_IO_UPP_LIMIT_MASK (0xffff << PRBU_IO_UPP_LIMIT_OFFS)
- +
- +
- +/* typedefs */
- +
- +typedef enum _mvPciBarMapping
- +{
- + PCI_MEMORY_BAR,
- + PCI_IO_BAR,
- + PCI_NO_MAPPING
- +}MV_PCI_BAR_MAPPING;
- +
- +typedef enum _mvPciBarType
- +{
- + PCI_32BIT_BAR,
- + PCI_64BIT_BAR
- +}MV_PCI_BAR_TYPE;
- +
- +typedef enum _mvPciIntPin
- +{
- + MV_PCI_INTA = 1,
- + MV_PCI_INTB = 2,
- + MV_PCI_INTC = 3,
- + MV_PCI_INTD = 4
- +}MV_PCI_INT_PIN;
- +
- +typedef enum _mvPciHeader
- +{
- + MV_PCI_STANDARD,
- + MV_PCI_PCI2PCI_BRIDGE
- +
- +}MV_PCI_HEADER;
- +
- +
- +/* BAR structure */
- +typedef struct _pciBar
- +{
- + MV_U32 barOffset;
- + MV_U32 barBaseLow;
- + MV_U32 barBaseHigh;
- + MV_U32 barSizeLow;
- + MV_U32 barSizeHigh;
- + /* The 'barBaseAddr' is a 64-bit variable
- + that will contain the TOTAL base address
- + value achived by combining both the 'barBaseLow'
- + and the 'barBaseHigh' parameters as follows:
- +
- + BIT: 63 31 0
- + | | |
- + barBaseHigh barBaseLow */
- + MV_U64 barBaseAddr;
- + /* The 'barSize' is a 64-bit variable
- + that will contain the TOTAL size achived
- + by combining both the 'barSizeLow' and
- + the 'barSizeHigh' parameters as follows:
- +
- + BIT: 63 31 0
- + | | |
- + barSizeHigh barSizeLow
- +
- + NOTE: The total size described above
- + is AFTER the size calculation as
- + described in PCI spec rev2.2 */
- + MV_U64 barSize;
- + MV_BOOL isPrefetchable;
- + MV_PCI_BAR_TYPE barType;
- + MV_PCI_BAR_MAPPING barMapping;
- +
- +
- +} PCI_BAR;
- +
- +/* Device information structure */
- +typedef struct _mvPciDevice
- +{
- + /* Device specific information */
- + MV_U32 busNumber; /* Pci agent bus number */
- + MV_U32 deviceNum; /* Pci agent device number */
- + MV_U32 function; /* Pci agent function number */
- +
- + MV_U32 venID; /* Pci agent Vendor ID */
- + MV_U32 deviceID; /* Pci agent Device ID */
- +
- + MV_BOOL isFastB2BCapable; /* Capability of Fast Back to Back
- + transactions */
- + MV_BOOL isCapListSupport; /* Support of Capability list */
- + MV_BOOL is66MHZCapable; /* 66MHZ support */
- +
- + MV_U32 baseClassCode; /* Pci agent base Class Code */
- + MV_U32 subClassCode; /* Pci agent sub Class Code */
- + MV_U32 progIf; /* Pci agent Programing interface */
- + MV_U32 revisionID;
- +
- + PCI_BAR pciBar[6]; /* Pci agent bar list */
- +
- + MV_U32 p2pPrimBusNum; /* P2P Primary Bus number*/
- + MV_U32 p2pSecBusNum; /* P2P Secondary Bus Number*/
- + MV_U32 p2pSubBusNum; /* P2P Subordinate bus Number */
- + MV_U32 p2pSecLatencyTimer; /* P2P Econdary Latency Timer*/
- + MV_U32 p2pIObase; /* P2P IO Base */
- + MV_U32 p2pIOLimit; /* P2P IO Linit */
- + MV_BOOL bIO32;
- + MV_U32 p2pSecStatus; /* P2P Secondary Status */
- + MV_U32 p2pMemBase; /* P2P Memory Space */
- + MV_U32 p2pMemLimit; /* P2P Memory Limit*/
- + MV_U32 p2pPrefMemBase; /* P2P Prefetchable Mem Base*/
- + MV_U32 p2pPrefMemLimit; /* P2P Prefetchable Memory Limit*/
- + MV_BOOL bPrefMem64;
- + MV_U32 p2pPrefBaseUpper32Bits;/* P2P Prefetchable upper 32 bits*/
- + MV_U32 p2pPrefLimitUpper32Bits;/* P2P prefetchable limit upper 32*/
- +
- +
- + MV_U32 pciCacheLine; /* Pci agent cache line */
- + MV_U32 pciLatencyTimer; /* Pci agent Latency timer */
- + MV_PCI_HEADER pciHeader; /* Pci agent header type*/
- + MV_BOOL isMultiFunction; /* Multi function support */
- + MV_BOOL isBISTCapable; /* Self test capable */
- +
- + MV_U32 subSysID; /* Sub System ID */
- + MV_U32 subSysVenID; /* Sub System Vendor ID */
- +
- + MV_BOOL isExpRom; /* Expantion Rom support */
- + MV_U32 expRomAddr; /* Expantion Rom pointer */
- +
- + MV_U32 capListPointer; /* Capability list pointer */
- +
- + MV_U32 irqLine; /* IRQ line */
- + MV_PCI_INT_PIN intPin; /* Interrupt pin */
- + MV_U32 minGrant; /* Minimum grant*/
- + MV_U32 maxLatency; /* Maximum latency*/
- +
- + MV_U32 funtionsNum; /* pci agent total functions number */
- +
- + MV_U32 barsNum;
- + MV_U8 type[60]; /* class name of the pci agent */
- +
- +
- +} MV_PCI_DEVICE;
- +
- +/* PCI gloabl functions */
- +MV_STATUS mvPciClassNameGet(MV_U32 classCode, MV_8 *pType);
- +
- +
- +/* Performs a full scan on both PCIs and returns all possible details on the
- + agents found on the bus. */
- +MV_STATUS mvPciScan(MV_U32 pciIf,
- + MV_PCI_DEVICE *pPciAgents,
- + MV_U32 *pPciAgentsNum);
- +
- +
- +#endif /* #ifndef __INCmvPciUtilsh */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 2010-11-09 20:28:11.702495387 +0100
- @@ -0,0 +1,1143 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "pex/mvPex.h"
- +
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +/* defines */
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
- +{
- + MV_PEX_MODE pexMode;
- + MV_U32 regVal;
- + MV_U32 status;
- +
- + /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */
- + /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */
- + /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */
- +
- + if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&
- + (mvCtrlModelGet() != MV_6281_DEV_ID) &&
- + (mvCtrlModelGet() != MV_6192_DEV_ID) &&
- + (mvCtrlModelGet() != MV_6190_DEV_ID) &&
- + (mvCtrlModelGet() != MV_6180_DEV_ID) &&
- + (mvCtrlModelGet() != MV_6183_DEV_ID) &&
- + (mvCtrlModelGet() != MV_6183L_DEV_ID) &&
- + (mvCtrlModelGet() != MV_78100_DEV_ID) &&
- + (mvCtrlModelGet() != MV_78200_DEV_ID) &&
- + (mvCtrlModelGet() != MV_76100_DEV_ID) &&
- + (mvCtrlModelGet() != MV_78XX0_DEV_ID))
- + {
- +
- + /* Read current value of TXAMP */
- + MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
- +
- + regVal = MV_REG_READ(0x41b00); /* Extract the data */
- +
- + /* Prepare new data for write */
- + regVal &= ~0x7; /* Clear bits [2:0] */
- + regVal |= 0x4; /* Set the new value */
- + regVal &= ~0x80000000; /* Set "write" command */
- + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
- +
- + }
- + else
- + {
- + /* Implement 1.0V termination GL for 88F1281 device only */
- + /* BIT0 - Common mode feedback */
- + /* BIT3 - TxBuf, extra drive for 1.0V termination */
- + if (mvCtrlModelGet() == MV_1281_DEV_ID)
- + {
- + MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */
- + regVal = MV_REG_READ(0x41b00); /* Extract the data */
- + regVal |= (BIT0 | BIT3);
- + regVal &= ~0x80000000; /* Set "write" command */
- + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
- +
- + MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */
- + regVal = MV_REG_READ(0x31b00); /* Extract the data */
- + regVal |= (BIT0 | BIT3);
- + regVal &= ~0x80000000; /* Set "write" command */
- + MV_REG_WRITE(0x31b00, regVal); /* Write the write command */
- + }
- + }
- +
- + if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
- + {
- + mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
- + return MV_ERROR;
- + }
- +
- + /* Check that required PEX type is the one set in reset time */
- + if (pexType != pexMode.pexType)
- + {
- + /* No Link. Shut down the Phy */
- + mvPexPowerDown(pexIf);
- + mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);
- + return MV_ERROR;
- + }
- +
- + if (MV_PEX_ROOT_COMPLEX == pexType)
- + {
- + mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
- + mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
- +
- + /* Local device master Enable */
- + mvPexMasterEnable(pexIf, MV_TRUE);
- +
- + /* Local device slave Enable */
- + mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),
- + mvPexLocalDevNumGet(pexIf), MV_TRUE);
- + /* Interrupt disable */
- + status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));
- + status |= PXSAC_INT_DIS;
- + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);
- + }
- +
- + /* now wait 500 ms to be sure the link is valid (spec compliant) */
- + mvOsDelay(500);
- + /* Check if we have link */
- + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
- + {
- + mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
- + return MV_NO_SUCH;
- + }
- +
- + if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
- + {
- + mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
- + }
- + else
- + {
- + mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
- + }
- +
- +#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
- + mvPexVrtBrgInit(pexIf);
- +#endif
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPexModeGet - Get Pex Mode
- +*
- +* DESCRIPTION:
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +*
- +* OUTPUT:
- +* pexMode - Pex mode structure
- +*
- +* RETURN:
- +* MV_OK on success , MV_ERROR otherwise
- +*
- +*******************************************************************************/
- +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
- +{
- + MV_U32 pexData;
- +
- + /* Parameter checking */
- + if (PEX_DEFAULT_IF != pexIf)
- + {
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
- + return MV_ERROR;
- + }
- + }
- +
- + pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
- +
- + switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
- + {
- + case PXCR_DEV_TYPE_CTRL_CMPLX:
- + pexMode->pexType = MV_PEX_ROOT_COMPLEX;
- + break;
- + case PXCR_DEV_TYPE_CTRL_POINT:
- + pexMode->pexType = MV_PEX_END_POINT;
- + break;
- +
- + }
- +
- + /* Check if we have link */
- + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
- + {
- + pexMode->pexLinkUp = MV_FALSE;
- +
- + /* If there is no link, the auto negotiation data is worthless */
- + pexMode->pexWidth = MV_PEX_WITDH_INVALID;
- + }
- + else
- + {
- + pexMode->pexLinkUp = MV_TRUE;
- +
- + /* We have link. The link width is now valid */
- + pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
- + pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >>
- + PXLCSR_NEG_LNK_WDTH_OFFS);
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/* PEX configuration space read write */
- +
- +/*******************************************************************************
- +* mvPexConfigRead - Read from configuration space
- +*
- +* DESCRIPTION:
- +* This function performs a 32 bit read from PEX configuration space.
- +* It supports both type 0 and type 1 of Configuration Transactions
- +* (local and over bridge). In order to read from local bus segment, use
- +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
- +* will result configuration transaction of type 1 (over bridge).
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* bus - PEX segment bus number.
- +* dev - PEX device number.
- +* func - Function number.
- +* regOffs - Register offset.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* 32bit register data, 0xffffffff on error
- +*
- +*******************************************************************************/
- +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
- + MV_U32 regOff)
- +{
- +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
- + return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
- +}
- +
- +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
- + MV_U32 regOff)
- +{
- +#endif
- + MV_U32 pexData = 0;
- + MV_U32 localDev,localBus;
- +
- + /* Parameter checking */
- + if (PEX_DEFAULT_IF != pexIf)
- + {
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
- + return 0xFFFFFFFF;
- + }
- + }
- +
- + if (dev >= MAX_PEX_DEVICES)
- + {
- + DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
- + return 0xFFFFFFFF;
- + }
- +
- + if (func >= MAX_PEX_FUNCS)
- + {
- + DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
- + return 0xFFFFFFFF;
- + }
- +
- + if (bus >= MAX_PEX_BUSSES)
- + {
- + DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
- + return MV_ERROR;
- + }
- +
- + DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
- + pexIf, bus, dev, func, regOff));
- +
- + localDev = mvPexLocalDevNumGet(pexIf);
- + localBus = mvPexLocalBusNumGet(pexIf);
- +
- + /* Speed up the process. In case on no link, return MV_ERROR */
- + if ((dev != localDev) || (bus != localBus))
- + {
- + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
- +
- + if ((pexData & PXSR_DL_DOWN))
- + {
- + return MV_ERROR;
- + }
- + }
- +
- + /* in PCI Express we have only one device number */
- + /* and this number is the first number we encounter
- + else that the localDev*/
- + /* spec pex define return on config read/write on any device */
- + if (bus == localBus)
- + {
- + if (localDev == 0)
- + {
- + /* if local dev is 0 then the first number we encounter
- + after 0 is 1 */
- + if ((dev != 1)&&(dev != localDev))
- + {
- + return MV_ERROR;
- + }
- + }
- + else
- + {
- + /* if local dev is not 0 then the first number we encounter
- + is 0 */
- +
- + if ((dev != 0)&&(dev != localDev))
- + {
- + return MV_ERROR;
- + }
- + }
- + if(func != 0 ) /* i.e bridge */
- + {
- + return MV_ERROR;
- + }
- + }
- +
- +
- + /* Creating PEX address to be passed */
- + pexData = (bus << PXCAR_BUS_NUM_OFFS);
- + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
- + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
- + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
- + /* extended register space */
- + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
- + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
- +
- + pexData |= PXCAR_CONFIG_EN;
- +
- + /* Write the address to the PEX configuration address register */
- + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
- +
- + DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
- +
- +
- + /* In order to let the PEX controller absorbed the address of the read */
- + /* transaction we perform a validity check that the address was written */
- + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
- + {
- + return MV_ERROR;
- + }
- +
- + /* cleaning Master Abort */
- + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
- + PXSAC_MABORT);
- +#if 0
- + /* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration */
- + /* This guideline is relevant for all devices except of the following devices:
- + 88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
- + 88F6183 A0 and above, 88F6183L */
- + if ( ( (dev != localDev) || (bus != localBus) ) &&
- + (
- + !(MV_5281_DEV_ID == mvCtrlModelGet())&&
- + !((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
- + !(MV_1281_DEV_ID == mvCtrlModelGet())&&
- + !(MV_6183_DEV_ID == mvCtrlModelGet())&&
- + !(MV_6183L_DEV_ID == mvCtrlModelGet())&&
- + !(MV_6281_DEV_ID == mvCtrlModelGet())&&
- + !(MV_6192_DEV_ID == mvCtrlModelGet())&&
- + !(MV_6190_DEV_ID == mvCtrlModelGet())&&
- + !(MV_6180_DEV_ID == mvCtrlModelGet())&&
- + !(MV_78XX0_DEV_ID == mvCtrlModelGet())
- + ))
- + {
- +
- + /* PCI-Express configuration read work-around */
- +
- + /* we will use one of the Punit (AHBToMbus) windows to access the xbar
- + and read the data from there */
- + /*
- + Need to configure the 2 free Punit (AHB to MBus bridge)
- + address decoding windows:
- + Configure the flash Window to handle Configuration space requests
- + for PEX0/1:
- + 1. write 0x7931/0x7941 to the flash window and the size,
- + 79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
- + 2. write base to flash window
- +
- + Configuration transactions from the CPU should write/read the data
- + to/from address of the form:
- + addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
- + addr[27:24] = extended register number
- + addr[23:16] = bus number
- + addr[15:11] = device number
- + addr[10:8] = function number
- + addr[7:0] = register number
- + */
- +
- + #include "ctrlEnv/sys/mvAhbToMbus.h"
- + {
- + MV_U32 winNum;
- + MV_AHB_TO_MBUS_DEC_WIN originWin;
- + MV_U32 pciAddr=0;
- + MV_U32 remapLow=0,remapHigh=0;
- +
- + /*
- + We will use DEV_CS2\Flash window for this workarround
- + */
- +
- + winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
- +
- + /* save remap values if exist */
- + if ((1 == winNum)||(0 == winNum))
- + {
- + remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
- + remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));
- +
- + }
- +
- +
- + /* save the original window values */
- + mvAhbToMbusWinGet(winNum,&originWin);
- +
- + if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
- + {
- + /* set the window as xbar window */
- + if (pexIf)
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
- + (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
- + }
- + else
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
- + (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
- + }
- +
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
- + originWin.addrWin.baseLow);
- +
- + /*pciAddr = originWin.addrWin.baseLow;*/
- + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
- + (MV_U32)originWin.addrWin.baseLow);
- +
- + }
- + else
- + {
- + /* set the window as xbar window */
- + if (pexIf)
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
- + (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
- + }
- + else
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
- + (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
- + }
- +
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
- + PEX_CONFIG_RW_WA_BASE);
- +
- + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
- + }
- +
- +
- + /* remap should be as base */
- + if ((1 == winNum)||(0 == winNum))
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);
- +
- + }
- +
- + /* extended register space */
- + pciAddr |= (bus << 16);
- + pciAddr |= (dev << 11);
- + pciAddr |= (func << 8);
- + pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
- +
- + pexData = *(MV_U32*)pciAddr;
- + pexData = MV_32BIT_LE(pexData); /* Data always in LE */
- +
- + /* restore the original window values */
- + mvAhbToMbusWinSet(winNum,&originWin);
- +
- + /* restore original remap values*/
- + if ((1 == winNum)||(0 == winNum))
- + {
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);
- + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);
- +
- + }
- + }
- + }
- + else
- +#endif
- + {
- + /* Read the Data returned in the PEX Data register */
- + pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
- +
- + }
- +
- + DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
- +
- + return pexData;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPexConfigWrite - Write to configuration space
- +*
- +* DESCRIPTION:
- +* This function performs a 32 bit write to PEX configuration space.
- +* It supports both type 0 and type 1 of Configuration Transactions
- +* (local and over bridge). In order to write to local bus segment, use
- +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
- +* will result configuration transaction of type 1 (over bridge).
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* bus - PEX segment bus number.
- +* dev - PEX device number.
- +* func - Function number.
- +* regOffs - Register offset.
- +* data - 32bit data.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data)
- +{
- +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
- + return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
- +}
- +
- +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data)
- +{
- +#endif
- + MV_U32 pexData = 0;
- + MV_U32 localDev,localBus;
- +
- + /* Parameter checking */
- + if (PEX_DEFAULT_IF != pexIf)
- + {
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
- + pexIf);
- + return MV_ERROR;
- + }
- + }
- +
- + if (dev >= MAX_PEX_DEVICES)
- + {
- + mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
- + return MV_BAD_PARAM;
- + }
- +
- + if (func >= MAX_PEX_FUNCS)
- + {
- + mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
- + return MV_ERROR;
- + }
- +
- + if (bus >= MAX_PEX_BUSSES)
- + {
- + mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
- + return MV_ERROR;
- + }
- +
- +
- +
- + localDev = mvPexLocalDevNumGet(pexIf);
- + localBus = mvPexLocalBusNumGet(pexIf);
- +
- +
- + /* in PCI Express we have only one device number other than ourselves*/
- + /* and this number is the first number we encounter
- + else than the localDev that can be any valid dev number*/
- + /* pex spec define return on config read/write on any device */
- + if (bus == localBus)
- + {
- +
- + if (localDev == 0)
- + {
- + /* if local dev is 0 then the first number we encounter
- + after 0 is 1 */
- + if ((dev != 1)&&(dev != localDev))
- + {
- + return MV_ERROR;
- + }
- +
- + }
- + else
- + {
- + /* if local dev is not 0 then the first number we encounter
- + is 0 */
- +
- + if ((dev != 0)&&(dev != localDev))
- + {
- + return MV_ERROR;
- + }
- + }
- +
- +
- + }
- +
- + /* if we are not accessing ourselves , then check the link */
- + if ((dev != localDev) || (bus != localBus) )
- + {
- + /* workarround */
- + /* when no link return MV_ERROR */
- +
- + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
- +
- + if ((pexData & PXSR_DL_DOWN))
- + {
- + return MV_ERROR;
- + }
- +
- + }
- +
- + pexData =0;
- +
- + /* Creating PEX address to be passed */
- + pexData |= (bus << PXCAR_BUS_NUM_OFFS);
- + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
- + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
- + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
- + /* extended register space */
- + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
- + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
- + pexData |= PXCAR_CONFIG_EN;
- +
- + DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",
- + pexIf,bus,func,dev,regOff,data,pexData) );
- +
- + /* Write the address to the PEX configuration address register */
- + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
- +
- + /* Clear CPU pipe. Important where CPU can perform OOO execution */
- + CPU_PIPE_FLUSH;
- +
- + /* In order to let the PEX controller absorbed the address of the read */
- + /* transaction we perform a validity check that the address was written */
- + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
- + {
- + return MV_ERROR;
- + }
- +
- + /* Write the Data passed to the PEX Data register */
- + MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPexMasterEnable - Enable/disale PEX interface master transactions.
- +*
- +* DESCRIPTION:
- +* This function performs read modified write to PEX command status
- +* (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
- +* master is allowed to gain ownership on the bus, otherwise it is
- +* incapable to do so.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
- +{
- + MV_U32 pexCommandStatus;
- + MV_U32 localBus;
- + MV_U32 localDev;
- +
- + /* Parameter checking */
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_ERROR;
- + }
- +
- + localBus = mvPexLocalBusNumGet(pexIf);
- + localDev = mvPexLocalDevNumGet(pexIf);
- +
- + pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
- + PEX_STATUS_AND_COMMAND));
- +
- +
- + if (MV_TRUE == enable)
- + {
- + pexCommandStatus |= PXSAC_MASTER_EN;
- + }
- + else
- + {
- + pexCommandStatus &= ~PXSAC_MASTER_EN;
- + }
- +
- +
- + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
- + pexCommandStatus);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
- +*
- +* DESCRIPTION:
- +* This function performs read modified write to PEX command status
- +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
- +* the PEX slave is allowed to respond to PEX IO space access (bit 0)
- +* and PEX memory space access (bit 1).
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* dev - PEX device number.
- +* enable - Enable/disable parameter.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
- +{
- + MV_U32 pexCommandStatus;
- + MV_U32 RegOffs;
- +
- + /* Parameter checking */
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- + if (dev >= MAX_PEX_DEVICES)
- + {
- + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
- + return MV_BAD_PARAM;
- +
- + }
- +
- +
- + RegOffs = PEX_STATUS_AND_COMMAND;
- +
- + pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
- +
- + if (MV_TRUE == enable)
- + {
- + pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
- + }
- + else
- + {
- + pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
- + }
- +
- + mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvPexLocalBusNumSet - Set PEX interface local bus number.
- +*
- +* DESCRIPTION:
- +* This function sets given PEX interface its local bus number.
- +* Note: In case the PEX interface is PEX-X, the information is read-only.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* busNum - Bus number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
- +* MV_BAD_PARAM on bad parameters ,
- +* otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
- +{
- + MV_U32 pexStatus;
- + MV_U32 localBus;
- + MV_U32 localDev;
- +
- +
- + /* Parameter checking */
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
- + return MV_BAD_PARAM;
- + }
- + if (busNum >= MAX_PEX_BUSSES)
- + {
- + mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
- + return MV_ERROR;
- +
- + }
- +
- + localBus = mvPexLocalBusNumGet(pexIf);
- + localDev = mvPexLocalDevNumGet(pexIf);
- +
- +
- +
- + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
- +
- + pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
- +
- + pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
- +
- + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
- +
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPexLocalBusNumGet - Get PEX interface local bus number.
- +*
- +* DESCRIPTION:
- +* This function gets the local bus number of a given PEX interface.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Local bus number.0xffffffff on Error
- +*
- +*******************************************************************************/
- +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
- +{
- + MV_U32 pexStatus;
- +
- + /* Parameter checking */
- + if (PEX_DEFAULT_IF != pexIf)
- + {
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
- + return 0xFFFFFFFF;
- + }
- + }
- +
- +
- + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
- +
- + pexStatus &= PXSR_PEX_BUS_NUM_MASK;
- +
- + return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
- +
- +}
- +
- +
- +/*******************************************************************************
- +* mvPexLocalDevNumSet - Set PEX interface local device number.
- +*
- +* DESCRIPTION:
- +* This function sets given PEX interface its local device number.
- +* Note: In case the PEX interface is PEX-X, the information is read-only.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* devNum - Device number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
- +* MV_BAD_PARAM on bad parameters ,
- +* otherwise MV_OK
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
- +{
- + MV_U32 pexStatus;
- + MV_U32 localBus;
- + MV_U32 localDev;
- +
- + /* Parameter checking */
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
- + return MV_BAD_PARAM;
- + }
- + if (devNum >= MAX_PEX_DEVICES)
- + {
- + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
- + devNum);
- + return MV_BAD_PARAM;
- +
- + }
- +
- + localBus = mvPexLocalBusNumGet(pexIf);
- + localDev = mvPexLocalDevNumGet(pexIf);
- +
- +
- + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
- +
- + pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
- +
- + pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
- +
- + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
- +
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvPexLocalDevNumGet - Get PEX interface local device number.
- +*
- +* DESCRIPTION:
- +* This function gets the local device number of a given PEX interface.
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Local device number. 0xffffffff on Error
- +*
- +*******************************************************************************/
- +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
- +{
- + MV_U32 pexStatus;
- +
- + /* Parameter checking */
- +
- + if (PEX_DEFAULT_IF != pexIf)
- + {
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
- + pexIf);
- + return 0xFFFFFFFF;
- + }
- + }
- +
- + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
- +
- + pexStatus &= PXSR_PEX_DEV_NUM_MASK;
- +
- + return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
- +}
- +
- +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
- +{
- +
- + MV_U32 regAddr;
- + if (pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
- + return;
- + }
- + regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));
- + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
- + *value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf));
- +}
- +
- +
- +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
- +{
- +
- + MV_U32 regAddr;
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
- + return;
- + }
- + regAddr = (((regOffset & 0x3fff) << 16) | value);
- + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
- +}
- +
- +/*******************************************************************************
- +* mvPexActiveStateLinkPMEnable
- +*
- +* DESCRIPTION:
- +* Enable Active Link State Power Management
- +*
- +* INPUT:
- +* pexIf - PEX interface number.
- +* enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* MV_OK on success , MV_ERROR otherwise
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
- +{
- + MV_U32 reg;
- +
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_ERROR;
- + }
- +
- + reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
- + if(enable == MV_TRUE)
- + reg |= PXPMER_L1_ASPM_EN_MASK;
- + MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);
- +
- + /* Enable / Disable L0/1 entry */
- + reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
- + & ~PXLCSR_ASPM_CNT_MASK;
- + if(enable == MV_TRUE)
- + reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
- + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvPexForceX1
- +*
- +* DESCRIPTION:
- +* shut down lanes 1-3 if recognize that attached to an x1 end-point
- +* INPUT:
- +* pexIf - PEX interface number.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* MV_OK on success , MV_ERROR otherwise
- +*
- +*******************************************************************************/
- +MV_U32 mvPexForceX1(MV_U32 pexIf)
- +{
- + MV_U32 regData = 0;
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_BAD_PARAM;
- + }
- +
- + regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
- + regData |= PXCR_CONF_LINK_X1;
- +
- + MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
- + return MV_OK;
- +}
- +
- +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
- +{
- + if(pexIf >= mvCtrlPexMaxIfGet())
- + {
- + mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
- + return MV_FALSE;
- + }
- + return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
- +}
- +
- +
- +MV_VOID mvPexPowerDown(MV_U32 pexIf)
- +{
- + if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||
- + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
- + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
- + (mvCtrlModelGet() == MV_78200_DEV_ID) )
- + {
- + mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
- + }
- + else
- + {
- + MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);
- + }
- +}
- +
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 2010-11-09 20:28:11.742495415 +0100
- @@ -0,0 +1,168 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCPEXH
- +#define __INCPEXH
- +
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "pex/mvPexRegs.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +
- +
- +
- +/* NOTE not supported in this driver:*/
- +
- +
- +/* defines */
- +/* The number of supported PEX interfaces depend on Marvell controller */
- +/* device number. This device number ID is located on the PEX unit */
- +/* configuration header. This creates a loop where calling PEX */
- +/* configuration read/write routine results a call to get PEX configuration */
- +/* information etc. This macro defines a default PEX interface. This PEX */
- +/* interface is sure to exist. */
- +#define PEX_DEFAULT_IF 0
- +
- +
- +/* typedefs */
- +/* The Marvell controller supports both root complex and end point devices */
- +/* This enumeration describes the PEX type. */
- +typedef enum _mvPexType
- +{
- + MV_PEX_ROOT_COMPLEX, /* root complex device */
- + MV_PEX_END_POINT /* end point device */
- +}MV_PEX_TYPE;
- +
- +typedef enum _mvPexWidth
- +{
- + MV_PEX_WITDH_X1 = 1,
- + MV_PEX_WITDH_X2,
- + MV_PEX_WITDH_X3,
- + MV_PEX_WITDH_X4,
- + MV_PEX_WITDH_INVALID
- +}MV_PEX_WIDTH;
- +
- +/* PEX Bar attributes */
- +typedef struct _mvPexMode
- +{
- + MV_PEX_TYPE pexType;
- + MV_PEX_WIDTH pexWidth;
- + MV_BOOL pexLinkUp;
- +}MV_PEX_MODE;
- +
- +
- +
- +/* Global Functions prototypes */
- +/* mvPexInit - Initialize PEX interfaces*/
- +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
- +
- +/* mvPexModeGet - Get Pex If mode */
- +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode);
- +
- +/* mvPexConfigRead - Read from configuration space */
- +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func,MV_U32 regOff);
- +
- +/* mvPexConfigWrite - Write to configuration space */
- +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data);
- +
- +/* mvPexMasterEnable - Enable/disale PEX interface master transactions.*/
- +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable);
- +
- +/* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.*/
- +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable);
- +
- +/* mvPexLocalBusNumSet - Set PEX interface local bus number.*/
- +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum);
- +
- +/* mvPexLocalBusNumGet - Get PEX interface local bus number.*/
- +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf);
- +
- +/* mvPexLocalDevNumSet - Set PEX interface local device number.*/
- +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum);
- +
- +/* mvPexLocalDevNumGet - Get PEX interface local device number.*/
- +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf);
- +/* mvPexForceX1 - Force PEX interface to X1 mode. */
- +MV_U32 mvPexForceX1(MV_U32 pexIf);
- +
- +/* mvPexIsPowerUp - Is PEX interface Power up? */
- +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf);
- +
- +/* mvPexPowerDown - Power Down */
- +MV_VOID mvPexPowerDown(MV_U32 pexIf);
- +
- +/* mvPexPowerUp - Power Up */
- +MV_VOID mvPexPowerUp(MV_U32 pexIf);
- +
- +/* mvPexPhyRegRead - Pex phy read */
- +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value);
- +
- +/* mvPexPhyRegWrite - Pex phy write */
- +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value);
- +
- +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable);
- +
- +#endif /* #ifndef __INCPEXH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 2010-11-09 20:28:11.782495900 +0100
- @@ -0,0 +1,751 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCPEXREGSH
- +#define __INCPEXREGSH
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* defines */
- +#define MAX_PEX_DEVICES 32
- +#define MAX_PEX_FUNCS 8
- +#define MAX_PEX_BUSSES 256
- +
- +
- +
- +/*********************************************************/
- +/* PCI Express Configuration Cycles Generation Registers */
- +/*********************************************************/
- +
- +#define PEX_CFG_ADDR_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18F8)
- +#define PEX_CFG_DATA_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18FC)
- +#define PEX_PHY_ACCESS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1B00)
- +/* PCI Express Configuration Address Register */
- +/* PEX_CFG_ADDR_REG (PXCAR)*/
- +
- +#define PXCAR_REG_NUM_OFFS 2
- +#define PXCAR_REG_NUM_MAX 0x3F
- +#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS)
- +#define PXCAR_FUNC_NUM_OFFS 8
- +#define PXCAR_FUNC_NUM_MAX 0x7
- +#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS)
- +#define PXCAR_DEVICE_NUM_OFFS 11
- +#define PXCAR_DEVICE_NUM_MAX 0x1F
- +#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS)
- +#define PXCAR_BUS_NUM_OFFS 16
- +#define PXCAR_BUS_NUM_MAX 0xFF
- +#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS)
- +#define PXCAR_EXT_REG_NUM_OFFS 24
- +#define PXCAR_EXT_REG_NUM_MAX 0xF
- +
- +/* in pci express register address is now the legacy register address (8 bits)
- +with the new extended register address (more 4 bits) , below is the mask of
- +the upper 4 bits of the full register address */
- +
- +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
- +#define PXCAR_EXT_REG_NUM_MASK (PXCAR_EXT_REG_NUM_MAX << PXCAR_EXT_REG_NUM_OFFS)
- +#define PXCAR_CONFIG_EN BIT31
- +
- +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
- +#define PXCAR_REAL_EXT_REG_NUM_MASK (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS)
- +
- +/* The traditional PCI spec defined 6-bit field to describe register offset.*/
- +/* The new PCI Express extend the register offset by an extra 4-bits. */
- +/* The below macro assign 10-bit register offset into the apprpreate */
- +/* fields in the CFG_ADDR_REG */
- +#define PXCAR_REG_OFFS_SET(regOffs) \
- + ( (regOff & PXCAR_REG_NUM_MASK) | \
- + ( ((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS) )
- +
- +/***********************************/
- +/* PCI Express Interrupt registers */
- +/***********************************/
- +#define PEX_CAUSE_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1900)
- +#define PEX_MASK_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1910)
- +
- +#define PXICR_TX_REQ_IN_DLDOWN_ERR BIT0 /* Transmit request while field */
- + /* <DLDown> of the PCI Express */
- +/* PCI Express Interrupt Cause */
- +/* PEX_INT_CAUSE_REG (PXICR)*/
- +/* PEX_INT_MASK_REG*/
- +/*
- +NOTE:All bits except bits[27:24] are Read/Write Clear only. A cause bit sets
- +upon an error event occurrence. A write of 0 clears the bit. A write of 1 has
- +no affect. Bits[24:27} are set and cleared upon reception of interrupt
- +emulation messages.
- +
- +Mask bit per cause bit. If a bit is set to 1, the corresponding event is
- +enabled. Mask does not affect setting of the Interrupt Cause register bits;
- +it only affects the assertion of the interrupt .*/
- +
- +
- +#define PXICR_MDIS_CAUSE BIT1 /* Attempt to generate PCI transaction
- + while master is disabled */
- +#define PXICR_ERR_WRTO_REG_CAUSE BIT3 /* Erroneous write attempt to
- + PCI Express internal register*/
- +#define PXICR_HIT_DFLT_WIN_ERR BIT4 /* Hit Default Window Error */
- +#define PXICR_RX_RAM_PAR_ERR BIT6 /* Rx RAM Parity Error */
- +#define PXICR_TX_RAM_PAR_ERR BIT7 /* Tx RAM Parity Error */
- +#define PXICR_COR_ERR_DET BIT8 /* Correctable Error Detected*/
- +#define PXICR_NF_ERR_DET BIT9 /* Non-Fatal Error Detected*/
- +#define PXICR_FERR_DET BIT10 /* Fatal Error Detected*/
- +#define PXICR_DSTATE_CHANGE BIT11 /* Dstate Change Indication*/
- +#define PXICR_BIST BIT12 /* PCI-Express BIST activated*/
- +#define PXICR_FLW_CTRL_PROT BIT14 /* Flow Control Protocol Error */
- +
- +#define PXICR_RCV_UR_CA_ERR BIT15 /* Received UR or CA status. */
- +#define PXICR_RCV_ERR_FATAL BIT16 /* Received ERR_FATAL message.*/
- +#define PXICR_RCV_ERR_NON_FATAL BIT17 /* Received ERR_NONFATAL message*/
- +#define PXICR_RCV_ERR_COR BIT18 /* Received ERR_COR message.*/
- +#define PXICR_RCV_CRS BIT19 /* Received CRS completion status*/
- +#define PXICR_SLV_HOT_RESET BIT20 /* Received Hot Reset Indication*/
- +#define PXICR_SLV_DIS_LINK BIT21 /* Slave Disable Link Indication*/
- +#define PXICR_SLV_LB BIT22 /* Slave Loopback Indication*/
- +#define PXICR_LINK_FAIL BIT23 /* Link Failure indication.*/
- +#define PXICR_RCV_INTA BIT24 /* IntA status.*/
- +#define PXICR_RCV_INTB BIT25 /* IntB status.*/
- +#define PXICR_RCV_INTC BIT26 /* IntC status.*/
- +#define PXICR_RCV_INTD BIT27 /* IntD status.*/
- +#define PXICR_RCV_PM_PME BIT28 /* Received PM_PME message. */
- +
- +
- +/********************************************/
- +/* PCI Express Control and Status Registers */
- +/********************************************/
- +#define PEX_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A00)
- +#define PEX_STATUS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A04)
- +#define PEX_COMPLT_TMEOUT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A10)
- +#define PEX_PWR_MNG_EXT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A18)
- +#define PEX_FLOW_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A20)
- +#define PEX_ACK_TMR_4X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A30)
- +#define PEX_ACK_TMR_1X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A40)
- +#define PEX_TL_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1AB0)
- +
- +
- +#define PEX_RAM_PARITY_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A50)
- +/* PCI Express Control Register */
- +/* PEX_CTRL_REG (PXCR) */
- +
- +#define PXCR_CONF_LINK_OFFS 0
- +#define PXCR_CONF_LINK_MASK (1 << PXCR_CONF_LINK_OFFS)
- +#define PXCR_CONF_LINK_X4 (0 << PXCR_CONF_LINK_OFFS)
- +#define PXCR_CONF_LINK_X1 (1 << PXCR_CONF_LINK_OFFS)
- +#define PXCR_DEV_TYPE_CTRL_OFFS 1 /*PCI ExpressDevice Type Control*/
- +#define PXCR_DEV_TYPE_CTRL_MASK BIT1
- +#define PXCR_DEV_TYPE_CTRL_CMPLX (1 << PXCR_DEV_TYPE_CTRL_OFFS)
- +#define PXCR_DEV_TYPE_CTRL_POINT (0 << PXCR_DEV_TYPE_CTRL_OFFS)
- +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
- + to Memory Space Enable */
- +
- +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
- + to Memory Space Enable*/
- +
- +#define PXCR_RSRV1_OFFS 5
- +#define PXCR_RSRV1_MASK (0x7 << PXCR_RSRV1_OFFS)
- +#define PXCR_RSRV1_VAL (0x0 << PXCR_RSRV1_OFFS)
- +
- +#define PXCR_CONF_MAX_OUTSTND_OFFS 8 /*Maximum outstanding NP requests as a master*/
- +#define PXCR_CONF_MAX_OUTSTND_MASK (0x3 << PXCR_CONF_MAX_OUTSTND_OFFS)
- +
- +
- +#define PXCR_CONF_NFTS_OFFS 16 /*number of FTS Ordered-Sets*/
- +#define PXCR_CONF_NFTS_MASK (0xff << PXCR_CONF_NFTS_OFFS)
- +
- +#define PXCR_CONF_MSTR_HOT_RESET BIT24 /*Master Hot-Reset.*/
- +#define PXCR_CONF_MSTR_LB BIT26 /* Master Loopback */
- +#define PXCR_CONF_MSTR_DIS_SCRMB BIT27 /* Master Disable Scrambling*/
- +#define PXCR_CONF_DIRECT_DIS_SCRMB BIT28 /* Direct Disable Scrambling*/
- +
- +/* PCI Express Status Register */
- +/* PEX_STATUS_REG (PXSR) */
- +
- +#define PXSR_DL_DOWN BIT0 /* DL_Down indication.*/
- +
- +#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */
- +#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS)
- +
- +#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */
- +#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS)
- +
- +#define PXSR_PEX_SLV_HOT_RESET BIT24 /* Slave Hot Reset Indication*/
- +#define PXSR_PEX_SLV_DIS_LINK BIT25 /* Slave Disable Link Indication*/
- +#define PXSR_PEX_SLV_LB BIT26 /* Slave Loopback Indication*/
- +#define PXSR_PEX_SLV_DIS_SCRMB BIT27 /* Slave Disable Scrambling Indication*/
- +
- +
- +/* PCI Express Completion Timeout Register */
- +/* PEX_COMPLT_TMEOUT_REG (PXCTR)*/
- +
- +#define PXCTR_CMP_TO_THRSHLD_OFFS 0 /* Completion Timeout Threshold */
- +#define PXCTR_CMP_TO_THRSHLD_MASK (0xffff << PXCTR_CMP_TO_THRSHLD_OFFS)
- +
- +/* PCI Express Power Management Extended Register */
- +/* PEX_PWR_MNG_EXT_REG (PXPMER) */
- +
- +#define PXPMER_L1_ASPM_EN_OFFS 1
- +#define PXPMER_L1_ASPM_EN_MASK (0x1 << PXPMER_L1_ASPM_EN_OFFS)
- +
- +/* PCI Express Flow Control Register */
- +/* PEX_FLOW_CTRL_REG (PXFCR)*/
- +
- +#define PXFCR_PH_INIT_FC_OFFS 0 /*Posted Headers Flow Control Credit
- + Initial Value.*/
- +#define PXFCR_PH_INIT_FC_MASK (0xff << PXFCR_PH_INIT_FC_OFFS)
- +
- +
- +#define PXFCR_NPH_INIT_FC_OFFS 8 /* Classified Non-Posted Headers
- + Flow Control Credit Initial Value*/
- +#define PXFCR_NPH_INIT_FC_MASK (0xff << PXFCR_NPH_INIT_FC_OFFS)
- +
- +#define PXFCR_CH_INIT_FC_OFFS 16 /* Completion Headers Flow Control
- + Credit Initial Value Infinite*/
- +
- +#define PXFCR_CH_INIT_FC_MASK (0xff << PXFCR_CH_INIT_FC_OFFS)
- +
- +#define PXFCR_FC_UPDATE_TO_OFFS 24 /* Flow Control Update Timeout */
- +#define PXFCR_FC_UPDATE_TO_MASK (0xff << PXFCR_FC_UPDATE_TO_OFFS)
- +
- +/* PCI Express Acknowledge Timers (4X) Register */
- +/* PEX_ACK_TMR_4X_REG (PXAT4R) */
- +#define PXAT1R_ACK_LAT_TOX4_OFFS 0 /* Ack Latency Timer Timeout Value */
- +#define PXAT1R_ACK_LAT_TOX4_MASK (0xffff << PXAT4R_ACK_LAT_TOX1_OFFS)
- +#define PXAT1R_ACK_RPLY_TOX4_OFFS 16 /* Ack Replay Timer Timeout Value */
- +#define PXAT1R_ACK_RPLY_TOX4_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
- +
- +/* PCI Express Acknowledge Timers (1X) Register */
- +/* PEX_ACK_TMR_1X_REG (PXAT1R) */
- +
- +#define PXAT1R_ACK_LAT_TOX1_OFFS 0 /* Acknowledge Latency Timer Timeout
- + Value for 1X Link*/
- +#define PXAT1R_ACK_LAT_TOX1_MASK (0xffff << PXAT1R_ACK_LAT_TOX1_OFFS)
- +
- +#define PXAT1R_ACK_RPLY_TOX1_OFFS 16 /* Acknowledge Replay Timer Timeout
- + Value for 1X*/
- +#define PXAT1R_ACK_RPLY_TOX1_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
- +
- +
- +/* PCI Express TL Control Register */
- +/* PEX_TL_CTRL_REG (PXTCR) */
- +
- +#define PXTCR_TX_CMP_BUFF_NO_OFFS 8 /*Number of completion buffers in Tx*/
- +#define PXTCR_TX_CMP_BUFF_NO_MASK (0xf << PXTCR_TX_CMP_BUFF_NO_OFFS)
- +
- +/* PCI Express Debug MAC Control Register */
- +/* PEX_DEBUG_MAC_CTRL_REG (PXDMCR) */
- +
- +#define PXDMCR_LINKUP BIT4
- +
- +
- +
- +/**********************************************/
- +/* PCI Express Configuration Header Registers */
- +/**********************************************/
- +#define PEX_CFG_DIRECT_ACCESS(pexIf,cfgReg) ((PEX_IF_BASE(pexIf)) + (cfgReg))
- +
- +#define PEX_DEVICE_AND_VENDOR_ID 0x000
- +#define PEX_STATUS_AND_COMMAND 0x004
- +#define PEX_CLASS_CODE_AND_REVISION_ID 0x008
- +#define PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
- +#define PEX_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
- +#define PEX_MV_BAR_BASE(barNum) (0x010 + (barNum) * 8)
- +#define PEX_MV_BAR_BASE_HIGH(barNum) (0x014 + (barNum) * 8)
- +#define PEX_BAR0_INTER_REG 0x010
- +#define PEX_BAR0_INTER_REG_HIGH 0x014
- +#define PEX_BAR1_REG 0x018
- +#define PEX_BAR1_REG_HIGH 0x01C
- +#define PEX_BAR2_REG 0x020
- +#define PEX_BAR2_REG_HIGH 0x024
- +
- +#define PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
- +#define PEX_EXPANSION_ROM_BASE_ADDR_REG 0x030
- +#define PEX_CAPABILTY_LIST_POINTER 0x034
- +#define PEX_INTERRUPT_PIN_AND_LINE 0x03C
- +
- +/* capability list */
- +#define PEX_POWER_MNG_CAPABILITY 0x040
- +#define PEX_POWER_MNG_STATUS_CONTROL 0x044
- +
- +#define PEX_MSI_MESSAGE_CONTROL 0x050
- +#define PEX_MSI_MESSAGE_ADDR 0x054
- +#define PEX_MSI_MESSAGE_HIGH_ADDR 0x058
- +#define PEX_MSI_MESSAGE_DATA 0x05C
- +
- +#define PEX_CAPABILITY_REG 0x60
- +#define PEX_DEV_CAPABILITY_REG 0x64
- +#define PEX_DEV_CTRL_STAT_REG 0x68
- +#define PEX_LINK_CAPABILITY_REG 0x6C
- +#define PEX_LINK_CTRL_STAT_REG 0x70
- +
- +#define PEX_ADV_ERR_RPRT_HDR_TRGT_REG 0x100
- +#define PEX_UNCORRECT_ERR_STAT_REG 0x104
- +#define PEX_UNCORRECT_ERR_MASK_REG 0x108
- +#define PEX_UNCORRECT_ERR_SERVITY_REG 0x10C
- +#define PEX_CORRECT_ERR_STAT_REG 0x110
- +#define PEX_CORRECT_ERR_MASK_REG 0x114
- +#define PEX_ADV_ERR_CAPABILITY_CTRL_REG 0x118
- +#define PEX_HDR_LOG_FIRST_DWORD_REG 0x11C
- +#define PEX_HDR_LOG_SECOND_DWORD_REG 0x120
- +#define PEX_HDR_LOG_THIRD_DWORD_REG 0x124
- +#define PEX_HDR_LOG_FOURTH_DWORD_REG 0x128
- +
- +
- +
- +/* PCI Express Device and Vendor ID Register*/
- +/*PEX_DEVICE_AND_VENDOR_ID (PXDAVI)*/
- +
- +#define PXDAVI_VEN_ID_OFFS 0 /* Vendor ID */
- +#define PXDAVI_VEN_ID_MASK (0xffff << PXDAVI_VEN_ID_OFFS)
- +
- +#define PXDAVI_DEV_ID_OFFS 16 /* Device ID */
- +#define PXDAVI_DEV_ID_MASK (0xffff << PXDAVI_DEV_ID_OFFS)
- +
- +
- +/* PCI Express Command and Status Register*/
- +/*PEX_STATUS_AND_COMMAND (PXSAC)*/
- +
- +#define PXSAC_IO_EN BIT0 /* IO Enable */
- +#define PXSAC_MEM_EN BIT1 /* Memory Enable */
- +#define PXSAC_MASTER_EN BIT2 /* Master Enable */
- +#define PXSAC_PERR_EN BIT6 /* Parity Errors Respond Enable */
- +#define PXSAC_SERR_EN BIT8 /* Ability to assert SERR# line */
- +#define PXSAC_INT_DIS BIT10 /* Interrupt Disable */
- +#define PXSAC_INT_STAT BIT19 /* Interrupt Status */
- +#define PXSAC_CAP_LIST BIT20 /* Capability List Support */
- +#define PXSAC_MAS_DATA_PERR BIT24 /* Master Data Parity Error */
- +#define PXSAC_SLAVE_TABORT BIT27 /* Signalled Target Abort */
- +#define PXSAC_RT_ABORT BIT28 /* Recieved Target Abort */
- +#define PXSAC_MABORT BIT29 /* Recieved Master Abort */
- +#define PXSAC_SYSERR BIT30 /* Signalled system error */
- +#define PXSAC_DET_PARERR BIT31 /* Detect Parity Error */
- +
- +
- +/* PCI Express Class Code and Revision ID Register*/
- +/*PEX_CLASS_CODE_AND_REVISION_ID (PXCCARI)*/
- +
- +#define PXCCARI_REVID_OFFS 0 /* Revision ID */
- +#define PXCCARI_REVID_MASK (0xff << PXCCARI_REVID_OFFS)
- +
- +#define PXCCARI_FULL_CLASS_OFFS 8 /* Full Class Code */
- +#define PXCCARI_FULL_CLASS_MASK (0xffffff << PXCCARI_FULL_CLASS_OFFS)
- +
- +#define PXCCARI_PROGIF_OFFS 8 /* Prog .I/F*/
- +#define PXCCARI_PROGIF_MASK (0xff << PXCCARI_PROGIF_OFFS)
- +
- +#define PXCCARI_SUB_CLASS_OFFS 16 /* Sub Class*/
- +#define PXCCARI_SUB_CLASS_MASK (0xff << PXCCARI_SUB_CLASS_OFFS)
- +
- +#define PXCCARI_BASE_CLASS_OFFS 24 /* Base Class*/
- +#define PXCCARI_BASE_CLASS_MASK (0xff << PXCCARI_BASE_CLASS_OFFS)
- +
- +
- +/* PCI Express BIST, Header Type and Cache Line Size Register*/
- +/*PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE (PXBHTLTCL)*/
- +
- +#define PXBHTLTCL_CACHELINE_OFFS 0 /* Specifies the cache line size */
- +#define PXBHTLTCL_CACHELINE_MASK (0xff << PXBHTLTCL_CACHELINE_OFFS)
- +
- +#define PXBHTLTCL_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
- +#define PXBHTLTCL_HEADTYPE_FULL_MASK (0xff << PXBHTLTCL_HEADTYPE_FULL_OFFS)
- +
- +#define PXBHTLTCL_MULTI_FUNC BIT23 /* Multi/Single function */
- +
- +#define PXBHTLTCL_HEADER_OFFS 16 /* Header type */
- +#define PXBHTLTCL_HEADER_MASK (0x7f << PXBHTLTCL_HEADER_OFFS)
- +#define PXBHTLTCL_HEADER_STANDARD (0x0 << PXBHTLTCL_HEADER_OFFS)
- +#define PXBHTLTCL_HEADER_PCI2PCI_BRIDGE (0x1 << PXBHTLTCL_HEADER_OFFS)
- +
- +
- +#define PXBHTLTCL_BISTCOMP_OFFS 24 /* BIST Completion Code */
- +#define PXBHTLTCL_BISTCOMP_MASK (0xf << PXBHTLTCL_BISTCOMP_OFFS)
- +
- +#define PXBHTLTCL_BISTACT BIT30 /* BIST Activate bit */
- +#define PXBHTLTCL_BISTCAP BIT31 /* BIST Capable Bit */
- +#define PXBHTLTCL_BISTCAP_OFFS 31
- +#define PXBHTLTCL_BISTCAP_MASK BIT31
- +#define PXBHTLTCL_BISTCAP_VAL 0
- +
- +
- +/* PCI Express Subsystem Device and Vendor ID */
- +/*PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID (PXSIASVI)*/
- +
- +#define PXSIASVI_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
- +#define PXSIASVI_VENID_MASK (0xffff << PXSIASVI_VENID_OFFS)
- +
- +#define PXSIASVI_DEVID_OFFS 16 /* Subsystem Device ID Number */
- +#define PXSIASVI_DEVID_MASK (0xffff << PXSIASVI_DEVID_OFFS)
- +
- +
- +/* PCI Express Capability List Pointer Register*/
- +/*PEX_CAPABILTY_LIST_POINTER (PXCLP)*/
- +
- +#define PXCLP_CAPPTR_OFFS 0 /* Capability List Pointer */
- +#define PXCLP_CAPPTR_MASK (0xff << PXCLP_CAPPTR_OFFS)
- +
- +/* PCI Express Interrupt Pin and Line Register */
- +/*PEX_INTERRUPT_PIN_AND_LINE (PXIPAL)*/
- +
- +#define PXIPAL_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
- +#define PXIPAL_INTLINE_MASK (0xff << PXIPAL_INTLINE_OFFS)
- +
- +#define PXIPAL_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
- +#define PXIPAL_INTPIN_MASK (0xff << PXIPAL_INTPIN_OFFS)
- +
- +
- +/* PCI Express Power Management Capability Header Register*/
- +/*PEX_POWER_MNG_CAPABILITY (PXPMC)*/
- +
- +#define PXPMC_CAP_ID_OFFS 0 /* Capability ID */
- +#define PXPMC_CAP_ID_MASK (0xff << PXPMC_CAP_ID_OFFS)
- +
- +#define PXPMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
- +#define PXPMC_NEXT_PTR_MASK (0xff << PXPMC_NEXT_PTR_OFFS)
- +
- +#define PXPMC_PMC_VER_OFFS 16 /* PCI Power Management Capability Version*/
- +#define PXPMC_PMC_VER_MASK (0x7 << PXPMC_PMC_VER_OFFS)
- +
- +#define PXPMC_DSI BIT21/* Device Specific Initialization */
- +
- +#define PXPMC_AUX_CUR_OFFS 22 /* Auxiliary Current Requirements */
- +#define PXPMC_AUX_CUR_MASK (0x7 << PXPMC_AUX_CUR_OFFS)
- +
- +#define PXPMC_D1_SUP BIT25 /* D1 Power Management support*/
- +
- +#define PXPMC_D2_SUP BIT26 /* D2 Power Management support*/
- +
- +#define PXPMC_PME_SUP_OFFS 27 /* PM Event generation support*/
- +#define PXPMC_PME_SUP_MASK (0x1f << PXPMC_PME_SUP_OFFS)
- +
- +/* PCI Express Power Management Control and Status Register*/
- +/*PEX_POWER_MNG_STATUS_CONTROL (PXPMSC)*/
- +
- +#define PXPMSC_PM_STATE_OFFS 0 /* Power State */
- +#define PXPMSC_PM_STATE_MASK (0x3 << PXPMSC_PM_STATE_OFFS)
- +#define PXPMSC_PM_STATE_D0 (0x0 << PXPMSC_PM_STATE_OFFS)
- +#define PXPMSC_PM_STATE_D1 (0x1 << PXPMSC_PM_STATE_OFFS)
- +#define PXPMSC_PM_STATE_D2 (0x2 << PXPMSC_PM_STATE_OFFS)
- +#define PXPMSC_PM_STATE_D3 (0x3 << PXPMSC_PM_STATE_OFFS)
- +
- +#define PXPMSC_PME_EN BIT8/* PM_PME Message Generation Enable */
- +
- +#define PXPMSC_PM_DATA_SEL_OFFS 9 /* Data Select*/
- +#define PXPMSC_PM_DATA_SEL_MASK (0xf << PXPMSC_PM_DATA_SEL_OFFS)
- +
- +#define PXPMSC_PM_DATA_SCALE_OFFS 13 /* Data Scale */
- +#define PXPMSC_PM_DATA_SCALE_MASK (0x3 << PXPMSC_PM_DATA_SCALE_OFFS)
- +
- +#define PXPMSC_PME_STAT BIT15/* PME Status */
- +
- +#define PXPMSC_PM_DATA_OFFS 24 /* State Data */
- +#define PXPMSC_PM_DATA_MASK (0xff << PXPMSC_PM_DATA_OFFS)
- +
- +
- +/* PCI Express MSI Message Control Register*/
- +/*PEX_MSI_MESSAGE_CONTROL (PXMMC)*/
- +
- +#define PXMMC_CAP_ID_OFFS 0 /* Capability ID */
- +#define PXMMC_CAP_ID_MASK (0xff << PXMMC_CAP_ID_OFFS)
- +
- +#define PXMMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
- +#define PXMMC_NEXT_PTR_MASK (0xff << PXMMC_NEXT_PTR_OFFS)
- +
- +#define PXMMC_MSI_EN BIT18 /* MSI Enable */
- +
- +#define PXMMC_MULTI_CAP_OFFS 17 /* Multiple Message Capable */
- +#define PXMMC_MULTI_CAP_MASK (0x7 << PXMMC_MULTI_CAP_OFFS)
- +
- +#define PXMMC_MULTI_EN_OFFS 20 /* Multiple Messages Enable */
- +#define PXMMC_MULTI_EN_MASK (0x7 << PXMMC_MULTI_EN_OFFS)
- +
- +#define PXMMC_ADDR64 BIT23 /* 64-bit Addressing Capable */
- +
- +
- +/* PCI Express MSI Message Address Register*/
- +/*PEX_MSI_MESSAGE_ADDR (PXMMA)*/
- +
- +#define PXMMA_MSI_ADDR_OFFS 2 /* Message Address corresponds to
- + Address[31:2] of the MSI MWr TLP*/
- +#define PXMMA_MSI_ADDR_MASK (0x3fffffff << PXMMA_MSI_ADDR_OFFS)
- +
- +
- +/* PCI Express MSI Message Address (High) Register */
- +/*PEX_MSI_MESSAGE_HIGH_ADDR (PXMMHA)*/
- +
- +#define PXMMA_MSI_ADDR_H_OFFS 0 /* Message Upper Address corresponds to
- + Address[63:32] of the MSI MWr TLP*/
- +#define PXMMA_MSI_ADDR_H_MASK (0xffffffff << PXMMA_MSI_ADDR_H_OFFS )
- +
- +
- +/* PCI Express MSI Message Data Register*/
- +/*PEX_MSI_MESSAGE_DATA (PXMMD)*/
- +
- +#define PXMMD_MSI_DATA_OFFS 0 /* Message Data */
- +#define PXMMD_MSI_DATA_MASK (0xffff << PXMMD_MSI_DATA_OFFS )
- +
- +
- +/* PCI Express Capability Register*/
- +/*PEX_CAPABILITY_REG (PXCR)*/
- +
- +#define PXCR_CAP_ID_OFFS 0 /* Capability ID*/
- +#define PXCR_CAP_ID_MASK (0xff << PXCR_CAP_ID_OFFS)
- +
- +#define PXCR_NEXT_PTR_OFFS 8 /* Next Item Pointer*/
- +#define PXCR_NEXT_PTR_MASK (0xff << PXCR_NEXT_PTR_OFFS)
- +
- +#define PXCR_CAP_VER_OFFS 16 /* Capability Version*/
- +#define PXCR_CAP_VER_MASK (0xf << PXCR_CAP_VER_OFFS)
- +
- +#define PXCR_DEV_TYPE_OFFS 20 /* Device/Port Type*/
- +#define PXCR_DEV_TYPE_MASK (0xf << PXCR_DEV_TYPE_OFFS)
- +
- +#define PXCR_SLOT_IMP BIT24 /* Slot Implemented*/
- +
- +#define PXCR_INT_MSG_NUM_OFFS 25 /* Interrupt Message Number*/
- +#define PXCR_INT_MSG_NUM_MASK (0x1f << PXCR_INT_MSG_NUM_OFFS)
- +
- +
- +/* PCI Express Device Capabilities Register */
- +/*PEX_DEV_CAPABILITY_REG (PXDCR)*/
- +
- +#define PXDCR_MAX_PLD_SIZE_SUP_OFFS 0 /* Maximum Payload Size Supported*/
- +#define PXDCR_MAX_PLD_SIZE_SUP_MASK (0x7 << PXDCR_MAX_PLD_SIZE_SUP_OFFS)
- +
- +#define PXDCR_EP_L0S_ACC_LAT_OFFS 6/* Endpoint L0s Acceptable Latency*/
- +#define PXDCR_EP_L0S_ACC_LAT_MASK (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +#define PXDCR_EP_L0S_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
- +
- +#define PXDCR_EP_L1_ACC_LAT_OFFS 9 /* Endpoint L1 Acceptable Latency*/
- +#define PXDCR_EP_L1_ACC_LAT_MASK (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXDCR_EP_L1_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +
- +
- +#define PXDCR_ATT_BUT_PRS_OFFS 12 /* Attention Button Present*/
- +#define PXDCR_ATT_BUT_PRS_MASK BIT12
- +#define PXDCR_ATT_BUT_PRS_IMPLEMENTED BIT12
- +
- +#define PXDCR_ATT_IND_PRS_OFFS 13 /* Attention Indicator Present*/
- +#define PXDCR_ATT_IND_PRS_MASK BIT13
- +#define PXDCR_ATT_IND_PRS_IMPLEMENTED BIT13
- +
- +#define PXDCR_PWR_IND_PRS_OFFS 14/* Power Indicator Present*/
- +#define PXDCR_PWR_IND_PRS_MASK BIT14
- +#define PXDCR_PWR_IND_PRS_IMPLEMENTED BIT14
- +
- +#define PXDCR_CAP_SPL_VAL_OFFS 18 /*Captured Slot Power Limit
- + Value*/
- +#define PXDCR_CAP_SPL_VAL_MASK (0xff << PXDCR_CAP_SPL_VAL_OFFS)
- +
- +#define PXDCR_CAP_SP_LSCL_OFFS 26 /* Captured Slot Power Limit
- + Scale */
- +#define PXDCR_CAP_SP_LSCL_MASK (0x3 << PXDCR_CAP_SP_LSCL_OFFS)
- +
- +/* PCI Express Device Control Status Register */
- +/*PEX_DEV_CTRL_STAT_REG (PXDCSR)*/
- +
- +#define PXDCSR_COR_ERR_REP_EN BIT0 /* Correctable Error Reporting Enable*/
- +#define PXDCSR_NF_ERR_REP_EN BIT1 /* Non-Fatal Error Reporting Enable*/
- +#define PXDCSR_F_ERR_REP_EN BIT2 /* Fatal Error Reporting Enable*/
- +#define PXDCSR_UR_REP_EN BIT3 /* Unsupported Request (UR)
- + Reporting Enable*/
- +#define PXDCSR_EN_RO BIT4 /* Enable Relaxed Ordering*/
- +
- +#define PXDCSR_MAX_PLD_SZ_OFFS 5 /* Maximum Payload Size*/
- +#define PXDCSR_MAX_PLD_SZ_MASK (0x7 << PXDCSR_MAX_PLD_SZ_OFFS)
- +#define PXDCSR_MAX_PLD_SZ_128B (0x0 << PXDCSR_MAX_PLD_SZ_OFFS)
- +#define PXDCSR_EN_NS BIT11 /* Enable No Snoop*/
- +
- +#define PXDCSR_MAX_RD_RQ_SZ_OFFS 12 /* Maximum Read Request Size*/
- +#define PXDCSR_MAX_RD_RQ_SZ_MASK (0x7 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
- +#define PXDCSR_MAX_RD_RQ_SZ_128B (0x0 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
- +#define PXDCSR_MAX_RD_RQ_SZ_256B (0x1 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
- +#define PXDCSR_MAX_RD_RQ_SZ_512B (0x2 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
- +#define PXDCSR_MAX_RD_RQ_SZ_1KB (0x3 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
- +#define PXDCSR_MAX_RD_RQ_SZ_2KB (0x4 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
- +#define PXDCSR_MAX_RD_RQ_SZ_4KB (0x5 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
- +
- +#define PXDCSR_COR_ERR_DET BIT16 /* Correctable Error Detected*/
- +#define PXDCSR_NF_ERR_DET BIT17 /* Non-Fatal Error Detected.*/
- +#define PXDCSR_F_ERR_DET BIT18 /* Fatal Error Detected.*/
- +#define PXDCSR_UR_DET BIT19 /* Unsupported Request Detected */
- +#define PXDCSR_AUX_PWR_DET BIT20 /* Reserved*/
- +
- +#define PXDCSR_TRANS_PEND_OFFS 21 /* Transactions Pending*/
- +#define PXDCSR_TRANS_PEND_MASK BIT21
- +#define PXDCSR_TRANS_PEND_NOT_COMPLETED (0x1 << PXDCSR_TRANS_PEND_OFFS)
- +
- +
- +/* PCI Express Link Capabilities Register*/
- +/*PEX_LINK_CAPABILITY_REG (PXLCR)*/
- +
- +#define PXLCR_MAX_LINK_SPD_OFFS 0 /* Maximum Link Speed*/
- +#define PXLCR_MAX_LINK_SPD_MASK (0xf << PXLCR_MAX_LINK_SPD_OFFS)
- +
- +#define PXLCR_MAX_LNK_WDTH_OFFS 3 /* Maximum Link Width*/
- +#define PXLCR_MAX_LNK_WDTH_MASK (0x3f << PXLCR_MAX_LNK_WDTH_OFFS)
- +
- +#define PXLCR_ASPM_SUP_OFFS 10 /* Active State Link PM Support*/
- +#define PXLCR_ASPM_SUP_MASK (0x3 << PXLCR_ASPM_SUP_OFFS)
- +
- +#define PXLCR_L0S_EXT_LAT_OFFS 12 /* L0s Exit Latency*/
- +#define PXLCR_L0S_EXT_LAT_MASK (0x7 << PXLCR_L0S_EXT_LAT_OFFS)
- +#define PXLCR_L0S_EXT_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXLCR_L0S_EXT_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXLCR_L0S_EXT_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXLCR_L0S_EXT_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXLCR_L0S_EXT_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXLCR_L0S_EXT_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +#define PXLCR_L0S_EXT_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
- +
- +#define PXLCR_POR_TNUM_OFFS 24 /* Port Number */
- +#define PXLCR_POR_TNUM_MASK (0xff << PXLCR_POR_TNUM_OFFS)
- +
- +/* PCI Express Link Control Status Register */
- +/*PEX_LINK_CTRL_STAT_REG (PXLCSR)*/
- +
- +#define PXLCSR_ASPM_CNT_OFFS 0 /* Active State Link PM Control */
- +#define PXLCSR_ASPM_CNT_MASK (0x3 << PXLCSR_ASPM_CNT_OFFS)
- +#define PXLCSR_ASPM_CNT_DISABLED (0x0 << PXLCSR_ASPM_CNT_OFFS)
- +#define PXLCSR_ASPM_CNT_L0S_ENT_SUPP (0x1 << PXLCSR_ASPM_CNT_OFFS)
- +#define PXLCSR_ASPM_CNT_L1S_ENT_SUPP (0x2 << PXLCSR_ASPM_CNT_OFFS)
- +#define PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP (0x3 << PXLCSR_ASPM_CNT_OFFS)
- +
- +#define PXLCSR_RCB_OFFS 3 /* Read Completion Boundary */
- +#define PXLCSR_RCB_MASK BIT3
- +#define PXLCSR_RCB_64B (0 << PXLCSR_RCB_OFFS)
- +#define PXLCSR_RCB_128B (1 << PXLCSR_RCB_OFFS)
- +
- +#define PXLCSR_LNK_DIS BIT4 /* Link Disable */
- +#define PXLCSR_RETRN_LNK BIT5 /* Retrain Link */
- +#define PXLCSR_CMN_CLK_CFG BIT6 /* Common Clock Configuration */
- +#define PXLCSR_EXTD_SNC BIT7 /* Extended Sync */
- +
- +#define PXLCSR_LNK_SPD_OFFS 16 /* Link Speed */
- +#define PXLCSR_LNK_SPD_MASK (0xf << PXLCSR_LNK_SPD_OFFS)
- +
- +#define PXLCSR_NEG_LNK_WDTH_OFFS 20 /* Negotiated Link Width */
- +#define PXLCSR_NEG_LNK_WDTH_MASK (0x3f << PXLCSR_NEG_LNK_WDTH_OFFS)
- +#define PXLCSR_NEG_LNK_WDTH_X1 (0x1 << PXLCSR_NEG_LNK_WDTH_OFFS)
- +
- +#define PXLCSR_LNK_TRN BIT27 /* Link Training */
- +
- +#define PXLCSR_SLT_CLK_CFG_OFFS 28 /* Slot Clock Configuration */
- +#define PXLCSR_SLT_CLK_CFG_MASK BIT28
- +#define PXLCSR_SLT_CLK_CFG_INDPNT (0x0 << PXLCSR_SLT_CLK_CFG_OFFS)
- +#define PXLCSR_SLT_CLK_CFG_REF (0x1 << PXLCSR_SLT_CLK_CFG_OFFS)
- +
- +/* PCI Express Advanced Error Report Header Register */
- +/*PEX_ADV_ERR_RPRT_HDR_TRGT_REG (PXAERHTR)*/
- +
- +/* PCI Express Uncorrectable Error Status Register*/
- +/*PEX_UNCORRECT_ERR_STAT_REG (PXUESR)*/
- +
- +/* PCI Express Uncorrectable Error Mask Register */
- +/*PEX_UNCORRECT_ERR_MASK_REG (PXUEMR)*/
- +
- +/* PCI Express Uncorrectable Error Severity Register */
- +/*PEX_UNCORRECT_ERR_SERVITY_REG (PXUESR)*/
- +
- +/* PCI Express Correctable Error Status Register */
- +/*PEX_CORRECT_ERR_STAT_REG (PXCESR)*/
- +
- +/* PCI Express Correctable Error Mask Register */
- +/*PEX_CORRECT_ERR_MASK_REG (PXCEMR)*/
- +
- +/* PCI Express Advanced Error Capability and Control Register*/
- +/*PEX_ADV_ERR_CAPABILITY_CTRL_REG (PXAECCR)*/
- +
- +/* PCI Express Header Log First DWORD Register*/
- +/*PEX_HDR_LOG_FIRST_DWORD_REG (PXHLFDR)*/
- +
- +/* PCI Express Header Log Second DWORD Register*/
- +/*PEX_HDR_LOG_SECOND_DWORD_REG (PXHLSDR)*/
- +
- +/* PCI Express Header Log Third DWORD Register*/
- +/*PEX_HDR_LOG_THIRD_DWORD_REG (PXHLTDR)*/
- +
- +/* PCI Express Header Log Fourth DWORD Register*/
- +/*PEX_HDR_LOG_FOURTH_DWORD_REG (PXHLFDR)*/
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* #ifndef __INCPEXREGSH */
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 2010-11-09 20:28:11.822495468 +0100
- @@ -0,0 +1,313 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "mvPex.h"
- +
- +//#define MV_DEBUG
- +/* defines */
- +#ifdef MV_DEBUG
- + #define DB(x) x
- +#else
- + #define DB(x)
- +#endif
- +
- +/* locals */
- +typedef struct
- +{
- + MV_U32 data;
- + MV_U32 mask;
- +}PEX_HEADER_DATA;
- +
- +/* local function forwad decleration */
- +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
- + MV_U32 regOff);
- +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data);
- +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev);
- +
- +
- +PEX_HEADER_DATA configHdr[16] =
- +{
- +{0x888811ab, 0x00000000}, /*[device ID, vendor ID] */
- +{0x00100007, 0x0000ffff}, /*[status register, command register] */
- +{0x0604000e, 0x00000000}, /*[programming interface, sub class code, class code, revision ID] */
- +{0x00010008, 0x00000000}, /*[BIST, header type, latency time, cache line] */
- +{0x00000000, 0x00000000}, /*[base address 0] */
- +{0x00000000, 0x00000000}, /*[base address 1] */
- +{0x00000000, 0x00ffffff}, /*[secondary latency timersubordinate bus number, secondary bus number, primary bus number] */
- +{0x0000f101, 0x00000000}, /*[secondary status ,IO limit, IO base] */
- +{0x9ff0a000, 0x00000000}, /*[memory limit, memory base] */
- +{0x0001fff1, 0x00000000}, /*[prefetch memory limit, prefetch memory base] */
- +{0xffffffff, 0x00000000}, /*[prefetch memory base upper] */
- +{0x00000000, 0x00000000}, /*[prefetch memory limit upper] */
- +{0xeffff000, 0x00000000}, /*[IO limit upper 16 bits, IO base upper 16 bits] */
- +{0x00000000, 0x00000000}, /*[reserved, capability pointer] */
- +{0x00000000, 0x00000000}, /*[expansion ROM base address] */
- +{0x00000000, 0x000000FF}, /*[bridge control, interrupt pin, interrupt line] */
- +};
- +
- +
- +#define HEADER_WRITE(data, offset) configHdr[offset/4].data = ((configHdr[offset/4].data & ~configHdr[offset/4].mask) | \
- + (data & configHdr[offset/4].mask))
- +#define HEADER_READ(offset) configHdr[offset/4].data
- +
- +/*******************************************************************************
- +* mvVrtBrgPexInit - Initialize PEX interfaces
- +*
- +* DESCRIPTION:
- +*
- +* This function is responsible of intialization of the Pex Interface , It
- +* configure the Pex Bars and Windows in the following manner:
- +*
- +* Assumptions :
- +* Bar0 is always internal registers bar
- +* Bar1 is always the DRAM bar
- +* Bar2 is always the Device bar
- +*
- +* 1) Sets the Internal registers bar base by obtaining the base from
- +* the CPU Interface
- +* 2) Sets the DRAM bar base and size by getting the base and size from
- +* the CPU Interface when the size is the sum of all enabled DRAM
- +* chip selects and the base is the base of CS0 .
- +* 3) Sets the Device bar base and size by getting these values from the
- +* CPU Interface when the base is the base of the lowest base of the
- +* Device chip selects, and the
- +*
- +*
- +* INPUT:
- +*
- +* pexIf - PEX interface number.
- +*
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
- +*
- +*******************************************************************************/
- +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf)
- +{
- + /* reset PEX tree to recover previous U-boot/Boot configurations */
- + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
- +
- +
- + resetPexConfig(pexIf, localBus, 1);
- + return MV_OK;
- +}
- +
- +
- +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
- + MV_U32 regOff)
- +{
- +
- + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
- + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
- + MV_U32 val;
- + if(bus == localBus)
- + {
- + if(dev > 1)
- + {
- +/* on the local device allow only device #0 & #1 */
- + return 0xffffffff;
- + }
- + else
- + if (dev == localDev)
- + {
- + /* read the memory controller registers */
- + return mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
- + }
- + else
- + {
- + /* access the virtual brg header */
- + return HEADER_READ(regOff);
- + }
- + }
- + else
- + if(bus == (localBus + 1))
- + {
- + /* access the device behind the virtual bridge */
- + if((dev == localDev) || (dev > 1))
- + {
- + return 0xffffffff;
- + }
- + else
- + {
- + /* access the device behind the virtual bridge, in this case
- + * change the bus number to the local bus number in order to
- + * generate type 0 config cycle
- + */
- + mvPexLocalBusNumSet(pexIf, bus);
- + mvPexLocalDevNumSet(pexIf, 1);
- + val = mvPexHwConfigRead (pexIf, bus, 0, func, regOff);
- + mvPexLocalBusNumSet(pexIf, localBus);
- + mvPexLocalDevNumSet(pexIf, localDev);
- + return val;
- + }
- + }
- + /* for all other devices use the HW function to get the
- + * requested registers
- + */
- + mvPexLocalDevNumSet(pexIf, 1);
- + val = mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
- + mvPexLocalDevNumSet(pexIf, localDev);
- + return val;
- +}
- +
- +
- +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data)
- +{
- + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
- + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
- + MV_STATUS status;
- +
- + if(bus == localBus)
- + {
- + if(dev > 1)
- + {
- + /* on the local device allow only device #0 & #1 */
- + return MV_ERROR;
- + }
- + else
- + if (dev == localDev)
- + {
- + /* read the memory controller registers */
- + return mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
- + }
- + else
- + {
- + /* access the virtual brg header */
- + HEADER_WRITE(data, regOff);
- + return MV_OK;
- + }
- + }
- + else
- + if(bus == (localBus + 1))
- + {
- + /* access the device behind the virtual bridge */
- + if((dev == localDev) || (dev > 1))
- + {
- + return MV_ERROR;
- + }
- + else
- + {
- + /* access the device behind the virtual bridge, in this case
- + * change the bus number to the local bus number in order to
- + * generate type 0 config cycle
- + */
- + //return mvPexHwConfigWrite (pexIf, localBus, dev, func, regOff, data);
- + mvPexLocalBusNumSet(pexIf, bus);
- + mvPexLocalDevNumSet(pexIf, 1);
- + status = mvPexHwConfigWrite (pexIf, bus, 0, func, regOff, data);
- + mvPexLocalBusNumSet(pexIf, localBus);
- + mvPexLocalDevNumSet(pexIf, localDev);
- + return status;
- +
- + }
- + }
- + /* for all other devices use the HW function to get the
- + * requested registers
- + */
- + mvPexLocalDevNumSet(pexIf, 1);
- + status = mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
- + mvPexLocalDevNumSet(pexIf, localDev);
- + return status;
- +}
- +
- +
- +
- +
- +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev)
- +{
- + MV_U32 tData;
- + MV_U32 i;
- +
- + /* restore the PEX configuration to initialization state */
- + /* in case PEX P2P call recursive and reset config */
- + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x0);
- + if(tData != 0xffffffff)
- + {
- + /* agent had been found - check whether P2P */
- + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x8);
- + if((tData & 0xffff0000) == 0x06040000)
- + {/* P2P */
- + /* get the sec bus and the subordinate */
- + MV_U32 secBus;
- + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x18);
- + secBus = ((tData >> 8) & 0xff);
- + /* now scan on sec bus */
- + for(i = 0;i < 0xff;i++)
- + {
- + resetPexConfig(pexIf, secBus, i);
- + }
- + /* now reset this device */
- + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
- + mvPexHwConfigWrite(pexIf, bus, dev, 0x0, 0x18, 0x0);
- + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
- + }
- + }
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 2010-11-09 20:28:11.861239834 +0100
- @@ -0,0 +1,82 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCVRTBRGPEXH
- +#define __INCVRTBRGPEXH
- +
- +
- +/* Global Functions prototypes */
- +/* mvPexInit - Initialize PEX interfaces*/
- +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf);
- +
- +/* mvPexConfigRead - Read from configuration space */
- +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func,MV_U32 regOff);
- +
- +/* mvPexConfigWrite - Write to configuration space */
- +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
- + MV_U32 func, MV_U32 regOff, MV_U32 data);
- +
- +
- +#endif /* #ifndef __INCPEXH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 2010-11-09 20:28:11.901246212 +0100
- @@ -0,0 +1,1522 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#include "mvOs.h"
- +#include "sflash/mvSFlash.h"
- +#include "sflash/mvSFlashSpec.h"
- +#include "spi/mvSpi.h"
- +#include "spi/mvSpiCmnd.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +/*#define MV_DEBUG*/
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +/* Globals */
- +static MV_SFLASH_DEVICE_PARAMS sflash[] = {
- + /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */
- + {
- + MV_M25P_WREN_CMND_OPCD,
- + MV_M25P_WRDI_CMND_OPCD,
- + MV_M25P_RDID_CMND_OPCD,
- + MV_M25P_RDSR_CMND_OPCD,
- + MV_M25P_WRSR_CMND_OPCD,
- + MV_M25P_READ_CMND_OPCD,
- + MV_M25P_FAST_RD_CMND_OPCD,
- + MV_M25P_PP_CMND_OPCD,
- + MV_M25P_SE_CMND_OPCD,
- + MV_M25P_BE_CMND_OPCD,
- + MV_M25P_RES_CMND_OPCD,
- + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
- + MV_M25P32_SECTOR_SIZE,
- + MV_M25P32_SECTOR_NUMBER,
- + MV_M25P_PAGE_SIZE,
- + "ST M25P32",
- + MV_M25PXXX_ST_MANF_ID,
- + MV_M25P32_DEVICE_ID,
- + MV_M25P32_MAX_SPI_FREQ,
- + MV_M25P32_MAX_FAST_SPI_FREQ,
- + MV_M25P32_FAST_READ_DUMMY_BYTES
- + },
- + /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */
- + {
- + MV_M25P_WREN_CMND_OPCD,
- + MV_M25P_WRDI_CMND_OPCD,
- + MV_M25P_RDID_CMND_OPCD,
- + MV_M25P_RDSR_CMND_OPCD,
- + MV_M25P_WRSR_CMND_OPCD,
- + MV_M25P_READ_CMND_OPCD,
- + MV_M25P_FAST_RD_CMND_OPCD,
- + MV_M25P_PP_CMND_OPCD,
- + MV_M25P_SE_CMND_OPCD,
- + MV_M25P_BE_CMND_OPCD,
- + MV_M25P_RES_CMND_OPCD,
- + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
- + MV_M25P64_SECTOR_SIZE,
- + MV_M25P64_SECTOR_NUMBER,
- + MV_M25P_PAGE_SIZE,
- + "ST M25P64",
- + MV_M25PXXX_ST_MANF_ID,
- + MV_M25P64_DEVICE_ID,
- + MV_M25P64_MAX_SPI_FREQ,
- + MV_M25P64_MAX_FAST_SPI_FREQ,
- + MV_M25P64_FAST_READ_DUMMY_BYTES
- + },
- + /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */
- + {
- + MV_M25P_WREN_CMND_OPCD,
- + MV_M25P_WRDI_CMND_OPCD,
- + MV_M25P_RDID_CMND_OPCD,
- + MV_M25P_RDSR_CMND_OPCD,
- + MV_M25P_WRSR_CMND_OPCD,
- + MV_M25P_READ_CMND_OPCD,
- + MV_M25P_FAST_RD_CMND_OPCD,
- + MV_M25P_PP_CMND_OPCD,
- + MV_M25P_SE_CMND_OPCD,
- + MV_M25P_BE_CMND_OPCD,
- + MV_M25P_RES_CMND_OPCD,
- + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
- + MV_M25P128_SECTOR_SIZE,
- + MV_M25P128_SECTOR_NUMBER,
- + MV_M25P_PAGE_SIZE,
- + "ST M25P128",
- + MV_M25PXXX_ST_MANF_ID,
- + MV_M25P128_DEVICE_ID,
- + MV_M25P128_MAX_SPI_FREQ,
- + MV_M25P128_MAX_FAST_SPI_FREQ,
- + MV_M25P128_FAST_READ_DUMMY_BYTES
- + },
- + /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */
- + {
- + MV_MX25L_WREN_CMND_OPCD,
- + MV_MX25L_WRDI_CMND_OPCD,
- + MV_MX25L_RDID_CMND_OPCD,
- + MV_MX25L_RDSR_CMND_OPCD,
- + MV_MX25L_WRSR_CMND_OPCD,
- + MV_MX25L_READ_CMND_OPCD,
- + MV_MX25L_FAST_RD_CMND_OPCD,
- + MV_MX25L_PP_CMND_OPCD,
- + MV_MX25L_SE_CMND_OPCD,
- + MV_MX25L_BE_CMND_OPCD,
- + MV_MX25L_RES_CMND_OPCD,
- + MV_MX25L_DP_CMND_OPCD,
- + MV_MX25L6405_SECTOR_SIZE,
- + MV_MX25L6405_SECTOR_NUMBER,
- + MV_MXIC_PAGE_SIZE,
- + "MXIC MX25L6405",
- + MV_MXIC_MANF_ID,
- + MV_MX25L6405_DEVICE_ID,
- + MV_MX25L6405_MAX_SPI_FREQ,
- + MV_MX25L6405_MAX_FAST_SPI_FREQ,
- + MV_MX25L6405_FAST_READ_DUMMY_BYTES
- + },
- + /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */
- + {
- + MV_S25FL_WREN_CMND_OPCD,
- + MV_S25FL_WRDI_CMND_OPCD,
- + MV_S25FL_RDID_CMND_OPCD,
- + MV_S25FL_RDSR_CMND_OPCD,
- + MV_S25FL_WRSR_CMND_OPCD,
- + MV_S25FL_READ_CMND_OPCD,
- + MV_S25FL_FAST_RD_CMND_OPCD,
- + MV_S25FL_PP_CMND_OPCD,
- + MV_S25FL_SE_CMND_OPCD,
- + MV_S25FL_BE_CMND_OPCD,
- + MV_S25FL_RES_CMND_OPCD,
- + MV_S25FL_DP_CMND_OPCD,
- + MV_S25FL128_SECTOR_SIZE,
- + MV_S25FL128_SECTOR_NUMBER,
- + MV_S25FL_PAGE_SIZE,
- + "SPANSION S25FL128",
- + MV_SPANSION_MANF_ID,
- + MV_S25FL128_DEVICE_ID,
- + MV_S25FL128_MAX_SPI_FREQ,
- + MV_M25P128_MAX_FAST_SPI_FREQ,
- + MV_M25P128_FAST_READ_DUMMY_BYTES
- + }
- +};
- +
- +/* Static Functions */
- +static MV_STATUS mvWriteEnable (MV_SFLASH_INFO * pFlinfo);
- +static MV_STATUS mvStatusRegGet (MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg);
- +static MV_STATUS mvStatusRegSet (MV_SFLASH_INFO * pFlinfo, MV_U8 sr);
- +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo);
- +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset, \
- + MV_U8* pPageBuff, MV_U32 buffSize);
- +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, \
- + MV_U8* manId, MV_U16* devId);
- +
- +/*******************************************************************************
- +* mvWriteEnable - serialize the write enable sequence
- +*
- +* DESCRIPTION:
- +* transmit the sequence for write enable
- +*
- +********************************************************************************/
- +static MV_STATUS mvWriteEnable(MV_SFLASH_INFO * pFlinfo)
- +{
- + MV_U8 cmd[MV_SFLASH_WREN_CMND_LENGTH];
- +
- +
- + cmd[0] = sflash[pFlinfo->index].opcdWREN;
- +
- + return mvSpiWriteThenRead(cmd, MV_SFLASH_WREN_CMND_LENGTH, NULL, 0, 0);
- +}
- +
- +/*******************************************************************************
- +* mvStatusRegGet - Retrieve the value of the status register
- +*
- +* DESCRIPTION:
- +* perform the RDSR sequence to get the 8bit status register
- +*
- +********************************************************************************/
- +static MV_STATUS mvStatusRegGet(MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_RDSR_CMND_LENGTH];
- + MV_U8 sr[MV_SFLASH_RDSR_REPLY_LENGTH];
- +
- +
- +
- +
- + cmd[0] = sflash[pFlinfo->index].opcdRDSR;
- +
- + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDSR_CMND_LENGTH, sr,
- + MV_SFLASH_RDSR_REPLY_LENGTH,0)) != MV_OK)
- + return ret;
- +
- + *pStatReg = sr[0];
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared
- +*
- +* DESCRIPTION:
- +* Block waiting for the WIP (write in progress) to be cleared
- +*
- +********************************************************************************/
- +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo)
- +{
- + MV_STATUS ret;
- + MV_U32 i;
- + MV_U8 stat;
- +
- + for (i=0; i<MV_SFLASH_MAX_WAIT_LOOP; i++)
- + {
- + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
- + return ret;
- +
- + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
- + return MV_OK;
- + }
- +
- + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
- + return MV_TIMEOUT;
- +}
- +
- +/*******************************************************************************
- +* mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be
- +* cleared after a chip erase command which is supposed
- +* to take about 2:30 minutes
- +*
- +* DESCRIPTION:
- +* Block waiting for the WIP (write in progress) to be cleared
- +*
- +********************************************************************************/
- +static MV_STATUS mvWaitOnChipEraseDone(MV_SFLASH_INFO * pFlinfo)
- +{
- + MV_STATUS ret;
- + MV_U32 i;
- + MV_U8 stat;
- +
- + for (i=0; i<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP; i++)
- + {
- + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
- + return ret;
- +
- + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
- + return MV_OK;
- + }
- +
- + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
- + return MV_TIMEOUT;
- +}
- +
- +/*******************************************************************************
- +* mvStatusRegSet - Set the value of the 8bit status register
- +*
- +* DESCRIPTION:
- +* Set the value of the 8bit status register
- +*
- +********************************************************************************/
- +static MV_STATUS mvStatusRegSet(MV_SFLASH_INFO * pFlinfo, MV_U8 sr)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_WRSR_CMND_LENGTH];
- +
- +
- + /* Issue the Write enable command prior the WRSR command */
- + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
- + return ret;
- +
- + /* Write the SR with the new values */
- + cmd[0] = sflash[pFlinfo->index].opcdWRSR;
- + cmd[1] = sr;
- +
- + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_WRSR_CMND_LENGTH, NULL, 0, 0)) != MV_OK)
- + return ret;
- +
- + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
- + return ret;
- +
- + mvOsDelay(1);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashPageWr - Write up to 256 Bytes in the same page
- +*
- +* DESCRIPTION:
- +* Write a buffer up to the page size in length provided that the whole address
- +* range is within the same page (alligned to page bounderies)
- +*
- +*******************************************************************************/
- +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
- + MV_U8* pPageBuff, MV_U32 buffSize)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_PP_CMND_LENGTH];
- +
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* check that we do not cross the page bounderies */
- + if (((offset & (sflash[pFlinfo->index].pageSize - 1)) + buffSize) >
- + sflash[pFlinfo->index].pageSize)
- + {
- + DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__);)
- + return MV_OUT_OF_RANGE;
- + }
- +
- + /* Issue the Write enable command prior the page program command */
- + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
- + return ret;
- +
- + cmd[0] = sflash[pFlinfo->index].opcdPP;
- + cmd[1] = ((offset >> 16) & 0xFF);
- + cmd[2] = ((offset >> 8) & 0xFF);
- + cmd[3] = (offset & 0xFF);
- +
- + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_PP_CMND_LENGTH, pPageBuff, buffSize)) != MV_OK)
- + return ret;
- +
- + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
- + return ret;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from
- +* the device using the default RDID opcode and the default WREN opcode.
- +*
- +* DESCRIPTION:
- +* This is used to detect a generic device that uses the default opcodes
- +* for the WREN and RDID.
- +*
- +********************************************************************************/
- +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* manId, MV_U16* devId)
- +{
- + MV_STATUS ret;
- + MV_U8 cmdRDID[MV_SFLASH_RDID_CMND_LENGTH];
- + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
- +
- +
- +
- + /* Use the default RDID opcode to read the IDs */
- + cmdRDID[0] = MV_SFLASH_DEFAULT_RDID_OPCD; /* unknown model try default */
- + if ((ret = mvSpiWriteThenRead(cmdRDID, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
- + return ret;
- +
- + *manId = id[0];
- + *devId = 0;
- + *devId |= (id[1] << 8);
- + *devId |= id[2];
- +
- + return MV_OK;
- +}
- +
- +/*
- +#####################################################################################
- +#####################################################################################
- +*/
- +
- +/*******************************************************************************
- +* mvSFlashInit - Initialize the serial flash device
- +*
- +* DESCRIPTION:
- +* Perform the neccessary initialization and configuration
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* pFlinfo->baseAddr: base address in fast mode.
- +* pFlinfo->index: Index of the flash in the sflash tabel. If the SPI
- +* flash device does not support read Id command with
- +* the standard opcode, then the user should supply this
- +* as an input to skip the autodetection process!!!!
- +*
- +* OUTPUT:
- +* pFlinfo: pointer to the Flash information structure after detection
- +* pFlinfo->manufacturerId: Manufacturer ID
- +* pFlinfo->deviceId: Device ID
- +* pFlinfo->sectorSize: size of the sector (all sectors are the same).
- +* pFlinfo->sectorNumber: number of sectors.
- +* pFlinfo->pageSize: size of the page.
- +* pFlinfo->index: Index of the detected flash in the sflash tabel
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo)
- +{
- + MV_STATUS ret;
- + MV_U8 manf;
- + MV_U16 dev;
- + MV_U32 indx;
- + MV_BOOL detectFlag = MV_FALSE;
- +
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */
- + if ((ret = mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ)) != MV_OK)
- + {
- + mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__);
- + return ret;
- + }
- +
- + /* First try to read the Manufacturer and Device IDs */
- + if ((ret = mvSFlashIdGet(pFlinfo, &manf, &dev)) != MV_OK)
- + {
- + mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__);
- + return ret;
- + }
- +
- + /* loop over the whole table and look for the appropriate SFLASH */
- + for (indx=0; indx<MV_ARRAY_SIZE(sflash); indx++)
- + {
- + if ((manf == sflash[indx].manufacturerId) && (dev == sflash[indx].deviceId))
- + {
- + pFlinfo->manufacturerId = manf;
- + pFlinfo->deviceId = dev;
- + pFlinfo->index = indx;
- + detectFlag = MV_TRUE;
- + }
- + }
- +
- + if(!detectFlag)
- + {
- + mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__);
- + return MV_FAIL;
- + }
- +
- + /* fill the info based on the model detected */
- + pFlinfo->sectorSize = sflash[pFlinfo->index].sectorSize;
- + pFlinfo->sectorNumber = sflash[pFlinfo->index].sectorNumber;
- + pFlinfo->pageSize = sflash[pFlinfo->index].pageSize;
- +
- + /* Set the SPI frequency to the MAX allowed for the device for best performance */
- + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
- + {
- + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
- + return ret;
- + }
- +
- + /* As default lock the SR */
- + if ((ret = mvSFlashStatRegLock(pFlinfo, MV_TRUE)) != MV_OK)
- + return ret;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashSectorErase - Erasse a single sector of the serial flash
- +*
- +* DESCRIPTION:
- +* Issue the erase sector command and address
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* secNumber: sector Number to erase (0 -> (sectorNumber-1))
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_SE_CMND_LENGTH];
- +
- + MV_U32 secAddr = (secNumber * pFlinfo->sectorSize);
- +#if 0
- + MV_U32 i;
- + MV_U32 * pW = (MV_U32*) (secAddr + pFlinfo->baseAddr);
- + MV_U32 erasedWord = 0xFFFFFFFF;
- + MV_U32 wordsPerSector = (pFlinfo->sectorSize / sizeof(MV_U32));
- + MV_BOOL eraseNeeded = MV_FALSE;
- +#endif
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* check that the sector number is valid */
- + if (secNumber >= pFlinfo->sectorNumber)
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* we don't want to access SPI in direct mode from in-direct API,
- + becasue of timing issue between CS asserts. */
- +#if 0
- + /* First compare to FF and check if erase is needed */
- + for (i=0; i<wordsPerSector; i++)
- + {
- + if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)
- + {
- + eraseNeeded = MV_TRUE;
- + break;
- + }
- +
- + ++pW;
- + }
- + if (!eraseNeeded)
- + return MV_OK;
- +#endif
- +
- + cmd[0] = sflash[pFlinfo->index].opcdSE;
- + cmd[1] = ((secAddr >> 16) & 0xFF);
- + cmd[2] = ((secAddr >> 8) & 0xFF);
- + cmd[3] = (secAddr & 0xFF);
- +
- + /* Issue the Write enable command prior the sector erase command */
- + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
- + return ret;
- +
- + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_SE_CMND_LENGTH, NULL, 0)) != MV_OK)
- + return ret;
- +
- + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
- + return ret;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashChipErase - Erasse the whole serial flash
- +*
- +* DESCRIPTION:
- +* Issue the bulk (chip) erase command
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_BE_CMND_LENGTH];
- +
- +
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + cmd[0] = sflash[pFlinfo->index].opcdBE;
- +
- + /* Issue the Write enable command prior the Bulk erase command */
- + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
- + return ret;
- +
- + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_BE_CMND_LENGTH, NULL, 0)) != MV_OK)
- + return ret;
- +
- + if ((ret = mvWaitOnChipEraseDone(pFlinfo)) != MV_OK)
- + return ret;
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashBlockRd - Read from the serial flash
- +*
- +* DESCRIPTION:
- +* Issue the read command and address then perfom the needed read
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* offset: byte offset with the flash to start reading from
- +* pReadBuff: pointer to the buffer to read the data in
- +* buffSize: size of the buffer to read.
- +*
- +* OUTPUT:
- +* pReadBuff: pointer to the buffer containing the read data
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
- + MV_U8* pReadBuff, MV_U32 buffSize)
- +{
- + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
- +
- +
- + /* check for NULL pointer */
- + if ((pFlinfo == NULL) || (pReadBuff == NULL))
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + cmd[0] = sflash[pFlinfo->index].opcdREAD;
- + cmd[1] = ((offset >> 16) & 0xFF);
- + cmd[2] = ((offset >> 8) & 0xFF);
- + cmd[3] = (offset & 0xFF);
- +
- + return mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize, 0);
- +}
- +
- +/*******************************************************************************
- +* mvSFlashFastBlockRd - Fast read from the serial flash
- +*
- +* DESCRIPTION:
- +* Issue the fast read command and address then perfom the needed read
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* offset: byte offset with the flash to start reading from
- +* pReadBuff: pointer to the buffer to read the data in
- +* buffSize: size of the buffer to read.
- +*
- +* OUTPUT:
- +* pReadBuff: pointer to the buffer containing the read data
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
- + MV_U8* pReadBuff, MV_U32 buffSize)
- +{
- + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
- + MV_STATUS ret;
- +
- + /* check for NULL pointer */
- + if ((pFlinfo == NULL) || (pReadBuff == NULL))
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* Set the SPI frequency to the MAX allowed for fast-read operations */
- + mvOsPrintf("Setting freq to %d.\n",sflash[pFlinfo->index].spiMaxFastFreq);
- + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFastFreq)) != MV_OK)
- + {
- + mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__);
- + return ret;
- + }
- +
- + cmd[0] = sflash[pFlinfo->index].opcdFSTRD;
- + cmd[1] = ((offset >> 16) & 0xFF);
- + cmd[2] = ((offset >> 8) & 0xFF);
- + cmd[3] = (offset & 0xFF);
- +
- +
- + ret = mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize,
- + sflash[pFlinfo->index].spiFastRdDummyBytes);
- +
- + /* Reset the SPI frequency to the MAX allowed for the device for best performance */
- + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
- + {
- + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
- + return ret;
- + }
- +
- + return ret;
- +}
- +
- +
- +/*******************************************************************************
- +* mvSFlashBlockWr - Write a buffer with any size
- +*
- +* DESCRIPTION:
- +* write regardless of the page boundaries and size limit per Page
- +* program command
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* offset: byte offset within the flash region
- +* pWriteBuff: pointer to the buffer holding the data to program
- +* buffSize: size of the buffer to write
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
- + MV_U8* pWriteBuff, MV_U32 buffSize)
- +{
- + MV_STATUS ret;
- + MV_U32 data2write = buffSize;
- + MV_U32 preAllOffset = (offset & MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE));
- + MV_U32 preAllSz = (preAllOffset ? (MV_M25P_PAGE_SIZE - preAllOffset) : 0);
- + MV_U32 writeOffset = offset;
- +
- + /* check for NULL pointer */
- +#ifndef CONFIG_MARVELL
- + if(NULL == pWriteBuff)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +#endif
- +
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* check that the buffer size does not exceed the flash size */
- + if ((offset + buffSize) > mvSFlashSizeGet(pFlinfo))
- + {
- + DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__);)
- + return MV_OUT_OF_RANGE;
- + }
- +
- + /* check if the total block size is less than the first chunk remainder */
- + if (data2write < preAllSz)
- + preAllSz = data2write;
- +
- + /* check if programing does not start at a 64byte alligned offset */
- + if (preAllSz)
- + {
- + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, preAllSz)) != MV_OK)
- + return ret;
- +
- + /* increment pointers and counters */
- + writeOffset += preAllSz;
- + data2write -= preAllSz;
- + pWriteBuff += preAllSz;
- + }
- +
- + /* program the data that fits in complete page chunks */
- + while (data2write >= sflash[pFlinfo->index].pageSize)
- + {
- + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, sflash[pFlinfo->index].pageSize)) != MV_OK)
- + return ret;
- +
- + /* increment pointers and counters */
- + writeOffset += sflash[pFlinfo->index].pageSize;
- + data2write -= sflash[pFlinfo->index].pageSize;
- + pWriteBuff += sflash[pFlinfo->index].pageSize;
- + }
- +
- + /* program the last partial chunk */
- + if (data2write)
- + {
- + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, data2write)) != MV_OK)
- + return ret;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashIdGet - Get the manufacturer and device IDs.
- +*
- +* DESCRIPTION:
- +* Get the Manufacturer and device IDs from the serial flash through
- +* writing the RDID command then reading 3 bytes of data. In case that
- +* this command was called for the first time in order to detect the
- +* manufacturer and device IDs, then the default RDID opcode will be used
- +* unless the device index is indicated by the user (in case the SPI flash
- +* does not use the default RDID opcode).
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* pManId: pointer to the 8bit variable to hold the manufacturing ID
- +* pDevId: pointer to the 16bit variable to hold the device ID
- +*
- +* OUTPUT:
- +* pManId: pointer to the 8bit variable holding the manufacturing ID
- +* pDevId: pointer to the 16bit variable holding the device ID
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_RDID_CMND_LENGTH];
- + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
- +
- +
- +
- + /* check for NULL pointer */
- + if ((pFlinfo == NULL) || (pManId == NULL) || (pDevId == NULL))
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + return mvSFlashWithDefaultsIdGet(pFlinfo, pManId, pDevId);
- + else
- + cmd[0] = sflash[pFlinfo->index].opcdRDID;
- +
- + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
- + return ret;
- +
- + *pManId = id[0];
- + *pDevId = 0;
- + *pDevId |= (id[1] << 8);
- + *pDevId |= id[2];
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashWpRegionSet - Set the Write-Protected region
- +*
- +* DESCRIPTION:
- +* Set the Write-Protected region
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* wpRegion: which region will be protected
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion)
- +{
- + MV_U8 wpMask;
- +
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check if the chip is an ST flash; then WP supports only 3 bits */
- + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
- + {
- + switch (wpRegion)
- + {
- + case MV_WP_NONE:
- + wpMask = MV_M25P_STATUS_BP_NONE;
- + break;
- +
- + case MV_WP_UPR_1OF128:
- + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
- + return MV_NOT_SUPPORTED;
- +
- + case MV_WP_UPR_1OF64:
- + wpMask = MV_M25P_STATUS_BP_1_OF_64;
- + break;
- +
- + case MV_WP_UPR_1OF32:
- + wpMask = MV_M25P_STATUS_BP_1_OF_32;
- + break;
- +
- + case MV_WP_UPR_1OF16:
- + wpMask = MV_M25P_STATUS_BP_1_OF_16;
- + break;
- +
- + case MV_WP_UPR_1OF8:
- + wpMask = MV_M25P_STATUS_BP_1_OF_8;
- + break;
- +
- + case MV_WP_UPR_1OF4:
- + wpMask = MV_M25P_STATUS_BP_1_OF_4;
- + break;
- +
- + case MV_WP_UPR_1OF2:
- + wpMask = MV_M25P_STATUS_BP_1_OF_2;
- + break;
- +
- + case MV_WP_ALL:
- + wpMask = MV_M25P_STATUS_BP_ALL;
- + break;
- +
- + default:
- + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- + }
- + /* check if the manufacturer is MXIC then the WP is 4bits */
- + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
- + {
- + switch (wpRegion)
- + {
- + case MV_WP_NONE:
- + wpMask = MV_MX25L_STATUS_BP_NONE;
- + break;
- +
- + case MV_WP_UPR_1OF128:
- + wpMask = MV_MX25L_STATUS_BP_1_OF_128;
- + break;
- +
- + case MV_WP_UPR_1OF64:
- + wpMask = MV_MX25L_STATUS_BP_1_OF_64;
- + break;
- +
- + case MV_WP_UPR_1OF32:
- + wpMask = MV_MX25L_STATUS_BP_1_OF_32;
- + break;
- +
- + case MV_WP_UPR_1OF16:
- + wpMask = MV_MX25L_STATUS_BP_1_OF_16;
- + break;
- +
- + case MV_WP_UPR_1OF8:
- + wpMask = MV_MX25L_STATUS_BP_1_OF_8;
- + break;
- +
- + case MV_WP_UPR_1OF4:
- + wpMask = MV_MX25L_STATUS_BP_1_OF_4;
- + break;
- +
- + case MV_WP_UPR_1OF2:
- + wpMask = MV_MX25L_STATUS_BP_1_OF_2;
- + break;
- +
- + case MV_WP_ALL:
- + wpMask = MV_MX25L_STATUS_BP_ALL;
- + break;
- +
- + default:
- + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- + }
- + /* check if the manufacturer is SPANSION then the WP is 4bits */
- + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
- + {
- + switch (wpRegion)
- + {
- + case MV_WP_NONE:
- + wpMask = MV_S25FL_STATUS_BP_NONE;
- + break;
- +
- + case MV_WP_UPR_1OF128:
- + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
- + return MV_NOT_SUPPORTED;
- +
- + case MV_WP_UPR_1OF64:
- + wpMask = MV_S25FL_STATUS_BP_1_OF_64;
- + break;
- +
- + case MV_WP_UPR_1OF32:
- + wpMask = MV_S25FL_STATUS_BP_1_OF_32;
- + break;
- +
- + case MV_WP_UPR_1OF16:
- + wpMask = MV_S25FL_STATUS_BP_1_OF_16;
- + break;
- +
- + case MV_WP_UPR_1OF8:
- + wpMask = MV_S25FL_STATUS_BP_1_OF_8;
- + break;
- +
- + case MV_WP_UPR_1OF4:
- + wpMask = MV_S25FL_STATUS_BP_1_OF_4;
- + break;
- +
- + case MV_WP_UPR_1OF2:
- + wpMask = MV_S25FL_STATUS_BP_1_OF_2;
- + break;
- +
- + case MV_WP_ALL:
- + wpMask = MV_S25FL_STATUS_BP_ALL;
- + break;
- +
- +
- + default:
- + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- + }
- + else
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* Verify that the SRWD bit is always set - register is s/w locked */
- + wpMask |= MV_SFLASH_STATUS_REG_SRWD_MASK;
- +
- + return mvStatusRegSet(pFlinfo, wpMask);
- +}
- +
- +/*******************************************************************************
- +* mvSFlashWpRegionGet - Get the Write-Protected region configured
- +*
- +* DESCRIPTION:
- +* Get from the chip the Write-Protected region configured
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* pWpRegion: pointer to the variable to return the WP region in
- +*
- +* OUTPUT:
- +* wpRegion: pointer to the variable holding the WP region configured
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion)
- +{
- + MV_STATUS ret;
- + MV_U8 reg;
- +
- + /* check for NULL pointer */
- + if ((pFlinfo == NULL) || (pWpRegion == NULL))
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + if ((ret = mvStatusRegGet(pFlinfo, ®)) != MV_OK)
- + return ret;
- +
- + /* Check if the chip is an ST flash; then WP supports only 3 bits */
- + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
- + {
- + switch ((reg & MV_M25P_STATUS_REG_WP_MASK))
- + {
- + case MV_M25P_STATUS_BP_NONE:
- + *pWpRegion = MV_WP_NONE;
- + break;
- +
- + case MV_M25P_STATUS_BP_1_OF_64:
- + *pWpRegion = MV_WP_UPR_1OF64;
- + break;
- +
- + case MV_M25P_STATUS_BP_1_OF_32:
- + *pWpRegion = MV_WP_UPR_1OF32;
- + break;
- +
- + case MV_M25P_STATUS_BP_1_OF_16:
- + *pWpRegion = MV_WP_UPR_1OF16;
- + break;
- +
- + case MV_M25P_STATUS_BP_1_OF_8:
- + *pWpRegion = MV_WP_UPR_1OF8;
- + break;
- +
- + case MV_M25P_STATUS_BP_1_OF_4:
- + *pWpRegion = MV_WP_UPR_1OF4;
- + break;
- +
- + case MV_M25P_STATUS_BP_1_OF_2:
- + *pWpRegion = MV_WP_UPR_1OF2;
- + break;
- +
- + case MV_M25P_STATUS_BP_ALL:
- + *pWpRegion = MV_WP_ALL;
- + break;
- +
- + default:
- + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
- + return MV_BAD_VALUE;
- + }
- + }
- + /* check if the manufacturer is MXIC then the WP is 4bits */
- + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
- + {
- + switch ((reg & MV_MX25L_STATUS_REG_WP_MASK))
- + {
- + case MV_MX25L_STATUS_BP_NONE:
- + *pWpRegion = MV_WP_NONE;
- + break;
- +
- + case MV_MX25L_STATUS_BP_1_OF_128:
- + *pWpRegion = MV_WP_UPR_1OF128;
- + break;
- +
- + case MV_MX25L_STATUS_BP_1_OF_64:
- + *pWpRegion = MV_WP_UPR_1OF64;
- + break;
- +
- + case MV_MX25L_STATUS_BP_1_OF_32:
- + *pWpRegion = MV_WP_UPR_1OF32;
- + break;
- +
- + case MV_MX25L_STATUS_BP_1_OF_16:
- + *pWpRegion = MV_WP_UPR_1OF16;
- + break;
- +
- + case MV_MX25L_STATUS_BP_1_OF_8:
- + *pWpRegion = MV_WP_UPR_1OF8;
- + break;
- +
- + case MV_MX25L_STATUS_BP_1_OF_4:
- + *pWpRegion = MV_WP_UPR_1OF4;
- + break;
- +
- + case MV_MX25L_STATUS_BP_1_OF_2:
- + *pWpRegion = MV_WP_UPR_1OF2;
- + break;
- +
- + case MV_MX25L_STATUS_BP_ALL:
- + *pWpRegion = MV_WP_ALL;
- + break;
- +
- + default:
- + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
- + return MV_BAD_VALUE;
- + }
- + }
- + /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */
- + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
- + {
- + switch ((reg & MV_S25FL_STATUS_REG_WP_MASK))
- + {
- + case MV_S25FL_STATUS_BP_NONE:
- + *pWpRegion = MV_WP_NONE;
- + break;
- +
- + case MV_S25FL_STATUS_BP_1_OF_64:
- + *pWpRegion = MV_WP_UPR_1OF64;
- + break;
- +
- + case MV_S25FL_STATUS_BP_1_OF_32:
- + *pWpRegion = MV_WP_UPR_1OF32;
- + break;
- +
- + case MV_S25FL_STATUS_BP_1_OF_16:
- + *pWpRegion = MV_WP_UPR_1OF16;
- + break;
- +
- + case MV_S25FL_STATUS_BP_1_OF_8:
- + *pWpRegion = MV_WP_UPR_1OF8;
- + break;
- +
- + case MV_S25FL_STATUS_BP_1_OF_4:
- + *pWpRegion = MV_WP_UPR_1OF4;
- + break;
- +
- + case MV_S25FL_STATUS_BP_1_OF_2:
- + *pWpRegion = MV_WP_UPR_1OF2;
- + break;
- +
- + case MV_S25FL_STATUS_BP_ALL:
- + *pWpRegion = MV_WP_ALL;
- + break;
- +
- + default:
- + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
- + return MV_BAD_VALUE;
- + }
- + }
- + else
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSFlashStatRegLock - Lock the status register for writing - W/Vpp
- +* pin should be low to take effect
- +*
- +* DESCRIPTION:
- +* Lock the access to the Status Register for writing. This will
- +* cause the flash to enter the hardware protection mode if the W/Vpp
- +* is low. If the W/Vpp is hi, the chip will be in soft protection mode, but
- +* the register will continue to be writable if WREN sequence was used.
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +* srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock)
- +{
- + MV_STATUS ret;
- + MV_U8 reg;
- +
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + if ((ret = mvStatusRegGet(pFlinfo, ®)) != MV_OK)
- + return ret;
- +
- + if (srLock)
- + reg |= MV_SFLASH_STATUS_REG_SRWD_MASK;
- + else
- + reg &= ~MV_SFLASH_STATUS_REG_SRWD_MASK;
- +
- + return mvStatusRegSet(pFlinfo, reg);
- +}
- +
- +/*******************************************************************************
- +* mvSFlashSizeGet - Get the size of the SPI flash
- +*
- +* DESCRIPTION:
- +* based on the sector number and size of each sector calculate the total
- +* size of the flash memory.
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Size of the flash in bytes.
- +*
- +*
- +*******************************************************************************/
- +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo)
- +{
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return 0;
- + }
- +
- + return (pFlinfo->sectorSize * pFlinfo->sectorNumber);
- +}
- +
- +/*******************************************************************************
- +* mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode
- +*
- +* DESCRIPTION:
- +* Enter a special power save mode.
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Size of the flash in bytes.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_DP_CMND_LENGTH];
- +
- +
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return 0;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* check that power save mode is supported in the specific device */
- + if (sflash[pFlinfo->index].opcdPwrSave == MV_SFLASH_NO_SPECIFIC_OPCD)
- + {
- + DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__);)
- + return MV_NOT_SUPPORTED;
- + }
- +
- + cmd[0] = sflash[pFlinfo->index].opcdPwrSave;
- +
- + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_DP_CMND_LENGTH, NULL, 0)) != MV_OK)
- + return ret;
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode
- +*
- +* DESCRIPTION:
- +* Exit the deep power save mode.
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Size of the flash in bytes.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo)
- +{
- + MV_STATUS ret;
- + MV_U8 cmd[MV_SFLASH_RES_CMND_LENGTH];
- +
- +
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return 0;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return MV_BAD_PARAM;
- + }
- +
- + /* check that power save mode is supported in the specific device */
- + if (sflash[pFlinfo->index].opcdRES == MV_SFLASH_NO_SPECIFIC_OPCD)
- + {
- + DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__);)
- + return MV_NOT_SUPPORTED;
- + }
- +
- + cmd[0] = sflash[pFlinfo->index].opcdRES;
- +
- + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_RES_CMND_LENGTH, NULL, 0)) != MV_OK)
- + return ret;
- +
- + /* add the delay needed for the device to wake up */
- + mvOsDelay(MV_MXIC_DP_EXIT_DELAY); /* 30 ms */
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvSFlashModelGet - Retreive the string with the device manufacturer and model
- +*
- +* DESCRIPTION:
- +* Retreive the string with the device manufacturer and model
- +*
- +* INPUT:
- +* pFlinfo: pointer to the Flash information structure
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* pointer to the string indicating the device manufacturer and model
- +*
- +*
- +*******************************************************************************/
- +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo)
- +{
- + static const MV_8 * unknModel = (const MV_8 *)"Unknown";
- +
- + /* check for NULL pointer */
- + if (pFlinfo == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return 0;
- + }
- +
- + /* Protection - check if the model was detected */
- + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
- + {
- + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
- + return unknModel;
- + }
- +
- + return sflash[pFlinfo->index].deviceModel;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 2010-11-09 20:28:11.941246441 +0100
- @@ -0,0 +1,166 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSFlashH
- +#define __INCmvSFlashH
- +
- +#include "mvTypes.h"
- +
- +/* MCAROS */
- +#define MV_SFLASH_PAGE_ALLIGN_MASK(pgSz) (pgSz-1)
- +#define MV_ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))
- +
- +/* Constants */
- +#define MV_INVALID_DEVICE_NUMBER 0xFFFFFFFF
- +/* 10 MHz is the minimum possible SPI frequency when tclk is set 200MHz*/
- +#define MV_SFLASH_BASIC_SPI_FREQ 10000000
- +/* enumerations */
- +typedef enum
- +{
- + MV_WP_NONE, /* Unprotect the whole chip */
- + MV_WP_UPR_1OF128, /* Write protect the upper 1/128 part */
- + MV_WP_UPR_1OF64, /* Write protect the upper 1/64 part */
- + MV_WP_UPR_1OF32, /* Write protect the upper 1/32 part */
- + MV_WP_UPR_1OF16, /* Write protect the upper 1/16 part */
- + MV_WP_UPR_1OF8, /* Write protect the upper 1/8 part */
- + MV_WP_UPR_1OF4, /* Write protect the upper 1/4 part */
- + MV_WP_UPR_1OF2, /* Write protect the upper 1/2 part */
- + MV_WP_ALL /* Write protect the whole chip */
- +} MV_SFLASH_WP_REGION;
- +
- +/* Type Definitions */
- +typedef struct
- +{
- + MV_U8 opcdWREN; /* Write enable opcode */
- + MV_U8 opcdWRDI; /* Write disable opcode */
- + MV_U8 opcdRDID; /* Read ID opcode */
- + MV_U8 opcdRDSR; /* Read Status Register opcode */
- + MV_U8 opcdWRSR; /* Write Status register opcode */
- + MV_U8 opcdREAD; /* Read opcode */
- + MV_U8 opcdFSTRD; /* Fast Read opcode */
- + MV_U8 opcdPP; /* Page program opcode */
- + MV_U8 opcdSE; /* Sector erase opcode */
- + MV_U8 opcdBE; /* Bulk erase opcode */
- + MV_U8 opcdRES; /* Read electronic signature */
- + MV_U8 opcdPwrSave; /* Go into power save mode */
- + MV_U32 sectorSize; /* Size of each sector */
- + MV_U32 sectorNumber; /* Number of sectors */
- + MV_U32 pageSize; /* size of each page */
- + const char * deviceModel; /* string with the device model */
- + MV_U32 manufacturerId; /* The manufacturer ID */
- + MV_U32 deviceId; /* Device ID */
- + MV_U32 spiMaxFreq; /* The MAX frequency that can be used with the device */
- + MV_U32 spiMaxFastFreq; /* The MAX frequency that can be used with the device for fast reads */
- + MV_U32 spiFastRdDummyBytes; /* Number of dumy bytes to read before real data when working in fast read mode. */
- +} MV_SFLASH_DEVICE_PARAMS;
- +
- +typedef struct
- +{
- + MV_U32 baseAddr; /* Flash Base Address used in fast mode */
- + MV_U8 manufacturerId; /* Manufacturer ID */
- + MV_U16 deviceId; /* Device ID */
- + MV_U32 sectorSize; /* Size of each sector - all the same */
- + MV_U32 sectorNumber; /* Number of sectors */
- + MV_U32 pageSize; /* Page size - affect allignment */
- + MV_U32 index; /* index of the device in the sflash table (internal parameter) */
- +} MV_SFLASH_INFO;
- +
- +/* Function Prototypes */
- +/* Init */
- +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo);
- +
- +/* erase */
- +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber);
- +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo);
- +
- +/* Read */
- +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
- + MV_U8* pReadBuff, MV_U32 buffSize);
- +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
- + MV_U8* pReadBuff, MV_U32 buffSize);
- +
- +/* write regardless of the page boundaries and size limit per Page program command */
- +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
- + MV_U8* pWriteBuff, MV_U32 buffSize);
- +/* Get IDs */
- +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId);
- +
- +/* Set and Get the Write Protection region - if the Status register is not locked */
- +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion);
- +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion);
- +
- +/* Lock the status register for writing - W/Vpp pin should be low to take effect */
- +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock);
- +
- +/* Get the regions sizes */
- +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo);
- +
- +/* Cause the falsh device to go into power save mode */
- +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo);
- +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo);
- +
- +/* Retreive the string with the device manufacturer and model */
- +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo);
- +
- +#endif /* __INCmvSFlashH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 2010-11-09 20:28:11.981246772 +0100
- @@ -0,0 +1,233 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSFlashSpecH
- +#define __INCmvSFlashSpecH
- +
- +/* Constants */
- +#define MV_SFLASH_READ_CMND_LENGTH 4 /* 1B opcode + 3B address */
- +#define MV_SFLASH_SE_CMND_LENGTH 4 /* 1B opcode + 3B address */
- +#define MV_SFLASH_BE_CMND_LENGTH 1 /* 1B opcode */
- +#define MV_SFLASH_PP_CMND_LENGTH 4 /* 1B opcode + 3B address */
- +#define MV_SFLASH_WREN_CMND_LENGTH 1 /* 1B opcode */
- +#define MV_SFLASH_WRDI_CMND_LENGTH 1 /* 1B opcode */
- +#define MV_SFLASH_RDID_CMND_LENGTH 1 /* 1B opcode */
- +#define MV_SFLASH_RDID_REPLY_LENGTH 3 /* 1B manf ID and 2B device ID */
- +#define MV_SFLASH_RDSR_CMND_LENGTH 1 /* 1B opcode */
- +#define MV_SFLASH_RDSR_REPLY_LENGTH 1 /* 1B status */
- +#define MV_SFLASH_WRSR_CMND_LENGTH 2 /* 1B opcode + 1B status value */
- +#define MV_SFLASH_DP_CMND_LENGTH 1 /* 1B opcode */
- +#define MV_SFLASH_RES_CMND_LENGTH 1 /* 1B opcode */
- +
- +/* Status Register Bit Masks */
- +#define MV_SFLASH_STATUS_REG_WIP_OFFSET 0 /* bit 0; write in progress */
- +#define MV_SFLASH_STATUS_REG_WP_OFFSET 2 /* bit 2-4; write protect option */
- +#define MV_SFLASH_STATUS_REG_SRWD_OFFSET 7 /* bit 7; lock status register write */
- +#define MV_SFLASH_STATUS_REG_WIP_MASK (0x1 << MV_SFLASH_STATUS_REG_WIP_OFFSET)
- +#define MV_SFLASH_STATUS_REG_SRWD_MASK (0x1 << MV_SFLASH_STATUS_REG_SRWD_OFFSET)
- +
- +#define MV_SFLASH_MAX_WAIT_LOOP 1000000
- +#define MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP 0x50000000
- +
- +#define MV_SFLASH_DEFAULT_RDID_OPCD 0x9F /* Default Read ID */
- +#define MV_SFLASH_DEFAULT_WREN_OPCD 0x06 /* Default Write Enable */
- +#define MV_SFLASH_NO_SPECIFIC_OPCD 0x00
- +
- +/********************************/
- +/* ST M25Pxxx Device Specific */
- +/********************************/
- +
- +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
- +#define MV_M25PXXX_ST_MANF_ID 0x20
- +#define MV_M25P32_DEVICE_ID 0x2016
- +#define MV_M25P32_MAX_SPI_FREQ 20000000 /* 20MHz */
- +#define MV_M25P32_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
- +#define MV_M25P32_FAST_READ_DUMMY_BYTES 1
- +#define MV_M25P64_DEVICE_ID 0x2017
- +#define MV_M25P64_MAX_SPI_FREQ 20000000 /* 20MHz */
- +#define MV_M25P64_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
- +#define MV_M25P64_FAST_READ_DUMMY_BYTES 1
- +#define MV_M25P128_DEVICE_ID 0x2018
- +#define MV_M25P128_MAX_SPI_FREQ 20000000 /* 20MHz */
- +#define MV_M25P128_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
- +#define MV_M25P128_FAST_READ_DUMMY_BYTES 1
- +
- +
- +/* Sector Sizes and population per device model*/
- +#define MV_M25P32_SECTOR_SIZE 0x10000 /* 64K */
- +#define MV_M25P64_SECTOR_SIZE 0x10000 /* 64K */
- +#define MV_M25P128_SECTOR_SIZE 0x40000 /* 256K */
- +#define MV_M25P32_SECTOR_NUMBER 64
- +#define MV_M25P64_SECTOR_NUMBER 128
- +#define MV_M25P128_SECTOR_NUMBER 64
- +#define MV_M25P_PAGE_SIZE 0x100 /* 256 byte */
- +
- +#define MV_M25P_WREN_CMND_OPCD 0x06 /* Write Enable */
- +#define MV_M25P_WRDI_CMND_OPCD 0x04 /* Write Disable */
- +#define MV_M25P_RDID_CMND_OPCD 0x9F /* Read ID */
- +#define MV_M25P_RDSR_CMND_OPCD 0x05 /* Read Status Register */
- +#define MV_M25P_WRSR_CMND_OPCD 0x01 /* Write Status Register */
- +#define MV_M25P_READ_CMND_OPCD 0x03 /* Sequential Read */
- +#define MV_M25P_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
- +#define MV_M25P_PP_CMND_OPCD 0x02 /* Page Program */
- +#define MV_M25P_SE_CMND_OPCD 0xD8 /* Sector Erase */
- +#define MV_M25P_BE_CMND_OPCD 0xC7 /* Bulk Erase */
- +#define MV_M25P_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
- +
- +/* Status Register Write Protect Bit Masks - 3bits */
- +#define MV_M25P_STATUS_REG_WP_MASK (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_1_OF_64 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_1_OF_32 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_1_OF_16 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_1_OF_8 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_1_OF_4 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_1_OF_2 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_M25P_STATUS_BP_ALL (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +
- +/************************************/
- +/* MXIC MX25L6405 Device Specific */
- +/************************************/
- +
- +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
- +#define MV_MXIC_MANF_ID 0xC2
- +#define MV_MX25L6405_DEVICE_ID 0x2017
- +#define MV_MX25L6405_MAX_SPI_FREQ 20000000 /* 20MHz */
- +#define MV_MX25L6405_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
- +#define MV_MX25L6405_FAST_READ_DUMMY_BYTES 1
- +#define MV_MXIC_DP_EXIT_DELAY 30 /* 30 ms */
- +
- +/* Sector Sizes and population per device model*/
- +#define MV_MX25L6405_SECTOR_SIZE 0x10000 /* 64K */
- +#define MV_MX25L6405_SECTOR_NUMBER 128
- +#define MV_MXIC_PAGE_SIZE 0x100 /* 256 byte */
- +
- +#define MV_MX25L_WREN_CMND_OPCD 0x06 /* Write Enable */
- +#define MV_MX25L_WRDI_CMND_OPCD 0x04 /* Write Disable */
- +#define MV_MX25L_RDID_CMND_OPCD 0x9F /* Read ID */
- +#define MV_MX25L_RDSR_CMND_OPCD 0x05 /* Read Status Register */
- +#define MV_MX25L_WRSR_CMND_OPCD 0x01 /* Write Status Register */
- +#define MV_MX25L_READ_CMND_OPCD 0x03 /* Sequential Read */
- +#define MV_MX25L_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
- +#define MV_MX25L_PP_CMND_OPCD 0x02 /* Page Program */
- +#define MV_MX25L_SE_CMND_OPCD 0xD8 /* Sector Erase */
- +#define MV_MX25L_BE_CMND_OPCD 0xC7 /* Bulk Erase */
- +#define MV_MX25L_DP_CMND_OPCD 0xB9 /* Deep Power Down */
- +#define MV_MX25L_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
- +
- +/* Status Register Write Protect Bit Masks - 4bits */
- +#define MV_MX25L_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_MX25L_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +
- +/************************************/
- +/* SPANSION S25FL128P Device Specific */
- +/************************************/
- +
- +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
- +#define MV_SPANSION_MANF_ID 0x01
- +#define MV_S25FL128_DEVICE_ID 0x2018
- +#define MV_S25FL128_MAX_SPI_FREQ 33000000 /* 33MHz */
- +#define MV_S25FL128_MAX_FAST_SPI_FREQ 104000000 /* 104MHz */
- +#define MV_S25FL128_FAST_READ_DUMMY_BYTES 1
- +
- +/* Sector Sizes and population per device model*/
- +#define MV_S25FL128_SECTOR_SIZE 0x40000 /* 256K */
- +#define MV_S25FL128_SECTOR_NUMBER 64
- +#define MV_S25FL_PAGE_SIZE 0x100 /* 256 byte */
- +
- +#define MV_S25FL_WREN_CMND_OPCD 0x06 /* Write Enable */
- +#define MV_S25FL_WRDI_CMND_OPCD 0x04 /* Write Disable */
- +#define MV_S25FL_RDID_CMND_OPCD 0x9F /* Read ID */
- +#define MV_S25FL_RDSR_CMND_OPCD 0x05 /* Read Status Register */
- +#define MV_S25FL_WRSR_CMND_OPCD 0x01 /* Write Status Register */
- +#define MV_S25FL_READ_CMND_OPCD 0x03 /* Sequential Read */
- +#define MV_S25FL_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
- +#define MV_S25FL_PP_CMND_OPCD 0x02 /* Page Program */
- +#define MV_S25FL_SE_CMND_OPCD 0xD8 /* Sector Erase */
- +#define MV_S25FL_BE_CMND_OPCD 0xC7 /* Bulk Erase */
- +#define MV_S25FL_DP_CMND_OPCD 0xB9 /* Deep Power Down */
- +#define MV_S25FL_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
- +
- +/* Status Register Write Protect Bit Masks - 4bits */
- +#define MV_S25FL_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +#define MV_S25FL_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
- +
- +#endif /* __INCmvSFlashSpecH */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 2010-11-09 20:28:12.022495595 +0100
- @@ -0,0 +1,576 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "spi/mvSpi.h"
- +#include "spi/mvSpiSpec.h"
- +
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +/* #define MV_DEBUG */
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#define mvOsPrintf printf
- +#else
- +#define DB(x)
- +#endif
- +
- +
- +/*******************************************************************************
- +* mvSpi16bitDataTxRx - Transmt and receive data
- +*
- +* DESCRIPTION:
- +* Tx data and block waiting for data to be transmitted
- +*
- +********************************************************************************/
- +static MV_STATUS mvSpi16bitDataTxRx (MV_U16 txData, MV_U16 * pRxData)
- +{
- + MV_U32 i;
- + MV_BOOL ready = MV_FALSE;
- +
- + /* First clear the bit in the interrupt cause register */
- + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
- +
- + /* Transmit data */
- + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, MV_16BIT_LE(txData));
- +
- + /* wait with timeout for memory ready */
- + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
- + {
- + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
- + {
- + ready = MV_TRUE;
- + break;
- + }
- +#ifdef MV_SPI_SLEEP_ON_WAIT
- + mvOsSleep(1);
- +#endif /* MV_SPI_SLEEP_ON_WAIT */
- + }
- +
- + if (!ready)
- + return MV_TIMEOUT;
- +
- + /* check that the RX data is needed */
- + if (pRxData)
- + {
- + if ((MV_U32)pRxData & 0x1) /* check if address is not alligned to 16bit */
- + {
- +#if defined(MV_CPU_LE)
- + /* perform the data write to the buffer in two stages with 8bit each */
- + MV_U8 * bptr = (MV_U8*)pRxData;
- + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
- + *bptr = (data & 0xFF);
- + ++bptr;
- + *bptr = ((data >> 8) & 0xFF);
- +
- +#elif defined(MV_CPU_BE)
- +
- + /* perform the data write to the buffer in two stages with 8bit each */
- + MV_U8 * bptr = (MV_U8 *)pRxData;
- + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
- + *bptr = ((data >> 8) & 0xFF);
- + ++bptr;
- + *bptr = (data & 0xFF);
- +
- +#else
- + #error "CPU endianess isn't defined!\n"
- +#endif
- +
- + }
- + else
- + *pRxData = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvSpi8bitDataTxRx - Transmt and receive data (8bits)
- +*
- +* DESCRIPTION:
- +* Tx data and block waiting for data to be transmitted
- +*
- +********************************************************************************/
- +static MV_STATUS mvSpi8bitDataTxRx (MV_U8 txData, MV_U8 * pRxData)
- +{
- + MV_U32 i;
- + MV_BOOL ready = MV_FALSE;
- +
- + /* First clear the bit in the interrupt cause register */
- + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
- +
- + /* Transmit data */
- + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, txData);
- +
- + /* wait with timeout for memory ready */
- + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
- + {
- + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
- + {
- + ready = MV_TRUE;
- + break;
- + }
- +#ifdef MV_SPI_SLEEP_ON_WAIT
- + mvOsSleep(1);
- +#endif /* MV_SPI_SLEEP_ON_WAIT */
- + }
- +
- + if (!ready)
- + return MV_TIMEOUT;
- +
- + /* check that the RX data is needed */
- + if (pRxData)
- + *pRxData = MV_REG_READ(MV_SPI_DATA_IN_REG);
- +
- + return MV_OK;
- +}
- +
- +/*
- +#####################################################################################
- +#####################################################################################
- +*/
- +
- +/*******************************************************************************
- +* mvSpiInit - Initialize the SPI controller
- +*
- +* DESCRIPTION:
- +* Perform the neccessary initialization in order to be able to send an
- +* receive over the SPI interface.
- +*
- +* INPUT:
- +* serialBaudRate: Baud rate (SPI clock frequency)
- +* use16BitMode: Whether to use 2bytes (MV_TRUE) or 1bytes (MV_FALSE)
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiInit (MV_U32 serialBaudRate)
- +{
- + MV_STATUS ret;
- +
- + /* Set the serial clock */
- + if ((ret = mvSpiBaudRateSet(serialBaudRate)) != MV_OK)
- + return ret;
- +
- + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
- + mvMPPConfigToSPI();
- +
- + /* Configure the default SPI mode to be 16bit */
- + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
- +
- + /* Fix ac timing on SPI in 6183, 6183L and 78x00 only */
- + if ( (mvCtrlModelGet() == MV_6183_DEV_ID) ||
- + (mvCtrlModelGet() == MV_6183L_DEV_ID) ||
- + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
- + (mvCtrlModelGet() == MV_78200_DEV_ID) ||
- + (mvCtrlModelGet() == MV_76100_DEV_ID))
- + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, BIT14);
- +
- + /* Verify that the CS is deasserted */
- + mvSpiCsDeassert();
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSpiBaudRateSet - Set the Frequency of the SPI clock
- +*
- +* DESCRIPTION:
- +* Set the Prescale bits to adapt to the requested baud rate (the clock
- +* used for thr SPI).
- +*
- +* INPUT:
- +* serialBaudRate: Baud rate (SPI clock frequency)
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiBaudRateSet (MV_U32 serialBaudRate)
- +{
- + MV_U8 i;
- + /* MV_U8 preScale[32] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- + 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
- + */
- + MV_U8 preScale[14] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
- + MV_U8 bestPrescaleIndx = 100;
- + MV_U32 minBaudOffset = 0xFFFFFFFF;
- + MV_U32 cpuClk = mvBoardTclkGet(); /*mvCpuPclkGet();*/
- + MV_U32 tempReg;
- +
- + /* Find the best prescale configuration - less or equal */
- + for (i=0; i<14; i++)
- + {
- + /* check for higher - irrelevent */
- + if ((cpuClk / preScale[i]) > serialBaudRate)
- + continue;
- +
- + /* check for exact fit */
- + if ((cpuClk / preScale[i]) == serialBaudRate)
- + {
- + bestPrescaleIndx = i;
- + break;
- + }
- +
- + /* check if this is better than the previous one */
- + if ((serialBaudRate - (cpuClk / preScale[i])) < minBaudOffset)
- + {
- + minBaudOffset = (serialBaudRate - (cpuClk / preScale[i]));
- + bestPrescaleIndx = i;
- + }
- + }
- +
- + if (bestPrescaleIndx > 14)
- + {
- + mvOsPrintf("%s ERROR: SPI baud rate prescale error!\n", __FUNCTION__);
- + return MV_OUT_OF_RANGE;
- + }
- +
- + /* configure the Prescale */
- + tempReg = MV_REG_READ(MV_SPI_IF_CONFIG_REG);
- + tempReg = ((tempReg & ~MV_SPI_CLK_PRESCALE_MASK) | (bestPrescaleIndx + 0x12));
- + MV_REG_WRITE(MV_SPI_IF_CONFIG_REG, tempReg);
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSpiCsAssert - Assert the Chip Select pin indicating a new transfer
- +*
- +* DESCRIPTION:
- +* Assert The chip select - used to select an external SPI device
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +********************************************************************************/
- +MV_VOID mvSpiCsAssert(MV_VOID)
- +{
- + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
- + mvMPPConfigToSPI();
- + mvOsUDelay(1);
- + MV_REG_BIT_SET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
- +}
- +
- +/*******************************************************************************
- +* mvSpiCsDeassert - DeAssert the Chip Select pin indicating the end of a
- +* SPI transfer sequence
- +*
- +* DESCRIPTION:
- +* DeAssert the chip select pin
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +********************************************************************************/
- +MV_VOID mvSpiCsDeassert(MV_VOID)
- +{
- + MV_REG_BIT_RESET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
- +
- + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
- + mvMPPConfigToDefault();
- +}
- +
- +/*******************************************************************************
- +* mvSpiRead - Read a buffer over the SPI interface
- +*
- +* DESCRIPTION:
- +* Receive (read) a buffer over the SPI interface in 16bit chunks. If the
- +* buffer size is odd, then the last chunk will be 8bits. Chip select is not
- +* handled at this level.
- +*
- +* INPUT:
- +* pRxBuff: Pointer to the buffer to hold the received data
- +* buffSize: length of the pRxBuff
- +*
- +* OUTPUT:
- +* pRxBuff: Pointer to the buffer with the received data
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize)
- +{
- + MV_STATUS ret;
- + MV_U32 bytesLeft = buffSize;
- + MV_U16* rxPtr = (MV_U16*)pRxBuff;
- +
- + /* check for null parameters */
- + if (pRxBuff == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check that the buffer pointer and the buffer size are 16bit aligned */
- + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
- + {
- + /* Verify that the SPI mode is in 16bit mode */
- + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
- +
- + /* TX/RX as long we have complete 16bit chunks */
- + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
- + {
- + /* Transmitted and wait for the transfer to be completed */
- + if ((ret = mvSpi16bitDataTxRx(MV_SPI_DUMMY_WRITE_16BITS, rxPtr)) != MV_OK)
- + return ret;
- +
- + /* increment the pointers */
- + rxPtr++;
- + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
- + }
- +
- + }
- + else
- + {
- + /* Verify that the SPI mode is in 8bit mode */
- + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
- +
- + /* TX/RX in 8bit chanks */
- + while (bytesLeft > 0)
- + {
- + /* Transmitted and wait for the transfer to be completed */
- + if ((ret = mvSpi8bitDataTxRx(MV_SPI_DUMMY_WRITE_8BITS, pRxBuff)) != MV_OK)
- + return ret;
- + /* increment the pointers */
- + pRxBuff++;
- + bytesLeft--;
- + }
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvSpiWrite - Transmit a buffer over the SPI interface
- +*
- +* DESCRIPTION:
- +* Transmit a buffer over the SPI interface in 16bit chunks. If the
- +* buffer size is odd, then the last chunk will be 8bits. No chip select
- +* action is taken.
- +*
- +* INPUT:
- +* pTxBuff: Pointer to the buffer holding the TX data
- +* buffSize: length of the pTxBuff
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiWrite(MV_U8* pTxBuff, MV_U32 buffSize)
- +{
- + MV_STATUS ret;
- + MV_U32 bytesLeft = buffSize;
- + MV_U16* txPtr = (MV_U16*)pTxBuff;
- +
- + /* check for null parameters */
- + if (pTxBuff == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check that the buffer pointer and the buffer size are 16bit aligned */
- + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0))
- + {
- + /* Verify that the SPI mode is in 16bit mode */
- + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
- +
- + /* TX/RX as long we have complete 16bit chunks */
- + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
- + {
- + /* Transmitted and wait for the transfer to be completed */
- + if ((ret = mvSpi16bitDataTxRx(*txPtr, NULL)) != MV_OK)
- + return ret;
- +
- + /* increment the pointers */
- + txPtr++;
- + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
- + }
- + }
- + else
- + {
- +
- + /* Verify that the SPI mode is in 8bit mode */
- + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
- +
- + /* TX/RX in 8bit chanks */
- + while (bytesLeft > 0)
- + {
- + /* Transmitted and wait for the transfer to be completed */
- + if ((ret = mvSpi8bitDataTxRx(*pTxBuff, NULL)) != MV_OK)
- + return ret;
- +
- + /* increment the pointers */
- + pTxBuff++;
- + bytesLeft--;
- + }
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +/*******************************************************************************
- +* mvSpiReadWrite - Read and Write a buffer simultanuosely
- +*
- +* DESCRIPTION:
- +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
- +* buffer size is odd, then the last chunk will be 8bits. The SPI chip
- +* select is not handled implicitely.
- +*
- +* INPUT:
- +* pRxBuff: Pointer to the buffer to write the RX info in
- +* pTxBuff: Pointer to the buffer holding the TX info
- +* buffSize: length of both the pTxBuff and pRxBuff
- +*
- +* OUTPUT:
- +* pRxBuff: Pointer of the buffer holding the RX data
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiReadWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
- +{
- + MV_STATUS ret;
- + MV_U32 bytesLeft = buffSize;
- + MV_U16* txPtr = (MV_U16*)pTxBuff;
- + MV_U16* rxPtr = (MV_U16*)pRxBuff;
- +
- + /* check for null parameters */
- + if ((pRxBuff == NULL) || (pTxBuff == NULL))
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* Check that the buffer pointer and the buffer size are 16bit aligned */
- + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
- + {
- + /* Verify that the SPI mode is in 16bit mode */
- + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
- +
- + /* TX/RX as long we have complete 16bit chunks */
- + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
- + {
- + /* Transmitted and wait for the transfer to be completed */
- + if ((ret = mvSpi16bitDataTxRx(*txPtr, rxPtr)) != MV_OK)
- + return ret;
- +
- + /* increment the pointers */
- + txPtr++;
- + rxPtr++;
- + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
- + }
- + }
- + else
- + {
- + /* Verify that the SPI mode is in 8bit mode */
- + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
- +
- + /* TX/RX in 8bit chanks */
- + while (bytesLeft > 0)
- + {
- + /* Transmitted and wait for the transfer to be completed */
- + if ( (ret = mvSpi8bitDataTxRx(*pTxBuff, pRxBuff) ) != MV_OK)
- + return ret;
- + pRxBuff++;
- + pTxBuff++;
- + bytesLeft--;
- + }
- + }
- +
- + return MV_OK;
- +}
- +
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 2010-11-09 20:28:12.052495353 +0100
- @@ -0,0 +1,249 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#include "spi/mvSpi.h"
- +#include "spi/mvSpiSpec.h"
- +
- +/*#define MV_DEBUG*/
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +
- +/*******************************************************************************
- +* mvSpiReadAndWrite - Read and Write a buffer simultanuousely
- +*
- +* DESCRIPTION:
- +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
- +* buffer size is odd, then the last chunk will be 8bits.
- +*
- +* INPUT:
- +* pRxBuff: Pointer to the buffer to write the RX info in
- +* pTxBuff: Pointer to the buffer holding the TX info
- +* buffSize: length of both the pTxBuff and pRxBuff
- +*
- +* OUTPUT:
- +* pRxBuff: Pointer of the buffer holding the RX data
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiReadAndWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
- +{
- + MV_STATUS ret;
- +
- + /* check for null parameters */
- + if ((pRxBuff == NULL) || (pTxBuff == NULL) || (buffSize == 0))
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* First assert the chip select */
- + mvSpiCsAssert();
- +
- + ret = mvSpiReadWrite(pRxBuff, pTxBuff, buffSize);
- +
- + /* Finally deassert the chip select */
- + mvSpiCsDeassert();
- +
- + return ret;
- +}
- +
- +/*******************************************************************************
- +* mvSpiWriteThenWrite - Serialize a command followed by the data over the TX line
- +*
- +* DESCRIPTION:
- +* Assert the chip select line. Transmit the command buffer followed by
- +* the data buffer. Then deassert the CS line.
- +*
- +* INPUT:
- +* pCmndBuff: Pointer to the command buffer to transmit
- +* cmndSize: length of the command size
- +* pTxDataBuff: Pointer to the data buffer to transmit
- +* txDataSize: length of the data buffer
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff,
- + MV_U32 txDataSize)
- +{
- + MV_STATUS ret = MV_OK, tempRet;
- +
- + /* check for null parameters */
- +#ifndef CONFIG_MARVELL
- + if(NULL == pTxDataBuff)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +#endif
- +
- + if (pCmndBuff == NULL)
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* First assert the chip select */
- + mvSpiCsAssert();
- +
- + /* first write the command */
- + if ((cmndSize) && (pCmndBuff != NULL))
- + {
- + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
- + ret = tempRet;
- + }
- +
- + /* Then write the data buffer */
- +#ifndef CONFIG_MARVELL
- + if (txDataSize)
- +#else
- + if ((txDataSize) && (pTxDataBuff != NULL))
- +#endif
- + {
- + if ((tempRet = mvSpiWrite(pTxDataBuff, txDataSize)) != MV_OK)
- + ret = tempRet;
- + }
- +
- + /* Finally deassert the chip select */
- + mvSpiCsDeassert();
- +
- + return ret;
- +}
- +
- +/*******************************************************************************
- +* mvSpiWriteThenRead - Serialize a command then read a data buffer
- +*
- +* DESCRIPTION:
- +* Assert the chip select line. Transmit the command buffer then read
- +* the data buffer. Then deassert the CS line.
- +*
- +* INPUT:
- +* pCmndBuff: Pointer to the command buffer to transmit
- +* cmndSize: length of the command size
- +* pRxDataBuff: Pointer to the buffer to read the data in
- +* txDataSize: length of the data buffer
- +*
- +* OUTPUT:
- +* pRxDataBuff: Pointer to the buffer holding the data
- +*
- +* RETURN:
- +* Success or Error code.
- +*
- +*
- +*******************************************************************************/
- +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
- + MV_U32 rxDataSize,MV_U32 dummyBytesToRead)
- +{
- + MV_STATUS ret = MV_OK, tempRet;
- + MV_U8 dummyByte;
- +
- + /* check for null parameters */
- + if ((pCmndBuff == NULL) && (pRxDataBuff == NULL))
- + {
- + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
- + return MV_BAD_PARAM;
- + }
- +
- + /* First assert the chip select */
- + mvSpiCsAssert();
- +
- + /* first write the command */
- + if ((cmndSize) && (pCmndBuff != NULL))
- + {
- + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
- + ret = tempRet;
- + }
- +
- + /* Read dummy bytes before real data. */
- + while(dummyBytesToRead)
- + {
- + mvSpiRead(&dummyByte,1);
- + dummyBytesToRead--;
- + }
- +
- + /* Then write the data buffer */
- + if ((rxDataSize) && (pRxDataBuff != NULL))
- + {
- + if ((tempRet = mvSpiRead(pRxDataBuff, rxDataSize)) != MV_OK)
- + ret = tempRet;
- + }
- +
- + /* Finally deassert the chip select */
- + mvSpiCsDeassert();
- +
- + return ret;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 2010-11-09 20:28:12.082495364 +0100
- @@ -0,0 +1,82 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSpiCmndhH
- +#define __INCmvSpiCmndhH
- +
- +#include "mvTypes.h"
- +
- +/* Function Prototypes */
- +
- +/* Simultanuous Read and write */
- +MV_STATUS mvSpiReadAndWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
- +
- +/* write command - write a command and then write data */
- +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff, MV_U32 txDataSize);
- +
- +/* read command - write a command and then read data by writing dummy data */
- +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
- + MV_U32 rxDataSize,MV_U32 dummyBytesToRead);
- +
- +#endif /* __INCmvSpiCmndhH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 2010-11-09 20:28:12.121243940 +0100
- @@ -0,0 +1,94 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSpihH
- +#define __INCmvSpihH
- +
- +#include "mvCommon.h"
- +#include "mvOs.h"
- +#include "ctrlEnv/mvCtrlEnvSpec.h"
- +
- +/* Function Prototypes */
- +/* Init */
- +MV_STATUS mvSpiInit (MV_U32 serialBaudRate);
- +
- +/* Set the Frequency of the Spi clock */
- +MV_STATUS mvSpiBaudRateSet(MV_U32 serialBaudRate);
- +
- +/* Assert the SPI chip select */
- +MV_VOID mvSpiCsAssert (MV_VOID);
- +
- +/* De-assert the SPI chip select */
- +MV_VOID mvSpiCsDeassert (MV_VOID);
- +
- +/* Simultanuous Read and write */
- +MV_STATUS mvSpiReadWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
- +
- +/* serialize a buffer on the TX line - Rx is ignored */
- +MV_STATUS mvSpiWrite (MV_U8* pTxBuff, MV_U32 buffSize);
- +
- +/* read from the RX line by writing dummy values to the TX line */
- +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize);
- +
- +#endif /* __INCmvSpihH */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 2010-11-09 20:28:12.162495430 +0100
- @@ -0,0 +1,98 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +#ifndef __INCmvSpiSpecH
- +#define __INCmvSpiSpecH
- +
- +/* Constants */
- +#define MV_SPI_WAIT_RDY_MAX_LOOP 100000
- +#define MV_SPI_16_BIT_CHUNK_SIZE 2
- +#define MV_SPI_DUMMY_WRITE_16BITS 0xFFFF
- +#define MV_SPI_DUMMY_WRITE_8BITS 0xFF
- +
- +/* Marvell Flash Device Controller Registers */
- +#define MV_SPI_CTRLR_OFST 0x10600
- +#define MV_SPI_IF_CTRL_REG (MV_SPI_CTRLR_OFST + 0x00)
- +#define MV_SPI_IF_CONFIG_REG (MV_SPI_CTRLR_OFST + 0x04)
- +#define MV_SPI_DATA_OUT_REG (MV_SPI_CTRLR_OFST + 0x08)
- +#define MV_SPI_DATA_IN_REG (MV_SPI_CTRLR_OFST + 0x0c)
- +#define MV_SPI_INT_CAUSE_REG (MV_SPI_CTRLR_OFST + 0x10)
- +#define MV_SPI_INT_CAUSE_MASK_REG (MV_SPI_CTRLR_OFST + 0x14)
- +
- +/* Serial Memory Interface Control Register Masks */
- +#define MV_SPI_CS_ENABLE_OFFSET 0 /* bit 0 */
- +#define MV_SPI_MEMORY_READY_OFFSET 1 /* bit 1 */
- +#define MV_SPI_CS_ENABLE_MASK (0x1 << MV_SPI_CS_ENABLE_OFFSET)
- +#define MV_SPI_MEMORY_READY_MASK (0x1 << MV_SPI_MEMORY_READY_OFFSET)
- +
- +/* Serial Memory Interface Configuration Register Masks */
- +#define MV_SPI_CLK_PRESCALE_OFFSET 0 /* bit 0-4 */
- +#define MV_SPI_BYTE_LENGTH_OFFSET 5 /* bit 5 */
- +#define MV_SPI_ADDRESS_BURST_LENGTH_OFFSET 8 /* bit 8-9 */
- +#define MV_SPI_CLK_PRESCALE_MASK (0x1F << MV_SPI_CLK_PRESCALE_OFFSET)
- +#define MV_SPI_BYTE_LENGTH_MASK (0x1 << MV_SPI_BYTE_LENGTH_OFFSET)
- +#define MV_SPI_ADDRESS_BURST_LENGTH_MASK (0x3 << MV_SPI_ADDRESS_BURST_LENGTH_OFFSET)
- +
- +#endif /* __INCmvSpiSpecH */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 2010-11-09 20:28:12.192495512 +0100
- @@ -0,0 +1,1023 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +
- +
- +#include "mvTwsi.h"
- +#include "mvTwsiSpec.h"
- +#include "cpu/mvCpu.h"
- +
- +
- +/*#define MV_DEBUG*/
- +#ifdef MV_DEBUG
- +#define DB(x) x
- +#else
- +#define DB(x)
- +#endif
- +
- +static MV_VOID twsiIntFlgClr(MV_U8 chanNum);
- +static MV_BOOL twsiMainIntGet(MV_U8 chanNum);
- +static MV_VOID twsiAckBitSet(MV_U8 chanNum);
- +static MV_U32 twsiStsGet(MV_U8 chanNum);
- +static MV_VOID twsiReset(MV_U8 chanNum);
- +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
- +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
- +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
- +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
- +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset,MV_BOOL moreThen256);
- +
- +
- +static MV_BOOL twsiTimeoutChk(MV_U32 timeout, const MV_8 *pString)
- +{
- + if(timeout >= TWSI_TIMEOUT_VALUE)
- + {
- + DB(mvOsPrintf("%s",pString));
- + return MV_TRUE;
- + }
- + return MV_FALSE;
- +
- +}
- +/*******************************************************************************
- +* mvTwsiStartBitSet - Set start bit on the bus
- +*
- +* DESCRIPTION:
- +* This routine sets the start bit on the TWSI bus.
- +* The routine first checks for interrupt flag condition, then it sets
- +* the start bit in the TWSI Control register.
- +* If the interrupt flag condition check previously was set, the function
- +* will clear it.
- +* The function then wait for the start bit to be cleared by the HW.
- +* Then it waits for the interrupt flag to be set and eventually, the
- +* TWSI status is checked to be 0x8 or 0x10(repeated start bit).
- +*
- +* INPUT:
- +* chanNum - TWSI channel.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK is start bit was set successfuly on the bus.
- +* MV_FAIL if interrupt flag was set before setting start bit.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)
- +{
- + MV_BOOL isIntFlag = MV_FALSE;
- + MV_U32 timeout, temp;
- +
- + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));
- + /* check Int flag */
- + if(twsiMainIntGet(chanNum))
- + isIntFlag = MV_TRUE;
- + /* set start Bit */
- + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
- + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);
- +
- + /* in case that the int flag was set before i.e. repeated start bit */
- + if(isIntFlag){
- + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));
- + twsiIntFlgClr(chanNum);
- + }
- +
- + /* wait for interrupt */
- + timeout = 0;
- + while(!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))
- + return MV_TIMEOUT;
- +
- +
- + /* check that start bit went down */
- + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0)
- + {
- + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");
- + return MV_FAIL;
- + }
- +
- + /* check the status */
- + temp = twsiStsGet(chanNum);
- + if(( temp != TWSI_START_CON_TRA ) && ( temp != TWSI_REPEATED_START_CON_TRA ))
- + {
- + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n",temp);
- + return MV_FAIL;
- + }
- +
- + return MV_OK;
- +
- +}
- +
- +/*******************************************************************************
- +* mvTwsiStopBitSet - Set stop bit on the bus
- +*
- +* DESCRIPTION:
- +* This routine set the stop bit on the TWSI bus.
- +* The function then wait for the stop bit to be cleared by the HW.
- +* Finally the function checks for status of 0xF8.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE is stop bit was set successfuly on the bus.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
- +{
- + MV_U32 timeout, temp;
- +
- + /* Generate stop bit */
- + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
- + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);
- +
- + twsiIntFlgClr(chanNum);
- +
- + /* wait for stop bit to come down */
- + timeout = 0;
- + while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
- + return MV_TIMEOUT;
- +
- + /* check that the stop bit went down */
- + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
- + {
- + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");
- + return MV_FAIL;
- + }
- +
- + /* check the status */
- + temp = twsiStsGet(chanNum);
- + if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){
- + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);
- + return MV_FAIL;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* twsiMainIntGet - Get twsi bit from main Interrupt cause.
- +*
- +* DESCRIPTION:
- +* This routine returns the twsi interrupt flag value.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_TRUE is interrupt flag is set, MV_FALSE otherwise.
- +*
- +*******************************************************************************/
- +static MV_BOOL twsiMainIntGet(MV_U8 chanNum)
- +{
- + MV_U32 temp;
- +
- + /* get the int flag bit */
- +
- + temp = MV_REG_READ(TWSI_CPU_MAIN_INT_CAUSE_REG);
- + if (temp & (TWSI0_CPU_MAIN_INT_BIT << chanNum))
- + return MV_TRUE;
- +
- + return MV_FALSE;
- +}
- +/*******************************************************************************
- +* twsiIntFlgClr - Clear Interrupt flag.
- +*
- +* DESCRIPTION:
- +* This routine clears the interrupt flag. It does NOT poll the interrupt
- +* to make sure the clear. After clearing the interrupt, it waits for at
- +* least 1 miliseconds.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +static MV_VOID twsiIntFlgClr(MV_U8 chanNum)
- +{
- + MV_U32 temp;
- +
- + /* wait for 1 mili to prevent TWSI register write after write problems */
- + mvOsDelay(1);
- + /* clear the int flag bit */
- + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
- + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));
- +
- + /* wait for 1 mili sec for the clear to take effect */
- + mvOsDelay(1);
- +
- + return;
- +}
- +
- +
- +/*******************************************************************************
- +* twsiAckBitSet - Set acknowledge bit on the bus
- +*
- +* DESCRIPTION:
- +* This routine set the acknowledge bit on the TWSI bus.
- +*
- +* INPUT:
- +* None.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None.
- +*
- +*******************************************************************************/
- +static MV_VOID twsiAckBitSet(MV_U8 chanNum)
- +{
- + MV_U32 temp;
- +
- + /*Set the Ack bit */
- + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
- + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);
- +
- + /* Add delay of 1ms */
- + mvOsDelay(1);
- + return;
- +}
- +
- +
- +/*******************************************************************************
- +* twsiInit - Initialize TWSI interface
- +*
- +* DESCRIPTION:
- +* This routine:
- +* -Reset the TWSI.
- +* -Initialize the TWSI clock baud rate according to given frequancy
- +* parameter based on Tclk frequancy and enables TWSI slave.
- +* -Set the ack bit.
- +* -Assign the TWSI slave address according to the TWSI address Type.
- +*
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* frequancy - TWSI frequancy in KHz. (up to 100KHZ)
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* Actual frequancy.
- +*
- +*******************************************************************************/
- +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
- +{
- + MV_U32 n,m,freq,margin,minMargin = 0xffffffff;
- + MV_U32 power;
- + MV_U32 actualFreq = 0,actualN = 0,actualM = 0,val;
- +
- + if(frequancy > 100000)
- + {
- + mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");
- + }
- +
- + DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));
- + /* Calucalte N and M for the TWSI clock baud rate */
- + for(n = 0 ; n < 8 ; n++)
- + {
- + for(m = 0 ; m < 16 ; m++)
- + {
- + power = 2 << n; /* power = 2^(n+1) */
- + freq = Tclk/(10*(m+1)*power);
- + margin = MV_ABS(frequancy - freq);
- + if(margin < minMargin)
- + {
- + minMargin = margin;
- + actualFreq = freq;
- + actualN = n;
- + actualM = m;
- + }
- + }
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));
- + /* Reset the TWSI logic */
- + twsiReset(chanNum);
- +
- + /* Set the baud rate */
- + val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
- + MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);
- +
- + /* Enable the TWSI and slave */
- + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);
- +
- + /* set the TWSI slave address */
- + if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */
- + {
- + /* writing the 2 most significant bits of the 10 bit address*/
- + val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );
- + /* bits 7:3 must be 0x11110 */
- + val |= TWSI_SLAVE_ADDR_10BIT_CONST;
- + /* set GCE bit */
- + if(generalCallEnable)
- + val |= TWSI_SLAVE_ADDR_GCE_ENA;
- + /* write slave address */
- + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);
- +
- + /* writing the 8 least significant bits of the 10 bit address*/
- + val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
- + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
- + }
- + else /*7 bit address*/
- + {
- + /* set the 7 Bits address */
- + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum),0x0);
- + val = (pTwsiAddr->address << TWSI_SLAVE_ADDR_7BIT_OFFS) & TWSI_SLAVE_ADDR_7BIT_MASK;
- + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);
- + }
- +
- + /* unmask twsi int */
- + val = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
- + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), val | TWSI_CONTROL_INT_ENA);
- + /* Add delay of 1ms */
- + mvOsDelay(1);
- +
- + return actualFreq;
- +}
- +
- +
- +/*******************************************************************************
- +* twsiStsGet - Get the TWSI status value.
- +*
- +* DESCRIPTION:
- +* This routine returns the TWSI status value.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_U32 - the TWSI status.
- +*
- +*******************************************************************************/
- +static MV_U32 twsiStsGet(MV_U8 chanNum)
- +{
- + return MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(chanNum));
- +
- +}
- +
- +/*******************************************************************************
- +* twsiReset - Reset the TWSI.
- +*
- +* DESCRIPTION:
- +* Resets the TWSI logic and sets all TWSI registers to their reset values.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* None
- +*
- +*******************************************************************************/
- +static MV_VOID twsiReset(MV_U8 chanNum)
- +{
- + /* Reset the TWSI logic */
- + MV_REG_WRITE(TWSI_SOFT_RESET_REG(chanNum),0);
- +
- + /* wait for 2 mili sec */
- + mvOsDelay(2);
- +
- + return;
- +}
- +
- +
- +
- +
- +/******************************* POLICY ****************************************/
- +
- +
- +
- +/*******************************************************************************
- +* mvTwsiAddrSet - Set address on TWSI bus.
- +*
- +* DESCRIPTION:
- +* This function Set address (7 or 10 Bit address) on the Twsi Bus.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* pTwsiAddr - twsi address.
- +* command - read / write .
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK - if setting the address completed succesfully.
- +* MV_FAIL otherwmise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *pTwsiAddr, MV_TWSI_CMD command)
- +{
- + DB(mvOsPrintf("TWSI: mvTwsiAddr7BitSet addr %x , type %d, cmd is %s\n",pTwsiAddr->address,\
- + pTwsiAddr->type, ((command==MV_TWSI_WRITE)?"Write":"Read") ));
- + /* 10 Bit address */
- + if(pTwsiAddr->type == ADDR10_BIT)
- + {
- + return twsiAddr10BitSet(chanNum, pTwsiAddr->address,command);
- + }
- + /* 7 Bit address */
- + else
- + {
- + return twsiAddr7BitSet(chanNum, pTwsiAddr->address,command);
- + }
- +
- +}
- +
- +/*******************************************************************************
- +* twsiAddr10BitSet - Set 10 Bit address on TWSI bus.
- +*
- +* DESCRIPTION:
- +* There are two address phases:
- +* 1) Write '11110' to data register bits [7:3] and 10-bit address MSB
- +* (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1) bit
- +* to the Data register. Then it clears interrupt flag which drive
- +* the address on the TWSI bus. The function then waits for interrupt
- +* flag to be active and status 0x18 (write) or 0x40 (read) to be set.
- +* 2) write the rest of 10-bit address to data register and clears
- +* interrupt flag which drive the address on the TWSI bus. The
- +* function then waits for interrupt flag to be active and status
- +* 0xD0 (write) or 0xE0 (read) to be set.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* deviceAddress - twsi address.
- +* command - read / write .
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK - if setting the address completed succesfully.
- +* MV_FAIL otherwmise.
- +*
- +*******************************************************************************/
- +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
- +{
- + MV_U32 val,timeout;
- +
- + /* writing the 2 most significant bits of the 10 bit address*/
- + val = ((deviceAddress & TWSI_DATA_ADDR_10BIT_MASK) >> TWSI_DATA_ADDR_10BIT_OFFS );
- + /* bits 7:3 must be 0x11110 */
- + val |= TWSI_DATA_ADDR_10BIT_CONST;
- + /* set command */
- + val |= command;
- + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
- + /* WA add a delay */
- + mvOsDelay(1);
- +
- + /* clear Int flag */
- + twsiIntFlgClr(chanNum);
- +
- + /* wait for Int to be Set */
- + timeout = 0;
- + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 1st addr (10Bit) Int TimeOut.\n"))
- + return MV_TIMEOUT;
- +
- + /* check the status */
- + val = twsiStsGet(chanNum);
- + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
- + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
- + {
- + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 1st addr (10 Bit) in %s mode.\n"\
- + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
- + return MV_FAIL;
- + }
- +
- + /* set 8 LSB of the address */
- + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
- + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
- +
- + /* clear Int flag */
- + twsiIntFlgClr(chanNum);
- +
- + /* wait for Int to be Set */
- + timeout = 0;
- + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 2nd (10 Bit) Int TimOut.\n"))
- + return MV_TIMEOUT;
- +
- + /* check the status */
- + val = twsiStsGet(chanNum);
- + if(( (val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
- + ( (val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
- + {
- + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 2nd addr(10 Bit) in %s mode.\n"\
- + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
- + return MV_FAIL;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* twsiAddr7BitSet - Set 7 Bit address on TWSI bus.
- +*
- +* DESCRIPTION:
- +* This function writes 7 bit address plus a write or read bit to the
- +* Data register. Then it clears interrupt flag which drive the address on
- +* the TWSI bus. The function then waits for interrupt flag to be active
- +* and status 0x18 (write) or 0x40 (read) to be set.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* deviceAddress - twsi address.
- +* command - read / write .
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK - if setting the address completed succesfully.
- +* MV_FAIL otherwmise.
- +*
- +*******************************************************************************/
- +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
- +{
- + MV_U32 val,timeout;
- +
- + /* set the address */
- + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
- + /* set command */
- + val |= command;
- + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
- + /* WA add a delay */
- + mvOsDelay(1);
- +
- + /* clear Int flag */
- + twsiIntFlgClr(chanNum);
- +
- + /* wait for Int to be Set */
- + timeout = 0;
- + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr7BitSet ERROR - Addr (7 Bit) int TimeOut.\n"))
- + return MV_TIMEOUT;
- +
- + /* check the status */
- + val = twsiStsGet(chanNum);
- + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
- + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
- + {
- + /* only in debug, since in boot we try to read the SPD of both DRAM, and we don't
- + want error messeges in case DIMM doesn't exist. */
- + DB(mvOsPrintf("TWSI: twsiAddr7BitSet ERROR - status %x addr (7 Bit) in %s mode.\n"\
- + ,val,((command==MV_TWSI_WRITE)?"Write":"Read") ));
- + return MV_FAIL;
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* twsiDataWrite - Trnasmit a data block over TWSI bus.
- +*
- +* DESCRIPTION:
- +* This function writes a given data block to TWSI bus in 8 bit granularity.
- +* first The function waits for interrupt flag to be active then
- +* For each 8-bit data:
- +* The function writes data to data register. It then clears
- +* interrupt flag which drives the data on the TWSI bus.
- +* The function then waits for interrupt flag to be active and status
- +* 0x28 to be set.
- +*
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* pBlock - Data block.
- +* blockSize - number of chars in pBlock.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK - if transmiting the block completed succesfully,
- +* MV_BAD_PARAM - if pBlock is NULL,
- +* MV_FAIL otherwmise.
- +*
- +*******************************************************************************/
- +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
- +{
- + MV_U32 timeout, temp, blockSizeWr = blockSize;
- +
- + if(NULL == pBlock)
- + return MV_BAD_PARAM;
- +
- + /* wait for Int to be Set */
- + timeout = 0;
- + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
- + return MV_TIMEOUT;
- +
- + while(blockSizeWr)
- + {
- + /* write the data*/
- + MV_REG_WRITE(TWSI_DATA_REG(chanNum),(MV_U32)*pBlock);
- + DB(mvOsPrintf("TWSI: twsiDataTransmit place = %d write %x \n",\
- + blockSize - blockSizeWr, *pBlock));
- + pBlock++;
- + blockSizeWr--;
- +
- + twsiIntFlgClr(chanNum);
- +
- + /* wait for Int to be Set */
- + timeout = 0;
- + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
- + return MV_TIMEOUT;
- +
- + /* check the status */
- + temp = twsiStsGet(chanNum);
- + if(temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC)
- + {
- + mvOsPrintf("TWSI: twsiDataTransmit ERROR - status %x in write trans\n",temp);
- + return MV_FAIL;
- + }
- +
- + }
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* twsiDataReceive - Receive data block from TWSI bus.
- +*
- +* DESCRIPTION:
- +* This function receive data block from TWSI bus in 8bit granularity
- +* into pBlock buffer.
- +* first The function waits for interrupt flag to be active then
- +* For each 8-bit data:
- +* It clears the interrupt flag which allows the next data to be
- +* received from TWSI bus.
- +* The function waits for interrupt flag to be active,
- +* and status reg is 0x50.
- +* Then the function reads data from data register, and copies it to
- +* the given buffer.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* blockSize - number of bytes to read.
- +*
- +* OUTPUT:
- +* pBlock - Data block.
- +*
- +* RETURN:
- +* MV_OK - if receive transaction completed succesfully,
- +* MV_BAD_PARAM - if pBlock is NULL,
- +* MV_FAIL otherwmise.
- +*
- +*******************************************************************************/
- +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
- +{
- + MV_U32 timeout, temp, blockSizeRd = blockSize;
- + if(NULL == pBlock)
- + return MV_BAD_PARAM;
- +
- + /* wait for Int to be Set */
- + timeout = 0;
- + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data int Time out .\n"))
- + return MV_TIMEOUT;
- +
- + while(blockSizeRd)
- + {
- + if(blockSizeRd == 1)
- + {
- + /* clear ack and Int flag */
- + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
- + temp &= ~(TWSI_CONTROL_ACK);
- + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp);
- + }
- + twsiIntFlgClr(chanNum);
- + /* wait for Int to be Set */
- + timeout = 0;
- + while( (!twsiMainIntGet(chanNum)) && (timeout++ < TWSI_TIMEOUT_VALUE));
- +
- + /* check for timeout */
- + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data Int Time out .\n"))
- + return MV_TIMEOUT;
- +
- + /* check the status */
- + temp = twsiStsGet(chanNum);
- + if((temp != TWSI_M_REC_RD_DATA_ACK_TRA) && (blockSizeRd !=1))
- + {
- + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in read trans \n",temp);
- + return MV_FAIL;
- + }
- + else if((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) && (blockSizeRd ==1))
- + {
- + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in Rd Terminate\n",temp);
- + return MV_FAIL;
- + }
- +
- + /* read the data*/
- + *pBlock = (MV_U8)MV_REG_READ(TWSI_DATA_REG(chanNum));
- + DB(mvOsPrintf("TWSI: twsiDataReceive place %d read %x \n",\
- + blockSize - blockSizeRd,*pBlock));
- + pBlock++;
- + blockSizeRd--;
- + }
- +
- + return MV_OK;
- +}
- +
- +
- +
- +/*******************************************************************************
- +* twsiTargetOffsSet - Set TWST target offset on TWSI bus.
- +*
- +* DESCRIPTION:
- +* The function support TWSI targets that have inside address space (for
- +* example EEPROMs). The function:
- +* 1) Convert the given offset into pBlock and size.
- +* in case the offset should be set to a TWSI slave which support
- +* more then 256 bytes offset, the offset setting will be done
- +* in 2 transactions.
- +* 2) Use twsiDataTransmit to place those on the bus.
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* offset - offset to be set on the EEPROM device.
- +* moreThen256 - whether the EEPROM device support more then 256 byte offset.
- +*
- +* OUTPUT:
- +* None.
- +*
- +* RETURN:
- +* MV_OK - if setting the offset completed succesfully.
- +* MV_FAIL otherwmise.
- +*
- +*******************************************************************************/
- +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset, MV_BOOL moreThen256)
- +{
- + MV_U8 offBlock[2];
- + MV_U32 offSize;
- +
- + if(moreThen256 == MV_TRUE)
- + {
- + offBlock[0] = (offset >> 8) & 0xff;
- + offBlock[1] = offset & 0xff;
- + offSize = 2;
- + }
- + else
- + {
- + offBlock[0] = offset & 0xff;
- + offSize = 1;
- + }
- + DB(mvOsPrintf("TWSI: twsiTargetOffsSet offSize = %x addr1 = %x addr2 = %x\n",\
- + offSize,offBlock[0],offBlock[1]));
- + return twsiDataTransmit(chanNum, offBlock, offSize);
- +
- +}
- +
- +/*******************************************************************************
- +* mvTwsiRead - Read data block from a TWSI Slave.
- +*
- +* DESCRIPTION:
- +* The function calls the following functions:
- +* -) mvTwsiStartBitSet();
- +* if(EEPROM device)
- +* -) mvTwsiAddrSet(w);
- +* -) twsiTargetOffsSet();
- +* -) mvTwsiStartBitSet();
- +* -) mvTwsiAddrSet(r);
- +* -) twsiDataReceive();
- +* -) mvTwsiStopBitSet();
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* pTwsiSlave - Twsi Slave structure.
- +* blockSize - number of bytes to read.
- +*
- +* OUTPUT:
- +* pBlock - Data block.
- +*
- +* RETURN:
- +* MV_OK - if EEPROM read transaction completed succesfully,
- +* MV_BAD_PARAM - if pBlock is NULL,
- +* MV_FAIL otherwmise.
- +*
- +*******************************************************************************/
- +MV_STATUS mvTwsiRead(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
- +{
- + if((NULL == pBlock) || (NULL == pTwsiSlave))
- + return MV_BAD_PARAM;
- + if(MV_OK != mvTwsiStartBitSet(chanNum))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- +
- + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
- +
- + /* in case offset exsist (i.e. eeprom ) */
- + if(MV_TRUE == pTwsiSlave->validOffset)
- + {
- + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
- + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiTargetOffsSet\n"));
- + if(MV_OK != mvTwsiStartBitSet(chanNum))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
- + }
- + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_READ))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
- + if(MV_OK != twsiDataReceive(chanNum, pBlock, blockSize))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiDataReceive\n"));
- +
- + if(MV_OK != mvTwsiStopBitSet(chanNum))
- + {
- + return MV_FAIL;
- + }
- +
- + twsiAckBitSet(chanNum);
- +
- + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStopBitSet\n"));
- +
- + return MV_OK;
- +}
- +
- +/*******************************************************************************
- +* mvTwsiWrite - Write data block to a TWSI Slave.
- +*
- +* DESCRIPTION:
- +* The function calls the following functions:
- +* -) mvTwsiStartBitSet();
- +* -) mvTwsiAddrSet();
- +* -)if(EEPROM device)
- +* -) twsiTargetOffsSet();
- +* -) twsiDataTransmit();
- +* -) mvTwsiStopBitSet();
- +*
- +* INPUT:
- +* chanNum - TWSI channel
- +* eepromAddress - eeprom address.
- +* blockSize - number of bytes to write.
- +* pBlock - Data block.
- +*
- +* OUTPUT:
- +* None
- +*
- +* RETURN:
- +* MV_OK - if EEPROM read transaction completed succesfully.
- +* MV_BAD_PARAM - if pBlock is NULL,
- +* MV_FAIL otherwmise.
- +*
- +* NOTE: Part of the EEPROM, required that the offset will be aligned to the
- +* max write burst supported.
- +*******************************************************************************/
- +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
- +{
- + if((NULL == pBlock) || (NULL == pTwsiSlave))
- + return MV_BAD_PARAM;
- +
- + if(MV_OK != mvTwsiStartBitSet(chanNum))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- +
- + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStartBitSet\n"));
- + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI :mvTwsiEepromWrite after mvTwsiAddrSet\n"));
- +
- + /* in case offset exsist (i.e. eeprom ) */
- + if(MV_TRUE == pTwsiSlave->validOffset)
- + {
- + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiTargetOffsSet\n"));
- + }
- + if(MV_OK != twsiDataTransmit(chanNum, pBlock, blockSize))
- + {
- + mvTwsiStopBitSet(chanNum);
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiDataTransmit\n"));
- + if(MV_OK != mvTwsiStopBitSet(chanNum))
- + {
- + return MV_FAIL;
- + }
- + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStopBitSet\n"));
- +
- + return MV_OK;
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 2010-11-09 20:28:12.231824496 +0100
- @@ -0,0 +1,121 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +#ifndef __INCmvTwsiH
- +#define __INCmvTwsiH
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* need to update this includes */
- +#include "twsi/mvTwsiSpec.h"
- +#include "ctrlEnv/mvCtrlEnvLib.h"
- +
- +
- +/* The TWSI interface supports both 7-bit and 10-bit addressing. */
- +/* This enumerator describes addressing type. */
- +typedef enum _mvTwsiAddrType
- +{
- + ADDR7_BIT, /* 7 bit address */
- + ADDR10_BIT /* 10 bit address */
- +}MV_TWSI_ADDR_TYPE;
- +
- +/* This structure describes TWSI address. */
- +typedef struct _mvTwsiAddr
- +{
- + MV_U32 address; /* address */
- + MV_TWSI_ADDR_TYPE type; /* Address type */
- +}MV_TWSI_ADDR;
- +
- +/* This structure describes a TWSI slave. */
- +typedef struct _mvTwsiSlave
- +{
- + MV_TWSI_ADDR slaveAddr;
- + MV_BOOL validOffset; /* whether the slave has offset (i.e. Eeprom etc.) */
- + MV_U32 offset; /* offset in the slave. */
- + MV_BOOL moreThen256; /* whether the ofset is bigger then 256 */
- +}MV_TWSI_SLAVE;
- +
- +/* This enumerator describes TWSI protocol commands. */
- +typedef enum _mvTwsiCmd
- +{
- + MV_TWSI_WRITE, /* TWSI write command - 0 according to spec */
- + MV_TWSI_READ /* TWSI read command - 1 according to spec */
- +}MV_TWSI_CMD;
- +
- +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum);
- +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum);
- +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *twsiAddr, MV_TWSI_CMD command);
- +
- +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_KHZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *twsiAddr, MV_BOOL generalCallEnable);
- +MV_STATUS mvTwsiRead (MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
- +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
- +
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvTwsiH */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 2010-11-09 20:28:12.272374071 +0100
- @@ -0,0 +1,160 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +This software file (the "File") is owned and distributed by Marvell
- +International Ltd. and/or its affiliates ("Marvell") under the following
- +alternative licensing terms. Once you have made an election to distribute the
- +File under one of the following license alternatives, please (i) delete this
- +introductory statement regarding license alternatives, (ii) delete the two
- +license alternatives that you have not elected to use and (iii) preserve the
- +Marvell copyright notice above.
- +
- +********************************************************************************
- +Marvell Commercial License Option
- +
- +If you received this File from Marvell and you have entered into a commercial
- +license agreement (a "Commercial License") with Marvell, the File is licensed
- +to you under the terms of the applicable Commercial License.
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +********************************************************************************
- +Marvell BSD License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File under the following licensing terms.
- +Redistribution and use in source and binary forms, with or without modification,
- +are permitted provided that the following conditions are met:
- +
- + * Redistributions of source code must retain the above copyright notice,
- + this list of conditions and the following disclaimer.
- +
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- +
- + * Neither the name of Marvell nor the names of its contributors may be
- + used to endorse or promote products derived from this software without
- + specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +
- +*******************************************************************************/
- +/****************************************/
- +/* TWSI Registers */
- +/****************************************/
- +#ifndef __INCmvTwsiSpech
- +#define __INCmvTwsiSpech
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif /* __cplusplus */
- +
- +/* defines */
- +#define TWSI_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum)+ 0x00)
- +
- +#define TWSI_SLAVE_ADDR_GCE_ENA BIT0
- +#define TWSI_SLAVE_ADDR_7BIT_OFFS 0x1
- +#define TWSI_SLAVE_ADDR_7BIT_MASK (0xFF << TWSI_SLAVE_ADDR_7BIT_OFFS)
- +#define TWSI_SLAVE_ADDR_10BIT_OFFS 0x7
- +#define TWSI_SLAVE_ADDR_10BIT_MASK 0x300
- +#define TWSI_SLAVE_ADDR_10BIT_CONST 0xF0
- +
- +
- +#define TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x10)
- +#define TWSI_EXTENDED_SLAVE_OFFS 0
- +#define TWSI_EXTENDED_SLAVE_MASK (0xFF << TWSI_EXTENDED_SLAVE_OFFS)
- +
- +
- +#define TWSI_DATA_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x04)
- +#define TWSI_DATA_COMMAND_OFFS 0x0
- +#define TWSI_DATA_COMMAND_MASK (0x1 << TWSI_DATA_COMMAND_OFFS)
- +#define TWSI_DATA_COMMAND_WR (0x1 << TWSI_DATA_COMMAND_OFFS)
- +#define TWSI_DATA_COMMAND_RD (0x0 << TWSI_DATA_COMMAND_OFFS)
- +#define TWSI_DATA_ADDR_7BIT_OFFS 0x1
- +#define TWSI_DATA_ADDR_7BIT_MASK (0xFF << TWSI_DATA_ADDR_7BIT_OFFS)
- +#define TWSI_DATA_ADDR_10BIT_OFFS 0x7
- +#define TWSI_DATA_ADDR_10BIT_MASK 0x300
- +#define TWSI_DATA_ADDR_10BIT_CONST 0xF0
- +
- +
- +#define TWSI_CONTROL_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x08)
- +#define TWSI_CONTROL_ACK BIT2
- +#define TWSI_CONTROL_INT_FLAG_SET BIT3
- +#define TWSI_CONTROL_STOP_BIT BIT4
- +#define TWSI_CONTROL_START_BIT BIT5
- +#define TWSI_CONTROL_ENA BIT6
- +#define TWSI_CONTROL_INT_ENA BIT7
- +
- +
- +#define TWSI_STATUS_BAUDE_RATE_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x0c)
- +#define TWSI_BAUD_RATE_N_OFFS 0
- +#define TWSI_BAUD_RATE_N_MASK (0x7 << TWSI_BAUD_RATE_N_OFFS)
- +#define TWSI_BAUD_RATE_M_OFFS 3
- +#define TWSI_BAUD_RATE_M_MASK (0xF << TWSI_BAUD_RATE_M_OFFS)
- +
- +#define TWSI_SOFT_RESET_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x1c)
- +
- +/* defines */
- +#define TWSI_TIMEOUT_VALUE 0x500
- +
- +/* TWSI status codes */
- +#define TWSI_BUS_ERROR 0x00
- +#define TWSI_START_CON_TRA 0x08
- +#define TWSI_REPEATED_START_CON_TRA 0x10
- +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_REC 0x18
- +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0x20
- +#define TWSI_M_TRAN_DATA_BYTE_ACK_REC 0x28
- +#define TWSI_M_TRAN_DATA_BYTE_ACK_NOT_REC 0x30
- +#define TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA 0x38
- +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_REC 0x40
- +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0x48
- +#define TWSI_M_REC_RD_DATA_ACK_TRA 0x50
- +#define TWSI_M_REC_RD_DATA_ACK_NOT_TRA 0x58
- +#define TWSI_SLA_REC_AD_PLS_WR_BIT_ACK_TRA 0x60
- +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_W 0x68
- +#define TWSI_GNL_CALL_REC_ACK_TRA 0x70
- +#define TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA 0x78
- +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_TRAN 0x80
- +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_NOT_TRAN 0x88
- +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_TRAN 0x90
- +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_NOT_TRAN 0x98
- +#define TWSI_SLA_REC_STOP_OR_REPEATED_STRT_CON 0xA0
- +#define TWSI_SLA_REC_AD_PLS_RD_BIT_ACK_TRA 0xA8
- +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_R 0xB0
- +#define TWSI_SLA_TRA_RD_DATA_ACK_REC 0xB8
- +#define TWSI_SLA_TRA_RD_DATA_ACK_NOT_REC 0xC0
- +#define TWSI_SLA_TRA_LAST_RD_DATA_ACK_REC 0xC8
- +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC 0xD0
- +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0xD8
- +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC 0xE0
- +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0xE8
- +#define TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0 0xF8
- +
- +
- +#ifdef __cplusplus
- +}
- +#endif /* __cplusplus */
- +
- +#endif /* __INCmvTwsiSpech */
- diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
- --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 2010-11-09 20:28:12.322486315 +0100
- @@ -0,0 +1,375 @@
- +/*******************************************************************************
- +Copyright (C) Marvell International Ltd. and its affiliates
- +
- +********************************************************************************
- +Marvell GPL License Option
- +
- +If you received this File from Marvell, you may opt to use, redistribute and/or
- +modify this File in accordance with the terms and conditions of the General
- +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
- +available along with the File in the license.txt file or by writing to the Free
- +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
- +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
- +
- +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
- +DISCLAIMED. The GPL License provides additional details about this warranty
- +disclaimer.
- +
- +*******************************************************************************/
- +/*******************************************************************************
- +* mvSysHwCfg.h - Marvell system HW configuration file
- +*
- +* DESCRIPTION:
- +* None.
- +*
- +* DEPENDENCIES:
- +* None.
- +*
- +*******************************************************************************/
- +
- +#ifndef __INCmvSysHwConfigh
- +#define __INCmvSysHwConfigh
- +
- +#include "../../../../include/linux/autoconf.h"
- +
- +#define CONFIG_MARVELL 1
- +
- +/* includes */
- +#define _1K 0x00000400
- +#define _4K 0x00001000
- +#define _8K 0x00002000
- +#define _16K 0x00004000
- +#define _32K 0x00008000
- +#define _64K 0x00010000
- +#define _128K 0x00020000
- +#define _256K 0x00040000
- +#define _512K 0x00080000
- +
- +#define _1M 0x00100000
- +#define _2M 0x00200000
- +#define _4M 0x00400000
- +#define _8M 0x00800000
- +#define _16M 0x01000000
- +#define _32M 0x02000000
- +#define _64M 0x04000000
- +#define _128M 0x08000000
- +#define _256M 0x10000000
- +#define _512M 0x20000000
- +
- +#define _1G 0x40000000
- +#define _2G 0x80000000
- +
- +/****************************************/
- +/* Soc supporeted Units definitions */
- +/****************************************/
- +
- +#ifdef CONFIG_MV_INCLUDE_PEX
- +#define MV_INCLUDE_PEX
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_TWSI
- +#define MV_INCLUDE_TWSI
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_CESA
- +#define MV_INCLUDE_CESA
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_GIG_ETH
- +#define MV_INCLUDE_GIG_ETH
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_INTEG_SATA
- +#define MV_INCLUDE_INTEG_SATA
- +#define MV_INCLUDE_SATA
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_USB
- +#define MV_INCLUDE_USB
- +#define MV_USB_VOLTAGE_FIX
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_NAND
- +#define MV_INCLUDE_NAND
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_TDM
- +#define MV_INCLUDE_TDM
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_XOR
- +#define MV_INCLUDE_XOR
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_TWSI
- +#define MV_INCLUDE_TWSI
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_UART
- +#define MV_INCLUDE_UART
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_SPI
- +#define MV_INCLUDE_SPI
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_SFLASH_MTD
- +#define MV_INCLUDE_SFLASH_MTD
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_AUDIO
- +#define MV_INCLUDE_AUDIO
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_TS
- +#define MV_INCLUDE_TS
- +#endif
- +#ifdef CONFIG_MV_INCLUDE_SDIO
- +#define MV_INCLUDE_SDIO
- +#endif
- +
- +
- +/* NAND flash stuff */
- +#ifdef CONFIG_MV_NAND_BOOT
- +#define MV_NAND_BOOT
- +#endif
- +#ifdef CONFIG_MV_NAND
- +#define MV_NAND
- +#endif
- +
- +/* SPI flash stuff */
- +#ifdef CONFIG_MV_SPI_BOOT
- +#define MV_SPI_BOOT
- +#endif
- +
- +
- +/****************************************************************/
- +/************* General configuration ********************/
- +/****************************************************************/
- +
- +/* Enable Clock Power Control */
- +#define MV_INCLUDE_CLK_PWR_CNTRL
- +
- +/* Disable the DEVICE BAR in the PEX */
- +#define MV_DISABLE_PEX_DEVICE_BAR
- +
- +/* Allow the usage of early printings during initialization */
- +#define MV_INCLUDE_EARLY_PRINTK
- +
- +/****************************************************************/
- +/************* NFP configuration ********************************/
- +/****************************************************************/
- +#define MV_NFP_SEC_Q_SIZE 64
- +#define MV_NFP_SEC_REQ_Q_SIZE 1000
- +
- +
- +
- +/****************************************************************/
- +/************* CESA configuration ********************/
- +/****************************************************************/
- +
- +#ifdef MV_INCLUDE_CESA
- +
- +#define MV_CESA_MAX_CHAN 4
- +
- +/* Use 2K of SRAM */
- +#define MV_CESA_MAX_BUF_SIZE 1600
- +
- +#endif /* MV_INCLUDE_CESA */
- +
- +#if defined(CONFIG_MV_INCLUDE_GIG_ETH)
- +
- +#ifdef CONFIG_MV_NFP_STATS
- +#define MV_FP_STATISTICS
- +#else
- +#undef MV_FP_STATISTICS
- +#endif
- +/* Default configuration for SKB_REUSE: 0 - Disabled, 1 - Enabled */
- +#define MV_ETH_SKB_REUSE_DEFAULT 1
- +/* Default configuration for TX_EN workaround: 0 - Disabled, 1 - Enabled */
- +#define MV_ETH_TX_EN_DEFAULT 0
- +
- +/* un-comment if you want to perform tx_done from within the poll function */
- +/* #define ETH_TX_DONE_ISR */
- +
- +/* put descriptors in uncached memory */
- +/* #define ETH_DESCR_UNCACHED */
- +
- +/* Descriptors location: DRAM/internal-SRAM */
- +#define ETH_DESCR_IN_SDRAM
- +#undef ETH_DESCR_IN_SRAM /* No integrated SRAM in 88Fxx81 devices */
- +
- +#if defined(ETH_DESCR_IN_SRAM)
- +#if defined(ETH_DESCR_UNCACHED)
- + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in integrated SRAM"
- +#else
- + #define ETH_DESCR_CONFIG_STR "Cached descriptors in integrated SRAM"
- +#endif
- +#elif defined(ETH_DESCR_IN_SDRAM)
- +#if defined(ETH_DESCR_UNCACHED)
- + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in DRAM"
- +#else
- + #define ETH_DESCR_CONFIG_STR "Cached descriptors in DRAM"
- +#endif
- +#else
- + #error "Ethernet descriptors location undefined"
- +#endif /* ETH_DESCR_IN_SRAM or ETH_DESCR_IN_SDRAM*/
- +
- +/* SW Sync-Barrier: not relevant for 88fxx81*/
- +/* Reasnable to define this macro when descriptors in SRAM and buffers in DRAM */
- +/* In RX the CPU theoretically might see himself as the descriptor owner, */
- +/* although the buffer hadn't been written to DRAM yet. Performance cost. */
- +/* #define INCLUDE_SYNC_BARR */
- +
- +/* Buffers cache coherency method (buffers in DRAM) */
- +#ifndef MV_CACHE_COHER_SW
- +/* Taken from mvCommon.h */
- +/* Memory uncached, HW or SW cache coherency is not needed */
- +#define MV_UNCACHED 0
- +/* Memory cached, HW cache coherency supported in WriteThrough mode */
- +#define MV_CACHE_COHER_HW_WT 1
- +/* Memory cached, HW cache coherency supported in WriteBack mode */
- +#define MV_CACHE_COHER_HW_WB 2
- +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
- +#define MV_CACHE_COHER_SW 3
- +
- +#endif
- +
- +/* DRAM cache coherency configuration */
- +#define MV_CACHE_COHERENCY MV_CACHE_COHER_SW
- +
- +
- +#define ETHER_DRAM_COHER MV_CACHE_COHER_SW /* No HW coherency in 88Fxx81 devices */
- +
- +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB)
- + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-back)"
- +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT)
- + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-through)"
- +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
- + #define ETH_SDRAM_CONFIG_STR "DRAM SW cache-coherency"
- +#elif (ETHER_DRAM_COHER == MV_UNCACHED)
- +# define ETH_SDRAM_CONFIG_STR "DRAM uncached"
- +#else
- + #error "Ethernet-DRAM undefined"
- +#endif /* ETHER_DRAM_COHER */
- +
- +
- +/****************************************************************/
- +/************* Ethernet driver configuration ********************/
- +/****************************************************************/
- +
- +/* port's default queueus */
- +#define ETH_DEF_TXQ 0
- +#define ETH_DEF_RXQ 0
- +
- +#define MV_ETH_RX_Q_NUM CONFIG_MV_ETH_RX_Q_NUM
- +#define MV_ETH_TX_Q_NUM CONFIG_MV_ETH_TX_Q_NUM
- +
- +/* interrupt coalescing setting */
- +#define ETH_TX_COAL 200
- +#define ETH_RX_COAL 200
- +
- +/* Checksum offloading */
- +#define TX_CSUM_OFFLOAD
- +#define RX_CSUM_OFFLOAD
- +
- +#endif /* CONFIG_MV_INCLUDE_GIG_ETH */
- +
- +/****************************************************************/
- +/*************** Telephony configuration ************************/
- +/****************************************************************/
- +#if defined(CONFIG_MV_TDM_LINEAR_MODE)
- + #define MV_TDM_LINEAR_MODE
- +#elif defined(CONFIG_MV_TDM_ULAW_MODE)
- + #define MV_TDM_ULAW_MODE
- +#endif
- +
- +#if defined(CONFIG_MV_TDM_5CHANNELS)
- + #define MV_TDM_5CHANNELS
- +#endif
- +
- +#if defined(CONFIG_MV_TDM_USE_EXTERNAL_PCLK_SOURCE)
- + #define MV_TDM_USE_EXTERNAL_PCLK_SOURCE
- +#endif
- +
- +/* We use the following registers to store DRAM interface pre configuration */
- +/* auto-detection results */
- +/* IMPORTANT: We are using mask register for that purpose. Before writing */
- +/* to units mask register, make sure main maks register is set to disable */
- +/* all interrupts. */
- +#define DRAM_BUF_REG0 0x30810 /* sdram bank 0 size */
- +#define DRAM_BUF_REG1 0x30820 /* sdram config */
- +#define DRAM_BUF_REG2 0x30830 /* sdram mode */
- +#define DRAM_BUF_REG3 0x308c4 /* dunit control low */
- +#define DRAM_BUF_REG4 0x60a90 /* sdram address control */
- +#define DRAM_BUF_REG5 0x60a94 /* sdram timing control low */
- +#define DRAM_BUF_REG6 0x60a98 /* sdram timing control high */
- +#define DRAM_BUF_REG7 0x60a9c /* sdram ODT control low */
- +#define DRAM_BUF_REG8 0x60b90 /* sdram ODT control high */
- +#define DRAM_BUF_REG9 0x60b94 /* sdram Dunit ODT control */
- +#define DRAM_BUF_REG10 0x60b98 /* sdram Extended Mode */
- +#define DRAM_BUF_REG11 0x60b9c /* sdram Ddr2 Time Low Reg */
- +#define DRAM_BUF_REG12 0x60a00 /* sdram Ddr2 Time High Reg */
- +#define DRAM_BUF_REG13 0x60a04 /* dunit Ctrl High */
- +#define DRAM_BUF_REG14 0x60b00 /* sdram second DIMM exist */
- +
- +/* Following the pre-configuration registers default values restored after */
- +/* auto-detection is done */
- +#define DRAM_BUF_REG_DV 0
- +
- +/* System Mapping */
- +#define SDRAM_CS0_BASE 0x00000000
- +#define SDRAM_CS0_SIZE _256M
- +
- +#define SDRAM_CS1_BASE 0x10000000
- +#define SDRAM_CS1_SIZE _256M
- +
- +#define SDRAM_CS2_BASE 0x20000000
- +#define SDRAM_CS2_SIZE _256M
- +
- +#define SDRAM_CS3_BASE 0x30000000
- +#define SDRAM_CS3_SIZE _256M
- +
- +/* PEX */
- +#define PEX0_MEM_BASE 0xe8000000
- +#define PEX0_MEM_SIZE _128M
- +
- +#define PEX0_IO_BASE 0xf2000000
- +#define PEX0_IO_SIZE _1M
- +
- +/* Device Chip Selects */
- +#define NFLASH_CS_BASE 0xfa000000
- +#define NFLASH_CS_SIZE _2M
- +
- +#define SPI_CS_BASE 0xf4000000
- +#define SPI_CS_SIZE _16M
- +
- +#define CRYPT_ENG_BASE 0xf0000000
- +#define CRYPT_ENG_SIZE _2M
- +
- +#define BOOTDEV_CS_BASE 0xff800000
- +#define BOOTDEV_CS_SIZE _8M
- +
- +/* CS2 - BOOTROM */
- +#define DEVICE_CS2_BASE 0xff900000
- +#define DEVICE_CS2_SIZE _1M
- +
- +/* PEX Work arround */
- +/* the target we will use for the workarround */
- +#define PEX_CONFIG_RW_WA_TARGET PEX0_MEM
- +/*a flag that indicates if we are going to use the
- +size and base of the target we using for the workarround
- +window */
- +#define PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES 1
- +/* if the above flag is 0 then the following values
- +will be used for the workarround window base and size,
- +otherwise the following defines will be ignored */
- +#define PEX_CONFIG_RW_WA_BASE 0xF3000000
- +#define PEX_CONFIG_RW_WA_SIZE _16M
- +
- +/* Internal registers: size is defined in Controllerenvironment */
- +#define INTER_REGS_BASE 0xFEE00000
- +
- +/* DRAM detection stuff */
- +#define MV_DRAM_AUTO_SIZE
- +
- +/* Board clock detection */
- +#define TCLK_AUTO_DETECT /* Use Tclk auto detection */
- +#define SYSCLK_AUTO_DETECT /* Use SysClk auto detection */
- +#define PCLCK_AUTO_DETECT /* Use PClk auto detection */
- +#define L2CLK_AUTO_DETECT /* Use L2Clk auto detection */
- +
- +/* PEX-PCI\PCI-PCI Bridge*/
- +#define PCI0_IF_PTP 0 /* Bridge exist on pciIf0*/
- +
- +
- +
- +#endif /* __INCmvSysHwConfigh */
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/Makefile linux-2.6.36/crypto/ocf/Makefile
- --- linux-2.6.36.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/Makefile 2010-11-09 20:28:12.342495369 +0100
- @@ -0,0 +1,124 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +OCF_OBJS = crypto.o criov.o
- +
- +ifdef CONFIG_OCF_RANDOMHARVEST
- + OCF_OBJS += random.o
- +endif
- +
- +ifdef CONFIG_OCF_FIPS
- + OCF_OBJS += rndtest.o
- +endif
- +
- +# Add in autoconf.h to get #defines for CONFIG_xxx
- +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
- +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
- + EXTRA_CFLAGS += -include $(AUTOCONF_H)
- + export EXTRA_CFLAGS
- +endif
- +
- +ifndef obj
- + obj ?= .
- + _obj = subdir
- + mod-subdirs := safe hifn ixp4xx talitos ocfnull
- + export-objs += crypto.o criov.o random.o
- + list-multi += ocf.o
- + _slash :=
- +else
- + _obj = obj
- + _slash := /
- +endif
- +
- +EXTRA_CFLAGS += -I$(obj)/.
- +
- +obj-$(CONFIG_OCF_OCF) += ocf.o
- +obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
- +obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
- +obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
- +
- +$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
- +$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
- +$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
- +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
- +$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
- +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
- +$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
- +$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
- +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
- +$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
- +
- +ocf-objs := $(OCF_OBJS)
- +
- +$(list-multi) dummy1: $(ocf-objs)
- + $(LD) -r -o $@ $(ocf-objs)
- +
- +.PHONY:
- +clean:
- + rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
- + rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- +#
- +# release gen targets
- +#
- +
- +.PHONY: patch
- +patch:
- + REL=`date +%Y%m%d`; \
- + patch=ocf-linux-$$REL.patch; \
- + patch24=ocf-linux-24-$$REL.patch; \
- + patch26=ocf-linux-26-$$REL.patch; \
- + ( \
- + find . -name Makefile; \
- + find . -name Config.in; \
- + find . -name Kconfig; \
- + find . -name README; \
- + find . -name '*.[ch]' | grep -v '.mod.c'; \
- + ) | while read t; do \
- + diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
- + done > $$patch; \
- + cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
- + cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26
- +
- +.PHONY: tarball
- +tarball:
- + REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
- + CURDIR=`pwd`; \
- + rm -rf /tmp/ocf-linux-$$REL*; \
- + mkdir -p $$RELDIR/tools; \
- + cp README* $$RELDIR; \
- + cp patches/openss*.patch $$RELDIR; \
- + cp patches/crypto-tools.patch $$RELDIR; \
- + cp tools/[!C]* $$RELDIR/tools; \
- + cd ..; \
- + tar cvf $$RELDIR/ocf-linux.tar \
- + --exclude=CVS \
- + --exclude=.* \
- + --exclude=*.o \
- + --exclude=*.ko \
- + --exclude=*.mod.* \
- + --exclude=README* \
- + --exclude=ocf-*.patch \
- + --exclude=ocf/patches/openss*.patch \
- + --exclude=ocf/patches/crypto-tools.patch \
- + --exclude=ocf/tools \
- + ocf; \
- + gzip -9 $$RELDIR/ocf-linux.tar; \
- + cd /tmp; \
- + tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
- + gzip -9 ocf-linux-$$REL.tar; \
- + cd $$CURDIR/../../user; \
- + rm -rf /tmp/crypto-tools-$$REL*; \
- + tar cvf /tmp/crypto-tools-$$REL.tar \
- + --exclude=CVS \
- + --exclude=.* \
- + --exclude=*.o \
- + --exclude=cryptotest \
- + --exclude=cryptokeytest \
- + crypto-tools; \
- + gzip -9 /tmp/crypto-tools-$$REL.tar
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/ocf-bench.c linux-2.6.36/crypto/ocf/ocf-bench.c
- --- linux-2.6.36.orig/crypto/ocf/ocf-bench.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ocf-bench.c 2010-11-09 20:28:12.381251524 +0100
- @@ -0,0 +1,436 @@
- +/*
- + * A loadable module that benchmarks the OCF crypto speed from kernel space.
- + *
- + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * ALTERNATIVELY, provided that this notice is retained in full, this product
- + * may be distributed under the terms of the GNU General Public License (GPL),
- + * in which case the provisions of the GPL apply INSTEAD OF those given above.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + */
- +
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/wait.h>
- +#include <linux/sched.h>
- +#include <linux/spinlock.h>
- +#include <linux/version.h>
- +#include <linux/interrupt.h>
- +#include <cryptodev.h>
- +
- +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
- +#define BENCH_IXP_ACCESS_LIB 1
- +#endif
- +#ifdef BENCH_IXP_ACCESS_LIB
- +#include <IxTypes.h>
- +#include <IxOsBuffMgt.h>
- +#include <IxNpeDl.h>
- +#include <IxCryptoAcc.h>
- +#include <IxQMgr.h>
- +#include <IxOsServices.h>
- +#include <IxOsCacheMMU.h>
- +#endif
- +
- +/*
- + * support for access lib version 1.4
- + */
- +#ifndef IX_MBUF_PRIV
- +#define IX_MBUF_PRIV(x) ((x)->priv)
- +#endif
- +
- +/*
- + * the number of simultaneously active requests
- + */
- +static int request_q_len = 20;
- +module_param(request_q_len, int, 0);
- +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
- +/*
- + * how many requests we want to have processed
- + */
- +static int request_num = 1024;
- +module_param(request_num, int, 0);
- +MODULE_PARM_DESC(request_num, "run for at least this many requests");
- +/*
- + * the size of each request
- + */
- +static int request_size = 1500;
- +module_param(request_size, int, 0);
- +MODULE_PARM_DESC(request_size, "size of each request");
- +
- +/*
- + * a structure for each request
- + */
- +typedef struct {
- + struct work_struct work;
- +#ifdef BENCH_IXP_ACCESS_LIB
- + IX_MBUF mbuf;
- +#endif
- + unsigned char *buffer;
- +} request_t;
- +
- +static request_t *requests;
- +
- +static int outstanding;
- +static int total;
- +
- +/*************************************************************************/
- +/*
- + * OCF benchmark routines
- + */
- +
- +static uint64_t ocf_cryptoid;
- +static int ocf_init(void);
- +static int ocf_cb(struct cryptop *crp);
- +static void ocf_request(void *arg);
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +static void ocf_request_wq(struct work_struct *work);
- +#endif
- +
- +static int
- +ocf_init(void)
- +{
- + int error;
- + struct cryptoini crie, cria;
- + struct cryptodesc crda, crde;
- +
- + memset(&crie, 0, sizeof(crie));
- + memset(&cria, 0, sizeof(cria));
- + memset(&crde, 0, sizeof(crde));
- + memset(&crda, 0, sizeof(crda));
- +
- + cria.cri_alg = CRYPTO_SHA1_HMAC;
- + cria.cri_klen = 20 * 8;
- + cria.cri_key = "0123456789abcdefghij";
- +
- + crie.cri_alg = CRYPTO_3DES_CBC;
- + crie.cri_klen = 24 * 8;
- + crie.cri_key = "0123456789abcdefghijklmn";
- +
- + crie.cri_next = &cria;
- +
- + error = crypto_newsession(&ocf_cryptoid, &crie, 0);
- + if (error) {
- + printk("crypto_newsession failed %d\n", error);
- + return -1;
- + }
- + return 0;
- +}
- +
- +static int
- +ocf_cb(struct cryptop *crp)
- +{
- + request_t *r = (request_t *) crp->crp_opaque;
- +
- + if (crp->crp_etype)
- + printk("Error in OCF processing: %d\n", crp->crp_etype);
- + total++;
- + crypto_freereq(crp);
- + crp = NULL;
- +
- + if (total > request_num) {
- + outstanding--;
- + return 0;
- + }
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + INIT_WORK(&r->work, ocf_request_wq);
- +#else
- + INIT_WORK(&r->work, ocf_request, r);
- +#endif
- + schedule_work(&r->work);
- + return 0;
- +}
- +
- +
- +static void
- +ocf_request(void *arg)
- +{
- + request_t *r = arg;
- + struct cryptop *crp = crypto_getreq(2);
- + struct cryptodesc *crde, *crda;
- +
- + if (!crp) {
- + outstanding--;
- + return;
- + }
- +
- + crde = crp->crp_desc;
- + crda = crde->crd_next;
- +
- + crda->crd_skip = 0;
- + crda->crd_flags = 0;
- + crda->crd_len = request_size;
- + crda->crd_inject = request_size;
- + crda->crd_alg = CRYPTO_SHA1_HMAC;
- + crda->crd_key = "0123456789abcdefghij";
- + crda->crd_klen = 20 * 8;
- +
- + crde->crd_skip = 0;
- + crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
- + crde->crd_len = request_size;
- + crde->crd_inject = request_size;
- + crde->crd_alg = CRYPTO_3DES_CBC;
- + crde->crd_key = "0123456789abcdefghijklmn";
- + crde->crd_klen = 24 * 8;
- +
- + crp->crp_ilen = request_size + 64;
- + crp->crp_flags = CRYPTO_F_CBIMM;
- + crp->crp_buf = (caddr_t) r->buffer;
- + crp->crp_callback = ocf_cb;
- + crp->crp_sid = ocf_cryptoid;
- + crp->crp_opaque = (caddr_t) r;
- + crypto_dispatch(crp);
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +static void
- +ocf_request_wq(struct work_struct *work)
- +{
- + request_t *r = container_of(work, request_t, work);
- + ocf_request(r);
- +}
- +#endif
- +
- +/*************************************************************************/
- +#ifdef BENCH_IXP_ACCESS_LIB
- +/*************************************************************************/
- +/*
- + * CryptoAcc benchmark routines
- + */
- +
- +static IxCryptoAccCtx ixp_ctx;
- +static UINT32 ixp_ctx_id;
- +static IX_MBUF ixp_pri;
- +static IX_MBUF ixp_sec;
- +static int ixp_registered = 0;
- +
- +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
- + IxCryptoAccStatus status);
- +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
- + IxCryptoAccStatus status);
- +static void ixp_request(void *arg);
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +static void ixp_request_wq(struct work_struct *work);
- +#endif
- +
- +static int
- +ixp_init(void)
- +{
- + IxCryptoAccStatus status;
- +
- + ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
- + ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
- + ixp_ctx.cipherCtx.cipherKeyLen = 24;
- + ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
- + ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
- + memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
- +
- + ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
- + ixp_ctx.authCtx.authDigestLen = 12;
- + ixp_ctx.authCtx.aadLen = 0;
- + ixp_ctx.authCtx.authKeyLen = 20;
- + memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
- +
- + ixp_ctx.useDifferentSrcAndDestMbufs = 0;
- + ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
- +
- + IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
- + IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
- + IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
- + IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
- +
- + status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
- + ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
- +
- + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
- + while (!ixp_registered)
- + schedule();
- + return ixp_registered < 0 ? -1 : 0;
- + }
- +
- + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
- + return -1;
- +}
- +
- +static void
- +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
- +{
- + if (bufp) {
- + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
- + kfree(IX_MBUF_MDATA(bufp));
- + IX_MBUF_MDATA(bufp) = NULL;
- + }
- +
- + if (IX_CRYPTO_ACC_STATUS_WAIT == status)
- + return;
- + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
- + ixp_registered = 1;
- + else
- + ixp_registered = -1;
- +}
- +
- +static void
- +ixp_perform_cb(
- + UINT32 ctx_id,
- + IX_MBUF *sbufp,
- + IX_MBUF *dbufp,
- + IxCryptoAccStatus status)
- +{
- + request_t *r = NULL;
- +
- + total++;
- + if (total > request_num) {
- + outstanding--;
- + return;
- + }
- +
- + if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
- + printk("crappo %p %p\n", sbufp, r);
- + outstanding--;
- + return;
- + }
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + INIT_WORK(&r->work, ixp_request_wq);
- +#else
- + INIT_WORK(&r->work, ixp_request, r);
- +#endif
- + schedule_work(&r->work);
- +}
- +
- +static void
- +ixp_request(void *arg)
- +{
- + request_t *r = arg;
- + IxCryptoAccStatus status;
- +
- + memset(&r->mbuf, 0, sizeof(r->mbuf));
- + IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
- + IX_MBUF_MDATA(&r->mbuf) = r->buffer;
- + IX_MBUF_PRIV(&r->mbuf) = r;
- + status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
- + 0, request_size, 0, request_size, request_size, r->buffer);
- + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
- + printk("status1 = %d\n", status);
- + outstanding--;
- + return;
- + }
- + return;
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +static void
- +ixp_request_wq(struct work_struct *work)
- +{
- + request_t *r = container_of(work, request_t, work);
- + ixp_request(r);
- +}
- +#endif
- +
- +/*************************************************************************/
- +#endif /* BENCH_IXP_ACCESS_LIB */
- +/*************************************************************************/
- +
- +int
- +ocfbench_init(void)
- +{
- + int i, jstart, jstop;
- +
- + printk("Crypto Speed tests\n");
- +
- + requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
- + if (!requests) {
- + printk("malloc failed\n");
- + return -EINVAL;
- + }
- +
- + for (i = 0; i < request_q_len; i++) {
- + /* +64 for return data */
- + requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
- + if (!requests[i].buffer) {
- + printk("malloc failed\n");
- + return -EINVAL;
- + }
- + memset(requests[i].buffer, '0' + i, request_size + 128);
- + }
- +
- + /*
- + * OCF benchmark
- + */
- + printk("OCF: testing ...\n");
- + ocf_init();
- + total = outstanding = 0;
- + jstart = jiffies;
- + for (i = 0; i < request_q_len; i++) {
- + outstanding++;
- + ocf_request(&requests[i]);
- + }
- + while (outstanding > 0)
- + schedule();
- + jstop = jiffies;
- +
- + printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
- + jstop - jstart);
- +
- +#ifdef BENCH_IXP_ACCESS_LIB
- + /*
- + * IXP benchmark
- + */
- + printk("IXP: testing ...\n");
- + ixp_init();
- + total = outstanding = 0;
- + jstart = jiffies;
- + for (i = 0; i < request_q_len; i++) {
- + outstanding++;
- + ixp_request(&requests[i]);
- + }
- + while (outstanding > 0)
- + schedule();
- + jstop = jiffies;
- +
- + printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
- + jstop - jstart);
- +#endif /* BENCH_IXP_ACCESS_LIB */
- +
- + for (i = 0; i < request_q_len; i++)
- + kfree(requests[i].buffer);
- + kfree(requests);
- + return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
- +}
- +
- +static void __exit ocfbench_exit(void)
- +{
- +}
- +
- +module_init(ocfbench_init);
- +module_exit(ocfbench_exit);
- +
- +MODULE_LICENSE("BSD");
- +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
- +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
- diff -Nur linux-2.6.36.orig/crypto/ocf/ocf-compat.h linux-2.6.36/crypto/ocf/ocf-compat.h
- --- linux-2.6.36.orig/crypto/ocf/ocf-compat.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ocf-compat.h 2010-11-09 20:28:12.422358492 +0100
- @@ -0,0 +1,294 @@
- +#ifndef _BSD_COMPAT_H_
- +#define _BSD_COMPAT_H_ 1
- +/****************************************************************************/
- +/*
- + * Provide compat routines for older linux kernels and BSD kernels
- + *
- + * Written by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * ALTERNATIVELY, provided that this notice is retained in full, this file
- + * may be distributed under the terms of the GNU General Public License (GPL),
- + * in which case the provisions of the GPL apply INSTEAD OF those given above.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + */
- +/****************************************************************************/
- +#ifdef __KERNEL__
- +/*
- + * fake some BSD driver interface stuff specifically for OCF use
- + */
- +
- +typedef struct ocf_device *device_t;
- +
- +typedef struct {
- + int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
- + int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
- + int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
- + int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
- +} device_method_t;
- +#define DEVMETHOD(id, func) id: func
- +
- +struct ocf_device {
- + char name[32]; /* the driver name */
- + char nameunit[32]; /* the driver name + HW instance */
- + int unit;
- + device_method_t methods;
- + void *softc;
- +};
- +
- +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
- + ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
- +#define CRYPTODEV_FREESESSION(dev, sid) \
- + ((*(dev)->methods.cryptodev_freesession)(dev, sid))
- +#define CRYPTODEV_PROCESS(dev, crp, hint) \
- + ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
- +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
- + ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
- +
- +#define device_get_name(dev) ((dev)->name)
- +#define device_get_nameunit(dev) ((dev)->nameunit)
- +#define device_get_unit(dev) ((dev)->unit)
- +#define device_get_softc(dev) ((dev)->softc)
- +
- +#define softc_device_decl \
- + struct ocf_device _device; \
- + device_t
- +
- +#define softc_device_init(_sc, _name, _unit, _methods) \
- + if (1) {\
- + strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
- + snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
- + (_sc)->_device.unit = _unit; \
- + (_sc)->_device.methods = _methods; \
- + (_sc)->_device.softc = (void *) _sc; \
- + *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
- + } else
- +
- +#define softc_get_device(_sc) (&(_sc)->_device)
- +
- +/*
- + * iomem support for 2.4 and 2.6 kernels
- + */
- +#include <linux/version.h>
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- +#define ocf_iomem_t unsigned long
- +
- +/*
- + * implement simple workqueue like support for older kernels
- + */
- +
- +#include <linux/tqueue.h>
- +
- +#define work_struct tq_struct
- +
- +#define INIT_WORK(wp, fp, ap) \
- + do { \
- + (wp)->sync = 0; \
- + (wp)->routine = (fp); \
- + (wp)->data = (ap); \
- + } while (0)
- +
- +#define schedule_work(wp) \
- + do { \
- + queue_task((wp), &tq_immediate); \
- + mark_bh(IMMEDIATE_BH); \
- + } while (0)
- +
- +#define flush_scheduled_work() run_task_queue(&tq_immediate)
- +
- +#else
- +#define ocf_iomem_t void __iomem *
- +
- +#include <linux/workqueue.h>
- +
- +#endif
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
- +#include <linux/fdtable.h>
- +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
- +#define files_fdtable(files) (files)
- +#endif
- +
- +#ifdef MODULE_PARM
- +#undef module_param /* just in case */
- +#define module_param(a,b,c) MODULE_PARM(a,"i")
- +#endif
- +
- +#define bzero(s,l) memset(s,0,l)
- +#define bcopy(s,d,l) memcpy(d,s,l)
- +#define bcmp(x, y, l) memcmp(x,y,l)
- +
- +#define MIN(x,y) ((x) < (y) ? (x) : (y))
- +
- +#define device_printf(dev, a...) ({ \
- + printk("%s: ", device_get_nameunit(dev)); printk(a); \
- + })
- +
- +#undef printf
- +#define printf(fmt...) printk(fmt)
- +
- +#define KASSERT(c,p) if (!(c)) { printk p ; } else
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- +#define ocf_daemonize(str) \
- + daemonize(); \
- + spin_lock_irq(¤t->sigmask_lock); \
- + sigemptyset(¤t->blocked); \
- + recalc_sigpending(current); \
- + spin_unlock_irq(¤t->sigmask_lock); \
- + sprintf(current->comm, str);
- +#else
- +#define ocf_daemonize(str) daemonize(str);
- +#endif
- +
- +#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
- +#define TAILQ_EMPTY(q) list_empty(q)
- +#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
- +
- +#define read_random(p,l) get_random_bytes(p,l)
- +
- +#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
- +#define strtoul simple_strtoul
- +
- +#define pci_get_vendor(dev) ((dev)->vendor)
- +#define pci_get_device(dev) ((dev)->device)
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- +#define pci_set_consistent_dma_mask(dev, mask) (0)
- +#endif
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
- +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
- +#endif
- +
- +#ifndef DMA_32BIT_MASK
- +#define DMA_32BIT_MASK 0x00000000ffffffffULL
- +#endif
- +
- +#ifndef htole32
- +#define htole32(x) cpu_to_le32(x)
- +#endif
- +#ifndef htobe32
- +#define htobe32(x) cpu_to_be32(x)
- +#endif
- +#ifndef htole16
- +#define htole16(x) cpu_to_le16(x)
- +#endif
- +#ifndef htobe16
- +#define htobe16(x) cpu_to_be16(x)
- +#endif
- +
- +/* older kernels don't have these */
- +
- +#include <asm/irq.h>
- +#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
- +#define IRQ_NONE
- +#define IRQ_HANDLED
- +#define IRQ_WAKE_THREAD
- +#define IRQ_RETVAL
- +#define irqreturn_t void
- +typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
- +#endif
- +#ifndef IRQF_SHARED
- +#define IRQF_SHARED SA_SHIRQ
- +#endif
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- +# define strlcpy(dest,src,len) \
- + ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
- +#endif
- +
- +#ifndef MAX_ERRNO
- +#define MAX_ERRNO 4095
- +#endif
- +#ifndef IS_ERR_VALUE
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
- +#include <linux/err.h>
- +#endif
- +#ifndef IS_ERR_VALUE
- +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
- +#endif
- +#endif
- +
- +/*
- + * common debug for all
- + */
- +#if 1
- +#define dprintk(a...) do { if (debug) printk(a); } while(0)
- +#else
- +#define dprintk(a...)
- +#endif
- +
- +#ifndef SLAB_ATOMIC
- +/* Changed in 2.6.20, must use GFP_ATOMIC now */
- +#define SLAB_ATOMIC GFP_ATOMIC
- +#endif
- +
- +/*
- + * need some additional support for older kernels */
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
- +#define pci_register_driver_compat(driver, rc) \
- + do { \
- + if ((rc) > 0) { \
- + (rc) = 0; \
- + } else if (rc == 0) { \
- + (rc) = -ENODEV; \
- + } else { \
- + pci_unregister_driver(driver); \
- + } \
- + } while (0)
- +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
- +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
- +#else
- +#define pci_register_driver_compat(driver,rc)
- +#endif
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- +
- +#include <linux/mm.h>
- +#include <asm/scatterlist.h>
- +
- +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
- + unsigned int len, unsigned int offset)
- +{
- + sg->page = page;
- + sg->offset = offset;
- + sg->length = len;
- +}
- +
- +static inline void *sg_virt(struct scatterlist *sg)
- +{
- + return page_address(sg->page) + sg->offset;
- +}
- +
- +#define sg_init_table(sg, n)
- +
- +#endif
- +
- +#ifndef late_initcall
- +#define late_initcall(init) module_init(init)
- +#endif
- +
- +#endif /* __KERNEL__ */
- +
- +/****************************************************************************/
- +#endif /* _BSD_COMPAT_H_ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/ocfnull/Makefile linux-2.6.36/crypto/ocf/ocfnull/Makefile
- --- linux-2.6.36.orig/crypto/ocf/ocfnull/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ocfnull/Makefile 2010-11-09 20:28:12.462495574 +0100
- @@ -0,0 +1,12 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += -I$(obj)/..
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.36/crypto/ocf/ocfnull/ocfnull.c
- --- linux-2.6.36.orig/crypto/ocf/ocfnull/ocfnull.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/ocfnull/ocfnull.c 2010-11-09 20:28:12.501251038 +0100
- @@ -0,0 +1,203 @@
- +/*
- + * An OCF module for determining the cost of crypto versus the cost of
- + * IPSec processing outside of OCF. This modules gives us the effect of
- + * zero cost encryption, of course you will need to run it at both ends
- + * since it does no crypto at all.
- + *
- + * Written by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * ALTERNATIVELY, provided that this notice is retained in full, this product
- + * may be distributed under the terms of the GNU General Public License (GPL),
- + * in which case the provisions of the GPL apply INSTEAD OF those given above.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/sched.h>
- +#include <linux/wait.h>
- +#include <linux/crypto.h>
- +#include <linux/interrupt.h>
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +
- +static int32_t null_id = -1;
- +static u_int32_t null_sesnum = 0;
- +
- +static int null_process(device_t, struct cryptop *, int);
- +static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
- +static int null_freesession(device_t, u_int64_t);
- +
- +#define debug ocfnull_debug
- +int ocfnull_debug = 0;
- +module_param(ocfnull_debug, int, 0644);
- +MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
- +
- +/*
- + * dummy device structure
- + */
- +
- +static struct {
- + softc_device_decl sc_dev;
- +} nulldev;
- +
- +static device_method_t null_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, null_newsession),
- + DEVMETHOD(cryptodev_freesession,null_freesession),
- + DEVMETHOD(cryptodev_process, null_process),
- +};
- +
- +/*
- + * Generate a new software session.
- + */
- +static int
- +null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid == NULL || cri == NULL) {
- + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + if (null_sesnum == 0)
- + null_sesnum++;
- + *sid = null_sesnum++;
- + return 0;
- +}
- +
- +
- +/*
- + * Free a session.
- + */
- +static int
- +null_freesession(device_t arg, u_int64_t tid)
- +{
- + u_int32_t sid = CRYPTO_SESID2LID(tid);
- +
- + dprintk("%s()\n", __FUNCTION__);
- + if (sid > null_sesnum) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + /* Silently accept and return */
- + if (sid == 0)
- + return 0;
- + return 0;
- +}
- +
- +
- +/*
- + * Process a request.
- + */
- +static int
- +null_process(device_t arg, struct cryptop *crp, int hint)
- +{
- + unsigned int lid;
- +
- + dprintk("%s()\n", __FUNCTION__);
- +
- + /* Sanity check */
- + if (crp == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- +
- + crp->crp_etype = 0;
- +
- + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
- + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- + crp->crp_etype = EINVAL;
- + goto done;
- + }
- +
- + /*
- + * find the session we are using
- + */
- +
- + lid = crp->crp_sid & 0xffffffff;
- + if (lid >= null_sesnum || lid == 0) {
- + crp->crp_etype = ENOENT;
- + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
- + goto done;
- + }
- +
- +done:
- + crypto_done(crp);
- + return 0;
- +}
- +
- +
- +/*
- + * our driver startup and shutdown routines
- + */
- +
- +static int
- +null_init(void)
- +{
- + dprintk("%s(%p)\n", __FUNCTION__, null_init);
- +
- + memset(&nulldev, 0, sizeof(nulldev));
- + softc_device_init(&nulldev, "ocfnull", 0, null_methods);
- +
- + null_id = crypto_get_driverid(softc_get_device(&nulldev),
- + CRYPTOCAP_F_HARDWARE);
- + if (null_id < 0)
- + panic("ocfnull: crypto device cannot initialize!");
- +
- +#define REGISTER(alg) \
- + crypto_register(null_id,alg,0,0)
- + REGISTER(CRYPTO_DES_CBC);
- + REGISTER(CRYPTO_3DES_CBC);
- + REGISTER(CRYPTO_RIJNDAEL128_CBC);
- + REGISTER(CRYPTO_MD5);
- + REGISTER(CRYPTO_SHA1);
- + REGISTER(CRYPTO_MD5_HMAC);
- + REGISTER(CRYPTO_SHA1_HMAC);
- +#undef REGISTER
- +
- + return 0;
- +}
- +
- +static void
- +null_exit(void)
- +{
- + dprintk("%s()\n", __FUNCTION__);
- + crypto_unregister_all(null_id);
- + null_id = -1;
- +}
- +
- +module_init(null_init);
- +module_exit(null_exit);
- +
- +MODULE_LICENSE("Dual BSD/GPL");
- +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
- +MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
- diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/Makefile linux-2.6.36/crypto/ocf/pasemi/Makefile
- --- linux-2.6.36.orig/crypto/ocf/pasemi/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/pasemi/Makefile 2010-11-09 20:28:12.532495480 +0100
- @@ -0,0 +1,12 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.36/crypto/ocf/pasemi/pasemi.c
- --- linux-2.6.36.orig/crypto/ocf/pasemi/pasemi.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/pasemi/pasemi.c 2010-11-09 20:28:12.572495531 +0100
- @@ -0,0 +1,1009 @@
- +/*
- + * Copyright (C) 2007 PA Semi, Inc
- + *
- + * Driver for the PA Semi PWRficient DMA Crypto Engine
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/interrupt.h>
- +#include <linux/timer.h>
- +#include <linux/random.h>
- +#include <linux/skbuff.h>
- +#include <asm/scatterlist.h>
- +#include <linux/moduleparam.h>
- +#include <linux/pci.h>
- +#include <cryptodev.h>
- +#include <uio.h>
- +#include "pasemi_fnu.h"
- +
- +#define DRV_NAME "pasemi"
- +
- +#define TIMER_INTERVAL 1000
- +
- +static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
- +static struct pasdma_status volatile * dma_status;
- +
- +static int debug;
- +module_param(debug, int, 0644);
- +MODULE_PARM_DESC(debug, "Enable debug");
- +
- +static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
- +{
- + desc->postop = 0;
- + desc->quad[0] = hdr;
- + desc->quad_cnt = 1;
- + desc->size = 1;
- +}
- +
- +static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
- +{
- + desc->quad[desc->quad_cnt++] = val;
- + desc->size = (desc->quad_cnt + 1) / 2;
- +}
- +
- +static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
- +{
- + desc->quad[0] |= hdr;
- +}
- +
- +static int pasemi_desc_size(struct pasemi_desc *desc)
- +{
- + return desc->size;
- +}
- +
- +static void pasemi_ring_add_desc(
- + struct pasemi_fnu_txring *ring,
- + struct pasemi_desc *desc,
- + struct cryptop *crp) {
- + int i;
- + int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
- +
- + TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
- + TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
- + TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
- +
- + for (i = 0; i < desc->quad_cnt; i += 2) {
- + ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
- + ring->desc[ring_index] = desc->quad[i];
- + ring->desc[ring_index + 1] = desc->quad[i + 1];
- + ring->next_to_fill++;
- + }
- +
- + if (desc->quad_cnt & 1)
- + ring->desc[ring_index + 1] = 0;
- +}
- +
- +static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
- +{
- + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
- + incr);
- +}
- +
- +/*
- + * Generate a new software session.
- + */
- +static int
- +pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
- +{
- + struct cryptoini *c, *encini = NULL, *macini = NULL;
- + struct pasemi_softc *sc = device_get_softc(dev);
- + struct pasemi_session *ses = NULL, **sespp;
- + int sesn, blksz = 0;
- + u64 ccmd = 0;
- + unsigned long flags;
- + struct pasemi_desc init_desc;
- + struct pasemi_fnu_txring *txring;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- + if (sidp == NULL || cri == NULL || sc == NULL) {
- + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
- + return -EINVAL;
- + }
- + for (c = cri; c != NULL; c = c->cri_next) {
- + if (ALG_IS_SIG(c->cri_alg)) {
- + if (macini)
- + return -EINVAL;
- + macini = c;
- + } else if (ALG_IS_CIPHER(c->cri_alg)) {
- + if (encini)
- + return -EINVAL;
- + encini = c;
- + } else {
- + DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
- + return -EINVAL;
- + }
- + }
- + if (encini == NULL && macini == NULL)
- + return -EINVAL;
- + if (encini) {
- + /* validate key length */
- + switch (encini->cri_alg) {
- + case CRYPTO_DES_CBC:
- + if (encini->cri_klen != 64)
- + return -EINVAL;
- + ccmd = DMA_CALGO_DES;
- + break;
- + case CRYPTO_3DES_CBC:
- + if (encini->cri_klen != 192)
- + return -EINVAL;
- + ccmd = DMA_CALGO_3DES;
- + break;
- + case CRYPTO_AES_CBC:
- + if (encini->cri_klen != 128 &&
- + encini->cri_klen != 192 &&
- + encini->cri_klen != 256)
- + return -EINVAL;
- + ccmd = DMA_CALGO_AES;
- + break;
- + case CRYPTO_ARC4:
- + if (encini->cri_klen != 128)
- + return -EINVAL;
- + ccmd = DMA_CALGO_ARC;
- + break;
- + default:
- + DPRINTF("UNKNOWN encini->cri_alg %d\n",
- + encini->cri_alg);
- + return -EINVAL;
- + }
- + }
- +
- + if (macini) {
- + switch (macini->cri_alg) {
- + case CRYPTO_MD5:
- + case CRYPTO_MD5_HMAC:
- + blksz = 16;
- + break;
- + case CRYPTO_SHA1:
- + case CRYPTO_SHA1_HMAC:
- + blksz = 20;
- + break;
- + default:
- + DPRINTF("UNKNOWN macini->cri_alg %d\n",
- + macini->cri_alg);
- + return -EINVAL;
- + }
- + if (((macini->cri_klen + 7) / 8) > blksz) {
- + DPRINTF("key length %d bigger than blksize %d not supported\n",
- + ((macini->cri_klen + 7) / 8), blksz);
- + return -EINVAL;
- + }
- + }
- +
- + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
- + if (sc->sc_sessions[sesn] == NULL) {
- + sc->sc_sessions[sesn] = (struct pasemi_session *)
- + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
- + ses = sc->sc_sessions[sesn];
- + break;
- + } else if (sc->sc_sessions[sesn]->used == 0) {
- + ses = sc->sc_sessions[sesn];
- + break;
- + }
- + }
- +
- + if (ses == NULL) {
- + sespp = (struct pasemi_session **)
- + kzalloc(sc->sc_nsessions * 2 *
- + sizeof(struct pasemi_session *), GFP_ATOMIC);
- + if (sespp == NULL)
- + return -ENOMEM;
- + memcpy(sespp, sc->sc_sessions,
- + sc->sc_nsessions * sizeof(struct pasemi_session *));
- + kfree(sc->sc_sessions);
- + sc->sc_sessions = sespp;
- + sesn = sc->sc_nsessions;
- + ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
- + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
- + if (ses == NULL)
- + return -ENOMEM;
- + sc->sc_nsessions *= 2;
- + }
- +
- + ses->used = 1;
- +
- + ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
- + sizeof(struct pasemi_session), DMA_TO_DEVICE);
- +
- + /* enter the channel scheduler */
- + spin_lock_irqsave(&sc->sc_chnlock, flags);
- +
- + /* ARC4 has to be processed by the even channel */
- + if (encini && (encini->cri_alg == CRYPTO_ARC4))
- + ses->chan = sc->sc_lastchn & ~1;
- + else
- + ses->chan = sc->sc_lastchn;
- + sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
- +
- + spin_unlock_irqrestore(&sc->sc_chnlock, flags);
- +
- + txring = &sc->tx[ses->chan];
- +
- + if (encini) {
- + ses->ccmd = ccmd;
- +
- + /* get an IV */
- + /* XXX may read fewer than requested */
- + get_random_bytes(ses->civ, sizeof(ses->civ));
- +
- + ses->keysz = (encini->cri_klen - 63) / 64;
- + memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
- +
- + pasemi_desc_start(&init_desc,
- + XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
- + pasemi_desc_build(&init_desc,
- + XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
- + }
- + if (macini) {
- + if (macini->cri_alg == CRYPTO_MD5_HMAC ||
- + macini->cri_alg == CRYPTO_SHA1_HMAC)
- + memcpy(ses->hkey, macini->cri_key, blksz);
- + else {
- + /* Load initialization constants(RFC 1321, 3174) */
- + ses->hiv[0] = 0x67452301efcdab89ULL;
- + ses->hiv[1] = 0x98badcfe10325476ULL;
- + ses->hiv[2] = 0xc3d2e1f000000000ULL;
- + }
- + ses->hseq = 0ULL;
- + }
- +
- + spin_lock_irqsave(&txring->fill_lock, flags);
- +
- + if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
- + txring->next_to_clean) > TX_RING_SIZE) {
- + spin_unlock_irqrestore(&txring->fill_lock, flags);
- + return ERESTART;
- + }
- +
- + if (encini) {
- + pasemi_ring_add_desc(txring, &init_desc, NULL);
- + pasemi_ring_incr(sc, ses->chan,
- + pasemi_desc_size(&init_desc));
- + }
- +
- + txring->sesn = sesn;
- + spin_unlock_irqrestore(&txring->fill_lock, flags);
- +
- + *sidp = PASEMI_SID(sesn);
- + return 0;
- +}
- +
- +/*
- + * Deallocate a session.
- + */
- +static int
- +pasemi_freesession(device_t dev, u_int64_t tid)
- +{
- + struct pasemi_softc *sc = device_get_softc(dev);
- + int session;
- + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (sc == NULL)
- + return -EINVAL;
- + session = PASEMI_SESSION(sid);
- + if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
- + return -EINVAL;
- +
- + pci_unmap_single(sc->dma_pdev,
- + sc->sc_sessions[session]->dma_addr,
- + sizeof(struct pasemi_session), DMA_TO_DEVICE);
- + memset(sc->sc_sessions[session], 0,
- + sizeof(struct pasemi_session));
- +
- + return 0;
- +}
- +
- +static int
- +pasemi_process(device_t dev, struct cryptop *crp, int hint)
- +{
- +
- + int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
- + struct pasemi_softc *sc = device_get_softc(dev);
- + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
- + caddr_t ivp;
- + struct pasemi_desc init_desc, work_desc;
- + struct pasemi_session *ses;
- + struct sk_buff *skb;
- + struct uio *uiop;
- + unsigned long flags;
- + struct pasemi_fnu_txring *txring;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
- + return -EINVAL;
- +
- + crp->crp_etype = 0;
- + if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
- + return -EINVAL;
- +
- + ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
- +
- + crd1 = crp->crp_desc;
- + if (crd1 == NULL) {
- + err = -EINVAL;
- + goto errout;
- + }
- + crd2 = crd1->crd_next;
- +
- + if (ALG_IS_SIG(crd1->crd_alg)) {
- + maccrd = crd1;
- + if (crd2 == NULL)
- + enccrd = NULL;
- + else if (ALG_IS_CIPHER(crd2->crd_alg) &&
- + (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
- + enccrd = crd2;
- + else
- + goto erralg;
- + } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
- + enccrd = crd1;
- + if (crd2 == NULL)
- + maccrd = NULL;
- + else if (ALG_IS_SIG(crd2->crd_alg) &&
- + (crd1->crd_flags & CRD_F_ENCRYPT))
- + maccrd = crd2;
- + else
- + goto erralg;
- + } else
- + goto erralg;
- +
- + chsel = ses->chan;
- +
- + txring = &sc->tx[chsel];
- +
- + if (enccrd && !maccrd) {
- + if (enccrd->crd_alg == CRYPTO_ARC4)
- + reinit = 1;
- + reinit_size = 0x40;
- + srclen = crp->crp_ilen;
- +
- + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
- + | XCT_FUN_FUN(chsel));
- + if (enccrd->crd_flags & CRD_F_ENCRYPT)
- + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
- + else
- + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
- + } else if (enccrd && maccrd) {
- + if (enccrd->crd_alg == CRYPTO_ARC4)
- + reinit = 1;
- + reinit_size = 0x68;
- +
- + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
- + /* Encrypt -> Authenticate */
- + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
- + | XCT_FUN_A | XCT_FUN_FUN(chsel));
- + srclen = maccrd->crd_skip + maccrd->crd_len;
- + } else {
- + /* Authenticate -> Decrypt */
- + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
- + | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
- + pasemi_desc_build(&work_desc, 0);
- + pasemi_desc_build(&work_desc, 0);
- + pasemi_desc_build(&work_desc, 0);
- + work_desc.postop = PASEMI_CHECK_SIG;
- + srclen = crp->crp_ilen;
- + }
- +
- + pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
- + pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
- + } else if (!enccrd && maccrd) {
- + srclen = maccrd->crd_len;
- +
- + pasemi_desc_start(&init_desc,
- + XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
- + pasemi_desc_build(&init_desc,
- + XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
- +
- + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
- + | XCT_FUN_A | XCT_FUN_FUN(chsel));
- + }
- +
- + if (enccrd) {
- + switch (enccrd->crd_alg) {
- + case CRYPTO_3DES_CBC:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
- + XCT_FUN_BCM_CBC);
- + ivsize = sizeof(u64);
- + break;
- + case CRYPTO_DES_CBC:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
- + XCT_FUN_BCM_CBC);
- + ivsize = sizeof(u64);
- + break;
- + case CRYPTO_AES_CBC:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
- + XCT_FUN_BCM_CBC);
- + ivsize = 2 * sizeof(u64);
- + break;
- + case CRYPTO_ARC4:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
- + ivsize = 0;
- + break;
- + default:
- + printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
- + enccrd->crd_alg);
- + err = -EINVAL;
- + goto errout;
- + }
- +
- + ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
- + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
- + memcpy(ivp, enccrd->crd_iv, ivsize);
- + /* If IV is not present in the buffer already, it has to be copied there */
- + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + enccrd->crd_inject, ivsize, ivp);
- + } else {
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
- + /* IV is provided expicitly in descriptor */
- + memcpy(ivp, enccrd->crd_iv, ivsize);
- + else
- + /* IV is provided in the packet */
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + enccrd->crd_inject, ivsize,
- + ivp);
- + }
- + }
- +
- + if (maccrd) {
- + switch (maccrd->crd_alg) {
- + case CRYPTO_MD5:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
- + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
- + break;
- + case CRYPTO_SHA1:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
- + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
- + break;
- + case CRYPTO_MD5_HMAC:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
- + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
- + break;
- + case CRYPTO_SHA1_HMAC:
- + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
- + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
- + break;
- + default:
- + printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
- + maccrd->crd_alg);
- + err = -EINVAL;
- + goto errout;
- + }
- + }
- +
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + /* using SKB buffers */
- + skb = (struct sk_buff *)crp->crp_buf;
- + if (skb_shinfo(skb)->nr_frags) {
- + printk(DRV_NAME ": skb frags unimplemented\n");
- + err = -EINVAL;
- + goto errout;
- + }
- + pasemi_desc_build(
- + &work_desc,
- + XCT_FUN_DST_PTR(skb->len, pci_map_single(
- + sc->dma_pdev, skb->data,
- + skb->len, DMA_TO_DEVICE)));
- + pasemi_desc_build(
- + &work_desc,
- + XCT_FUN_SRC_PTR(
- + srclen, pci_map_single(
- + sc->dma_pdev, skb->data,
- + srclen, DMA_TO_DEVICE)));
- + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + /* using IOV buffers */
- + uiop = (struct uio *)crp->crp_buf;
- + if (uiop->uio_iovcnt > 1) {
- + printk(DRV_NAME ": iov frags unimplemented\n");
- + err = -EINVAL;
- + goto errout;
- + }
- +
- + /* crp_olen is never set; always use crp_ilen */
- + pasemi_desc_build(
- + &work_desc,
- + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
- + sc->dma_pdev,
- + uiop->uio_iov->iov_base,
- + crp->crp_ilen, DMA_TO_DEVICE)));
- + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
- +
- + pasemi_desc_build(
- + &work_desc,
- + XCT_FUN_SRC_PTR(srclen, pci_map_single(
- + sc->dma_pdev,
- + uiop->uio_iov->iov_base,
- + srclen, DMA_TO_DEVICE)));
- + } else {
- + /* using contig buffers */
- + pasemi_desc_build(
- + &work_desc,
- + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
- + sc->dma_pdev,
- + crp->crp_buf,
- + crp->crp_ilen, DMA_TO_DEVICE)));
- + pasemi_desc_build(
- + &work_desc,
- + XCT_FUN_SRC_PTR(srclen, pci_map_single(
- + sc->dma_pdev,
- + crp->crp_buf, srclen,
- + DMA_TO_DEVICE)));
- + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
- + }
- +
- + spin_lock_irqsave(&txring->fill_lock, flags);
- +
- + if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
- + txring->sesn = PASEMI_SESSION(crp->crp_sid);
- + reinit = 1;
- + }
- +
- + if (enccrd) {
- + pasemi_desc_start(&init_desc,
- + XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
- + pasemi_desc_build(&init_desc,
- + XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
- + }
- +
- + if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
- + pasemi_desc_size(&work_desc)) -
- + txring->next_to_clean) > TX_RING_SIZE) {
- + spin_unlock_irqrestore(&txring->fill_lock, flags);
- + err = ERESTART;
- + goto errout;
- + }
- +
- + pasemi_ring_add_desc(txring, &init_desc, NULL);
- + pasemi_ring_add_desc(txring, &work_desc, crp);
- +
- + pasemi_ring_incr(sc, chsel,
- + pasemi_desc_size(&init_desc) +
- + pasemi_desc_size(&work_desc));
- +
- + spin_unlock_irqrestore(&txring->fill_lock, flags);
- +
- + mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
- +
- + return 0;
- +
- +erralg:
- + printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
- + crd1->crd_alg, crd2->crd_alg);
- + err = -EINVAL;
- +
- +errout:
- + if (err != ERESTART) {
- + crp->crp_etype = err;
- + crypto_done(crp);
- + }
- + return err;
- +}
- +
- +static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
- +{
- + int i, j, ring_idx;
- + struct pasemi_fnu_txring *ring = &sc->tx[chan];
- + u16 delta_cnt;
- + int flags, loops = 10;
- + int desc_size;
- + struct cryptop *crp;
- +
- + spin_lock_irqsave(&ring->clean_lock, flags);
- +
- + while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
- + & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
- + && loops--) {
- +
- + for (i = 0; i < delta_cnt; i++) {
- + desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
- + crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
- + if (crp) {
- + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
- + if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
- + /* Need to make sure signature matched,
- + * if not - return error */
- + if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
- + crp->crp_etype = -EINVAL;
- + }
- + crypto_done(TX_DESC_INFO(ring,
- + ring->next_to_clean).cf_crp);
- + TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
- + pci_unmap_single(
- + sc->dma_pdev,
- + XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
- + PCI_DMA_TODEVICE);
- +
- + ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
- +
- + ring->next_to_clean++;
- + for (j = 1; j < desc_size; j++) {
- + ring_idx = 2 *
- + (ring->next_to_clean &
- + (TX_RING_SIZE-1));
- + pci_unmap_single(
- + sc->dma_pdev,
- + XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
- + PCI_DMA_TODEVICE);
- + if (ring->desc[ring_idx + 1])
- + pci_unmap_single(
- + sc->dma_pdev,
- + XCT_PTR_ADDR_LEN(
- + ring->desc[
- + ring_idx + 1]),
- + PCI_DMA_TODEVICE);
- + ring->desc[ring_idx] =
- + ring->desc[ring_idx + 1] = 0;
- + ring->next_to_clean++;
- + }
- + } else {
- + for (j = 0; j < desc_size; j++) {
- + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
- + ring->desc[ring_idx] =
- + ring->desc[ring_idx + 1] = 0;
- + ring->next_to_clean++;
- + }
- + }
- + }
- +
- + ring->total_pktcnt += delta_cnt;
- + }
- + spin_unlock_irqrestore(&ring->clean_lock, flags);
- +
- + return 0;
- +}
- +
- +static void sweepup_tx(struct pasemi_softc *sc)
- +{
- + int i;
- +
- + for (i = 0; i < sc->sc_num_channels; i++)
- + pasemi_clean_tx(sc, i);
- +}
- +
- +static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
- +{
- + struct pasemi_softc *sc = arg;
- + unsigned int reg;
- + int chan = irq - sc->base_irq;
- + int chan_index = sc->base_chan + chan;
- + u64 stat = dma_status->tx_sta[chan_index];
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (!(stat & PAS_STATUS_CAUSE_M))
- + return IRQ_NONE;
- +
- + pasemi_clean_tx(sc, chan);
- +
- + stat = dma_status->tx_sta[chan_index];
- +
- + reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
- + PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
- +
- + if (stat & PAS_STATUS_SOFT)
- + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
- +
- + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
- +
- +
- + return IRQ_HANDLED;
- +}
- +
- +static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
- +{
- + u32 val;
- + int chan_index = chan + sc->base_chan;
- + int ret;
- + struct pasemi_fnu_txring *ring;
- +
- + ring = &sc->tx[chan];
- +
- + spin_lock_init(&ring->fill_lock);
- + spin_lock_init(&ring->clean_lock);
- +
- + ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
- + TX_RING_SIZE, GFP_KERNEL);
- + if (!ring->desc_info)
- + return -ENOMEM;
- +
- + /* Allocate descriptors */
- + ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
- + TX_RING_SIZE *
- + 2 * sizeof(u64),
- + &ring->dma, GFP_KERNEL);
- + if (!ring->desc)
- + return -ENOMEM;
- +
- + memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
- +
- + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
- +
- + ring->total_pktcnt = 0;
- +
- + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
- + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
- +
- + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
- + val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
- +
- + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
- +
- + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
- + PAS_DMA_TXCHAN_CFG_TY_FUNC |
- + PAS_DMA_TXCHAN_CFG_TATTR(chan) |
- + PAS_DMA_TXCHAN_CFG_WT(2));
- +
- + /* enable tx channel */
- + out_le32(sc->dma_regs +
- + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
- + PAS_DMA_TXCHAN_TCMDSTA_EN);
- +
- + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
- + PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
- +
- + ring->next_to_fill = 0;
- + ring->next_to_clean = 0;
- +
- + snprintf(ring->irq_name, sizeof(ring->irq_name),
- + "%s%d", "crypto", chan);
- +
- + ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
- + ret = request_irq(ring->irq, (irq_handler_t)
- + pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
- + if (ret) {
- + printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
- + ring->irq, ret);
- + ring->irq = -1;
- + return ret;
- + }
- +
- + setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
- +
- + return 0;
- +}
- +
- +static device_method_t pasemi_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, pasemi_newsession),
- + DEVMETHOD(cryptodev_freesession, pasemi_freesession),
- + DEVMETHOD(cryptodev_process, pasemi_process),
- +};
- +
- +/* Set up the crypto device structure, private data,
- + * and anything else we need before we start */
- +
- +static int __devinit
- +pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
- +{
- + struct pasemi_softc *sc;
- + int ret, i;
- +
- + DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
- +
- + sc = kzalloc(sizeof(*sc), GFP_KERNEL);
- + if (!sc)
- + return -ENOMEM;
- +
- + softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
- +
- + pci_set_drvdata(pdev, sc);
- +
- + spin_lock_init(&sc->sc_chnlock);
- +
- + sc->sc_sessions = (struct pasemi_session **)
- + kzalloc(PASEMI_INITIAL_SESSIONS *
- + sizeof(struct pasemi_session *), GFP_ATOMIC);
- + if (sc->sc_sessions == NULL) {
- + ret = -ENOMEM;
- + goto out;
- + }
- +
- + sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
- + sc->sc_lastchn = 0;
- + sc->base_irq = pdev->irq + 6;
- + sc->base_chan = 6;
- + sc->sc_cid = -1;
- + sc->dma_pdev = pdev;
- +
- + sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
- + if (!sc->iob_pdev) {
- + dev_err(&pdev->dev, "Can't find I/O Bridge\n");
- + ret = -ENODEV;
- + goto out;
- + }
- +
- + /* This is hardcoded and ugly, but we have some firmware versions
- + * who don't provide the register space in the device tree. Luckily
- + * they are at well-known locations so we can just do the math here.
- + */
- + sc->dma_regs =
- + ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
- + sc->iob_regs =
- + ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
- + if (!sc->dma_regs || !sc->iob_regs) {
- + dev_err(&pdev->dev, "Can't map registers\n");
- + ret = -ENODEV;
- + goto out;
- + }
- +
- + dma_status = __ioremap(0xfd800000, 0x1000, 0);
- + if (!dma_status) {
- + ret = -ENODEV;
- + dev_err(&pdev->dev, "Can't map dmastatus space\n");
- + goto out;
- + }
- +
- + sc->tx = (struct pasemi_fnu_txring *)
- + kzalloc(sizeof(struct pasemi_fnu_txring)
- + * 8, GFP_KERNEL);
- + if (!sc->tx) {
- + ret = -ENOMEM;
- + goto out;
- + }
- +
- + /* Initialize the h/w */
- + out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
- + (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
- + PAS_DMA_COM_CFG_FWF));
- + out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
- +
- + for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
- + sc->sc_num_channels++;
- + ret = pasemi_dma_setup_tx_resources(sc, i);
- + if (ret)
- + goto out;
- + }
- +
- + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
- + CRYPTOCAP_F_HARDWARE);
- + if (sc->sc_cid < 0) {
- + printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
- + ret = -ENXIO;
- + goto out;
- + }
- +
- + /* register algorithms with the framework */
- + printk(DRV_NAME ":");
- +
- + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
- +
- + return 0;
- +
- +out:
- + pasemi_dma_remove(pdev);
- + return ret;
- +}
- +
- +#define MAX_RETRIES 5000
- +
- +static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
- +{
- + struct pasemi_fnu_txring *ring = &sc->tx[chan];
- + int chan_index = chan + sc->base_chan;
- + int retries;
- + u32 stat;
- +
- + /* Stop the channel */
- + out_le32(sc->dma_regs +
- + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
- + PAS_DMA_TXCHAN_TCMDSTA_ST);
- +
- + for (retries = 0; retries < MAX_RETRIES; retries++) {
- + stat = in_le32(sc->dma_regs +
- + PAS_DMA_TXCHAN_TCMDSTA(chan_index));
- + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
- + break;
- + cond_resched();
- + }
- +
- + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
- + dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
- + chan_index);
- +
- + /* Disable the channel */
- + out_le32(sc->dma_regs +
- + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
- + 0);
- +
- + if (ring->desc_info)
- + kfree((void *) ring->desc_info);
- + if (ring->desc)
- + dma_free_coherent(&sc->dma_pdev->dev,
- + TX_RING_SIZE *
- + 2 * sizeof(u64),
- + (void *) ring->desc, ring->dma);
- + if (ring->irq != -1)
- + free_irq(ring->irq, sc);
- +
- + del_timer(&ring->crypto_timer);
- +}
- +
- +static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
- +{
- + struct pasemi_softc *sc = pci_get_drvdata(pdev);
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (sc->sc_cid >= 0) {
- + crypto_unregister_all(sc->sc_cid);
- + }
- +
- + if (sc->tx) {
- + for (i = 0; i < sc->sc_num_channels; i++)
- + pasemi_free_tx_resources(sc, i);
- +
- + kfree(sc->tx);
- + }
- + if (sc->sc_sessions) {
- + for (i = 0; i < sc->sc_nsessions; i++)
- + kfree(sc->sc_sessions[i]);
- + kfree(sc->sc_sessions);
- + }
- + if (sc->iob_pdev)
- + pci_dev_put(sc->iob_pdev);
- + if (sc->dma_regs)
- + iounmap(sc->dma_regs);
- + if (sc->iob_regs)
- + iounmap(sc->iob_regs);
- + kfree(sc);
- +}
- +
- +static struct pci_device_id pasemi_dma_pci_tbl[] = {
- + { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
- +};
- +
- +MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
- +
- +static struct pci_driver pasemi_dma_driver = {
- + .name = "pasemi_dma",
- + .id_table = pasemi_dma_pci_tbl,
- + .probe = pasemi_dma_probe,
- + .remove = __devexit_p(pasemi_dma_remove),
- +};
- +
- +static void __exit pasemi_dma_cleanup_module(void)
- +{
- + pci_unregister_driver(&pasemi_dma_driver);
- + __iounmap(dma_status);
- + dma_status = NULL;
- +}
- +
- +int pasemi_dma_init_module(void)
- +{
- + return pci_register_driver(&pasemi_dma_driver);
- +}
- +
- +module_init(pasemi_dma_init_module);
- +module_exit(pasemi_dma_cleanup_module);
- +
- +MODULE_LICENSE("Dual BSD/GPL");
- +MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
- +MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
- diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.36/crypto/ocf/pasemi/pasemi_fnu.h
- --- linux-2.6.36.orig/crypto/ocf/pasemi/pasemi_fnu.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/pasemi/pasemi_fnu.h 2010-11-09 20:28:12.612495424 +0100
- @@ -0,0 +1,410 @@
- +/*
- + * Copyright (C) 2007 PA Semi, Inc
- + *
- + * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
- + * hardware register layouts.
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- + */
- +
- +#ifndef PASEMI_FNU_H
- +#define PASEMI_FNU_H
- +
- +#include <linux/spinlock.h>
- +
- +#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
- +#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
- +#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
- +
- +/* Must be a power of two */
- +#define RX_RING_SIZE 512
- +#define TX_RING_SIZE 512
- +#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
- +#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
- +#define MAX_DESC_SIZE 8
- +#define PASEMI_INITIAL_SESSIONS 10
- +#define PASEMI_FNU_CHANNELS 8
- +
- +/* DMA descriptor */
- +struct pasemi_desc {
- + u64 quad[2*MAX_DESC_SIZE];
- + int quad_cnt;
- + int size;
- + int postop;
- +};
- +
- +/*
- + * Holds per descriptor data
- + */
- +struct pasemi_desc_info {
- + int desc_size;
- + int desc_postop;
- +#define PASEMI_CHECK_SIG 0x1
- +
- + struct cryptop *cf_crp;
- +};
- +
- +/*
- + * Holds per channel data
- + */
- +struct pasemi_fnu_txring {
- + volatile u64 *desc;
- + volatile struct
- + pasemi_desc_info *desc_info;
- + dma_addr_t dma;
- + struct timer_list crypto_timer;
- + spinlock_t fill_lock;
- + spinlock_t clean_lock;
- + unsigned int next_to_fill;
- + unsigned int next_to_clean;
- + u16 total_pktcnt;
- + int irq;
- + int sesn;
- + char irq_name[10];
- +};
- +
- +/*
- + * Holds data specific to a single pasemi device.
- + */
- +struct pasemi_softc {
- + softc_device_decl sc_cdev;
- + struct pci_dev *dma_pdev; /* device backpointer */
- + struct pci_dev *iob_pdev; /* device backpointer */
- + void __iomem *dma_regs;
- + void __iomem *iob_regs;
- + int base_irq;
- + int base_chan;
- + int32_t sc_cid; /* crypto tag */
- + int sc_nsessions;
- + struct pasemi_session **sc_sessions;
- + int sc_num_channels;/* number of crypto channels */
- +
- + /* pointer to the array of txring datastructures, one txring per channel */
- + struct pasemi_fnu_txring *tx;
- +
- + /*
- + * mutual exclusion for the channel scheduler
- + */
- + spinlock_t sc_chnlock;
- + /* last channel used, for now use round-robin to allocate channels */
- + int sc_lastchn;
- +};
- +
- +struct pasemi_session {
- + u64 civ[2];
- + u64 keysz;
- + u64 key[4];
- + u64 ccmd;
- + u64 hkey[4];
- + u64 hseq;
- + u64 giv[2];
- + u64 hiv[4];
- +
- + int used;
- + dma_addr_t dma_addr;
- + int chan;
- +};
- +
- +/* status register layout in IOB region, at 0xfd800000 */
- +struct pasdma_status {
- + u64 rx_sta[64];
- + u64 tx_sta[20];
- +};
- +
- +#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
- + (alg == CRYPTO_3DES_CBC) || \
- + (alg == CRYPTO_AES_CBC) || \
- + (alg == CRYPTO_ARC4) || \
- + (alg == CRYPTO_NULL_CBC))
- +
- +#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
- + (alg == CRYPTO_MD5_HMAC) || \
- + (alg == CRYPTO_SHA1) || \
- + (alg == CRYPTO_SHA1_HMAC) || \
- + (alg == CRYPTO_NULL_HMAC))
- +
- +enum {
- + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
- + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
- + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
- + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
- + PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
- +};
- +
- +/* All these registers live in the PCI configuration space for the DMA PCI
- + * device. Use the normal PCI config access functions for them.
- + */
- +
- +#define PAS_DMA_COM_CFG_FWF 0x18000000
- +
- +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
- +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
- +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
- +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
- +
- +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
- +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
- +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
- +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
- +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
- +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
- +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
- +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
- +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
- +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
- +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
- +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
- +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
- +#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
- +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
- +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
- +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
- +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
- + PAS_DMA_TXCHAN_CFG_TATTR_M)
- +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
- +#define PAS_DMA_TXCHAN_CFG_WT_S 6
- +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
- + PAS_DMA_TXCHAN_CFG_WT_M)
- +#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
- +#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
- +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
- +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
- +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
- +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
- +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
- +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
- +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
- +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
- + PAS_DMA_TXCHAN_BASEL_BRBL_M)
- +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
- +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
- +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
- +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
- + PAS_DMA_TXCHAN_BASEU_BRBH_M)
- +/* # of cache lines worth of buffer ring */
- +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
- +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
- +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
- + PAS_DMA_TXCHAN_BASEU_SIZ_M)
- +
- +#define PAS_STATUS_PCNT_M 0x000000000000ffffull
- +#define PAS_STATUS_PCNT_S 0
- +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
- +#define PAS_STATUS_DCNT_S 16
- +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
- +#define PAS_STATUS_BPCNT_S 32
- +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
- +#define PAS_STATUS_TIMER 0x1000000000000000ull
- +#define PAS_STATUS_ERROR 0x2000000000000000ull
- +#define PAS_STATUS_SOFT 0x4000000000000000ull
- +#define PAS_STATUS_INT 0x8000000000000000ull
- +
- +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
- +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
- +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
- +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
- + PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
- +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
- +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
- +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
- +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
- + PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
- +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
- +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
- +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
- +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
- +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
- + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
- +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
- +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
- +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
- +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
- +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
- + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
- +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
- +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
- +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
- +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
- + PAS_IOB_DMA_RXCH_RESET_PCNT_M)
- +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
- +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
- +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
- +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
- +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
- +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
- +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
- +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
- +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
- +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
- + PAS_IOB_DMA_TXCH_RESET_PCNT_M)
- +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
- +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
- +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
- +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
- +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
- +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
- +
- +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
- +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
- +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
- +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
- + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
- +
- +/* Transmit descriptor fields */
- +#define XCT_MACTX_T 0x8000000000000000ull
- +#define XCT_MACTX_ST 0x4000000000000000ull
- +#define XCT_MACTX_NORES 0x0000000000000000ull
- +#define XCT_MACTX_8BRES 0x1000000000000000ull
- +#define XCT_MACTX_24BRES 0x2000000000000000ull
- +#define XCT_MACTX_40BRES 0x3000000000000000ull
- +#define XCT_MACTX_I 0x0800000000000000ull
- +#define XCT_MACTX_O 0x0400000000000000ull
- +#define XCT_MACTX_E 0x0200000000000000ull
- +#define XCT_MACTX_VLAN_M 0x0180000000000000ull
- +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
- +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
- +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
- +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
- +#define XCT_MACTX_CRC_M 0x0060000000000000ull
- +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
- +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
- +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
- +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
- +#define XCT_MACTX_SS 0x0010000000000000ull
- +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
- +#define XCT_MACTX_LLEN_S 32ull
- +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
- + XCT_MACTX_LLEN_M)
- +#define XCT_MACTX_IPH_M 0x00000000f8000000ull
- +#define XCT_MACTX_IPH_S 27ull
- +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
- + XCT_MACTX_IPH_M)
- +#define XCT_MACTX_IPO_M 0x0000000007c00000ull
- +#define XCT_MACTX_IPO_S 22ull
- +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
- + XCT_MACTX_IPO_M)
- +#define XCT_MACTX_CSUM_M 0x0000000000000060ull
- +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
- +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
- +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
- +#define XCT_MACTX_V6 0x0000000000000010ull
- +#define XCT_MACTX_C 0x0000000000000004ull
- +#define XCT_MACTX_AL2 0x0000000000000002ull
- +
- +#define XCT_PTR_T 0x8000000000000000ull
- +#define XCT_PTR_LEN_M 0x7ffff00000000000ull
- +#define XCT_PTR_LEN_S 44
- +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
- + XCT_PTR_LEN_M)
- +#define XCT_PTR_ADDR_M 0x00000fffffffffffull
- +#define XCT_PTR_ADDR_S 0
- +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
- + XCT_PTR_ADDR_M)
- +
- +/* Function descriptor fields */
- +#define XCT_FUN_T 0x8000000000000000ull
- +#define XCT_FUN_ST 0x4000000000000000ull
- +#define XCT_FUN_NORES 0x0000000000000000ull
- +#define XCT_FUN_8BRES 0x1000000000000000ull
- +#define XCT_FUN_24BRES 0x2000000000000000ull
- +#define XCT_FUN_40BRES 0x3000000000000000ull
- +#define XCT_FUN_I 0x0800000000000000ull
- +#define XCT_FUN_O 0x0400000000000000ull
- +#define XCT_FUN_E 0x0200000000000000ull
- +#define XCT_FUN_FUN_S 54
- +#define XCT_FUN_FUN_M 0x01c0000000000000ull
- +#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
- + XCT_FUN_FUN_M)
- +#define XCT_FUN_CRM_NOP 0x0000000000000000ull
- +#define XCT_FUN_CRM_SIG 0x0008000000000000ull
- +#define XCT_FUN_CRM_ENC 0x0010000000000000ull
- +#define XCT_FUN_CRM_DEC 0x0018000000000000ull
- +#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
- +#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
- +#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
- +#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
- +#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
- +#define XCT_FUN_LLEN_S 32ULL
- +#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
- + XCT_FUN_LLEN_M)
- +#define XCT_FUN_SHL_M 0x00000000f8000000ull
- +#define XCT_FUN_SHL_S 27ull
- +#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
- + XCT_FUN_SHL_M)
- +#define XCT_FUN_CHL_M 0x0000000007c00000ull
- +#define XCT_FUN_CHL_S 22ull
- +#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
- + XCT_FUN_CHL_M)
- +#define XCT_FUN_HSZ_M 0x00000000003c0000ull
- +#define XCT_FUN_HSZ_S 18ull
- +#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
- + XCT_FUN_HSZ_M)
- +#define XCT_FUN_ALG_DES 0x0000000000000000ull
- +#define XCT_FUN_ALG_3DES 0x0000000000008000ull
- +#define XCT_FUN_ALG_AES 0x0000000000010000ull
- +#define XCT_FUN_ALG_ARC 0x0000000000018000ull
- +#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
- +#define XCT_FUN_BCM_ECB 0x0000000000000000ull
- +#define XCT_FUN_BCM_CBC 0x0000000000001000ull
- +#define XCT_FUN_BCM_CFB 0x0000000000002000ull
- +#define XCT_FUN_BCM_OFB 0x0000000000003000ull
- +#define XCT_FUN_BCM_CNT 0x0000000000003800ull
- +#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
- +#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
- +#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
- +#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
- +#define XCT_FUN_BCP_PL 0x0000000000000400ull
- +#define XCT_FUN_BCP_INCR 0x0000000000000600ull
- +#define XCT_FUN_SIG_MD5 (0ull << 4)
- +#define XCT_FUN_SIG_SHA1 (2ull << 4)
- +#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
- +#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
- +#define XCT_FUN_A 0x0000000000000008ull
- +#define XCT_FUN_C 0x0000000000000004ull
- +#define XCT_FUN_AL2 0x0000000000000002ull
- +#define XCT_FUN_SE 0x0000000000000001ull
- +
- +#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
- +#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
- + 0x8000000000000000ull)
- +
- +#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
- +#define XCT_CTRL_HDR_FUN_NUM_S 54
- +#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
- +#define XCT_CTRL_HDR_LEN_S 32
- +#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
- +#define XCT_CTRL_HDR_REG_S 0
- +
- +#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
- + ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
- + & XCT_CTRL_HDR_FUN_NUM_M) | \
- + ((((long)(len)) << \
- + XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
- + ((((long)(reg)) << \
- + XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
- +
- +/* Function config command options */
- +#define DMA_CALGO_DES 0x00
- +#define DMA_CALGO_3DES 0x01
- +#define DMA_CALGO_AES 0x02
- +#define DMA_CALGO_ARC 0x03
- +
- +#define DMA_FN_CIV0 0x02
- +#define DMA_FN_CIV1 0x03
- +#define DMA_FN_HKEY0 0x0a
- +
- +#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
- + (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
- +
- +#endif /* PASEMI_FNU_H */
- diff -Nur linux-2.6.36.orig/crypto/ocf/random.c linux-2.6.36/crypto/ocf/random.c
- --- linux-2.6.36.orig/crypto/ocf/random.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/random.c 2010-11-09 20:28:12.652495434 +0100
- @@ -0,0 +1,322 @@
- +/*
- + * A system independant way of adding entropy to the kernels pool
- + * this way the drivers can focus on the real work and we can take
- + * care of pushing it to the appropriate place in the kernel.
- + *
- + * This should be fast and callable from timers/interrupts
- + *
- + * Written by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * ALTERNATIVELY, provided that this notice is retained in full, this product
- + * may be distributed under the terms of the GNU General Public License (GPL),
- + * in which case the provisions of the GPL apply INSTEAD OF those given above.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/wait.h>
- +#include <linux/sched.h>
- +#include <linux/spinlock.h>
- +#include <linux/version.h>
- +#include <linux/unistd.h>
- +#include <linux/poll.h>
- +#include <linux/random.h>
- +#include <cryptodev.h>
- +
- +#ifdef CONFIG_OCF_FIPS
- +#include "rndtest.h"
- +#endif
- +
- +#ifndef HAS_RANDOM_INPUT_WAIT
- +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
- +#endif
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
- +#include <linux/sched.h>
- +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
- +#endif
- +
- +/*
- + * a hack to access the debug levels from the crypto driver
- + */
- +extern int crypto_debug;
- +#define debug crypto_debug
- +
- +/*
- + * a list of all registered random providers
- + */
- +static LIST_HEAD(random_ops);
- +static int started = 0;
- +static int initted = 0;
- +
- +struct random_op {
- + struct list_head random_list;
- + u_int32_t driverid;
- + int (*read_random)(void *arg, u_int32_t *buf, int len);
- + void *arg;
- +};
- +
- +static int random_proc(void *arg);
- +
- +static pid_t randomproc = (pid_t) -1;
- +static spinlock_t random_lock;
- +
- +/*
- + * just init the spin locks
- + */
- +static int
- +crypto_random_init(void)
- +{
- + spin_lock_init(&random_lock);
- + initted = 1;
- + return(0);
- +}
- +
- +/*
- + * Add the given random reader to our list (if not present)
- + * and start the thread (if not already started)
- + *
- + * we have to assume that driver id is ok for now
- + */
- +int
- +crypto_rregister(
- + u_int32_t driverid,
- + int (*read_random)(void *arg, u_int32_t *buf, int len),
- + void *arg)
- +{
- + unsigned long flags;
- + int ret = 0;
- + struct random_op *rops, *tmp;
- +
- + dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
- + __FUNCTION__, driverid, read_random, arg);
- +
- + if (!initted)
- + crypto_random_init();
- +
- +#if 0
- + struct cryptocap *cap;
- +
- + cap = crypto_checkdriver(driverid);
- + if (!cap)
- + return EINVAL;
- +#endif
- +
- + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
- + if (rops->driverid == driverid && rops->read_random == read_random)
- + return EEXIST;
- + }
- +
- + rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
- + if (!rops)
- + return ENOMEM;
- +
- + rops->driverid = driverid;
- + rops->read_random = read_random;
- + rops->arg = arg;
- +
- + spin_lock_irqsave(&random_lock, flags);
- + list_add_tail(&rops->random_list, &random_ops);
- + if (!started) {
- + randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
- + if (randomproc < 0) {
- + ret = randomproc;
- + printk("crypto: crypto_rregister cannot start random thread; "
- + "error %d", ret);
- + } else
- + started = 1;
- + }
- + spin_unlock_irqrestore(&random_lock, flags);
- +
- + return ret;
- +}
- +EXPORT_SYMBOL(crypto_rregister);
- +
- +int
- +crypto_runregister_all(u_int32_t driverid)
- +{
- + struct random_op *rops, *tmp;
- + unsigned long flags;
- +
- + dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
- +
- + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
- + if (rops->driverid == driverid) {
- + list_del(&rops->random_list);
- + kfree(rops);
- + }
- + }
- +
- + spin_lock_irqsave(&random_lock, flags);
- + if (list_empty(&random_ops) && started)
- + kill_proc(randomproc, SIGKILL, 1);
- + spin_unlock_irqrestore(&random_lock, flags);
- + return(0);
- +}
- +EXPORT_SYMBOL(crypto_runregister_all);
- +
- +/*
- + * while we can add entropy to random.c continue to read random data from
- + * the drivers and push it to random.
- + */
- +static int
- +random_proc(void *arg)
- +{
- + int n;
- + int wantcnt;
- + int bufcnt = 0;
- + int retval = 0;
- + int *buf = NULL;
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- + daemonize();
- + spin_lock_irq(¤t->sigmask_lock);
- + sigemptyset(¤t->blocked);
- + recalc_sigpending(current);
- + spin_unlock_irq(¤t->sigmask_lock);
- + sprintf(current->comm, "ocf-random");
- +#else
- + daemonize("ocf-random");
- + allow_signal(SIGKILL);
- +#endif
- +
- + (void) get_fs();
- + set_fs(get_ds());
- +
- +#ifdef CONFIG_OCF_FIPS
- +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
- +#else
- +#define NUM_INT 32
- +#endif
- +
- + /*
- + * some devices can transferr their RNG data direct into memory,
- + * so make sure it is device friendly
- + */
- + buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
- + if (NULL == buf) {
- + printk("crypto: RNG could not allocate memory\n");
- + retval = -ENOMEM;
- + goto bad_alloc;
- + }
- +
- + wantcnt = NUM_INT; /* start by adding some entropy */
- +
- + /*
- + * its possible due to errors or driver removal that we no longer
- + * have anything to do, if so exit or we will consume all the CPU
- + * doing nothing
- + */
- + while (!list_empty(&random_ops)) {
- + struct random_op *rops, *tmp;
- +
- +#ifdef CONFIG_OCF_FIPS
- + if (wantcnt)
- + wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
- +#endif
- +
- + /* see if we can get enough entropy to make the world
- + * a better place.
- + */
- + while (bufcnt < wantcnt && bufcnt < NUM_INT) {
- + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
- +
- + n = (*rops->read_random)(rops->arg, &buf[bufcnt],
- + NUM_INT - bufcnt);
- +
- + /* on failure remove the random number generator */
- + if (n == -1) {
- + list_del(&rops->random_list);
- + printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
- + rops->driverid);
- + kfree(rops);
- + } else if (n > 0)
- + bufcnt += n;
- + }
- + /* give up CPU for a bit, just in case as this is a loop */
- + schedule();
- + }
- +
- +
- +#ifdef CONFIG_OCF_FIPS
- + if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
- + dprintk("crypto: buffer had fips errors, discarding\n");
- + bufcnt = 0;
- + }
- +#endif
- +
- + /*
- + * if we have a certified buffer, we can send some data
- + * to /dev/random and move along
- + */
- + if (bufcnt > 0) {
- + /* add what we have */
- + random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
- + bufcnt = 0;
- + }
- +
- + /* give up CPU for a bit so we don't hog while filling */
- + schedule();
- +
- + /* wait for needing more */
- + wantcnt = random_input_wait();
- +
- + if (wantcnt <= 0)
- + wantcnt = 0; /* try to get some info again */
- + else
- + /* round up to one word or we can loop forever */
- + wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
- + if (wantcnt > NUM_INT) {
- + wantcnt = NUM_INT;
- + }
- +
- + if (signal_pending(current)) {
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- + spin_lock_irq(¤t->sigmask_lock);
- +#endif
- + flush_signals(current);
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- + spin_unlock_irq(¤t->sigmask_lock);
- +#endif
- + }
- + }
- +
- + kfree(buf);
- +
- +bad_alloc:
- + spin_lock_irq(&random_lock);
- + randomproc = (pid_t) -1;
- + started = 0;
- + spin_unlock_irq(&random_lock);
- +
- + return retval;
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/README linux-2.6.36/crypto/ocf/README
- --- linux-2.6.36.orig/crypto/ocf/README 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/README 2010-11-09 20:28:12.681240186 +0100
- @@ -0,0 +1,167 @@
- +README - ocf-linux-20100325
- +---------------------------
- +
- +This README provides instructions for getting ocf-linux compiled and
- +operating in a generic linux environment. For other information you
- +might like to visit the home page for this project:
- +
- + http://ocf-linux.sourceforge.net/
- +
- +Adding OCF to linux
- +-------------------
- +
- + Not much in this file for now, just some notes. I usually build
- + the ocf support as modules but it can be built into the kernel as
- + well. To use it:
- +
- + * mknod /dev/crypto c 10 70
- +
- + * to add OCF to your kernel source, you have two options. Apply
- + the kernel specific patch:
- +
- + cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
- + cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
- +
- + if you do one of the above, then you can proceed to the next step,
- + or you can do the above process by hand with using the patches against
- + linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.
- + Here's how to add it:
- +
- + for 2.4.35 (and later)
- +
- + cd linux-2.4.35/crypto
- + tar xvzf ocf-linux.tar.gz
- + cd ..
- + patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
- +
- + for 2.6.23 (and later), find the kernel patch specific (or nearest)
- + to your kernel versions and then:
- +
- + cd linux-2.6.NN/crypto
- + tar xvzf ocf-linux.tar.gz
- + cd ..
- + patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
- +
- + It should be easy to take this patch and apply it to other more
- + recent versions of the kernels. The same patches should also work
- + relatively easily on kernels as old as 2.6.11 and 2.4.18.
- +
- + * under 2.4 if you are on a non-x86 platform, you may need to:
- +
- + cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
- +
- + so that you can build the kernel crypto support needed for the cryptosoft
- + driver.
- +
- + * For simplicity you should enable all the crypto support in your kernel
- + except for the test driver. Likewise for the OCF options. Do not
- + enable OCF crypto drivers for HW that you do not have (for example
- + ixp4xx will not compile on non-Xscale systems).
- +
- + * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
- + crypto/cryptodev.h in an include directory that is used for building
- + applications for your platform. For example on a host system that
- + might be:
- +
- + /usr/include/crypto/cryptodev.h
- +
- + * patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.
- + (NOTE: there is no longer a need to patch ssh). The patch is against:
- + openssl-0_9_8e
- +
- + If you need a patch for an older version of openssl, you should look
- + to older OCF releases. This patch is unlikely to work on older
- + openssl versions.
- +
- + openssl-0.9.8n.patch
- + - enables --with-cryptodev for non BSD systems
- + - adds -cpu option to openssl speed for calculating CPU load
- + under linux
- + - fixes null pointer in openssl speed multi thread output.
- + - fixes test keys to work with linux crypto's more stringent
- + key checking.
- + - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
- + with the --with-cryptodev-digests option
- + - fixes bug in engine code caching.
- +
- + * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
- + tools for testing OCF (ie., cryptotest).
- +
- +How to load the OCF drivers
- +---------------------------
- +
- + First insert the base modules:
- +
- + insmod ocf
- + insmod cryptodev
- +
- + You can then install the software OCF driver with:
- +
- + insmod cryptosoft
- +
- + and one or more of the OCF HW drivers with:
- +
- + insmod safe
- + insmod hifn7751
- + insmod ixp4xx
- + ...
- +
- + all the drivers take a debug option to enable verbose debug so that
- + you can see what is going on. For debug you load them as:
- +
- + insmod ocf crypto_debug=1
- + insmod cryptodev cryptodev_debug=1
- + insmod cryptosoft swcr_debug=1
- +
- + You may load more than one OCF crypto driver but then there is no guarantee
- + as to which will be used.
- +
- + You can also enable debug at run time on 2.6 systems with the following:
- +
- + echo 1 > /sys/module/ocf/parameters/crypto_debug
- + echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
- + echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
- + echo 1 > /sys/module/hifn7751/parameters/hifn_debug
- + echo 1 > /sys/module/safe/parameters/safe_debug
- + echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
- + ...
- +
- +Testing the OCF support
- +-----------------------
- +
- + run "cryptotest", it should do a short test for a couple of
- + des packets. If it does everything is working.
- +
- + If this works, then ssh will use the driver when invoked as:
- +
- + ssh -c 3des username@host
- +
- + to see for sure that it is operating, enable debug as defined above.
- +
- + To get a better idea of performance run:
- +
- + cryptotest 100 4096
- +
- + There are more options to cryptotest, see the help.
- +
- + It is also possible to use openssl to test the speed of the crypto
- + drivers.
- +
- + openssl speed -evp des -engine cryptodev -elapsed
- + openssl speed -evp des3 -engine cryptodev -elapsed
- + openssl speed -evp aes128 -engine cryptodev -elapsed
- +
- + and multiple threads (10) with:
- +
- + openssl speed -evp des -engine cryptodev -elapsed -multi 10
- + openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
- + openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
- +
- + for public key testing you can try:
- +
- + cryptokeytest
- + openssl speed -engine cryptodev rsa -elapsed
- + openssl speed -engine cryptodev dsa -elapsed
- +
- +David McCullough
- +david_mccullough@mcafee.com
- diff -Nur linux-2.6.36.orig/crypto/ocf/rndtest.c linux-2.6.36/crypto/ocf/rndtest.c
- --- linux-2.6.36.orig/crypto/ocf/rndtest.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/rndtest.c 2010-11-09 20:28:12.722495563 +0100
- @@ -0,0 +1,300 @@
- +/* $OpenBSD$ */
- +
- +/*
- + * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + * The license and original author are listed below.
- + *
- + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. All advertising materials mentioning features or use of this software
- + * must display the following acknowledgement:
- + * This product includes software developed by Jason L. Wright
- + * 4. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/list.h>
- +#include <linux/wait.h>
- +#include <linux/time.h>
- +#include <linux/version.h>
- +#include <linux/unistd.h>
- +#include <linux/kernel.h>
- +#include <linux/string.h>
- +#include <linux/time.h>
- +#include <cryptodev.h>
- +#include "rndtest.h"
- +
- +static struct rndtest_stats rndstats;
- +
- +static void rndtest_test(struct rndtest_state *);
- +
- +/* The tests themselves */
- +static int rndtest_monobit(struct rndtest_state *);
- +static int rndtest_runs(struct rndtest_state *);
- +static int rndtest_longruns(struct rndtest_state *);
- +static int rndtest_chi_4(struct rndtest_state *);
- +
- +static int rndtest_runs_check(struct rndtest_state *, int, int *);
- +static void rndtest_runs_record(struct rndtest_state *, int, int *);
- +
- +static const struct rndtest_testfunc {
- + int (*test)(struct rndtest_state *);
- +} rndtest_funcs[] = {
- + { rndtest_monobit },
- + { rndtest_runs },
- + { rndtest_chi_4 },
- + { rndtest_longruns },
- +};
- +
- +#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
- +
- +static void
- +rndtest_test(struct rndtest_state *rsp)
- +{
- + int i, rv = 0;
- +
- + rndstats.rst_tests++;
- + for (i = 0; i < RNDTEST_NTESTS; i++)
- + rv |= (*rndtest_funcs[i].test)(rsp);
- + rsp->rs_discard = (rv != 0);
- +}
- +
- +
- +extern int crypto_debug;
- +#define rndtest_verbose 2
- +#define rndtest_report(rsp, failure, fmt, a...) \
- + { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
- +
- +#define RNDTEST_MONOBIT_MINONES 9725
- +#define RNDTEST_MONOBIT_MAXONES 10275
- +
- +static int
- +rndtest_monobit(struct rndtest_state *rsp)
- +{
- + int i, ones = 0, j;
- + u_int8_t r;
- +
- + for (i = 0; i < RNDTEST_NBYTES; i++) {
- + r = rsp->rs_buf[i];
- + for (j = 0; j < 8; j++, r <<= 1)
- + if (r & 0x80)
- + ones++;
- + }
- + if (ones > RNDTEST_MONOBIT_MINONES &&
- + ones < RNDTEST_MONOBIT_MAXONES) {
- + if (rndtest_verbose > 1)
- + rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
- + RNDTEST_MONOBIT_MINONES, ones,
- + RNDTEST_MONOBIT_MAXONES);
- + return (0);
- + } else {
- + if (rndtest_verbose)
- + rndtest_report(rsp, 1,
- + "monobit failed (%d ones)", ones);
- + rndstats.rst_monobit++;
- + return (-1);
- + }
- +}
- +
- +#define RNDTEST_RUNS_NINTERVAL 6
- +
- +static const struct rndtest_runs_tabs {
- + u_int16_t min, max;
- +} rndtest_runs_tab[] = {
- + { 2343, 2657 },
- + { 1135, 1365 },
- + { 542, 708 },
- + { 251, 373 },
- + { 111, 201 },
- + { 111, 201 },
- +};
- +
- +static int
- +rndtest_runs(struct rndtest_state *rsp)
- +{
- + int i, j, ones, zeros, rv = 0;
- + int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
- + u_int8_t c;
- +
- + bzero(onei, sizeof(onei));
- + bzero(zeroi, sizeof(zeroi));
- + ones = zeros = 0;
- + for (i = 0; i < RNDTEST_NBYTES; i++) {
- + c = rsp->rs_buf[i];
- + for (j = 0; j < 8; j++, c <<= 1) {
- + if (c & 0x80) {
- + ones++;
- + rndtest_runs_record(rsp, zeros, zeroi);
- + zeros = 0;
- + } else {
- + zeros++;
- + rndtest_runs_record(rsp, ones, onei);
- + ones = 0;
- + }
- + }
- + }
- + rndtest_runs_record(rsp, ones, onei);
- + rndtest_runs_record(rsp, zeros, zeroi);
- +
- + rv |= rndtest_runs_check(rsp, 0, zeroi);
- + rv |= rndtest_runs_check(rsp, 1, onei);
- +
- + if (rv)
- + rndstats.rst_runs++;
- +
- + return (rv);
- +}
- +
- +static void
- +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
- +{
- + if (len == 0)
- + return;
- + if (len > RNDTEST_RUNS_NINTERVAL)
- + len = RNDTEST_RUNS_NINTERVAL;
- + len -= 1;
- + intrv[len]++;
- +}
- +
- +static int
- +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
- +{
- + int i, rv = 0;
- +
- + for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
- + if (src[i] < rndtest_runs_tab[i].min ||
- + src[i] > rndtest_runs_tab[i].max) {
- + rndtest_report(rsp, 1,
- + "%s interval %d failed (%d, %d-%d)",
- + val ? "ones" : "zeros",
- + i + 1, src[i], rndtest_runs_tab[i].min,
- + rndtest_runs_tab[i].max);
- + rv = -1;
- + } else {
- + rndtest_report(rsp, 0,
- + "runs pass %s interval %d (%d < %d < %d)",
- + val ? "ones" : "zeros",
- + i + 1, rndtest_runs_tab[i].min, src[i],
- + rndtest_runs_tab[i].max);
- + }
- + }
- + return (rv);
- +}
- +
- +static int
- +rndtest_longruns(struct rndtest_state *rsp)
- +{
- + int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
- + u_int8_t c;
- +
- + for (i = 0; i < RNDTEST_NBYTES; i++) {
- + c = rsp->rs_buf[i];
- + for (j = 0; j < 8; j++, c <<= 1) {
- + if (c & 0x80) {
- + zeros = 0;
- + ones++;
- + if (ones > maxones)
- + maxones = ones;
- + } else {
- + ones = 0;
- + zeros++;
- + if (zeros > maxzeros)
- + maxzeros = zeros;
- + }
- + }
- + }
- +
- + if (maxones < 26 && maxzeros < 26) {
- + rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
- + maxones, maxzeros);
- + return (0);
- + } else {
- + rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
- + maxones, maxzeros);
- + rndstats.rst_longruns++;
- + return (-1);
- + }
- +}
- +
- +/*
- + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
- + * but it is really the chi^2 test over 4 bits (the poker test as described
- + * by Knuth vol 2 is something different, and I take him as authoritative
- + * on nomenclature over NIST).
- + */
- +#define RNDTEST_CHI4_K 16
- +#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
- +
- +/*
- + * The unnormalized values are used so that we don't have to worry about
- + * fractional precision. The "real" value is found by:
- + * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
- + */
- +#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
- +#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
- +
- +static int
- +rndtest_chi_4(struct rndtest_state *rsp)
- +{
- + unsigned int freq[RNDTEST_CHI4_K], i, sum;
- +
- + for (i = 0; i < RNDTEST_CHI4_K; i++)
- + freq[i] = 0;
- +
- + /* Get number of occurances of each 4 bit pattern */
- + for (i = 0; i < RNDTEST_NBYTES; i++) {
- + freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
- + freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
- + }
- +
- + for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
- + sum += freq[i] * freq[i];
- +
- + if (sum >= 1563181 && sum <= 1576929) {
- + rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
- + return (0);
- + } else {
- + rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
- + rndstats.rst_chi++;
- + return (-1);
- + }
- +}
- +
- +int
- +rndtest_buf(unsigned char *buf)
- +{
- + struct rndtest_state rsp;
- +
- + memset(&rsp, 0, sizeof(rsp));
- + rsp.rs_buf = buf;
- + rndtest_test(&rsp);
- + return(rsp.rs_discard);
- +}
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/rndtest.h linux-2.6.36/crypto/ocf/rndtest.h
- --- linux-2.6.36.orig/crypto/ocf/rndtest.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/rndtest.h 2010-11-09 20:28:12.762495556 +0100
- @@ -0,0 +1,54 @@
- +/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
- +/* $OpenBSD$ */
- +
- +/*
- + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. All advertising materials mentioning features or use of this software
- + * must display the following acknowledgement:
- + * This product includes software developed by Jason L. Wright
- + * 4. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +
- +/* Some of the tests depend on these values */
- +#define RNDTEST_NBYTES 2500
- +#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
- +
- +struct rndtest_state {
- + int rs_discard; /* discard/accept random data */
- + u_int8_t *rs_buf;
- +};
- +
- +struct rndtest_stats {
- + u_int32_t rst_discard; /* number of bytes discarded */
- + u_int32_t rst_tests; /* number of test runs */
- + u_int32_t rst_monobit; /* monobit test failures */
- + u_int32_t rst_runs; /* 0/1 runs failures */
- + u_int32_t rst_longruns; /* longruns failures */
- + u_int32_t rst_chi; /* chi^2 failures */
- +};
- +
- +extern int rndtest_buf(unsigned char *buf);
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/Makefile linux-2.6.36/crypto/ocf/safe/Makefile
- --- linux-2.6.36.orig/crypto/ocf/safe/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/Makefile 2010-11-09 20:28:12.805576889 +0100
- @@ -0,0 +1,12 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_SAFE) += safe.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/md5.c linux-2.6.36/crypto/ocf/safe/md5.c
- --- linux-2.6.36.orig/crypto/ocf/safe/md5.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/md5.c 2010-11-09 20:28:12.842495449 +0100
- @@ -0,0 +1,308 @@
- +/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
- +/*
- + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. Neither the name of the project nor the names of its contributors
- + * may be used to endorse or promote products derived from this software
- + * without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + */
- +
- +#if 0
- +#include <sys/cdefs.h>
- +__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
- +
- +#include <sys/types.h>
- +#include <sys/cdefs.h>
- +#include <sys/time.h>
- +#include <sys/systm.h>
- +#include <crypto/md5.h>
- +#endif
- +
- +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
- +
- +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
- +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
- +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
- +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
- +
- +#define ROUND1(a, b, c, d, k, s, i) { \
- + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
- + (a) = SHIFT((a), (s)); \
- + (a) = (b) + (a); \
- +}
- +
- +#define ROUND2(a, b, c, d, k, s, i) { \
- + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
- + (a) = SHIFT((a), (s)); \
- + (a) = (b) + (a); \
- +}
- +
- +#define ROUND3(a, b, c, d, k, s, i) { \
- + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
- + (a) = SHIFT((a), (s)); \
- + (a) = (b) + (a); \
- +}
- +
- +#define ROUND4(a, b, c, d, k, s, i) { \
- + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
- + (a) = SHIFT((a), (s)); \
- + (a) = (b) + (a); \
- +}
- +
- +#define Sa 7
- +#define Sb 12
- +#define Sc 17
- +#define Sd 22
- +
- +#define Se 5
- +#define Sf 9
- +#define Sg 14
- +#define Sh 20
- +
- +#define Si 4
- +#define Sj 11
- +#define Sk 16
- +#define Sl 23
- +
- +#define Sm 6
- +#define Sn 10
- +#define So 15
- +#define Sp 21
- +
- +#define MD5_A0 0x67452301
- +#define MD5_B0 0xefcdab89
- +#define MD5_C0 0x98badcfe
- +#define MD5_D0 0x10325476
- +
- +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
- +static const u_int32_t T[65] = {
- + 0,
- + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
- + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
- + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
- + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
- +
- + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
- + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
- + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
- + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
- +
- + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
- + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
- + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
- + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
- +
- + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
- + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
- + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
- + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
- +};
- +
- +static const u_int8_t md5_paddat[MD5_BUFLEN] = {
- + 0x80, 0, 0, 0, 0, 0, 0, 0,
- + 0, 0, 0, 0, 0, 0, 0, 0,
- + 0, 0, 0, 0, 0, 0, 0, 0,
- + 0, 0, 0, 0, 0, 0, 0, 0,
- + 0, 0, 0, 0, 0, 0, 0, 0,
- + 0, 0, 0, 0, 0, 0, 0, 0,
- + 0, 0, 0, 0, 0, 0, 0, 0,
- + 0, 0, 0, 0, 0, 0, 0, 0,
- +};
- +
- +static void md5_calc(u_int8_t *, md5_ctxt *);
- +
- +void md5_init(ctxt)
- + md5_ctxt *ctxt;
- +{
- + ctxt->md5_n = 0;
- + ctxt->md5_i = 0;
- + ctxt->md5_sta = MD5_A0;
- + ctxt->md5_stb = MD5_B0;
- + ctxt->md5_stc = MD5_C0;
- + ctxt->md5_std = MD5_D0;
- + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
- +}
- +
- +void md5_loop(ctxt, input, len)
- + md5_ctxt *ctxt;
- + u_int8_t *input;
- + u_int len; /* number of bytes */
- +{
- + u_int gap, i;
- +
- + ctxt->md5_n += len * 8; /* byte to bit */
- + gap = MD5_BUFLEN - ctxt->md5_i;
- +
- + if (len >= gap) {
- + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
- + gap);
- + md5_calc(ctxt->md5_buf, ctxt);
- +
- + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
- + md5_calc((u_int8_t *)(input + i), ctxt);
- + }
- +
- + ctxt->md5_i = len - i;
- + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
- + } else {
- + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
- + len);
- + ctxt->md5_i += len;
- + }
- +}
- +
- +void md5_pad(ctxt)
- + md5_ctxt *ctxt;
- +{
- + u_int gap;
- +
- + /* Don't count up padding. Keep md5_n. */
- + gap = MD5_BUFLEN - ctxt->md5_i;
- + if (gap > 8) {
- + bcopy(md5_paddat,
- + (void *)(ctxt->md5_buf + ctxt->md5_i),
- + gap - sizeof(ctxt->md5_n));
- + } else {
- + /* including gap == 8 */
- + bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
- + gap);
- + md5_calc(ctxt->md5_buf, ctxt);
- + bcopy((md5_paddat + gap),
- + (void *)ctxt->md5_buf,
- + MD5_BUFLEN - sizeof(ctxt->md5_n));
- + }
- +
- + /* 8 byte word */
- +#if BYTE_ORDER == LITTLE_ENDIAN
- + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
- +#endif
- +#if BYTE_ORDER == BIG_ENDIAN
- + ctxt->md5_buf[56] = ctxt->md5_n8[7];
- + ctxt->md5_buf[57] = ctxt->md5_n8[6];
- + ctxt->md5_buf[58] = ctxt->md5_n8[5];
- + ctxt->md5_buf[59] = ctxt->md5_n8[4];
- + ctxt->md5_buf[60] = ctxt->md5_n8[3];
- + ctxt->md5_buf[61] = ctxt->md5_n8[2];
- + ctxt->md5_buf[62] = ctxt->md5_n8[1];
- + ctxt->md5_buf[63] = ctxt->md5_n8[0];
- +#endif
- +
- + md5_calc(ctxt->md5_buf, ctxt);
- +}
- +
- +void md5_result(digest, ctxt)
- + u_int8_t *digest;
- + md5_ctxt *ctxt;
- +{
- + /* 4 byte words */
- +#if BYTE_ORDER == LITTLE_ENDIAN
- + bcopy(&ctxt->md5_st8[0], digest, 16);
- +#endif
- +#if BYTE_ORDER == BIG_ENDIAN
- + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
- + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
- + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
- + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
- + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
- + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
- + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
- + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
- +#endif
- +}
- +
- +static void md5_calc(b64, ctxt)
- + u_int8_t *b64;
- + md5_ctxt *ctxt;
- +{
- + u_int32_t A = ctxt->md5_sta;
- + u_int32_t B = ctxt->md5_stb;
- + u_int32_t C = ctxt->md5_stc;
- + u_int32_t D = ctxt->md5_std;
- +#if BYTE_ORDER == LITTLE_ENDIAN
- + u_int32_t *X = (u_int32_t *)b64;
- +#endif
- +#if BYTE_ORDER == BIG_ENDIAN
- + /* 4 byte words */
- + /* what a brute force but fast! */
- + u_int32_t X[16];
- + u_int8_t *y = (u_int8_t *)X;
- + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
- + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
- + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
- + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
- + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
- + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
- + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
- + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
- + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
- + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
- + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
- + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
- + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
- + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
- + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
- + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
- +#endif
- +
- + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
- + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
- + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
- + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
- + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
- + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
- + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
- + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
- +
- + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
- + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
- + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
- + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
- + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
- + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
- + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
- + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
- +
- + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
- + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
- + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
- + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
- + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
- + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
- + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
- + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
- +
- + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
- + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
- + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
- + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
- + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
- + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
- + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
- + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
- +
- + ctxt->md5_sta += A;
- + ctxt->md5_stb += B;
- + ctxt->md5_stc += C;
- + ctxt->md5_std += D;
- +}
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/md5.h linux-2.6.36/crypto/ocf/safe/md5.h
- --- linux-2.6.36.orig/crypto/ocf/safe/md5.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/md5.h 2010-11-09 20:28:12.881683669 +0100
- @@ -0,0 +1,76 @@
- +/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
- +/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
- +
- +/*
- + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. Neither the name of the project nor the names of its contributors
- + * may be used to endorse or promote products derived from this software
- + * without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + */
- +
- +#ifndef _NETINET6_MD5_H_
- +#define _NETINET6_MD5_H_
- +
- +#define MD5_BUFLEN 64
- +
- +typedef struct {
- + union {
- + u_int32_t md5_state32[4];
- + u_int8_t md5_state8[16];
- + } md5_st;
- +
- +#define md5_sta md5_st.md5_state32[0]
- +#define md5_stb md5_st.md5_state32[1]
- +#define md5_stc md5_st.md5_state32[2]
- +#define md5_std md5_st.md5_state32[3]
- +#define md5_st8 md5_st.md5_state8
- +
- + union {
- + u_int64_t md5_count64;
- + u_int8_t md5_count8[8];
- + } md5_count;
- +#define md5_n md5_count.md5_count64
- +#define md5_n8 md5_count.md5_count8
- +
- + u_int md5_i;
- + u_int8_t md5_buf[MD5_BUFLEN];
- +} md5_ctxt;
- +
- +extern void md5_init(md5_ctxt *);
- +extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
- +extern void md5_pad(md5_ctxt *);
- +extern void md5_result(u_int8_t *, md5_ctxt *);
- +
- +/* compatibility */
- +#define MD5_CTX md5_ctxt
- +#define MD5Init(x) md5_init((x))
- +#define MD5Update(x, y, z) md5_loop((x), (y), (z))
- +#define MD5Final(x, y) \
- +do { \
- + md5_pad((y)); \
- + md5_result((x), (y)); \
- +} while (0)
- +
- +#endif /* ! _NETINET6_MD5_H_*/
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safe.c linux-2.6.36/crypto/ocf/safe/safe.c
- --- linux-2.6.36.orig/crypto/ocf/safe/safe.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/safe.c 2010-11-09 20:28:12.922204086 +0100
- @@ -0,0 +1,2288 @@
- +/*-
- + * Linux port done by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2004-2010 David McCullough
- + * The license and original author are listed below.
- + *
- + * Copyright (c) 2003 Sam Leffler, Errno Consulting
- + * Copyright (c) 2003 Global Technology Associates, Inc.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + *
- +__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/kernel.h>
- +#include <linux/init.h>
- +#include <linux/list.h>
- +#include <linux/slab.h>
- +#include <linux/wait.h>
- +#include <linux/sched.h>
- +#include <linux/pci.h>
- +#include <linux/delay.h>
- +#include <linux/interrupt.h>
- +#include <linux/spinlock.h>
- +#include <linux/random.h>
- +#include <linux/version.h>
- +#include <linux/skbuff.h>
- +#include <asm/io.h>
- +
- +/*
- + * SafeNet SafeXcel-1141 hardware crypto accelerator
- + */
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +#include <safe/safereg.h>
- +#include <safe/safevar.h>
- +
- +#if 1
- +#define DPRINTF(a) do { \
- + if (debug) { \
- + printk("%s: ", sc ? \
- + device_get_nameunit(sc->sc_dev) : "safe"); \
- + printk a; \
- + } \
- + } while (0)
- +#else
- +#define DPRINTF(a)
- +#endif
- +
- +/*
- + * until we find a cleaner way, include the BSD md5/sha1 code
- + * here
- + */
- +#define HMAC_HACK 1
- +#ifdef HMAC_HACK
- +#define LITTLE_ENDIAN 1234
- +#define BIG_ENDIAN 4321
- +#ifdef __LITTLE_ENDIAN
- +#define BYTE_ORDER LITTLE_ENDIAN
- +#endif
- +#ifdef __BIG_ENDIAN
- +#define BYTE_ORDER BIG_ENDIAN
- +#endif
- +#include <safe/md5.h>
- +#include <safe/md5.c>
- +#include <safe/sha1.h>
- +#include <safe/sha1.c>
- +
- +u_int8_t hmac_ipad_buffer[64] = {
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
- +};
- +
- +u_int8_t hmac_opad_buffer[64] = {
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
- +};
- +#endif /* HMAC_HACK */
- +
- +/* add proc entry for this */
- +struct safe_stats safestats;
- +
- +#define debug safe_debug
- +int safe_debug = 0;
- +module_param(safe_debug, int, 0644);
- +MODULE_PARM_DESC(safe_debug, "Enable debug");
- +
- +static void safe_callback(struct safe_softc *, struct safe_ringentry *);
- +static void safe_feed(struct safe_softc *, struct safe_ringentry *);
- +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
- +static void safe_rng_init(struct safe_softc *);
- +int safe_rngbufsize = 8; /* 32 bytes each read */
- +module_param(safe_rngbufsize, int, 0644);
- +MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
- +int safe_rngmaxalarm = 8; /* max alarms before reset */
- +module_param(safe_rngmaxalarm, int, 0644);
- +MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
- +#endif /* SAFE_NO_RNG */
- +
- +static void safe_totalreset(struct safe_softc *sc);
- +static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
- +static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
- +static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
- +static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
- +static int safe_kstart(struct safe_softc *sc);
- +static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
- +static void safe_kfeed(struct safe_softc *sc);
- +static void safe_kpoll(unsigned long arg);
- +static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
- + u_int32_t len, struct crparam *n);
- +
- +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
- +static int safe_freesession(device_t, u_int64_t);
- +static int safe_process(device_t, struct cryptop *, int);
- +
- +static device_method_t safe_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, safe_newsession),
- + DEVMETHOD(cryptodev_freesession,safe_freesession),
- + DEVMETHOD(cryptodev_process, safe_process),
- + DEVMETHOD(cryptodev_kprocess, safe_kprocess),
- +};
- +
- +#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
- +#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
- +
- +#define SAFE_MAX_CHIPS 8
- +static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
- +
- +/*
- + * split our buffers up into safe DMAable byte fragments to avoid lockup
- + * bug in 1141 HW on rev 1.0.
- + */
- +
- +static int
- +pci_map_linear(
- + struct safe_softc *sc,
- + struct safe_operand *buf,
- + void *addr,
- + int len)
- +{
- + dma_addr_t tmp;
- + int chunk, tlen = len;
- +
- + tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
- +
- + buf->mapsize += len;
- + while (len > 0) {
- + chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
- + buf->segs[buf->nsegs].ds_addr = tmp;
- + buf->segs[buf->nsegs].ds_len = chunk;
- + buf->segs[buf->nsegs].ds_tlen = tlen;
- + buf->nsegs++;
- + tmp += chunk;
- + len -= chunk;
- + tlen = 0;
- + }
- + return 0;
- +}
- +
- +/*
- + * map in a given uio buffer (great on some arches :-)
- + */
- +
- +static int
- +pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
- +{
- + struct iovec *iov = uio->uio_iov;
- + int n;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + buf->mapsize = 0;
- + buf->nsegs = 0;
- +
- + for (n = 0; n < uio->uio_iovcnt; n++) {
- + pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
- + iov++;
- + }
- +
- + /* identify this buffer by the first segment */
- + buf->map = (void *) buf->segs[0].ds_addr;
- + return(0);
- +}
- +
- +/*
- + * map in a given sk_buff
- + */
- +
- +static int
- +pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
- +{
- + int i;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + buf->mapsize = 0;
- + buf->nsegs = 0;
- +
- + pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
- +
- + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- + pci_map_linear(sc, buf,
- + page_address(skb_shinfo(skb)->frags[i].page) +
- + skb_shinfo(skb)->frags[i].page_offset,
- + skb_shinfo(skb)->frags[i].size);
- + }
- +
- + /* identify this buffer by the first segment */
- + buf->map = (void *) buf->segs[0].ds_addr;
- + return(0);
- +}
- +
- +
- +#if 0 /* not needed at this time */
- +static void
- +pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
- +{
- + int i;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- + for (i = 0; i < buf->nsegs; i++)
- + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
- + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
- +}
- +#endif
- +
- +static void
- +pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
- +{
- + int i;
- + DPRINTF(("%s()\n", __FUNCTION__));
- + for (i = 0; i < buf->nsegs; i++) {
- + if (buf->segs[i].ds_tlen) {
- + DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
- + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
- + buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
- + DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
- + }
- + buf->segs[i].ds_addr = 0;
- + buf->segs[i].ds_len = 0;
- + buf->segs[i].ds_tlen = 0;
- + }
- + buf->nsegs = 0;
- + buf->mapsize = 0;
- + buf->map = 0;
- +}
- +
- +
- +/*
- + * SafeXcel Interrupt routine
- + */
- +static irqreturn_t
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- +safe_intr(int irq, void *arg)
- +#else
- +safe_intr(int irq, void *arg, struct pt_regs *regs)
- +#endif
- +{
- + struct safe_softc *sc = arg;
- + int stat;
- + unsigned long flags;
- +
- + stat = READ_REG(sc, SAFE_HM_STAT);
- +
- + DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
- +
- + if (stat == 0) /* shared irq, not for us */
- + return IRQ_NONE;
- +
- + WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
- +
- + if ((stat & SAFE_INT_PE_DDONE)) {
- + /*
- + * Descriptor(s) done; scan the ring and
- + * process completed operations.
- + */
- + spin_lock_irqsave(&sc->sc_ringmtx, flags);
- + while (sc->sc_back != sc->sc_front) {
- + struct safe_ringentry *re = sc->sc_back;
- +
- +#ifdef SAFE_DEBUG
- + if (debug) {
- + safe_dump_ringstate(sc, __func__);
- + safe_dump_request(sc, __func__, re);
- + }
- +#endif
- + /*
- + * safe_process marks ring entries that were allocated
- + * but not used with a csr of zero. This insures the
- + * ring front pointer never needs to be set backwards
- + * in the event that an entry is allocated but not used
- + * because of a setup error.
- + */
- + DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
- + if (re->re_desc.d_csr != 0) {
- + if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
- + DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
- + break;
- + }
- + if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
- + DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
- + break;
- + }
- + sc->sc_nqchip--;
- + safe_callback(sc, re);
- + }
- + if (++(sc->sc_back) == sc->sc_ringtop)
- + sc->sc_back = sc->sc_ring;
- + }
- + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
- + }
- +
- + /*
- + * Check to see if we got any DMA Error
- + */
- + if (stat & SAFE_INT_PE_ERROR) {
- + printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
- + (int)READ_REG(sc, SAFE_PE_DMASTAT));
- + safestats.st_dmaerr++;
- + safe_totalreset(sc);
- +#if 0
- + safe_feed(sc);
- +#endif
- + }
- +
- + if (sc->sc_needwakeup) { /* XXX check high watermark */
- + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
- + DPRINTF(("%s: wakeup crypto %x\n", __func__,
- + sc->sc_needwakeup));
- + sc->sc_needwakeup &= ~wakeup;
- + crypto_unblock(sc->sc_cid, wakeup);
- + }
- +
- + return IRQ_HANDLED;
- +}
- +
- +/*
- + * safe_feed() - post a request to chip
- + */
- +static void
- +safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
- +{
- + DPRINTF(("%s()\n", __FUNCTION__));
- +#ifdef SAFE_DEBUG
- + if (debug) {
- + safe_dump_ringstate(sc, __func__);
- + safe_dump_request(sc, __func__, re);
- + }
- +#endif
- + sc->sc_nqchip++;
- + if (sc->sc_nqchip > safestats.st_maxqchip)
- + safestats.st_maxqchip = sc->sc_nqchip;
- + /* poke h/w to check descriptor ring, any value can be written */
- + WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
- +}
- +
- +#define N(a) (sizeof(a) / sizeof (a[0]))
- +static void
- +safe_setup_enckey(struct safe_session *ses, caddr_t key)
- +{
- + int i;
- +
- + bcopy(key, ses->ses_key, ses->ses_klen / 8);
- +
- + /* PE is little-endian, insure proper byte order */
- + for (i = 0; i < N(ses->ses_key); i++)
- + ses->ses_key[i] = htole32(ses->ses_key[i]);
- +}
- +
- +static void
- +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
- +{
- +#ifdef HMAC_HACK
- + MD5_CTX md5ctx;
- + SHA1_CTX sha1ctx;
- + int i;
- +
- +
- + for (i = 0; i < klen; i++)
- + key[i] ^= HMAC_IPAD_VAL;
- +
- + if (algo == CRYPTO_MD5_HMAC) {
- + MD5Init(&md5ctx);
- + MD5Update(&md5ctx, key, klen);
- + MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
- + bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
- + } else {
- + SHA1Init(&sha1ctx);
- + SHA1Update(&sha1ctx, key, klen);
- + SHA1Update(&sha1ctx, hmac_ipad_buffer,
- + SHA1_HMAC_BLOCK_LEN - klen);
- + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
- + }
- +
- + for (i = 0; i < klen; i++)
- + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
- +
- + if (algo == CRYPTO_MD5_HMAC) {
- + MD5Init(&md5ctx);
- + MD5Update(&md5ctx, key, klen);
- + MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
- + bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
- + } else {
- + SHA1Init(&sha1ctx);
- + SHA1Update(&sha1ctx, key, klen);
- + SHA1Update(&sha1ctx, hmac_opad_buffer,
- + SHA1_HMAC_BLOCK_LEN - klen);
- + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
- + }
- +
- + for (i = 0; i < klen; i++)
- + key[i] ^= HMAC_OPAD_VAL;
- +
- +#if 0
- + /*
- + * this code prevents SHA working on a BE host,
- + * so it is obviously wrong. I think the byte
- + * swap setup we do with the chip fixes this for us
- + */
- +
- + /* PE is little-endian, insure proper byte order */
- + for (i = 0; i < N(ses->ses_hminner); i++) {
- + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
- + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
- + }
- +#endif
- +#else /* HMAC_HACK */
- + printk("safe: md5/sha not implemented\n");
- +#endif /* HMAC_HACK */
- +}
- +#undef N
- +
- +/*
- + * Allocate a new 'session' and return an encoded session id. 'sidp'
- + * contains our registration id, and should contain an encoded session
- + * id on successful allocation.
- + */
- +static int
- +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
- +{
- + struct safe_softc *sc = device_get_softc(dev);
- + struct cryptoini *c, *encini = NULL, *macini = NULL;
- + struct safe_session *ses = NULL;
- + int sesn;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (sidp == NULL || cri == NULL || sc == NULL)
- + return (EINVAL);
- +
- + for (c = cri; c != NULL; c = c->cri_next) {
- + if (c->cri_alg == CRYPTO_MD5_HMAC ||
- + c->cri_alg == CRYPTO_SHA1_HMAC ||
- + c->cri_alg == CRYPTO_NULL_HMAC) {
- + if (macini)
- + return (EINVAL);
- + macini = c;
- + } else if (c->cri_alg == CRYPTO_DES_CBC ||
- + c->cri_alg == CRYPTO_3DES_CBC ||
- + c->cri_alg == CRYPTO_AES_CBC ||
- + c->cri_alg == CRYPTO_NULL_CBC) {
- + if (encini)
- + return (EINVAL);
- + encini = c;
- + } else
- + return (EINVAL);
- + }
- + if (encini == NULL && macini == NULL)
- + return (EINVAL);
- + if (encini) { /* validate key length */
- + switch (encini->cri_alg) {
- + case CRYPTO_DES_CBC:
- + if (encini->cri_klen != 64)
- + return (EINVAL);
- + break;
- + case CRYPTO_3DES_CBC:
- + if (encini->cri_klen != 192)
- + return (EINVAL);
- + break;
- + case CRYPTO_AES_CBC:
- + if (encini->cri_klen != 128 &&
- + encini->cri_klen != 192 &&
- + encini->cri_klen != 256)
- + return (EINVAL);
- + break;
- + }
- + }
- +
- + if (sc->sc_sessions == NULL) {
- + ses = sc->sc_sessions = (struct safe_session *)
- + kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
- + if (ses == NULL)
- + return (ENOMEM);
- + memset(ses, 0, sizeof(struct safe_session));
- + sesn = 0;
- + sc->sc_nsessions = 1;
- + } else {
- + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
- + if (sc->sc_sessions[sesn].ses_used == 0) {
- + ses = &sc->sc_sessions[sesn];
- + break;
- + }
- + }
- +
- + if (ses == NULL) {
- + sesn = sc->sc_nsessions;
- + ses = (struct safe_session *)
- + kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
- + if (ses == NULL)
- + return (ENOMEM);
- + memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
- + bcopy(sc->sc_sessions, ses, sesn *
- + sizeof(struct safe_session));
- + bzero(sc->sc_sessions, sesn *
- + sizeof(struct safe_session));
- + kfree(sc->sc_sessions);
- + sc->sc_sessions = ses;
- + ses = &sc->sc_sessions[sesn];
- + sc->sc_nsessions++;
- + }
- + }
- +
- + bzero(ses, sizeof(struct safe_session));
- + ses->ses_used = 1;
- +
- + if (encini) {
- + /* get an IV */
- + /* XXX may read fewer than requested */
- + read_random(ses->ses_iv, sizeof(ses->ses_iv));
- +
- + ses->ses_klen = encini->cri_klen;
- + if (encini->cri_key != NULL)
- + safe_setup_enckey(ses, encini->cri_key);
- + }
- +
- + if (macini) {
- + ses->ses_mlen = macini->cri_mlen;
- + if (ses->ses_mlen == 0) {
- + if (macini->cri_alg == CRYPTO_MD5_HMAC)
- + ses->ses_mlen = MD5_HASH_LEN;
- + else
- + ses->ses_mlen = SHA1_HASH_LEN;
- + }
- +
- + if (macini->cri_key != NULL) {
- + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
- + macini->cri_klen / 8);
- + }
- + }
- +
- + *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
- + return (0);
- +}
- +
- +/*
- + * Deallocate a session.
- + */
- +static int
- +safe_freesession(device_t dev, u_int64_t tid)
- +{
- + struct safe_softc *sc = device_get_softc(dev);
- + int session, ret;
- + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (sc == NULL)
- + return (EINVAL);
- +
- + session = SAFE_SESSION(sid);
- + if (session < sc->sc_nsessions) {
- + bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
- + ret = 0;
- + } else
- + ret = EINVAL;
- + return (ret);
- +}
- +
- +
- +static int
- +safe_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + struct safe_softc *sc = device_get_softc(dev);
- + int err = 0, i, nicealign, uniform;
- + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
- + int bypass, oplen, ivsize;
- + caddr_t iv;
- + int16_t coffset;
- + struct safe_session *ses;
- + struct safe_ringentry *re;
- + struct safe_sarec *sa;
- + struct safe_pdesc *pd;
- + u_int32_t cmd0, cmd1, staterec;
- + unsigned long flags;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
- + safestats.st_invalid++;
- + return (EINVAL);
- + }
- + if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
- + safestats.st_badsession++;
- + return (EINVAL);
- + }
- +
- + spin_lock_irqsave(&sc->sc_ringmtx, flags);
- + if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
- + safestats.st_ringfull++;
- + sc->sc_needwakeup |= CRYPTO_SYMQ;
- + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
- + return (ERESTART);
- + }
- + re = sc->sc_front;
- +
- + staterec = re->re_sa.sa_staterec; /* save */
- + /* NB: zero everything but the PE descriptor */
- + bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
- + re->re_sa.sa_staterec = staterec; /* restore */
- +
- + re->re_crp = crp;
- + re->re_sesn = SAFE_SESSION(crp->crp_sid);
- +
- + re->re_src.nsegs = 0;
- + re->re_dst.nsegs = 0;
- +
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + re->re_src_skb = (struct sk_buff *)crp->crp_buf;
- + re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + re->re_src_io = (struct uio *)crp->crp_buf;
- + re->re_dst_io = (struct uio *)crp->crp_buf;
- + } else {
- + safestats.st_badflags++;
- + err = EINVAL;
- + goto errout; /* XXX we don't handle contiguous blocks! */
- + }
- +
- + sa = &re->re_sa;
- + ses = &sc->sc_sessions[re->re_sesn];
- +
- + crd1 = crp->crp_desc;
- + if (crd1 == NULL) {
- + safestats.st_nodesc++;
- + err = EINVAL;
- + goto errout;
- + }
- + crd2 = crd1->crd_next;
- +
- + cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
- + cmd1 = 0;
- + if (crd2 == NULL) {
- + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd1->crd_alg == CRYPTO_NULL_HMAC) {
- + maccrd = crd1;
- + enccrd = NULL;
- + cmd0 |= SAFE_SA_CMD0_OP_HASH;
- + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
- + crd1->crd_alg == CRYPTO_3DES_CBC ||
- + crd1->crd_alg == CRYPTO_AES_CBC ||
- + crd1->crd_alg == CRYPTO_NULL_CBC) {
- + maccrd = NULL;
- + enccrd = crd1;
- + cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
- + } else {
- + safestats.st_badalg++;
- + err = EINVAL;
- + goto errout;
- + }
- + } else {
- + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd1->crd_alg == CRYPTO_NULL_HMAC) &&
- + (crd2->crd_alg == CRYPTO_DES_CBC ||
- + crd2->crd_alg == CRYPTO_3DES_CBC ||
- + crd2->crd_alg == CRYPTO_AES_CBC ||
- + crd2->crd_alg == CRYPTO_NULL_CBC) &&
- + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
- + maccrd = crd1;
- + enccrd = crd2;
- + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
- + crd1->crd_alg == CRYPTO_3DES_CBC ||
- + crd1->crd_alg == CRYPTO_AES_CBC ||
- + crd1->crd_alg == CRYPTO_NULL_CBC) &&
- + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
- + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd2->crd_alg == CRYPTO_NULL_HMAC) &&
- + (crd1->crd_flags & CRD_F_ENCRYPT)) {
- + enccrd = crd1;
- + maccrd = crd2;
- + } else {
- + safestats.st_badalg++;
- + err = EINVAL;
- + goto errout;
- + }
- + cmd0 |= SAFE_SA_CMD0_OP_BOTH;
- + }
- +
- + if (enccrd) {
- + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
- + safe_setup_enckey(ses, enccrd->crd_key);
- +
- + if (enccrd->crd_alg == CRYPTO_DES_CBC) {
- + cmd0 |= SAFE_SA_CMD0_DES;
- + cmd1 |= SAFE_SA_CMD1_CBC;
- + ivsize = 2*sizeof(u_int32_t);
- + } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
- + cmd0 |= SAFE_SA_CMD0_3DES;
- + cmd1 |= SAFE_SA_CMD1_CBC;
- + ivsize = 2*sizeof(u_int32_t);
- + } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
- + cmd0 |= SAFE_SA_CMD0_AES;
- + cmd1 |= SAFE_SA_CMD1_CBC;
- + if (ses->ses_klen == 128)
- + cmd1 |= SAFE_SA_CMD1_AES128;
- + else if (ses->ses_klen == 192)
- + cmd1 |= SAFE_SA_CMD1_AES192;
- + else
- + cmd1 |= SAFE_SA_CMD1_AES256;
- + ivsize = 4*sizeof(u_int32_t);
- + } else {
- + cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
- + ivsize = 0;
- + }
- +
- + /*
- + * Setup encrypt/decrypt state. When using basic ops
- + * we can't use an inline IV because hash/crypt offset
- + * must be from the end of the IV to the start of the
- + * crypt data and this leaves out the preceding header
- + * from the hash calculation. Instead we place the IV
- + * in the state record and set the hash/crypt offset to
- + * copy both the header+IV.
- + */
- + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
- + cmd0 |= SAFE_SA_CMD0_OUTBOUND;
- +
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
- + iv = enccrd->crd_iv;
- + else
- + iv = (caddr_t) ses->ses_iv;
- + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + enccrd->crd_inject, ivsize, iv);
- + }
- + bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
- + /* make iv LE */
- + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
- + re->re_sastate.sa_saved_iv[i] =
- + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
- + cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
- + re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
- + } else {
- + cmd0 |= SAFE_SA_CMD0_INBOUND;
- +
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
- + bcopy(enccrd->crd_iv,
- + re->re_sastate.sa_saved_iv, ivsize);
- + } else {
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + enccrd->crd_inject, ivsize,
- + (caddr_t)re->re_sastate.sa_saved_iv);
- + }
- + /* make iv LE */
- + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
- + re->re_sastate.sa_saved_iv[i] =
- + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
- + cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
- + }
- + /*
- + * For basic encryption use the zero pad algorithm.
- + * This pads results to an 8-byte boundary and
- + * suppresses padding verification for inbound (i.e.
- + * decrypt) operations.
- + *
- + * NB: Not sure if the 8-byte pad boundary is a problem.
- + */
- + cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
- +
- + /* XXX assert key bufs have the same size */
- + bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
- + }
- +
- + if (maccrd) {
- + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
- + safe_setup_mackey(ses, maccrd->crd_alg,
- + maccrd->crd_key, maccrd->crd_klen / 8);
- + }
- +
- + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
- + cmd0 |= SAFE_SA_CMD0_MD5;
- + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
- + } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
- + cmd0 |= SAFE_SA_CMD0_SHA1;
- + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
- + } else {
- + cmd0 |= SAFE_SA_CMD0_HASH_NULL;
- + }
- + /*
- + * Digest data is loaded from the SA and the hash
- + * result is saved to the state block where we
- + * retrieve it for return to the caller.
- + */
- + /* XXX assert digest bufs have the same size */
- + bcopy(ses->ses_hminner, sa->sa_indigest,
- + sizeof(sa->sa_indigest));
- + bcopy(ses->ses_hmouter, sa->sa_outdigest,
- + sizeof(sa->sa_outdigest));
- +
- + cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
- + re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
- + }
- +
- + if (enccrd && maccrd) {
- + /*
- + * The offset from hash data to the start of
- + * crypt data is the difference in the skips.
- + */
- + bypass = maccrd->crd_skip;
- + coffset = enccrd->crd_skip - maccrd->crd_skip;
- + if (coffset < 0) {
- + DPRINTF(("%s: hash does not precede crypt; "
- + "mac skip %u enc skip %u\n",
- + __func__, maccrd->crd_skip, enccrd->crd_skip));
- + safestats.st_skipmismatch++;
- + err = EINVAL;
- + goto errout;
- + }
- + oplen = enccrd->crd_skip + enccrd->crd_len;
- + if (maccrd->crd_skip + maccrd->crd_len != oplen) {
- + DPRINTF(("%s: hash amount %u != crypt amount %u\n",
- + __func__, maccrd->crd_skip + maccrd->crd_len,
- + oplen));
- + safestats.st_lenmismatch++;
- + err = EINVAL;
- + goto errout;
- + }
- +#ifdef SAFE_DEBUG
- + if (debug) {
- + printf("mac: skip %d, len %d, inject %d\n",
- + maccrd->crd_skip, maccrd->crd_len,
- + maccrd->crd_inject);
- + printf("enc: skip %d, len %d, inject %d\n",
- + enccrd->crd_skip, enccrd->crd_len,
- + enccrd->crd_inject);
- + printf("bypass %d coffset %d oplen %d\n",
- + bypass, coffset, oplen);
- + }
- +#endif
- + if (coffset & 3) { /* offset must be 32-bit aligned */
- + DPRINTF(("%s: coffset %u misaligned\n",
- + __func__, coffset));
- + safestats.st_coffmisaligned++;
- + err = EINVAL;
- + goto errout;
- + }
- + coffset >>= 2;
- + if (coffset > 255) { /* offset must be <256 dwords */
- + DPRINTF(("%s: coffset %u too big\n",
- + __func__, coffset));
- + safestats.st_cofftoobig++;
- + err = EINVAL;
- + goto errout;
- + }
- + /*
- + * Tell the hardware to copy the header to the output.
- + * The header is defined as the data from the end of
- + * the bypass to the start of data to be encrypted.
- + * Typically this is the inline IV. Note that you need
- + * to do this even if src+dst are the same; it appears
- + * that w/o this bit the crypted data is written
- + * immediately after the bypass data.
- + */
- + cmd1 |= SAFE_SA_CMD1_HDRCOPY;
- + /*
- + * Disable IP header mutable bit handling. This is
- + * needed to get correct HMAC calculations.
- + */
- + cmd1 |= SAFE_SA_CMD1_MUTABLE;
- + } else {
- + if (enccrd) {
- + bypass = enccrd->crd_skip;
- + oplen = bypass + enccrd->crd_len;
- + } else {
- + bypass = maccrd->crd_skip;
- + oplen = bypass + maccrd->crd_len;
- + }
- + coffset = 0;
- + }
- + /* XXX verify multiple of 4 when using s/g */
- + if (bypass > 96) { /* bypass offset must be <= 96 bytes */
- + DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
- + safestats.st_bypasstoobig++;
- + err = EINVAL;
- + goto errout;
- + }
- +
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
- + safestats.st_noload++;
- + err = ENOMEM;
- + goto errout;
- + }
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
- + safestats.st_noload++;
- + err = ENOMEM;
- + goto errout;
- + }
- + }
- + nicealign = safe_dmamap_aligned(sc, &re->re_src);
- + uniform = safe_dmamap_uniform(sc, &re->re_src);
- +
- + DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
- + nicealign, uniform, re->re_src.nsegs));
- + if (re->re_src.nsegs > 1) {
- + re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
- + ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
- + for (i = 0; i < re->re_src_nsegs; i++) {
- + /* NB: no need to check if there's space */
- + pd = sc->sc_spfree;
- + if (++(sc->sc_spfree) == sc->sc_springtop)
- + sc->sc_spfree = sc->sc_spring;
- +
- + KASSERT((pd->pd_flags&3) == 0 ||
- + (pd->pd_flags&3) == SAFE_PD_DONE,
- + ("bogus source particle descriptor; flags %x",
- + pd->pd_flags));
- + pd->pd_addr = re->re_src_segs[i].ds_addr;
- + pd->pd_size = re->re_src_segs[i].ds_len;
- + pd->pd_flags = SAFE_PD_READY;
- + }
- + cmd0 |= SAFE_SA_CMD0_IGATHER;
- + } else {
- + /*
- + * No need for gather, reference the operand directly.
- + */
- + re->re_desc.d_src = re->re_src_segs[0].ds_addr;
- + }
- +
- + if (enccrd == NULL && maccrd != NULL) {
- + /*
- + * Hash op; no destination needed.
- + */
- + } else {
- + if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
- + if (!nicealign) {
- + safestats.st_iovmisaligned++;
- + err = EINVAL;
- + goto errout;
- + }
- + if (uniform != 1) {
- + device_printf(sc->sc_dev, "!uniform source\n");
- + if (!uniform) {
- + /*
- + * There's no way to handle the DMA
- + * requirements with this uio. We
- + * could create a separate DMA area for
- + * the result and then copy it back,
- + * but for now we just bail and return
- + * an error. Note that uio requests
- + * > SAFE_MAX_DSIZE are handled because
- + * the DMA map and segment list for the
- + * destination wil result in a
- + * destination particle list that does
- + * the necessary scatter DMA.
- + */
- + safestats.st_iovnotuniform++;
- + err = EINVAL;
- + goto errout;
- + }
- + } else
- + re->re_dst = re->re_src;
- + } else {
- + safestats.st_badflags++;
- + err = EINVAL;
- + goto errout;
- + }
- +
- + if (re->re_dst.nsegs > 1) {
- + re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
- + ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
- + for (i = 0; i < re->re_dst_nsegs; i++) {
- + pd = sc->sc_dpfree;
- + KASSERT((pd->pd_flags&3) == 0 ||
- + (pd->pd_flags&3) == SAFE_PD_DONE,
- + ("bogus dest particle descriptor; flags %x",
- + pd->pd_flags));
- + if (++(sc->sc_dpfree) == sc->sc_dpringtop)
- + sc->sc_dpfree = sc->sc_dpring;
- + pd->pd_addr = re->re_dst_segs[i].ds_addr;
- + pd->pd_flags = SAFE_PD_READY;
- + }
- + cmd0 |= SAFE_SA_CMD0_OSCATTER;
- + } else {
- + /*
- + * No need for scatter, reference the operand directly.
- + */
- + re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
- + }
- + }
- +
- + /*
- + * All done with setup; fillin the SA command words
- + * and the packet engine descriptor. The operation
- + * is now ready for submission to the hardware.
- + */
- + sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
- + sa->sa_cmd1 = cmd1
- + | (coffset << SAFE_SA_CMD1_OFFSET_S)
- + | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
- + | SAFE_SA_CMD1_SRPCI
- + ;
- + /*
- + * NB: the order of writes is important here. In case the
- + * chip is scanning the ring because of an outstanding request
- + * it might nab this one too. In that case we need to make
- + * sure the setup is complete before we write the length
- + * field of the descriptor as it signals the descriptor is
- + * ready for processing.
- + */
- + re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
- + if (maccrd)
- + re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
- + wmb();
- + re->re_desc.d_len = oplen
- + | SAFE_PE_LEN_READY
- + | (bypass << SAFE_PE_LEN_BYPASS_S)
- + ;
- +
- + safestats.st_ipackets++;
- + safestats.st_ibytes += oplen;
- +
- + if (++(sc->sc_front) == sc->sc_ringtop)
- + sc->sc_front = sc->sc_ring;
- +
- + /* XXX honor batching */
- + safe_feed(sc, re);
- + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
- + return (0);
- +
- +errout:
- + if (re->re_src.map != re->re_dst.map)
- + pci_unmap_operand(sc, &re->re_dst);
- + if (re->re_src.map)
- + pci_unmap_operand(sc, &re->re_src);
- + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
- + if (err != ERESTART) {
- + crp->crp_etype = err;
- + crypto_done(crp);
- + } else {
- + sc->sc_needwakeup |= CRYPTO_SYMQ;
- + }
- + return (err);
- +}
- +
- +static void
- +safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
- +{
- + struct cryptop *crp = (struct cryptop *)re->re_crp;
- + struct cryptodesc *crd;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + safestats.st_opackets++;
- + safestats.st_obytes += re->re_dst.mapsize;
- +
- + if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
- + device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
- + re->re_desc.d_csr,
- + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
- + safestats.st_peoperr++;
- + crp->crp_etype = EIO; /* something more meaningful? */
- + }
- +
- + if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
- + pci_unmap_operand(sc, &re->re_dst);
- + pci_unmap_operand(sc, &re->re_src);
- +
- + /*
- + * If result was written to a differet mbuf chain, swap
- + * it in as the return value and reclaim the original.
- + */
- + if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
- + device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
- + /* kfree_skb(skb) */
- + /* crp->crp_buf = (caddr_t)re->re_dst_skb */
- + return;
- + }
- +
- + if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
- + /* copy out IV for future use */
- + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
- + int i;
- + int ivsize;
- +
- + if (crd->crd_alg == CRYPTO_DES_CBC ||
- + crd->crd_alg == CRYPTO_3DES_CBC) {
- + ivsize = 2*sizeof(u_int32_t);
- + } else if (crd->crd_alg == CRYPTO_AES_CBC) {
- + ivsize = 4*sizeof(u_int32_t);
- + } else
- + continue;
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + crd->crd_skip + crd->crd_len - ivsize, ivsize,
- + (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
- + for (i = 0;
- + i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
- + i++)
- + sc->sc_sessions[re->re_sesn].ses_iv[i] =
- + cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
- + break;
- + }
- + }
- +
- + if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
- + /* copy out ICV result */
- + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
- + if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
- + crd->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd->crd_alg == CRYPTO_NULL_HMAC))
- + continue;
- + if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
- + /*
- + * SHA-1 ICV's are byte-swapped; fix 'em up
- + * before copy them to their destination.
- + */
- + re->re_sastate.sa_saved_indigest[0] =
- + cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
- + re->re_sastate.sa_saved_indigest[1] =
- + cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
- + re->re_sastate.sa_saved_indigest[2] =
- + cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
- + } else {
- + re->re_sastate.sa_saved_indigest[0] =
- + cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
- + re->re_sastate.sa_saved_indigest[1] =
- + cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
- + re->re_sastate.sa_saved_indigest[2] =
- + cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
- + }
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + crd->crd_inject,
- + sc->sc_sessions[re->re_sesn].ses_mlen,
- + (caddr_t)re->re_sastate.sa_saved_indigest);
- + break;
- + }
- + }
- + crypto_done(crp);
- +}
- +
- +
- +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
- +#define SAFE_RNG_MAXWAIT 1000
- +
- +static void
- +safe_rng_init(struct safe_softc *sc)
- +{
- + u_int32_t w, v;
- + int i;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + WRITE_REG(sc, SAFE_RNG_CTRL, 0);
- + /* use default value according to the manual */
- + WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
- + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
- +
- + /*
- + * There is a bug in rev 1.0 of the 1140 that when the RNG
- + * is brought out of reset the ready status flag does not
- + * work until the RNG has finished its internal initialization.
- + *
- + * So in order to determine the device is through its
- + * initialization we must read the data register, using the
- + * status reg in the read in case it is initialized. Then read
- + * the data register until it changes from the first read.
- + * Once it changes read the data register until it changes
- + * again. At this time the RNG is considered initialized.
- + * This could take between 750ms - 1000ms in time.
- + */
- + i = 0;
- + w = READ_REG(sc, SAFE_RNG_OUT);
- + do {
- + v = READ_REG(sc, SAFE_RNG_OUT);
- + if (v != w) {
- + w = v;
- + break;
- + }
- + DELAY(10);
- + } while (++i < SAFE_RNG_MAXWAIT);
- +
- + /* Wait Until data changes again */
- + i = 0;
- + do {
- + v = READ_REG(sc, SAFE_RNG_OUT);
- + if (v != w)
- + break;
- + DELAY(10);
- + } while (++i < SAFE_RNG_MAXWAIT);
- +}
- +
- +static __inline void
- +safe_rng_disable_short_cycle(struct safe_softc *sc)
- +{
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + WRITE_REG(sc, SAFE_RNG_CTRL,
- + READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
- +}
- +
- +static __inline void
- +safe_rng_enable_short_cycle(struct safe_softc *sc)
- +{
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + WRITE_REG(sc, SAFE_RNG_CTRL,
- + READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
- +}
- +
- +static __inline u_int32_t
- +safe_rng_read(struct safe_softc *sc)
- +{
- + int i;
- +
- + i = 0;
- + while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
- + ;
- + return READ_REG(sc, SAFE_RNG_OUT);
- +}
- +
- +static int
- +safe_read_random(void *arg, u_int32_t *buf, int maxwords)
- +{
- + struct safe_softc *sc = (struct safe_softc *) arg;
- + int i, rc;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + safestats.st_rng++;
- + /*
- + * Fetch the next block of data.
- + */
- + if (maxwords > safe_rngbufsize)
- + maxwords = safe_rngbufsize;
- + if (maxwords > SAFE_RNG_MAXBUFSIZ)
- + maxwords = SAFE_RNG_MAXBUFSIZ;
- +retry:
- + /* read as much as we can */
- + for (rc = 0; rc < maxwords; rc++) {
- + if (READ_REG(sc, SAFE_RNG_STAT) != 0)
- + break;
- + buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
- + }
- + if (rc == 0)
- + return 0;
- + /*
- + * Check the comparator alarm count and reset the h/w if
- + * it exceeds our threshold. This guards against the
- + * hardware oscillators resonating with external signals.
- + */
- + if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
- + u_int32_t freq_inc, w;
- +
- + DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
- + (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
- + safestats.st_rngalarm++;
- + safe_rng_enable_short_cycle(sc);
- + freq_inc = 18;
- + for (i = 0; i < 64; i++) {
- + w = READ_REG(sc, SAFE_RNG_CNFG);
- + freq_inc = ((w + freq_inc) & 0x3fL);
- + w = ((w & ~0x3fL) | freq_inc);
- + WRITE_REG(sc, SAFE_RNG_CNFG, w);
- +
- + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
- +
- + (void) safe_rng_read(sc);
- + DELAY(25);
- +
- + if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
- + safe_rng_disable_short_cycle(sc);
- + goto retry;
- + }
- + freq_inc = 1;
- + }
- + safe_rng_disable_short_cycle(sc);
- + } else
- + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
- +
- + return(rc);
- +}
- +#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
- +
- +
- +/*
- + * Resets the board. Values in the regesters are left as is
- + * from the reset (i.e. initial values are assigned elsewhere).
- + */
- +static void
- +safe_reset_board(struct safe_softc *sc)
- +{
- + u_int32_t v;
- + /*
- + * Reset the device. The manual says no delay
- + * is needed between marking and clearing reset.
- + */
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + v = READ_REG(sc, SAFE_PE_DMACFG) &~
- + (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
- + SAFE_PE_DMACFG_SGRESET);
- + WRITE_REG(sc, SAFE_PE_DMACFG, v
- + | SAFE_PE_DMACFG_PERESET
- + | SAFE_PE_DMACFG_PDRRESET
- + | SAFE_PE_DMACFG_SGRESET);
- + WRITE_REG(sc, SAFE_PE_DMACFG, v);
- +}
- +
- +/*
- + * Initialize registers we need to touch only once.
- + */
- +static void
- +safe_init_board(struct safe_softc *sc)
- +{
- + u_int32_t v, dwords;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + v = READ_REG(sc, SAFE_PE_DMACFG);
- + v &=~ ( SAFE_PE_DMACFG_PEMODE
- + | SAFE_PE_DMACFG_FSENA /* failsafe enable */
- + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
- + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
- + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
- + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
- + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
- + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
- + );
- + v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
- + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
- + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
- + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
- + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
- + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
- +#if 0
- + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
- +#endif
- + ;
- + WRITE_REG(sc, SAFE_PE_DMACFG, v);
- +
- +#ifdef __BIG_ENDIAN
- + /* tell the safenet that we are 4321 and not 1234 */
- + WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
- +#endif
- +
- + if (sc->sc_chiprev == SAFE_REV(1,0)) {
- + /*
- + * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
- + * "target mode transfers" done while the chip is DMA'ing
- + * >1020 bytes cause the hardware to lockup. To avoid this
- + * we reduce the max PCI transfer size and use small source
- + * particle descriptors (<= 256 bytes).
- + */
- + WRITE_REG(sc, SAFE_DMA_CFG, 256);
- + device_printf(sc->sc_dev,
- + "Reduce max DMA size to %u words for rev %u.%u WAR\n",
- + (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
- + (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
- + (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
- + sc->sc_max_dsize = 256;
- + } else {
- + sc->sc_max_dsize = SAFE_MAX_DSIZE;
- + }
- +
- + /* NB: operands+results are overlaid */
- + WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
- + WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
- + /*
- + * Configure ring entry size and number of items in the ring.
- + */
- + KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
- + ("PE ring entry not 32-bit aligned!"));
- + dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
- + WRITE_REG(sc, SAFE_PE_RINGCFG,
- + (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
- + WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
- +
- + WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
- + WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
- + WRITE_REG(sc, SAFE_PE_PARTSIZE,
- + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
- + /*
- + * NB: destination particles are fixed size. We use
- + * an mbuf cluster and require all results go to
- + * clusters or smaller.
- + */
- + WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
- +
- + /* it's now safe to enable PE mode, do it */
- + WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
- +
- + /*
- + * Configure hardware to use level-triggered interrupts and
- + * to interrupt after each descriptor is processed.
- + */
- + WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
- + WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
- + WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
- + WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
- +}
- +
- +
- +/*
- + * Clean up after a chip crash.
- + * It is assumed that the caller in splimp()
- + */
- +static void
- +safe_cleanchip(struct safe_softc *sc)
- +{
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (sc->sc_nqchip != 0) {
- + struct safe_ringentry *re = sc->sc_back;
- +
- + while (re != sc->sc_front) {
- + if (re->re_desc.d_csr != 0)
- + safe_free_entry(sc, re);
- + if (++re == sc->sc_ringtop)
- + re = sc->sc_ring;
- + }
- + sc->sc_back = re;
- + sc->sc_nqchip = 0;
- + }
- +}
- +
- +/*
- + * free a safe_q
- + * It is assumed that the caller is within splimp().
- + */
- +static int
- +safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
- +{
- + struct cryptop *crp;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + /*
- + * Free header MCR
- + */
- + if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
- +#ifdef NOTYET
- + m_freem(re->re_dst_m);
- +#else
- + printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
- +#endif
- +
- + crp = (struct cryptop *)re->re_crp;
- +
- + re->re_desc.d_csr = 0;
- +
- + crp->crp_etype = EFAULT;
- + crypto_done(crp);
- + return(0);
- +}
- +
- +/*
- + * Routine to reset the chip and clean up.
- + * It is assumed that the caller is in splimp()
- + */
- +static void
- +safe_totalreset(struct safe_softc *sc)
- +{
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + safe_reset_board(sc);
- + safe_init_board(sc);
- + safe_cleanchip(sc);
- +}
- +
- +/*
- + * Is the operand suitable aligned for direct DMA. Each
- + * segment must be aligned on a 32-bit boundary and all
- + * but the last segment must be a multiple of 4 bytes.
- + */
- +static int
- +safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
- +{
- + int i;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + for (i = 0; i < op->nsegs; i++) {
- + if (op->segs[i].ds_addr & 3)
- + return (0);
- + if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
- + return (0);
- + }
- + return (1);
- +}
- +
- +/*
- + * Is the operand suitable for direct DMA as the destination
- + * of an operation. The hardware requires that each ``particle''
- + * but the last in an operation result have the same size. We
- + * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
- + * 0 if some segment is not a multiple of of this size, 1 if all
- + * segments are exactly this size, or 2 if segments are at worst
- + * a multple of this size.
- + */
- +static int
- +safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
- +{
- + int result = 1;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (op->nsegs > 0) {
- + int i;
- +
- + for (i = 0; i < op->nsegs-1; i++) {
- + if (op->segs[i].ds_len % sc->sc_max_dsize)
- + return (0);
- + if (op->segs[i].ds_len != sc->sc_max_dsize)
- + result = 2;
- + }
- + }
- + return (result);
- +}
- +
- +static int
- +safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
- +{
- + struct safe_softc *sc = device_get_softc(dev);
- + struct safe_pkq *q;
- + unsigned long flags;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (sc == NULL) {
- + krp->krp_status = EINVAL;
- + goto err;
- + }
- +
- + if (krp->krp_op != CRK_MOD_EXP) {
- + krp->krp_status = EOPNOTSUPP;
- + goto err;
- + }
- +
- + q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
- + if (q == NULL) {
- + krp->krp_status = ENOMEM;
- + goto err;
- + }
- + memset(q, 0, sizeof(*q));
- + q->pkq_krp = krp;
- + INIT_LIST_HEAD(&q->pkq_list);
- +
- + spin_lock_irqsave(&sc->sc_pkmtx, flags);
- + list_add_tail(&q->pkq_list, &sc->sc_pkq);
- + safe_kfeed(sc);
- + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
- + return (0);
- +
- +err:
- + crypto_kdone(krp);
- + return (0);
- +}
- +
- +#define SAFE_CRK_PARAM_BASE 0
- +#define SAFE_CRK_PARAM_EXP 1
- +#define SAFE_CRK_PARAM_MOD 2
- +
- +static int
- +safe_kstart(struct safe_softc *sc)
- +{
- + struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
- + int exp_bits, mod_bits, base_bits;
- + u_int32_t op, a_off, b_off, c_off, d_off;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
- + krp->krp_status = EINVAL;
- + return (1);
- + }
- +
- + base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
- + if (base_bits > 2048)
- + goto too_big;
- + if (base_bits <= 0) /* 5. base not zero */
- + goto too_small;
- +
- + exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
- + if (exp_bits > 2048)
- + goto too_big;
- + if (exp_bits <= 0) /* 1. exponent word length > 0 */
- + goto too_small; /* 4. exponent not zero */
- +
- + mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
- + if (mod_bits > 2048)
- + goto too_big;
- + if (mod_bits <= 32) /* 2. modulus word length > 1 */
- + goto too_small; /* 8. MSW of modulus != zero */
- + if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
- + goto too_small;
- + if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
- + goto bad_domain; /* 6. modulus is odd */
- + if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
- + goto too_small; /* make sure result will fit */
- +
- + /* 7. modulus > base */
- + if (mod_bits < base_bits)
- + goto too_small;
- + if (mod_bits == base_bits) {
- + u_int8_t *basep, *modp;
- + int i;
- +
- + basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
- + ((base_bits + 7) / 8) - 1;
- + modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
- + ((mod_bits + 7) / 8) - 1;
- +
- + for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
- + if (*modp < *basep)
- + goto too_small;
- + if (*modp > *basep)
- + break;
- + }
- + }
- +
- + /* And on the 9th step, he rested. */
- +
- + WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
- + WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
- + if (mod_bits > 1024) {
- + op = SAFE_PK_FUNC_EXP4;
- + a_off = 0x000;
- + b_off = 0x100;
- + c_off = 0x200;
- + d_off = 0x300;
- + } else {
- + op = SAFE_PK_FUNC_EXP16;
- + a_off = 0x000;
- + b_off = 0x080;
- + c_off = 0x100;
- + d_off = 0x180;
- + }
- + sc->sc_pk_reslen = b_off - a_off;
- + sc->sc_pk_resoff = d_off;
- +
- + /* A is exponent, B is modulus, C is base, D is result */
- + safe_kload_reg(sc, a_off, b_off - a_off,
- + &krp->krp_param[SAFE_CRK_PARAM_EXP]);
- + WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
- + safe_kload_reg(sc, b_off, b_off - a_off,
- + &krp->krp_param[SAFE_CRK_PARAM_MOD]);
- + WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
- + safe_kload_reg(sc, c_off, b_off - a_off,
- + &krp->krp_param[SAFE_CRK_PARAM_BASE]);
- + WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
- + WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
- +
- + WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
- +
- + return (0);
- +
- +too_big:
- + krp->krp_status = E2BIG;
- + return (1);
- +too_small:
- + krp->krp_status = ERANGE;
- + return (1);
- +bad_domain:
- + krp->krp_status = EDOM;
- + return (1);
- +}
- +
- +static int
- +safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
- +{
- + u_int plen = (cr->crp_nbits + 7) / 8;
- + int i, sig = plen * 8;
- + u_int8_t c, *p = cr->crp_p;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + for (i = plen - 1; i >= 0; i--) {
- + c = p[i];
- + if (c != 0) {
- + while ((c & 0x80) == 0) {
- + sig--;
- + c <<= 1;
- + }
- + break;
- + }
- + sig -= 8;
- + }
- + return (sig);
- +}
- +
- +static void
- +safe_kfeed(struct safe_softc *sc)
- +{
- + struct safe_pkq *q, *tmp;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
- + return;
- + if (sc->sc_pkq_cur != NULL)
- + return;
- + list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
- + sc->sc_pkq_cur = q;
- + list_del(&q->pkq_list);
- + if (safe_kstart(sc) != 0) {
- + crypto_kdone(q->pkq_krp);
- + kfree(q);
- + sc->sc_pkq_cur = NULL;
- + } else {
- + /* op started, start polling */
- + mod_timer(&sc->sc_pkto, jiffies + 1);
- + break;
- + }
- + }
- +}
- +
- +static void
- +safe_kpoll(unsigned long arg)
- +{
- + struct safe_softc *sc = NULL;
- + struct safe_pkq *q;
- + struct crparam *res;
- + int i;
- + u_int32_t buf[64];
- + unsigned long flags;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (arg >= SAFE_MAX_CHIPS)
- + return;
- + sc = safe_chip_idx[arg];
- + if (!sc) {
- + DPRINTF(("%s() - bad callback\n", __FUNCTION__));
- + return;
- + }
- +
- + spin_lock_irqsave(&sc->sc_pkmtx, flags);
- + if (sc->sc_pkq_cur == NULL)
- + goto out;
- + if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
- + /* still running, check back later */
- + mod_timer(&sc->sc_pkto, jiffies + 1);
- + goto out;
- + }
- +
- + q = sc->sc_pkq_cur;
- + res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
- + bzero(buf, sizeof(buf));
- + bzero(res->crp_p, (res->crp_nbits + 7) / 8);
- + for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
- + buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
- + sc->sc_pk_resoff + (i << 2)));
- + bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
- + /*
- + * reduce the bits that need copying if possible
- + */
- + res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
- + res->crp_nbits = safe_ksigbits(sc, res);
- +
- + for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
- + WRITE_REG(sc, i, 0);
- +
- + crypto_kdone(q->pkq_krp);
- + kfree(q);
- + sc->sc_pkq_cur = NULL;
- +
- + safe_kfeed(sc);
- +out:
- + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
- +}
- +
- +static void
- +safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
- + struct crparam *n)
- +{
- + u_int32_t buf[64], i;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + bzero(buf, sizeof(buf));
- + bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
- +
- + for (i = 0; i < len >> 2; i++)
- + WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
- + cpu_to_le32(buf[i]));
- +}
- +
- +#ifdef SAFE_DEBUG
- +static void
- +safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
- +{
- + printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
- + , tag
- + , READ_REG(sc, SAFE_DMA_ENDIAN)
- + , READ_REG(sc, SAFE_DMA_SRCADDR)
- + , READ_REG(sc, SAFE_DMA_DSTADDR)
- + , READ_REG(sc, SAFE_DMA_STAT)
- + );
- +}
- +
- +static void
- +safe_dump_intrstate(struct safe_softc *sc, const char *tag)
- +{
- + printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
- + , tag
- + , READ_REG(sc, SAFE_HI_CFG)
- + , READ_REG(sc, SAFE_HI_MASK)
- + , READ_REG(sc, SAFE_HI_DESC_CNT)
- + , READ_REG(sc, SAFE_HU_STAT)
- + , READ_REG(sc, SAFE_HM_STAT)
- + );
- +}
- +
- +static void
- +safe_dump_ringstate(struct safe_softc *sc, const char *tag)
- +{
- + u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
- +
- + /* NB: assume caller has lock on ring */
- + printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
- + tag,
- + estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
- + (unsigned long)(sc->sc_back - sc->sc_ring),
- + (unsigned long)(sc->sc_front - sc->sc_ring));
- +}
- +
- +static void
- +safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
- +{
- + int ix, nsegs;
- +
- + ix = re - sc->sc_ring;
- + printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
- + , tag
- + , re, ix
- + , re->re_desc.d_csr
- + , re->re_desc.d_src
- + , re->re_desc.d_dst
- + , re->re_desc.d_sa
- + , re->re_desc.d_len
- + );
- + if (re->re_src.nsegs > 1) {
- + ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
- + sizeof(struct safe_pdesc);
- + for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
- + printf(" spd[%u] %p: %p size %u flags %x"
- + , ix, &sc->sc_spring[ix]
- + , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
- + , sc->sc_spring[ix].pd_size
- + , sc->sc_spring[ix].pd_flags
- + );
- + if (sc->sc_spring[ix].pd_size == 0)
- + printf(" (zero!)");
- + printf("\n");
- + if (++ix == SAFE_TOTAL_SPART)
- + ix = 0;
- + }
- + }
- + if (re->re_dst.nsegs > 1) {
- + ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
- + sizeof(struct safe_pdesc);
- + for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
- + printf(" dpd[%u] %p: %p flags %x\n"
- + , ix, &sc->sc_dpring[ix]
- + , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
- + , sc->sc_dpring[ix].pd_flags
- + );
- + if (++ix == SAFE_TOTAL_DPART)
- + ix = 0;
- + }
- + }
- + printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
- + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
- + printf("sa: key %x %x %x %x %x %x %x %x\n"
- + , re->re_sa.sa_key[0]
- + , re->re_sa.sa_key[1]
- + , re->re_sa.sa_key[2]
- + , re->re_sa.sa_key[3]
- + , re->re_sa.sa_key[4]
- + , re->re_sa.sa_key[5]
- + , re->re_sa.sa_key[6]
- + , re->re_sa.sa_key[7]
- + );
- + printf("sa: indigest %x %x %x %x %x\n"
- + , re->re_sa.sa_indigest[0]
- + , re->re_sa.sa_indigest[1]
- + , re->re_sa.sa_indigest[2]
- + , re->re_sa.sa_indigest[3]
- + , re->re_sa.sa_indigest[4]
- + );
- + printf("sa: outdigest %x %x %x %x %x\n"
- + , re->re_sa.sa_outdigest[0]
- + , re->re_sa.sa_outdigest[1]
- + , re->re_sa.sa_outdigest[2]
- + , re->re_sa.sa_outdigest[3]
- + , re->re_sa.sa_outdigest[4]
- + );
- + printf("sr: iv %x %x %x %x\n"
- + , re->re_sastate.sa_saved_iv[0]
- + , re->re_sastate.sa_saved_iv[1]
- + , re->re_sastate.sa_saved_iv[2]
- + , re->re_sastate.sa_saved_iv[3]
- + );
- + printf("sr: hashbc %u indigest %x %x %x %x %x\n"
- + , re->re_sastate.sa_saved_hashbc
- + , re->re_sastate.sa_saved_indigest[0]
- + , re->re_sastate.sa_saved_indigest[1]
- + , re->re_sastate.sa_saved_indigest[2]
- + , re->re_sastate.sa_saved_indigest[3]
- + , re->re_sastate.sa_saved_indigest[4]
- + );
- +}
- +
- +static void
- +safe_dump_ring(struct safe_softc *sc, const char *tag)
- +{
- + unsigned long flags;
- +
- + spin_lock_irqsave(&sc->sc_ringmtx, flags);
- + printf("\nSafeNet Ring State:\n");
- + safe_dump_intrstate(sc, tag);
- + safe_dump_dmastatus(sc, tag);
- + safe_dump_ringstate(sc, tag);
- + if (sc->sc_nqchip) {
- + struct safe_ringentry *re = sc->sc_back;
- + do {
- + safe_dump_request(sc, tag, re);
- + if (++re == sc->sc_ringtop)
- + re = sc->sc_ring;
- + } while (re != sc->sc_front);
- + }
- + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
- +}
- +#endif /* SAFE_DEBUG */
- +
- +
- +static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
- +{
- + struct safe_softc *sc = NULL;
- + u32 mem_start, mem_len, cmd;
- + int i, rc, devinfo;
- + dma_addr_t raddr;
- + static int num_chips = 0;
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + if (pci_enable_device(dev) < 0)
- + return(-ENODEV);
- +
- + if (!dev->irq) {
- + printk("safe: found device with no IRQ assigned. check BIOS settings!");
- + pci_disable_device(dev);
- + return(-ENODEV);
- + }
- +
- + if (pci_set_mwi(dev)) {
- + printk("safe: pci_set_mwi failed!");
- + return(-ENODEV);
- + }
- +
- + sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
- + if (!sc)
- + return(-ENOMEM);
- + memset(sc, 0, sizeof(*sc));
- +
- + softc_device_init(sc, "safe", num_chips, safe_methods);
- +
- + sc->sc_irq = -1;
- + sc->sc_cid = -1;
- + sc->sc_pcidev = dev;
- + if (num_chips < SAFE_MAX_CHIPS) {
- + safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
- + num_chips++;
- + }
- +
- + INIT_LIST_HEAD(&sc->sc_pkq);
- + spin_lock_init(&sc->sc_pkmtx);
- +
- + pci_set_drvdata(sc->sc_pcidev, sc);
- +
- + /* we read its hardware registers as memory */
- + mem_start = pci_resource_start(sc->sc_pcidev, 0);
- + mem_len = pci_resource_len(sc->sc_pcidev, 0);
- +
- + sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
- + if (!sc->sc_base_addr) {
- + device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
- + mem_start, mem_start + mem_len - 1);
- + goto out;
- + }
- +
- + /* fix up the bus size */
- + if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
- + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
- + goto out;
- + }
- + if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
- + device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
- + goto out;
- + }
- +
- + pci_set_master(sc->sc_pcidev);
- +
- + pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
- +
- + if (!(cmd & PCI_COMMAND_MEMORY)) {
- + device_printf(sc->sc_dev, "failed to enable memory mapping\n");
- + goto out;
- + }
- +
- + if (!(cmd & PCI_COMMAND_MASTER)) {
- + device_printf(sc->sc_dev, "failed to enable bus mastering\n");
- + goto out;
- + }
- +
- + rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
- + if (rc) {
- + device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
- + goto out;
- + }
- + sc->sc_irq = dev->irq;
- +
- + sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
- + (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
- +
- + /*
- + * Allocate packet engine descriptors.
- + */
- + sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
- + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
- + &sc->sc_ringalloc.dma_paddr);
- + if (!sc->sc_ringalloc.dma_vaddr) {
- + device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
- + goto out;
- + }
- +
- + /*
- + * Hookup the static portion of all our data structures.
- + */
- + sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
- + sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
- + sc->sc_front = sc->sc_ring;
- + sc->sc_back = sc->sc_ring;
- + raddr = sc->sc_ringalloc.dma_paddr;
- + bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
- + for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
- + struct safe_ringentry *re = &sc->sc_ring[i];
- +
- + re->re_desc.d_sa = raddr +
- + offsetof(struct safe_ringentry, re_sa);
- + re->re_sa.sa_staterec = raddr +
- + offsetof(struct safe_ringentry, re_sastate);
- +
- + raddr += sizeof (struct safe_ringentry);
- + }
- + spin_lock_init(&sc->sc_ringmtx);
- +
- + /*
- + * Allocate scatter and gather particle descriptors.
- + */
- + sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
- + SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
- + &sc->sc_spalloc.dma_paddr);
- + if (!sc->sc_spalloc.dma_vaddr) {
- + device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
- + goto out;
- + }
- + sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
- + sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
- + sc->sc_spfree = sc->sc_spring;
- + bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
- +
- + sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
- + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
- + &sc->sc_dpalloc.dma_paddr);
- + if (!sc->sc_dpalloc.dma_vaddr) {
- + device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
- + goto out;
- + }
- + sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
- + sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
- + sc->sc_dpfree = sc->sc_dpring;
- + bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
- +
- + sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
- + if (sc->sc_cid < 0) {
- + device_printf(sc->sc_dev, "could not get crypto driver id\n");
- + goto out;
- + }
- +
- + printf("%s:", device_get_nameunit(sc->sc_dev));
- +
- + devinfo = READ_REG(sc, SAFE_DEVINFO);
- + if (devinfo & SAFE_DEVINFO_RNG) {
- + sc->sc_flags |= SAFE_FLAGS_RNG;
- + printf(" rng");
- + }
- + if (devinfo & SAFE_DEVINFO_PKEY) {
- + printf(" key");
- + sc->sc_flags |= SAFE_FLAGS_KEY;
- + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
- +#if 0
- + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
- +#endif
- + init_timer(&sc->sc_pkto);
- + sc->sc_pkto.function = safe_kpoll;
- + sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
- + }
- + if (devinfo & SAFE_DEVINFO_DES) {
- + printf(" des/3des");
- + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
- + }
- + if (devinfo & SAFE_DEVINFO_AES) {
- + printf(" aes");
- + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
- + }
- + if (devinfo & SAFE_DEVINFO_MD5) {
- + printf(" md5");
- + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
- + }
- + if (devinfo & SAFE_DEVINFO_SHA1) {
- + printf(" sha1");
- + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
- + }
- + printf(" null");
- + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
- + /* XXX other supported algorithms */
- + printf("\n");
- +
- + safe_reset_board(sc); /* reset h/w */
- + safe_init_board(sc); /* init h/w */
- +
- +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
- + if (sc->sc_flags & SAFE_FLAGS_RNG) {
- + safe_rng_init(sc);
- + crypto_rregister(sc->sc_cid, safe_read_random, sc);
- + }
- +#endif /* SAFE_NO_RNG */
- +
- + return (0);
- +
- +out:
- + if (sc->sc_cid >= 0)
- + crypto_unregister_all(sc->sc_cid);
- + if (sc->sc_irq != -1)
- + free_irq(sc->sc_irq, sc);
- + if (sc->sc_ringalloc.dma_vaddr)
- + pci_free_consistent(sc->sc_pcidev,
- + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
- + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
- + if (sc->sc_spalloc.dma_vaddr)
- + pci_free_consistent(sc->sc_pcidev,
- + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
- + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
- + if (sc->sc_dpalloc.dma_vaddr)
- + pci_free_consistent(sc->sc_pcidev,
- + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
- + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
- + kfree(sc);
- + return(-ENODEV);
- +}
- +
- +static void safe_remove(struct pci_dev *dev)
- +{
- + struct safe_softc *sc = pci_get_drvdata(dev);
- +
- + DPRINTF(("%s()\n", __FUNCTION__));
- +
- + /* XXX wait/abort active ops */
- +
- + WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
- +
- + del_timer_sync(&sc->sc_pkto);
- +
- + crypto_unregister_all(sc->sc_cid);
- +
- + safe_cleanchip(sc);
- +
- + if (sc->sc_irq != -1)
- + free_irq(sc->sc_irq, sc);
- + if (sc->sc_ringalloc.dma_vaddr)
- + pci_free_consistent(sc->sc_pcidev,
- + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
- + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
- + if (sc->sc_spalloc.dma_vaddr)
- + pci_free_consistent(sc->sc_pcidev,
- + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
- + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
- + if (sc->sc_dpalloc.dma_vaddr)
- + pci_free_consistent(sc->sc_pcidev,
- + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
- + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
- + sc->sc_irq = -1;
- + sc->sc_ringalloc.dma_vaddr = NULL;
- + sc->sc_spalloc.dma_vaddr = NULL;
- + sc->sc_dpalloc.dma_vaddr = NULL;
- +}
- +
- +static struct pci_device_id safe_pci_tbl[] = {
- + { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
- + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
- + { },
- +};
- +MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
- +
- +static struct pci_driver safe_driver = {
- + .name = "safe",
- + .id_table = safe_pci_tbl,
- + .probe = safe_probe,
- + .remove = safe_remove,
- + /* add PM stuff here one day */
- +};
- +
- +static int __init safe_init (void)
- +{
- + struct safe_softc *sc = NULL;
- + int rc;
- +
- + DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
- +
- + rc = pci_register_driver(&safe_driver);
- + pci_register_driver_compat(&safe_driver, rc);
- +
- + return rc;
- +}
- +
- +static void __exit safe_exit (void)
- +{
- + pci_unregister_driver(&safe_driver);
- +}
- +
- +module_init(safe_init);
- +module_exit(safe_exit);
- +
- +MODULE_LICENSE("BSD");
- +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
- +MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safereg.h linux-2.6.36/crypto/ocf/safe/safereg.h
- --- linux-2.6.36.orig/crypto/ocf/safe/safereg.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/safereg.h 2010-11-09 20:28:12.962495464 +0100
- @@ -0,0 +1,421 @@
- +/*-
- + * Copyright (c) 2003 Sam Leffler, Errno Consulting
- + * Copyright (c) 2003 Global Technology Associates, Inc.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + *
- + * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
- + */
- +#ifndef _SAFE_SAFEREG_H_
- +#define _SAFE_SAFEREG_H_
- +
- +/*
- + * Register definitions for SafeNet SafeXcel-1141 crypto device.
- + * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
- + */
- +
- +#define BS_BAR 0x10 /* DMA base address register */
- +#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
- +#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
- +
- +#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
- +
- +/* SafeNet */
- +#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
- +
- +#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
- +#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
- +#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
- +#define SAFE_PE_SA 0x000c /* Packet Engine SA */
- +#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
- +#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
- +#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
- +#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
- +#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
- +#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
- +#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
- +#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
- +#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
- +#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
- +#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
- +#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
- +#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
- +#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
- +#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
- +#define SAFE_DEVID 0x0084 /* Device ID */
- +#define SAFE_DEVINFO 0x0088 /* Device Info */
- +#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
- +#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
- +#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
- +#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
- +#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
- +#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
- +#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
- +#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
- +#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
- +#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
- +#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
- +#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
- +#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
- +#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
- +#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
- +#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
- +#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
- +#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
- +#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
- +#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
- +#define SAFE_PK_FUNC 0x081c /* Public Key Function */
- +#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
- +#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
- +
- +#define SAFE_RNG_OUT 0x0100 /* RNG Output */
- +#define SAFE_RNG_STAT 0x0104 /* RNG Status */
- +#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
- +#define SAFE_RNG_A 0x010c /* RNG A */
- +#define SAFE_RNG_B 0x0110 /* RNG B */
- +#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
- +#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
- +#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
- +#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
- +#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
- +#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
- +#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
- +#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
- +#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
- +#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
- +
- +#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
- +#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
- +#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
- +#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
- +#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
- +#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
- +#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
- +#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
- +#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
- +#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
- +#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
- +#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
- +#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
- +#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
- +#define SAFE_PE_CSR_XECODE_S 20
- +#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
- +#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
- +#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
- +#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
- +#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
- +#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
- +#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
- +#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
- +#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
- +#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
- +#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
- +#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
- +#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
- +#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
- +#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
- +
- +/*
- + * Check the CSR to see if the PE has returned ownership to
- + * the host. Note that before processing a descriptor this
- + * must be done followed by a check of the SAFE_PE_LEN register
- + * status bits to avoid premature processing of a descriptor
- + * on its way back to the host.
- + */
- +#define SAFE_PE_CSR_IS_DONE(_csr) \
- + (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
- +
- +#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
- +#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
- +#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
- +#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
- +#define SAFE_PE_LEN_BYPASS_S 24
- +
- +#define SAFE_PE_LEN_IS_DONE(_len) \
- + (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
- +
- +/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
- +#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
- +#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
- +#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
- +#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
- +
- +#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
- +#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
- +#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
- +
- +#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
- +#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
- +
- +#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
- +#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
- +#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
- +#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
- +#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
- +#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
- +#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
- +#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
- +#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
- +#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
- +#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
- +#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
- +#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
- +#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
- +#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
- +#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
- +#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
- +
- +#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
- +#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
- +#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
- +#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
- +#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
- +#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
- +#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
- +#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
- +#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
- +#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
- +#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
- +#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
- +#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
- +#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
- +
- +#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
- +#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
- +#define SAFE_PE_RINGCFG_OFFSET_S 16
- +
- +#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
- +#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
- +#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
- +
- +#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
- +
- +#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
- +#define SAFE_PE_ERNGSTAT_NEXT_S 16
- +
- +#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
- +#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
- +
- +#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
- +#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
- +#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
- +#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
- +#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
- +#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
- +#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
- +#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
- +#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
- +#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
- +#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
- +
- +#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
- +#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
- +
- +#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
- +#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
- +#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
- +
- +#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
- +#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
- +#define SAFE_DEVINFO_REV_MAJ_S 4
- +#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
- +#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
- +#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
- +#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
- +#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
- +#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
- +#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
- +#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
- +#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
- +#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
- +#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
- +
- +#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
- +#define SAFE_REV_MAJ(_chiprev) \
- + (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
- +#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
- +
- +#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
- +#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
- +#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
- +#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
- +#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
- +#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
- +#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
- +#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
- +#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
- +#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
- +#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
- +#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
- +
- +#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
- +
- +#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
- +#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
- +#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
- +#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
- +#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
- +#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
- +#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
- +#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
- +#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
- +#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
- +
- +/*
- + * Packet engine descriptor. Note that d_csr is a copy of the
- + * SAFE_PE_CSR register and all definitions apply, and d_len
- + * is a copy of the SAFE_PE_LEN register and all definitions apply.
- + * d_src and d_len may point directly to contiguous data or to a
- + * list of ``particle descriptors'' when using scatter/gather i/o.
- + */
- +struct safe_desc {
- + u_int32_t d_csr; /* per-packet control/status */
- + u_int32_t d_src; /* source address */
- + u_int32_t d_dst; /* destination address */
- + u_int32_t d_sa; /* SA address */
- + u_int32_t d_len; /* length, bypass, status */
- +};
- +
- +/*
- + * Scatter/Gather particle descriptor.
- + *
- + * NB: scatter descriptors do not specify a size; this is fixed
- + * by the setting of the SAFE_PE_PARTCFG register.
- + */
- +struct safe_pdesc {
- + u_int32_t pd_addr; /* particle address */
- +#ifdef __BIG_ENDIAN
- + u_int16_t pd_flags; /* control word */
- + u_int16_t pd_size; /* particle size (bytes) */
- +#else
- + u_int16_t pd_flags; /* control word */
- + u_int16_t pd_size; /* particle size (bytes) */
- +#endif
- +};
- +
- +#define SAFE_PD_READY 0x0001 /* ready for processing */
- +#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
- +
- +/*
- + * Security Association (SA) Record (Rev 1). One of these is
- + * required for each operation processed by the packet engine.
- + */
- +struct safe_sarec {
- + u_int32_t sa_cmd0;
- + u_int32_t sa_cmd1;
- + u_int32_t sa_resv0;
- + u_int32_t sa_resv1;
- + u_int32_t sa_key[8]; /* DES/3DES/AES key */
- + u_int32_t sa_indigest[5]; /* inner digest */
- + u_int32_t sa_outdigest[5]; /* outer digest */
- + u_int32_t sa_spi; /* SPI */
- + u_int32_t sa_seqnum; /* sequence number */
- + u_int32_t sa_seqmask[2]; /* sequence number mask */
- + u_int32_t sa_resv2;
- + u_int32_t sa_staterec; /* address of state record */
- + u_int32_t sa_resv3[2];
- + u_int32_t sa_samgmt0; /* SA management field 0 */
- + u_int32_t sa_samgmt1; /* SA management field 0 */
- +};
- +
- +#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
- +#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
- +#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
- +#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
- +#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
- +#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
- +#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
- +#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
- +#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
- +#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
- +#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
- +#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
- +#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
- +#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
- +#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
- +#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
- +#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
- +#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
- +#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
- +#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
- +#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
- +#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
- +#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
- +#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
- +#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
- +#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
- +#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
- +#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
- +#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
- +#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
- +#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
- +#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
- +#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
- +#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
- +#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
- +#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
- +#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
- +#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
- +#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
- +#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
- +#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
- +#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
- +#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
- +
- +#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
- +#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
- +#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
- +#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
- +#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
- +#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
- +#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
- +#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
- +#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
- +#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
- +#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
- +#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
- +#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
- +#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
- +#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
- +#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
- +#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
- +#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
- +#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
- +#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
- +#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
- +#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
- +#define SAFE_SA_CMD1_OFFSET_S 16
- +#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
- +#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
- +#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
- +#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
- +
- +/*
- + * Security Associate State Record (Rev 1).
- + */
- +struct safe_sastate {
- + u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
- + u_int32_t sa_saved_hashbc; /* saved hash byte count */
- + u_int32_t sa_saved_indigest[5]; /* saved inner digest */
- +};
- +#endif /* _SAFE_SAFEREG_H_ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safevar.h linux-2.6.36/crypto/ocf/safe/safevar.h
- --- linux-2.6.36.orig/crypto/ocf/safe/safevar.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/safevar.h 2010-11-09 20:28:13.022495375 +0100
- @@ -0,0 +1,230 @@
- +/*-
- + * The linux port of this code done by David McCullough
- + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
- + * The license and original author are listed below.
- + *
- + * Copyright (c) 2003 Sam Leffler, Errno Consulting
- + * Copyright (c) 2003 Global Technology Associates, Inc.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + *
- + * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
- + */
- +#ifndef _SAFE_SAFEVAR_H_
- +#define _SAFE_SAFEVAR_H_
- +
- +/* Maximum queue length */
- +#ifndef SAFE_MAX_NQUEUE
- +#define SAFE_MAX_NQUEUE 60
- +#endif
- +
- +#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
- +#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
- +#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
- +#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
- +#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
- +/* total src+dst particle descriptors */
- +#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
- +#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
- +
- +#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
- +
- +#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
- +#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
- +#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
- +
- +#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
- +#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
- +#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
- +
- +#ifdef __KERNEL__
- +/*
- + * State associated with the allocation of each chunk
- + * of memory setup for DMA.
- + */
- +struct safe_dma_alloc {
- + dma_addr_t dma_paddr;
- + void *dma_vaddr;
- +};
- +
- +/*
- + * Cryptographic operand state. One of these exists for each
- + * source and destination operand passed in from the crypto
- + * subsystem. When possible source and destination operands
- + * refer to the same memory. More often they are distinct.
- + * We track the virtual address of each operand as well as
- + * where each is mapped for DMA.
- + */
- +struct safe_operand {
- + union {
- + struct sk_buff *skb;
- + struct uio *io;
- + } u;
- + void *map;
- + int mapsize; /* total number of bytes in segs */
- + struct {
- + dma_addr_t ds_addr;
- + int ds_len;
- + int ds_tlen;
- + } segs[SAFE_MAX_PART];
- + int nsegs;
- +};
- +
- +/*
- + * Packet engine ring entry and cryptographic operation state.
- + * The packet engine requires a ring of descriptors that contain
- + * pointers to various cryptographic state. However the ring
- + * configuration register allows you to specify an arbitrary size
- + * for ring entries. We use this feature to collect most of the
- + * state for each cryptographic request into one spot. Other than
- + * ring entries only the ``particle descriptors'' (scatter/gather
- + * lists) and the actual operand data are kept separate. The
- + * particle descriptors must also be organized in rings. The
- + * operand data can be located aribtrarily (modulo alignment constraints).
- + *
- + * Note that the descriptor ring is mapped onto the PCI bus so
- + * the hardware can DMA data. This means the entire ring must be
- + * contiguous.
- + */
- +struct safe_ringentry {
- + struct safe_desc re_desc; /* command descriptor */
- + struct safe_sarec re_sa; /* SA record */
- + struct safe_sastate re_sastate; /* SA state record */
- +
- + struct cryptop *re_crp; /* crypto operation */
- +
- + struct safe_operand re_src; /* source operand */
- + struct safe_operand re_dst; /* destination operand */
- +
- + int re_sesn; /* crypto session ID */
- + int re_flags;
- +#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
- +#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
- +};
- +
- +#define re_src_skb re_src.u.skb
- +#define re_src_io re_src.u.io
- +#define re_src_map re_src.map
- +#define re_src_nsegs re_src.nsegs
- +#define re_src_segs re_src.segs
- +#define re_src_mapsize re_src.mapsize
- +
- +#define re_dst_skb re_dst.u.skb
- +#define re_dst_io re_dst.u.io
- +#define re_dst_map re_dst.map
- +#define re_dst_nsegs re_dst.nsegs
- +#define re_dst_segs re_dst.segs
- +#define re_dst_mapsize re_dst.mapsize
- +
- +struct rndstate_test;
- +
- +struct safe_session {
- + u_int32_t ses_used;
- + u_int32_t ses_klen; /* key length in bits */
- + u_int32_t ses_key[8]; /* DES/3DES/AES key */
- + u_int32_t ses_mlen; /* hmac length in bytes */
- + u_int32_t ses_hminner[5]; /* hmac inner state */
- + u_int32_t ses_hmouter[5]; /* hmac outer state */
- + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
- +};
- +
- +struct safe_pkq {
- + struct list_head pkq_list;
- + struct cryptkop *pkq_krp;
- +};
- +
- +struct safe_softc {
- + softc_device_decl sc_dev;
- + u32 sc_irq;
- +
- + struct pci_dev *sc_pcidev;
- + ocf_iomem_t sc_base_addr;
- +
- + u_int sc_chiprev; /* major/minor chip revision */
- + int sc_flags; /* device specific flags */
- +#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
- +#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
- + int sc_suspended;
- + int sc_needwakeup; /* notify crypto layer */
- + int32_t sc_cid; /* crypto tag */
- +
- + struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
- + struct safe_ringentry *sc_ring; /* PE ring */
- + struct safe_ringentry *sc_ringtop; /* PE ring top */
- + struct safe_ringentry *sc_front; /* next free entry */
- + struct safe_ringentry *sc_back; /* next pending entry */
- + int sc_nqchip; /* # passed to chip */
- + spinlock_t sc_ringmtx; /* PE ring lock */
- + struct safe_pdesc *sc_spring; /* src particle ring */
- + struct safe_pdesc *sc_springtop; /* src particle ring top */
- + struct safe_pdesc *sc_spfree; /* next free src particle */
- + struct safe_dma_alloc sc_spalloc; /* src particle ring state */
- + struct safe_pdesc *sc_dpring; /* dest particle ring */
- + struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
- + struct safe_pdesc *sc_dpfree; /* next free dest particle */
- + struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
- + int sc_nsessions; /* # of sessions */
- + struct safe_session *sc_sessions; /* sessions */
- +
- + struct timer_list sc_pkto; /* PK polling */
- + spinlock_t sc_pkmtx; /* PK lock */
- + struct list_head sc_pkq; /* queue of PK requests */
- + struct safe_pkq *sc_pkq_cur; /* current processing request */
- + u_int32_t sc_pk_reslen, sc_pk_resoff;
- +
- + int sc_max_dsize; /* maximum safe DMA size */
- +};
- +#endif /* __KERNEL__ */
- +
- +struct safe_stats {
- + u_int64_t st_ibytes;
- + u_int64_t st_obytes;
- + u_int32_t st_ipackets;
- + u_int32_t st_opackets;
- + u_int32_t st_invalid; /* invalid argument */
- + u_int32_t st_badsession; /* invalid session id */
- + u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
- + u_int32_t st_nodesc; /* op submitted w/o descriptors */
- + u_int32_t st_badalg; /* unsupported algorithm */
- + u_int32_t st_ringfull; /* PE descriptor ring full */
- + u_int32_t st_peoperr; /* PE marked error */
- + u_int32_t st_dmaerr; /* PE DMA error */
- + u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
- + u_int32_t st_skipmismatch; /* enc part begins before auth part */
- + u_int32_t st_lenmismatch; /* enc length different auth length */
- + u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
- + u_int32_t st_cofftoobig; /* crypto offset > 255 words */
- + u_int32_t st_iovmisaligned; /* iov op not aligned */
- + u_int32_t st_iovnotuniform; /* iov op not suitable */
- + u_int32_t st_unaligned; /* unaligned src caused copy */
- + u_int32_t st_notuniform; /* non-uniform src caused copy */
- + u_int32_t st_nomap; /* bus_dmamap_create failed */
- + u_int32_t st_noload; /* bus_dmamap_load_* failed */
- + u_int32_t st_nombuf; /* MGET* failed */
- + u_int32_t st_nomcl; /* MCLGET* failed */
- + u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
- + u_int32_t st_rng; /* RNG requests */
- + u_int32_t st_rngalarm; /* RNG alarm requests */
- + u_int32_t st_noicvcopy; /* ICV data copies suppressed */
- +};
- +#endif /* _SAFE_SAFEVAR_H_ */
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/sha1.c linux-2.6.36/crypto/ocf/safe/sha1.c
- --- linux-2.6.36.orig/crypto/ocf/safe/sha1.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/sha1.c 2010-11-09 20:28:13.072495484 +0100
- @@ -0,0 +1,279 @@
- +/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
- +/*
- + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. Neither the name of the project nor the names of its contributors
- + * may be used to endorse or promote products derived from this software
- + * without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + */
- +
- +/*
- + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
- + * based on: http://csrc.nist.gov/fips/fip180-1.txt
- + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
- + */
- +
- +#if 0
- +#include <sys/cdefs.h>
- +__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
- +
- +#include <sys/types.h>
- +#include <sys/cdefs.h>
- +#include <sys/time.h>
- +#include <sys/systm.h>
- +
- +#include <crypto/sha1.h>
- +#endif
- +
- +/* sanity check */
- +#if BYTE_ORDER != BIG_ENDIAN
- +# if BYTE_ORDER != LITTLE_ENDIAN
- +# define unsupported 1
- +# endif
- +#endif
- +
- +#ifndef unsupported
- +
- +/* constant table */
- +static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
- +#define K(t) _K[(t) / 20]
- +
- +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
- +#define F1(b, c, d) (((b) ^ (c)) ^ (d))
- +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
- +#define F3(b, c, d) (((b) ^ (c)) ^ (d))
- +
- +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
- +
- +#undef H
- +#define H(n) (ctxt->h.b32[(n)])
- +#define COUNT (ctxt->count)
- +#define BCOUNT (ctxt->c.b64[0] / 8)
- +#define W(n) (ctxt->m.b32[(n)])
- +
- +#define PUTBYTE(x) { \
- + ctxt->m.b8[(COUNT % 64)] = (x); \
- + COUNT++; \
- + COUNT %= 64; \
- + ctxt->c.b64[0] += 8; \
- + if (COUNT % 64 == 0) \
- + sha1_step(ctxt); \
- + }
- +
- +#define PUTPAD(x) { \
- + ctxt->m.b8[(COUNT % 64)] = (x); \
- + COUNT++; \
- + COUNT %= 64; \
- + if (COUNT % 64 == 0) \
- + sha1_step(ctxt); \
- + }
- +
- +static void sha1_step(struct sha1_ctxt *);
- +
- +static void
- +sha1_step(ctxt)
- + struct sha1_ctxt *ctxt;
- +{
- + u_int32_t a, b, c, d, e;
- + size_t t, s;
- + u_int32_t tmp;
- +
- +#if BYTE_ORDER == LITTLE_ENDIAN
- + struct sha1_ctxt tctxt;
- + bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
- + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
- + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
- + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
- + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
- + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
- + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
- + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
- + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
- + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
- + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
- + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
- + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
- + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
- + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
- + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
- + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
- + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
- + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
- + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
- + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
- + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
- + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
- + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
- + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
- + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
- + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
- + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
- + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
- + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
- + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
- + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
- + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
- +#endif
- +
- + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
- +
- + for (t = 0; t < 20; t++) {
- + s = t & 0x0f;
- + if (t >= 16) {
- + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
- + }
- + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
- + e = d; d = c; c = S(30, b); b = a; a = tmp;
- + }
- + for (t = 20; t < 40; t++) {
- + s = t & 0x0f;
- + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
- + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
- + e = d; d = c; c = S(30, b); b = a; a = tmp;
- + }
- + for (t = 40; t < 60; t++) {
- + s = t & 0x0f;
- + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
- + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
- + e = d; d = c; c = S(30, b); b = a; a = tmp;
- + }
- + for (t = 60; t < 80; t++) {
- + s = t & 0x0f;
- + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
- + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
- + e = d; d = c; c = S(30, b); b = a; a = tmp;
- + }
- +
- + H(0) = H(0) + a;
- + H(1) = H(1) + b;
- + H(2) = H(2) + c;
- + H(3) = H(3) + d;
- + H(4) = H(4) + e;
- +
- + bzero(&ctxt->m.b8[0], 64);
- +}
- +
- +/*------------------------------------------------------------*/
- +
- +void
- +sha1_init(ctxt)
- + struct sha1_ctxt *ctxt;
- +{
- + bzero(ctxt, sizeof(struct sha1_ctxt));
- + H(0) = 0x67452301;
- + H(1) = 0xefcdab89;
- + H(2) = 0x98badcfe;
- + H(3) = 0x10325476;
- + H(4) = 0xc3d2e1f0;
- +}
- +
- +void
- +sha1_pad(ctxt)
- + struct sha1_ctxt *ctxt;
- +{
- + size_t padlen; /*pad length in bytes*/
- + size_t padstart;
- +
- + PUTPAD(0x80);
- +
- + padstart = COUNT % 64;
- + padlen = 64 - padstart;
- + if (padlen < 8) {
- + bzero(&ctxt->m.b8[padstart], padlen);
- + COUNT += padlen;
- + COUNT %= 64;
- + sha1_step(ctxt);
- + padstart = COUNT % 64; /* should be 0 */
- + padlen = 64 - padstart; /* should be 64 */
- + }
- + bzero(&ctxt->m.b8[padstart], padlen - 8);
- + COUNT += (padlen - 8);
- + COUNT %= 64;
- +#if BYTE_ORDER == BIG_ENDIAN
- + PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
- + PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
- + PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
- + PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
- +#else
- + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
- + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
- + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
- + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
- +#endif
- +}
- +
- +void
- +sha1_loop(ctxt, input, len)
- + struct sha1_ctxt *ctxt;
- + const u_int8_t *input;
- + size_t len;
- +{
- + size_t gaplen;
- + size_t gapstart;
- + size_t off;
- + size_t copysiz;
- +
- + off = 0;
- +
- + while (off < len) {
- + gapstart = COUNT % 64;
- + gaplen = 64 - gapstart;
- +
- + copysiz = (gaplen < len - off) ? gaplen : len - off;
- + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
- + COUNT += copysiz;
- + COUNT %= 64;
- + ctxt->c.b64[0] += copysiz * 8;
- + if (COUNT % 64 == 0)
- + sha1_step(ctxt);
- + off += copysiz;
- + }
- +}
- +
- +void
- +sha1_result(ctxt, digest0)
- + struct sha1_ctxt *ctxt;
- + caddr_t digest0;
- +{
- + u_int8_t *digest;
- +
- + digest = (u_int8_t *)digest0;
- + sha1_pad(ctxt);
- +#if BYTE_ORDER == BIG_ENDIAN
- + bcopy(&ctxt->h.b8[0], digest, 20);
- +#else
- + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
- + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
- + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
- + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
- + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
- + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
- + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
- + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
- + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
- + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
- +#endif
- +}
- +
- +#endif /*unsupported*/
- diff -Nur linux-2.6.36.orig/crypto/ocf/safe/sha1.h linux-2.6.36/crypto/ocf/safe/sha1.h
- --- linux-2.6.36.orig/crypto/ocf/safe/sha1.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/safe/sha1.h 2010-11-09 20:28:13.112495423 +0100
- @@ -0,0 +1,72 @@
- +/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
- +/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
- +
- +/*
- + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. Neither the name of the project nor the names of its contributors
- + * may be used to endorse or promote products derived from this software
- + * without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + */
- +/*
- + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
- + * based on: http://csrc.nist.gov/fips/fip180-1.txt
- + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
- + */
- +
- +#ifndef _NETINET6_SHA1_H_
- +#define _NETINET6_SHA1_H_
- +
- +struct sha1_ctxt {
- + union {
- + u_int8_t b8[20];
- + u_int32_t b32[5];
- + } h;
- + union {
- + u_int8_t b8[8];
- + u_int64_t b64[1];
- + } c;
- + union {
- + u_int8_t b8[64];
- + u_int32_t b32[16];
- + } m;
- + u_int8_t count;
- +};
- +
- +#ifdef __KERNEL__
- +extern void sha1_init(struct sha1_ctxt *);
- +extern void sha1_pad(struct sha1_ctxt *);
- +extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
- +extern void sha1_result(struct sha1_ctxt *, caddr_t);
- +
- +/* compatibilty with other SHA1 source codes */
- +typedef struct sha1_ctxt SHA1_CTX;
- +#define SHA1Init(x) sha1_init((x))
- +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
- +#define SHA1Final(x, y) sha1_result((y), (x))
- +#endif /* __KERNEL__ */
- +
- +#define SHA1_RESULTLEN (160/8)
- +
- +#endif /*_NETINET6_SHA1_H_*/
- diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/Makefile linux-2.6.36/crypto/ocf/talitos/Makefile
- --- linux-2.6.36.orig/crypto/ocf/talitos/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/talitos/Makefile 2010-11-09 20:28:13.155214387 +0100
- @@ -0,0 +1,12 @@
- +# for SGlinux builds
- +-include $(ROOTDIR)/modules/.config
- +
- +obj-$(CONFIG_OCF_TALITOS) += talitos.o
- +
- +obj ?= .
- +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
- +
- +ifdef TOPDIR
- +-include $(TOPDIR)/Rules.make
- +endif
- +
- diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos.c linux-2.6.36/crypto/ocf/talitos/talitos.c
- --- linux-2.6.36.orig/crypto/ocf/talitos/talitos.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/talitos/talitos.c 2010-11-09 20:28:13.192104548 +0100
- @@ -0,0 +1,1359 @@
- +/*
- + * crypto/ocf/talitos/talitos.c
- + *
- + * An OCF-Linux module that uses Freescale's SEC to do the crypto.
- + * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
- + *
- + * Copyright (c) 2006 Freescale Semiconductor, Inc.
- + *
- + * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
- + * some code copied from files with the following:
- + * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + * ---------------------------------------------------------------------------
- + *
- + * NOTES:
- + *
- + * The Freescale SEC (also known as 'talitos') resides on the
- + * internal bus, and runs asynchronous to the processor core. It has
- + * a wide gamut of cryptographic acceleration features, including single-
- + * pass IPsec (also known as algorithm chaining). To properly utilize
- + * all of the SEC's performance enhancing features, further reworking
- + * of higher level code (framework, applications) will be necessary.
- + *
- + * The following table shows which SEC version is present in which devices:
- + *
- + * Devices SEC version
- + *
- + * 8272, 8248 SEC 1.0
- + * 885, 875 SEC 1.2
- + * 8555E, 8541E SEC 2.0
- + * 8349E SEC 2.01
- + * 8548E SEC 2.1
- + *
- + * The following table shows the features offered by each SEC version:
- + *
- + * Max. chan-
- + * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
- + *
- + * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
- + * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
- + * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
- + * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
- + * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
- + *
- + * Each execution unit in the SEC has two modes of execution; channel and
- + * slave/debug. This driver employs the channel infrastructure in the
- + * device for convenience. Only the RNG is directly accessed due to the
- + * convenience of its random fifo pool. The relationship between the
- + * channels and execution units is depicted in the following diagram:
- + *
- + * ------- ------------
- + * ---| ch0 |---| |
- + * ------- | |
- + * | |------+-------+-------+-------+------------
- + * ------- | | | | | | |
- + * ---| ch1 |---| | | | | | |
- + * ------- | | ------ ------ ------ ------ ------
- + * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
- + * ------- | | ------ ------ ------ ------ ------
- + * ---| ch2 |---| | | | | | |
- + * ------- | | | | | | |
- + * | |------+-------+-------+-------+------------
- + * ------- | |
- + * ---| ch3 |---| |
- + * ------- ------------
- + *
- + * Channel ch0 may drive an aes operation to the aes unit (AESU),
- + * and, at the same time, ch1 may drive a message digest operation
- + * to the mdeu. Each channel has an input descriptor FIFO, and the
- + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
- + * a buffer overrun error is triggered. The controller is responsible
- + * for fetching the data from descriptor pointers, and passing the
- + * data to the appropriate EUs. The controller also writes the
- + * cryptographic operation's result to memory. The SEC notifies
- + * completion by triggering an interrupt and/or setting the 1st byte
- + * of the hdr field to 0xff.
- + *
- + * TODO:
- + * o support more algorithms
- + * o support more versions of the SEC
- + * o add support for linux 2.4
- + * o scatter-gather (sg) support
- + * o add support for public key ops (PKEU)
- + * o add statistics
- + */
- +
- +#ifndef AUTOCONF_INCLUDED
- +#include <linux/config.h>
- +#endif
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/interrupt.h>
- +#include <linux/spinlock.h>
- +#include <linux/random.h>
- +#include <linux/skbuff.h>
- +#include <asm/scatterlist.h>
- +#include <linux/dma-mapping.h> /* dma_map_single() */
- +#include <linux/moduleparam.h>
- +
- +#include <linux/version.h>
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
- +#include <linux/platform_device.h>
- +#endif
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- +#include <linux/of_platform.h>
- +#endif
- +
- +#include <cryptodev.h>
- +#include <uio.h>
- +
- +#define DRV_NAME "talitos"
- +
- +#include "talitos_dev.h"
- +#include "talitos_soft.h"
- +
- +#define read_random(p,l) get_random_bytes(p,l)
- +
- +const char talitos_driver_name[] = "Talitos OCF";
- +const char talitos_driver_version[] = "0.2";
- +
- +static int talitos_newsession(device_t dev, u_int32_t *sidp,
- + struct cryptoini *cri);
- +static int talitos_freesession(device_t dev, u_int64_t tid);
- +static int talitos_process(device_t dev, struct cryptop *crp, int hint);
- +static void dump_talitos_status(struct talitos_softc *sc);
- +static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
- + int chsel);
- +static void talitos_doneprocessing(struct talitos_softc *sc);
- +static void talitos_init_device(struct talitos_softc *sc);
- +static void talitos_reset_device_master(struct talitos_softc *sc);
- +static void talitos_reset_device(struct talitos_softc *sc);
- +static void talitos_errorprocessing(struct talitos_softc *sc);
- +#ifdef CONFIG_PPC_MERGE
- +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
- +static int talitos_remove(struct of_device *ofdev);
- +#else
- +static int talitos_probe(struct platform_device *pdev);
- +static int talitos_remove(struct platform_device *pdev);
- +#endif
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- +static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
- +static void talitos_rng_init(struct talitos_softc *sc);
- +#endif
- +
- +static device_method_t talitos_methods = {
- + /* crypto device methods */
- + DEVMETHOD(cryptodev_newsession, talitos_newsession),
- + DEVMETHOD(cryptodev_freesession,talitos_freesession),
- + DEVMETHOD(cryptodev_process, talitos_process),
- +};
- +
- +#define debug talitos_debug
- +int talitos_debug = 0;
- +module_param(talitos_debug, int, 0644);
- +MODULE_PARM_DESC(talitos_debug, "Enable debug");
- +
- +static inline void talitos_write(volatile unsigned *addr, u32 val)
- +{
- + out_be32(addr, val);
- +}
- +
- +static inline u32 talitos_read(volatile unsigned *addr)
- +{
- + u32 val;
- + val = in_be32(addr);
- + return val;
- +}
- +
- +static void dump_talitos_status(struct talitos_softc *sc)
- +{
- + unsigned int v, v_hi, i, *ptr;
- + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
- + v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
- + printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
- + device_get_nameunit(sc->sc_cdev), v, v_hi);
- + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
- + v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
- + printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
- + device_get_nameunit(sc->sc_cdev), v, v_hi);
- + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
- + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
- + printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
- + device_get_nameunit(sc->sc_cdev), v, v_hi);
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
- + TALITOS_CH_CDPR);
- + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
- + TALITOS_CH_CDPR_HI);
- + printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
- + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
- + }
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
- + TALITOS_CH_CCPSR);
- + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
- + TALITOS_CH_CCPSR_HI);
- + printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
- + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
- + }
- + ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
- + for (i = 0; i < 16; i++) {
- + v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
- + printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
- + device_get_nameunit(sc->sc_cdev), v, v_hi, i);
- + }
- + return;
- +}
- +
- +
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- +/*
- + * pull random numbers off the RNG FIFO, not exceeding amount available
- + */
- +static int
- +talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
- +{
- + struct talitos_softc *sc = (struct talitos_softc *) arg;
- + int rc;
- + u_int32_t v;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + /* check for things like FIFO underflow */
- + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
- + if (unlikely(v)) {
- + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
- + device_get_nameunit(sc->sc_cdev), v);
- + return 0;
- + }
- + /*
- + * OFL is number of available 64-bit words,
- + * shift and convert to a 32-bit word count
- + */
- + v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
- + v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
- + if (maxwords > v)
- + maxwords = v;
- + for (rc = 0; rc < maxwords; rc++) {
- + buf[rc] = talitos_read(sc->sc_base_addr +
- + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
- + }
- + if (maxwords & 1) {
- + /*
- + * RNG will complain with an AE in the RNGISR
- + * if we don't complete the pairs of 32-bit reads
- + * to its 64-bit register based FIFO
- + */
- + v = talitos_read(sc->sc_base_addr +
- + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
- + }
- +
- + return rc;
- +}
- +
- +static void
- +talitos_rng_init(struct talitos_softc *sc)
- +{
- + u_int32_t v;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- + /* reset RNG EU */
- + v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
- + v |= TALITOS_RNGRCR_HI_SR;
- + talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
- + while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
- + & TALITOS_RNGSR_HI_RD) == 0)
- + cpu_relax();
- + /*
- + * we tell the RNG to start filling the RNG FIFO
- + * by writing the RNGDSR
- + */
- + v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
- + talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
- + /*
- + * 64 bits of data will be pushed onto the FIFO every
- + * 256 SEC cycles until the FIFO is full. The RNG then
- + * attempts to keep the FIFO full.
- + */
- + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
- + if (v) {
- + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
- + device_get_nameunit(sc->sc_cdev), v);
- + return;
- + }
- + /*
- + * n.b. we need to add a FIPS test here - if the RNG is going
- + * to fail, it's going to fail at reset time
- + */
- + return;
- +}
- +#endif /* CONFIG_OCF_RANDOMHARVEST */
- +
- +/*
- + * Generate a new software session.
- + */
- +static int
- +talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
- +{
- + struct cryptoini *c, *encini = NULL, *macini = NULL;
- + struct talitos_softc *sc = device_get_softc(dev);
- + struct talitos_session *ses = NULL;
- + int sesn;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- + if (sidp == NULL || cri == NULL || sc == NULL) {
- + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
- + return EINVAL;
- + }
- + for (c = cri; c != NULL; c = c->cri_next) {
- + if (c->cri_alg == CRYPTO_MD5 ||
- + c->cri_alg == CRYPTO_MD5_HMAC ||
- + c->cri_alg == CRYPTO_SHA1 ||
- + c->cri_alg == CRYPTO_SHA1_HMAC ||
- + c->cri_alg == CRYPTO_NULL_HMAC) {
- + if (macini)
- + return EINVAL;
- + macini = c;
- + } else if (c->cri_alg == CRYPTO_DES_CBC ||
- + c->cri_alg == CRYPTO_3DES_CBC ||
- + c->cri_alg == CRYPTO_AES_CBC ||
- + c->cri_alg == CRYPTO_NULL_CBC) {
- + if (encini)
- + return EINVAL;
- + encini = c;
- + } else {
- + DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
- + return EINVAL;
- + }
- + }
- + if (encini == NULL && macini == NULL)
- + return EINVAL;
- + if (encini) {
- + /* validate key length */
- + switch (encini->cri_alg) {
- + case CRYPTO_DES_CBC:
- + if (encini->cri_klen != 64)
- + return EINVAL;
- + break;
- + case CRYPTO_3DES_CBC:
- + if (encini->cri_klen != 192) {
- + return EINVAL;
- + }
- + break;
- + case CRYPTO_AES_CBC:
- + if (encini->cri_klen != 128 &&
- + encini->cri_klen != 192 &&
- + encini->cri_klen != 256)
- + return EINVAL;
- + break;
- + default:
- + DPRINTF("UNKNOWN encini->cri_alg %d\n",
- + encini->cri_alg);
- + return EINVAL;
- + }
- + }
- +
- + if (sc->sc_sessions == NULL) {
- + ses = sc->sc_sessions = (struct talitos_session *)
- + kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
- + if (ses == NULL)
- + return ENOMEM;
- + memset(ses, 0, sizeof(struct talitos_session));
- + sesn = 0;
- + sc->sc_nsessions = 1;
- + } else {
- + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
- + if (sc->sc_sessions[sesn].ses_used == 0) {
- + ses = &sc->sc_sessions[sesn];
- + break;
- + }
- + }
- +
- + if (ses == NULL) {
- + /* allocating session */
- + sesn = sc->sc_nsessions;
- + ses = (struct talitos_session *) kmalloc(
- + (sesn + 1) * sizeof(struct talitos_session),
- + SLAB_ATOMIC);
- + if (ses == NULL)
- + return ENOMEM;
- + memset(ses, 0,
- + (sesn + 1) * sizeof(struct talitos_session));
- + memcpy(ses, sc->sc_sessions,
- + sesn * sizeof(struct talitos_session));
- + memset(sc->sc_sessions, 0,
- + sesn * sizeof(struct talitos_session));
- + kfree(sc->sc_sessions);
- + sc->sc_sessions = ses;
- + ses = &sc->sc_sessions[sesn];
- + sc->sc_nsessions++;
- + }
- + }
- +
- + ses->ses_used = 1;
- +
- + if (encini) {
- + /* get an IV */
- + /* XXX may read fewer than requested */
- + read_random(ses->ses_iv, sizeof(ses->ses_iv));
- +
- + ses->ses_klen = (encini->cri_klen + 7) / 8;
- + memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
- + if (macini) {
- + /* doing hash on top of cipher */
- + ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
- + memcpy(ses->ses_hmac, macini->cri_key,
- + ses->ses_hmac_len);
- + }
- + } else if (macini) {
- + /* doing hash */
- + ses->ses_klen = (macini->cri_klen + 7) / 8;
- + memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
- + }
- +
- + /* back compat way of determining MSC result len */
- + if (macini) {
- + ses->ses_mlen = macini->cri_mlen;
- + if (ses->ses_mlen == 0) {
- + if (macini->cri_alg == CRYPTO_MD5_HMAC)
- + ses->ses_mlen = MD5_HASH_LEN;
- + else
- + ses->ses_mlen = SHA1_HASH_LEN;
- + }
- + }
- +
- + /* really should make up a template td here,
- + * and only fill things like i/o and direction in process() */
- +
- + /* assign session ID */
- + *sidp = TALITOS_SID(sc->sc_num, sesn);
- + return 0;
- +}
- +
- +/*
- + * Deallocate a session.
- + */
- +static int
- +talitos_freesession(device_t dev, u_int64_t tid)
- +{
- + struct talitos_softc *sc = device_get_softc(dev);
- + int session, ret;
- + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
- +
- + if (sc == NULL)
- + return EINVAL;
- + session = TALITOS_SESSION(sid);
- + if (session < sc->sc_nsessions) {
- + memset(&sc->sc_sessions[session], 0,
- + sizeof(sc->sc_sessions[session]));
- + ret = 0;
- + } else
- + ret = EINVAL;
- + return ret;
- +}
- +
- +/*
- + * launch device processing - it will come back with done notification
- + * in the form of an interrupt and/or HDR_DONE_BITS in header
- + */
- +static int
- +talitos_submit(
- + struct talitos_softc *sc,
- + struct talitos_desc *td,
- + int chsel)
- +{
- + u_int32_t v;
- +
- + v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
- + talitos_write(sc->sc_base_addr +
- + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
- + talitos_write(sc->sc_base_addr +
- + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
- + return 0;
- +}
- +
- +static int
- +talitos_process(device_t dev, struct cryptop *crp, int hint)
- +{
- + int i, err = 0, ivsize;
- + struct talitos_softc *sc = device_get_softc(dev);
- + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
- + caddr_t iv;
- + struct talitos_session *ses;
- + struct talitos_desc *td;
- + unsigned long flags;
- + /* descriptor mappings */
- + int hmac_key, hmac_data, cipher_iv, cipher_key,
- + in_fifo, out_fifo, cipher_iv_out;
- + static int chsel = -1;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
- + return EINVAL;
- + }
- + crp->crp_etype = 0;
- + if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
- + return EINVAL;
- + }
- +
- + ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
- +
- + /* enter the channel scheduler */
- + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
- +
- + /* reuse channel that already had/has requests for the required EU */
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
- + break;
- + }
- + if (i == sc->sc_num_channels) {
- + /*
- + * haven't seen this algo the last sc_num_channels or more
- + * use round robin in this case
- + * nb: sc->sc_num_channels must be power of 2
- + */
- + chsel = (chsel + 1) & (sc->sc_num_channels - 1);
- + } else {
- + /*
- + * matches channel with same target execution unit;
- + * use same channel in this case
- + */
- + chsel = i;
- + }
- + sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
- +
- + /* release the channel scheduler lock */
- + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
- +
- + /* acquire the selected channel fifo lock */
- + spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
- +
- + /* find and reserve next available descriptor-cryptop pair */
- + for (i = 0; i < sc->sc_chfifo_len; i++) {
- + if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
- + /*
- + * ensure correct descriptor formation by
- + * avoiding inadvertently setting "optional" entries
- + * e.g. not using "optional" dptr2 for MD/HMAC descs
- + */
- + memset(&sc->sc_chnfifo[chsel][i].cf_desc,
- + 0, sizeof(*td));
- + /* reserve it with done notification request bit */
- + sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
- + TALITOS_DONE_NOTIFY;
- + break;
- + }
- + }
- + spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
- +
- + if (i == sc->sc_chfifo_len) {
- + /* fifo full */
- + err = ERESTART;
- + goto errout;
- + }
- +
- + td = &sc->sc_chnfifo[chsel][i].cf_desc;
- + sc->sc_chnfifo[chsel][i].cf_crp = crp;
- +
- + crd1 = crp->crp_desc;
- + if (crd1 == NULL) {
- + err = EINVAL;
- + goto errout;
- + }
- + crd2 = crd1->crd_next;
- + /* prevent compiler warning */
- + hmac_key = 0;
- + hmac_data = 0;
- + if (crd2 == NULL) {
- + td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
- + /* assign descriptor dword ptr mappings for this desc. type */
- + cipher_iv = 1;
- + cipher_key = 2;
- + in_fifo = 3;
- + cipher_iv_out = 5;
- + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1 ||
- + crd1->crd_alg == CRYPTO_MD5) {
- + out_fifo = 5;
- + maccrd = crd1;
- + enccrd = NULL;
- + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
- + crd1->crd_alg == CRYPTO_3DES_CBC ||
- + crd1->crd_alg == CRYPTO_AES_CBC ||
- + crd1->crd_alg == CRYPTO_ARC4) {
- + out_fifo = 4;
- + maccrd = NULL;
- + enccrd = crd1;
- + } else {
- + DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
- + err = EINVAL;
- + goto errout;
- + }
- + } else {
- + if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
- + td->hdr |= TD_TYPE_IPSEC_ESP;
- + } else {
- + DPRINTF("unimplemented: multiple descriptor ipsec\n");
- + err = EINVAL;
- + goto errout;
- + }
- + /* assign descriptor dword ptr mappings for this desc. type */
- + hmac_key = 0;
- + hmac_data = 1;
- + cipher_iv = 2;
- + cipher_key = 3;
- + in_fifo = 4;
- + out_fifo = 5;
- + cipher_iv_out = 6;
- + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
- + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd1->crd_alg == CRYPTO_MD5 ||
- + crd1->crd_alg == CRYPTO_SHA1) &&
- + (crd2->crd_alg == CRYPTO_DES_CBC ||
- + crd2->crd_alg == CRYPTO_3DES_CBC ||
- + crd2->crd_alg == CRYPTO_AES_CBC ||
- + crd2->crd_alg == CRYPTO_ARC4) &&
- + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
- + maccrd = crd1;
- + enccrd = crd2;
- + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
- + crd1->crd_alg == CRYPTO_ARC4 ||
- + crd1->crd_alg == CRYPTO_3DES_CBC ||
- + crd1->crd_alg == CRYPTO_AES_CBC) &&
- + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
- + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
- + crd2->crd_alg == CRYPTO_MD5 ||
- + crd2->crd_alg == CRYPTO_SHA1) &&
- + (crd1->crd_flags & CRD_F_ENCRYPT)) {
- + enccrd = crd1;
- + maccrd = crd2;
- + } else {
- + /* We cannot order the SEC as requested */
- + printk("%s: cannot do the order\n",
- + device_get_nameunit(sc->sc_cdev));
- + err = EINVAL;
- + goto errout;
- + }
- + }
- + /* assign in_fifo and out_fifo based on input/output struct type */
- + if (crp->crp_flags & CRYPTO_F_SKBUF) {
- + /* using SKB buffers */
- + struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
- + if (skb_shinfo(skb)->nr_frags) {
- + printk("%s: skb frags unimplemented\n",
- + device_get_nameunit(sc->sc_cdev));
- + err = EINVAL;
- + goto errout;
- + }
- + td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
- + skb->len, DMA_TO_DEVICE);
- + td->ptr[in_fifo].len = skb->len;
- + td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
- + skb->len, DMA_TO_DEVICE);
- + td->ptr[out_fifo].len = skb->len;
- + td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
- + skb->len, DMA_TO_DEVICE);
- + } else if (crp->crp_flags & CRYPTO_F_IOV) {
- + /* using IOV buffers */
- + struct uio *uiop = (struct uio *)crp->crp_buf;
- + if (uiop->uio_iovcnt > 1) {
- + printk("%s: iov frags unimplemented\n",
- + device_get_nameunit(sc->sc_cdev));
- + err = EINVAL;
- + goto errout;
- + }
- + td->ptr[in_fifo].ptr = dma_map_single(NULL,
- + uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
- + td->ptr[in_fifo].len = crp->crp_ilen;
- + /* crp_olen is never set; always use crp_ilen */
- + td->ptr[out_fifo].ptr = dma_map_single(NULL,
- + uiop->uio_iov->iov_base,
- + crp->crp_ilen, DMA_TO_DEVICE);
- + td->ptr[out_fifo].len = crp->crp_ilen;
- + } else {
- + /* using contig buffers */
- + td->ptr[in_fifo].ptr = dma_map_single(NULL,
- + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
- + td->ptr[in_fifo].len = crp->crp_ilen;
- + td->ptr[out_fifo].ptr = dma_map_single(NULL,
- + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
- + td->ptr[out_fifo].len = crp->crp_ilen;
- + }
- + if (enccrd) {
- + switch (enccrd->crd_alg) {
- + case CRYPTO_3DES_CBC:
- + td->hdr |= TALITOS_MODE0_DEU_3DES;
- + /* FALLTHROUGH */
- + case CRYPTO_DES_CBC:
- + td->hdr |= TALITOS_SEL0_DEU
- + | TALITOS_MODE0_DEU_CBC;
- + if (enccrd->crd_flags & CRD_F_ENCRYPT)
- + td->hdr |= TALITOS_MODE0_DEU_ENC;
- + ivsize = 2*sizeof(u_int32_t);
- + DPRINTF("%cDES ses %d ch %d len %d\n",
- + (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
- + (u32)TALITOS_SESSION(crp->crp_sid),
- + chsel, td->ptr[in_fifo].len);
- + break;
- + case CRYPTO_AES_CBC:
- + td->hdr |= TALITOS_SEL0_AESU
- + | TALITOS_MODE0_AESU_CBC;
- + if (enccrd->crd_flags & CRD_F_ENCRYPT)
- + td->hdr |= TALITOS_MODE0_AESU_ENC;
- + ivsize = 4*sizeof(u_int32_t);
- + DPRINTF("AES ses %d ch %d len %d\n",
- + (u32)TALITOS_SESSION(crp->crp_sid),
- + chsel, td->ptr[in_fifo].len);
- + break;
- + default:
- + printk("%s: unimplemented enccrd->crd_alg %d\n",
- + device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
- + err = EINVAL;
- + goto errout;
- + }
- + /*
- + * Setup encrypt/decrypt state. When using basic ops
- + * we can't use an inline IV because hash/crypt offset
- + * must be from the end of the IV to the start of the
- + * crypt data and this leaves out the preceding header
- + * from the hash calculation. Instead we place the IV
- + * in the state record and set the hash/crypt offset to
- + * copy both the header+IV.
- + */
- + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
- + td->hdr |= TALITOS_DIR_OUTBOUND;
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
- + iv = enccrd->crd_iv;
- + else
- + iv = (caddr_t) ses->ses_iv;
- + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- + crypto_copyback(crp->crp_flags, crp->crp_buf,
- + enccrd->crd_inject, ivsize, iv);
- + }
- + } else {
- + td->hdr |= TALITOS_DIR_INBOUND;
- + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
- + iv = enccrd->crd_iv;
- + bcopy(enccrd->crd_iv, iv, ivsize);
- + } else {
- + iv = (caddr_t) ses->ses_iv;
- + crypto_copydata(crp->crp_flags, crp->crp_buf,
- + enccrd->crd_inject, ivsize, iv);
- + }
- + }
- + td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
- + DMA_TO_DEVICE);
- + td->ptr[cipher_iv].len = ivsize;
- + /*
- + * we don't need the cipher iv out length/pointer
- + * field to do ESP IPsec. Therefore we set the len field as 0,
- + * which tells the SEC not to do anything with this len/ptr
- + * field. Previously, when length/pointer as pointing to iv,
- + * it gave us corruption of packets.
- + */
- + td->ptr[cipher_iv_out].len = 0;
- + }
- + if (enccrd && maccrd) {
- + /* this is ipsec only for now */
- + td->hdr |= TALITOS_SEL1_MDEU
- + | TALITOS_MODE1_MDEU_INIT
- + | TALITOS_MODE1_MDEU_PAD;
- + switch (maccrd->crd_alg) {
- + case CRYPTO_MD5:
- + td->hdr |= TALITOS_MODE1_MDEU_MD5;
- + break;
- + case CRYPTO_MD5_HMAC:
- + td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
- + break;
- + case CRYPTO_SHA1:
- + td->hdr |= TALITOS_MODE1_MDEU_SHA1;
- + break;
- + case CRYPTO_SHA1_HMAC:
- + td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
- + break;
- + default:
- + /* We cannot order the SEC as requested */
- + printk("%s: cannot do the order\n",
- + device_get_nameunit(sc->sc_cdev));
- + err = EINVAL;
- + goto errout;
- + }
- + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
- + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
- + /*
- + * The offset from hash data to the start of
- + * crypt data is the difference in the skips.
- + */
- + /* ipsec only for now */
- + td->ptr[hmac_key].ptr = dma_map_single(NULL,
- + ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
- + td->ptr[hmac_key].len = ses->ses_hmac_len;
- + td->ptr[in_fifo].ptr += enccrd->crd_skip;
- + td->ptr[in_fifo].len = enccrd->crd_len;
- + td->ptr[out_fifo].ptr += enccrd->crd_skip;
- + td->ptr[out_fifo].len = enccrd->crd_len;
- + /* bytes of HMAC to postpend to ciphertext */
- + td->ptr[out_fifo].extent = ses->ses_mlen;
- + td->ptr[hmac_data].ptr += maccrd->crd_skip;
- + td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
- + }
- + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
- + printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
- + device_get_nameunit(sc->sc_cdev));
- + }
- + }
- + if (!enccrd && maccrd) {
- + /* single MD5 or SHA */
- + td->hdr |= TALITOS_SEL0_MDEU
- + | TALITOS_MODE0_MDEU_INIT
- + | TALITOS_MODE0_MDEU_PAD;
- + switch (maccrd->crd_alg) {
- + case CRYPTO_MD5:
- + td->hdr |= TALITOS_MODE0_MDEU_MD5;
- + DPRINTF("MD5 ses %d ch %d len %d\n",
- + (u32)TALITOS_SESSION(crp->crp_sid),
- + chsel, td->ptr[in_fifo].len);
- + break;
- + case CRYPTO_MD5_HMAC:
- + td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
- + break;
- + case CRYPTO_SHA1:
- + td->hdr |= TALITOS_MODE0_MDEU_SHA1;
- + DPRINTF("SHA1 ses %d ch %d len %d\n",
- + (u32)TALITOS_SESSION(crp->crp_sid),
- + chsel, td->ptr[in_fifo].len);
- + break;
- + case CRYPTO_SHA1_HMAC:
- + td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
- + break;
- + default:
- + /* We cannot order the SEC as requested */
- + DPRINTF("cannot do the order\n");
- + err = EINVAL;
- + goto errout;
- + }
- +
- + if (crp->crp_flags & CRYPTO_F_IOV)
- + td->ptr[out_fifo].ptr += maccrd->crd_inject;
- +
- + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
- + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
- + td->ptr[hmac_key].ptr = dma_map_single(NULL,
- + ses->ses_hmac, ses->ses_hmac_len,
- + DMA_TO_DEVICE);
- + td->ptr[hmac_key].len = ses->ses_hmac_len;
- + }
- + }
- + else {
- + /* using process key (session data has duplicate) */
- + td->ptr[cipher_key].ptr = dma_map_single(NULL,
- + enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
- + DMA_TO_DEVICE);
- + td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
- + }
- + /* descriptor complete - GO! */
- + return talitos_submit(sc, td, chsel);
- +
- +errout:
- + if (err != ERESTART) {
- + crp->crp_etype = err;
- + crypto_done(crp);
- + }
- + return err;
- +}
- +
- +/* go through all channels descriptors, notifying OCF what has
- + * _and_hasn't_ successfully completed and reset the device
- + * (otherwise it's up to decoding desc hdrs!)
- + */
- +static void talitos_errorprocessing(struct talitos_softc *sc)
- +{
- + unsigned long flags;
- + int i, j;
- +
- + /* disable further scheduling until under control */
- + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
- +
- + if (debug) dump_talitos_status(sc);
- + /* go through descriptors, try and salvage those successfully done,
- + * and EIO those that weren't
- + */
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
- + for (j = 0; j < sc->sc_chfifo_len; j++) {
- + if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
- + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
- + & TALITOS_HDR_DONE_BITS)
- + != TALITOS_HDR_DONE_BITS) {
- + /* this one didn't finish */
- + /* signify in crp->etype */
- + sc->sc_chnfifo[i][j].cf_crp->crp_etype
- + = EIO;
- + }
- + } else
- + continue; /* free entry */
- + /* either way, notify ocf */
- + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
- + /* and tag it available again
- + *
- + * memset to ensure correct descriptor formation by
- + * avoiding inadvertently setting "optional" entries
- + * e.g. not using "optional" dptr2 MD/HMAC processing
- + */
- + memset(&sc->sc_chnfifo[i][j].cf_desc,
- + 0, sizeof(struct talitos_desc));
- + }
- + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
- + }
- + /* reset and initialize the SEC h/w device */
- + talitos_reset_device(sc);
- + talitos_init_device(sc);
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
- + talitos_rng_init(sc);
- +#endif
- +
- + /* Okay. Stand by. */
- + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
- +
- + return;
- +}
- +
- +/* go through all channels descriptors, notifying OCF what's been done */
- +static void talitos_doneprocessing(struct talitos_softc *sc)
- +{
- + unsigned long flags;
- + int i, j;
- +
- + /* go through descriptors looking for done bits */
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
- + for (j = 0; j < sc->sc_chfifo_len; j++) {
- + /* descriptor has done bits set? */
- + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
- + & TALITOS_HDR_DONE_BITS)
- + == TALITOS_HDR_DONE_BITS) {
- + /* notify ocf */
- + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
- + /* and tag it available again
- + *
- + * memset to ensure correct descriptor formation by
- + * avoiding inadvertently setting "optional" entries
- + * e.g. not using "optional" dptr2 MD/HMAC processing
- + */
- + memset(&sc->sc_chnfifo[i][j].cf_desc,
- + 0, sizeof(struct talitos_desc));
- + }
- + }
- + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
- + }
- + return;
- +}
- +
- +static irqreturn_t
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- +talitos_intr(int irq, void *arg)
- +#else
- +talitos_intr(int irq, void *arg, struct pt_regs *regs)
- +#endif
- +{
- + struct talitos_softc *sc = arg;
- + u_int32_t v, v_hi;
- +
- + /* ack */
- + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
- + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
- + talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
- + talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
- +
- + if (unlikely(v & TALITOS_ISR_ERROR)) {
- + /* Okay, Houston, we've had a problem here. */
- + printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
- + device_get_nameunit(sc->sc_cdev), v, v_hi);
- + talitos_errorprocessing(sc);
- + } else
- + if (likely(v & TALITOS_ISR_DONE)) {
- + talitos_doneprocessing(sc);
- + }
- + return IRQ_HANDLED;
- +}
- +
- +/*
- + * Initialize registers we need to touch only once.
- + */
- +static void
- +talitos_init_device(struct talitos_softc *sc)
- +{
- + u_int32_t v;
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + /* init all channels */
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + v = talitos_read(sc->sc_base_addr +
- + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
- + v |= TALITOS_CH_CCCR_HI_CDWE
- + | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
- + talitos_write(sc->sc_base_addr +
- + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
- + }
- + /* enable all interrupts */
- + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
- + v |= TALITOS_IMR_ALL;
- + talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
- + v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
- + v |= TALITOS_IMR_HI_ERRONLY;
- + talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
- + return;
- +}
- +
- +/*
- + * set the master reset bit on the device.
- + */
- +static void
- +talitos_reset_device_master(struct talitos_softc *sc)
- +{
- + u_int32_t v;
- +
- + /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
- + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
- + talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
- +
- + while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
- + cpu_relax();
- +
- + return;
- +}
- +
- +/*
- + * Resets the device. Values in the registers are left as is
- + * from the reset (i.e. initial values are assigned elsewhere).
- + */
- +static void
- +talitos_reset_device(struct talitos_softc *sc)
- +{
- + u_int32_t v;
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + /*
- + * Master reset
- + * errata documentation: warning: certain SEC interrupts
- + * are not fully cleared by writing the MCR:SWR bit,
- + * set bit twice to completely reset
- + */
- + talitos_reset_device_master(sc); /* once */
- + talitos_reset_device_master(sc); /* and once again */
- +
- + /* reset all channels */
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
- + TALITOS_CH_CCCR);
- + talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
- + TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
- + }
- +}
- +
- +/* Set up the crypto device structure, private data,
- + * and anything else we need before we start */
- +#ifdef CONFIG_PPC_MERGE
- +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
- +#else
- +static int talitos_probe(struct platform_device *pdev)
- +#endif
- +{
- + struct talitos_softc *sc = NULL;
- + struct resource *r;
- +#ifdef CONFIG_PPC_MERGE
- + struct device *device = &ofdev->dev;
- + struct device_node *np = ofdev->node;
- + const unsigned int *prop;
- + int err;
- + struct resource res;
- +#endif
- + static int num_chips = 0;
- + int rc;
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- +
- + sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
- + if (!sc)
- + return -ENOMEM;
- + memset(sc, 0, sizeof(*sc));
- +
- + softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
- +
- + sc->sc_irq = -1;
- + sc->sc_cid = -1;
- +#ifndef CONFIG_PPC_MERGE
- + sc->sc_dev = pdev;
- +#endif
- + sc->sc_num = num_chips++;
- +
- +#ifdef CONFIG_PPC_MERGE
- + dev_set_drvdata(device, sc);
- +#else
- + platform_set_drvdata(sc->sc_dev, sc);
- +#endif
- +
- + /* get the irq line */
- +#ifdef CONFIG_PPC_MERGE
- + err = of_address_to_resource(np, 0, &res);
- + if (err)
- + return -EINVAL;
- + r = &res;
- +
- + sc->sc_irq = irq_of_parse_and_map(np, 0);
- +#else
- + /* get a pointer to the register memory */
- + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- +
- + sc->sc_irq = platform_get_irq(pdev, 0);
- +#endif
- + rc = request_irq(sc->sc_irq, talitos_intr, 0,
- + device_get_nameunit(sc->sc_cdev), sc);
- + if (rc) {
- + printk(KERN_ERR "%s: failed to hook irq %d\n",
- + device_get_nameunit(sc->sc_cdev), sc->sc_irq);
- + sc->sc_irq = -1;
- + goto out;
- + }
- +
- + sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
- + if (!sc->sc_base_addr) {
- + printk(KERN_ERR "%s: failed to ioremap\n",
- + device_get_nameunit(sc->sc_cdev));
- + goto out;
- + }
- +
- + /* figure out our SEC's properties and capabilities */
- + sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
- + | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
- + DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
- +
- +#ifdef CONFIG_PPC_MERGE
- + /* get SEC properties from device tree, defaulting to SEC 2.0 */
- +
- + prop = of_get_property(np, "num-channels", NULL);
- + sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
- +
- + prop = of_get_property(np, "channel-fifo-len", NULL);
- + sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
- +
- + prop = of_get_property(np, "exec-units-mask", NULL);
- + sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
- +
- + prop = of_get_property(np, "descriptor-types-mask", NULL);
- + sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
- +#else
- + /* bulk should go away with openfirmware flat device tree support */
- + if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
- + sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
- + sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
- + sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
- + sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
- + } else {
- + printk(KERN_ERR "%s: failed to id device\n",
- + device_get_nameunit(sc->sc_cdev));
- + goto out;
- + }
- +#endif
- +
- + /* + 1 is for the meta-channel lock used by the channel scheduler */
- + sc->sc_chnfifolock = (spinlock_t *) kmalloc(
- + (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
- + if (!sc->sc_chnfifolock)
- + goto out;
- + for (i = 0; i < sc->sc_num_channels + 1; i++) {
- + spin_lock_init(&sc->sc_chnfifolock[i]);
- + }
- +
- + sc->sc_chnlastalg = (int *) kmalloc(
- + sc->sc_num_channels * sizeof(int), GFP_KERNEL);
- + if (!sc->sc_chnlastalg)
- + goto out;
- + memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
- +
- + sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
- + sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
- + GFP_KERNEL);
- + if (!sc->sc_chnfifo)
- + goto out;
- + for (i = 0; i < sc->sc_num_channels; i++) {
- + sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
- + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
- + GFP_KERNEL);
- + if (!sc->sc_chnfifo[i])
- + goto out;
- + memset(sc->sc_chnfifo[i], 0,
- + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
- + }
- +
- + /* reset and initialize the SEC h/w device */
- + talitos_reset_device(sc);
- + talitos_init_device(sc);
- +
- + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
- + if (sc->sc_cid < 0) {
- + printk(KERN_ERR "%s: could not get crypto driver id\n",
- + device_get_nameunit(sc->sc_cdev));
- + goto out;
- + }
- +
- + /* register algorithms with the framework */
- + printk("%s:", device_get_nameunit(sc->sc_cdev));
- +
- + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
- + printk(" rng");
- +#ifdef CONFIG_OCF_RANDOMHARVEST
- + talitos_rng_init(sc);
- + crypto_rregister(sc->sc_cid, talitos_read_random, sc);
- +#endif
- + }
- + if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
- + printk(" des/3des");
- + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
- + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
- + }
- + if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
- + printk(" aes");
- + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
- + }
- + if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
- + printk(" md5");
- + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
- + /* HMAC support only with IPsec for now */
- + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
- + printk(" sha1");
- + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
- + /* HMAC support only with IPsec for now */
- + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
- + }
- + printk("\n");
- + return 0;
- +
- +out:
- +#ifndef CONFIG_PPC_MERGE
- + talitos_remove(pdev);
- +#endif
- + return -ENOMEM;
- +}
- +
- +#ifdef CONFIG_PPC_MERGE
- +static int talitos_remove(struct of_device *ofdev)
- +#else
- +static int talitos_remove(struct platform_device *pdev)
- +#endif
- +{
- +#ifdef CONFIG_PPC_MERGE
- + struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
- +#else
- + struct talitos_softc *sc = platform_get_drvdata(pdev);
- +#endif
- + int i;
- +
- + DPRINTF("%s()\n", __FUNCTION__);
- + if (sc->sc_cid >= 0)
- + crypto_unregister_all(sc->sc_cid);
- + if (sc->sc_chnfifo) {
- + for (i = 0; i < sc->sc_num_channels; i++)
- + if (sc->sc_chnfifo[i])
- + kfree(sc->sc_chnfifo[i]);
- + kfree(sc->sc_chnfifo);
- + }
- + if (sc->sc_chnlastalg)
- + kfree(sc->sc_chnlastalg);
- + if (sc->sc_chnfifolock)
- + kfree(sc->sc_chnfifolock);
- + if (sc->sc_irq != -1)
- + free_irq(sc->sc_irq, sc);
- + if (sc->sc_base_addr)
- + iounmap((void *) sc->sc_base_addr);
- + kfree(sc);
- + return 0;
- +}
- +
- +#ifdef CONFIG_PPC_MERGE
- +static struct of_device_id talitos_match[] = {
- + {
- + .type = "crypto",
- + .compatible = "talitos",
- + },
- + {},
- +};
- +
- +MODULE_DEVICE_TABLE(of, talitos_match);
- +
- +static struct of_platform_driver talitos_driver = {
- + .name = DRV_NAME,
- + .match_table = talitos_match,
- + .probe = talitos_probe,
- + .remove = talitos_remove,
- +};
- +
- +static int __init talitos_init(void)
- +{
- + return of_register_platform_driver(&talitos_driver);
- +}
- +
- +static void __exit talitos_exit(void)
- +{
- + of_unregister_platform_driver(&talitos_driver);
- +}
- +#else
- +/* Structure for a platform device driver */
- +static struct platform_driver talitos_driver = {
- + .probe = talitos_probe,
- + .remove = talitos_remove,
- + .driver = {
- + .name = "fsl-sec2",
- + }
- +};
- +
- +static int __init talitos_init(void)
- +{
- + return platform_driver_register(&talitos_driver);
- +}
- +
- +static void __exit talitos_exit(void)
- +{
- + platform_driver_unregister(&talitos_driver);
- +}
- +#endif
- +
- +module_init(talitos_init);
- +module_exit(talitos_exit);
- +
- +MODULE_LICENSE("Dual BSD/GPL");
- +MODULE_AUTHOR("kim.phillips@freescale.com");
- +MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
- diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.36/crypto/ocf/talitos/talitos_dev.h
- --- linux-2.6.36.orig/crypto/ocf/talitos/talitos_dev.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/talitos/talitos_dev.h 2010-11-09 20:28:13.232495491 +0100
- @@ -0,0 +1,277 @@
- +/*
- + * Freescale SEC (talitos) device dependent data structures
- + *
- + * Copyright (c) 2006 Freescale Semiconductor, Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + *
- + */
- +
- +/* device ID register values */
- +#define TALITOS_ID_SEC_2_0 0x40
- +#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
- +
- +/*
- + * following num_channels, channel-fifo-depth, exec-unit-mask, and
- + * descriptor-types-mask are for forward-compatibility with openfirmware
- + * flat device trees
- + */
- +
- +/*
- + * num_channels : the number of channels available in each SEC version.
- + */
- +
- +/* n.b. this driver requires these values be a power of 2 */
- +#define TALITOS_NCHANNELS_SEC_1_0 4
- +#define TALITOS_NCHANNELS_SEC_1_2 1
- +#define TALITOS_NCHANNELS_SEC_2_0 4
- +#define TALITOS_NCHANNELS_SEC_2_01 4
- +#define TALITOS_NCHANNELS_SEC_2_1 4
- +#define TALITOS_NCHANNELS_SEC_2_4 4
- +
- +/*
- + * channel-fifo-depth : The number of descriptor
- + * pointers a channel fetch fifo can hold.
- + */
- +#define TALITOS_CHFIFOLEN_SEC_1_0 1
- +#define TALITOS_CHFIFOLEN_SEC_1_2 1
- +#define TALITOS_CHFIFOLEN_SEC_2_0 24
- +#define TALITOS_CHFIFOLEN_SEC_2_01 24
- +#define TALITOS_CHFIFOLEN_SEC_2_1 24
- +#define TALITOS_CHFIFOLEN_SEC_2_4 24
- +
- +/*
- + * exec-unit-mask : The bitmask representing what Execution Units (EUs)
- + * are available. EU information should be encoded following the SEC's
- + * EU_SEL0 bitfield documentation, i.e. as follows:
- + *
- + * bit 31 = set if SEC permits no-EU selection (should be always set)
- + * bit 30 = set if SEC has the ARC4 EU (AFEU)
- + * bit 29 = set if SEC has the des/3des EU (DEU)
- + * bit 28 = set if SEC has the message digest EU (MDEU)
- + * bit 27 = set if SEC has the random number generator EU (RNG)
- + * bit 26 = set if SEC has the public key EU (PKEU)
- + * bit 25 = set if SEC has the aes EU (AESU)
- + * bit 24 = set if SEC has the Kasumi EU (KEU)
- + *
- + */
- +#define TALITOS_HAS_EU_NONE (1<<0)
- +#define TALITOS_HAS_EU_AFEU (1<<1)
- +#define TALITOS_HAS_EU_DEU (1<<2)
- +#define TALITOS_HAS_EU_MDEU (1<<3)
- +#define TALITOS_HAS_EU_RNG (1<<4)
- +#define TALITOS_HAS_EU_PKEU (1<<5)
- +#define TALITOS_HAS_EU_AESU (1<<6)
- +#define TALITOS_HAS_EU_KEU (1<<7)
- +
- +/* the corresponding masks for each SEC version */
- +#define TALITOS_HAS_EUS_SEC_1_0 0x7f
- +#define TALITOS_HAS_EUS_SEC_1_2 0x4d
- +#define TALITOS_HAS_EUS_SEC_2_0 0x7f
- +#define TALITOS_HAS_EUS_SEC_2_01 0x7f
- +#define TALITOS_HAS_EUS_SEC_2_1 0xff
- +#define TALITOS_HAS_EUS_SEC_2_4 0x7f
- +
- +/*
- + * descriptor-types-mask : The bitmask representing what descriptors
- + * are available. Descriptor type information should be encoded
- + * following the SEC's Descriptor Header Dword DESC_TYPE field
- + * documentation, i.e. as follows:
- + *
- + * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
- + * bit 1 = set if SEC supports the ipsec_esp descriptor type
- + * bit 2 = set if SEC supports the common_nonsnoop desc. type
- + * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
- + * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
- + * bit 5 = set if SEC supports the srtp descriptor type
- + * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
- + * bit 7 = set if SEC supports the pkeu_assemble descriptor type
- + * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
- + * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
- + * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
- + * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
- + *
- + * ..and so on and so forth.
- + */
- +#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
- +#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
- +#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
- +
- +/* the corresponding masks for each SEC version */
- +#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
- +#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
- +
- +/*
- + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
- + */
- +
- +/* global register offset addresses */
- +#define TALITOS_ID 0x1020
- +#define TALITOS_ID_HI 0x1024
- +#define TALITOS_MCR 0x1030 /* master control register */
- +#define TALITOS_MCR_HI 0x1038 /* master control register */
- +#define TALITOS_MCR_SWR 0x1
- +#define TALITOS_IMR 0x1008 /* interrupt mask register */
- +#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
- +#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
- +#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
- +#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
- +#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
- +#define TALITOS_ISR 0x1010 /* interrupt status register */
- +#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
- +#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
- +#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
- +#define TALITOS_ICR 0x1018 /* interrupt clear register */
- +#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
- +
- +/* channel register address stride */
- +#define TALITOS_CH_OFFSET 0x100
- +
- +/* channel register offset addresses and bits */
- +#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
- +#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
- +#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
- +#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
- +#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
- +#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
- +#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
- +#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
- +#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
- +#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
- +#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
- +#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
- +#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
- + * Descriptor Buffer (debug) */
- +
- +/* execution unit register offset addresses and bits */
- +#define TALITOS_DEUSR 0x2028 /* DEU status register */
- +#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
- +#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
- +#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
- +#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
- +#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
- +#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
- +#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
- +#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
- +#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
- +#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
- +#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
- +#define TALITOS_RNGSR 0xa028 /* RNG status register */
- +#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
- +#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
- +#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
- +#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
- +#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
- +#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
- +#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
- +#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
- +#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
- +#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
- +#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
- +
- +/* descriptor pointer entry */
- +struct talitos_desc_ptr {
- + u16 len; /* length */
- + u8 extent; /* jump (to s/g link table) and extent */
- + u8 res; /* reserved */
- + u32 ptr; /* pointer */
- +};
- +
- +/* descriptor */
- +struct talitos_desc {
- + u32 hdr; /* header */
- + u32 res; /* reserved */
- + struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
- +};
- +
- +/* talitos descriptor header (hdr) bits */
- +
- +/* primary execution unit select */
- +#define TALITOS_SEL0_AFEU 0x10000000
- +#define TALITOS_SEL0_DEU 0x20000000
- +#define TALITOS_SEL0_MDEU 0x30000000
- +#define TALITOS_SEL0_RNG 0x40000000
- +#define TALITOS_SEL0_PKEU 0x50000000
- +#define TALITOS_SEL0_AESU 0x60000000
- +
- +/* primary execution unit mode (MODE0) and derivatives */
- +#define TALITOS_MODE0_AESU_CBC 0x00200000
- +#define TALITOS_MODE0_AESU_ENC 0x00100000
- +#define TALITOS_MODE0_DEU_CBC 0x00400000
- +#define TALITOS_MODE0_DEU_3DES 0x00200000
- +#define TALITOS_MODE0_DEU_ENC 0x00100000
- +#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
- +#define TALITOS_MODE0_MDEU_HMAC 0x00800000
- +#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
- +#define TALITOS_MODE0_MDEU_MD5 0x00200000
- +#define TALITOS_MODE0_MDEU_SHA256 0x00100000
- +#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
- +#define TALITOS_MODE0_MDEU_MD5_HMAC \
- + (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
- +#define TALITOS_MODE0_MDEU_SHA256_HMAC \
- + (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
- +#define TALITOS_MODE0_MDEU_SHA1_HMAC \
- + (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
- +
- +/* secondary execution unit select (SEL1) */
- +/* it's MDEU or nothing */
- +#define TALITOS_SEL1_MDEU 0x00030000
- +
- +/* secondary execution unit mode (MODE1) and derivatives */
- +#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
- +#define TALITOS_MODE1_MDEU_HMAC 0x00000800
- +#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
- +#define TALITOS_MODE1_MDEU_MD5 0x00000200
- +#define TALITOS_MODE1_MDEU_SHA256 0x00000100
- +#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
- +#define TALITOS_MODE1_MDEU_MD5_HMAC \
- + (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
- +#define TALITOS_MODE1_MDEU_SHA256_HMAC \
- + (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
- +#define TALITOS_MODE1_MDEU_SHA1_HMAC \
- + (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
- +
- +/* direction of overall data flow (DIR) */
- +#define TALITOS_DIR_OUTBOUND 0x00000000
- +#define TALITOS_DIR_INBOUND 0x00000002
- +
- +/* done notification (DN) */
- +#define TALITOS_DONE_NOTIFY 0x00000001
- +
- +/* descriptor types */
- +/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
- +#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
- +#define TD_TYPE_IPSEC_ESP (1 << 3)
- +#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
- +#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
- +
- +#define TALITOS_HDR_DONE_BITS 0xff000000
- +
- +#define DPRINTF(a...) do { \
- + if (debug) { \
- + printk("%s: ", sc ? \
- + device_get_nameunit(sc->sc_cdev) : "talitos"); \
- + printk(a); \
- + } \
- + } while (0)
- diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.36/crypto/ocf/talitos/talitos_soft.h
- --- linux-2.6.36.orig/crypto/ocf/talitos/talitos_soft.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/talitos/talitos_soft.h 2010-11-09 20:28:13.272495451 +0100
- @@ -0,0 +1,77 @@
- +/*
- + * Freescale SEC data structures for integration with ocf-linux
- + *
- + * Copyright (c) 2006 Freescale Semiconductor, Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + *
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 3. The name of the author may not be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +/*
- + * paired descriptor and associated crypto operation
- + */
- +struct desc_cryptop_pair {
- + struct talitos_desc cf_desc; /* descriptor ptr */
- + struct cryptop *cf_crp; /* cryptop ptr */
- +};
- +
- +/*
- + * Holds data specific to a single talitos device.
- + */
- +struct talitos_softc {
- + softc_device_decl sc_cdev;
- + struct platform_device *sc_dev; /* device backpointer */
- + ocf_iomem_t sc_base_addr;
- + int sc_irq;
- + int sc_num; /* if we have multiple chips */
- + int32_t sc_cid; /* crypto tag */
- + u64 sc_chiprev; /* major/minor chip revision */
- + int sc_nsessions;
- + struct talitos_session *sc_sessions;
- + int sc_num_channels;/* number of crypto channels */
- + int sc_chfifo_len; /* channel fetch fifo len */
- + int sc_exec_units; /* execution units mask */
- + int sc_desc_types; /* descriptor types mask */
- + /*
- + * mutual exclusion for intra-channel resources, e.g. fetch fifos
- + * the last entry is a meta-channel lock used by the channel scheduler
- + */
- + spinlock_t *sc_chnfifolock;
- + /* sc_chnlastalgo contains last algorithm for that channel */
- + int *sc_chnlastalg;
- + /* sc_chnfifo holds pending descriptor--crypto operation pairs */
- + struct desc_cryptop_pair **sc_chnfifo;
- +};
- +
- +struct talitos_session {
- + u_int32_t ses_used;
- + u_int32_t ses_klen; /* key length in bits */
- + u_int32_t ses_key[8]; /* DES/3DES/AES key */
- + u_int32_t ses_hmac[5]; /* hmac inner state */
- + u_int32_t ses_hmac_len; /* hmac length */
- + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
- + u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
- +};
- +
- +#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
- +#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
- diff -Nur linux-2.6.36.orig/crypto/ocf/uio.h linux-2.6.36/crypto/ocf/uio.h
- --- linux-2.6.36.orig/crypto/ocf/uio.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/crypto/ocf/uio.h 2010-11-09 20:28:13.313482727 +0100
- @@ -0,0 +1,54 @@
- +#ifndef _OCF_UIO_H_
- +#define _OCF_UIO_H_
- +
- +#include <linux/uio.h>
- +
- +/*
- + * The linux uio.h doesn't have all we need. To be fully api compatible
- + * with the BSD cryptodev, we need to keep this around. Perhaps this can
- + * be moved back into the linux/uio.h
- + *
- + * Linux port done by David McCullough <david_mccullough@mcafee.com>
- + * Copyright (C) 2006-2010 David McCullough
- + * Copyright (C) 2004-2005 Intel Corporation.
- + *
- + * LICENSE TERMS
- + *
- + * The free distribution and use of this software in both source and binary
- + * form is allowed (with or without changes) provided that:
- + *
- + * 1. distributions of this source code include the above copyright
- + * notice, this list of conditions and the following disclaimer;
- + *
- + * 2. distributions in binary form include the above copyright
- + * notice, this list of conditions and the following disclaimer
- + * in the documentation and/or other associated materials;
- + *
- + * 3. the copyright holder's name is not used to endorse products
- + * built using this software without specific written permission.
- + *
- + * ALTERNATIVELY, provided that this notice is retained in full, this product
- + * may be distributed under the terms of the GNU General Public License (GPL),
- + * in which case the provisions of the GPL apply INSTEAD OF those given above.
- + *
- + * DISCLAIMER
- + *
- + * This software is provided 'as is' with no explicit or implied warranties
- + * in respect of its properties, including, but not limited to, correctness
- + * and/or fitness for purpose.
- + * ---------------------------------------------------------------------------
- + */
- +
- +struct uio {
- + struct iovec *uio_iov;
- + int uio_iovcnt;
- + off_t uio_offset;
- + int uio_resid;
- +#if 0
- + enum uio_seg uio_segflg;
- + enum uio_rw uio_rw;
- + struct thread *uio_td;
- +#endif
- +};
- +
- +#endif
- diff -Nur linux-2.6.36.orig/drivers/char/random.c linux-2.6.36/drivers/char/random.c
- --- linux-2.6.36.orig/drivers/char/random.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/drivers/char/random.c 2010-11-09 20:28:13.352495461 +0100
- @@ -129,6 +129,9 @@
- * unsigned int value);
- * void add_interrupt_randomness(int irq);
- *
- + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
- + * int random_input_wait(void);
- + *
- * add_input_randomness() uses the input layer interrupt timing, as well as
- * the event type information from the hardware.
- *
- @@ -140,6 +143,13 @@
- * a better measure, since the timing of the disk interrupts are more
- * unpredictable.
- *
- + * random_input_words() just provides a raw block of entropy to the input
- + * pool, such as from a hardware entropy generator.
- + *
- + * random_input_wait() suspends the caller until such time as the
- + * entropy pool falls below the write threshold, and returns a count of how
- + * much entropy (in bits) is needed to sustain the pool.
- + *
- * All of these routines try to estimate how many bits of randomness a
- * particular randomness source. They do this by keeping track of the
- * first and second order deltas of the event timings.
- @@ -259,6 +269,7 @@
- #define SEC_XFER_SIZE 512
- #define EXTRACT_SIZE 10
-
- +
- /*
- * The minimum number of bits of entropy before we wake up a read on
- * /dev/random. Should be enough to do a significant reseed.
- @@ -552,6 +563,60 @@
- spin_unlock_irqrestore(&r->lock, flags);
- }
-
- +/*
- + * random_input_words - add bulk entropy to pool
- + *
- + * @buf: buffer to add
- + * @wordcount: number of __u32 words to add
- + * @ent_count: total amount of entropy (in bits) to credit
- + *
- + * this provides bulk input of entropy to the input pool
- + *
- + */
- +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
- +{
- + mix_pool_bytes(&input_pool, buf, wordcount*4);
- +
- + credit_entropy_bits(&input_pool, ent_count);
- +
- + DEBUG_ENT("crediting %d bits => %d\n",
- + ent_count, input_pool.entropy_count);
- + /*
- + * Wake up waiting processes if we have enough
- + * entropy.
- + */
- + if (input_pool.entropy_count >= random_read_wakeup_thresh)
- + wake_up_interruptible(&random_read_wait);
- +}
- +EXPORT_SYMBOL(random_input_words);
- +
- +/*
- + * random_input_wait - wait until random needs entropy
- + *
- + * this function sleeps until the /dev/random subsystem actually
- + * needs more entropy, and then return the amount of entropy
- + * that it would be nice to have added to the system.
- + */
- +int random_input_wait(void)
- +{
- + int count;
- +
- + wait_event_interruptible(random_write_wait,
- + input_pool.entropy_count < random_write_wakeup_thresh);
- +
- + count = random_write_wakeup_thresh - input_pool.entropy_count;
- +
- + /* likely we got woken up due to a signal */
- + if (count <= 0) count = random_read_wakeup_thresh;
- +
- + DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
- + count,
- + input_pool.entropy_count, random_write_wakeup_thresh);
- +
- + return count;
- +}
- +EXPORT_SYMBOL(random_input_wait);
- +
- /*********************************************************************
- *
- * Entropy input management
- diff -Nur linux-2.6.36.orig/fs/fcntl.c linux-2.6.36/fs/fcntl.c
- --- linux-2.6.36.orig/fs/fcntl.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/fs/fcntl.c 2010-11-09 20:28:13.392495458 +0100
- @@ -142,6 +142,7 @@
- }
- return ret;
- }
- +EXPORT_SYMBOL(sys_dup);
-
- #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
-
- diff -Nur linux-2.6.36.orig/include/linux/miscdevice.h linux-2.6.36/include/linux/miscdevice.h
- --- linux-2.6.36.orig/include/linux/miscdevice.h 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/include/linux/miscdevice.h 2010-11-09 20:28:13.432495492 +0100
- @@ -18,6 +18,7 @@
- #define APOLLO_MOUSE_MINOR 7
- #define PC110PAD_MINOR 9
- /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
- +#define CRYPTODEV_MINOR 70 /* /dev/crypto */
- #define WATCHDOG_MINOR 130 /* Watchdog timer */
- #define TEMP_MINOR 131 /* Temperature Sensor */
- #define RTC_MINOR 135
- diff -Nur linux-2.6.36.orig/include/linux/random.h linux-2.6.36/include/linux/random.h
- --- linux-2.6.36.orig/include/linux/random.h 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/include/linux/random.h 2010-11-09 20:28:13.597270121 +0100
- @@ -9,6 +9,7 @@
-
- #include <linux/types.h>
- #include <linux/ioctl.h>
- +#include <linux/types.h> /* for __u32 in user space */
- #include <linux/irqnr.h>
-
- /* ioctl()'s for the random number generator */
- @@ -34,6 +35,30 @@
- /* Clear the entropy pool and associated counters. (Superuser only.) */
- #define RNDCLEARPOOL _IO( 'R', 0x06 )
-
- +#ifdef CONFIG_FIPS_RNG
- +
- +/* Size of seed value - equal to AES blocksize */
- +#define AES_BLOCK_SIZE_BYTES 16
- +#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
- +/* Size of AES key */
- +#define KEY_SIZE_BYTES 16
- +
- +/* ioctl() structure used by FIPS 140-2 Tests */
- +struct rand_fips_test {
- + unsigned char key[KEY_SIZE_BYTES]; /* Input */
- + unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
- + unsigned char seed[SEED_SIZE_BYTES]; /* Input */
- + unsigned char result[SEED_SIZE_BYTES]; /* Output */
- +};
- +
- +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
- +#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
- +
- +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
- +#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
- +
- +#endif /* #ifdef CONFIG_FIPS_RNG */
- +
- struct rand_pool_info {
- int entropy_count;
- int buf_size;
- @@ -54,6 +79,10 @@
- unsigned int value);
- extern void add_interrupt_randomness(int irq);
-
- +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
- +extern int random_input_wait(void);
- +#define HAS_RANDOM_INPUT_WAIT 1
- +
- extern void get_random_bytes(void *buf, int nbytes);
- void generate_random_uuid(unsigned char uuid_out[16]);
-
|