7072-LS1012-Add-PPFE-driver-in-Linux.patch 450 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167
  1. From 0157efe2fbe2fe56c34727d326cd74284c06cbd5 Mon Sep 17 00:00:00 2001
  2. From: Bhaskar Upadhaya <Bhaskar.Upadhaya@freescale.com>
  3. Date: Wed, 24 Aug 2016 10:51:21 +0800
  4. Subject: [PATCH 072/113] LS1012: Add PPFE driver in Linux
  5. commit 7584b690d4c8e4e435c2e6abcdb38d6595a0c302
  6. [context adjustment]
  7. [don't apply fsl-ls1012a-rdb.dts and fsl-ls1012a.dtsi]
  8. [Let PPFE driver can be selectd as a module]
  9. Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@freescale.com>
  10. Integrated-by: Zhao Qiang <qiang.zhao@nxp.com>
  11. Integrated-by: Yutang Jiang <yutang.jiang@nxp.com>
  12. ---
  13. drivers/staging/Kconfig | 2 +
  14. drivers/staging/Makefile | 1 +
  15. drivers/staging/fsl_ppfe/Kconfig | 5 +
  16. drivers/staging/fsl_ppfe/Makefile | 44 +
  17. drivers/staging/fsl_ppfe/config.h | 8 +
  18. drivers/staging/fsl_ppfe/control_link.lds | 32 +
  19. drivers/staging/fsl_ppfe/include/pfe/cbus.h | 88 +
  20. drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h | 55 +
  21. .../staging/fsl_ppfe/include/pfe/cbus/class_csr.h | 242 ++
  22. drivers/staging/fsl_ppfe/include/pfe/cbus/emac.h | 243 ++
  23. .../staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h | 250 ++
  24. drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h | 78 +
  25. drivers/staging/fsl_ppfe/include/pfe/cbus/gpt.h | 29 +
  26. drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h | 96 +
  27. .../staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h | 51 +
  28. .../staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h | 128 +
  29. .../staging/fsl_ppfe/include/pfe/cbus/util_csr.h | 61 +
  30. drivers/staging/fsl_ppfe/include/pfe/class.h | 133 +
  31. drivers/staging/fsl_ppfe/include/pfe/class/ccu.h | 28 +
  32. drivers/staging/fsl_ppfe/include/pfe/class/efet.h | 44 +
  33. .../staging/fsl_ppfe/include/pfe/class/mac_hash.h | 55 +
  34. drivers/staging/fsl_ppfe/include/pfe/class/perg.h | 39 +
  35. .../staging/fsl_ppfe/include/pfe/class/vlan_hash.h | 46 +
  36. drivers/staging/fsl_ppfe/include/pfe/gpt.h | 44 +
  37. drivers/staging/fsl_ppfe/include/pfe/pe.h | 626 +++++
  38. drivers/staging/fsl_ppfe/include/pfe/pfe.h | 444 +++
  39. drivers/staging/fsl_ppfe/include/pfe/tmu.h | 68 +
  40. .../staging/fsl_ppfe/include/pfe/tmu/phy_queue.h | 56 +
  41. drivers/staging/fsl_ppfe/include/pfe/tmu/sched.h | 72 +
  42. drivers/staging/fsl_ppfe/include/pfe/tmu/shaper.h | 37 +
  43. drivers/staging/fsl_ppfe/include/pfe/uart.h | 31 +
  44. drivers/staging/fsl_ppfe/include/pfe/util.h | 49 +
  45. drivers/staging/fsl_ppfe/include/pfe/util/eape.h | 57 +
  46. drivers/staging/fsl_ppfe/include/pfe/util/efet.h | 119 +
  47. drivers/staging/fsl_ppfe/include/pfe/util/inq.h | 28 +
  48. drivers/staging/fsl_ppfe/pfe_ctrl.c | 363 +++
  49. drivers/staging/fsl_ppfe/pfe_ctrl.h | 111 +
  50. drivers/staging/fsl_ppfe/pfe_ctrl_hal.c | 207 ++
  51. drivers/staging/fsl_ppfe/pfe_ctrl_hal.h | 129 +
  52. drivers/staging/fsl_ppfe/pfe_debugfs.c | 109 +
  53. drivers/staging/fsl_ppfe/pfe_debugfs.h | 8 +
  54. drivers/staging/fsl_ppfe/pfe_eth.c | 2956 ++++++++++++++++++++
  55. drivers/staging/fsl_ppfe/pfe_eth.h | 384 +++
  56. drivers/staging/fsl_ppfe/pfe_firmware.c | 322 +++
  57. drivers/staging/fsl_ppfe/pfe_firmware.h | 41 +
  58. drivers/staging/fsl_ppfe/pfe_hal.c | 2217 +++++++++++++++
  59. drivers/staging/fsl_ppfe/pfe_hif.c | 939 +++++++
  60. drivers/staging/fsl_ppfe/pfe_hif.h | 322 +++
  61. drivers/staging/fsl_ppfe/pfe_hif_lib.c | 658 +++++
  62. drivers/staging/fsl_ppfe/pfe_hif_lib.h | 219 ++
  63. drivers/staging/fsl_ppfe/pfe_hw.c | 188 ++
  64. drivers/staging/fsl_ppfe/pfe_hw.h | 32 +
  65. drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 341 +++
  66. drivers/staging/fsl_ppfe/pfe_mod.c | 140 +
  67. drivers/staging/fsl_ppfe/pfe_mod.h | 163 ++
  68. drivers/staging/fsl_ppfe/pfe_perfmon.c | 175 ++
  69. drivers/staging/fsl_ppfe/pfe_perfmon.h | 41 +
  70. drivers/staging/fsl_ppfe/pfe_platform.c | 358 +++
  71. drivers/staging/fsl_ppfe/pfe_sysfs.c | 855 ++++++
  72. drivers/staging/fsl_ppfe/pfe_sysfs.h | 34 +
  73. drivers/staging/fsl_ppfe/platform.h | 25 +
  74. include/linux/skbuff.h | 11 +
  75. net/core/skbuff.c | 84 +
  76. 63 files changed, 14821 insertions(+)
  77. create mode 100644 drivers/staging/fsl_ppfe/Kconfig
  78. create mode 100644 drivers/staging/fsl_ppfe/Makefile
  79. create mode 100644 drivers/staging/fsl_ppfe/config.h
  80. create mode 100644 drivers/staging/fsl_ppfe/control_link.lds
  81. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus.h
  82. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
  83. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
  84. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/emac.h
  85. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
  86. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
  87. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/gpt.h
  88. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
  89. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
  90. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
  91. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
  92. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/class.h
  93. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/class/ccu.h
  94. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/class/efet.h
  95. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/class/mac_hash.h
  96. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/class/perg.h
  97. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/class/vlan_hash.h
  98. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/gpt.h
  99. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pe.h
  100. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pfe.h
  101. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/tmu.h
  102. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/tmu/phy_queue.h
  103. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/tmu/sched.h
  104. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/tmu/shaper.h
  105. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/uart.h
  106. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/util.h
  107. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/util/eape.h
  108. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/util/efet.h
  109. create mode 100644 drivers/staging/fsl_ppfe/include/pfe/util/inq.h
  110. create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.c
  111. create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.h
  112. create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl_hal.c
  113. create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl_hal.h
  114. create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.c
  115. create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.h
  116. create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.c
  117. create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.h
  118. create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.c
  119. create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.h
  120. create mode 100644 drivers/staging/fsl_ppfe/pfe_hal.c
  121. create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.c
  122. create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.h
  123. create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.c
  124. create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.h
  125. create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.c
  126. create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.h
  127. create mode 100644 drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
  128. create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.c
  129. create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.h
  130. create mode 100644 drivers/staging/fsl_ppfe/pfe_perfmon.c
  131. create mode 100644 drivers/staging/fsl_ppfe/pfe_perfmon.h
  132. create mode 100644 drivers/staging/fsl_ppfe/pfe_platform.c
  133. create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.c
  134. create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.h
  135. create mode 100644 drivers/staging/fsl_ppfe/platform.h
  136. --- a/drivers/staging/Kconfig
  137. +++ b/drivers/staging/Kconfig
  138. @@ -112,4 +112,6 @@ source "drivers/staging/wilc1000/Kconfig
  139. source "drivers/staging/most/Kconfig"
  140. +source "drivers/staging/fsl_ppfe/Kconfig"
  141. +
  142. endif # STAGING
  143. --- a/drivers/staging/Makefile
  144. +++ b/drivers/staging/Makefile
  145. @@ -48,3 +48,4 @@ obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/
  146. obj-$(CONFIG_FSL_DPA) += fsl_qbman/
  147. obj-$(CONFIG_WILC1000) += wilc1000/
  148. obj-$(CONFIG_MOST) += most/
  149. +obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/
  150. --- /dev/null
  151. +++ b/drivers/staging/fsl_ppfe/Kconfig
  152. @@ -0,0 +1,5 @@
  153. +config FSL_PPFE
  154. + tristate "Freescale PPFE Driver"
  155. + default m
  156. + help
  157. + only compiled as module !
  158. --- /dev/null
  159. +++ b/drivers/staging/fsl_ppfe/Makefile
  160. @@ -0,0 +1,44 @@
  161. +#
  162. +# Copyright (C) 2007 Freescale Semiconductor, Inc.
  163. +#
  164. +# This program is free software; you can redistribute it and/or modify
  165. +# it under the terms of the GNU General Public License as published by
  166. +# the Free Software Foundation; either version 2 of the License, or
  167. +# (at your option) any later version.
  168. +#
  169. +# This program is distributed in the hope that it will be useful,
  170. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  171. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  172. +# GNU General Public License for more details.
  173. +#
  174. +# You should have received a copy of the GNU General Public License
  175. +# along with this program; if not, write to the Free Software
  176. +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  177. +
  178. +
  179. +all: modules
  180. +
  181. +modules clean:
  182. + make CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) -C $(KERNELDIR) M=`pwd` $@
  183. +
  184. +EXTRA_CFLAGS += -I$(src)/include -I$(src) -DCOMCERTO_2000 -DCONFIG_PLATFORM_LS1012A -DGEMAC_MTIP -DCONFIG_UTIL_DISABLED
  185. +
  186. +EXTRA_LDFLAGS += -T$(srctree)/$(src)/control_link.lds
  187. +
  188. +#only compiled as module !
  189. +obj-$(CONFIG_FSL_PPFE) += pfe.o
  190. +
  191. +pfe-y += pfe_mod.o \
  192. + pfe_hw.o \
  193. + pfe_firmware.o \
  194. + pfe_ctrl.o \
  195. + pfe_ctrl_hal.o \
  196. + pfe_hif.o \
  197. + pfe_hif_lib.o\
  198. + pfe_eth.o \
  199. + pfe_perfmon.o \
  200. + pfe_sysfs.o \
  201. + pfe_debugfs.o \
  202. + pfe_ls1012a_platform.o \
  203. + pfe_hal.o \
  204. +
  205. --- /dev/null
  206. +++ b/drivers/staging/fsl_ppfe/config.h
  207. @@ -0,0 +1,8 @@
  208. +#ifndef _CONFIG_H_
  209. +#define _CONFIG_H_
  210. +#define CFG_WIFI_OFFLOAD (1 << 1)
  211. +#define CFG_ICC (1 << 11)
  212. +#define CFG_RTP (1 << 14)
  213. +#define CFG_ELLIPTIC (1 << 15)
  214. +#define CFG_ALL (0 | CFG_WIFI_OFFLOAD | CFG_ICC | CFG_RTP | CFG_ELLIPTIC )
  215. +#endif /* _CONFIG_H_ */
  216. --- /dev/null
  217. +++ b/drivers/staging/fsl_ppfe/control_link.lds
  218. @@ -0,0 +1,32 @@
  219. +/*
  220. + *
  221. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  222. + *
  223. + * This program is free software; you can redistribute it and/or modify
  224. + * it under the terms of the GNU General Public License as published by
  225. + * the Free Software Foundation; either version 2 of the License, or
  226. + * (at your option) any later version.
  227. + *
  228. + * This program is distributed in the hope that it will be useful,
  229. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  230. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  231. + * GNU General Public License for more details.
  232. + *
  233. + * You should have received a copy of the GNU General Public License
  234. + * along with this program; if not, write to the Free Software
  235. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  236. + */
  237. +
  238. +SECTIONS
  239. +{
  240. + .class_dmem_sh : SUBALIGN(8) {
  241. + __class_dmem_sh = .;
  242. + *(SORT(.class_dmem_sh_*))
  243. + }
  244. +
  245. + .tmu_dmem_sh : SUBALIGN(8) {
  246. + __tmu_dmem_sh = .;
  247. + *(SORT(.tmu_dmem_sh_*))
  248. + }
  249. +
  250. +}
  251. --- /dev/null
  252. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus.h
  253. @@ -0,0 +1,88 @@
  254. +/*
  255. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  256. + *
  257. + * This program is free software; you can redistribute it and/or
  258. + * modify it under the terms of the GNU General Public License
  259. + * as published by the Free Software Foundation; either version 2
  260. + * of the License, or (at your option) any later version.
  261. + *
  262. + * This program is distributed in the hope that it will be useful,
  263. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  264. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  265. + * GNU General Public License for more details.
  266. + *
  267. + * You should have received a copy of the GNU General Public License
  268. + * along with this program; if not, write to the Free Software
  269. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  270. + *
  271. +*/
  272. +#ifndef _CBUS_H_
  273. +#define _CBUS_H_
  274. +
  275. +#define EMAC1_BASE_ADDR (CBUS_BASE_ADDR + 0x200000)
  276. +#define EGPI1_BASE_ADDR (CBUS_BASE_ADDR + 0x210000)
  277. +#define EMAC2_BASE_ADDR (CBUS_BASE_ADDR + 0x220000)
  278. +#define EGPI2_BASE_ADDR (CBUS_BASE_ADDR + 0x230000)
  279. +#define BMU1_BASE_ADDR (CBUS_BASE_ADDR + 0x240000)
  280. +#define BMU2_BASE_ADDR (CBUS_BASE_ADDR + 0x250000)
  281. +#define ARB_BASE_ADDR (CBUS_BASE_ADDR + 0x260000) /* FIXME not documented */
  282. +#define DDR_CONFIG_BASE_ADDR (CBUS_BASE_ADDR + 0x270000) /* FIXME not documented */
  283. +#define HIF_BASE_ADDR (CBUS_BASE_ADDR + 0x280000)
  284. +#define HGPI_BASE_ADDR (CBUS_BASE_ADDR + 0x290000)
  285. +#define LMEM_BASE_ADDR (CBUS_BASE_ADDR + 0x300000)
  286. +#define LMEM_SIZE 0x10000
  287. +#define LMEM_END (LMEM_BASE_ADDR + LMEM_SIZE)
  288. +#define TMU_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x310000)
  289. +#define CLASS_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x320000)
  290. +#if defined(CONFIG_PLATFORM_C2000)
  291. +#define EMAC3_BASE_ADDR (CBUS_BASE_ADDR + 0x330000)
  292. +#define EGPI3_BASE_ADDR (CBUS_BASE_ADDR + 0x340000)
  293. +#endif
  294. +#define HIF_NOCPY_BASE_ADDR (CBUS_BASE_ADDR + 0x350000)
  295. +#define UTIL_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x360000)
  296. +#define CBUS_GPT_BASE_ADDR (CBUS_BASE_ADDR + 0x370000)
  297. +
  298. +#define IS_LMEM(addr, len) (((unsigned long)(addr) >= (unsigned long)LMEM_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= (unsigned long)LMEM_END))
  299. +
  300. +/**
  301. +* \defgroup XXX_MEM_ACCESS_ADDR PE memory access through CSR
  302. +* XXX_MEM_ACCESS_ADDR register bit definitions.
  303. +* @{
  304. +*/
  305. +#define PE_MEM_ACCESS_WRITE (1<<31) /**< Internal Memory Write. */
  306. +#define PE_MEM_ACCESS_IMEM (1<<15)
  307. +#define PE_MEM_ACCESS_DMEM (1<<16)
  308. +#define PE_MEM_ACCESS_BYTE_ENABLE(offset,size) (((((1 << (size)) - 1) << (4 - (offset) - (size))) & 0xf) << 24) /**< Byte Enables of the Internal memory access. These are interpred in BE */
  309. +// @}
  310. +#if defined(CONFIG_PLATFORM_LS1012A)
  311. +#include "cbus/emac_mtip.h"
  312. +#else
  313. +#include "cbus/emac.h"
  314. +#endif //CONFIG_PLATFORM_LS1012A
  315. +#include "cbus/gpi.h"
  316. +#include "cbus/bmu.h"
  317. +#include "cbus/hif.h"
  318. +#include "cbus/tmu_csr.h"
  319. +#include "cbus/class_csr.h"
  320. +#include "cbus/hif_nocpy.h"
  321. +#include "cbus/util_csr.h"
  322. +#include "cbus/gpt.h"
  323. +
  324. +
  325. +/* PFE cores states */
  326. +#define CORE_DISABLE 0x00000000
  327. +#define CORE_ENABLE 0x00000001
  328. +#define CORE_SW_RESET 0x00000002
  329. +
  330. +/* LMEM defines */
  331. +#define LMEM_HDR_SIZE 0x0010
  332. +#define LMEM_BUF_SIZE_LN2 0x7
  333. +#define LMEM_BUF_SIZE (1 << LMEM_BUF_SIZE_LN2)
  334. +
  335. +/* DDR defines */
  336. +#define DDR_HDR_SIZE 0x0100
  337. +#define DDR_BUF_SIZE_LN2 0xb
  338. +#define DDR_BUF_SIZE (1 << DDR_BUF_SIZE_LN2)
  339. +
  340. +
  341. +#endif /* _CBUS_H_ */
  342. --- /dev/null
  343. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
  344. @@ -0,0 +1,55 @@
  345. +/*
  346. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  347. + *
  348. + * This program is free software; you can redistribute it and/or
  349. + * modify it under the terms of the GNU General Public License
  350. + * as published by the Free Software Foundation; either version 2
  351. + * of the License, or (at your option) any later version.
  352. + *
  353. + * This program is distributed in the hope that it will be useful,
  354. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  355. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  356. + * GNU General Public License for more details.
  357. + *
  358. + * You should have received a copy of the GNU General Public License
  359. + * along with this program; if not, write to the Free Software
  360. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  361. + *
  362. +*/
  363. +#ifndef _BMU_H_
  364. +#define _BMU_H_
  365. +
  366. +#define BMU_VERSION 0x000
  367. +#define BMU_CTRL 0x004
  368. +#define BMU_UCAST_CONFIG 0x008
  369. +#define BMU_UCAST_BASE_ADDR 0x00c
  370. +#define BMU_BUF_SIZE 0x010
  371. +#define BMU_BUF_CNT 0x014
  372. +#define BMU_THRES 0x018
  373. +#define BMU_INT_SRC 0x020
  374. +#define BMU_INT_ENABLE 0x024
  375. +#define BMU_ALLOC_CTRL 0x030
  376. +#define BMU_FREE_CTRL 0x034
  377. +#define BMU_FREE_ERR_ADDR 0x038
  378. +#define BMU_CURR_BUF_CNT 0x03c
  379. +#define BMU_MCAST_CNT 0x040
  380. +#define BMU_MCAST_ALLOC_CTRL 0x044
  381. +#define BMU_REM_BUF_CNT 0x048
  382. +#define BMU_LOW_WATERMARK 0x050
  383. +#define BMU_HIGH_WATERMARK 0x054
  384. +#define BMU_INT_MEM_ACCESS 0x100
  385. +
  386. +typedef struct {
  387. + unsigned long baseaddr;
  388. + u32 count;
  389. + u32 size;
  390. +} BMU_CFG;
  391. +
  392. +
  393. +#define BMU1_BUF_SIZE LMEM_BUF_SIZE_LN2
  394. +#define BMU2_BUF_SIZE DDR_BUF_SIZE_LN2
  395. +
  396. +#define BMU2_MCAST_ALLOC_CTRL BMU2_BASE_ADDR + BMU_MCAST_ALLOC_CTRL
  397. +
  398. +#endif /* _BMU_H_ */
  399. +
  400. --- /dev/null
  401. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
  402. @@ -0,0 +1,242 @@
  403. +/*
  404. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  405. + *
  406. + * This program is free software; you can redistribute it and/or
  407. + * modify it under the terms of the GNU General Public License
  408. + * as published by the Free Software Foundation; either version 2
  409. + * of the License, or (at your option) any later version.
  410. + *
  411. + * This program is distributed in the hope that it will be useful,
  412. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  413. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  414. + * GNU General Public License for more details.
  415. + *
  416. + * You should have received a copy of the GNU General Public License
  417. + * along with this program; if not, write to the Free Software
  418. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  419. + *
  420. +*/
  421. +#ifndef _CLASS_CSR_H_
  422. +#define _CLASS_CSR_H_
  423. +
  424. +/** @file class_csr.h.
  425. + * class_csr - block containing all the classifier control and status register. Mapped on CBUS and accessible from all PE's and ARM.
  426. + */
  427. +
  428. +
  429. +#define CLASS_VERSION (CLASS_CSR_BASE_ADDR + 0x000)
  430. +#define CLASS_TX_CTRL (CLASS_CSR_BASE_ADDR + 0x004)
  431. +#define CLASS_INQ_PKTPTR (CLASS_CSR_BASE_ADDR + 0x010)
  432. +#define CLASS_HDR_SIZE (CLASS_CSR_BASE_ADDR + 0x014) /**< (ddr_hdr_size[24:16], lmem_hdr_size[5:0]) */
  433. +#define CLASS_HDR_SIZE_LMEM(off) ((off) & 0x3f) /**< LMEM header size for the Classifier block.\ Data in the LMEM is written from this offset. */
  434. +#define CLASS_HDR_SIZE_DDR(off) (((off) & 0x1ff) << 16) /**< DDR header size for the Classifier block.\ Data in the DDR is written from this offset. */
  435. +
  436. +#define CLASS_PE0_QB_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x020) /**< DMEM address of first [15:0] and second [31:16] buffers on QB side. */
  437. +#define CLASS_PE0_QB_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x024) /**< DMEM address of third [15:0] and fourth [31:16] buffers on QB side. */
  438. +
  439. +#define CLASS_PE0_RO_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x060) /**< DMEM address of first [15:0] and second [31:16] buffers on RO side. */
  440. +#define CLASS_PE0_RO_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x064) /**< DMEM address of third [15:0] and fourth [31:16] buffers on RO side. */
  441. +
  442. +/** @name Class PE memory access. Allows external PE's and HOST to read/write PMEM/DMEM memory ranges for each classifier PE.
  443. + */
  444. +//@{
  445. +#define CLASS_MEM_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x100) /**< {sr_pe_mem_cmd[31], csr_pe_mem_wren[27:24], csr_pe_mem_addr[23:0]}, See \ref XXX_MEM_ACCESS_ADDR for details. */
  446. +#define CLASS_MEM_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x104) /**< Internal Memory Access Write Data [31:0] */
  447. +#define CLASS_MEM_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x108) /**< Internal Memory Access Read Data [31:0] */
  448. +//@}
  449. +#define CLASS_TM_INQ_ADDR (CLASS_CSR_BASE_ADDR + 0x114)
  450. +#define CLASS_PE_STATUS (CLASS_CSR_BASE_ADDR + 0x118)
  451. +
  452. +#define CLASS_PHY1_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x11c)
  453. +#define CLASS_PHY1_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x120)
  454. +#define CLASS_PHY1_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x124)
  455. +#define CLASS_PHY1_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x128)
  456. +#define CLASS_PHY1_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x12c)
  457. +#define CLASS_PHY1_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x130)
  458. +#define CLASS_PHY1_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x134)
  459. +#define CLASS_PHY1_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x138)
  460. +#define CLASS_PHY1_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x13c)
  461. +#define CLASS_PHY1_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x140)
  462. +#define CLASS_PHY2_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x144)
  463. +#define CLASS_PHY2_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x148)
  464. +#define CLASS_PHY2_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x14c)
  465. +#define CLASS_PHY2_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x150)
  466. +#define CLASS_PHY2_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x154)
  467. +#define CLASS_PHY2_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x158)
  468. +#define CLASS_PHY2_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x15c)
  469. +#define CLASS_PHY2_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x160)
  470. +#define CLASS_PHY2_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x164)
  471. +#define CLASS_PHY2_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x168)
  472. +#define CLASS_PHY3_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x16c)
  473. +#define CLASS_PHY3_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x170)
  474. +#define CLASS_PHY3_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x174)
  475. +#define CLASS_PHY3_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x178)
  476. +#define CLASS_PHY3_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x17c)
  477. +#define CLASS_PHY3_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x180)
  478. +#define CLASS_PHY3_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x184)
  479. +#define CLASS_PHY3_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x188)
  480. +#define CLASS_PHY3_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x18c)
  481. +#define CLASS_PHY3_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x190)
  482. +#define CLASS_PHY1_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x194)
  483. +#define CLASS_PHY1_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x198)
  484. +#define CLASS_PHY1_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x19c)
  485. +#define CLASS_PHY1_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a0)
  486. +#define CLASS_PHY2_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a4)
  487. +#define CLASS_PHY2_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a8)
  488. +#define CLASS_PHY2_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1ac)
  489. +#define CLASS_PHY2_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b0)
  490. +#define CLASS_PHY3_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b4)
  491. +#define CLASS_PHY3_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b8)
  492. +#define CLASS_PHY3_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1bc)
  493. +#define CLASS_PHY3_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c0)
  494. +#define CLASS_PHY4_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c4)
  495. +#define CLASS_PHY4_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c8)
  496. +#define CLASS_PHY4_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1cc)
  497. +#define CLASS_PHY4_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1d0)
  498. +#define CLASS_PHY4_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d4)
  499. +#define CLASS_PHY4_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d8)
  500. +#define CLASS_PHY4_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1dc)
  501. +#define CLASS_PHY4_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e0)
  502. +#define CLASS_PHY4_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x1e4)
  503. +#define CLASS_PHY4_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e8)
  504. +#define CLASS_PHY4_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x1ec)
  505. +#define CLASS_PHY4_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x1f0)
  506. +#define CLASS_PHY4_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f4)
  507. +#define CLASS_PHY4_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f8)
  508. +
  509. +#define CLASS_PE_SYS_CLK_RATIO (CLASS_CSR_BASE_ADDR + 0x200)
  510. +#define CLASS_AFULL_THRES (CLASS_CSR_BASE_ADDR + 0x204)
  511. +#define CLASS_GAP_BETWEEN_READS (CLASS_CSR_BASE_ADDR + 0x208)
  512. +#define CLASS_MAX_BUF_CNT (CLASS_CSR_BASE_ADDR + 0x20c)
  513. +#define CLASS_TSQ_FIFO_THRES (CLASS_CSR_BASE_ADDR + 0x210)
  514. +#define CLASS_TSQ_MAX_CNT (CLASS_CSR_BASE_ADDR + 0x214)
  515. +#define CLASS_IRAM_DATA_0 (CLASS_CSR_BASE_ADDR + 0x218)
  516. +#define CLASS_IRAM_DATA_1 (CLASS_CSR_BASE_ADDR + 0x21c)
  517. +#define CLASS_IRAM_DATA_2 (CLASS_CSR_BASE_ADDR + 0x220)
  518. +#define CLASS_IRAM_DATA_3 (CLASS_CSR_BASE_ADDR + 0x224)
  519. +
  520. +#define CLASS_BUS_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x228)
  521. +
  522. +#define CLASS_BUS_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x22c)
  523. +#define CLASS_BUS_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x230)
  524. +
  525. +#define CLASS_ROUTE_HASH_ENTRY_SIZE (CLASS_CSR_BASE_ADDR + 0x234) /**< (route_entry_size[9:0], route_hash_size[23:16] (this is actually ln2(size))) */
  526. +#define CLASS_ROUTE_ENTRY_SIZE(size) ((size) & 0x1ff)
  527. +#define CLASS_ROUTE_HASH_SIZE(hash_bits) (((hash_bits) & 0xff) << 16)
  528. +
  529. +#define CLASS_ROUTE_TABLE_BASE (CLASS_CSR_BASE_ADDR + 0x238)
  530. +
  531. +#define CLASS_ROUTE_MULTI (CLASS_CSR_BASE_ADDR + 0x23c)
  532. +#define CLASS_SMEM_OFFSET (CLASS_CSR_BASE_ADDR + 0x240)
  533. +#define CLASS_LMEM_BUF_SIZE (CLASS_CSR_BASE_ADDR + 0x244)
  534. +#define CLASS_VLAN_ID (CLASS_CSR_BASE_ADDR + 0x248)
  535. +#define CLASS_BMU1_BUF_FREE (CLASS_CSR_BASE_ADDR + 0x24c)
  536. +#define CLASS_USE_TMU_INQ (CLASS_CSR_BASE_ADDR + 0x250)
  537. +#define CLASS_VLAN_ID1 (CLASS_CSR_BASE_ADDR + 0x254)
  538. +
  539. +#define CLASS_BUS_ACCESS_BASE (CLASS_CSR_BASE_ADDR + 0x258)
  540. +#define CLASS_BUS_ACCESS_BASE_MASK (0xFF000000) //bit 31:24 of PE peripheral address are stored in CLASS_BUS_ACCESS_BASE
  541. +
  542. +#define CLASS_HIF_PARSE (CLASS_CSR_BASE_ADDR + 0x25c)
  543. +
  544. +#define CLASS_HOST_PE0_GP (CLASS_CSR_BASE_ADDR + 0x260)
  545. +#define CLASS_PE0_GP (CLASS_CSR_BASE_ADDR + 0x264)
  546. +#define CLASS_HOST_PE1_GP (CLASS_CSR_BASE_ADDR + 0x268)
  547. +#define CLASS_PE1_GP (CLASS_CSR_BASE_ADDR + 0x26c)
  548. +#define CLASS_HOST_PE2_GP (CLASS_CSR_BASE_ADDR + 0x270)
  549. +#define CLASS_PE2_GP (CLASS_CSR_BASE_ADDR + 0x274)
  550. +#define CLASS_HOST_PE3_GP (CLASS_CSR_BASE_ADDR + 0x278)
  551. +#define CLASS_PE3_GP (CLASS_CSR_BASE_ADDR + 0x27c)
  552. +#define CLASS_HOST_PE4_GP (CLASS_CSR_BASE_ADDR + 0x280)
  553. +#define CLASS_PE4_GP (CLASS_CSR_BASE_ADDR + 0x284)
  554. +#define CLASS_HOST_PE5_GP (CLASS_CSR_BASE_ADDR + 0x288)
  555. +#define CLASS_PE5_GP (CLASS_CSR_BASE_ADDR + 0x28c)
  556. +
  557. +#define CLASS_PE_INT_SRC (CLASS_CSR_BASE_ADDR + 0x290)
  558. +#define CLASS_PE_INT_ENABLE (CLASS_CSR_BASE_ADDR + 0x294)
  559. +
  560. +#define CLASS_TPID0_TPID1 (CLASS_CSR_BASE_ADDR + 0x298)
  561. +#define CLASS_TPID2 (CLASS_CSR_BASE_ADDR + 0x29c)
  562. +
  563. +#define CLASS_L4_CHKSUM_ADDR (CLASS_CSR_BASE_ADDR + 0x2a0)
  564. +
  565. +#define CLASS_PE0_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a4)
  566. +#define CLASS_PE1_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a8)
  567. +#define CLASS_PE2_DEBUG (CLASS_CSR_BASE_ADDR + 0x2ac)
  568. +#define CLASS_PE3_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b0)
  569. +#define CLASS_PE4_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b4)
  570. +#define CLASS_PE5_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b8)
  571. +
  572. +#define CLASS_STATE (CLASS_CSR_BASE_ADDR + 0x2bc)
  573. +
  574. +/* CLASS defines */
  575. +#define CLASS_PBUF_SIZE 0x100 /* Fixed by hardware */
  576. +#define CLASS_PBUF_HEADER_OFFSET 0x80 /* Can be configured */
  577. +
  578. +#define CLASS_PBUF0_BASE_ADDR 0x000 /* Can be configured */
  579. +#define CLASS_PBUF1_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_SIZE) /* Can be configured */
  580. +#define CLASS_PBUF2_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_SIZE) /* Can be configured */
  581. +#define CLASS_PBUF3_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_SIZE) /* Can be configured */
  582. +
  583. +#define CLASS_PBUF0_HEADER_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_HEADER_OFFSET)
  584. +#define CLASS_PBUF1_HEADER_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_HEADER_OFFSET)
  585. +#define CLASS_PBUF2_HEADER_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_HEADER_OFFSET)
  586. +#define CLASS_PBUF3_HEADER_BASE_ADDR (CLASS_PBUF3_BASE_ADDR + CLASS_PBUF_HEADER_OFFSET)
  587. +
  588. +#define CLASS_PE0_RO_DM_ADDR0_VAL ((CLASS_PBUF1_BASE_ADDR << 16) | CLASS_PBUF0_BASE_ADDR)
  589. +#define CLASS_PE0_RO_DM_ADDR1_VAL ((CLASS_PBUF3_BASE_ADDR << 16) | CLASS_PBUF2_BASE_ADDR)
  590. +
  591. +#define CLASS_PE0_QB_DM_ADDR0_VAL ((CLASS_PBUF1_HEADER_BASE_ADDR << 16) | CLASS_PBUF0_HEADER_BASE_ADDR)
  592. +#define CLASS_PE0_QB_DM_ADDR1_VAL ((CLASS_PBUF3_HEADER_BASE_ADDR << 16) | CLASS_PBUF2_HEADER_BASE_ADDR)
  593. +
  594. +#define CLASS_ROUTE_SIZE 128
  595. +#define CLASS_MAX_ROUTE_SIZE 256
  596. +#define CLASS_ROUTE_HASH_BITS 20
  597. +#define CLASS_ROUTE_HASH_MASK ((1 << CLASS_ROUTE_HASH_BITS) - 1)
  598. +
  599. +#define CLASS_ROUTE0_BASE_ADDR 0x400 /* Can be configured */
  600. +#define CLASS_ROUTE1_BASE_ADDR (CLASS_ROUTE0_BASE_ADDR + CLASS_ROUTE_SIZE) /* Can be configured */
  601. +#define CLASS_ROUTE2_BASE_ADDR (CLASS_ROUTE1_BASE_ADDR + CLASS_ROUTE_SIZE) /* Can be configured */
  602. +#define CLASS_ROUTE3_BASE_ADDR (CLASS_ROUTE2_BASE_ADDR + CLASS_ROUTE_SIZE) /* Can be configured */
  603. +
  604. +#define CLASS_SA_SIZE 128
  605. +#define CLASS_IPSEC_SA0_BASE_ADDR 0x600
  606. +#define CLASS_IPSEC_SA1_BASE_ADDR (CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE) /* not used */
  607. +#define CLASS_IPSEC_SA2_BASE_ADDR (CLASS_IPSEC_SA1_BASE_ADDR + CLASS_SA_SIZE) /* not used */
  608. +#define CLASS_IPSEC_SA3_BASE_ADDR (CLASS_IPSEC_SA2_BASE_ADDR + CLASS_SA_SIZE) /* not used */
  609. +
  610. +/* generic purpose free dmem buffer, last portion of 2K dmem pbuf */
  611. +#define CLASS_GP_DMEM_BUF_SIZE (2048 - (CLASS_PBUF_SIZE*4) - (CLASS_ROUTE_SIZE*4) - (CLASS_SA_SIZE))
  612. +#define CLASS_GP_DMEM_BUF ((void *)(CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE))
  613. +
  614. +
  615. +#define TWO_LEVEL_ROUTE (1 << 0)
  616. +#define PHYNO_IN_HASH (1 << 1)
  617. +#define HW_ROUTE_FETCH (1 << 3)
  618. +#define HW_BRIDGE_FETCH (1 << 5)
  619. +#define IP_ALIGNED (1 << 6)
  620. +#define ARC_HIT_CHECK_EN (1 << 7)
  621. +#define CLASS_TOE (1 << 11)
  622. +#define HASH_NORMAL (0 << 12)
  623. +#define HASH_CRC_PORT (1 << 12)
  624. +#define HASH_CRC_IP (2 << 12)
  625. +#define HASH_CRC_PORT_IP (3 << 12)
  626. +#define QB2BUS_LE (1 << 15)
  627. +
  628. +#define TCP_CHKSUM_DROP (1 << 0)
  629. +#define UDP_CHKSUM_DROP (1 << 1)
  630. +#define IPV4_CHKSUM_DROP (1 << 9)
  631. +
  632. +/*CLASS_HIF_PARSE bits*/
  633. +#define HIF_PKT_CLASS_EN (1 << 0)
  634. +#define HIF_PKT_OFFSET(ofst) ((ofst&0xF) << 1)
  635. +
  636. +typedef struct {
  637. + u32 toe_mode;
  638. + unsigned long route_table_baseaddr;
  639. + u32 route_table_hash_bits;
  640. + u32 pe_sys_clk_ratio;
  641. + u32 resume;
  642. +} CLASS_CFG;
  643. +
  644. +#endif /* _CLASS_CSR_H_ */
  645. --- /dev/null
  646. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/emac.h
  647. @@ -0,0 +1,243 @@
  648. +/*
  649. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  650. + *
  651. + * This program is free software; you can redistribute it and/or
  652. + * modify it under the terms of the GNU General Public License
  653. + * as published by the Free Software Foundation; either version 2
  654. + * of the License, or (at your option) any later version.
  655. + *
  656. + * This program is distributed in the hope that it will be useful,
  657. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  658. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  659. + * GNU General Public License for more details.
  660. + *
  661. + * You should have received a copy of the GNU General Public License
  662. + * along with this program; if not, write to the Free Software
  663. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  664. + *
  665. +*/
  666. +#ifndef _EMAC_H_
  667. +#define _EMAC_H_
  668. +
  669. +#define EMAC_NETWORK_CONTROL 0x000
  670. +#define EMAC_NETWORK_CONFIG 0x004
  671. +#define EMAC_NETWORK_STATUS 0x008
  672. +#define EMAC_DMA_CONFIG 0x010
  673. +
  674. +#define EMAC_PHY_MANAGEMENT 0x034
  675. +
  676. +#define EMAC_HASH_BOT 0x080
  677. +#define EMAC_HASH_TOP 0x084
  678. +
  679. +#define EMAC_SPEC1_ADD_BOT 0x088
  680. +#define EMAC_SPEC1_ADD_TOP 0x08c
  681. +#define EMAC_SPEC2_ADD_BOT 0x090
  682. +#define EMAC_SPEC2_ADD_TOP 0x094
  683. +#define EMAC_SPEC3_ADD_BOT 0x098
  684. +#define EMAC_SPEC3_ADD_TOP 0x09c
  685. +#define EMAC_SPEC4_ADD_BOT 0x0a0
  686. +#define EMAC_SPEC4_ADD_TOP 0x0a4
  687. +#define EMAC_WOL 0x0b8
  688. +
  689. +#define EMAC_STACKED_VLAN_REG 0x0c0
  690. +
  691. +#define EMAC_SPEC1_ADD_MASK_BOT 0x0c8
  692. +#define EMAC_SPEC1_ADD_MASK_TOP 0x0cc
  693. +
  694. +#define EMAC_RMON_BASE_OFST 0x100
  695. +
  696. +#define EMAC_SPEC5_ADD_BOT 0x300
  697. +#define EMAC_SPEC5_ADD_TOP 0x304
  698. +#define EMAC_SPEC6_ADD_BOT 0x308
  699. +#define EMAC_SPEC6_ADD_TOP 0x30c
  700. +#define EMAC_SPEC7_ADD_BOT 0x310
  701. +#define EMAC_SPEC7_ADD_TOP 0x314
  702. +#define EMAC_SPEC8_ADD_BOT 0x318
  703. +#define EMAC_SPEC8_ADD_TOP 0x31c
  704. +#define EMAC_SPEC9_ADD_BOT 0x320
  705. +#define EMAC_SPEC9_ADD_TOP 0x324
  706. +#define EMAC_SPEC10_ADD_BOT 0x328
  707. +#define EMAC_SPEC10_ADD_TOP 0x32c
  708. +#define EMAC_SPEC11_ADD_BOT 0x330
  709. +#define EMAC_SPEC11_ADD_TOP 0x334
  710. +#define EMAC_SPEC12_ADD_BOT 0x338
  711. +#define EMAC_SPEC12_ADD_TOP 0x33c
  712. +#define EMAC_SPEC13_ADD_BOT 0x340
  713. +#define EMAC_SPEC13_ADD_TOP 0x344
  714. +#define EMAC_SPEC14_ADD_BOT 0x348
  715. +#define EMAC_SPEC14_ADD_TOP 0x34c
  716. +#define EMAC_SPEC15_ADD_BOT 0x350
  717. +#define EMAC_SPEC15_ADD_TOP 0x354
  718. +#define EMAC_SPEC16_ADD_BOT 0x358
  719. +#define EMAC_SPEC16_ADD_TOP 0x35c
  720. +#define EMAC_SPEC17_ADD_BOT 0x360
  721. +#define EMAC_SPEC17_ADD_TOP 0x364
  722. +#define EMAC_SPEC18_ADD_BOT 0x368
  723. +#define EMAC_SPEC18_ADD_TOP 0x36c
  724. +#define EMAC_SPEC19_ADD_BOT 0x370
  725. +#define EMAC_SPEC19_ADD_TOP 0x374
  726. +#define EMAC_SPEC20_ADD_BOT 0x378
  727. +#define EMAC_SPEC20_ADD_TOP 0x37c
  728. +#define EMAC_SPEC21_ADD_BOT 0x380
  729. +#define EMAC_SPEC21_ADD_TOP 0x384
  730. +#define EMAC_SPEC22_ADD_BOT 0x388
  731. +#define EMAC_SPEC22_ADD_TOP 0x38c
  732. +#define EMAC_SPEC23_ADD_BOT 0x390
  733. +#define EMAC_SPEC23_ADD_TOP 0x394
  734. +#define EMAC_SPEC24_ADD_BOT 0x398
  735. +#define EMAC_SPEC24_ADD_TOP 0x39c
  736. +#define EMAC_SPEC25_ADD_BOT 0x3a0
  737. +#define EMAC_SPEC25_ADD_TOP 0x3a4
  738. +#define EMAC_SPEC26_ADD_BOT 0x3a8
  739. +#define EMAC_SPEC26_ADD_TOP 0x3ac
  740. +#define EMAC_SPEC27_ADD_BOT 0x3b0
  741. +#define EMAC_SPEC27_ADD_TOP 0x3b4
  742. +#define EMAC_SPEC28_ADD_BOT 0x3b8
  743. +#define EMAC_SPEC28_ADD_TOP 0x3bc
  744. +#define EMAC_SPEC29_ADD_BOT 0x3c0
  745. +#define EMAC_SPEC29_ADD_TOP 0x3c4
  746. +#define EMAC_SPEC30_ADD_BOT 0x3c8
  747. +#define EMAC_SPEC30_ADD_TOP 0x3cc
  748. +#define EMAC_SPEC31_ADD_BOT 0x3d0
  749. +#define EMAC_SPEC31_ADD_TOP 0x3d4
  750. +#define EMAC_SPEC32_ADD_BOT 0x3d8
  751. +#define EMAC_SPEC32_ADD_TOP 0x3dc
  752. +
  753. +#define EMAC_SPEC_ADDR_MAX 32
  754. +
  755. +#define EMAC_CONTROL 0x7a0
  756. +
  757. +/* GEMAC definitions and settings */
  758. +
  759. +#define EMAC_PORT_0 0
  760. +#define EMAC_PORT_1 1
  761. +#define EMAC_PORT_2 2
  762. +
  763. +/* The possible operating speeds of the MAC, currently supporting 10, 100 and
  764. + * 1000Mb modes.
  765. + */
  766. +typedef enum {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS} MAC_SPEED;
  767. +
  768. +#define GMII 1
  769. +#define MII 2
  770. +#define RMII 3
  771. +#define RGMII 4
  772. +#define SGMII 5
  773. +
  774. +#define DUP_HALF 0x00
  775. +#define DUP_FULL 0x01
  776. +
  777. +/* EMAC_NETWORK_CONTROL bits definition */
  778. +#define EMAC_LB_PHY (1 << 0)
  779. +#define EMAC_LB_MAC (1 << 1)
  780. +#define EMAC_RX_ENABLE (1 << 2)
  781. +#define EMAC_TX_ENABLE (1 << 3)
  782. +#define EMAC_MDIO_EN (1 << 4) /* Enable MDIO port */
  783. +
  784. +/* WoL (Wake on Lan bit definition) */
  785. +#define EMAC_WOL_MAGIC (1 << 16)
  786. +#define EMAC_WOL_ARP (1 << 17)
  787. +#define EMAC_WOL_SPEC_ADDR (1 << 18)
  788. +#define EMAC_WOL_MULTI (1 << 19)
  789. +
  790. +/* EMAC_NETWORK_CONFIG bits definition */
  791. +#define EMAC_SPEED_100 (1 << 0)
  792. +#define EMAC_HALF_DUP (0 << 1)
  793. +#define EMAC_FULL_DUP (1 << 1)
  794. +#define EMAC_DUPLEX_MASK (1 << 1)
  795. +#define EMAC_ENABLE_JUMBO_FRAME (1 << 3)
  796. +#define EMAC_ENABLE_COPY_ALL (1 << 4)
  797. +#define EMAC_NO_BROADCAST (1 << 5)
  798. +#define EMAC_ENABLE_MULTICAST (1 << 6)
  799. +#define EMAC_ENABLE_UNICAST (1 << 7)
  800. +#define EMAC_ENABLE_1536_RX (1 << 8)
  801. +#define EMAC_SPEED_1000 (1 << 10)
  802. +#define EMAC_PCS_ENABLE (1 << 11)
  803. +#define EMAC_ENABLE_PAUSE_RX (1 << 13)
  804. +#define EMAC_REMOVE_FCS (1 << 17)
  805. +#define EMAC_ENABLE_CHKSUM_RX (1 << 24)
  806. +#define EMAC_MDC_DIV_MASK (0x7 << 18) /* PCLK divisor for MDC */
  807. +#define EMAC_DATA_BUS_WIDTH_SHIFT 21
  808. +#define EMAC_DATA_BUS_WIDTH_MASK (0x3 << EMAC_DATA_BUS_WIDTH_SHIFT)
  809. +#define EMAC_DATA_BUS_WIDTH_32 (0x00 << EMAC_DATA_BUS_WIDTH_SHIFT)
  810. +#define EMAC_DATA_BUS_WIDTH_64 (0x01 << EMAC_DATA_BUS_WIDTH_SHIFT)
  811. +#define EMAC_DATA_BUS_WIDTH_128 (0x10 << EMAC_DATA_BUS_WIDTH_SHIFT)
  812. +#define EMAC_ENABLE_FCS_RX (1 << 26)
  813. +#define EMAC_SGMII_MODE_ENABLE (1 << 27)
  814. +
  815. +#define EMAC_SPEED_MASK (EMAC_SPEED_100 | EMAC_SPEED_1000)
  816. +
  817. +/* EMAC_STACKED_VLAN_REG bits definition */
  818. +#define EMAC_ENABLE_STACKED_VLAN (1 << 31)
  819. +
  820. +/* EMAC_CONTROL bits definition */
  821. +#define EMAC_TWO_BYTES_IP_ALIGN (1 << 0) // two bytes IP alignement
  822. +
  823. +/* EMAC_NET_STATUS bits definition */
  824. +#define EMAC_PHY_IDLE (1<<2) /* PHY management is idle */
  825. +#define EMAC_MDIO_IN (1<<1) /* Status of mdio_in pin */
  826. +#define EMAC_LINK_STATUS (1<<0) /* Status of link pin */
  827. +
  828. +/* EMAC_DMA_CONFIG Bit definitions */
  829. +#define EMAC_ENABLE_CHKSUM_TX (1<<11)
  830. +
  831. +//RMII enable – bit 1 / RGMII enable – bit 2
  832. +#define EMAC_RMII_MODE_ENABLE ((1 << 1) | (0 << 2))
  833. +#define EMAC_RMII_MODE_DISABLE (0 << 1)
  834. +#define EMAC_RGMII_MODE_ENABLE ((0 << 1) | (1 << 2))
  835. +#define EMAC_RGMII_MODE_DISABLE (0 << 2)
  836. +#define EMAC_MII_MODE_ENABLE (EMAC_RMII_MODE_DISABLE | EMAC_RGMII_MODE_DISABLE)
  837. +#define EMAC_GMII_MODE_ENABLE (EMAC_RMII_MODE_DISABLE | EMAC_RGMII_MODE_DISABLE)
  838. +#define EMAC_MODE_MASK (0x3 << 1)
  839. +
  840. +/* Default configuration */
  841. +#define EMAC0_DEFAULT_DUPLEX_MODE FULLDUPLEX
  842. +#define EMAC0_DEFAULT_EMAC_MODE RGMII
  843. +#define EMAC0_DEFAULT_EMAC_SPEED SPEED_1000M
  844. +
  845. +#define EMAC1_DEFAULT_DUPLEX_MODE FULLDUPLEX
  846. +#define EMAC1_DEFAULT_EMAC_MODE RGMII
  847. +#define EMAC1_DEFAULT_EMAC_SPEED SPEED_1000M
  848. +
  849. +#define EMAC2_DEFAULT_DUPLEX_MODE FULLDUPLEX
  850. +#define EMAC2_DEFAULT_EMAC_MODE RGMII
  851. +#define EMAC2_DEFAULT_EMAC_SPEED SPEED_1000M
  852. +
  853. +/* EMAC Hash size */
  854. +#define EMAC_HASH_REG_BITS 64
  855. +
  856. +/* The Address organisation for the MAC device. All addresses are split into
  857. + * two 32-bit register fields. The first one (bottom) is the lower 32-bits of
  858. + * the address and the other field are the high order bits - this may be 16-bits
  859. + * in the case of MAC addresses, or 32-bits for the hash address.
  860. + * In terms of memory storage, the first item (bottom) is assumed to be at a
  861. + * lower address location than 'top'. i.e. top should be at address location of
  862. + * 'bottom' + 4 bytes.
  863. + */
  864. +typedef struct {
  865. + u32 bottom; /* Lower 32-bits of address. */
  866. + u32 top; /* Upper 32-bits of address. */
  867. +} MAC_ADDR;
  868. +
  869. +
  870. +/* The following is the organisation of the address filters section of the MAC
  871. + * registers. The Cadence MAC contains four possible specific address match
  872. + * addresses, if an incoming frame corresponds to any one of these four
  873. + * addresses then the frame will be copied to memory.
  874. + * It is not necessary for all four of the address match registers to be
  875. + * programmed, this is application dependant.
  876. + */
  877. +typedef struct {
  878. + MAC_ADDR one; /* Specific address register 1. */
  879. + MAC_ADDR two; /* Specific address register 2. */
  880. + MAC_ADDR three; /* Specific address register 3. */
  881. + MAC_ADDR four; /* Specific address register 4. */
  882. +} SPEC_ADDR;
  883. +
  884. +typedef struct {
  885. + u32 mode;
  886. + u32 speed;
  887. + u32 duplex;
  888. +} GEMAC_CFG;
  889. +
  890. +#endif /* _EMAC_H_ */
  891. --- /dev/null
  892. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
  893. @@ -0,0 +1,250 @@
  894. +/*
  895. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  896. + *
  897. + * This program is free software; you can redistribute it and/or
  898. + * modify it under the terms of the GNU General Public License
  899. + * as published by the Free Software Foundation; either version 2
  900. + * of the License, or (at your option) any later version.
  901. + *
  902. + * This program is distributed in the hope that it will be useful,
  903. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  904. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  905. + * GNU General Public License for more details.
  906. + *
  907. + * You should have received a copy of the GNU General Public License
  908. + * along with this program; if not, write to the Free Software
  909. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  910. + *
  911. +*/
  912. +#ifndef _EMAC_H_
  913. +#define _EMAC_H_
  914. +
  915. +#define EMAC_IEVENT_REG 0x004
  916. +#define EMAC_IMASK_REG 0x008
  917. +#define EMAC_R_DES_ACTIVE_REG 0x010
  918. +#define EMAC_X_DES_ACTIVE_REG 0x014
  919. +#define EMAC_ECNTRL_REG 0x024
  920. +#define EMAC_MII_DATA_REG 0x040
  921. +#define EMAC_MII_CTRL_REG 0x044
  922. +#define EMAC_MIB_CTRL_STS_REG 0x064
  923. +#define EMAC_RCNTRL_REG 0x084
  924. +#define EMAC_TCNTRL_REG 0x0C4
  925. +#define EMAC_PHY_ADDR_LOW 0x0E4
  926. +#define EMAC_PHY_ADDR_HIGH 0x0E8
  927. +#define EMAC_GAUR 0x120
  928. +#define EMAC_GALR 0x124
  929. +#define EMAC_TFWR_STR_FWD 0x144
  930. +#define EMAC_RX_SECTIOM_FULL 0x190
  931. +#define EMAC_TX_SECTION_EMPTY 0x1A0
  932. +#define EMAC_TRUNC_FL 0x1B0
  933. +
  934. +#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */
  935. +#define RMON_T_PACKETS 0x204 /* RMON TX packet count */
  936. +#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */
  937. +#define RMON_T_MC_PKT 0x20c /* RMON TX multicast pkts */
  938. +#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */
  939. +#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */
  940. +#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */
  941. +#define RMON_T_FRAG 0x21c /* RMON TX pkts < 64 bytes, bad CRC */
  942. +#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */
  943. +#define RMON_T_COL 0x224 /* RMON TX collision count */
  944. +#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */
  945. +#define RMON_T_P65TO127 0x22c /* RMON TX 65 to 127 byte pkts */
  946. +#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */
  947. +#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */
  948. +#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */
  949. +#define RMON_T_P1024TO2047 0x23c /* RMON TX 1024 to 2047 byte pkts */
  950. +#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */
  951. +#define RMON_T_OCTETS 0x244 /* RMON TX octets */
  952. +#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */
  953. +#define IEEE_T_FRAME_OK 0x24c /* Frames tx'd OK */
  954. +#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */
  955. +#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */
  956. +#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */
  957. +#define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */
  958. +#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */
  959. +#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */
  960. +#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */
  961. +#define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */
  962. +#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */
  963. +#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */
  964. +#define RMON_R_PACKETS 0x284 /* RMON RX packet count */
  965. +#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */
  966. +#define RMON_R_MC_PKT 0x28c /* RMON RX multicast pkts */
  967. +#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */
  968. +#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */
  969. +#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */
  970. +#define RMON_R_FRAG 0x29c /* RMON RX pkts < 64 bytes, bad CRC */
  971. +#define RMON_R_JAB 0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */
  972. +#define RMON_R_RESVD_O 0x2a4 /* Reserved */
  973. +#define RMON_R_P64 0x2a8 /* RMON RX 64 byte pkts */
  974. +#define RMON_R_P65TO127 0x2ac /* RMON RX 65 to 127 byte pkts */
  975. +#define RMON_R_P128TO255 0x2b0 /* RMON RX 128 to 255 byte pkts */
  976. +#define RMON_R_P256TO511 0x2b4 /* RMON RX 256 to 511 byte pkts */
  977. +#define RMON_R_P512TO1023 0x2b8 /* RMON RX 512 to 1023 byte pkts */
  978. +#define RMON_R_P1024TO2047 0x2bc /* RMON RX 1024 to 2047 byte pkts */
  979. +#define RMON_R_P_GTE2048 0x2c0 /* RMON RX pkts > 2048 bytes */
  980. +#define RMON_R_OCTETS 0x2c4 /* RMON RX octets */
  981. +#define IEEE_R_DROP 0x2c8 /* Count frames not counted correctly */
  982. +#define IEEE_R_FRAME_OK 0x2cc /* Frames rx'd OK */
  983. +#define IEEE_R_CRC 0x2d0 /* Frames rx'd with CRC err */
  984. +#define IEEE_R_ALIGN 0x2d4 /* Frames rx'd with alignment err */
  985. +#define IEEE_R_MACERR 0x2d8 /* Receive FIFO overflow count */
  986. +#define IEEE_R_FDXFC 0x2dc /* Flow control pause frames rx'd */
  987. +#define IEEE_R_OCTETS_OK 0x2e0 /* Octet cnt for frames rx'd w/o err */
  988. +
  989. +#define EMAC_SMAC_0_0 0x500 /*Supplemental MAC Address 0 (RW).*/
  990. +#define EMAC_SMAC_0_1 0x504 /*Supplemental MAC Address 0 (RW).*/
  991. +
  992. +/* GEMAC definitions and settings */
  993. +
  994. +#define EMAC_PORT_0 0
  995. +#define EMAC_PORT_1 1
  996. +
  997. +/* GEMAC Bit definitions */
  998. +#define EMAC_IEVENT_HBERR 0x80000000
  999. +#define EMAC_IEVENT_BABR 0x40000000
  1000. +#define EMAC_IEVENT_BABT 0x20000000
  1001. +#define EMAC_IEVENT_GRA 0x10000000
  1002. +#define EMAC_IEVENT_TXF 0x08000000
  1003. +#define EMAC_IEVENT_TXB 0x04000000
  1004. +#define EMAC_IEVENT_RXF 0x02000000
  1005. +#define EMAC_IEVENT_RXB 0x01000000
  1006. +#define EMAC_IEVENT_MII 0x00800000
  1007. +#define EMAC_IEVENT_EBERR 0x00400000
  1008. +#define EMAC_IEVENT_LC 0x00200000
  1009. +#define EMAC_IEVENT_RL 0x00100000
  1010. +#define EMAC_IEVENT_UN 0x00080000
  1011. +
  1012. +#define EMAC_IMASK_HBERR 0x80000000
  1013. +#define EMAC_IMASK_BABR 0x40000000
  1014. +#define EMAC_IMASKT_BABT 0x20000000
  1015. +#define EMAC_IMASK_GRA 0x10000000
  1016. +#define EMAC_IMASKT_TXF 0x08000000
  1017. +#define EMAC_IMASK_TXB 0x04000000
  1018. +#define EMAC_IMASKT_RXF 0x02000000
  1019. +#define EMAC_IMASK_RXB 0x01000000
  1020. +#define EMAC_IMASK_MII 0x00800000
  1021. +#define EMAC_IMASK_EBERR 0x00400000
  1022. +#define EMAC_IMASK_LC 0x00200000
  1023. +#define EMAC_IMASKT_RL 0x00100000
  1024. +#define EMAC_IMASK_UN 0x00080000
  1025. +
  1026. +#define EMAC_RCNTRL_MAX_FL_SHIFT 16
  1027. +#define EMAC_RCNTRL_LOOP 0x00000001
  1028. +#define EMAC_RCNTRL_DRT 0x00000002
  1029. +#define EMAC_RCNTRL_MII_MODE 0x00000004
  1030. +#define EMAC_RCNTRL_PROM 0x00000008
  1031. +#define EMAC_RCNTRL_BC_REJ 0x00000010
  1032. +#define EMAC_RCNTRL_FCE 0x00000020
  1033. +#define EMAC_RCNTRL_RGMII 0x00000040
  1034. +#define EMAC_RCNTRL_SGMII 0x00000080
  1035. +#define EMAC_RCNTRL_RMII 0x00000100
  1036. +#define EMAC_RCNTRL_RMII_10T 0x00000200
  1037. +#define EMAC_RCNTRL_CRC_FWD 0x00004000
  1038. +
  1039. +#define EMAC_TCNTRL_GTS 0x00000001
  1040. +#define EMAC_TCNTRL_HBC 0x00000002
  1041. +#define EMAC_TCNTRL_FDEN 0x00000004
  1042. +#define EMAC_TCNTRL_TFC_PAUSE 0x00000008
  1043. +#define EMAC_TCNTRL_RFC_PAUSE 0x00000010
  1044. +
  1045. +#define EMAC_ECNTRL_RESET 0x00000001 /* reset the EMAC */
  1046. +#define EMAC_ECNTRL_ETHER_EN 0x00000002 /* enable the EMAC */
  1047. +#define EMAC_ECNTRL_SPEED 0x00000020
  1048. +#define EMAC_ECNTRL_DBSWAP 0x00000100
  1049. +
  1050. +#define EMAC_X_WMRK_STRFWD 0x00000100
  1051. +
  1052. +#define EMAC_X_DES_ACTIVE_TDAR 0x01000000
  1053. +#define EMAC_R_DES_ACTIVE_RDAR 0x01000000
  1054. +
  1055. +
  1056. +
  1057. +/* The possible operating speeds of the MAC, currently supporting 10, 100 and
  1058. + * 1000Mb modes.
  1059. + */
  1060. +typedef enum {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS} MAC_SPEED;
  1061. +
  1062. +#define GMII 1
  1063. +#define MII 2
  1064. +#define RMII 3
  1065. +#define RGMII 4
  1066. +#define SGMII 5
  1067. +
  1068. +#define DUPLEX_HALF 0x00
  1069. +#define DUPLEX_FULL 0x01
  1070. +
  1071. +
  1072. +/* Default configuration */
  1073. +#define EMAC0_DEFAULT_DUPLEX_MODE FULLDUPLEX
  1074. +#define EMAC0_DEFAULT_EMAC_MODE RGMII
  1075. +#define EMAC0_DEFAULT_EMAC_SPEED SPEED_1000M
  1076. +
  1077. +#define EMAC1_DEFAULT_DUPLEX_MODE FULLDUPLEX
  1078. +#define EMAC1_DEFAULT_EMAC_MODE SGMII
  1079. +#define EMAC1_DEFAULT_EMAC_SPEED SPEED_1000M
  1080. +
  1081. +/* MII-related definitios */
  1082. +#define EMAC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */
  1083. +#define EMAC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */
  1084. +#define EMAC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */
  1085. +#define EMAC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */
  1086. +#define EMAC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */
  1087. +#define EMAC_MII_DATA_TA 0x00020000 /* Turnaround */
  1088. +#define EMAC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */
  1089. +
  1090. +#define EMAC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */
  1091. +#define EMAC_MII_DATA_RA_MASK 0x1F /* MII Register address mask */
  1092. +#define EMAC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */
  1093. +#define EMAC_MII_DATA_PA_MASK 0x1F /* MII PHY address mask */
  1094. +
  1095. +#define EMAC_MII_DATA_RA(v) ((v & EMAC_MII_DATA_RA_MASK) << EMAC_MII_DATA_RA_SHIFT)
  1096. +#define EMAC_MII_DATA_PA(v) ((v & EMAC_MII_DATA_RA_MASK) << EMAC_MII_DATA_PA_SHIFT)
  1097. +#define EMAC_MII_DATA(v) (v & 0xffff)
  1098. +
  1099. +#define EMAC_MII_SPEED_SHIFT 1
  1100. +#define EMAC_HOLDTIME_SHIFT 8
  1101. +#define EMAC_HOLDTIME_MASK 0x7
  1102. +#define EMAC_HOLDTIME(v) ((v & EMAC_HOLDTIME_MASK) << EMAC_HOLDTIME_SHIFT)
  1103. +
  1104. +/* The Address organisation for the MAC device. All addresses are split into
  1105. + * two 32-bit register fields. The first one (bottom) is the lower 32-bits of
  1106. + * the address and the other field are the high order bits - this may be 16-bits
  1107. + * in the case of MAC addresses, or 32-bits for the hash address.
  1108. + * In terms of memory storage, the first item (bottom) is assumed to be at a
  1109. + * lower address location than 'top'. i.e. top should be at address location of
  1110. + * 'bottom' + 4 bytes.
  1111. + */
  1112. +typedef struct {
  1113. + u32 bottom; /* Lower 32-bits of address. */
  1114. + u32 top; /* Upper 32-bits of address. */
  1115. +} MAC_ADDR;
  1116. +
  1117. +
  1118. +/* The following is the organisation of the address filters section of the MAC
  1119. + * registers. The Cadence MAC contains four possible specific address match
  1120. + * addresses, if an incoming frame corresponds to any one of these four
  1121. + * addresses then the frame will be copied to memory.
  1122. + * It is not necessary for all four of the address match registers to be
  1123. + * programmed, this is application dependant.
  1124. + */
  1125. +typedef struct {
  1126. + MAC_ADDR one; /* Specific address register 1. */
  1127. + MAC_ADDR two; /* Specific address register 2. */
  1128. + MAC_ADDR three; /* Specific address register 3. */
  1129. + MAC_ADDR four; /* Specific address register 4. */
  1130. +} SPEC_ADDR;
  1131. +
  1132. +typedef struct {
  1133. + u32 mode;
  1134. + u32 speed;
  1135. + u32 duplex;
  1136. +} GEMAC_CFG;
  1137. +
  1138. +/* EMAC Hash size */
  1139. +#define EMAC_HASH_REG_BITS 64
  1140. +
  1141. +#define EMAC_SPEC_ADDR_MAX 4
  1142. +
  1143. +#endif /* _EMAC_H_ */
  1144. --- /dev/null
  1145. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
  1146. @@ -0,0 +1,78 @@
  1147. +/*
  1148. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1149. + *
  1150. + * This program is free software; you can redistribute it and/or
  1151. + * modify it under the terms of the GNU General Public License
  1152. + * as published by the Free Software Foundation; either version 2
  1153. + * of the License, or (at your option) any later version.
  1154. + *
  1155. + * This program is distributed in the hope that it will be useful,
  1156. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1157. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1158. + * GNU General Public License for more details.
  1159. + *
  1160. + * You should have received a copy of the GNU General Public License
  1161. + * along with this program; if not, write to the Free Software
  1162. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1163. + *
  1164. +*/
  1165. +#ifndef _GPI_H_
  1166. +#define _GPI_H_
  1167. +
  1168. +#define GPI_VERSION 0x00
  1169. +#define GPI_CTRL 0x04
  1170. +#define GPI_RX_CONFIG 0x08
  1171. +#define GPI_HDR_SIZE 0x0c
  1172. +#define GPI_BUF_SIZE 0x10
  1173. +#define GPI_LMEM_ALLOC_ADDR 0x14
  1174. +#define GPI_LMEM_FREE_ADDR 0x18
  1175. +#define GPI_DDR_ALLOC_ADDR 0x1c
  1176. +#define GPI_DDR_FREE_ADDR 0x20
  1177. +#define GPI_CLASS_ADDR 0x24
  1178. +#define GPI_DRX_FIFO 0x28
  1179. +#define GPI_TRX_FIFO 0x2c
  1180. +#define GPI_INQ_PKTPTR 0x30
  1181. +#define GPI_DDR_DATA_OFFSET 0x34
  1182. +#define GPI_LMEM_DATA_OFFSET 0x38
  1183. +#define GPI_TMLF_TX 0x4c
  1184. +#define GPI_DTX_ASEQ 0x50
  1185. +#define GPI_FIFO_STATUS 0x54
  1186. +#define GPI_FIFO_DEBUG 0x58
  1187. +#define GPI_TX_PAUSE_TIME 0x5c
  1188. +#define GPI_LMEM_SEC_BUF_DATA_OFFSET 0x60
  1189. +#define GPI_DDR_SEC_BUF_DATA_OFFSET 0x64
  1190. +#define GPI_TOE_CHKSUM_EN 0x68
  1191. +#define GPI_OVERRUN_DROPCNT 0x6c
  1192. +
  1193. +typedef struct {
  1194. + u32 lmem_rtry_cnt;
  1195. + u32 tmlf_txthres;
  1196. + u32 aseq_len;
  1197. +} GPI_CFG;
  1198. +
  1199. +
  1200. +/* GPI commons defines */
  1201. +#define GPI_LMEM_BUF_EN 0x1
  1202. +#define GPI_DDR_BUF_EN 0x1
  1203. +
  1204. +/* EGPI 1 defines */
  1205. +#define EGPI1_LMEM_RTRY_CNT 0x40
  1206. +#define EGPI1_TMLF_TXTHRES 0xBC
  1207. +#define EGPI1_ASEQ_LEN 0x50
  1208. +
  1209. +/* EGPI 2 defines */
  1210. +#define EGPI2_LMEM_RTRY_CNT 0x40
  1211. +#define EGPI2_TMLF_TXTHRES 0xBC
  1212. +#define EGPI2_ASEQ_LEN 0x40
  1213. +
  1214. +/* EGPI 3 defines */
  1215. +#define EGPI3_LMEM_RTRY_CNT 0x40
  1216. +#define EGPI3_TMLF_TXTHRES 0xBC
  1217. +#define EGPI3_ASEQ_LEN 0x40
  1218. +
  1219. +/* HGPI defines */
  1220. +#define HGPI_LMEM_RTRY_CNT 0x40
  1221. +#define HGPI_TMLF_TXTHRES 0xBC
  1222. +#define HGPI_ASEQ_LEN 0x40
  1223. +
  1224. +#endif /* _GPI_H_ */
  1225. --- /dev/null
  1226. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/gpt.h
  1227. @@ -0,0 +1,29 @@
  1228. +/*
  1229. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1230. + *
  1231. + * This program is free software; you can redistribute it and/or
  1232. + * modify it under the terms of the GNU General Public License
  1233. + * as published by the Free Software Foundation; either version 2
  1234. + * of the License, or (at your option) any later version.
  1235. + *
  1236. + * This program is distributed in the hope that it will be useful,
  1237. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1238. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1239. + * GNU General Public License for more details.
  1240. + *
  1241. + * You should have received a copy of the GNU General Public License
  1242. + * along with this program; if not, write to the Free Software
  1243. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1244. + *
  1245. +*/
  1246. +#ifndef _CBUS_GPT_H_
  1247. +#define _CBUS_GPT_H_
  1248. +
  1249. +#define CBUS_GPT_VERSION (CBUS_GPT_BASE_ADDR + 0x00)
  1250. +#define CBUS_GPT_STATUS (CBUS_GPT_BASE_ADDR + 0x04)
  1251. +#define CBUS_GPT_CONFIG (CBUS_GPT_BASE_ADDR + 0x08)
  1252. +#define CBUS_GPT_COUNTER (CBUS_GPT_BASE_ADDR + 0x0c)
  1253. +#define CBUS_GPT_PERIOD (CBUS_GPT_BASE_ADDR + 0x10)
  1254. +#define CBUS_GPT_WIDTH (CBUS_GPT_BASE_ADDR + 0x14)
  1255. +
  1256. +#endif /* _CBUS_GPT_H_ */
  1257. --- /dev/null
  1258. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
  1259. @@ -0,0 +1,96 @@
  1260. +/*
  1261. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1262. + *
  1263. + * This program is free software; you can redistribute it and/or
  1264. + * modify it under the terms of the GNU General Public License
  1265. + * as published by the Free Software Foundation; either version 2
  1266. + * of the License, or (at your option) any later version.
  1267. + *
  1268. + * This program is distributed in the hope that it will be useful,
  1269. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1270. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1271. + * GNU General Public License for more details.
  1272. + *
  1273. + * You should have received a copy of the GNU General Public License
  1274. + * along with this program; if not, write to the Free Software
  1275. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1276. + *
  1277. +*/
  1278. +#ifndef _HIF_H_
  1279. +#define _HIF_H_
  1280. +
  1281. +/** @file hif.h.
  1282. + * hif - PFE hif block control and status register. Mapped on CBUS and accessible from all PE's and ARM.
  1283. + */
  1284. +#define HIF_VERSION (HIF_BASE_ADDR + 0x00)
  1285. +#define HIF_TX_CTRL (HIF_BASE_ADDR + 0x04)
  1286. +#define HIF_TX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x08)
  1287. +#define HIF_TX_ALLOC (HIF_BASE_ADDR + 0x0c)
  1288. +#define HIF_TX_BDP_ADDR (HIF_BASE_ADDR + 0x10)
  1289. +#define HIF_TX_STATUS (HIF_BASE_ADDR + 0x14)
  1290. +#define HIF_RX_CTRL (HIF_BASE_ADDR + 0x20)
  1291. +#define HIF_RX_BDP_ADDR (HIF_BASE_ADDR + 0x24)
  1292. +#define HIF_RX_STATUS (HIF_BASE_ADDR + 0x30)
  1293. +#define HIF_INT_SRC (HIF_BASE_ADDR + 0x34)
  1294. +#define HIF_INT_ENABLE (HIF_BASE_ADDR + 0x38)
  1295. +#define HIF_POLL_CTRL (HIF_BASE_ADDR + 0x3c)
  1296. +#define HIF_RX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x40)
  1297. +#define HIF_RX_ALLOC (HIF_BASE_ADDR + 0x44)
  1298. +#define HIF_TX_DMA_STATUS (HIF_BASE_ADDR + 0x48)
  1299. +#define HIF_RX_DMA_STATUS (HIF_BASE_ADDR + 0x4c)
  1300. +#define HIF_INT_COAL (HIF_BASE_ADDR + 0x50)
  1301. +
  1302. +/*HIF_INT_SRC/ HIF_INT_ENABLE control bits */
  1303. +#define HIF_INT (1 << 0)
  1304. +#define HIF_RXBD_INT (1 << 1)
  1305. +#define HIF_RXPKT_INT (1 << 2)
  1306. +#define HIF_TXBD_INT (1 << 3)
  1307. +#define HIF_TXPKT_INT (1 << 4)
  1308. +
  1309. +/*HIF_TX_CTRL bits */
  1310. +#define HIF_CTRL_DMA_EN (1<<0)
  1311. +#define HIF_CTRL_BDP_POLL_CTRL_EN (1<<1)
  1312. +#define HIF_CTRL_BDP_CH_START_WSTB (1<<2)
  1313. +
  1314. +/*HIF_INT_ENABLE bits */
  1315. +#define HIF_INT_EN (1 << 0)
  1316. +#define HIF_RXBD_INT_EN (1 << 1)
  1317. +#define HIF_RXPKT_INT_EN (1 << 2)
  1318. +#define HIF_TXBD_INT_EN (1 << 3)
  1319. +#define HIF_TXPKT_INT_EN (1 << 4)
  1320. +
  1321. +/*HIF_POLL_CTRL bits*/
  1322. +#define HIF_RX_POLL_CTRL_CYCLE 0x0400
  1323. +#define HIF_TX_POLL_CTRL_CYCLE 0x0400
  1324. +
  1325. +/*HIF_INT_COAL bits*/
  1326. +#define HIF_INT_COAL_ENABLE (1 << 31)
  1327. +
  1328. +/*Buffer descriptor control bits */
  1329. +#define BD_CTRL_BUFLEN_MASK 0x3fff
  1330. +#define BD_BUF_LEN(x) (x & BD_CTRL_BUFLEN_MASK)
  1331. +#define BD_CTRL_CBD_INT_EN (1 << 16)
  1332. +#define BD_CTRL_PKT_INT_EN (1 << 17)
  1333. +#define BD_CTRL_LIFM (1 << 18)
  1334. +#define BD_CTRL_LAST_BD (1 << 19)
  1335. +#define BD_CTRL_DIR (1 << 20)
  1336. +#define BD_CTRL_LMEM_CPY (1 << 21) /*Valid only for HIF_NOCPY*/
  1337. +#define BD_CTRL_PKT_XFER (1 << 24)
  1338. +#define BD_CTRL_DESC_EN (1 << 31)
  1339. +#define BD_CTRL_PARSE_DISABLE (1 << 25)
  1340. +#define BD_CTRL_BRFETCH_DISABLE (1 << 26)
  1341. +#define BD_CTRL_RTFETCH_DISABLE (1 << 27)
  1342. +
  1343. +/*Buffer descriptor status bits*/
  1344. +#define BD_STATUS_CONN_ID(x) ((x) & 0xffff)
  1345. +#define BD_STATUS_DIR_PROC_ID (1 << 16)
  1346. +#define BD_STATUS_CONN_ID_EN (1 << 17))
  1347. +#define BD_STATUS_PE2PROC_ID(x) (((x) & 7) << 18)
  1348. +#define BD_STATUS_LE_DATA (1 << 21)
  1349. +#define BD_STATUS_CHKSUM_EN (1 << 22)
  1350. +
  1351. +/*HIF Buffer descriptor status bits */
  1352. +#define DIR_PROC_ID (1 << 16)
  1353. +#define PROC_ID(id) ((id) << 18)
  1354. +
  1355. +#endif /* _HIF_H_ */
  1356. --- /dev/null
  1357. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
  1358. @@ -0,0 +1,51 @@
  1359. +/*
  1360. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1361. + *
  1362. + * This program is free software; you can redistribute it and/or
  1363. + * modify it under the terms of the GNU General Public License
  1364. + * as published by the Free Software Foundation; either version 2
  1365. + * of the License, or (at your option) any later version.
  1366. + *
  1367. + * This program is distributed in the hope that it will be useful,
  1368. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1369. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1370. + * GNU General Public License for more details.
  1371. + *
  1372. + * You should have received a copy of the GNU General Public License
  1373. + * along with this program; if not, write to the Free Software
  1374. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1375. + *
  1376. +*/
  1377. +#ifndef _HIF_NOCPY_H_
  1378. +#define _HIF_NOCPY_H_
  1379. +
  1380. +#define HIF_NOCPY_VERSION (HIF_NOCPY_BASE_ADDR + 0x00)
  1381. +#define HIF_NOCPY_TX_CTRL (HIF_NOCPY_BASE_ADDR + 0x04)
  1382. +#define HIF_NOCPY_TX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x08)
  1383. +#define HIF_NOCPY_TX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x0c)
  1384. +#define HIF_NOCPY_TX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x10)
  1385. +#define HIF_NOCPY_TX_STATUS (HIF_NOCPY_BASE_ADDR + 0x14)
  1386. +#define HIF_NOCPY_RX_CTRL (HIF_NOCPY_BASE_ADDR + 0x20)
  1387. +#define HIF_NOCPY_RX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x24)
  1388. +#define HIF_NOCPY_RX_STATUS (HIF_NOCPY_BASE_ADDR + 0x30)
  1389. +#define HIF_NOCPY_INT_SRC (HIF_NOCPY_BASE_ADDR + 0x34)
  1390. +#define HIF_NOCPY_INT_ENABLE (HIF_NOCPY_BASE_ADDR + 0x38)
  1391. +#define HIF_NOCPY_POLL_CTRL (HIF_NOCPY_BASE_ADDR + 0x3c)
  1392. +#define HIF_NOCPY_RX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x40)
  1393. +#define HIF_NOCPY_RX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x44)
  1394. +#define HIF_NOCPY_TX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x48)
  1395. +#define HIF_NOCPY_RX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x4c)
  1396. +#define HIF_NOCPY_RX_INQ0_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x50)
  1397. +#define HIF_NOCPY_RX_INQ1_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x54)
  1398. +#define HIF_NOCPY_TX_PORT_NO (HIF_NOCPY_BASE_ADDR + 0x60)
  1399. +#define HIF_NOCPY_LMEM_ALLOC_ADDR (HIF_NOCPY_BASE_ADDR + 0x64)
  1400. +#define HIF_NOCPY_CLASS_ADDR (HIF_NOCPY_BASE_ADDR + 0x68)
  1401. +#define HIF_NOCPY_TMU_PORT0_ADDR (HIF_NOCPY_BASE_ADDR + 0x70)
  1402. +#define HIF_NOCPY_TMU_PORT1_ADDR (HIF_NOCPY_BASE_ADDR + 0x74)
  1403. +#define HIF_NOCPY_TMU_PORT2_ADDR (HIF_NOCPY_BASE_ADDR + 0x7c)
  1404. +#define HIF_NOCPY_TMU_PORT3_ADDR (HIF_NOCPY_BASE_ADDR + 0x80)
  1405. +#define HIF_NOCPY_TMU_PORT4_ADDR (HIF_NOCPY_BASE_ADDR + 0x84)
  1406. +#define HIF_NOCPY_INT_COAL (HIF_NOCPY_BASE_ADDR + 0x90)
  1407. +
  1408. +
  1409. +#endif /* _HIF_NOCPY_H_ */
  1410. --- /dev/null
  1411. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
  1412. @@ -0,0 +1,128 @@
  1413. +/*
  1414. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1415. + *
  1416. + * This program is free software; you can redistribute it and/or
  1417. + * modify it under the terms of the GNU General Public License
  1418. + * as published by the Free Software Foundation; either version 2
  1419. + * of the License, or (at your option) any later version.
  1420. + *
  1421. + * This program is distributed in the hope that it will be useful,
  1422. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1423. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1424. + * GNU General Public License for more details.
  1425. + *
  1426. + * You should have received a copy of the GNU General Public License
  1427. + * along with this program; if not, write to the Free Software
  1428. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1429. + *
  1430. +*/
  1431. +#ifndef _TMU_CSR_H_
  1432. +#define _TMU_CSR_H_
  1433. +
  1434. +#define TMU_VERSION (TMU_CSR_BASE_ADDR + 0x000)
  1435. +#define TMU_INQ_WATERMARK (TMU_CSR_BASE_ADDR + 0x004)
  1436. +#define TMU_PHY_INQ_PKTPTR (TMU_CSR_BASE_ADDR + 0x008)
  1437. +#define TMU_PHY_INQ_PKTINFO (TMU_CSR_BASE_ADDR + 0x00c)
  1438. +#define TMU_PHY_INQ_FIFO_CNT (TMU_CSR_BASE_ADDR + 0x010)
  1439. +#define TMU_SYS_GENERIC_CONTROL (TMU_CSR_BASE_ADDR + 0x014)
  1440. +#define TMU_SYS_GENERIC_STATUS (TMU_CSR_BASE_ADDR + 0x018)
  1441. +#define TMU_SYS_GEN_CON0 (TMU_CSR_BASE_ADDR + 0x01c)
  1442. +#define TMU_SYS_GEN_CON1 (TMU_CSR_BASE_ADDR + 0x020)
  1443. +#define TMU_SYS_GEN_CON2 (TMU_CSR_BASE_ADDR + 0x024)
  1444. +#define TMU_SYS_GEN_CON3 (TMU_CSR_BASE_ADDR + 0x028)
  1445. +#define TMU_SYS_GEN_CON4 (TMU_CSR_BASE_ADDR + 0x02c)
  1446. +#define TMU_TEQ_DISABLE_DROPCHK (TMU_CSR_BASE_ADDR + 0x030)
  1447. +#define TMU_TEQ_CTRL (TMU_CSR_BASE_ADDR + 0x034)
  1448. +#define TMU_TEQ_QCFG (TMU_CSR_BASE_ADDR + 0x038)
  1449. +#define TMU_TEQ_DROP_STAT (TMU_CSR_BASE_ADDR + 0x03c)
  1450. +#define TMU_TEQ_QAVG (TMU_CSR_BASE_ADDR + 0x040)
  1451. +#define TMU_TEQ_WREG_PROB (TMU_CSR_BASE_ADDR + 0x044)
  1452. +#define TMU_TEQ_TRANS_STAT (TMU_CSR_BASE_ADDR + 0x048)
  1453. +#define TMU_TEQ_HW_PROB_CFG0 (TMU_CSR_BASE_ADDR + 0x04c)
  1454. +#define TMU_TEQ_HW_PROB_CFG1 (TMU_CSR_BASE_ADDR + 0x050)
  1455. +#define TMU_TEQ_HW_PROB_CFG2 (TMU_CSR_BASE_ADDR + 0x054)
  1456. +#define TMU_TEQ_HW_PROB_CFG3 (TMU_CSR_BASE_ADDR + 0x058)
  1457. +#define TMU_TEQ_HW_PROB_CFG4 (TMU_CSR_BASE_ADDR + 0x05c)
  1458. +#define TMU_TEQ_HW_PROB_CFG5 (TMU_CSR_BASE_ADDR + 0x060)
  1459. +#define TMU_TEQ_HW_PROB_CFG6 (TMU_CSR_BASE_ADDR + 0x064)
  1460. +#define TMU_TEQ_HW_PROB_CFG7 (TMU_CSR_BASE_ADDR + 0x068)
  1461. +#define TMU_TEQ_HW_PROB_CFG8 (TMU_CSR_BASE_ADDR + 0x06c)
  1462. +#define TMU_TEQ_HW_PROB_CFG9 (TMU_CSR_BASE_ADDR + 0x070)
  1463. +#define TMU_TEQ_HW_PROB_CFG10 (TMU_CSR_BASE_ADDR + 0x074)
  1464. +#define TMU_TEQ_HW_PROB_CFG11 (TMU_CSR_BASE_ADDR + 0x078)
  1465. +#define TMU_TEQ_HW_PROB_CFG12 (TMU_CSR_BASE_ADDR + 0x07c)
  1466. +#define TMU_TEQ_HW_PROB_CFG13 (TMU_CSR_BASE_ADDR + 0x080)
  1467. +#define TMU_TEQ_HW_PROB_CFG14 (TMU_CSR_BASE_ADDR + 0x084)
  1468. +#define TMU_TEQ_HW_PROB_CFG15 (TMU_CSR_BASE_ADDR + 0x088)
  1469. +#define TMU_TEQ_HW_PROB_CFG16 (TMU_CSR_BASE_ADDR + 0x08c)
  1470. +#define TMU_TEQ_HW_PROB_CFG17 (TMU_CSR_BASE_ADDR + 0x090)
  1471. +#define TMU_TEQ_HW_PROB_CFG18 (TMU_CSR_BASE_ADDR + 0x094)
  1472. +#define TMU_TEQ_HW_PROB_CFG19 (TMU_CSR_BASE_ADDR + 0x098)
  1473. +#define TMU_TEQ_HW_PROB_CFG20 (TMU_CSR_BASE_ADDR + 0x09c)
  1474. +#define TMU_TEQ_HW_PROB_CFG21 (TMU_CSR_BASE_ADDR + 0x0a0)
  1475. +#define TMU_TEQ_HW_PROB_CFG22 (TMU_CSR_BASE_ADDR + 0x0a4)
  1476. +#define TMU_TEQ_HW_PROB_CFG23 (TMU_CSR_BASE_ADDR + 0x0a8)
  1477. +#define TMU_TEQ_HW_PROB_CFG24 (TMU_CSR_BASE_ADDR + 0x0ac)
  1478. +#define TMU_TEQ_HW_PROB_CFG25 (TMU_CSR_BASE_ADDR + 0x0b0)
  1479. +#define TMU_TDQ_IIFG_CFG (TMU_CSR_BASE_ADDR + 0x0b4)
  1480. +#define TMU_TDQ0_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x0b8) /**< [9:0] Scheduler Enable for each of the scheduler in the TDQ. This is a global Enable for all schedulers in PHY0 */
  1481. +#define TMU_LLM_CTRL (TMU_CSR_BASE_ADDR + 0x0bc)
  1482. +#define TMU_LLM_BASE_ADDR (TMU_CSR_BASE_ADDR + 0x0c0)
  1483. +#define TMU_LLM_QUE_LEN (TMU_CSR_BASE_ADDR + 0x0c4)
  1484. +#define TMU_LLM_QUE_HEADPTR (TMU_CSR_BASE_ADDR + 0x0c8)
  1485. +#define TMU_LLM_QUE_TAILPTR (TMU_CSR_BASE_ADDR + 0x0cc)
  1486. +#define TMU_LLM_QUE_DROPCNT (TMU_CSR_BASE_ADDR + 0x0d0)
  1487. +#define TMU_INT_EN (TMU_CSR_BASE_ADDR + 0x0d4)
  1488. +#define TMU_INT_SRC (TMU_CSR_BASE_ADDR + 0x0d8)
  1489. +#define TMU_INQ_STAT (TMU_CSR_BASE_ADDR + 0x0dc)
  1490. +#define TMU_CTRL (TMU_CSR_BASE_ADDR + 0x0e0)
  1491. +
  1492. +#define TMU_MEM_ACCESS_ADDR (TMU_CSR_BASE_ADDR + 0x0e4) /**< [31] Mem Access Command. 0 = Internal Memory Read, 1 = Internal memory Write [27:24] Byte Enables of the Internal memory access [23:0] Address of the internal memory. This address is used to access both the PM and DM of all the PE's */
  1493. +#define TMU_MEM_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x0e8) /**< Internal Memory Access Write Data */
  1494. +#define TMU_MEM_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x0ec) /**< Internal Memory Access Read Data. The commands are blocked at the mem_access only */
  1495. +
  1496. +#define TMU_PHY0_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f0) /**< [31:0] PHY0 in queue address (must be initialized with one of the xxx_INQ_PKTPTR cbus addresses) */
  1497. +#define TMU_PHY1_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f4) /**< [31:0] PHY1 in queue address (must be initialized with one of the xxx_INQ_PKTPTR cbus addresses) */
  1498. +#define TMU_PHY2_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f8) /**< [31:0] PHY2 in queue address (must be initialized with one of the xxx_INQ_PKTPTR cbus addresses) */
  1499. +#define TMU_PHY3_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0fc) /**< [31:0] PHY3 in queue address (must be initialized with one of the xxx_INQ_PKTPTR cbus addresses) */
  1500. +#define TMU_BMU_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x100)
  1501. +#define TMU_TX_CTRL (TMU_CSR_BASE_ADDR + 0x104)
  1502. +
  1503. +#define TMU_BUS_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x108)
  1504. +#define TMU_BUS_ACCESS (TMU_CSR_BASE_ADDR + 0x10c)
  1505. +#define TMU_BUS_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x110)
  1506. +
  1507. +#define TMU_PE_SYS_CLK_RATIO (TMU_CSR_BASE_ADDR + 0x114)
  1508. +#define TMU_PE_STATUS (TMU_CSR_BASE_ADDR + 0x118)
  1509. +#define TMU_TEQ_MAX_THRESHOLD (TMU_CSR_BASE_ADDR + 0x11c)
  1510. +#define TMU_PHY4_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x134) /**< [31:0] PHY4 in queue address (must be initialized with one of the xxx_INQ_PKTPTR cbus addresses) */
  1511. +#define TMU_TDQ1_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x138) /**< [9:0] Scheduler Enable for each of the scheduler in the TDQ. This is a global Enable for all schedulers in PHY1 */
  1512. +#define TMU_TDQ2_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x13c) /**< [9:0] Scheduler Enable for each of the scheduler in the TDQ. This is a global Enable for all schedulers in PHY2 */
  1513. +#define TMU_TDQ3_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x140) /**< [9:0] Scheduler Enable for each of the scheduler in the TDQ. This is a global Enable for all schedulers in PHY3 */
  1514. +#define TMU_BMU_BUF_SIZE (TMU_CSR_BASE_ADDR + 0x144)
  1515. +#define TMU_PHY5_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x148) /**< [31:0] PHY5 in queue address (must be initialized with one of the xxx_INQ_PKTPTR cbus addresses) */
  1516. +
  1517. +#define SW_RESET (1 << 0) /**< Global software reset */
  1518. +#define INQ_RESET (1 << 2)
  1519. +#define TEQ_RESET (1 << 3)
  1520. +#define TDQ_RESET (1 << 4)
  1521. +#define PE_RESET (1 << 5)
  1522. +#define MEM_INIT (1 << 6)
  1523. +#define MEM_INIT_DONE (1 << 7)
  1524. +#define LLM_INIT (1 << 8)
  1525. +#define LLM_INIT_DONE (1 << 9)
  1526. +#define ECC_MEM_INIT_DONE (1<<10)
  1527. +
  1528. +typedef struct {
  1529. + u32 pe_sys_clk_ratio;
  1530. + unsigned long llm_base_addr;
  1531. + u32 llm_queue_len;
  1532. +} TMU_CFG;
  1533. +
  1534. +/* Not HW related for pfe_ctrl / pfe common defines */
  1535. +#define DEFAULT_MAX_QDEPTH 80
  1536. +#define DEFAULT_Q0_QDEPTH 511 //We keep one large queue for host tx qos
  1537. +#define DEFAULT_TMU3_QDEPTH 127
  1538. +
  1539. +
  1540. +#endif /* _TMU_CSR_H_ */
  1541. --- /dev/null
  1542. +++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
  1543. @@ -0,0 +1,61 @@
  1544. +/*
  1545. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1546. + *
  1547. + * This program is free software; you can redistribute it and/or
  1548. + * modify it under the terms of the GNU General Public License
  1549. + * as published by the Free Software Foundation; either version 2
  1550. + * of the License, or (at your option) any later version.
  1551. + *
  1552. + * This program is distributed in the hope that it will be useful,
  1553. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1554. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1555. + * GNU General Public License for more details.
  1556. + *
  1557. + * You should have received a copy of the GNU General Public License
  1558. + * along with this program; if not, write to the Free Software
  1559. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1560. + *
  1561. +*/
  1562. +#ifndef _UTIL_CSR_H_
  1563. +#define _UTIL_CSR_H_
  1564. +
  1565. +#define UTIL_VERSION (UTIL_CSR_BASE_ADDR + 0x000)
  1566. +#define UTIL_TX_CTRL (UTIL_CSR_BASE_ADDR + 0x004)
  1567. +#define UTIL_INQ_PKTPTR (UTIL_CSR_BASE_ADDR + 0x010)
  1568. +
  1569. +#define UTIL_HDR_SIZE (UTIL_CSR_BASE_ADDR + 0x014)
  1570. +
  1571. +#define UTIL_PE0_QB_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x020)
  1572. +#define UTIL_PE0_QB_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x024)
  1573. +#define UTIL_PE0_RO_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x060)
  1574. +#define UTIL_PE0_RO_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x064)
  1575. +
  1576. +#define UTIL_MEM_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x100)
  1577. +#define UTIL_MEM_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x104)
  1578. +#define UTIL_MEM_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x108)
  1579. +
  1580. +#define UTIL_TM_INQ_ADDR (UTIL_CSR_BASE_ADDR + 0x114)
  1581. +#define UTIL_PE_STATUS (UTIL_CSR_BASE_ADDR + 0x118)
  1582. +
  1583. +#define UTIL_PE_SYS_CLK_RATIO (UTIL_CSR_BASE_ADDR + 0x200)
  1584. +#define UTIL_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x204)
  1585. +#define UTIL_GAP_BETWEEN_READS (UTIL_CSR_BASE_ADDR + 0x208)
  1586. +#define UTIL_MAX_BUF_CNT (UTIL_CSR_BASE_ADDR + 0x20c)
  1587. +#define UTIL_TSQ_FIFO_THRES (UTIL_CSR_BASE_ADDR + 0x210)
  1588. +#define UTIL_TSQ_MAX_CNT (UTIL_CSR_BASE_ADDR + 0x214)
  1589. +#define UTIL_IRAM_DATA_0 (UTIL_CSR_BASE_ADDR + 0x218)
  1590. +#define UTIL_IRAM_DATA_1 (UTIL_CSR_BASE_ADDR + 0x21c)
  1591. +#define UTIL_IRAM_DATA_2 (UTIL_CSR_BASE_ADDR + 0x220)
  1592. +#define UTIL_IRAM_DATA_3 (UTIL_CSR_BASE_ADDR + 0x224)
  1593. +
  1594. +#define UTIL_BUS_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x228)
  1595. +#define UTIL_BUS_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x22c)
  1596. +#define UTIL_BUS_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x230)
  1597. +
  1598. +#define UTIL_INQ_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x234)
  1599. +
  1600. +typedef struct {
  1601. + u32 pe_sys_clk_ratio;
  1602. +} UTIL_CFG;
  1603. +
  1604. +#endif /* _UTIL_CSR_H_ */
  1605. --- /dev/null
  1606. +++ b/drivers/staging/fsl_ppfe/include/pfe/class.h
  1607. @@ -0,0 +1,133 @@
  1608. +/*
  1609. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1610. + *
  1611. + * This program is free software; you can redistribute it and/or
  1612. + * modify it under the terms of the GNU General Public License
  1613. + * as published by the Free Software Foundation; either version 2
  1614. + * of the License, or (at your option) any later version.
  1615. + *
  1616. + * This program is distributed in the hope that it will be useful,
  1617. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1618. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1619. + * GNU General Public License for more details.
  1620. + *
  1621. + * You should have received a copy of the GNU General Public License
  1622. + * along with this program; if not, write to the Free Software
  1623. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1624. + *
  1625. +*/
  1626. +#ifndef _CLASS_H_
  1627. +#define _CLASS_H_
  1628. +
  1629. +#include "pe.h"
  1630. +
  1631. +#define CLASS_DMEM_BASE_ADDR 0x00000000
  1632. +#define CLASS_DMEM_SIZE 0x2000
  1633. +#define CLASS_DMEM_END (CLASS_DMEM_BASE_ADDR + CLASS_DMEM_SIZE)
  1634. +#define CLASS_PMEM_BASE_ADDR 0x00010000
  1635. +
  1636. +#define CBUS_BASE_ADDR 0xc0000000
  1637. +#define CLASS_APB_BASE_ADDR 0xc1000000
  1638. +#define CLASS_AHB1_BASE_ADDR 0xc2000000
  1639. +#define CLASS_AHB2_BASE_ADDR 0xc3000000
  1640. +
  1641. +#include "cbus.h"
  1642. +
  1643. +#define GPT_BASE_ADDR (CLASS_APB_BASE_ADDR + 0x00000)
  1644. +#define UART_BASE_ADDR (CLASS_APB_BASE_ADDR + 0x10000)
  1645. +#define PERG_BASE_ADDR (CLASS_APB_BASE_ADDR + 0x20000)
  1646. +#define EFET_BASE_ADDR (CLASS_APB_BASE_ADDR + 0x40000)
  1647. +
  1648. +#define MAC_HASH_BASE_ADDR (CLASS_AHB1_BASE_ADDR + 0x30000)
  1649. +#define VLAN_HASH_BASE_ADDR (CLASS_AHB1_BASE_ADDR + 0x50000)
  1650. +
  1651. +#define PE_LMEM_BASE_ADDR (CLASS_AHB2_BASE_ADDR + 0x10000)
  1652. +#define PE_LMEM_SIZE 0x8000
  1653. +#define PE_LMEM_END (PE_LMEM_BASE_ADDR + PE_LMEM_SIZE)
  1654. +#define CCU_BASE_ADDR (CLASS_AHB2_BASE_ADDR + 0x20000)
  1655. +
  1656. +#define IS_DMEM(addr, len) (((unsigned long)(addr) >= CLASS_DMEM_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= CLASS_DMEM_END))
  1657. +#define IS_PE_LMEM(addr, len) (((unsigned long)(addr) >= PE_LMEM_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= PE_LMEM_END))
  1658. +
  1659. +
  1660. +#include "gpt.h"
  1661. +#include "uart.h"
  1662. +#include "class/perg.h"
  1663. +#include "class/efet.h"
  1664. +#include "class/mac_hash.h"
  1665. +#include "class/vlan_hash.h"
  1666. +#include "class/ccu.h"
  1667. +
  1668. +
  1669. +#define CLASS_MAX_PBUFFERS 4
  1670. +
  1671. +#define PBUF_HWPARSE_OFFSET 0x10 /* Fixed by hardware */
  1672. +
  1673. +#define PAYLOAD_DMEM_MAX_SIZE (CLASS_PBUF_SIZE - CLASS_PBUF_HEADER_OFFSET - sizeof(class_rx_hdr_t))
  1674. +
  1675. +
  1676. +#define MIN_PKT_SIZE 56
  1677. +
  1678. +#define PARSE_ETH_TYPE (1 << 0)
  1679. +#define PARSE_VLAN_TYPE (1 << 1)
  1680. +#define PARSE_PPPOE_TYPE (1 << 2)
  1681. +#define PARSE_ARP_TYPE (1 << 3)
  1682. +#define PARSE_MCAST_TYPE (1 << 4)
  1683. +#define PARSE_IP_TYPE (1 << 5)
  1684. +#define PARSE_IPV6_TYPE (1 << 6)
  1685. +#define PARSE_IPV4_TYPE (1 << 7)
  1686. +
  1687. +#define PARSE_IPX_TYPE (1 << 9)
  1688. +
  1689. +#define PARSE_UDP_FLOW (1 << 11)
  1690. +#define PARSE_TCP_FLOW (1 << 12)
  1691. +#define PARSE_ICMP_FLOW (1 << 13)
  1692. +#define PARSE_IGMP_FLOW (1 << 14)
  1693. +#define PARSE_FRAG_FLOW (1 << 15)
  1694. +
  1695. +#define PARSE_HIF_PKT (1 << 23)
  1696. +#define PARSE_ARC_HIT (1 << 24)
  1697. +#define PARSE_PKT_OVERFLOW (1 << 25)
  1698. +
  1699. +#define PARSE_PROTO_MISMATCH (1 << 28)
  1700. +#define PARSE_L3_MISMATCH (1 << 29)
  1701. +#define PARSE_L2_MISMATCH (1 << 30)
  1702. +#define PARSE_INCOMPLETE (1 << 31)
  1703. +
  1704. +
  1705. +typedef struct _hwparse_t {
  1706. + u16 sid;
  1707. + u16 connid;
  1708. + u8 toevec;
  1709. + u8 pLayer2Hdr;
  1710. + u8 pLayer3Hdr;
  1711. + u8 pLayer4Hdr;
  1712. + u16 vlanid;
  1713. + u16 ifParseFlags;
  1714. + u32 parseFlags;
  1715. + u16 srcport;
  1716. + u16 dstport;
  1717. + u32 proto:8;
  1718. + u32 port:4;
  1719. + u32 hash:20;
  1720. + u64 rte_res_valid:1;
  1721. + u64 vlan_res_valid:1;
  1722. + u64 dst_res_valid:1;
  1723. + u64 src_res_valid:1;
  1724. + u64 vlan_lookup:20;
  1725. + u64 dst_lookup:20;
  1726. + u64 src_lookup:20;
  1727. +} hwparse_t;
  1728. +
  1729. +
  1730. +typedef struct {
  1731. + u8 num_cpy; /* no of copies to send out from RO block, for each there must be a corresponding tx pre-header */
  1732. + u8 dma_len; /* len to be DMAed to DDR mem, including all tx pre-headers */
  1733. + u16 src_addr; /* class dmem source address, pointing to first tx pre-header */
  1734. + u32 dst_addr; /* DDR memory destination address of first tx pre-header, must be so packet data is continuous in DDR */
  1735. + u32 res1; /* reserved for software usage - queue number? */
  1736. + u16 res2; /* reserved for software usage */
  1737. + u16 tsv; /* time stamp val */
  1738. +} class_tx_desc_t;
  1739. +
  1740. +#endif /* _CLASS_H_ */
  1741. --- /dev/null
  1742. +++ b/drivers/staging/fsl_ppfe/include/pfe/class/ccu.h
  1743. @@ -0,0 +1,28 @@
  1744. +/*
  1745. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1746. + *
  1747. + * This program is free software; you can redistribute it and/or
  1748. + * modify it under the terms of the GNU General Public License
  1749. + * as published by the Free Software Foundation; either version 2
  1750. + * of the License, or (at your option) any later version.
  1751. + *
  1752. + * This program is distributed in the hope that it will be useful,
  1753. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1754. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1755. + * GNU General Public License for more details.
  1756. + *
  1757. + * You should have received a copy of the GNU General Public License
  1758. + * along with this program; if not, write to the Free Software
  1759. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1760. + *
  1761. +*/
  1762. +#ifndef _CCU_H_
  1763. +#define _CCU_H_
  1764. +
  1765. +#define CCU_ADDR (CCU_BASE_ADDR + 0x00)
  1766. +#define CCU_CNT (CCU_BASE_ADDR + 0x04)
  1767. +#define CCU_STATUS (CCU_BASE_ADDR + 0x08)
  1768. +#define CCU_VAL (CCU_BASE_ADDR + 0x0c)
  1769. +
  1770. +#endif /* _CCU_H_ */
  1771. +
  1772. --- /dev/null
  1773. +++ b/drivers/staging/fsl_ppfe/include/pfe/class/efet.h
  1774. @@ -0,0 +1,44 @@
  1775. +/*
  1776. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1777. + *
  1778. + * This program is free software; you can redistribute it and/or
  1779. + * modify it under the terms of the GNU General Public License
  1780. + * as published by the Free Software Foundation; either version 2
  1781. + * of the License, or (at your option) any later version.
  1782. + *
  1783. + * This program is distributed in the hope that it will be useful,
  1784. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1785. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1786. + * GNU General Public License for more details.
  1787. + *
  1788. + * You should have received a copy of the GNU General Public License
  1789. + * along with this program; if not, write to the Free Software
  1790. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1791. + *
  1792. +*/
  1793. +#ifndef _CLASS_EFET_H_
  1794. +#define _CLASS_EFET_H_
  1795. +
  1796. +//#define CLASS_EFET_ASYNC 1
  1797. +
  1798. +#define CLASS_EFET_ENTRY_ADDR (EFET_BASE_ADDR + 0x00)
  1799. +#define CLASS_EFET_ENTRY_SIZE (EFET_BASE_ADDR + 0x04)
  1800. +#define CLASS_EFET_ENTRY_DMEM_ADDR (EFET_BASE_ADDR + 0x08)
  1801. +#define CLASS_EFET_ENTRY_STATUS (EFET_BASE_ADDR + 0x0c)
  1802. +#define CLASS_EFET_ENTRY_ENDIAN (EFET_BASE_ADDR + 0x10)
  1803. +
  1804. +#define CBUS2DMEM 0
  1805. +#define DMEM2CBUS 1
  1806. +
  1807. +#define EFET2BUS_LE (1 << 0)
  1808. +#define PE2BUS_LE (1 << 1)
  1809. +
  1810. +#ifdef CLASS_EFET_ASYNC
  1811. +void class_efet_async(u32 cbus_addr, u32 dmem_addr, u32 len, u32 dir);
  1812. +#endif
  1813. +
  1814. +void class_efet_sync(u32 cbus_addr, u32 dmem_addr, u32 len, u32 dir);
  1815. +
  1816. +
  1817. +#endif /* _CLASS_EFET_H_ */
  1818. +
  1819. --- /dev/null
  1820. +++ b/drivers/staging/fsl_ppfe/include/pfe/class/mac_hash.h
  1821. @@ -0,0 +1,55 @@
  1822. +/*
  1823. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1824. + *
  1825. + * This program is free software; you can redistribute it and/or
  1826. + * modify it under the terms of the GNU General Public License
  1827. + * as published by the Free Software Foundation; either version 2
  1828. + * of the License, or (at your option) any later version.
  1829. + *
  1830. + * This program is distributed in the hope that it will be useful,
  1831. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1832. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1833. + * GNU General Public License for more details.
  1834. + *
  1835. + * You should have received a copy of the GNU General Public License
  1836. + * along with this program; if not, write to the Free Software
  1837. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1838. + *
  1839. +*/
  1840. +#ifndef _MAC_HASH_H_
  1841. +#define _MAC_HASH_H_
  1842. +
  1843. +#define MAC_HASH_REQ1_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x000)
  1844. +#define MAC_HASH_REQ2_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x020)
  1845. +#define MAC_HASH_REQ3_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x040)
  1846. +#define MAC_HASH_REQ4_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x060)
  1847. +#define MAC_HASH_REQ5_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x080)
  1848. +#define MAC_HASH_REQ6_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x0a0)
  1849. +#define MAC_HASH_REQ7_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x0c0)
  1850. +#define MAC_HASH_REQ8_BASE_ADDR (MAC_HASH_BASE_ADDR + 0x0e0)
  1851. +
  1852. +#define MAC_HASH_REQ_CMD(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x000)
  1853. +#define MAC_HASH_REQ_MAC1_ADDR(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x004)
  1854. +#define MAC_HASH_REQ_MAC2_ADDR(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x008)
  1855. +#define MAC_HASH_REQ_MASK1_ADDR(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x00c)
  1856. +#define MAC_HASH_REQ_MASK2_ADDR(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x010)
  1857. +#define MAC_HASH_REQ_ENTRY(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x014)
  1858. +#define MAC_HASH_REQ_STATUS(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x018)
  1859. +#define MAC_HASH_REQ_ENTRY_MAYCH(i) (MAC_HASH_REQ##i##_BASE_ADDR + 0x01c)
  1860. +
  1861. +
  1862. +#define MAC_HASH_FREELIST_PTR_HEAD (MAC_HASH_BASE_ADDR + 0x100)
  1863. +#define MAC_HASH_FREELIST_PTR_TAIL (MAC_HASH_BASE_ADDR + 0x104)
  1864. +#define MAC_HASH_FREELIST_ENTRIES_ADDR (MAC_HASH_BASE_ADDR + 0x108)
  1865. +
  1866. +
  1867. +#define HASH_CMD_INIT 1
  1868. +#define HASH_CMD_ADD 2
  1869. +#define HASH_CMD_DELETE 3
  1870. +#define HASH_CMD_UPDATE 4
  1871. +#define HASH_CMD_SEARCH 5
  1872. +#define HASH_CMD_MEM_READ 6
  1873. +#define HASH_CMD_MEM_WRITE 7
  1874. +
  1875. +#endif /* _MAC_HASH_H_ */
  1876. +
  1877. --- /dev/null
  1878. +++ b/drivers/staging/fsl_ppfe/include/pfe/class/perg.h
  1879. @@ -0,0 +1,39 @@
  1880. +/*
  1881. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1882. + *
  1883. + * This program is free software; you can redistribute it and/or
  1884. + * modify it under the terms of the GNU General Public License
  1885. + * as published by the Free Software Foundation; either version 2
  1886. + * of the License, or (at your option) any later version.
  1887. + *
  1888. + * This program is distributed in the hope that it will be useful,
  1889. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1890. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1891. + * GNU General Public License for more details.
  1892. + *
  1893. + * You should have received a copy of the GNU General Public License
  1894. + * along with this program; if not, write to the Free Software
  1895. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1896. + *
  1897. +*/
  1898. +#ifndef _PERG_H_
  1899. +#define _PERG_H_
  1900. +
  1901. +#define PERG_QB_BUF_STATUS (PERG_BASE_ADDR + 0x00)
  1902. +#define PERG_RO_BUF_STATUS (PERG_BASE_ADDR + 0x04)
  1903. +#define PERG_CLR_QB_BUF_STATUS (PERG_BASE_ADDR + 0x08)
  1904. +#define PERG_SET_RO_BUF_STATUS (PERG_BASE_ADDR + 0x0c)
  1905. +#define PERG_CLR_RO_ERR_PKT (PERG_BASE_ADDR + 0x10)
  1906. +#define PERG_CLR_BMU2_ERR_PKT (PERG_BASE_ADDR + 0x14)
  1907. +
  1908. +#define PERG_ID (PERG_BASE_ADDR + 0x18)
  1909. +#define PERG_TIMER1 (PERG_BASE_ADDR + 0x1c)
  1910. +//FIXME #define PERG_TIMER2 (PERG_BASE_ADDR + 0x20)
  1911. +#define PERG_BMU1_CURRDEPTH (PERG_BASE_ADDR + 0x20)
  1912. +#define PERG_BMU2_CURRDEPTH (PERG_BASE_ADDR + 0x24)
  1913. +#define PERG_HOST_GP (PERG_BASE_ADDR + 0x2c)
  1914. +#define PERG_PE_GP (PERG_BASE_ADDR + 0x30)
  1915. +#define PERG_INT_ENABLE (PERG_BASE_ADDR + 0x34)
  1916. +#define PERG_INT_SRC (PERG_BASE_ADDR + 0x38)
  1917. +
  1918. +#endif /* _PERG_H_ */
  1919. --- /dev/null
  1920. +++ b/drivers/staging/fsl_ppfe/include/pfe/class/vlan_hash.h
  1921. @@ -0,0 +1,46 @@
  1922. +/*
  1923. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1924. + *
  1925. + * This program is free software; you can redistribute it and/or
  1926. + * modify it under the terms of the GNU General Public License
  1927. + * as published by the Free Software Foundation; either version 2
  1928. + * of the License, or (at your option) any later version.
  1929. + *
  1930. + * This program is distributed in the hope that it will be useful,
  1931. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1932. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1933. + * GNU General Public License for more details.
  1934. + *
  1935. + * You should have received a copy of the GNU General Public License
  1936. + * along with this program; if not, write to the Free Software
  1937. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1938. + *
  1939. +*/
  1940. +#ifndef _VLAN_HASH_H_
  1941. +#define _VLAN_HASH_H_
  1942. +
  1943. +#define VLAN_HASH_REQ1_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x000)
  1944. +#define VLAN_HASH_REQ2_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x020)
  1945. +#define VLAN_HASH_REQ3_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x040)
  1946. +#define VLAN_HASH_REQ4_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x060)
  1947. +#define VLAN_HASH_REQ5_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x080)
  1948. +#define VLAN_HASH_REQ6_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x0a0)
  1949. +#define VLAN_HASH_REQ7_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x0c0)
  1950. +#define VLAN_HASH_REQ8_BASE_ADDR (VLAN_HASH_BASE_ADDR + 0x0e0)
  1951. +
  1952. +#define VLAN_HASH_REQ_CMD(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x000)
  1953. +#define VLAN_HASH_REQ_MAC1_ADDR(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x004)
  1954. +#define VLAN_HASH_REQ_MAC2_ADDR(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x008)
  1955. +#define VLAN_HASH_REQ_MASK1_ADDR(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x00c)
  1956. +#define VLAN_HASH_REQ_MASK2_ADDR(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x010)
  1957. +#define VLAN_HASH_REQ_ENTRY(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x014)
  1958. +#define VLAN_HASH_REQ_STATUS(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x018)
  1959. +#define VLAN_HASH_REQ_ENTRY_MAYCH(i) (VLAN_HASH_REQ##i##_BASE_ADDR + 0x01c)
  1960. +
  1961. +
  1962. +#define VLAN_HASH_FREELIST_PTR_HEAD (VLAN_HASH_BASE_ADDR + 0x100)
  1963. +#define VLAN_HASH_FREELIST_PTR_TAIL (VLAN_HASH_BASE_ADDR + 0x104)
  1964. +#define VLAN_HASH_FREELIST_ENTRIES_ADDR (VLAN_HASH_BASE_ADDR + 0x108)
  1965. +
  1966. +#endif /* _VLAN_HASH_H_ */
  1967. +
  1968. --- /dev/null
  1969. +++ b/drivers/staging/fsl_ppfe/include/pfe/gpt.h
  1970. @@ -0,0 +1,44 @@
  1971. +/*
  1972. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  1973. + *
  1974. + * This program is free software; you can redistribute it and/or
  1975. + * modify it under the terms of the GNU General Public License
  1976. + * as published by the Free Software Foundation; either version 2
  1977. + * of the License, or (at your option) any later version.
  1978. + *
  1979. + * This program is distributed in the hope that it will be useful,
  1980. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1981. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1982. + * GNU General Public License for more details.
  1983. + *
  1984. + * You should have received a copy of the GNU General Public License
  1985. + * along with this program; if not, write to the Free Software
  1986. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  1987. + *
  1988. +*/
  1989. +#ifndef _GPT_H_
  1990. +#define _GPT_H_
  1991. +
  1992. +#define GPT_VERSION (GPT_BASE_ADDR + 0x00)
  1993. +#define GPT_STATUS (GPT_BASE_ADDR + 0x04)
  1994. +#define GPT_CONFIG (GPT_BASE_ADDR + 0x08)
  1995. +#define GPT_COUNTER (GPT_BASE_ADDR + 0x0c)
  1996. +#define GPT_PERIOD (GPT_BASE_ADDR + 0x10)
  1997. +#define GPT_WIDTH (GPT_BASE_ADDR + 0x14)
  1998. +
  1999. +/*** These bits are defined for GPT_STATUS register */
  2000. +#define GPT_STAT_IRQ (1<<0)
  2001. +#define GPT_STAT_OVERFLOW_ERR (1<<4)
  2002. +#define GPT_STAT_TMR_ENABLE (1<<8)
  2003. +#define GPT_STAT_TMR_DISABLE (1<<9)
  2004. +
  2005. +/*** These bits are defined for GPT_CONFIG register */
  2006. +#define GPT_CONFIG_PWM_MODE 0x1
  2007. +#define GPT_CONFIG_WCAP_MODE 0x2
  2008. +#define GPT_CONFIG_CAP_PULSE_OUT (1<<2)
  2009. +#define GPT_CONFIG_PERIOD_CNT (1<<3)
  2010. +#define GPT_CONFIG_INTR_ENABLE (1<<4)
  2011. +#define GPT_CONFIG_AUX_SEL (1<<5)
  2012. +
  2013. +
  2014. +#endif /* _GPT_H_ */
  2015. --- /dev/null
  2016. +++ b/drivers/staging/fsl_ppfe/include/pfe/pe.h
  2017. @@ -0,0 +1,626 @@
  2018. +/*
  2019. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  2020. + *
  2021. + * This program is free software; you can redistribute it and/or
  2022. + * modify it under the terms of the GNU General Public License
  2023. + * as published by the Free Software Foundation; either version 2
  2024. + * of the License, or (at your option) any later version.
  2025. + *
  2026. + * This program is distributed in the hope that it will be useful,
  2027. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2028. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2029. + * GNU General Public License for more details.
  2030. + *
  2031. + * You should have received a copy of the GNU General Public License
  2032. + * along with this program; if not, write to the Free Software
  2033. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  2034. + *
  2035. +*/
  2036. +#ifndef _PE_H_
  2037. +#define _PE_H_
  2038. +
  2039. +#include "hal.h"
  2040. +
  2041. +#if defined(COMCERTO_2000_CLASS)
  2042. +#include "pfe/class.h"
  2043. +#elif defined(COMCERTO_2000_TMU)
  2044. +#include "pfe/tmu.h"
  2045. +#elif defined(COMCERTO_2000_UTIL)
  2046. +#include "pfe/util.h"
  2047. +#endif
  2048. +
  2049. +enum {
  2050. + CLASS0_ID = 0,
  2051. + CLASS1_ID,
  2052. + CLASS2_ID,
  2053. + CLASS3_ID,
  2054. + CLASS4_ID,
  2055. + CLASS5_ID,
  2056. + TMU0_ID,
  2057. + TMU1_ID,
  2058. + TMU2_ID,
  2059. + TMU3_ID,
  2060. + UTIL_ID,
  2061. + MAX_PE
  2062. +};
  2063. +#define PE_ID_ANY MAX_PE
  2064. +
  2065. +/* Hardware definition of physical ports */
  2066. +/* CLASS rx header phy number */
  2067. +enum CLASS_RX_PHY {
  2068. + RX_PHY_0 = 0x0,
  2069. + RX_PHY_1,
  2070. + RX_PHY_2,
  2071. + RX_PHY_HIF,
  2072. + RX_PHY_HIF_NOCPY,
  2073. + RX_PHY_CLASS = 1 << 14, /**< Control bit (in PHYNO field) used to inform CLASS PE that packet comes from Class. */
  2074. + RX_PHY_UTIL = 1 << 15 /**< Control bit (in PHYNO field) used to inform CLASS PE that packet comes from UtilPE. */
  2075. +};
  2076. +
  2077. +#define RX_PHY_SW_INPUT_PORT_OFFSET 11 /**< Offset in PHYNO field where the original input port will be stored for packets coming directly from software (UtilPE or Class). */
  2078. +
  2079. +
  2080. +/* CLASS/TMU tx header phy number */
  2081. +enum TMU_TX_PHY {
  2082. + TX_PHY_TMU0 = 0x0,
  2083. + TX_PHY_TMU1,
  2084. + TX_PHY_TMU2,
  2085. + TX_PHY_TMU3
  2086. +};
  2087. +
  2088. +
  2089. +// NOTE: Any changes to the following drop counter definitions must also
  2090. +// be reflected in the pfe/pfe.h file and in pfe_ctrl/pfe_sysfs.c.
  2091. +
  2092. +#if defined(COMCERTO_2000_CLASS)
  2093. +
  2094. +#define CLASS_DROP_ICC 0
  2095. +#define CLASS_DROP_HOST_PKT_ERROR 1
  2096. +#define CLASS_DROP_RX_ERROR 2
  2097. +#define CLASS_DROP_IPSEC_OUT 3
  2098. +#define CLASS_DROP_IPSEC_IN 4
  2099. +#define CLASS_DROP_EXPT_IPSEC 5
  2100. +#define CLASS_DROP_REASSEMBLY 6
  2101. +#define CLASS_DROP_FRAGMENTER 7
  2102. +#define CLASS_DROP_NATT 8
  2103. +#define CLASS_DROP_SOCKET 9
  2104. +#define CLASS_DROP_MULTICAST 10
  2105. +#define CLASS_DROP_NATPT 11
  2106. +#define CLASS_DROP_TX_DISABLE 12
  2107. +
  2108. +#define CLASS_NUM_DROP_COUNTERS 13
  2109. +
  2110. +extern U32 drop_counter[CLASS_NUM_DROP_COUNTERS];
  2111. +#define DROP_PACKET(pmtd, counter) free_packet(pmtd, CLASS_DROP_##counter)
  2112. +#define DROP_BUFFER(addr, counter) free_buffer(addr, CLASS_DROP_##counter)
  2113. +
  2114. +#elif defined(COMCERTO_2000_UTIL)
  2115. +
  2116. +#define UTIL_DROP_IPSEC_OUT 0
  2117. +#define UTIL_DROP_IPSEC_IN 1
  2118. +#define UTIL_DROP_IPSEC_RATE_LIMIT 2
  2119. +#define UTIL_DROP_FRAGMENTER 3
  2120. +#define UTIL_DROP_SOCKET 4
  2121. +#define UTIL_DROP_TX_DISABLE 5
  2122. +#define UTIL_DROP_RX_ERROR 6
  2123. +#define UTIL_DROP_NO_MTD 7
  2124. +
  2125. +#define UTIL_NUM_DROP_COUNTERS 8
  2126. +
  2127. +extern U32 drop_counter[UTIL_NUM_DROP_COUNTERS];
  2128. +#define DROP_PACKET(pmtd, counter) free_packet(pmtd, UTIL_DROP_##counter)
  2129. +#define DROP_BUFFER(addr, counter) free_buffer(addr, UTIL_DROP_##counter)
  2130. +
  2131. +#endif
  2132. +
  2133. +
  2134. +
  2135. +#define DDR_BASE_ADDR 0x00020000
  2136. +#define DDR_END 0x86000000 /* This includes ACP and IRAM areas */
  2137. +#define IRAM_BASE_ADDR 0x83000000
  2138. +
  2139. +#define IS_DDR(addr, len) (((unsigned long)(addr) >= DDR_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= DDR_END))
  2140. +/* action bits of act_phyno is defined as follows */
  2141. +
  2142. +#define ACT_SRC_MAC_REPLACE (1 << (4 + 0))
  2143. +#define ACT_VLAN_ADD (1 << (4 + 1))
  2144. +#define ACT_TCPCHKSUM_REPLACE (1 << (4 + 2))
  2145. +#define ACT_VLAN_REPLACE (1 << (4 + 3))
  2146. +#define ACT_DONT_FREE_BUFFER (1 << (4 + 5))
  2147. +#define ACT_IPCHKSUM_REPLACE (1 << (4 + 6))
  2148. +
  2149. +typedef struct {
  2150. + u8 start_data_off; /* packet data start offset, relative to start of this tx pre-header */
  2151. + u8 start_buf_off; /* this tx pre-header start offset, relative to start of DDR buffer */
  2152. + u16 pkt_length; /* total packet length */
  2153. + u8 act_phyno; /* action / phy number */
  2154. + u8 queueno; /* queueno */
  2155. + u16 unused;
  2156. +} class_tx_hdr_t;
  2157. +
  2158. +typedef struct {
  2159. + u8 start_data_off; /* packet data start offset, relative to start of this tx pre-header */
  2160. + u8 start_buf_off; /* this tx pre-header start offset, relative to start of DDR buffer */
  2161. + u16 pkt_length; /* total packet length */
  2162. + u8 act_phyno; /* action / phy number */
  2163. + u8 queueno; /* queueno */
  2164. + u16 src_mac_msb; /* indicates src_mac 47:32 */
  2165. + u32 src_mac_lsb; /* indicates src_mac 31:0 */
  2166. + u32 vlanid; /* vlanid */
  2167. +} class_tx_hdr_mc_t;
  2168. +
  2169. +typedef struct {
  2170. + u32 next_ptr; /* ptr to the start of the first DDR buffer */
  2171. + u16 length; /* total packet length */
  2172. + u16 phyno; /* input physical port number */
  2173. + u32 status; /* gemac status bits bits[32:63]*/
  2174. + u32 status2; /* gemac status bits bits[0:31] */
  2175. +} class_rx_hdr_t;
  2176. +/* class_rx_hdr status bits (status0 bits in hardware blocks)
  2177. + * from hif_top/dma_dxr_dtx.v
  2178. + * STATUS[9:0] is the encoding of bits in the LMEM buffer as seen by the QB block,
  2179. + * NOT the encoding of bits as seen by the Class PEs in the DMEM rx header */
  2180. +#define STATUS_PARSE_DISABLE (1 << 0)
  2181. +#define STATUS_BRFETCH_DISABLE (1 << 1)
  2182. +#define STATUS_RTFETCH_DISABLE (1 << 2)
  2183. +#define STATUS_DIR_PROC_ID (1 << 3)
  2184. +#define STATUS_CONN_ID_EN (1 << 4))
  2185. +#define STATUS_PE2PROC_ID(x) (((x) & 7) << 5)
  2186. +#define STATUS_LE_DATA (1 << 8)
  2187. +#define STATUS_CHKSUM_EN (1 << 9)
  2188. +
  2189. +/* from gpi/gpi_rmlf.v */
  2190. +#define STATUS_CUMULATIVE_ERR (1 << 16)
  2191. +#define STATUS_LENGTH_ERR (1 << 17)
  2192. +#define STATUS_CRC_ERR (1 << 18)
  2193. +#define STATUS_TOO_SHORT_ERR (1 << 19)
  2194. +#define STATUS_TOO_LONG_ERR (1 << 20)
  2195. +#define STATUS_CODE_ERR (1 << 21)
  2196. +#define STATUS_MC_HASH_MATCH (1 << 22)
  2197. +#define STATUS_CUMULATIVE_ARC_HIT (1 << 23)
  2198. +#define STATUS_UNICAST_HASH_MATCH (1 << 24)
  2199. +#define STATUS_IP_CHECKSUM_CORRECT (1 << 25)
  2200. +#define STATUS_TCP_CHECKSUM_CORRECT (1 << 26)
  2201. +#define STATUS_UDP_CHECKSUM_CORRECT (1 << 27)
  2202. +#define STATUS_OVERFLOW_ERR (1 << 28)
  2203. +
  2204. +#define UTIL_MAGIC_NUM 0xffd8ffe000104a46
  2205. +#define UTIL_DDRC_WA
  2206. +
  2207. +/* The following structure is filled by class-pe when the packet
  2208. + * has to be sent to util-pe, by filling the required information */
  2209. +typedef struct {
  2210. + u32 mtd_flags : 16;
  2211. + u32 packet_type : 8;
  2212. + u32 input_port : 4;
  2213. + u32 data_offset : 4;
  2214. + u32 word[MTD_PRIV];
  2215. +#ifdef UTIL_DDRC_WA
  2216. + u64 magic_num; // magic_number to verify the data validity in utilpe
  2217. +#endif
  2218. +} __attribute__((aligned(8))) util_rx_hdr_t; // Size must be a multiple of 64-bit to allow copies using EFET.
  2219. +
  2220. +#define UTIL_RX_IPS_IN_PKT EVENT_IPS_IN
  2221. +#define UTIL_RX_IPS_OUT_PKT EVENT_IPS_OUT
  2222. +#define UTIL_RX_RTP_PKT EVENT_RTP_RELAY
  2223. +#define UTIL_RX_RTP_QOS_PKT EVENT_RTP_QOS
  2224. +#define UTIL_RX_FRAG4_PKT EVENT_FRAG4
  2225. +#define UTIL_RX_FRAG6_PKT EVENT_FRAG6
  2226. +
  2227. +/** Structure passed from UtilPE to Class, stored at the end of the LMEM buffer. Defined and used by software only.
  2228. + *
  2229. + */
  2230. +
  2231. +typedef struct
  2232. +{
  2233. + void *next;
  2234. + u16 next_length;
  2235. + u8 next_l3offset;
  2236. + u8 next_l4offset;
  2237. +} frag_info;
  2238. +
  2239. +typedef struct {
  2240. + u8 packet_type : 6;
  2241. + u8 padding : 2;
  2242. +
  2243. + u8 offset : 3;
  2244. + u8 ddr_offset : 5;
  2245. +
  2246. + u16 mtd_flags;
  2247. + union {
  2248. + u16 half[6];
  2249. + u8 byte[12];
  2250. +
  2251. + struct {
  2252. + u16 sa_handle[2]; // SA_MAX_OP value should be used here instead of 2
  2253. + u8 proto;
  2254. + S8 sa_op;
  2255. + u8 l2hdr_len;
  2256. + u8 adj_dmem;
  2257. + } ipsec;
  2258. +
  2259. + struct {
  2260. + u16 l4offset;
  2261. + u16 socket_id;
  2262. + BOOL update;
  2263. + u8 reserved;
  2264. + u32 payload_diff;
  2265. + } relay;
  2266. +
  2267. + struct {
  2268. + u16 l3offset;
  2269. + u16 l4offset;
  2270. +
  2271. + frag_info frag;
  2272. + } ipv6;
  2273. +
  2274. + struct {
  2275. + u16 l3offset;
  2276. + } ipv4;
  2277. +
  2278. + struct {
  2279. + u32 ddr_addr;
  2280. + u16 length;
  2281. + u8 port;
  2282. + u8 queue;
  2283. + u8 action;
  2284. + } tx;
  2285. + };
  2286. +} lmem_trailer_t;
  2287. +
  2288. +/* The following values are defined for packet_type of lmem_trailer_t.
  2289. + * These represent different types of packets sent from util to class
  2290. + * for processing */
  2291. +enum {
  2292. + UTIL_TX_IPS_IN = 0,
  2293. + UTIL_TX_IPV4_RTP_PKT,
  2294. + UTIL_TX_IPV6_RTP_PKT,
  2295. + UTIL_TX_IPV4_PKT,
  2296. + UTIL_TX_IPV6_PKT,
  2297. + UTIL_TX_EXPT_PKT,
  2298. +#ifdef CFG_PCAP
  2299. + UTIL_TX_PKT,
  2300. +#endif
  2301. + UTIL_TX_MAX_PKT
  2302. +};
  2303. +
  2304. +
  2305. +#define UTIL_TX_TRAILER_SIZE sizeof(lmem_trailer_t)
  2306. +#define UTIL_TX_TRAILER(mtd) ((lmem_trailer_t *)ROUND_UP32((u32)(mtd)->rx_dmem_end))
  2307. +
  2308. +typedef struct {
  2309. + u32 pkt_ptr;
  2310. + u8 phyno;
  2311. + u8 queueno;
  2312. + u16 len;
  2313. +} tmu_tx_hdr_t;
  2314. +
  2315. +struct hif_pkt_hdr {
  2316. + u8 client_id;
  2317. + u8 qNo;
  2318. + u16 client_ctrl_le_lsw;
  2319. + u16 client_ctrl_le_msw;
  2320. +};
  2321. +
  2322. +
  2323. +#if defined(CFG_WIFI_OFFLOAD)
  2324. +#define MAX_WIFI_VAPS 3
  2325. +#define PFE_WIFI_PKT_HEADROOM 96 /*PFE inserts this headroom for WiFi tx packets only in lro mode */
  2326. +#else
  2327. +#define MAX_WIFI_VAPS 0
  2328. +#endif
  2329. +
  2330. +/* HIF header client id */
  2331. +enum HIF_CLIENT_ID {
  2332. + CLIENT_ID_GEM0 = 0,
  2333. + CLIENT_ID_GEM1,
  2334. + CLIENT_ID_GEM2,
  2335. + CLIENT_ID_WIFI0,
  2336. + CLIENT_ID_WIFI_LAST = MAX_WIFI_VAPS + CLIENT_ID_GEM2,
  2337. + CLIENT_ID_PCAP,
  2338. + CLIENT_ID_UNKNOWN = 0xff,
  2339. +};
  2340. +
  2341. +
  2342. +#define IS_WIFI_CLIENT_ID(_clid) (((_clid) >= CLIENT_ID_WIFI0) && ((_clid) <= CLIENT_ID_WIFI_LAST))
  2343. +
  2344. +/* These match LE definition */
  2345. +#define HIF_CTRL_TX_TSO_NOCPY __cpu_to_le32(1 << 8)
  2346. +#define HIF_CTRL_TX_IPSEC_OUT __cpu_to_le32(1 << 7)
  2347. +#define HIF_CTRL_TX_WIFI_OWNMAC __cpu_to_le32(1 << 6)
  2348. +#define HIF_CTRL_TX_TSO_END __cpu_to_le32(1 << 5)
  2349. +#define HIF_CTRL_TX_TSO6 __cpu_to_le32(1 << 4)
  2350. +#define HIF_CTRL_TX_TSO __cpu_to_le32(1 << 3)
  2351. +#define HIF_CTRL_TX_CHECKSUM __cpu_to_le32(1 << 2)
  2352. +#define HIF_CTRL_TX_CSUM_VALIDATE __cpu_to_le32(1 << 1)
  2353. +#define HIF_CTRL_TX_WIFI_TXOFLD __cpu_to_le32(1 << 0)
  2354. +
  2355. +#define HIF_CTRL_RX_OFFSET_MASK __cpu_to_le32(0xf << 24)
  2356. +#define HIF_CTRL_RX_PE_ID_MASK __cpu_to_le32(0xf << 16)
  2357. +#define HIF_CTRL_RX_IPSEC_IN __cpu_to_le32(1 << 4)
  2358. +#define HIF_CTRL_RX_WIFI_EXPT __cpu_to_le32(1 << 3)
  2359. +#define HIF_CTRL_RX_CHECKSUMMED __cpu_to_le32(1 << 2)
  2360. +#define HIF_CTRL_RX_CONTINUED __cpu_to_le32(1 << 1)
  2361. +#define HIF_CTRL_RX_WIFI_HEADROOM __cpu_to_le32(1 << 0)
  2362. +
  2363. +#ifdef CFG_LRO
  2364. +struct hif_lro_hdr {
  2365. + u16 data_offset;
  2366. + u16 mss;
  2367. +};
  2368. +#endif
  2369. +
  2370. +struct hif_ipsec_hdr {
  2371. + u16 sa_handle[2];
  2372. +};
  2373. +
  2374. +#define MAX_TSO_BUF_DESCS 5
  2375. +struct hif_tso_buf_desc {
  2376. + u32 addr;
  2377. + u32 ctrl;
  2378. +#define TSO_CTRL_LAST_BUFFER (1 << 31)
  2379. +};
  2380. +
  2381. +struct hif_tso_hdr {
  2382. + u16 ip_off;
  2383. + u16 ip_id;
  2384. + u16 ip_len;
  2385. + u16 tcp_off;
  2386. + u32 tcp_seq;
  2387. +};
  2388. +
  2389. +struct hif_tso_hdr_nocpy {
  2390. + u16 ip_off;
  2391. + u16 ip_id;
  2392. + u16 ip_len;
  2393. + u16 tcp_off;
  2394. + u32 tcp_seq;
  2395. + struct hif_tso_buf_desc bdesc[MAX_TSO_BUF_DESCS];
  2396. +};
  2397. +
  2398. +struct hif_pcap_hdr {
  2399. + u8 ifindex;
  2400. + u8 unused;
  2401. + u16 seqno;
  2402. + u32 timestamp;
  2403. +};
  2404. +
  2405. +
  2406. +struct pe_sync_mailbox
  2407. +{
  2408. + u32 stop;
  2409. + u32 stopped;
  2410. +};
  2411. +
  2412. +struct pe_msg_mailbox
  2413. +{
  2414. + u32 dst;
  2415. + u32 src;
  2416. + u32 len;
  2417. + u32 request;
  2418. +};
  2419. +
  2420. +
  2421. +/** Basic busy loop delay function
  2422. +*
  2423. +* @param cycles Number of cycles to delay (actual cpu cycles should be close to 3 x cycles)
  2424. +*
  2425. +*/
  2426. +static inline void delay(u32 cycles)
  2427. +{
  2428. + volatile int i;
  2429. +
  2430. + for (i = 0; i < cycles; i++);
  2431. +}
  2432. +
  2433. +
  2434. +/** Read PE id
  2435. +*
  2436. +* @return PE id (0 - 5 for CLASS-PE's, 6 - 9 for TMU-PE's, 10 for UTIL-PE)
  2437. +*
  2438. +*/
  2439. +static inline u32 esi_get_mpid(void)
  2440. +{
  2441. + u32 mpid;
  2442. +
  2443. + asm ("rcsr %0, Configuration, MPID" : "=d" (mpid));
  2444. +
  2445. + return mpid;
  2446. +}
  2447. +
  2448. +
  2449. +#define esi_get_csr(bank, csr) \
  2450. +({ \
  2451. + u32 res; \
  2452. + asm ("rcsr %0, " #bank ", " #csr : "=d" (res)); \
  2453. + res; \
  2454. +})
  2455. +
  2456. +#define esi_get_isa0() esi_get_csr(Configuration, ISA0)
  2457. +#define esi_get_isa1() esi_get_csr(Configuration, ISA1)
  2458. +#define esi_get_isa2() esi_get_csr(Configuration, ISA2)
  2459. +#define esi_get_isa3() esi_get_csr(Configuration, ISA3)
  2460. +#define esi_get_epc() esi_get_csr(Thread, EPC)
  2461. +#define esi_get_ecas() esi_get_csr(Thread, ECAS)
  2462. +#define esi_get_eid() esi_get_csr(Thread, EID)
  2463. +#define esi_get_ed() esi_get_csr(Thread, ED)
  2464. +
  2465. +static inline void esi_pe_stop(U32 state)
  2466. +{
  2467. + PESTATUS_SETSTATE(state);
  2468. + while (1)
  2469. + {
  2470. + asm("stop");
  2471. + }
  2472. +}
  2473. +
  2474. +
  2475. +/** Same 64bit alignment memory copy using efet.
  2476. +* Either the source or destination address must be in DMEM, the other address can be in LMEM or DDR.
  2477. +* Both the source and destination must have the same 64bit alignment, length should be more than four bytes
  2478. +* or dst/src must be 32bit aligned. Otherwise use efet_memcpy_any()
  2479. +* Uses efet synchronous interface to copy the data.
  2480. +*
  2481. +* @param dst Destination address to write to (must have the same 64bit alignment as src)
  2482. +* @param src Source address to read from (must have the same 64bit alignment as dst)
  2483. +* @param len Number of bytes to copy
  2484. +*
  2485. +*/
  2486. +void efet_memcpy(void *dst, void *src, unsigned int len);
  2487. +
  2488. +/** Same 64bit alignment memory copy using efet.
  2489. +* Either the source or destination address must be in DMEM, the other address can be in LMEM or DDR.
  2490. +* Both the source and destination must have the same 64bit alignment, there is no restriction on length.
  2491. +* For UTIL-PE revA0, this function will still fail to handle small/unaligned writes.
  2492. +* Uses efet synchronous interface to copy the data.
  2493. +*
  2494. +* @param dst Destination address to write to (must have the same 64bit alignment as src)
  2495. +* @param src Source address to read from (must have the same 64bit alignment as dst)
  2496. +* @param len Number of bytes to copy
  2497. +*
  2498. +*/
  2499. +void efet_memcpy_any(void *dst, void *src, unsigned int len);
  2500. +
  2501. +/** Same 64bit alignment memory copy using efet.
  2502. +* Either the source or destination address must be in DMEM, the other address can be in LMEM or DDR.
  2503. +* Both the source and destination must have the same 64bit alignment, length should be more than four bytes
  2504. +* or dst/src must be 32bit aligned.
  2505. +* Uses efet asynchronous interface to copy the data.
  2506. +*
  2507. +* @param dst Destination address to write to (must have the same 64bit alignment as src)
  2508. +* @param src Source address to read from (must have the same 64bit alignment as dst)
  2509. +* @param len Number of bytes to copy
  2510. +*
  2511. +*/
  2512. +void efet_memcpy_nowait(void *dst, void *src, unsigned int len);
  2513. +
  2514. +/** Unaligned memory copy using efet.
  2515. +* Either the source or destination address must be in DMEM, the other address can be in LMEM or DDR.
  2516. +* There is not restriction on source and destination, nor on length.
  2517. +*
  2518. +* @param dst Destination address to write to
  2519. +* @param src Source address to read from
  2520. +* @param len Number of bytes to copy
  2521. +* @param dmem_buf temp dmem buffer to use, must be 64bit aligned
  2522. +* @param dmem_len length of dmem buffer, must be 64bit aligned and at least 16 bytes
  2523. +*
  2524. +*/
  2525. +void efet_memcpy_unaligned(void *dst, void *src, unsigned int len, void *dmem_buf, unsigned int dmem_len);
  2526. +
  2527. +/** Aligned memory copy of 4 bytes to register address.
  2528. +* Register address must be 32 bit aligned.
  2529. +*
  2530. +* @param val value to be copied.
  2531. +* @param reg_addr Register address (must be 16bit aligned)
  2532. +*
  2533. +*/
  2534. +void __efet_writel(u32 val, void *addr);
  2535. +
  2536. +#ifdef REVA_WA
  2537. +#define efet_writel(val, addr) __efet_writel((u32)(val), (void *) (addr))
  2538. +#else
  2539. +#define efet_writel(val, addr) writel((u32)(val), (void *) (addr))
  2540. +#endif
  2541. +
  2542. +
  2543. +/** 32bit aligned memory copy.
  2544. +* Source and destination addresses must be 32bit aligned, there is no restriction on the length.
  2545. +*
  2546. +* @param dst Destination address (must be 32bit aligned)
  2547. +* @param src Source address (must be 32bit aligned)
  2548. +* @param len Number of bytes to copy
  2549. +*
  2550. +*/
  2551. +void memcpy_aligned32(void *dst, void *src, unsigned int len);
  2552. +
  2553. +/** Aligned memory copy.
  2554. +* Source and destination addresses must have the same alignment
  2555. +* relative to 32bit boundaries (but otherwsie may have any alignment),
  2556. +* there is no restriction on the length.
  2557. +*
  2558. +* @param dst Destination address
  2559. +* @param src Source address (must have same 32bit alignment as dst)
  2560. +* @param len Number of bytes to copy
  2561. +*
  2562. +*/
  2563. +void memcpy_aligned(void *dst, void *src, unsigned int len);
  2564. +
  2565. +/** Unaligned memory copy.
  2566. +* Implements unaligned memory copy. We first align the destination
  2567. +* to a 32bit boundary (using byte copies) then the src, and finally use a loop
  2568. +* of read, shift, write
  2569. +*
  2570. +* @param dst Destination address
  2571. +* @param src Source address (must have same 32bit alignment as dst)
  2572. +* @param len Number of bytes to copy
  2573. +*
  2574. +*/
  2575. +void memcpy_unaligned(void *dst, void *src, unsigned int len);
  2576. +
  2577. +/** Generic memory set.
  2578. +* Implements a generic memory set. Not very optimal (uses byte writes for the entire range)
  2579. +*
  2580. +*
  2581. +* @param dst Destination address
  2582. +* @param val Value to set memory to
  2583. +* @param len Number of bytes to set
  2584. +*
  2585. +*/
  2586. +void memset(void *dst, u8 val, unsigned int len);
  2587. +
  2588. +/** Generic memory copy.
  2589. +* Implements generic memory copy. If source and destination have the same
  2590. +* alignment memcpy_aligned() is used, otherwise memcpy_unaligned()
  2591. +*
  2592. +* @param dst Destination address
  2593. +* @param src Source address
  2594. +* @param len Number of bytes to copy
  2595. +*
  2596. +*/
  2597. +void memcpy(void *dst, void *src, unsigned int len);
  2598. +
  2599. +/** Generic memorymove.
  2600. +* Implements generic memorymove, where copies across overlapping
  2601. +* memory regions is supported.
  2602. +* Uses the dmem_buf passed as a parameter as a temporary buffer.
  2603. +* Includes two copies, forces one of the copies to be definitely aligned.
  2604. +* The "dmem_len" being passed should be atleast 3 bytes greater than "len"
  2605. +* The 3 bytes here are shift bytes used to ensure one aligned copy.
  2606. +*
  2607. +* @param dst Destination address
  2608. +* @param src Source address
  2609. +* @param len Number of bytes to copy
  2610. +* @param dmem_buf temp dmem buffer to use, must be 32bit aligned
  2611. +* @param dmem_len length of dmem buffer, must be 32bit aligned and at least 3 bytes greater
  2612. +* than @param len
  2613. +*
  2614. +*/
  2615. +
  2616. +void *memorymove(void * dst, void * src, unsigned int len, void *dmem_buf, unsigned int dmem_len);
  2617. +
  2618. +/** Aligned memory copy in DDR memory.
  2619. + * Implements aligned memory copy between two DDR buffers using efet_memcpy64 and DMEM
  2620. + * Both the source and destination must have the same 64bit alignment, there is no restriction on length.
  2621. + * If start or end are not 64bit aligned, data in destination buffer before start/after end will be corrupted.
  2622. + *
  2623. + * @param dst DDR Destination address
  2624. + * @param src DDR Source address
  2625. + * @param len Number of bytes to copy
  2626. + * @param dmem_buf temp dmem buffer to use, must be 64bit aligned
  2627. + * @param dmem_len length of dmem buffer, must be 64bit aligned and at least 16 bytes
  2628. + */
  2629. +void memcpy_ddr_to_ddr(void *dst, void *src, unsigned int len, void *dmem_buf, unsigned int dmem_len);
  2630. +
  2631. +/** Unaligned memory copy in DDR memory.
  2632. + * Implements generic memory copy between two DDR buffers using efet_memcpy and DMEM
  2633. + * There is no restriction on the source, destination and length alignments.
  2634. + *
  2635. + * @param dst DDR Destination address
  2636. + * @param src DDR Source address
  2637. + * @param len Number of bytes to copy
  2638. + * @param dmem_buf temp dmem buffer to use, must be 64bit aligned
  2639. + * @param dmem_len length of dmem buffer, must be 64bit aligned and at least 16 bytes
  2640. + */
  2641. +void memcpy_ddr_to_ddr_unaligned(void *dst, void *src, unsigned int len, void *dmem_buf, unsigned int dmem_len);
  2642. +
  2643. +#endif /* _PE_H_ */
  2644. --- /dev/null
  2645. +++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h
  2646. @@ -0,0 +1,444 @@
  2647. +/*
  2648. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  2649. + *
  2650. + * This program is free software; you can redistribute it and/or
  2651. + * modify it under the terms of the GNU General Public License
  2652. + * as published by the Free Software Foundation; either version 2
  2653. + * of the License, or (at your option) any later version.
  2654. + *
  2655. + * This program is distributed in the hope that it will be useful,
  2656. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2657. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2658. + * GNU General Public License for more details.
  2659. + *
  2660. + * You should have received a copy of the GNU General Public License
  2661. + * along with this program; if not, write to the Free Software
  2662. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  2663. + *
  2664. +*/
  2665. +#ifndef _PFE_H_
  2666. +#define _PFE_H_
  2667. +
  2668. +#define CLASS_DMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20))
  2669. +#define CLASS_IMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) /* Only valid for mem access register interface */
  2670. +#define CLASS_DMEM_SIZE 0x00002000
  2671. +#define CLASS_IMEM_SIZE 0x00008000
  2672. +
  2673. +#define TMU_DMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20))
  2674. +#define TMU_IMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20)) /* Only valid for mem access register interface */
  2675. +#define TMU_DMEM_SIZE 0x00000800
  2676. +#define TMU_IMEM_SIZE 0x00002000
  2677. +
  2678. +#define UTIL_DMEM_BASE_ADDR 0x00000000
  2679. +#define UTIL_DMEM_SIZE 0x00002000
  2680. +
  2681. +#define PE_LMEM_BASE_ADDR 0xc3010000
  2682. +#define PE_LMEM_SIZE 0x8000
  2683. +#define PE_LMEM_END (PE_LMEM_BASE_ADDR + PE_LMEM_SIZE)
  2684. +
  2685. +#define DMEM_BASE_ADDR 0x00000000
  2686. +#define DMEM_SIZE 0x2000 /**< TMU has less... */
  2687. +#define DMEM_END (DMEM_BASE_ADDR + DMEM_SIZE)
  2688. +
  2689. +#define PMEM_BASE_ADDR 0x00010000
  2690. +#define PMEM_SIZE 0x8000 /**< TMU has less... */
  2691. +#define PMEM_END (PMEM_BASE_ADDR + PMEM_SIZE)
  2692. +
  2693. +
  2694. +/* These check memory ranges from PE point of view/memory map */
  2695. +#define IS_DMEM(addr, len) (((unsigned long)(addr) >= DMEM_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= DMEM_END))
  2696. +#define IS_PMEM(addr, len) (((unsigned long)(addr) >= PMEM_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= PMEM_END))
  2697. +#define IS_PE_LMEM(addr, len) (((unsigned long)(addr) >= PE_LMEM_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= PE_LMEM_END))
  2698. +
  2699. +#define IS_PFE_LMEM(addr, len) (((unsigned long)(addr) >= CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR)) && (((unsigned long)(addr) + (len)) <= CBUS_VIRT_TO_PFE(LMEM_END)))
  2700. +#define __IS_PHYS_DDR(addr, len) (((unsigned long)(addr) >= DDR_PHYS_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= DDR_PHYS_END))
  2701. +#define IS_PHYS_DDR(addr, len) __IS_PHYS_DDR(DDR_PFE_TO_PHYS(addr), len)
  2702. +
  2703. +/* If using a run-time virtual address for the cbus base address use this code */
  2704. +extern void *cbus_base_addr;
  2705. +extern void *ddr_base_addr;
  2706. +extern unsigned long ddr_phys_base_addr;
  2707. +extern unsigned int ddr_size;
  2708. +
  2709. +#if defined(COMCERTO_2000_CONTROL)
  2710. +#include <linux/version.h>
  2711. +#if defined (CONFIG_PLATFORM_C2000)
  2712. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
  2713. +/*This is copied from arch/arm/include/asm/system_info.h */
  2714. +extern unsigned int system_rev;
  2715. +#endif
  2716. +#endif
  2717. +#endif
  2718. +
  2719. +#define CBUS_BASE_ADDR cbus_base_addr
  2720. +#define DDR_PHYS_BASE_ADDR ddr_phys_base_addr
  2721. +#define DDR_BASE_ADDR ddr_base_addr
  2722. +#define DDR_SIZE ddr_size
  2723. +
  2724. +#define DDR_PHYS_END (DDR_PHYS_BASE_ADDR + DDR_SIZE)
  2725. +
  2726. +#if defined(CONFIG_PLATFORM_C2000)
  2727. +#define PFE_CBUS_PHYS_BASE_ADDR 0xc0000000 /**< CBUS physical base address as seen by PE's. */
  2728. +#define DDR_PHYS_TO_PFE(p) (p)
  2729. +#define DDR_PFE_TO_PHYS(p) (p)
  2730. +#define CBUS_PHYS_TO_PFE(p) (p)
  2731. +#else
  2732. +#define LS1012A_PFE_RESET_WA /*PFE doesn't have global reset and re-init should takecare few things to make PFE functional after reset */
  2733. +#define PFE_CBUS_PHYS_BASE_ADDR 0xc0000000 /**< CBUS physical base address as seen by PE's. */
  2734. +#define PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE 0xc0000000 /**< CBUS physical base address as seen by PE's. */
  2735. +#define DDR_PHYS_TO_PFE(p) (((unsigned long int) (p)) & 0x7FFFFFFF)
  2736. +#define DDR_PFE_TO_PHYS(p) (((unsigned long int) (p)) | 0x80000000)
  2737. +#define CBUS_PHYS_TO_PFE(p) (((p) - PFE_CBUS_PHYS_BASE_ADDR) + PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE) /*Translates to PFE address map */
  2738. +#endif
  2739. +
  2740. +#define DDR_PHYS_TO_VIRT(p) (((p) - DDR_PHYS_BASE_ADDR) + DDR_BASE_ADDR)
  2741. +#define DDR_VIRT_TO_PHYS(v) (((v) - DDR_BASE_ADDR) + DDR_PHYS_BASE_ADDR)
  2742. +#define DDR_VIRT_TO_PFE(p) (DDR_PHYS_TO_PFE(DDR_VIRT_TO_PHYS(p)))
  2743. +
  2744. +#define CBUS_VIRT_TO_PFE(v) (((v) - CBUS_BASE_ADDR) + PFE_CBUS_PHYS_BASE_ADDR)
  2745. +#define CBUS_PFE_TO_VIRT(p) (((p) - PFE_CBUS_PHYS_BASE_ADDR) + CBUS_BASE_ADDR)
  2746. +
  2747. +/* The below part of the code is used in QOS control driver from host */
  2748. +#define TMU_APB_BASE_ADDR 0xc1000000 /** TMU base address seen by pe's */
  2749. +
  2750. +#define SHAPER0_BASE_ADDR (TMU_APB_BASE_ADDR + 0x020000)
  2751. +#define SHAPER1_BASE_ADDR (TMU_APB_BASE_ADDR + 0x030000)
  2752. +#define SHAPER2_BASE_ADDR (TMU_APB_BASE_ADDR + 0x040000)
  2753. +#define SHAPER3_BASE_ADDR (TMU_APB_BASE_ADDR + 0x050000)
  2754. +#define SHAPER4_BASE_ADDR (TMU_APB_BASE_ADDR + 0x060000)
  2755. +#define SHAPER5_BASE_ADDR (TMU_APB_BASE_ADDR + 0x070000)
  2756. +#define SHAPER6_BASE_ADDR (TMU_APB_BASE_ADDR + 0x080000)
  2757. +#define SHAPER7_BASE_ADDR (TMU_APB_BASE_ADDR + 0x090000)
  2758. +#define SHAPER8_BASE_ADDR (TMU_APB_BASE_ADDR + 0x0a0000)
  2759. +#define SHAPER9_BASE_ADDR (TMU_APB_BASE_ADDR + 0x0b0000)
  2760. +
  2761. +#define SCHED0_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1c0000)
  2762. +#define SCHED1_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1d0000)
  2763. +#define SCHED2_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1e0000)
  2764. +#define SCHED3_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1f0000)
  2765. +#define SCHED4_BASE_ADDR (TMU_APB_BASE_ADDR + 0x200000)
  2766. +#define SCHED5_BASE_ADDR (TMU_APB_BASE_ADDR + 0x210000)
  2767. +#define SCHED6_BASE_ADDR (TMU_APB_BASE_ADDR + 0x220000)
  2768. +#define SCHED7_BASE_ADDR (TMU_APB_BASE_ADDR + 0x230000)
  2769. +
  2770. +#define PHY_QUEUE_BASE_ADDR (TMU_APB_BASE_ADDR + 0x260000)
  2771. +#define QUEUE_RESULT0 (PHY_QUEUE_BASE_ADDR + 0x48) /**< [7] set to one to indicate output PHY (TMU0->PHY0, TMU1->PHY1, TMU2->PHY2, TMU3->PHY3), [6:0] winner input queue number */
  2772. +#define QUEUE_RESULT1 (PHY_QUEUE_BASE_ADDR + 0x4c) /**< [7] set to one to indicate output PHY (TMU0->PHY0, TMU1->PHY1, TMU2->PHY2, TMU3->PHY4), [6:0] winner input queue number */
  2773. +#define QUEUE_RESULT2 (PHY_QUEUE_BASE_ADDR + 0x50) /**< [7] set to one to indicate output PHY (TMU0->PHY0, TMU1->PHY1, TMU2->PHY2, TMU3->PHY5), [6:0] winner input queue number */
  2774. +
  2775. +#define QUEUE_RESULT0_REGOFFSET (QUEUE_RESULT0 - QUEUE_RESULT0)
  2776. +#define QUEUE_RESULT1_REGOFFSET (QUEUE_RESULT1 - QUEUE_RESULT0)
  2777. +#define QUEUE_RESULT2_REGOFFSET (QUEUE_RESULT2 - QUEUE_RESULT0)
  2778. +
  2779. +
  2780. +#include "cbus.h"
  2781. +
  2782. +enum {
  2783. + CLASS0_ID = 0,
  2784. + CLASS1_ID,
  2785. + CLASS2_ID,
  2786. + CLASS3_ID,
  2787. +#if !defined(CONFIG_PLATFORM_PCI)
  2788. + CLASS4_ID,
  2789. + CLASS5_ID,
  2790. +#endif
  2791. +#if !defined(CONFIG_TMU_DUMMY)
  2792. + TMU0_ID,
  2793. + TMU1_ID,
  2794. + TMU2_ID,
  2795. + TMU3_ID,
  2796. +#else
  2797. + TMU0_ID,
  2798. +#endif
  2799. +#if !defined(CONFIG_UTIL_DISABLED)
  2800. + UTIL_ID,
  2801. +#endif
  2802. + MAX_PE
  2803. +};
  2804. +
  2805. +enum {
  2806. + CLASS_TYPE = 0,
  2807. + TMU_TYPE,
  2808. + UTIL_TYPE
  2809. +};
  2810. +
  2811. +#if !defined(CONFIG_PLATFORM_PCI)
  2812. +#define CLASS_MASK ((1 << CLASS0_ID) | (1 << CLASS1_ID) | (1 << CLASS2_ID) | (1 << CLASS3_ID) | (1 << CLASS4_ID) | (1 << CLASS5_ID))
  2813. +#define CLASS_MAX_ID CLASS5_ID
  2814. +#else
  2815. +#define CLASS_MASK ((1 << CLASS0_ID) | (1 << CLASS1_ID) | (1 << CLASS2_ID) | (1 << CLASS3_ID))
  2816. +#define CLASS_MAX_ID CLASS3_ID
  2817. +#endif
  2818. +
  2819. +#if !defined(CONFIG_TMU_DUMMY)
  2820. +#if defined(CONFIG_PLATFORM_LS1012A)
  2821. +#define TMU_MASK ((1 << TMU0_ID) | (1 << TMU1_ID) | (1 << TMU3_ID))
  2822. +#else
  2823. +#define TMU_MASK ((1 << TMU0_ID) | (1 << TMU1_ID) | (1 << TMU2_ID) | (1 << TMU3_ID))
  2824. +#endif
  2825. +#define TMU_MAX_ID TMU3_ID
  2826. +#else
  2827. +#define TMU_MASK (1 << TMU0_ID)
  2828. +#define TMU_MAX_ID TMU0_ID
  2829. +#endif
  2830. +
  2831. +#if !defined(CONFIG_UTIL_DISABLED)
  2832. +#define UTIL_MASK (1 << UTIL_ID)
  2833. +#endif
  2834. +
  2835. +typedef struct tPE_STATUS
  2836. +{
  2837. + u32 cpu_state;
  2838. + u32 activity_counter;
  2839. + u32 rx;
  2840. + union {
  2841. + u32 tx;
  2842. + u32 tmu_qstatus;
  2843. + };
  2844. + u32 drop;
  2845. +#if defined(CFG_PE_DEBUG)
  2846. + u32 debug_indicator;
  2847. + u32 debug[16];
  2848. +#endif
  2849. +} __attribute__((aligned(16))) PE_STATUS;
  2850. +
  2851. +
  2852. +struct pe_sync_mailbox
  2853. +{
  2854. + u32 stop;
  2855. + u32 stopped;
  2856. +};
  2857. +
  2858. +struct pe_msg_mailbox
  2859. +{
  2860. + u32 dst;
  2861. + u32 src;
  2862. + u32 len;
  2863. + u32 request;
  2864. +};
  2865. +
  2866. +// Drop counter definitions
  2867. +
  2868. +#define CLASS_NUM_DROP_COUNTERS 13
  2869. +#define UTIL_NUM_DROP_COUNTERS 8
  2870. +
  2871. +
  2872. +/** PE information.
  2873. + * Structure containing PE's specific information. It is used to create
  2874. + * generic C functions common to all PE's.
  2875. + * Before using the library functions this structure needs to be initialized with the different registers virtual addresses
  2876. + * (according to the ARM MMU mmaping). The default initialization supports a virtual == physical mapping.
  2877. + *
  2878. + */
  2879. +struct pe_info
  2880. +{
  2881. + u32 dmem_base_addr; /**< PE's dmem base address */
  2882. + u32 pmem_base_addr; /**< PE's pmem base address */
  2883. + u32 pmem_size; /**< PE's pmem size */
  2884. +
  2885. + void *mem_access_wdata; /**< PE's _MEM_ACCESS_WDATA register address */
  2886. + void *mem_access_addr; /**< PE's _MEM_ACCESS_ADDR register address */
  2887. + void *mem_access_rdata; /**< PE's _MEM_ACCESS_RDATA register address */
  2888. +};
  2889. +
  2890. +
  2891. +void pe_lmem_read(u32 *dst, u32 len, u32 offset);
  2892. +void pe_lmem_write(u32 *src, u32 len, u32 offset);
  2893. +
  2894. +void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
  2895. +void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
  2896. +
  2897. +u32 pe_pmem_read(int id, u32 addr, u8 size);
  2898. +
  2899. +void pe_dmem_write(int id, u32 val, u32 addr, u8 size);
  2900. +u32 pe_dmem_read(int id, u32 addr, u8 size);
  2901. +void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len);
  2902. +void class_pe_lmem_memset(u32 dst, int val, unsigned int len);
  2903. +void class_bus_write(u32 val, u32 addr, u8 size);
  2904. +u32 class_bus_read(u32 addr, u8 size);
  2905. +
  2906. +
  2907. +#define class_bus_readl(addr) class_bus_read(addr, 4)
  2908. +#define class_bus_readw(addr) class_bus_read(addr, 2)
  2909. +#define class_bus_readb(addr) class_bus_read(addr, 1)
  2910. +
  2911. +#define class_bus_writel(val, addr) class_bus_write(val, addr, 4)
  2912. +#define class_bus_writew(val, addr) class_bus_write(val, addr, 2)
  2913. +#define class_bus_writeb(val, addr) class_bus_write(val, addr, 1)
  2914. +
  2915. +#define pe_dmem_readl(id, addr) pe_dmem_read(id, addr, 4)
  2916. +#define pe_dmem_readw(id, addr) pe_dmem_read(id, addr, 2)
  2917. +#define pe_dmem_readb(id, addr) pe_dmem_read(id, addr, 1)
  2918. +
  2919. +#define pe_dmem_writel(id, val, addr) pe_dmem_write(id, val, addr, 4)
  2920. +#define pe_dmem_writew(id, val, addr) pe_dmem_write(id, val, addr, 2)
  2921. +#define pe_dmem_writeb(id, val, addr) pe_dmem_write(id, val, addr, 1)
  2922. +
  2923. +//int pe_load_elf_section(int id, const void *data, Elf32_Shdr *shdr);
  2924. +int pe_load_elf_section(int id, const void *data, Elf32_Shdr *shdr, struct device *dev);
  2925. +
  2926. +void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, unsigned int ddr_size);
  2927. +void bmu_init(void *base, BMU_CFG *cfg);
  2928. +void bmu_reset(void *base);
  2929. +void bmu_enable(void *base);
  2930. +void bmu_disable(void *base);
  2931. +void bmu_set_config(void *base, BMU_CFG *cfg);
  2932. +
  2933. +/* An enumerated type for loopback values. This can be one of three values, no
  2934. + * loopback -normal operation, local loopback with internal loopback module of
  2935. + * MAC or PHY loopback which is through the external PHY.
  2936. + */
  2937. +#ifndef __MAC_LOOP_ENUM__
  2938. +#define __MAC_LOOP_ENUM__
  2939. +typedef enum {LB_NONE, LB_EXT, LB_LOCAL} MAC_LOOP;
  2940. +#endif
  2941. +
  2942. +
  2943. +void gemac_init(void *base, void *config);
  2944. +void gemac_disable_rx_checksum_offload(void *base);
  2945. +void gemac_enable_rx_checksum_offload(void *base);
  2946. +void gemac_set_mdc_div(void *base, int mdc_div);
  2947. +void gemac_set_speed(void *base, MAC_SPEED gem_speed);
  2948. +void gemac_set_duplex(void *base, int duplex);
  2949. +void gemac_set_mode(void *base, int mode);
  2950. +void gemac_enable(void *base);
  2951. +void gemac_tx_disable(void *base);
  2952. +void gemac_disable(void *base);
  2953. +void gemac_reset(void *base);
  2954. +void gemac_set_address(void *base, SPEC_ADDR *addr);
  2955. +SPEC_ADDR gemac_get_address(void *base);
  2956. +void gemac_set_loop( void *base, MAC_LOOP gem_loop );
  2957. +void gemac_set_laddr1(void *base, MAC_ADDR *address);
  2958. +void gemac_set_laddr2(void *base, MAC_ADDR *address);
  2959. +void gemac_set_laddr3(void *base, MAC_ADDR *address);
  2960. +void gemac_set_laddr4(void *base, MAC_ADDR *address);
  2961. +void gemac_set_laddrN(void *base, MAC_ADDR *address, unsigned int entry_index);
  2962. +void gemac_clear_laddr1(void *base);
  2963. +void gemac_clear_laddr2(void *base);
  2964. +void gemac_clear_laddr3(void *base);
  2965. +void gemac_clear_laddr4(void *base);
  2966. +void gemac_clear_laddrN(void *base, unsigned int entry_index);
  2967. +MAC_ADDR gemac_get_hash( void *base );
  2968. +void gemac_set_hash( void *base, MAC_ADDR *hash );
  2969. +MAC_ADDR gem_get_laddr1(void *base);
  2970. +MAC_ADDR gem_get_laddr2(void *base);
  2971. +MAC_ADDR gem_get_laddr3(void *base);
  2972. +MAC_ADDR gem_get_laddr4(void *base);
  2973. +MAC_ADDR gem_get_laddrN(void *base, unsigned int entry_index);
  2974. +void gemac_set_config(void *base, GEMAC_CFG *cfg);
  2975. +void gemac_allow_broadcast(void *base);
  2976. +void gemac_no_broadcast(void *base);
  2977. +void gemac_enable_unicast(void *base);
  2978. +void gemac_disable_unicast(void *base);
  2979. +void gemac_enable_multicast(void *base);
  2980. +void gemac_disable_multicast(void *base);
  2981. +void gemac_enable_fcs_rx(void *base);
  2982. +void gemac_disable_fcs_rx(void *base);
  2983. +void gemac_enable_1536_rx(void *base);
  2984. +void gemac_disable_1536_rx(void *base);
  2985. +void gemac_enable_rx_jmb(void *base);
  2986. +void gemac_disable_rx_jmb(void *base);
  2987. +void gemac_enable_stacked_vlan(void *base);
  2988. +void gemac_disable_stacked_vlan(void *base);
  2989. +void gemac_enable_pause_rx(void *base);
  2990. +void gemac_disable_pause_rx(void *base);
  2991. +void gemac_enable_copy_all(void *base);
  2992. +void gemac_disable_copy_all(void *base);
  2993. +void gemac_set_bus_width(void *base, int width);
  2994. +void gemac_set_wol(void *base, u32 wol_conf);
  2995. +
  2996. +void gpi_init(void *base, GPI_CFG *cfg);
  2997. +void gpi_reset(void *base);
  2998. +void gpi_enable(void *base);
  2999. +void gpi_disable(void *base);
  3000. +void gpi_set_config(void *base, GPI_CFG *cfg);
  3001. +
  3002. +void class_init(CLASS_CFG *cfg);
  3003. +void class_reset(void);
  3004. +void class_enable(void);
  3005. +void class_disable(void);
  3006. +void class_set_config(CLASS_CFG *cfg);
  3007. +
  3008. +void tmu_reset(void);
  3009. +void tmu_init(TMU_CFG *cfg);
  3010. +void tmu_enable(u32 pe_mask);
  3011. +void tmu_disable(u32 pe_mask);
  3012. +u32 tmu_qstatus(u32 if_id);
  3013. +u32 tmu_pkts_processed(u32 if_id);
  3014. +
  3015. +void util_init(UTIL_CFG *cfg);
  3016. +void util_reset(void);
  3017. +void util_enable(void);
  3018. +void util_disable(void);
  3019. +
  3020. +void hif_nocpy_init(void);
  3021. +void hif_nocpy_tx_enable(void);
  3022. +void hif_nocpy_tx_disable(void);
  3023. +void hif_nocpy_rx_enable(void);
  3024. +void hif_nocpy_rx_disable(void);
  3025. +
  3026. +void hif_init(void);
  3027. +void hif_tx_enable(void);
  3028. +void hif_tx_disable(void);
  3029. +void hif_rx_enable(void);
  3030. +void hif_rx_disable(void);
  3031. +
  3032. +
  3033. +/** Get Chip Revision level
  3034. +*
  3035. +*/
  3036. +
  3037. +static inline unsigned int CHIP_REVISION(void)
  3038. +{
  3039. +#if defined (CONFIG_PLATFORM_C2000)
  3040. +#if 1
  3041. + return system_rev;
  3042. + //return 0;
  3043. +#else
  3044. + return (readl(COMCERTO_GPIO_DEVICE_ID_REG) >> 24) & 0xf;
  3045. +#endif
  3046. +
  3047. +#else
  3048. + /*For LS1012A return always 1 */
  3049. + return 1;
  3050. +#endif
  3051. +}
  3052. +
  3053. +/** Start HIF rx DMA
  3054. +*
  3055. +*/
  3056. +static inline void hif_rx_dma_start(void)
  3057. +{
  3058. + /*TODO not sure poll_cntrl_en is required or not */
  3059. + writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_RX_CTRL);
  3060. +}
  3061. +
  3062. +/** Start HIF tx DMA
  3063. +*
  3064. +*/
  3065. +static inline void hif_tx_dma_start(void)
  3066. +{
  3067. + /*TODO not sure poll_cntrl_en is required or not */
  3068. + writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL);
  3069. +}
  3070. +
  3071. +/** Start HIF_NOCPY rx DMA
  3072. +*
  3073. +*/
  3074. +static inline void hif_nocpy_rx_dma_start(void)
  3075. +{
  3076. + /*TODO not sure poll_cntrl_en is required or not */
  3077. + writel((HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB), HIF_NOCPY_RX_CTRL);
  3078. +}
  3079. +
  3080. +/** Start HIF_NOCPY tx DMA
  3081. +*
  3082. +*/
  3083. +static inline void hif_nocpy_tx_dma_start(void)
  3084. +{
  3085. + /*TODO not sure poll_cntrl_en is required or not */
  3086. + writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_NOCPY_TX_CTRL);
  3087. +}
  3088. +
  3089. +#endif /* _PFE_H_ */
  3090. +
  3091. --- /dev/null
  3092. +++ b/drivers/staging/fsl_ppfe/include/pfe/tmu.h
  3093. @@ -0,0 +1,68 @@
  3094. +/*
  3095. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3096. + *
  3097. + * This program is free software; you can redistribute it and/or
  3098. + * modify it under the terms of the GNU General Public License
  3099. + * as published by the Free Software Foundation; either version 2
  3100. + * of the License, or (at your option) any later version.
  3101. + *
  3102. + * This program is distributed in the hope that it will be useful,
  3103. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3104. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3105. + * GNU General Public License for more details.
  3106. + *
  3107. + * You should have received a copy of the GNU General Public License
  3108. + * along with this program; if not, write to the Free Software
  3109. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3110. + *
  3111. +*/
  3112. +#ifndef _TMU_H_
  3113. +#define _TMU_H_
  3114. +
  3115. +#define TMU_DMEM_BASE_ADDR 0x00000000
  3116. +#define TMU_PMEM_BASE_ADDR 0x00010000
  3117. +
  3118. +#define CBUS_BASE_ADDR 0xc0000000
  3119. +#define TMU_APB_BASE_ADDR 0xc1000000
  3120. +
  3121. +#if defined (COMCERTO_2000_TMU) || defined (COMCERTO_2000_CONTROL)
  3122. +
  3123. +#include "cbus.h"
  3124. +
  3125. +#define GPT_BASE_ADDR (TMU_APB_BASE_ADDR + 0x00000)
  3126. +#define UART_BASE_ADDR (TMU_APB_BASE_ADDR + 0x10000)
  3127. +
  3128. +#define SHAPER0_BASE_ADDR (TMU_APB_BASE_ADDR + 0x020000)
  3129. +#define SHAPER1_BASE_ADDR (TMU_APB_BASE_ADDR + 0x030000)
  3130. +#define SHAPER2_BASE_ADDR (TMU_APB_BASE_ADDR + 0x040000)
  3131. +#define SHAPER3_BASE_ADDR (TMU_APB_BASE_ADDR + 0x050000)
  3132. +#define SHAPER4_BASE_ADDR (TMU_APB_BASE_ADDR + 0x060000)
  3133. +#define SHAPER5_BASE_ADDR (TMU_APB_BASE_ADDR + 0x070000)
  3134. +#define SHAPER6_BASE_ADDR (TMU_APB_BASE_ADDR + 0x080000)
  3135. +#define SHAPER7_BASE_ADDR (TMU_APB_BASE_ADDR + 0x090000)
  3136. +#define SHAPER8_BASE_ADDR (TMU_APB_BASE_ADDR + 0x0a0000)
  3137. +#define SHAPER9_BASE_ADDR (TMU_APB_BASE_ADDR + 0x0b0000)
  3138. +
  3139. +#define SCHED0_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1c0000)
  3140. +#define SCHED1_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1d0000)
  3141. +#define SCHED2_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1e0000)
  3142. +#define SCHED3_BASE_ADDR (TMU_APB_BASE_ADDR + 0x1f0000)
  3143. +#define SCHED4_BASE_ADDR (TMU_APB_BASE_ADDR + 0x200000)
  3144. +#define SCHED5_BASE_ADDR (TMU_APB_BASE_ADDR + 0x210000)
  3145. +#define SCHED6_BASE_ADDR (TMU_APB_BASE_ADDR + 0x220000)
  3146. +#define SCHED7_BASE_ADDR (TMU_APB_BASE_ADDR + 0x230000)
  3147. +
  3148. +#define SHAPER_STATUS (TMU_APB_BASE_ADDR + 0x270000) /**< [9:0] bitmask of shapers that have positive credit */
  3149. +
  3150. +#include "gpt.h"
  3151. +#include "uart.h"
  3152. +#include "tmu/shaper.h"
  3153. +#include "tmu/sched.h"
  3154. +
  3155. +#endif
  3156. +
  3157. +#define PHY_QUEUE_BASE_ADDR (TMU_APB_BASE_ADDR + 0x260000)
  3158. +
  3159. +#include "tmu/phy_queue.h"
  3160. +
  3161. +#endif /* _TMU_H_ */
  3162. --- /dev/null
  3163. +++ b/drivers/staging/fsl_ppfe/include/pfe/tmu/phy_queue.h
  3164. @@ -0,0 +1,56 @@
  3165. +/*
  3166. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3167. + *
  3168. + * This program is free software; you can redistribute it and/or
  3169. + * modify it under the terms of the GNU General Public License
  3170. + * as published by the Free Software Foundation; either version 2
  3171. + * of the License, or (at your option) any later version.
  3172. + *
  3173. + * This program is distributed in the hope that it will be useful,
  3174. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3175. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3176. + * GNU General Public License for more details.
  3177. + *
  3178. + * You should have received a copy of the GNU General Public License
  3179. + * along with this program; if not, write to the Free Software
  3180. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3181. + *
  3182. +*/
  3183. +#ifndef _PHY_QUEUE_H_
  3184. +#define _PHY_QUEUE_H_
  3185. +
  3186. +#define PHY_QUEUE_SHAPER_STATUS (PHY_QUEUE_BASE_ADDR + 0x00) /**< [28:19] same as SHAPER_STATUS, [18:3] same as QUEUE_STATUS, [2:0] must be zero before a new packet may be dequeued */
  3187. +#define QUEUE_STATUS (PHY_QUEUE_BASE_ADDR + 0x04) /**< [15:0] bit mask of input queues with pending packets */
  3188. +
  3189. +#define QUEUE0_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x08)
  3190. +#define QUEUE1_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x0c)
  3191. +#define QUEUE2_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x10)
  3192. +#define QUEUE3_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x14)
  3193. +#define QUEUE4_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x18)
  3194. +#define QUEUE5_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x1c)
  3195. +#define QUEUE6_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x20)
  3196. +#define QUEUE7_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x24)
  3197. +#define QUEUE8_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x28)
  3198. +#define QUEUE9_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x2c)
  3199. +#define QUEUE10_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x30)
  3200. +#define QUEUE11_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x34)
  3201. +#define QUEUE12_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x38)
  3202. +#define QUEUE13_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x3c)
  3203. +#define QUEUE14_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x40)
  3204. +#define QUEUE15_PKT_LEN (PHY_QUEUE_BASE_ADDR + 0x44)
  3205. +#define QUEUE_RESULT0 (PHY_QUEUE_BASE_ADDR + 0x48) /**< [7] set to one to indicate output PHY (TMU0->PHY0, TMU1->PHY1, TMU2->PHY2, TMU3->PHY3), [6:0] winner input queue number */
  3206. +#define QUEUE_RESULT1 (PHY_QUEUE_BASE_ADDR + 0x4c) /**< [7] set to one to indicate output PHY (TMU0->PHY0, TMU1->PHY1, TMU2->PHY2, TMU3->PHY4), [6:0] winner input queue number */
  3207. +#define QUEUE_RESULT2 (PHY_QUEUE_BASE_ADDR + 0x50) /**< [7] set to one to indicate output PHY (TMU0->PHY0, TMU1->PHY1, TMU2->PHY2, TMU3->PHY5), [6:0] winner input queue number */
  3208. +#define TMU_PE_GP_REG (PHY_QUEUE_BASE_ADDR + 0x54)
  3209. +#define QUEUE_GBL_PKTLEN (PHY_QUEUE_BASE_ADDR + 0x5c)
  3210. +#define QUEUE_GBL_PKTLEN_MASK (PHY_QUEUE_BASE_ADDR + 0x60)
  3211. +
  3212. +#define QUEUE_RESULT0_REGOFFSET (QUEUE_RESULT0 - QUEUE_RESULT0)
  3213. +#define QUEUE_RESULT1_REGOFFSET (QUEUE_RESULT1 - QUEUE_RESULT0)
  3214. +#define QUEUE_RESULT2_REGOFFSET (QUEUE_RESULT2 - QUEUE_RESULT0)
  3215. +
  3216. +#define TEQ_HTD (1 << 22)
  3217. +#define TEQ_HWRED (1 << 21)
  3218. +
  3219. +
  3220. +#endif /* _PHY_QUEUE_H_ */
  3221. --- /dev/null
  3222. +++ b/drivers/staging/fsl_ppfe/include/pfe/tmu/sched.h
  3223. @@ -0,0 +1,72 @@
  3224. +/*
  3225. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3226. + *
  3227. + * This program is free software; you can redistribute it and/or
  3228. + * modify it under the terms of the GNU General Public License
  3229. + * as published by the Free Software Foundation; either version 2
  3230. + * of the License, or (at your option) any later version.
  3231. + *
  3232. + * This program is distributed in the hope that it will be useful,
  3233. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3234. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3235. + * GNU General Public License for more details.
  3236. + *
  3237. + * You should have received a copy of the GNU General Public License
  3238. + * along with this program; if not, write to the Free Software
  3239. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3240. + *
  3241. +*/
  3242. +#ifndef _SCHED_H_
  3243. +#define _SCHED_H_
  3244. +
  3245. +/* Offsets from SCHEDx_BASE_ADDR */
  3246. +#define SCHED_CTRL 0x00
  3247. +#define SCHED_SLOT_TIME 0x04
  3248. +#define SCHED_RES 0x08
  3249. +#define SCHED_QUEUE_ALLOC0 0x0c
  3250. +#define SCHED_QUEUE_ALLOC1 0x10
  3251. +#define SCHED_BW 0x14
  3252. +#define SCHED_GUR_DEF_CTR 0x18
  3253. +#define SCHED_AVL_CTR 0x1c
  3254. +#define SCHED_QU0_WGHT 0x20
  3255. +#define SCHED_QU1_WGHT 0x24
  3256. +#define SCHED_QU2_WGHT 0x28
  3257. +#define SCHED_QU3_WGHT 0x2c
  3258. +#define SCHED_QU4_WGHT 0x30
  3259. +#define SCHED_QU5_WGHT 0x34
  3260. +#define SCHED_QU6_WGHT 0x38
  3261. +#define SCHED_QU7_WGHT 0x3c
  3262. +#define SCHED_QUE0_DEFICIT_CNT 0x40
  3263. +#define SCHED_QUE1_DEFICIT_CNT 0x44
  3264. +#define SCHED_QUE2_DEFICIT_CNT 0x48
  3265. +#define SCHED_QUE3_DEFICIT_CNT 0x4c
  3266. +#define SCHED_QUE4_DEFICIT_CNT 0x50
  3267. +#define SCHED_QUE5_DEFICIT_CNT 0x54
  3268. +#define SCHED_QUE6_DEFICIT_CNT 0x58
  3269. +#define SCHED_QUE7_DEFICIT_CNT 0x5c
  3270. +#define SCHED_PKT_LEN 0x60
  3271. +
  3272. +#define SCHED_CTRL_ALGOTYPE(x) (((x) & 0xf) << 0)
  3273. +#define SCHED_CTRL_CALQUOTA(x) (((x) & 0x1) << 4)
  3274. +#define SCHED_CTRL_ACTIVE_Q(x) (((x) & 0xff) << 8)
  3275. +#define SCHED_CTRL_SHARE_BW(x) (((x) & 0xff) << 16)
  3276. +#define SCHED_CTRL_BARROW_BW(x) (((x) & 0xff) << 24)
  3277. +
  3278. +#define SCHED_QUEUE_ALLOC(x, b) (((x) & 0x1f) << (b))
  3279. +
  3280. +#define SCHED_QUEUE_ALLOC0_QUEUEA(x) (((x) & 0x1f) << 0)
  3281. +#define SCHED_QUEUE_ALLOC0_QUEUEB(x) (((x) & 0x1f) << 8)
  3282. +#define SCHED_QUEUE_ALLOC0_QUEUEC(x) (((x) & 0x1f) << 16)
  3283. +#define SCHED_QUEUE_ALLOC0_QUEUED(x) (((x) & 0x1f) << 24)
  3284. +
  3285. +#define SCHED_QUEUE_ALLOC0_RES0(x) (((x) & 0x7) << 5)
  3286. +#define SCHED_QUEUE_ALLOC0_RES1(x) (((x) & 0x7) << 13)
  3287. +#define SCHED_QUEUE_ALLOC0_RES2(x) (((x) & 0x7) << 21)
  3288. +#define SCHED_QUEUE_ALLOC0_RES3(x) (((x) & 0x7) << 29)
  3289. +
  3290. +#define SCHED_QUEUE_ALLOC1_QUEUEA(x) (((x) & 0x1f) << 0)
  3291. +#define SCHED_QUEUE_ALLOC1_QUEUEB(x) (((x) & 0x1f) << 8)
  3292. +#define SCHED_QUEUE_ALLOC1_QUEUEC(x) (((x) & 0x1f) << 16)
  3293. +#define SCHED_QUEUE_ALLOC1_QUEUED(x) (((x) & 0x1f) << 24)
  3294. +
  3295. +#endif /* _SCHED_H_ */
  3296. --- /dev/null
  3297. +++ b/drivers/staging/fsl_ppfe/include/pfe/tmu/shaper.h
  3298. @@ -0,0 +1,37 @@
  3299. +/*
  3300. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3301. + *
  3302. + * This program is free software; you can redistribute it and/or
  3303. + * modify it under the terms of the GNU General Public License
  3304. + * as published by the Free Software Foundation; either version 2
  3305. + * of the License, or (at your option) any later version.
  3306. + *
  3307. + * This program is distributed in the hope that it will be useful,
  3308. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3309. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3310. + * GNU General Public License for more details.
  3311. + *
  3312. + * You should have received a copy of the GNU General Public License
  3313. + * along with this program; if not, write to the Free Software
  3314. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3315. + *
  3316. +*/
  3317. +#ifndef _SHAPER_H_
  3318. +#define _SHAPER_H_
  3319. +
  3320. +/* Offsets from SHAPPERx_BASE_ADDR */
  3321. +#define SHAPER_CTRL 0x00
  3322. +#define SHAPER_WEIGHT 0x04
  3323. +#define SHAPER_PKT_LEN 0x08
  3324. +
  3325. +#define SHAPER_CTRL_ENABLE(x) (((x) & 0x1) << 0)
  3326. +#define SHAPER_CTRL_QNO(x) (((x) & 0x3f) << 1)
  3327. +#define SHAPER_CTRL_CLKDIV(x) (((x) & 0xffff) << 16)
  3328. +
  3329. +#define SHAPER_WEIGHT_FRACWT(x) (((x) & 0xff) << 0)
  3330. +#define SHAPER_WEIGHT_INTWT(x) (((x) & 0x3) << 8)
  3331. +#define SHAPER_WEIGHT_MAXCREDIT(x) (((x) & 0x3fffff) << 10)
  3332. +
  3333. +#define PORT_SHAPER_MASK (1 << 0)
  3334. +
  3335. +#endif /* _SHAPER_H_ */
  3336. --- /dev/null
  3337. +++ b/drivers/staging/fsl_ppfe/include/pfe/uart.h
  3338. @@ -0,0 +1,31 @@
  3339. +/*
  3340. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3341. + *
  3342. + * This program is free software; you can redistribute it and/or
  3343. + * modify it under the terms of the GNU General Public License
  3344. + * as published by the Free Software Foundation; either version 2
  3345. + * of the License, or (at your option) any later version.
  3346. + *
  3347. + * This program is distributed in the hope that it will be useful,
  3348. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3349. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3350. + * GNU General Public License for more details.
  3351. + *
  3352. + * You should have received a copy of the GNU General Public License
  3353. + * along with this program; if not, write to the Free Software
  3354. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3355. + *
  3356. +*/
  3357. +#ifndef _UART_H_
  3358. +#define _UART_H_
  3359. +
  3360. +#define UART_THR (UART_BASE_ADDR + 0x00)
  3361. +#define UART_IER (UART_BASE_ADDR + 0x04)
  3362. +#define UART_IIR (UART_BASE_ADDR + 0x08)
  3363. +#define UART_LCR (UART_BASE_ADDR + 0x0c)
  3364. +#define UART_MCR (UART_BASE_ADDR + 0x10)
  3365. +#define UART_LSR (UART_BASE_ADDR + 0x14)
  3366. +#define UART_MDR (UART_BASE_ADDR + 0x18)
  3367. +#define UART_SCRATCH (UART_BASE_ADDR + 0x1c)
  3368. +
  3369. +#endif /* _UART_H_ */
  3370. --- /dev/null
  3371. +++ b/drivers/staging/fsl_ppfe/include/pfe/util.h
  3372. @@ -0,0 +1,49 @@
  3373. +/*
  3374. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3375. + *
  3376. + * This program is free software; you can redistribute it and/or
  3377. + * modify it under the terms of the GNU General Public License
  3378. + * as published by the Free Software Foundation; either version 2
  3379. + * of the License, or (at your option) any later version.
  3380. + *
  3381. + * This program is distributed in the hope that it will be useful,
  3382. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3383. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3384. + * GNU General Public License for more details.
  3385. + *
  3386. + * You should have received a copy of the GNU General Public License
  3387. + * along with this program; if not, write to the Free Software
  3388. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3389. + *
  3390. +*/
  3391. +#ifndef _UTIL_H_
  3392. +#define _UTIL_H_
  3393. +
  3394. +#define UTIL_DMEM_BASE_ADDR 0x00000000
  3395. +#define UTIL_DMEM_SIZE 0x00002000
  3396. +#define UTIL_DMEM_END (UTIL_DMEM_BASE_ADDR + UTIL_DMEM_SIZE)
  3397. +
  3398. +#define IS_DMEM(addr, len) (((unsigned long)(addr) >= UTIL_DMEM_BASE_ADDR) && (((unsigned long)(addr) + (len)) <= UTIL_DMEM_END))
  3399. +
  3400. +#define CBUS_BASE_ADDR 0xc0000000
  3401. +#define UTIL_APB_BASE_ADDR 0xc1000000
  3402. +
  3403. +#include "cbus.h"
  3404. +
  3405. +#define GPT_BASE_ADDR (UTIL_APB_BASE_ADDR + 0x00000)
  3406. +#define UART_BASE_ADDR (UTIL_APB_BASE_ADDR + 0x10000)
  3407. +#define EAPE_BASE_ADDR (UTIL_APB_BASE_ADDR + 0x20000)
  3408. +#define INQ_BASE_ADDR (UTIL_APB_BASE_ADDR + 0x30000)
  3409. +#define EFET1_BASE_ADDR (UTIL_APB_BASE_ADDR + 0x40000)
  3410. +#define EFET2_BASE_ADDR (UTIL_APB_BASE_ADDR + 0x50000)
  3411. +#define EFET3_BASE_ADDR (UTIL_APB_BASE_ADDR + 0x60000)
  3412. +
  3413. +
  3414. +#include "gpt.h"
  3415. +#include "uart.h"
  3416. +#include "util/eape.h"
  3417. +#include "util/inq.h"
  3418. +#include "util/efet.h"
  3419. +
  3420. +
  3421. +#endif /* _UTIL_H_ */
  3422. --- /dev/null
  3423. +++ b/drivers/staging/fsl_ppfe/include/pfe/util/eape.h
  3424. @@ -0,0 +1,57 @@
  3425. +/*
  3426. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3427. + *
  3428. + * This program is free software; you can redistribute it and/or
  3429. + * modify it under the terms of the GNU General Public License
  3430. + * as published by the Free Software Foundation; either version 2
  3431. + * of the License, or (at your option) any later version.
  3432. + *
  3433. + * This program is distributed in the hope that it will be useful,
  3434. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3435. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3436. + * GNU General Public License for more details.
  3437. + *
  3438. + * You should have received a copy of the GNU General Public License
  3439. + * along with this program; if not, write to the Free Software
  3440. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3441. + *
  3442. +*/
  3443. +#ifndef _EAPE_H_
  3444. +#define _EAPE_H_
  3445. +
  3446. +#define EAPE_STATUS (EAPE_BASE_ADDR + 0x0)
  3447. +#define EAPE_INT_ENABLE (EAPE_BASE_ADDR + 0x4)
  3448. +#define EAPE_INT_SRC (EAPE_BASE_ADDR + 0x8)
  3449. +#define EAPE_HOST_INT_ENABLE (EAPE_BASE_ADDR + 0xc)
  3450. +
  3451. +/** The following bits represents to enable interrupts from host and to host
  3452. +* from / to utilpe */
  3453. +
  3454. +#define IRQ_EN_EFET_TO_UTIL 0x1
  3455. +#define IRQ_EN_QB_TO_UTIL 0x2
  3456. +#define IRQ_EN_INQ_TO_UTIL 0x4
  3457. +#define IRQ_EN_EAPE_TO_UTIL 0x8
  3458. +#define IRQ_EN_GPT_TMR_TO_UTIL 0x10
  3459. +#define IRQ_EN_UART_TO_UTIL 0x20
  3460. +#define IRQ_EN_SYSLP_TO_UTIL 0x40
  3461. +#define IRQ_EN_UPEGP_TO_UTIL 0x80
  3462. +
  3463. +/** Out interrupts */
  3464. +
  3465. +#define IRQ_EN_EFET_OUT 0x100
  3466. +#define IRQ_EN_QB_OUT 0x200
  3467. +#define IRQ_EN_INQ_OUT 0x400
  3468. +#define IRQ_EN_EAPE_OUT 0x800
  3469. +#define IRQ_EN_GPT_TMR_OUT 0x1000
  3470. +#define IRQ_EN_UART_OUT 0x2000
  3471. +#define IRQ_EN_SYSLP_OUT 0x4000
  3472. +#define IRQ_EN_UPEGP_OUT 0x8000
  3473. +
  3474. +/** The following bits are enabled in the status register
  3475. + * which are mapped to IPSEC status register bits */
  3476. +#define EAPE_IN_STAT_AVAIL 0x1
  3477. +#define EAPE_OUT_STAT_AVAIL 0x2
  3478. +#define EAPE_IN_CMD_AVAIL 0x4
  3479. +#define EAPE_OUT_CMD_AVAIL 0x8
  3480. +
  3481. +#endif /* _EAPE_H_ */
  3482. --- /dev/null
  3483. +++ b/drivers/staging/fsl_ppfe/include/pfe/util/efet.h
  3484. @@ -0,0 +1,119 @@
  3485. +/*
  3486. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3487. + *
  3488. + * This program is free software; you can redistribute it and/or
  3489. + * modify it under the terms of the GNU General Public License
  3490. + * as published by the Free Software Foundation; either version 2
  3491. + * of the License, or (at your option) any later version.
  3492. + *
  3493. + * This program is distributed in the hope that it will be useful,
  3494. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3495. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3496. + * GNU General Public License for more details.
  3497. + *
  3498. + * You should have received a copy of the GNU General Public License
  3499. + * along with this program; if not, write to the Free Software
  3500. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3501. + *
  3502. +*/
  3503. +#ifndef _UTIL_EFET_H_
  3504. +#define _UTIL_EFET_H_
  3505. +
  3506. +#define EFET_ENTRY_ADDR 0x00
  3507. +#define EFET_ENTRY_SIZE 0x04
  3508. +#define EFET_ENTRY_DMEM_ADDR 0x08
  3509. +#define EFET_ENTRY_STATUS 0x0c
  3510. +#define EFET_ENTRY_ENDIAN 0x10
  3511. +
  3512. +#define CBUS2DMEM 0
  3513. +#define DMEM2CBUS 1
  3514. +
  3515. +#define EFET2BUS_LE (1 << 0)
  3516. +
  3517. +#define EFET1 0
  3518. +#define EFET2 1
  3519. +#define EFET3 2
  3520. +#define MAX_UTIL_EFET_LEN 128
  3521. +
  3522. +extern const unsigned long util_efet_baseaddr[3];
  3523. +extern u32 util_efet_status;
  3524. +
  3525. +/* The barrier call is an empirical work-around for an unknown bug: for some unknown reason, it solves
  3526. + * a UtilPE crash observed with LRO and packet steering. Other solutions also worked (e.g. barrier,
  3527. + * nop calls in other positions). However, no common pattern could be extracted from those solutions
  3528. + * to narrow down the source of the crash.
  3529. + */
  3530. +
  3531. +#define __UTIL_EFET(i, cbus_addr, dmem_addr,len,dir) do { \
  3532. + __writel((len & 0x3FF) | (dir << 16), util_efet_baseaddr[i] + EFET_ENTRY_SIZE); \
  3533. + __writel(dmem_addr, util_efet_baseaddr[i] + EFET_ENTRY_DMEM_ADDR);\
  3534. + __writel(cbus_addr, util_efet_baseaddr[i] + EFET_ENTRY_ADDR);\
  3535. + nop();\
  3536. + }while(0)
  3537. +
  3538. +#define UTIL_EFET(i, cbus_addr, dmem_addr,len,dir) do { \
  3539. + __UTIL_EFET(i, cbus_addr, dmem_addr, len, dir); \
  3540. + util_efet_status |= (1 << i); \
  3541. + } while(0)
  3542. +
  3543. +
  3544. +/** Waits for the util efet to finish a transaction, blocking the caller
  3545. +* (without updating the status).
  3546. +* Can be called at any time.
  3547. +*
  3548. +* @param i Efet index
  3549. +*
  3550. +*
  3551. +*/
  3552. +static inline void __util_efet_wait(int i)
  3553. +{
  3554. + while (!(readl(util_efet_baseaddr[i] + EFET_ENTRY_STATUS) & 0x1)) ;
  3555. +}
  3556. +
  3557. +/** Waits for the util efet to finish a transaction, blocking the caller.
  3558. +* Can be called at any time.
  3559. +*
  3560. +* @param i Efet index
  3561. +*
  3562. +*/
  3563. +static inline void util_efet_wait(int i)
  3564. +{
  3565. + __util_efet_wait(i);
  3566. +
  3567. + util_efet_status &= ~(1 << i);
  3568. +}
  3569. +
  3570. +/** Asynchronous interface to util efet read/write functions.
  3571. +* It will wait for the efet to finish previous transaction, but does not wait for the current transaction to finish.
  3572. +*
  3573. +* @param i Efet index
  3574. +* @param cbus_addr Cbus address (must be 64bits aligned)
  3575. +* @param dmem_addr DMEM address (must be 64bits aligned)
  3576. +* @param len Number of bytes to copy (must be 64bits aligned size)
  3577. +* @param dir Direction of the transaction (0 - cbus to dmem, 1 - dmem to cbus)
  3578. +*
  3579. +*/
  3580. +static inline void util_efet_async(int i, u32 cbus_addr, u32 dmem_addr, u32 len, u8 dir)
  3581. +{
  3582. + if (util_efet_status & (1 << i))
  3583. + util_efet_wait(i);
  3584. +
  3585. + UTIL_EFET(i, cbus_addr, dmem_addr, len, dir);
  3586. +}
  3587. +
  3588. +
  3589. +static inline void util_efet_async0( u32 cbus_addr, u32 dmem_addr, u32 len, u8 dir)
  3590. +{
  3591. + util_efet_async(0, cbus_addr, dmem_addr, len,dir);
  3592. +}
  3593. +
  3594. +/* EFET 2 is aways used for SYNC operations */
  3595. +static inline void util_efet_sync2(u32 cbus_addr, u32 dmem_addr, u32 len, u8 dir)
  3596. +{
  3597. + __UTIL_EFET(2, cbus_addr, dmem_addr, len,dir);
  3598. + __util_efet_wait(2);
  3599. +}
  3600. +
  3601. +void util_efet_sync0(u32 cbus_addr, u32 dmem_addr, u32 len, u8 dir);
  3602. +#endif /* _UTIL_EFET_H_ */
  3603. +
  3604. --- /dev/null
  3605. +++ b/drivers/staging/fsl_ppfe/include/pfe/util/inq.h
  3606. @@ -0,0 +1,28 @@
  3607. +/*
  3608. + * Copyright (c) 2011, 2014 Freescale Semiconductor, Inc.
  3609. + *
  3610. + * This program is free software; you can redistribute it and/or
  3611. + * modify it under the terms of the GNU General Public License
  3612. + * as published by the Free Software Foundation; either version 2
  3613. + * of the License, or (at your option) any later version.
  3614. + *
  3615. + * This program is distributed in the hope that it will be useful,
  3616. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3617. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3618. + * GNU General Public License for more details.
  3619. + *
  3620. + * You should have received a copy of the GNU General Public License
  3621. + * along with this program; if not, write to the Free Software
  3622. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  3623. + *
  3624. +*/
  3625. +#ifndef _INQ_H_
  3626. +#define _INQ_H_
  3627. +
  3628. +#define INQ_HOST_GP (INQ_BASE_ADDR + 0x00) /* FIXME what are these for ? */
  3629. +#define INQ_UPE_GP (INQ_BASE_ADDR + 0x04) /* FIXME what are these for ? */
  3630. +
  3631. +#define INQ_QB_PKTPTR (INQ_BASE_ADDR + 0x08)
  3632. +#define INQ_FIFO_CNT (INQ_BASE_ADDR + 0x0c)
  3633. +
  3634. +#endif /* _INQ_H_ */
  3635. --- /dev/null
  3636. +++ b/drivers/staging/fsl_ppfe/pfe_ctrl.c
  3637. @@ -0,0 +1,363 @@
  3638. +/*
  3639. + *
  3640. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  3641. + *
  3642. + * This program is free software; you can redistribute it and/or modify
  3643. + * it under the terms of the GNU General Public License as published by
  3644. + * the Free Software Foundation; either version 2 of the License, or
  3645. + * (at your option) any later version.
  3646. + *
  3647. + * This program is distributed in the hope that it will be useful,
  3648. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3649. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3650. + * GNU General Public License for more details.
  3651. + *
  3652. + * You should have received a copy of the GNU General Public License
  3653. + * along with this program; if not, write to the Free Software
  3654. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  3655. + */
  3656. +
  3657. +#ifdef __KERNEL__
  3658. +#include <linux/kernel.h>
  3659. +#include <linux/sched.h>
  3660. +#include <linux/module.h>
  3661. +#include <linux/list.h>
  3662. +#include <linux/kthread.h>
  3663. +#else
  3664. +#include "platform.h"
  3665. +#endif
  3666. +
  3667. +#include "pfe_mod.h"
  3668. +#include "pfe_ctrl.h"
  3669. +
  3670. +#include "pfe_ctrl_hal.h"
  3671. +
  3672. +static struct pe_sync_mailbox CLASS_DMEM_SH2(sync_mailbox);
  3673. +static struct pe_sync_mailbox TMU_DMEM_SH2(sync_mailbox);
  3674. +
  3675. +static struct pe_msg_mailbox CLASS_DMEM_SH2(msg_mailbox);
  3676. +static struct pe_msg_mailbox TMU_DMEM_SH2(msg_mailbox);
  3677. +
  3678. +#if !defined(CONFIG_PLATFORM_LS1012A)
  3679. +static u32 CLASS_DMEM_SH2(resume);
  3680. +static u32 TMU_DMEM_SH2(resume);
  3681. +#endif
  3682. +
  3683. +#if !defined(CONFIG_UTIL_DISABLED)
  3684. +static struct pe_sync_mailbox UTIL_DMEM_SH2(sync_mailbox);
  3685. +static struct pe_msg_mailbox UTIL_DMEM_SH2(msg_mailbox);
  3686. +static u32 UTIL_DMEM_SH2(resume);
  3687. +#endif
  3688. +
  3689. +static int pfe_ctrl_timer(void *data);
  3690. +
  3691. +static int initialized = 0;
  3692. +
  3693. +#define TIMEOUT_MS 1000
  3694. +
  3695. +int relax(unsigned long end)
  3696. +{
  3697. +#ifdef __KERNEL__
  3698. + if (time_after(jiffies, end)) {
  3699. + if (time_after(jiffies, end + (TIMEOUT_MS * HZ) / 1000)) {
  3700. + return -1;
  3701. + }
  3702. +
  3703. + if (need_resched())
  3704. + schedule();
  3705. + }
  3706. +#else
  3707. + udelay(1);
  3708. +#endif
  3709. +
  3710. + return 0;
  3711. +}
  3712. +
  3713. +#if !defined(CONFIG_PLATFORM_LS1012A)
  3714. +void pfe_ctrl_suspend(struct pfe_ctrl *ctrl)
  3715. +{
  3716. + int id;
  3717. +
  3718. + kthread_stop(ctrl->timer_thread);
  3719. +
  3720. + mutex_lock(&ctrl->mutex);
  3721. +
  3722. + initialized = 0;
  3723. + for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
  3724. + pe_dmem_write(id, cpu_to_be32(0x1), (unsigned long)virt_to_class_dmem(&class_resume), 4);
  3725. +
  3726. + for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
  3727. +#if defined(CONFIG_PLATFORM_LS1012A)
  3728. + if(id == TMU2_ID) continue;
  3729. +#endif
  3730. + pe_dmem_write(id, cpu_to_be32(0x1), (unsigned long)virt_to_class_dmem(&tmu_resume), 4);
  3731. + }
  3732. +
  3733. +#if !defined(CONFIG_UTIL_DISABLED)
  3734. + pe_dmem_write(UTIL_ID, cpu_to_be32(0x1), (unsigned long)virt_to_class_dmem(&util_resume), 4);
  3735. +#endif
  3736. +
  3737. + pe_sync_stop(&pfe->ctrl, 0xFF);
  3738. +
  3739. + mutex_unlock(&ctrl->mutex);
  3740. +}
  3741. +
  3742. +void pfe_ctrl_resume(struct pfe_ctrl *ctrl)
  3743. +{
  3744. + mutex_lock(&ctrl->mutex);
  3745. + initialized = 1;
  3746. + pe_start(&pfe->ctrl, 0xFF);
  3747. + mutex_unlock(&ctrl->mutex);
  3748. +
  3749. + ctrl->timer_thread = kthread_create(pfe_ctrl_timer, ctrl, "pfe_ctrl_timer");
  3750. +
  3751. + wake_up_process(ctrl->timer_thread);
  3752. +}
  3753. +#endif
  3754. +
  3755. +/** PE sync stop.
  3756. +* Stops packet processing for a list of PE's (specified using a bitmask).
  3757. +* The caller must hold ctrl->mutex.
  3758. +*
  3759. +* @param ctrl Control context
  3760. +* @param pe_mask Mask of PE id's to stop
  3761. +*
  3762. +*/
  3763. +int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask)
  3764. +{
  3765. + struct pe_sync_mailbox *mbox;
  3766. + int pe_stopped = 0;
  3767. + unsigned long end = jiffies + 2;
  3768. + int i;
  3769. +
  3770. +#if defined(CONFIG_PLATFORM_LS1012A)
  3771. + //TODO Util should be removed after IPSec is ported
  3772. + pe_mask &= 0x2FF; //Exclude Util + TMU2
  3773. +#endif
  3774. + for (i = 0; i < MAX_PE; i++)
  3775. + if (pe_mask & (1 << i)) {
  3776. + mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
  3777. +
  3778. + pe_dmem_write(i, cpu_to_be32(0x1), (unsigned long)&mbox->stop, 4);
  3779. + }
  3780. +
  3781. + while (pe_stopped != pe_mask) {
  3782. + for (i = 0; i < MAX_PE; i++)
  3783. + if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) {
  3784. + mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
  3785. +
  3786. + if (pe_dmem_read(i, (unsigned long)&mbox->stopped, 4) & cpu_to_be32(0x1))
  3787. + pe_stopped |= (1 << i);
  3788. + }
  3789. +
  3790. + if (relax(end) < 0)
  3791. + goto err;
  3792. + }
  3793. +
  3794. + return 0;
  3795. +
  3796. +err:
  3797. + printk(KERN_ERR "%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped);
  3798. +
  3799. + for (i = 0; i < MAX_PE; i++)
  3800. + if (pe_mask & (1 << i)) {
  3801. + mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
  3802. +
  3803. + pe_dmem_write(i, cpu_to_be32(0x0), (unsigned long)&mbox->stop, 4);
  3804. + }
  3805. +
  3806. + return -EIO;
  3807. +}
  3808. +
  3809. +/** PE start.
  3810. +* Starts packet processing for a list of PE's (specified using a bitmask).
  3811. +* The caller must hold ctrl->mutex.
  3812. +*
  3813. +* @param ctrl Control context
  3814. +* @param pe_mask Mask of PE id's to start
  3815. +*
  3816. +*/
  3817. +void pe_start(struct pfe_ctrl *ctrl, int pe_mask)
  3818. +{
  3819. + struct pe_sync_mailbox *mbox;
  3820. + int i;
  3821. +
  3822. +#if defined(CONFIG_PLATFORM_LS1012A)
  3823. + //TODO Util should be removed after IPSec is ported
  3824. + pe_mask &= 0x2FF; //Exclude Util + TMU2
  3825. +#endif
  3826. + for (i = 0; i < MAX_PE; i++)
  3827. + if (pe_mask & (1 << i)) {
  3828. +
  3829. + mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
  3830. +
  3831. + pe_dmem_write(i, cpu_to_be32(0x0), (unsigned long)&mbox->stop, 4);
  3832. + }
  3833. +}
  3834. +
  3835. +
  3836. +/** Sends a control request to a given PE (to copy data to/from internal memory from/to DDR).
  3837. +* The caller must hold ctrl->mutex.
  3838. +*
  3839. +* @param ctrl Control context
  3840. +* @param id PE id
  3841. +* @param dst Physical destination address of data
  3842. +* @param src Physical source address of data
  3843. +* @param len Data length
  3844. +*
  3845. +*/
  3846. +int pe_request(struct pfe_ctrl *ctrl, int id, unsigned short cmd_type, unsigned long dst, unsigned long src, int len)
  3847. +{
  3848. + struct pe_msg_mailbox mbox = {
  3849. + .dst = cpu_to_be32(dst),
  3850. + .src = cpu_to_be32(src),
  3851. + .len = cpu_to_be32(len),
  3852. + .request = cpu_to_be32((cmd_type << 16) | 0x1),
  3853. + };
  3854. + struct pe_msg_mailbox *pmbox = (void *)ctrl->msg_mailbox_baseaddr[id];
  3855. + unsigned long end = jiffies + 2;
  3856. + u32 rc;
  3857. +
  3858. + /* This works because .request is written last */
  3859. + pe_dmem_memcpy_to32(id, (unsigned long)pmbox, &mbox, sizeof(mbox));
  3860. +
  3861. + while ((rc = pe_dmem_read(id, (unsigned long)&pmbox->request, 4)) & cpu_to_be32(0xffff)) {
  3862. + if (relax(end) < 0)
  3863. + goto err;
  3864. + }
  3865. +
  3866. + rc = be32_to_cpu(rc);
  3867. +
  3868. + return rc >> 16;
  3869. +
  3870. +err:
  3871. + printk(KERN_ERR "%s: timeout, %x\n", __func__, be32_to_cpu(rc));
  3872. + pe_dmem_write(id, cpu_to_be32(0), (unsigned long)&pmbox->request, 4);
  3873. + return -EIO;
  3874. +}
  3875. +
  3876. +
  3877. +/** Control code timer thread.
  3878. +*
  3879. +* A kernel thread is used so that the timer code can be run under the control path mutex.
  3880. +* The thread wakes up regularly and checks if any timer in the timer list as expired.
  3881. +* The timers are re-started automatically.
  3882. +* The code tries to keep the number of times a timer runs per unit time constant on average,
  3883. +* if the thread scheduling is delayed, it's possible for a particular timer to be scheduled in
  3884. +* quick succession to make up for the lost time.
  3885. +*
  3886. +* @param data Pointer to the control context structure
  3887. +*
  3888. +* @return 0 on sucess, a negative value on error
  3889. +*
  3890. +*/
  3891. +static int pfe_ctrl_timer(void *data)
  3892. +{
  3893. + struct pfe_ctrl *ctrl = data;
  3894. + TIMER_ENTRY *timer, *next;
  3895. +
  3896. + printk(KERN_INFO "%s\n", __func__);
  3897. +
  3898. + while (1)
  3899. + {
  3900. + schedule_timeout_uninterruptible(ctrl->timer_period);
  3901. +
  3902. + mutex_lock(&ctrl->mutex);
  3903. +
  3904. + list_for_each_entry_safe(timer, next, &ctrl->timer_list, list)
  3905. + {
  3906. + if (time_after(jiffies, timer->timeout))
  3907. + {
  3908. + timer->timeout += timer->period;
  3909. +
  3910. + timer->handler();
  3911. + }
  3912. + }
  3913. +
  3914. + mutex_unlock(&ctrl->mutex);
  3915. +
  3916. + if (kthread_should_stop())
  3917. + break;
  3918. + }
  3919. +
  3920. + printk(KERN_INFO "%s exiting\n", __func__);
  3921. +
  3922. + return 0;
  3923. +}
  3924. +
  3925. +
  3926. +int pfe_ctrl_init(struct pfe *pfe)
  3927. +{
  3928. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  3929. + int id;
  3930. + int rc;
  3931. +
  3932. + printk(KERN_INFO "%s\n", __func__);
  3933. +
  3934. + mutex_init(&ctrl->mutex);
  3935. + spin_lock_init(&ctrl->lock);
  3936. +
  3937. + ctrl->timer_period = HZ / TIMER_TICKS_PER_SEC;
  3938. +
  3939. + INIT_LIST_HEAD(&ctrl->timer_list);
  3940. +
  3941. + /*INIT_WORK(&ctrl->work, comcerto_fpp_workqueue);*/
  3942. +
  3943. + INIT_LIST_HEAD(&ctrl->msg_list);
  3944. +
  3945. + for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
  3946. + ctrl->sync_mailbox_baseaddr[id] = virt_to_class_dmem(&class_sync_mailbox);
  3947. + ctrl->msg_mailbox_baseaddr[id] = virt_to_class_dmem(&class_msg_mailbox);
  3948. + }
  3949. +
  3950. + for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
  3951. +#if defined(CONFIG_PLATFORM_LS1012A)
  3952. + if(id == TMU2_ID) continue;
  3953. +#endif
  3954. + ctrl->sync_mailbox_baseaddr[id] = virt_to_tmu_dmem(&tmu_sync_mailbox);
  3955. + ctrl->msg_mailbox_baseaddr[id] = virt_to_tmu_dmem(&tmu_msg_mailbox);
  3956. + }
  3957. +
  3958. +#if !defined(CONFIG_UTIL_DISABLED)
  3959. + ctrl->sync_mailbox_baseaddr[UTIL_ID] = virt_to_util_dmem(&util_sync_mailbox);
  3960. + ctrl->msg_mailbox_baseaddr[UTIL_ID] = virt_to_util_dmem(&util_msg_mailbox);
  3961. +#endif
  3962. +
  3963. + ctrl->hash_array_baseaddr = pfe->ddr_baseaddr + ROUTE_TABLE_BASEADDR;
  3964. + ctrl->hash_array_phys_baseaddr = pfe->ddr_phys_baseaddr + ROUTE_TABLE_BASEADDR;
  3965. + ctrl->ipsec_lmem_phys_baseaddr = CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR + IPSEC_LMEM_BASEADDR);
  3966. + ctrl->ipsec_lmem_baseaddr = (LMEM_BASE_ADDR + IPSEC_LMEM_BASEADDR);
  3967. +
  3968. + ctrl->timer_thread = kthread_create(pfe_ctrl_timer, ctrl, "pfe_ctrl_timer");
  3969. + if (IS_ERR(ctrl->timer_thread))
  3970. + {
  3971. + printk (KERN_ERR "%s: kthread_create() failed\n", __func__);
  3972. + rc = PTR_ERR(ctrl->timer_thread);
  3973. + goto err0;
  3974. + }
  3975. +
  3976. + ctrl->dev = pfe->dev;
  3977. +
  3978. + wake_up_process(ctrl->timer_thread);
  3979. +
  3980. + printk(KERN_INFO "%s finished\n", __func__);
  3981. +
  3982. + initialized = 1;
  3983. +
  3984. + return 0;
  3985. +
  3986. +err0:
  3987. + return rc;
  3988. +}
  3989. +
  3990. +
  3991. +void pfe_ctrl_exit(struct pfe *pfe)
  3992. +{
  3993. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  3994. +
  3995. + printk(KERN_INFO "%s\n", __func__);
  3996. +
  3997. + initialized = 0;
  3998. +
  3999. + kthread_stop(ctrl->timer_thread);
  4000. +}
  4001. --- /dev/null
  4002. +++ b/drivers/staging/fsl_ppfe/pfe_ctrl.h
  4003. @@ -0,0 +1,111 @@
  4004. +/*
  4005. + *
  4006. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  4007. + *
  4008. + * This program is free software; you can redistribute it and/or modify
  4009. + * it under the terms of the GNU General Public License as published by
  4010. + * the Free Software Foundation; either version 2 of the License, or
  4011. + * (at your option) any later version.
  4012. + *
  4013. + * This program is distributed in the hope that it will be useful,
  4014. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4015. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4016. + * GNU General Public License for more details.
  4017. + *
  4018. + * You should have received a copy of the GNU General Public License
  4019. + * along with this program; if not, write to the Free Software
  4020. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  4021. + */
  4022. +
  4023. +#ifndef _PFE_CTRL_H_
  4024. +#define _PFE_CTRL_H_
  4025. +
  4026. +#include <linux/dmapool.h>
  4027. +
  4028. +#include "pfe_mod.h"
  4029. +#include "pfe/pfe.h"
  4030. +
  4031. +#define DMA_BUF_SIZE_128 0x80 /* enough for 1 conntracks */
  4032. +#define DMA_BUF_SIZE_256 0x100 /* enough for 2 conntracks, 1 bridge entry or 1 multicast entry */
  4033. +#define DMA_BUF_SIZE_512 0x200 /* 512bytes dma allocated buffers used by rtp relay feature */
  4034. +#define DMA_BUF_MIN_ALIGNMENT 8
  4035. +#define DMA_BUF_BOUNDARY (4 * 1024) /* bursts can not cross 4k boundary */
  4036. +
  4037. +#define CMD_TX_ENABLE 0x0501
  4038. +#define CMD_TX_DISABLE 0x0502
  4039. +
  4040. +#define CMD_RX_LRO 0x0011
  4041. +#define CMD_PKTCAP_ENABLE 0x0d01
  4042. +#define CMD_QM_EXPT_RATE 0x020c
  4043. +
  4044. +#define EXPT_TYPE_PCAP 0x3
  4045. +
  4046. +struct pfe_ctrl {
  4047. + struct mutex mutex;
  4048. + spinlock_t lock;
  4049. +
  4050. + void *dma_pool;
  4051. + void *dma_pool_512;
  4052. + void *dma_pool_128;
  4053. +
  4054. + struct device *dev;
  4055. +
  4056. + void *hash_array_baseaddr; /** Virtual base address of the conntrack hash array */
  4057. + unsigned long hash_array_phys_baseaddr; /** Physical base address of the conntrack hash array */
  4058. +
  4059. + struct task_struct *timer_thread;
  4060. + struct list_head timer_list;
  4061. + unsigned long timer_period;
  4062. +
  4063. + int (*event_cb)(u16, u16, u16*);
  4064. +
  4065. + unsigned long sync_mailbox_baseaddr[MAX_PE]; /* Sync mailbox PFE internal address, initialized when parsing elf images */
  4066. + unsigned long msg_mailbox_baseaddr[MAX_PE]; /* Msg mailbox PFE internal address, initialized when parsing elf images */
  4067. +
  4068. + unsigned long class_dmem_sh;
  4069. + unsigned long class_pe_lmem_sh;
  4070. + unsigned long tmu_dmem_sh;
  4071. + unsigned long util_dmem_sh;
  4072. + unsigned long util_ddr_sh;
  4073. + struct clk *clk_axi;
  4074. + unsigned int sys_clk; // AXI clock value, in KHz
  4075. + void *ipsec_lmem_baseaddr;
  4076. + unsigned long ipsec_lmem_phys_baseaddr;
  4077. +
  4078. + /* used for asynchronous message transfer to PFE */
  4079. + struct list_head msg_list;
  4080. + struct work_struct work;
  4081. +};
  4082. +
  4083. +int pfe_ctrl_init(struct pfe *pfe);
  4084. +void pfe_ctrl_exit(struct pfe *pfe);
  4085. +
  4086. +int pe_send_cmd(unsigned short cmd_type, unsigned short action, unsigned long param1, unsigned long param2);
  4087. +int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask);
  4088. +void pe_start(struct pfe_ctrl *ctrl, int pe_mask);
  4089. +int pe_request(struct pfe_ctrl *ctrl, int id,unsigned short cmd_type, unsigned long dst, unsigned long src, int len);
  4090. +int pe_read(struct pfe_ctrl *ctrl, int id, u32 *dst, unsigned long src, int len, int clear_flag);
  4091. +int tmu_pe_request(struct pfe_ctrl *ctrl, int id, unsigned int tmu_cmd_bitmask);
  4092. +
  4093. +int pfe_ctrl_set_eth_state(int id, unsigned int state, unsigned char *mac_addr);
  4094. +int pfe_ctrl_set_lro(char enable);
  4095. +#ifdef CFG_PCAP
  4096. +int pfe_ctrl_set_pcap(char enable);
  4097. +int pfe_ctrl_set_pcap_ratelimit(u32 pkts_per_msec);
  4098. +#endif
  4099. +void pfe_ctrl_suspend(struct pfe_ctrl *ctrl);
  4100. +void pfe_ctrl_resume(struct pfe_ctrl *ctrl);
  4101. +int relax(unsigned long end);
  4102. +
  4103. +/* used for asynchronous message transfer to PFE */
  4104. +#define FPP_MAX_MSG_LENGTH 256 /* expressed in U8 -> 256 bytes*/
  4105. +struct fpp_msg {
  4106. + struct list_head list;
  4107. + void (*callback)(unsigned long, int, u16, u16 *);
  4108. + unsigned long data;
  4109. + u16 fcode;
  4110. + u16 length;
  4111. + u16 *payload;
  4112. +};
  4113. +
  4114. +#endif /* _PFE_CTRL_H_ */
  4115. --- /dev/null
  4116. +++ b/drivers/staging/fsl_ppfe/pfe_ctrl_hal.c
  4117. @@ -0,0 +1,207 @@
  4118. +/*
  4119. + *
  4120. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  4121. + *
  4122. + * This program is free software; you can redistribute it and/or modify
  4123. + * it under the terms of the GNU General Public License as published by
  4124. + * the Free Software Foundation; either version 2 of the License, or
  4125. + * (at your option) any later version.
  4126. + *
  4127. + * This program is distributed in the hope that it will be useful,
  4128. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4129. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4130. + * GNU General Public License for more details.
  4131. + *
  4132. + * You should have received a copy of the GNU General Public License
  4133. + * along with this program; if not, write to the Free Software
  4134. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  4135. + */
  4136. +
  4137. +/* OS abstraction functions used by PFE control code */
  4138. +
  4139. +#include <linux/slab.h>
  4140. +
  4141. +#include "pfe_ctrl_hal.h"
  4142. +
  4143. +#include "pfe_mod.h"
  4144. +
  4145. +extern char *__class_dmem_sh;
  4146. +extern char *__tmu_dmem_sh;
  4147. +#if !defined(CONFIG_UTIL_DISABLED)
  4148. +extern char *__util_dmem_sh;
  4149. +extern char *__util_ddr_sh;
  4150. +#endif
  4151. +
  4152. +HostMessage msg_buf;
  4153. +static int msg_buf_used = 0;
  4154. +unsigned long virt_to_class_dmem(void *p)
  4155. +{
  4156. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  4157. +
  4158. + if (p)
  4159. + return (unsigned long)p - (unsigned long)&__class_dmem_sh + ctrl->class_dmem_sh;
  4160. + else
  4161. + return 0;
  4162. +}
  4163. +unsigned long virt_to_tmu_dmem(void *p)
  4164. +{
  4165. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  4166. +
  4167. + if (p)
  4168. + return (unsigned long)p - (unsigned long)&__tmu_dmem_sh + ctrl->tmu_dmem_sh;
  4169. + else
  4170. + return 0;
  4171. +}
  4172. +
  4173. +
  4174. +#if !defined(CONFIG_UTIL_DISABLED)
  4175. +unsigned long virt_to_util_dmem(void *p)
  4176. +{
  4177. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  4178. +
  4179. + if (p)
  4180. + return (unsigned long)p - (unsigned long)&__util_dmem_sh + ctrl->util_dmem_sh;
  4181. + else
  4182. + return 0;
  4183. +}
  4184. +
  4185. +/** Returns the DDR physical address of a Util PE shared DDR variable.
  4186. + *
  4187. + * @param p pointer (kernel space, virtual) to be converted to a physical address.
  4188. + */
  4189. +unsigned long virt_to_util_ddr(void *p)
  4190. +{
  4191. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  4192. +
  4193. + if (p)
  4194. + return (unsigned long)p - (unsigned long)&__util_ddr_sh + ctrl->util_ddr_sh;
  4195. + else
  4196. + return 0;
  4197. +}
  4198. +/** Returns the virtual address of a Util PE shared DDR variable.
  4199. + *
  4200. + * @param p pointer (kernel space, virtual) to be converted to a pointer (usable in kernel space)
  4201. + * pointing to the actual data.
  4202. + */
  4203. +
  4204. +void * virt_to_util_virt(void *p)
  4205. +{
  4206. + if (p)
  4207. + return DDR_PHYS_TO_VIRT(virt_to_util_ddr(p));
  4208. + else
  4209. + return NULL;
  4210. +}
  4211. +#endif
  4212. +unsigned long virt_to_phys_iram(void *p)
  4213. +{
  4214. + if (p)
  4215. + return (p - pfe->iram_baseaddr) + pfe->iram_phys_baseaddr;
  4216. + else
  4217. + return 0;
  4218. +}
  4219. +
  4220. +unsigned long virt_to_phys_ipsec_lmem(void *p)
  4221. +{
  4222. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  4223. +
  4224. + if (p)
  4225. + return (p - ctrl->ipsec_lmem_baseaddr) + ctrl->ipsec_lmem_phys_baseaddr;
  4226. + else
  4227. + return 0;
  4228. +}
  4229. +
  4230. +unsigned long virt_to_phys_ipsec_axi(void *p)
  4231. +{
  4232. + if (p)
  4233. + return (p - pfe->ipsec_baseaddr) + pfe->ipsec_phys_baseaddr;
  4234. + else
  4235. + return 0;
  4236. +}
  4237. +
  4238. +
  4239. +HostMessage *msg_alloc(void)
  4240. +{
  4241. + if (msg_buf_used)
  4242. + {
  4243. + printk(KERN_ERR "%s: failed\n", __func__);
  4244. + return NULL;
  4245. + }
  4246. +
  4247. + msg_buf_used = 1;
  4248. +
  4249. + return &msg_buf;
  4250. +}
  4251. +
  4252. +void msg_free(HostMessage *msg)
  4253. +{
  4254. + if (!msg_buf_used)
  4255. + printk(KERN_ERR "%s: freing already free msg buffer\n", __func__);
  4256. +
  4257. + msg_buf_used = 0;
  4258. +}
  4259. +
  4260. +int msg_send(HostMessage *msg)
  4261. +{
  4262. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  4263. + int rc = -1;
  4264. +
  4265. + if (!ctrl->event_cb)
  4266. + goto out;
  4267. +
  4268. + if (ctrl->event_cb(msg->code, msg->length, msg->data) < 0)
  4269. + goto out;
  4270. +
  4271. + rc = 0;
  4272. +
  4273. +out:
  4274. + msg_free(msg);
  4275. +
  4276. + return rc;
  4277. +}
  4278. +
  4279. +
  4280. +void timer_init(TIMER_ENTRY *timer, TIMER_HANDLER handler)
  4281. +{
  4282. + timer->handler = handler;
  4283. + timer->running = 0;
  4284. +}
  4285. +
  4286. +
  4287. +void timer_add(TIMER_ENTRY *timer, u16 granularity)
  4288. +{
  4289. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  4290. +
  4291. +
  4292. + timer->period = granularity;
  4293. + timer->timeout = jiffies + timer->period;
  4294. +
  4295. + if (!timer->running)
  4296. + {
  4297. + list_add(&timer->list, &ctrl->timer_list);
  4298. + timer->running = 1;
  4299. + }
  4300. +}
  4301. +
  4302. +
  4303. +void timer_del(TIMER_ENTRY *timer)
  4304. +{
  4305. +
  4306. + if (timer->running)
  4307. + {
  4308. + list_del(&timer->list);
  4309. + timer->running = 0;
  4310. + }
  4311. +}
  4312. +
  4313. +
  4314. +void *Heap_Alloc(int size)
  4315. +{
  4316. + /* FIXME we may want to use dma API's and use non cacheable memory */
  4317. + return pfe_kmalloc(size, GFP_KERNEL);
  4318. +}
  4319. +
  4320. +
  4321. +void Heap_Free(void *p)
  4322. +{
  4323. + pfe_kfree(p);
  4324. +}
  4325. --- /dev/null
  4326. +++ b/drivers/staging/fsl_ppfe/pfe_ctrl_hal.h
  4327. @@ -0,0 +1,129 @@
  4328. +/*
  4329. + *
  4330. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  4331. + *
  4332. + * This program is free software; you can redistribute it and/or modify
  4333. + * it under the terms of the GNU General Public License as published by
  4334. + * the Free Software Foundation; either version 2 of the License, or
  4335. + * (at your option) any later version.
  4336. + *
  4337. + * This program is distributed in the hope that it will be useful,
  4338. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4339. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4340. + * GNU General Public License for more details.
  4341. + *
  4342. + * You should have received a copy of the GNU General Public License
  4343. + * along with this program; if not, write to the Free Software
  4344. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  4345. + */
  4346. +
  4347. +#ifndef _PFE_CTRL_HAL_H_
  4348. +#define _PFE_CTRL_HAL_H_
  4349. +
  4350. +#include <linux/timer.h>
  4351. +#include <linux/jiffies.h>
  4352. +#include <linux/string.h>
  4353. +#include <linux/elf.h>
  4354. +#include <linux/slab.h>
  4355. +#include <asm/byteorder.h>
  4356. +#include <asm/io.h>
  4357. +
  4358. +#include "pfe_mod.h"
  4359. +
  4360. +#define CLASS_DMEM_SH(var) __attribute__((section(".class_dmem_sh_" #var))) var
  4361. +#define CLASS_PE_LMEM_SH(var) __attribute__((section(".class_pe_lmem_sh_" #var))) var
  4362. +#define TMU_DMEM_SH(var) __attribute__((section(".tmu_dmem_sh_" #var))) var
  4363. +#define UTIL_DMEM_SH(var) __attribute__((section(".util_dmem_sh_" #var))) var
  4364. +#define UTIL_DDR_SH(var) __attribute__((section(".util_ddr_sh_" #var))) var
  4365. +
  4366. +#define CLASS_DMEM_SH2(var) __attribute__((section(".class_dmem_sh_" #var))) class_##var
  4367. +#define CLASS_PE_LMEM_SH2(var) __attribute__((section(".class_pe_lmem_sh_" #var))) class_##var
  4368. +#define TMU_DMEM_SH2(var) __attribute__((section(".tmu_dmem_sh_" #var))) tmu_##var
  4369. +#define UTIL_DMEM_SH2(var) __attribute__((section(".util_dmem_sh_" #var))) util_##var
  4370. +
  4371. +/** Translate the name of a shared variable to its PFE counterpart.
  4372. + * Those macros may be used to determine the address of a shared variable,
  4373. + * and will work even if the variable is accessed through a macro, as is the case
  4374. + * with most fields of gFppGlobals.
  4375. + */
  4376. +#define CONCAT(str, var) str##var
  4377. +#define CLASS_VARNAME2(var) CONCAT(class_, var)
  4378. +#define UTIL_VARNAME2(var) CONCAT(util_, var)
  4379. +#define TMU_VARNAME2(var) CONCAT(tmu_, var)
  4380. +
  4381. +typedef struct tHostMessage {
  4382. + u16 length;
  4383. + u16 code;
  4384. + u16 data[128];
  4385. +} HostMessage;
  4386. +
  4387. +HostMessage *msg_alloc(void);
  4388. +void msg_free(HostMessage *msg);
  4389. +int msg_send(HostMessage *msg);
  4390. +
  4391. +
  4392. +unsigned long virt_to_class(void *p);
  4393. +unsigned long virt_to_class_dmem(void *p);
  4394. +unsigned long virt_to_class_pe_lmem(void *p);
  4395. +unsigned long virt_to_tmu_dmem(void *p);
  4396. +unsigned long virt_to_util_dmem(void *p);
  4397. +unsigned long virt_to_util_ddr(void *p);
  4398. +void * virt_to_util_virt(void *p);
  4399. +unsigned long virt_to_phys_iram(void *p);
  4400. +unsigned long virt_to_phys_ipsec_lmem(void *p);
  4401. +unsigned long virt_to_phys_ipsec_axi(void *p);
  4402. +
  4403. +
  4404. +#define TIMER_TICKS_PER_SEC 100
  4405. +
  4406. +#if TIMER_TICKS_PER_SEC > HZ
  4407. +#error TIMER_TICKS_PER_SEC is too high
  4408. +#endif
  4409. +
  4410. +
  4411. +typedef void (* TIMER_HANDLER)(void);
  4412. +
  4413. +typedef struct {
  4414. + struct list_head list;
  4415. + unsigned long timeout;
  4416. + unsigned long period;
  4417. + TIMER_HANDLER handler;
  4418. + char running;
  4419. +} TIMER_ENTRY;
  4420. +
  4421. +
  4422. +/** Initializes a timer structure.
  4423. +* Must be called once for each TIMER_ENTRY structure.
  4424. +* The caller must be holding the ctrl->mutex.
  4425. +*
  4426. +* @param timer pointer to the timer to be initialized
  4427. +* @param handler timer handler function pointer
  4428. +*
  4429. +*/
  4430. +void timer_init(TIMER_ENTRY *timer, TIMER_HANDLER handler);
  4431. +
  4432. +/** Adds a timer to the running timer list.
  4433. +* It's safe to call even if the timer was already running. In this case we just update the granularity.
  4434. +* The caller must be holding the ctrl->mutex.
  4435. +*
  4436. +* @param timer pointer to the timer to be added
  4437. +* @param granularity granularity of the timer (in timer tick units)
  4438. +*
  4439. +*/
  4440. +void timer_add(TIMER_ENTRY *timer, u16 granularity);
  4441. +
  4442. +/** Deletes a timer from the running timer list.
  4443. +* It's safe to call even if the timer is no longer running.
  4444. +* The caller must be holding the ctrl->mutex.
  4445. +*
  4446. +* @param timer pointer to the timer to be removed
  4447. +*/
  4448. +void timer_del(TIMER_ENTRY *timer);
  4449. +
  4450. +void *Heap_Alloc(int size);
  4451. +
  4452. +#define Heap_Alloc_ARAM(s) Heap_Alloc(s)
  4453. +#define __Heap_Alloc(h, s) Heap_Alloc(s)
  4454. +void Heap_Free(void *p);
  4455. +
  4456. +#endif /* _PFE_CTRL_HAL_H_ */
  4457. --- /dev/null
  4458. +++ b/drivers/staging/fsl_ppfe/pfe_debugfs.c
  4459. @@ -0,0 +1,109 @@
  4460. +/*
  4461. + * (C) Copyright 2013
  4462. + * Author : Freescale Technologes
  4463. + *
  4464. + * See file CREDITS for list of people who contributed to this
  4465. + * project.
  4466. + *
  4467. + * This program is free software; you can redistribute it and/or
  4468. + * modify it under the terms of the GNU General Public License as
  4469. + * published by the Free Software Foundation; either version 2 of
  4470. + * the License, or (at your option) any later version.
  4471. + *
  4472. + * This program is distributed in the hope that it will be useful,
  4473. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4474. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4475. + * GNU General Public License for more details.
  4476. + *
  4477. + * You should have received a copy of the GNU General Public License
  4478. + * along with this program; if not, write to the Free Software
  4479. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  4480. + * MA 02111-1307 USA
  4481. + * */
  4482. +
  4483. +#include <linux/module.h>
  4484. +#include <linux/debugfs.h>
  4485. +#include <linux/platform_device.h>
  4486. +
  4487. +#include "pfe_mod.h"
  4488. +
  4489. +static int dmem_show(struct seq_file *s, void *unused)
  4490. +{
  4491. + u32 dmem_addr, val;
  4492. + int id = (long int)s->private;
  4493. + int i;
  4494. +
  4495. + for (dmem_addr = 0; dmem_addr < CLASS_DMEM_SIZE; dmem_addr += 8 * 4) {
  4496. + seq_printf(s, "%04x:", dmem_addr);
  4497. +
  4498. + for (i = 0; i < 8; i++) {
  4499. + val = pe_dmem_read(id, dmem_addr + i * 4, 4);
  4500. + seq_printf(s, " %02x %02x %02x %02x", val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, (val >> 24) & 0xff);
  4501. + }
  4502. +
  4503. + seq_printf(s, "\n");
  4504. + }
  4505. +
  4506. + return 0;
  4507. +}
  4508. +
  4509. +static int dmem_open(struct inode *inode, struct file *file)
  4510. +{
  4511. + return single_open(file, dmem_show, inode->i_private);
  4512. +}
  4513. +
  4514. +static const struct file_operations dmem_fops = {
  4515. + .open = dmem_open,
  4516. + .read = seq_read,
  4517. + .llseek = seq_lseek,
  4518. + .release = single_release,
  4519. +};
  4520. +
  4521. +int pfe_debugfs_init(struct pfe *pfe)
  4522. +{
  4523. + struct dentry *d;
  4524. +
  4525. + printk(KERN_INFO "%s\n", __func__);
  4526. +
  4527. + pfe->dentry = debugfs_create_dir("pfe", NULL);
  4528. + if (IS_ERR_OR_NULL(pfe->dentry))
  4529. + goto err_dir;
  4530. +
  4531. + d = debugfs_create_file("pe0_dmem", S_IRUGO, pfe->dentry, (void *)0, &dmem_fops);
  4532. + if (IS_ERR_OR_NULL(d))
  4533. + goto err_pe;
  4534. +
  4535. + d = debugfs_create_file("pe1_dmem", S_IRUGO, pfe->dentry, (void *)1, &dmem_fops);
  4536. + if (IS_ERR_OR_NULL(d))
  4537. + goto err_pe;
  4538. +
  4539. + d = debugfs_create_file("pe2_dmem", S_IRUGO, pfe->dentry, (void *)2, &dmem_fops);
  4540. + if (IS_ERR_OR_NULL(d))
  4541. + goto err_pe;
  4542. +
  4543. + d = debugfs_create_file("pe3_dmem", S_IRUGO, pfe->dentry, (void *)3, &dmem_fops);
  4544. + if (IS_ERR_OR_NULL(d))
  4545. + goto err_pe;
  4546. +
  4547. + d = debugfs_create_file("pe4_dmem", S_IRUGO, pfe->dentry, (void *)4, &dmem_fops);
  4548. + if (IS_ERR_OR_NULL(d))
  4549. + goto err_pe;
  4550. +
  4551. + d = debugfs_create_file("pe5_dmem", S_IRUGO, pfe->dentry, (void *)5, &dmem_fops);
  4552. + if (IS_ERR_OR_NULL(d))
  4553. + goto err_pe;
  4554. +
  4555. + return 0;
  4556. +
  4557. +err_pe:
  4558. + debugfs_remove_recursive(pfe->dentry);
  4559. +
  4560. +err_dir:
  4561. + return -1;
  4562. +}
  4563. +
  4564. +void pfe_debugfs_exit(struct pfe *pfe)
  4565. +{
  4566. + debugfs_remove_recursive(pfe->dentry);
  4567. +}
  4568. +
  4569. --- /dev/null
  4570. +++ b/drivers/staging/fsl_ppfe/pfe_debugfs.h
  4571. @@ -0,0 +1,8 @@
  4572. +#ifndef _PFE_DEBUGFS_H_
  4573. +#define _PFE_DEBUGFS_H_
  4574. +
  4575. +int pfe_debugfs_init(struct pfe *pfe);
  4576. +void pfe_debugfs_exit(struct pfe *pfe);
  4577. +#endif /* _PFE_DEBUGFS_H_ */
  4578. +
  4579. +
  4580. --- /dev/null
  4581. +++ b/drivers/staging/fsl_ppfe/pfe_eth.c
  4582. @@ -0,0 +1,2956 @@
  4583. +/*
  4584. + *
  4585. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  4586. + *
  4587. + * This program is free software; you can redistribute it and/or modify
  4588. + * it under the terms of the GNU General Public License as published by
  4589. + * the Free Software Foundation; either version 2 of the License, or
  4590. + * (at your option) any later version.
  4591. + *
  4592. + * This program is distributed in the hope that it will be useful,
  4593. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4594. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4595. + * GNU General Public License for more details.
  4596. + *
  4597. + * You should have received a copy of the GNU General Public License
  4598. + * along with this program; if not, write to the Free Software
  4599. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  4600. + */
  4601. +
  4602. +/** @pfe_eth.c.
  4603. + * Ethernet driver for to handle exception path for PFE.
  4604. + * - uses HIF functions to send/receive packets.
  4605. + * - uses ctrl function to start/stop interfaces.
  4606. + * - uses direct register accesses to control phy operation.
  4607. + */
  4608. +#include <linux/version.h>
  4609. +#include <linux/kernel.h>
  4610. +#include <linux/interrupt.h>
  4611. +#include <linux/dma-mapping.h>
  4612. +#include <linux/dmapool.h>
  4613. +#include <linux/netdevice.h>
  4614. +#include <linux/etherdevice.h>
  4615. +#include <linux/ethtool.h>
  4616. +#include <linux/mii.h>
  4617. +#include <linux/phy.h>
  4618. +#include <linux/timer.h>
  4619. +#include <linux/hrtimer.h>
  4620. +#include <linux/platform_device.h>
  4621. +
  4622. +#include <net/ip.h>
  4623. +#include <net/sock.h>
  4624. +
  4625. +#include <asm/io.h>
  4626. +#include <asm/irq.h>
  4627. +#include <asm/delay.h>
  4628. +#include <linux/regmap.h>
  4629. +#include <linux/i2c.h>
  4630. +
  4631. +#if defined(CONFIG_NF_CONNTRACK_MARK)
  4632. +#include <net/netfilter/nf_conntrack.h>
  4633. +#endif
  4634. +
  4635. +#include "pfe_mod.h"
  4636. +#include "pfe_eth.h"
  4637. +
  4638. +const char comcerto_eth_driver_version[]="1.0";
  4639. +static void *cbus_emac_base[3];
  4640. +static void *cbus_gpi_base[3];
  4641. +
  4642. +/* Forward Declaration */
  4643. +static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv);
  4644. +static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv, int force);
  4645. +static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int txQ_num, int from_tx, int n_desc);
  4646. +
  4647. +#if defined(CONFIG_PLATFORM_C2000)
  4648. +static void pfe_eth_set_device_wakeup(struct pfe *pfe);
  4649. +
  4650. +
  4651. +
  4652. +unsigned int gemac_regs[] = {
  4653. + 0x0000, /* Network control */
  4654. + 0x0004, /* Network configuration */
  4655. + 0x0008, /* Network status */
  4656. + 0x0010, /* DMA configuration */
  4657. + 0x0014, /* Transmit status */
  4658. + 0x0020, /* Receive status */
  4659. + 0x0024, /* Interrupt status */
  4660. + 0x0030, /* Interrupt mask */
  4661. + 0x0038, /* Received pause quantum */
  4662. + 0x003c, /* Transmit pause quantum */
  4663. + 0x0080, /* Hash register bottom [31:0] */
  4664. + 0x0084, /* Hash register bottom [63:32] */
  4665. + 0x0088, /* Specific address 1 bottom [31:0] */
  4666. + 0x008c, /* Specific address 1 top [47:32] */
  4667. + 0x0090, /* Specific address 2 bottom [31:0] */
  4668. + 0x0094, /* Specific address 2 top [47:32] */
  4669. + 0x0098, /* Specific address 3 bottom [31:0] */
  4670. + 0x009c, /* Specific address 3 top [47:32] */
  4671. + 0x00a0, /* Specific address 4 bottom [31:0] */
  4672. + 0x00a4, /* Specific address 4 top [47:32] */
  4673. + 0x00a8, /* Type ID Match 1 */
  4674. + 0x00ac, /* Type ID Match 2 */
  4675. + 0x00b0, /* Type ID Match 3 */
  4676. + 0x00b4, /* Type ID Match 4 */
  4677. + 0x00b8, /* Wake Up ON LAN */
  4678. + 0x00bc, /* IPG stretch register */
  4679. + 0x00c0, /* Stacked VLAN Register */
  4680. + 0x00fc, /* Module ID */
  4681. + 0x07a0 /* EMAC Control register */
  4682. +};
  4683. +#else
  4684. +unsigned int gemac_regs[] = {
  4685. + 0x0004, /*Interrupt event */
  4686. + 0x0008, /*Interrupt mask */
  4687. + 0x0024, /*Ethernet control */
  4688. + 0x0064, /*MIB Control/Status */
  4689. + 0x0084, /*Receive control/status */
  4690. + 0x00C4, /*Transmit control */
  4691. + 0x00E4, /*Physical address low */
  4692. + 0x00E8, /*Physical address high */
  4693. + 0x0144, /*Transmit FIFO Watermark and Store and Forward Control*/
  4694. + 0x0190, /* Receive FIFO Section Full Threshold */
  4695. + 0x01A0, /* Transmit FIFO Section Empty Threshold */
  4696. + 0x01B0, /* Frame Truncation Length */
  4697. +};
  4698. +#endif
  4699. +/********************************************************************/
  4700. +/* SYSFS INTERFACE */
  4701. +/********************************************************************/
  4702. +
  4703. +
  4704. +
  4705. +#ifdef PFE_ETH_NAPI_STATS
  4706. +/*
  4707. + * pfe_eth_show_napi_stats
  4708. + */
  4709. +static ssize_t pfe_eth_show_napi_stats(struct device *dev,
  4710. + struct device_attribute *attr, char *buf)
  4711. +{
  4712. + struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
  4713. + ssize_t len = 0;
  4714. +
  4715. + len += sprintf(buf + len, "sched: %u\n", priv->napi_counters[NAPI_SCHED_COUNT]);
  4716. + len += sprintf(buf + len, "poll: %u\n", priv->napi_counters[NAPI_POLL_COUNT]);
  4717. + len += sprintf(buf + len, "packet: %u\n", priv->napi_counters[NAPI_PACKET_COUNT]);
  4718. + len += sprintf(buf + len, "budget: %u\n", priv->napi_counters[NAPI_FULL_BUDGET_COUNT]);
  4719. + len += sprintf(buf + len, "desc: %u\n", priv->napi_counters[NAPI_DESC_COUNT]);
  4720. +
  4721. + return len;
  4722. +}
  4723. +
  4724. +/*
  4725. + * pfe_eth_set_napi_stats
  4726. + */
  4727. +static ssize_t pfe_eth_set_napi_stats(struct device *dev,
  4728. + struct device_attribute *attr, const char *buf, size_t count)
  4729. +{
  4730. + struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
  4731. +
  4732. + memset(priv->napi_counters, 0, sizeof(priv->napi_counters));
  4733. +
  4734. + return count;
  4735. +}
  4736. +#endif
  4737. +#ifdef PFE_ETH_TX_STATS
  4738. +/** pfe_eth_show_tx_stats
  4739. + *
  4740. + */
  4741. +static ssize_t pfe_eth_show_tx_stats(struct device *dev,
  4742. + struct device_attribute *attr, char *buf)
  4743. +{
  4744. + struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
  4745. + ssize_t len = 0;
  4746. + int i;
  4747. +
  4748. + len += sprintf(buf + len, "TX queues stats:\n");
  4749. +
  4750. + for (i = 0; i < emac_txq_cnt; i++) {
  4751. + struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->dev, i);
  4752. +
  4753. + len += sprintf(buf + len, "\n");
  4754. + __netif_tx_lock_bh(tx_queue);
  4755. +
  4756. + hif_tx_lock(&pfe->hif);
  4757. + len += sprintf(buf + len, "Queue %2d : credits = %10d\n", i, hif_lib_tx_credit_avail(pfe, priv->id, i));
  4758. + len += sprintf(buf + len, " tx packets = %10d\n", pfe->tmu_credit.tx_packets[priv->id][i]);
  4759. + hif_tx_unlock(&pfe->hif);
  4760. +
  4761. + /* Don't output additionnal stats if queue never used */
  4762. + if (!pfe->tmu_credit.tx_packets[priv->id][i])
  4763. + goto skip;
  4764. +
  4765. + len += sprintf(buf + len, " clean_fail = %10d\n", priv->clean_fail[i]);
  4766. + len += sprintf(buf + len, " stop_queue = %10d\n", priv->stop_queue_total[i]);
  4767. + len += sprintf(buf + len, " stop_queue_hif = %10d\n", priv->stop_queue_hif[i]);
  4768. + len += sprintf(buf + len, " stop_queue_hif_client = %10d\n", priv->stop_queue_hif_client[i]);
  4769. + len += sprintf(buf + len, " stop_queue_credit = %10d\n", priv->stop_queue_credit[i]);
  4770. +skip:
  4771. + __netif_tx_unlock_bh(tx_queue);
  4772. + }
  4773. + return len;
  4774. +}
  4775. +
  4776. +/** pfe_eth_set_tx_stats
  4777. + *
  4778. + */
  4779. +static ssize_t pfe_eth_set_tx_stats(struct device *dev,
  4780. + struct device_attribute *attr, const char *buf, size_t count)
  4781. +{
  4782. + struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
  4783. + int i;
  4784. +
  4785. + for (i = 0; i < emac_txq_cnt; i++) {
  4786. + struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->dev, i);
  4787. +
  4788. + __netif_tx_lock_bh(tx_queue);
  4789. + priv->clean_fail[i] = 0;
  4790. + priv->stop_queue_total[i] = 0;
  4791. + priv->stop_queue_hif[i] = 0;
  4792. + priv->stop_queue_hif_client[i]= 0;
  4793. + priv->stop_queue_credit[i] = 0;
  4794. + __netif_tx_unlock_bh(tx_queue);
  4795. + }
  4796. +
  4797. + return count;
  4798. +}
  4799. +#endif
  4800. +/** pfe_eth_show_txavail
  4801. + *
  4802. + */
  4803. +static ssize_t pfe_eth_show_txavail(struct device *dev,
  4804. + struct device_attribute *attr, char *buf)
  4805. +{
  4806. + struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
  4807. + ssize_t len = 0;
  4808. + int i;
  4809. +
  4810. + for (i = 0; i < emac_txq_cnt; i++) {
  4811. + struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->dev, i);
  4812. +
  4813. + __netif_tx_lock_bh(tx_queue);
  4814. +
  4815. + len += sprintf(buf + len, "%d", hif_lib_tx_avail(&priv->client, i));
  4816. +
  4817. + __netif_tx_unlock_bh(tx_queue);
  4818. +
  4819. + if (i == (emac_txq_cnt - 1))
  4820. + len += sprintf(buf + len, "\n");
  4821. + else
  4822. + len += sprintf(buf + len, " ");
  4823. + }
  4824. +
  4825. + return len;
  4826. +}
  4827. +
  4828. +
  4829. +/** pfe_eth_show_default_priority
  4830. + *
  4831. + */
  4832. +static ssize_t pfe_eth_show_default_priority(struct device *dev,
  4833. + struct device_attribute *attr,
  4834. + char *buf)
  4835. +{
  4836. + struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
  4837. + unsigned long flags;
  4838. + int rc;
  4839. +
  4840. + spin_lock_irqsave(&priv->lock, flags);
  4841. + rc = sprintf(buf, "%d\n", priv->default_priority);
  4842. + spin_unlock_irqrestore(&priv->lock, flags);
  4843. +
  4844. + return rc;
  4845. +}
  4846. +
  4847. +/** pfe_eth_set_default_priority
  4848. + *
  4849. + */
  4850. +
  4851. +static ssize_t pfe_eth_set_default_priority(struct device *dev,
  4852. + struct device_attribute *attr,
  4853. + const char *buf, size_t count)
  4854. +{
  4855. + struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
  4856. + unsigned long flags;
  4857. +
  4858. + spin_lock_irqsave(&priv->lock, flags);
  4859. + priv->default_priority = simple_strtoul(buf, NULL, 0);
  4860. + spin_unlock_irqrestore(&priv->lock, flags);
  4861. +
  4862. + return count;
  4863. +}
  4864. +
  4865. +static DEVICE_ATTR(txavail, 0444, pfe_eth_show_txavail, NULL);
  4866. +static DEVICE_ATTR(default_priority, 0644, pfe_eth_show_default_priority, pfe_eth_set_default_priority);
  4867. +
  4868. +#ifdef PFE_ETH_NAPI_STATS
  4869. +static DEVICE_ATTR(napi_stats, 0644, pfe_eth_show_napi_stats, pfe_eth_set_napi_stats);
  4870. +#endif
  4871. +
  4872. +#ifdef PFE_ETH_TX_STATS
  4873. +static DEVICE_ATTR(tx_stats, 0644, pfe_eth_show_tx_stats, pfe_eth_set_tx_stats);
  4874. +#endif
  4875. +
  4876. +
  4877. +/** pfe_eth_sysfs_init
  4878. + *
  4879. + */
  4880. +static int pfe_eth_sysfs_init(struct net_device *dev)
  4881. +{
  4882. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  4883. + int err;
  4884. +
  4885. + /* Initialize the default values */
  4886. + /* By default, packets without conntrack will use this default high priority queue */
  4887. + priv->default_priority = 15;
  4888. +
  4889. + /* Create our sysfs files */
  4890. + err = device_create_file(&dev->dev, &dev_attr_default_priority);
  4891. + if (err) {
  4892. + netdev_err(dev, "failed to create default_priority sysfs files\n");
  4893. + goto err_priority;
  4894. + }
  4895. +
  4896. + err = device_create_file(&dev->dev, &dev_attr_txavail);
  4897. + if (err) {
  4898. + netdev_err(dev, "failed to create default_priority sysfs files\n");
  4899. + goto err_txavail;
  4900. + }
  4901. +
  4902. +#ifdef PFE_ETH_NAPI_STATS
  4903. + err = device_create_file(&dev->dev, &dev_attr_napi_stats);
  4904. + if (err) {
  4905. + netdev_err(dev, "failed to create napi stats sysfs files\n");
  4906. + goto err_napi;
  4907. + }
  4908. +#endif
  4909. +
  4910. +#ifdef PFE_ETH_TX_STATS
  4911. + err = device_create_file(&dev->dev, &dev_attr_tx_stats);
  4912. + if (err) {
  4913. + netdev_err(dev, "failed to create tx stats sysfs files\n");
  4914. + goto err_tx;
  4915. + }
  4916. +#endif
  4917. +
  4918. + return 0;
  4919. +
  4920. +#ifdef PFE_ETH_TX_STATS
  4921. +err_tx:
  4922. +#endif
  4923. +#ifdef PFE_ETH_NAPI_STATS
  4924. + device_remove_file(&dev->dev, &dev_attr_napi_stats);
  4925. +
  4926. +err_napi:
  4927. +#endif
  4928. + device_remove_file(&dev->dev, &dev_attr_txavail);
  4929. +
  4930. +err_txavail:
  4931. + device_remove_file(&dev->dev, &dev_attr_default_priority);
  4932. +
  4933. +err_priority:
  4934. + return -1;
  4935. +}
  4936. +
  4937. +/** pfe_eth_sysfs_exit
  4938. + *
  4939. + */
  4940. +void pfe_eth_sysfs_exit(struct net_device *dev)
  4941. +{
  4942. +#ifdef PFE_ETH_TX_STATS
  4943. + device_remove_file(&dev->dev, &dev_attr_tx_stats);
  4944. +#endif
  4945. +
  4946. +#ifdef PFE_ETH_NAPI_STATS
  4947. + device_remove_file(&dev->dev, &dev_attr_napi_stats);
  4948. +#endif
  4949. + device_remove_file(&dev->dev, &dev_attr_txavail);
  4950. + device_remove_file(&dev->dev, &dev_attr_default_priority);
  4951. +}
  4952. +
  4953. +/*************************************************************************/
  4954. +/* ETHTOOL INTERCAE */
  4955. +/*************************************************************************/
  4956. +
  4957. +#if defined(CONFIG_PLATFORM_C2000)
  4958. +static char stat_gstrings[][ETH_GSTRING_LEN] = {
  4959. + "tx- octets",
  4960. + "tx- packets",
  4961. + "tx- broadcast",
  4962. + "tx- multicast",
  4963. + "tx- pause",
  4964. + "tx- 64 bytes packets",
  4965. + "tx- 64 - 127 bytes packets",
  4966. + "tx- 128 - 255 bytes packets",
  4967. + "tx- 256 - 511 bytes packets",
  4968. + "tx- 512 - 1023 bytes packets",
  4969. + "tx- 1024 - 1518 bytes packets",
  4970. + "tx- > 1518 bytes packets",
  4971. + "tx- underruns - errors",
  4972. + "tx- single collision",
  4973. + "tx- multi collision",
  4974. + "tx- exces. collision - errors",
  4975. + "tx- late collision - errors",
  4976. + "tx- deferred",
  4977. + "tx- carrier sense - errors",
  4978. + "rx- octets",
  4979. + "rx- packets",
  4980. + "rx- broadcast",
  4981. + "rx- multicast",
  4982. + "rx- pause",
  4983. + "rx- 64 bytes packets",
  4984. + "rx- 64 - 127 bytes packets",
  4985. + "rx- 128 - 255 bytes packets",
  4986. + "rx- 256 - 511 bytes packets",
  4987. + "rx- 512 - 1023 bytes packets",
  4988. + "rx- 1024 - 1518 bytes packets",
  4989. + "rx- > 1518 bytes packets",
  4990. + "rx- undersize -errors",
  4991. + "rx- oversize - errors ",
  4992. + "rx- jabbers - errors",
  4993. + "rx- fcs - errors",
  4994. + "rx- length - errors",
  4995. + "rx- symbol - errors",
  4996. + "rx- align - errors",
  4997. + "rx- ressource - errors",
  4998. + "rx- overrun - errors",
  4999. + "rx- IP cksum - errors",
  5000. + "rx- TCP cksum - errors",
  5001. + "rx- UDP cksum - errors"
  5002. +};
  5003. +
  5004. +
  5005. +/**
  5006. + * pfe_eth_gstrings - Fill in a buffer with the strings which correspond to
  5007. + * the stats.
  5008. + *
  5009. + */
  5010. +static void pfe_eth_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
  5011. +{
  5012. + switch (stringset) {
  5013. + case ETH_SS_STATS:
  5014. + memcpy(buf, stat_gstrings, (EMAC_RMON_LEN - 2) * ETH_GSTRING_LEN);
  5015. + break;
  5016. +
  5017. + default:
  5018. + WARN_ON(1);
  5019. + break;
  5020. + }
  5021. +}
  5022. +
  5023. +/**
  5024. + * pfe_eth_fill_stats - Fill in an array of 64-bit statistics from
  5025. + * various sources. This array will be appended
  5026. + * to the end of the ethtool_stats* structure, and
  5027. + * returned to user space
  5028. + */
  5029. +static void pfe_eth_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
  5030. +{
  5031. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5032. + int i;
  5033. + for (i=0;i<EMAC_RMON_LEN;i++, buf++) {
  5034. + *buf = readl(priv->EMAC_baseaddr + EMAC_RMON_BASE_OFST + (i << 2));
  5035. + if ( ( i == EMAC_RMON_TXBYTES_POS ) || ( i == EMAC_RMON_RXBYTES_POS ) ){
  5036. + i++;
  5037. + *buf |= (u64)readl(priv->EMAC_baseaddr + EMAC_RMON_BASE_OFST + (i << 2)) << 32;
  5038. + }
  5039. + }
  5040. +
  5041. +}
  5042. +
  5043. +/**
  5044. + * pfe_eth_stats_count - Returns the number of stats (and their corresponding strings)
  5045. + *
  5046. + */
  5047. +static int pfe_eth_stats_count(struct net_device *dev, int sset)
  5048. +{
  5049. + switch (sset) {
  5050. + case ETH_SS_STATS:
  5051. + return EMAC_RMON_LEN - 2;
  5052. + default:
  5053. + return -EOPNOTSUPP;
  5054. + }
  5055. +}
  5056. +
  5057. +#if defined(CONFIG_PLATFORM_C2000)
  5058. +/**
  5059. + * pfe_eth_set_wol - Set the magic packet option, in WoL register.
  5060. + *
  5061. + */
  5062. +static int pfe_eth_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
  5063. +{
  5064. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5065. +
  5066. + if (wol->wolopts & ~(WAKE_MAGIC | WAKE_ARP | WAKE_MCAST | WAKE_UCAST))
  5067. + return -EOPNOTSUPP;
  5068. +
  5069. + priv->wol = 0;
  5070. +
  5071. + if (wol->wolopts & WAKE_MAGIC)
  5072. + priv->wol |= EMAC_WOL_MAGIC;
  5073. + if (wol->wolopts & WAKE_ARP)
  5074. + priv->wol |= EMAC_WOL_ARP;
  5075. + if (wol->wolopts & WAKE_MCAST)
  5076. + priv->wol |= EMAC_WOL_MULTI;
  5077. + if (wol->wolopts & WAKE_UCAST)
  5078. + priv->wol |= EMAC_WOL_SPEC_ADDR;
  5079. +
  5080. + pfe_eth_set_device_wakeup(priv->pfe);
  5081. +
  5082. + return 0;
  5083. +}
  5084. +
  5085. +/**
  5086. + *
  5087. + * pfe_eth_get_wol - Get the WoL options.
  5088. + *
  5089. + */
  5090. +static void pfe_eth_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
  5091. +{
  5092. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5093. +
  5094. + wol->supported = (WAKE_MAGIC | WAKE_ARP | WAKE_MCAST | WAKE_UCAST);
  5095. + wol->wolopts = 0;
  5096. +
  5097. + if(priv->wol & EMAC_WOL_MAGIC)
  5098. + wol->wolopts |= WAKE_MAGIC;
  5099. + if(priv->wol & EMAC_WOL_ARP)
  5100. + wol->wolopts |= WAKE_ARP;
  5101. + if(priv->wol & EMAC_WOL_MULTI)
  5102. + wol->wolopts |= WAKE_UCAST;
  5103. + if(priv->wol & EMAC_WOL_SPEC_ADDR)
  5104. + wol->wolopts |= WAKE_UCAST;
  5105. +
  5106. + memset(&wol->sopass, 0, sizeof(wol->sopass));
  5107. +}
  5108. +#endif
  5109. +/**
  5110. + * pfe_eth_gemac_reglen - Return the length of the register structure.
  5111. + *
  5112. + */
  5113. +static int pfe_eth_gemac_reglen(struct net_device *dev)
  5114. +{
  5115. + return (sizeof (gemac_regs)/ sizeof(u32)) + (( MAX_UC_SPEC_ADDR_REG - 3 ) * 2);
  5116. +}
  5117. +
  5118. +/**
  5119. + * pfe_eth_gemac_get_regs - Return the gemac register structure.
  5120. + *
  5121. + */
  5122. +static void pfe_eth_gemac_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
  5123. +{
  5124. + int i,j;
  5125. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5126. + u32 *buf = (u32 *) regbuf;
  5127. +
  5128. + for (i = 0; i < sizeof (gemac_regs) / sizeof (u32); i++)
  5129. + buf[i] = readl( priv->EMAC_baseaddr + gemac_regs[i] );
  5130. +
  5131. + for (j = 0; j < (( MAX_UC_SPEC_ADDR_REG - 3 ) * 2); j++,i++)
  5132. + buf[i] = readl( priv->EMAC_baseaddr + EMAC_SPEC5_ADD_BOT + (j<<2) );
  5133. +
  5134. +}
  5135. +
  5136. +
  5137. +#else //if defined(CONFIG_PLATFORM_C2000)
  5138. +/*MTIP GEMAC */
  5139. +static const struct fec_stat {
  5140. + char name[ETH_GSTRING_LEN];
  5141. + u16 offset;
  5142. +} fec_stats[] = {
  5143. + /* RMON TX */
  5144. + { "tx_dropped", RMON_T_DROP },
  5145. + { "tx_packets", RMON_T_PACKETS },
  5146. + { "tx_broadcast", RMON_T_BC_PKT },
  5147. + { "tx_multicast", RMON_T_MC_PKT },
  5148. + { "tx_crc_errors", RMON_T_CRC_ALIGN },
  5149. + { "tx_undersize", RMON_T_UNDERSIZE },
  5150. + { "tx_oversize", RMON_T_OVERSIZE },
  5151. + { "tx_fragment", RMON_T_FRAG },
  5152. + { "tx_jabber", RMON_T_JAB },
  5153. + { "tx_collision", RMON_T_COL },
  5154. + { "tx_64byte", RMON_T_P64 },
  5155. + { "tx_65to127byte", RMON_T_P65TO127 },
  5156. + { "tx_128to255byte", RMON_T_P128TO255 },
  5157. + { "tx_256to511byte", RMON_T_P256TO511 },
  5158. + { "tx_512to1023byte", RMON_T_P512TO1023 },
  5159. + { "tx_1024to2047byte", RMON_T_P1024TO2047 },
  5160. + { "tx_GTE2048byte", RMON_T_P_GTE2048 },
  5161. + { "tx_octets", RMON_T_OCTETS },
  5162. +
  5163. + /* IEEE TX */
  5164. + { "IEEE_tx_drop", IEEE_T_DROP },
  5165. + { "IEEE_tx_frame_ok", IEEE_T_FRAME_OK },
  5166. + { "IEEE_tx_1col", IEEE_T_1COL },
  5167. + { "IEEE_tx_mcol", IEEE_T_MCOL },
  5168. + { "IEEE_tx_def", IEEE_T_DEF },
  5169. + { "IEEE_tx_lcol", IEEE_T_LCOL },
  5170. + { "IEEE_tx_excol", IEEE_T_EXCOL },
  5171. + { "IEEE_tx_macerr", IEEE_T_MACERR },
  5172. + { "IEEE_tx_cserr", IEEE_T_CSERR },
  5173. + { "IEEE_tx_sqe", IEEE_T_SQE },
  5174. + { "IEEE_tx_fdxfc", IEEE_T_FDXFC },
  5175. + { "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK },
  5176. +
  5177. + /* RMON RX */
  5178. + { "rx_packets", RMON_R_PACKETS },
  5179. + { "rx_broadcast", RMON_R_BC_PKT },
  5180. + { "rx_multicast", RMON_R_MC_PKT },
  5181. + { "rx_crc_errors", RMON_R_CRC_ALIGN },
  5182. + { "rx_undersize", RMON_R_UNDERSIZE },
  5183. + { "rx_oversize", RMON_R_OVERSIZE },
  5184. + { "rx_fragment", RMON_R_FRAG },
  5185. + { "rx_jabber", RMON_R_JAB },
  5186. + { "rx_64byte", RMON_R_P64 },
  5187. + { "rx_65to127byte", RMON_R_P65TO127 },
  5188. + { "rx_128to255byte", RMON_R_P128TO255 },
  5189. + { "rx_256to511byte", RMON_R_P256TO511 },
  5190. + { "rx_512to1023byte", RMON_R_P512TO1023 },
  5191. + { "rx_1024to2047byte", RMON_R_P1024TO2047 },
  5192. + { "rx_GTE2048byte", RMON_R_P_GTE2048 },
  5193. + { "rx_octets", RMON_R_OCTETS },
  5194. +
  5195. + /* IEEE RX */
  5196. + { "IEEE_rx_drop", IEEE_R_DROP },
  5197. + { "IEEE_rx_frame_ok", IEEE_R_FRAME_OK },
  5198. + { "IEEE_rx_crc", IEEE_R_CRC },
  5199. + { "IEEE_rx_align", IEEE_R_ALIGN },
  5200. + { "IEEE_rx_macerr", IEEE_R_MACERR },
  5201. + { "IEEE_rx_fdxfc", IEEE_R_FDXFC },
  5202. + { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
  5203. +};
  5204. +
  5205. +static void pfe_eth_fill_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
  5206. +{
  5207. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5208. + int i;
  5209. +
  5210. + for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
  5211. + data[i] = readl(priv->EMAC_baseaddr + fec_stats[i].offset);
  5212. +}
  5213. +
  5214. +static void pfe_eth_gstrings(struct net_device *netdev,
  5215. + u32 stringset, u8 *data)
  5216. +{
  5217. + int i;
  5218. + switch (stringset) {
  5219. + case ETH_SS_STATS:
  5220. + for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
  5221. + memcpy(data + i * ETH_GSTRING_LEN,
  5222. + fec_stats[i].name, ETH_GSTRING_LEN);
  5223. + break;
  5224. + }
  5225. +}
  5226. +
  5227. +static int pfe_eth_stats_count(struct net_device *dev, int sset)
  5228. +{
  5229. + switch (sset) {
  5230. + case ETH_SS_STATS:
  5231. + return ARRAY_SIZE(fec_stats);
  5232. + default:
  5233. + return -EOPNOTSUPP;
  5234. + }
  5235. +}
  5236. +
  5237. +/**
  5238. + * pfe_eth_gemac_reglen - Return the length of the register structure.
  5239. + *
  5240. + */
  5241. +static int pfe_eth_gemac_reglen(struct net_device *dev)
  5242. +{
  5243. + printk("%s() \n", __func__);
  5244. + return (sizeof (gemac_regs)/ sizeof(u32)) ;
  5245. +}
  5246. +
  5247. +/**
  5248. + * pfe_eth_gemac_get_regs - Return the gemac register structure.
  5249. + *
  5250. + */
  5251. +static void pfe_eth_gemac_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
  5252. +{
  5253. + int i;
  5254. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5255. + u32 *buf = (u32 *) regbuf;
  5256. +
  5257. + printk("%s() \n", __func__);
  5258. + for (i = 0; i < sizeof (gemac_regs) / sizeof (u32); i++)
  5259. + buf[i] = readl( priv->EMAC_baseaddr + gemac_regs[i] );
  5260. +
  5261. +}
  5262. +
  5263. +
  5264. +#endif
  5265. +
  5266. +/**
  5267. + * pfe_eth_get_drvinfo - Fills in the drvinfo structure with some basic info
  5268. + *
  5269. + */
  5270. +static void pfe_eth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
  5271. +{
  5272. + strncpy(drvinfo->driver, DRV_NAME, COMCERTO_INFOSTR_LEN);
  5273. + strncpy(drvinfo->version, comcerto_eth_driver_version, COMCERTO_INFOSTR_LEN);
  5274. + strncpy(drvinfo->fw_version, "N/A", COMCERTO_INFOSTR_LEN);
  5275. + strncpy(drvinfo->bus_info, "N/A", COMCERTO_INFOSTR_LEN);
  5276. + drvinfo->testinfo_len = 0;
  5277. + drvinfo->regdump_len = 0;
  5278. + drvinfo->eedump_len = 0;
  5279. +}
  5280. +
  5281. +/**
  5282. + * pfe_eth_set_settings - Used to send commands to PHY.
  5283. + *
  5284. + */
  5285. +
  5286. +static int pfe_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  5287. +{
  5288. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5289. + struct phy_device *phydev = priv->phydev;
  5290. +
  5291. + if (NULL == phydev)
  5292. + return -ENODEV;
  5293. +
  5294. + return phy_ethtool_sset(phydev, cmd);
  5295. +}
  5296. +
  5297. +
  5298. +/**
  5299. + * pfe_eth_getsettings - Return the current settings in the ethtool_cmd structure.
  5300. + *
  5301. + */
  5302. +static int pfe_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  5303. +{
  5304. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5305. + struct phy_device *phydev = priv->phydev;
  5306. +
  5307. + if (NULL == phydev)
  5308. + return -ENODEV;
  5309. +
  5310. + return phy_ethtool_gset(phydev, cmd);
  5311. +}
  5312. +
  5313. +
  5314. +/**
  5315. + * pfe_eth_get_msglevel - Gets the debug message mask.
  5316. + *
  5317. + */
  5318. +static uint32_t pfe_eth_get_msglevel(struct net_device *dev)
  5319. +{
  5320. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5321. +
  5322. + return priv->msg_enable;
  5323. +}
  5324. +
  5325. +/**
  5326. + * pfe_eth_set_msglevel - Sets the debug message mask.
  5327. + *
  5328. + */
  5329. +static void pfe_eth_set_msglevel(struct net_device *dev, uint32_t data)
  5330. +{
  5331. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5332. +
  5333. + priv->msg_enable = data;
  5334. +}
  5335. +
  5336. +#define HIF_RX_COAL_MAX_CLKS (~(1<<31))
  5337. +#define HIF_RX_COAL_CLKS_PER_USEC (pfe->ctrl.sys_clk/1000)
  5338. +#define HIF_RX_COAL_MAX_USECS (HIF_RX_COAL_MAX_CLKS/HIF_RX_COAL_CLKS_PER_USEC)
  5339. +
  5340. +/**
  5341. + * pfe_eth_set_coalesce - Sets rx interrupt coalescing timer.
  5342. + *
  5343. + */
  5344. +static int pfe_eth_set_coalesce(struct net_device *dev,
  5345. + struct ethtool_coalesce *ec)
  5346. +{
  5347. + if (ec->rx_coalesce_usecs > HIF_RX_COAL_MAX_USECS)
  5348. + return -EINVAL;
  5349. +
  5350. + if (!ec->rx_coalesce_usecs) {
  5351. + writel(0, HIF_INT_COAL);
  5352. + return 0;
  5353. + }
  5354. +
  5355. + writel((ec->rx_coalesce_usecs * HIF_RX_COAL_CLKS_PER_USEC) | HIF_INT_COAL_ENABLE, HIF_INT_COAL);
  5356. +
  5357. + return 0;
  5358. +}
  5359. +
  5360. +/**
  5361. + * pfe_eth_get_coalesce - Gets rx interrupt coalescing timer value.
  5362. + *
  5363. + */
  5364. +static int pfe_eth_get_coalesce(struct net_device *dev,
  5365. + struct ethtool_coalesce *ec)
  5366. +{
  5367. + int reg_val = readl(HIF_INT_COAL);
  5368. +
  5369. + if (reg_val & HIF_INT_COAL_ENABLE)
  5370. + ec->rx_coalesce_usecs = (reg_val & HIF_RX_COAL_MAX_CLKS) / HIF_RX_COAL_CLKS_PER_USEC;
  5371. + else
  5372. + ec->rx_coalesce_usecs = 0;
  5373. +
  5374. + return 0;
  5375. +}
  5376. +
  5377. +#if defined(CONFIG_PLATFORM_C2000)
  5378. +/**
  5379. + * pfe_eth_pause_rx_enabled - Tests if pause rx is enabled on GEM
  5380. + *
  5381. + */
  5382. +static int pfe_eth_pause_rx_enabled(struct pfe_eth_priv_s *priv)
  5383. +{
  5384. + return (readl(priv->EMAC_baseaddr + EMAC_NETWORK_CONFIG) & EMAC_ENABLE_PAUSE_RX) != 0;
  5385. +}
  5386. +
  5387. +/**
  5388. + * pfe_eth_set_pauseparam - Sets pause parameters
  5389. + *
  5390. + */
  5391. +static int pfe_eth_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
  5392. +{
  5393. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5394. +
  5395. + if (epause->rx_pause)
  5396. + {
  5397. + gemac_enable_pause_rx(priv->EMAC_baseaddr);
  5398. + if (priv->phydev)
  5399. + priv->phydev->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
  5400. + }
  5401. + else
  5402. + {
  5403. + gemac_disable_pause_rx(priv->EMAC_baseaddr);
  5404. + if (priv->phydev)
  5405. + priv->phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
  5406. + }
  5407. +
  5408. + return 0;
  5409. +}
  5410. +
  5411. +/**
  5412. + * pfe_eth_get_pauseparam - Gets pause parameters
  5413. + *
  5414. + */
  5415. +static void pfe_eth_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
  5416. +{
  5417. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5418. +
  5419. + epause->autoneg = 0;
  5420. + epause->tx_pause = 0;
  5421. + epause->rx_pause = pfe_eth_pause_rx_enabled(priv);
  5422. +}
  5423. +
  5424. +/** pfe_eth_get_hash
  5425. + */
  5426. +static int pfe_eth_get_hash(u8 * addr)
  5427. +{
  5428. + u8 temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8;
  5429. + temp1 = addr[0] & 0x3F ;
  5430. + temp2 = ((addr[0] & 0xC0) >> 6)| ((addr[1] & 0x0F) << 2);
  5431. + temp3 = ((addr[1] & 0xF0) >> 4) | ((addr[2] & 0x03) << 4);
  5432. + temp4 = (addr[2] & 0xFC) >> 2;
  5433. + temp5 = addr[3] & 0x3F;
  5434. + temp6 = ((addr[3] & 0xC0) >> 6) | ((addr[4] & 0x0F) << 2);
  5435. + temp7 = ((addr[4] & 0xF0) >>4 ) | ((addr[5] & 0x03) << 4);
  5436. + temp8 = ((addr[5] &0xFC) >> 2);
  5437. + return (temp1 ^ temp2 ^ temp3 ^ temp4 ^ temp5 ^ temp6 ^ temp7 ^ temp8);
  5438. +}
  5439. +
  5440. +#else
  5441. + /*TODO Add pause frame support for LS1012A */
  5442. +
  5443. +/** pfe_eth_get_hash
  5444. + */
  5445. +#define HASH_BITS 6 /* #bits in hash */
  5446. +#define CRC32_POLY 0xEDB88320
  5447. +
  5448. +static int pfe_eth_get_hash(u8 * addr)
  5449. +{
  5450. + unsigned int i, bit, data, crc, hash;
  5451. +
  5452. + /* calculate crc32 value of mac address */
  5453. + crc = 0xffffffff;
  5454. +
  5455. + for (i = 0; i < 6; i++) {
  5456. + data = addr[i];
  5457. + for (bit = 0; bit < 8; bit++, data >>= 1) {
  5458. + crc = (crc >> 1) ^
  5459. + (((crc ^ data) & 1) ? CRC32_POLY : 0);
  5460. + }
  5461. + }
  5462. +
  5463. + /* only upper 6 bits (HASH_BITS) are used
  5464. + * which point to specific bit in he hash registers
  5465. + */
  5466. + hash = (crc >> (32 - HASH_BITS)) & 0x3f;
  5467. +
  5468. + return hash;
  5469. +}
  5470. +
  5471. +#endif
  5472. +
  5473. +struct ethtool_ops pfe_ethtool_ops = {
  5474. + .get_settings = pfe_eth_get_settings,
  5475. + .set_settings = pfe_eth_set_settings,
  5476. + .get_drvinfo = pfe_eth_get_drvinfo,
  5477. + .get_regs_len = pfe_eth_gemac_reglen,
  5478. + .get_regs = pfe_eth_gemac_get_regs,
  5479. + .get_link = ethtool_op_get_link,
  5480. +#if defined(CONFIG_PLATFORM_C2000)
  5481. + .get_wol = pfe_eth_get_wol,
  5482. + .set_wol = pfe_eth_set_wol,
  5483. + .set_pauseparam = pfe_eth_set_pauseparam,
  5484. + .get_pauseparam = pfe_eth_get_pauseparam,
  5485. +#endif
  5486. + .get_strings = pfe_eth_gstrings,
  5487. + .get_sset_count = pfe_eth_stats_count,
  5488. + .get_ethtool_stats = pfe_eth_fill_stats,
  5489. + .get_msglevel = pfe_eth_get_msglevel,
  5490. + .set_msglevel = pfe_eth_set_msglevel,
  5491. + .set_coalesce = pfe_eth_set_coalesce,
  5492. + .get_coalesce = pfe_eth_get_coalesce,
  5493. +};
  5494. +
  5495. +
  5496. +
  5497. +#if defined(CONFIG_PLATFORM_C2000)
  5498. +/** pfe_eth_mdio_reset
  5499. + */
  5500. +int pfe_eth_mdio_reset(struct mii_bus *bus)
  5501. +{
  5502. + struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
  5503. +
  5504. + netif_info(priv, hw, priv->dev, "%s\n", __func__);
  5505. +
  5506. +#if !defined(CONFIG_PLATFORM_EMULATION)
  5507. + mutex_lock(&bus->mdio_lock);
  5508. +
  5509. + /* Setup the MII Mgmt clock speed */
  5510. + if (priv->mii_bus)
  5511. + gemac_set_mdc_div(priv->EMAC_baseaddr, priv->mdc_div);
  5512. +
  5513. + /* Reset the management interface */
  5514. + __raw_writel(__raw_readl(priv->EMAC_baseaddr + EMAC_NETWORK_CONTROL) | EMAC_MDIO_EN,
  5515. + priv->EMAC_baseaddr + EMAC_NETWORK_CONTROL);
  5516. +
  5517. + /* Wait until the bus is free */
  5518. + while(!(__raw_readl(priv->EMAC_baseaddr + EMAC_NETWORK_STATUS) & EMAC_PHY_IDLE));
  5519. +
  5520. + mutex_unlock(&bus->mdio_lock);
  5521. +#endif
  5522. +
  5523. + return 0;
  5524. +}
  5525. +
  5526. +
  5527. +/** pfe_eth_gemac_phy_timeout
  5528. + *
  5529. + */
  5530. +static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout)
  5531. +{
  5532. + while(!(__raw_readl(priv->EMAC_baseaddr + EMAC_NETWORK_STATUS) & EMAC_PHY_IDLE)) {
  5533. +
  5534. + if (timeout-- <= 0) {
  5535. + return -1;
  5536. + }
  5537. +
  5538. + udelay(10);
  5539. + }
  5540. +
  5541. + return 0;
  5542. +}
  5543. +
  5544. +
  5545. +/** pfe_eth_mdio_write
  5546. + */
  5547. +static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
  5548. +{
  5549. + struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
  5550. + u32 write_data;
  5551. +
  5552. +#if !defined(CONFIG_PLATFORM_EMULATION)
  5553. +
  5554. + netif_info(priv, hw, priv->dev, "%s: phy %d\n", __func__, mii_id);
  5555. +
  5556. +// netif_info(priv, hw, priv->dev, "%s %d %d %x\n", bus->id, mii_id, regnum, value);
  5557. +
  5558. + write_data = 0x50020000;
  5559. + write_data |= ((mii_id << 23) | (regnum << 18) | value);
  5560. + __raw_writel(write_data, priv->EMAC_baseaddr + EMAC_PHY_MANAGEMENT);
  5561. +
  5562. + if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)){
  5563. + netdev_err(priv->dev, "%s: phy MDIO write timeout\n", __func__);
  5564. + return -1;
  5565. + }
  5566. +
  5567. +#endif
  5568. +
  5569. + return 0;
  5570. +}
  5571. +
  5572. +
  5573. +/** pfe_eth_mdio_read
  5574. + */
  5575. +static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
  5576. +{
  5577. + struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
  5578. + u16 value = 0;
  5579. + u32 write_data;
  5580. +
  5581. +#if !defined(CONFIG_PLATFORM_EMULATION)
  5582. + netif_info(priv, hw, priv->dev, "%s: phy %d\n", __func__, mii_id);
  5583. +
  5584. + write_data = 0x60020000;
  5585. + write_data |= ((mii_id << 23) | (regnum << 18));
  5586. +
  5587. + __raw_writel(write_data, priv->EMAC_baseaddr + EMAC_PHY_MANAGEMENT);
  5588. +
  5589. + if (pfe_eth_gemac_phy_timeout( priv, EMAC_MDIO_TIMEOUT)) {
  5590. + netdev_err(priv->dev, "%s: phy MDIO read timeout\n", __func__);
  5591. + return -1;
  5592. + }
  5593. +
  5594. + value = __raw_readl(priv->EMAC_baseaddr + EMAC_PHY_MANAGEMENT) & 0xFFFF;
  5595. +#endif
  5596. +
  5597. +// netif_info(priv, hw, priv->dev, "%s %d %d %x\n", bus->id, mii_id, regnum, value);
  5598. +
  5599. + return value;
  5600. +}
  5601. +
  5602. +#else
  5603. +/** pfe_eth_mdio_reset
  5604. + */
  5605. +int pfe_eth_mdio_reset(struct mii_bus *bus)
  5606. +{
  5607. + struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
  5608. + u32 phy_speed, pclk = 250000000; /*TODO this needs to be checked read from the correct source*/
  5609. +
  5610. + netif_info(priv, hw, priv->dev, "%s\n", __func__);
  5611. +
  5612. + mutex_lock(&bus->mdio_lock);
  5613. +
  5614. + /*
  5615. + * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed)
  5616. + *
  5617. + * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while
  5618. + * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'.
  5619. + */
  5620. + phy_speed = (DIV_ROUND_UP(pclk, 4000000) << EMAC_MII_SPEED_SHIFT);
  5621. + phy_speed |= EMAC_HOLDTIME(0x5);
  5622. + __raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG);
  5623. +
  5624. + mutex_unlock(&bus->mdio_lock);
  5625. +
  5626. + return 0;
  5627. +}
  5628. +
  5629. +/** pfe_eth_gemac_phy_timeout
  5630. + *
  5631. + */
  5632. +static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout)
  5633. +{
  5634. + while(!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) {
  5635. +
  5636. + if (timeout-- <= 0) {
  5637. + return -1;
  5638. + }
  5639. +
  5640. + udelay(10);
  5641. + }
  5642. + __raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG);
  5643. +
  5644. + return 0;
  5645. +}
  5646. +
  5647. +static int pfe_eth_mdio_mux(u8 muxval)
  5648. +{
  5649. + struct i2c_adapter *a;
  5650. + struct i2c_msg msg;
  5651. + unsigned char buf[2];
  5652. + int ret;
  5653. +
  5654. + a = i2c_get_adapter(0);
  5655. + if (!a)
  5656. + return -ENODEV;
  5657. +
  5658. + /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */
  5659. + buf[0] = 0x54; //reg number
  5660. + buf[1] = (muxval << 6)| 0x3; //data
  5661. + msg.addr = 0x66;
  5662. + msg.buf = buf;
  5663. + msg.len = 2;
  5664. + msg.flags = 0;
  5665. + ret = i2c_transfer(a, &msg, 1);
  5666. + i2c_put_adapter(a);
  5667. + if (ret != 1)
  5668. + return -ENODEV;
  5669. + return 0;
  5670. +
  5671. +
  5672. +}
  5673. +
  5674. +static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
  5675. +{
  5676. + struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
  5677. +
  5678. + /*FIXME Dirty hack to configure mux */
  5679. + if(priv->mdio_muxval) {
  5680. + if(mii_id == 0x1)
  5681. + pfe_eth_mdio_mux(0x1);
  5682. + else
  5683. + pfe_eth_mdio_mux(0x2);
  5684. + }
  5685. +
  5686. + /* start a write op */
  5687. + __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
  5688. + EMAC_MII_DATA_PA(mii_id) | EMAC_MII_DATA_RA(regnum) |
  5689. + EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
  5690. + priv->PHY_baseaddr + EMAC_MII_DATA_REG);
  5691. +
  5692. + if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)){
  5693. + netdev_err(priv->dev, "%s: phy MDIO write timeout\n", __func__);
  5694. + return -1;
  5695. + }
  5696. + netif_info(priv, hw, priv->dev, "%s: phy %x reg %x val %x\n", __func__, mii_id, regnum, value);
  5697. +
  5698. + return 0;
  5699. +
  5700. +
  5701. +}
  5702. +static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
  5703. +{
  5704. + struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
  5705. + u16 value = 0;
  5706. +
  5707. + /*FIXME Dirty hack to configure mux */
  5708. + if(priv->mdio_muxval){
  5709. + if(mii_id == 0x1)
  5710. + pfe_eth_mdio_mux(0x1);
  5711. + else
  5712. + pfe_eth_mdio_mux(0x2);
  5713. + }
  5714. +
  5715. + /* start a read op */
  5716. + __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
  5717. + EMAC_MII_DATA_PA(mii_id) | EMAC_MII_DATA_RA(regnum) |
  5718. + EMAC_MII_DATA_TA, priv->PHY_baseaddr + EMAC_MII_DATA_REG);
  5719. +
  5720. + if (pfe_eth_gemac_phy_timeout( priv, EMAC_MDIO_TIMEOUT)) {
  5721. + netdev_err(priv->dev, "%s: phy MDIO read timeout\n", __func__);
  5722. + return -1;
  5723. + }
  5724. +
  5725. + value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr + EMAC_MII_DATA_REG));
  5726. + netif_info(priv, hw, priv->dev, "%s: phy %x reg %x val %x\n", __func__, mii_id, regnum, value);
  5727. + return value;
  5728. +}
  5729. +#endif
  5730. +static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv, struct comcerto_mdio_platform_data *minfo)
  5731. +{
  5732. + struct mii_bus *bus;
  5733. + int rc;
  5734. +
  5735. + netif_info(priv, drv, priv->dev, "%s\n", __func__);
  5736. + printk( "%s\n", __func__);
  5737. +
  5738. +#if !defined(CONFIG_PLATFORM_EMULATION)
  5739. + bus = mdiobus_alloc();
  5740. + if (!bus) {
  5741. + netdev_err(priv->dev, "mdiobus_alloc() failed\n");
  5742. + rc = -ENOMEM;
  5743. + goto err0;
  5744. + }
  5745. +
  5746. + bus->name = "Comcerto MDIO Bus";
  5747. + bus->read = &pfe_eth_mdio_read;
  5748. + bus->write = &pfe_eth_mdio_write;
  5749. + bus->reset = &pfe_eth_mdio_reset;
  5750. + snprintf(bus->id, MII_BUS_ID_SIZE, "comcerto-%x", priv->id);
  5751. + bus->priv = priv;
  5752. +
  5753. + bus->phy_mask = minfo->phy_mask;
  5754. + priv->mdc_div = minfo->mdc_div;
  5755. +
  5756. + if (!priv->mdc_div)
  5757. + priv->mdc_div = 64;
  5758. +
  5759. + bus->irq = minfo->irq;
  5760. +
  5761. + bus->parent = priv->pfe->dev;
  5762. +
  5763. + netif_info(priv, drv, priv->dev, "%s: mdc_div: %d, phy_mask: %x \n", __func__, priv->mdc_div, bus->phy_mask);
  5764. + rc = mdiobus_register(bus);
  5765. + if (rc) {
  5766. + netdev_err(priv->dev, "mdiobus_register(%s) failed\n", bus->name);
  5767. + goto err1;
  5768. + }
  5769. +
  5770. + priv->mii_bus = bus;
  5771. + pfe_eth_mdio_reset(bus);
  5772. +
  5773. + return 0;
  5774. +
  5775. +err1:
  5776. + mdiobus_free(bus);
  5777. +err0:
  5778. + return rc;
  5779. +#else
  5780. + return 0;
  5781. +#endif
  5782. +
  5783. +}
  5784. +
  5785. +/** pfe_eth_mdio_exit
  5786. + */
  5787. +static void pfe_eth_mdio_exit(struct mii_bus *bus)
  5788. +{
  5789. + if (!bus)
  5790. + return;
  5791. +
  5792. + netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct pfe_eth_priv_s *)(bus->priv))->dev, "%s\n", __func__);
  5793. +
  5794. + mdiobus_unregister(bus);
  5795. + mdiobus_free(bus);
  5796. +}
  5797. +
  5798. +#if defined(CONFIG_PLATFORM_C2000)
  5799. +/** pfe_get_interface
  5800. + */
  5801. +static phy_interface_t pfe_get_interface(struct net_device *dev)
  5802. +{
  5803. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5804. + u32 mii_mode = priv->einfo->mii_config;
  5805. +
  5806. + netif_info(priv, drv, dev, "%s\n", __func__);
  5807. +
  5808. + if (priv->einfo->gemac_mode & (GEMAC_SW_CONF)) {
  5809. + switch (mii_mode) {
  5810. + case CONFIG_COMCERTO_USE_GMII:
  5811. + return PHY_INTERFACE_MODE_GMII;
  5812. + break;
  5813. + case CONFIG_COMCERTO_USE_RGMII:
  5814. + return PHY_INTERFACE_MODE_RGMII;
  5815. + break;
  5816. + case CONFIG_COMCERTO_USE_RMII:
  5817. + return PHY_INTERFACE_MODE_RMII;
  5818. + break;
  5819. + case CONFIG_COMCERTO_USE_SGMII:
  5820. + return PHY_INTERFACE_MODE_SGMII;
  5821. + break;
  5822. +
  5823. + default :
  5824. + case CONFIG_COMCERTO_USE_MII:
  5825. + return PHY_INTERFACE_MODE_MII;
  5826. + break;
  5827. +
  5828. + }
  5829. + } else {
  5830. + // Bootstrap config read from controller
  5831. + BUG();
  5832. + return 0;
  5833. + }
  5834. +}
  5835. +#endif
  5836. +
  5837. +/** pfe_get_phydev_speed
  5838. + */
  5839. +static int pfe_get_phydev_speed(struct phy_device *phydev)
  5840. +{
  5841. + switch (phydev->speed) {
  5842. + case 10:
  5843. + return SPEED_10M;
  5844. + case 100:
  5845. + return SPEED_100M;
  5846. + case 1000:
  5847. + default:
  5848. + return SPEED_1000M;
  5849. + }
  5850. +
  5851. +}
  5852. +
  5853. +/** pfe_set_rgmii_speed
  5854. + */
  5855. +#define RGMIIPCR 0x434
  5856. +/* RGMIIPCR bit definitions*/
  5857. +#define SCFG_RGMIIPCR_EN_AUTO (0x00000008)
  5858. +#define SCFG_RGMIIPCR_SETSP_1000M (0x00000004)
  5859. +#define SCFG_RGMIIPCR_SETSP_100M (0x00000000)
  5860. +#define SCFG_RGMIIPCR_SETSP_10M (0x00000002)
  5861. +#define SCFG_RGMIIPCR_SETFD (0x00000001)
  5862. +
  5863. +static void pfe_set_rgmii_speed(struct phy_device *phydev)
  5864. +{
  5865. + u32 rgmii_pcr;
  5866. +
  5867. + regmap_read(pfe->scfg, RGMIIPCR, &rgmii_pcr);
  5868. + rgmii_pcr &= ~(SCFG_RGMIIPCR_SETSP_1000M|SCFG_RGMIIPCR_SETSP_10M);
  5869. +
  5870. + switch (phydev->speed) {
  5871. + case 10:
  5872. + rgmii_pcr |= SCFG_RGMIIPCR_SETSP_10M;
  5873. + break;
  5874. + case 1000:
  5875. + rgmii_pcr |= SCFG_RGMIIPCR_SETSP_1000M;
  5876. + break;
  5877. + case 100:
  5878. + default:
  5879. + /* Default is 100M */
  5880. + break;
  5881. + }
  5882. + regmap_write(pfe->scfg, RGMIIPCR, rgmii_pcr);
  5883. +
  5884. +
  5885. +}
  5886. +/** pfe_get_phydev_duplex
  5887. + */
  5888. +static int pfe_get_phydev_duplex(struct phy_device *phydev)
  5889. +{
  5890. + //return ( phydev->duplex == DUPLEX_HALF ) ? DUP_HALF:DUP_FULL ;
  5891. + return DUPLEX_FULL;
  5892. +}
  5893. +
  5894. +/** pfe_eth_adjust_link
  5895. + */
  5896. +static void pfe_eth_adjust_link(struct net_device *dev)
  5897. +{
  5898. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5899. + unsigned long flags;
  5900. + struct phy_device *phydev = priv->phydev;
  5901. + int new_state = 0;
  5902. +
  5903. + netif_info(priv, drv, dev, "%s\n", __func__);
  5904. +
  5905. + spin_lock_irqsave(&priv->lock, flags);
  5906. + if (phydev->link) {
  5907. + /* Now we make sure that we can be in full duplex mode.
  5908. + * If not, we operate in half-duplex mode. */
  5909. + if (phydev->duplex != priv->oldduplex) {
  5910. + new_state = 1;
  5911. + gemac_set_duplex(priv->EMAC_baseaddr, pfe_get_phydev_duplex(phydev));
  5912. + priv->oldduplex = phydev->duplex;
  5913. + }
  5914. +
  5915. + if (phydev->speed != priv->oldspeed) {
  5916. + new_state = 1;
  5917. + gemac_set_speed(priv->EMAC_baseaddr, pfe_get_phydev_speed(phydev));
  5918. + if(priv->einfo->mii_config == PHY_INTERFACE_MODE_RGMII)
  5919. + pfe_set_rgmii_speed(phydev);
  5920. + priv->oldspeed = phydev->speed;
  5921. + }
  5922. +
  5923. + if (!priv->oldlink) {
  5924. + new_state = 1;
  5925. + priv->oldlink = 1;
  5926. + }
  5927. +
  5928. + } else if (priv->oldlink) {
  5929. + new_state = 1;
  5930. + priv->oldlink = 0;
  5931. + priv->oldspeed = 0;
  5932. + priv->oldduplex = -1;
  5933. + }
  5934. +
  5935. + if (new_state && netif_msg_link(priv))
  5936. + phy_print_status(phydev);
  5937. +
  5938. + spin_unlock_irqrestore(&priv->lock, flags);
  5939. +}
  5940. +
  5941. +
  5942. +/** pfe_phy_exit
  5943. + */
  5944. +static void pfe_phy_exit(struct net_device *dev)
  5945. +{
  5946. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5947. +
  5948. + netif_info(priv, drv, dev, "%s\n", __func__);
  5949. +
  5950. + phy_disconnect(priv->phydev);
  5951. + priv->phydev = NULL;
  5952. +}
  5953. +
  5954. +/** pfe_eth_stop
  5955. + */
  5956. +static void pfe_eth_stop( struct net_device *dev , int wake)
  5957. +{
  5958. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  5959. +
  5960. + netif_info(priv, drv, dev, "%s\n", __func__);
  5961. +
  5962. + if (wake)
  5963. + gemac_tx_disable(priv->EMAC_baseaddr);
  5964. + else {
  5965. + gemac_disable(priv->EMAC_baseaddr);
  5966. + gpi_disable(priv->GPI_baseaddr);
  5967. +
  5968. + if (priv->phydev)
  5969. + phy_stop(priv->phydev);
  5970. + }
  5971. +}
  5972. +
  5973. +/** pfe_eth_start
  5974. + */
  5975. +static int pfe_eth_start( struct pfe_eth_priv_s *priv )
  5976. +{
  5977. + netif_info(priv, drv, priv->dev, "%s\n", __func__);
  5978. +
  5979. + if (priv->phydev)
  5980. + phy_start(priv->phydev);
  5981. +
  5982. + gpi_enable(priv->GPI_baseaddr);
  5983. + gemac_enable(priv->EMAC_baseaddr);
  5984. +
  5985. + return 0;
  5986. +}
  5987. +
  5988. +/*Configure on chip serdes through mdio
  5989. + * Is there any better way to do this? */
  5990. +static void ls1012a_configure_serdes(struct net_device *dev)
  5991. +{
  5992. + struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0]; // FIXME This will not work for EMAC2 as SGMII
  5993. + /*int value,sgmii_2500=0; */
  5994. + struct mii_bus *bus = priv->mii_bus;
  5995. +
  5996. + netif_info(priv, drv, dev, "%s\n", __func__);
  5997. + /* PCS configuration done with corresponding GEMAC */
  5998. +
  5999. + pfe_eth_mdio_read(bus, 0, 0);
  6000. + pfe_eth_mdio_read(bus, 0, 1);
  6001. +#if 1
  6002. + /*These settings taken from validtion team */
  6003. + pfe_eth_mdio_write(bus, 0, 0x0, 0x8000);
  6004. + pfe_eth_mdio_write(bus, 0, 0x14, 0xb);
  6005. + pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1);
  6006. + pfe_eth_mdio_write(bus, 0, 0x12, 0x400);
  6007. + pfe_eth_mdio_write(bus, 0, 0x13, 0x0);
  6008. + pfe_eth_mdio_write(bus, 0, 0x0, 0x1140);
  6009. + return;
  6010. +#else
  6011. + /*Reset serdes */
  6012. + pfe_eth_mdio_write(bus, 0, 0x0, 0x8000);
  6013. +
  6014. + /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */
  6015. + value = PHY_SGMII_IF_MODE_SGMII;
  6016. + if (!sgmii_2500)
  6017. + value |= PHY_SGMII_IF_MODE_AN;
  6018. +
  6019. + pfe_eth_mdio_write(bus, 0, 0x14, value);
  6020. +
  6021. + /* Dev ability according to SGMII specification */
  6022. + value = PHY_SGMII_DEV_ABILITY_SGMII;
  6023. + pfe_eth_mdio_write(bus, 0, 0x4, value);
  6024. +
  6025. + //These values taken from validation team
  6026. + pfe_eth_mdio_write(bus, 0, 0x13, 0x0);
  6027. + pfe_eth_mdio_write(bus, 0, 0x12, 0x400);
  6028. +
  6029. + /* Restart AN */
  6030. + value = PHY_SGMII_CR_DEF_VAL;
  6031. + if (!sgmii_2500)
  6032. + value |= PHY_SGMII_CR_RESET_AN;
  6033. + pfe_eth_mdio_write(bus, 0, 0, value);
  6034. +
  6035. +#endif
  6036. +}
  6037. +
  6038. +/** pfe_phy_init
  6039. + *
  6040. + */
  6041. +static int pfe_phy_init(struct net_device *dev)
  6042. +{
  6043. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6044. + struct phy_device *phydev;
  6045. + char phy_id[MII_BUS_ID_SIZE + 3];
  6046. + char bus_id[MII_BUS_ID_SIZE];
  6047. + phy_interface_t interface;
  6048. +
  6049. + priv->oldlink = 0;
  6050. + priv->oldspeed = 0;
  6051. + priv->oldduplex = -1;
  6052. +
  6053. + snprintf(bus_id, MII_BUS_ID_SIZE, "comcerto-%d", 0);
  6054. + snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, priv->einfo->phy_id);
  6055. +
  6056. + netif_info(priv, drv, dev, "%s: %s\n", __func__, phy_id);
  6057. +#if defined(CONFIG_PLATFORM_C2000)
  6058. + interface = pfe_get_interface(dev);
  6059. +#else
  6060. + interface = priv->einfo->mii_config;
  6061. + if(interface == PHY_INTERFACE_MODE_SGMII) {
  6062. + /*Configure SGMII PCS */
  6063. + if(pfe->scfg) {
  6064. + /*Config MDIO from serdes */
  6065. + regmap_write(pfe->scfg, 0x484, 0x00000000);
  6066. + }
  6067. + ls1012a_configure_serdes(dev);
  6068. + }
  6069. +
  6070. + if(pfe->scfg) {
  6071. + /*Config MDIO from PAD */
  6072. + regmap_write(pfe->scfg, 0x484, 0x80000000);
  6073. + }
  6074. +#endif
  6075. +
  6076. +
  6077. + priv->oldlink = 0;
  6078. + priv->oldspeed = 0;
  6079. + priv->oldduplex = -1;
  6080. +
  6081. + printk("%s interface %x \n", __func__, interface);
  6082. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
  6083. + phydev = phy_connect(dev, phy_id, &pfe_eth_adjust_link, interface);
  6084. +#else
  6085. + phydev = phy_connect(dev, phy_id, &pfe_eth_adjust_link, 0, interface);
  6086. +#endif
  6087. +
  6088. + if (IS_ERR(phydev)) {
  6089. + netdev_err(dev, "phy_connect() failed\n");
  6090. + return PTR_ERR(phydev);
  6091. + }
  6092. +
  6093. + priv->phydev = phydev;
  6094. + phydev->irq = PHY_POLL;
  6095. +
  6096. +#if defined(CONFIG_PLATFORM_C2000)
  6097. + /* Pause frame support */
  6098. + phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
  6099. + if (pfe_eth_pause_rx_enabled(priv))
  6100. + phydev->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
  6101. + else
  6102. + phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
  6103. +#else
  6104. + /*TODO Add pause frame support for LS1012A */
  6105. +#endif
  6106. +
  6107. + return 0;
  6108. +}
  6109. +
  6110. +/** pfe_gemac_init
  6111. + */
  6112. +static int pfe_gemac_init(struct pfe_eth_priv_s *priv)
  6113. +{
  6114. + GEMAC_CFG cfg;
  6115. +
  6116. + netif_info(priv, ifup, priv->dev, "%s\n", __func__);
  6117. +
  6118. + /* software config */
  6119. + /* MII interface mode selection */
  6120. + switch (priv->einfo->mii_config) {
  6121. + case CONFIG_COMCERTO_USE_GMII:
  6122. + cfg.mode = GMII;
  6123. + break;
  6124. +
  6125. + case CONFIG_COMCERTO_USE_MII:
  6126. + cfg.mode = MII;
  6127. + break;
  6128. +
  6129. + case CONFIG_COMCERTO_USE_RGMII:
  6130. + cfg.mode = RGMII;
  6131. + break;
  6132. +
  6133. + case CONFIG_COMCERTO_USE_RMII:
  6134. + cfg.mode = RMII;
  6135. + break;
  6136. +
  6137. + case CONFIG_COMCERTO_USE_SGMII:
  6138. + cfg.mode = SGMII;
  6139. + break;
  6140. +
  6141. + default:
  6142. + cfg.mode = RGMII;
  6143. + }
  6144. +
  6145. + /* Speed selection */
  6146. + switch (priv->einfo->gemac_mode & GEMAC_SW_SPEED_1G ) {
  6147. + case GEMAC_SW_SPEED_1G:
  6148. + cfg.speed = SPEED_1000M;
  6149. + break;
  6150. +
  6151. + case GEMAC_SW_SPEED_100M:
  6152. + cfg.speed = SPEED_100M;
  6153. + break;
  6154. +
  6155. + case GEMAC_SW_SPEED_10M:
  6156. + cfg.speed = SPEED_10M;
  6157. + break;
  6158. +
  6159. + default:
  6160. + cfg.speed = SPEED_1000M;
  6161. + }
  6162. +
  6163. + /* Duplex selection */
  6164. + cfg.duplex = ( priv->einfo->gemac_mode & GEMAC_SW_FULL_DUPLEX ) ? DUPLEX_FULL : DUPLEX_HALF;
  6165. +
  6166. + gemac_set_config( priv->EMAC_baseaddr, &cfg);
  6167. + gemac_allow_broadcast( priv->EMAC_baseaddr );
  6168. + gemac_disable_unicast( priv->EMAC_baseaddr );
  6169. + gemac_disable_multicast( priv->EMAC_baseaddr );
  6170. + gemac_disable_fcs_rx( priv->EMAC_baseaddr );
  6171. + gemac_enable_1536_rx( priv->EMAC_baseaddr );
  6172. + gemac_enable_rx_jmb( priv->EMAC_baseaddr );
  6173. + gemac_enable_stacked_vlan( priv->EMAC_baseaddr );
  6174. + gemac_enable_pause_rx( priv->EMAC_baseaddr );
  6175. + gemac_set_bus_width(priv->EMAC_baseaddr, 64);
  6176. + /*TODO just for testing remove it later */
  6177. + gemac_enable_copy_all(priv->EMAC_baseaddr);
  6178. +
  6179. + /*GEM will perform checksum verifications*/
  6180. + if (priv->dev->features & NETIF_F_RXCSUM)
  6181. + gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
  6182. + else
  6183. + gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
  6184. +
  6185. + return 0;
  6186. +}
  6187. +
  6188. +/** pfe_eth_event_handler
  6189. + */
  6190. +static int pfe_eth_event_handler(void *data, int event, int qno)
  6191. +{
  6192. + struct pfe_eth_priv_s *priv = data;
  6193. +
  6194. + switch (event) {
  6195. + case EVENT_RX_PKT_IND:
  6196. +
  6197. + if (qno == 0) {
  6198. + if (napi_schedule_prep(&priv->high_napi)) {
  6199. + netif_info(priv, intr, priv->dev, "%s: schedule high prio poll\n", __func__);
  6200. +
  6201. +#ifdef PFE_ETH_NAPI_STATS
  6202. + priv->napi_counters[NAPI_SCHED_COUNT]++;
  6203. +#endif
  6204. +
  6205. + __napi_schedule(&priv->high_napi);
  6206. + }
  6207. + }
  6208. + else if (qno == 1) {
  6209. + if (napi_schedule_prep(&priv->low_napi)) {
  6210. + netif_info(priv, intr, priv->dev, "%s: schedule low prio poll\n", __func__);
  6211. +
  6212. +#ifdef PFE_ETH_NAPI_STATS
  6213. + priv->napi_counters[NAPI_SCHED_COUNT]++;
  6214. +#endif
  6215. + __napi_schedule(&priv->low_napi);
  6216. + }
  6217. + }
  6218. + else if (qno == 2) {
  6219. + if (napi_schedule_prep(&priv->lro_napi)) {
  6220. + netif_info(priv, intr, priv->dev, "%s: schedule lro prio poll\n", __func__);
  6221. +
  6222. +#ifdef PFE_ETH_NAPI_STATS
  6223. + priv->napi_counters[NAPI_SCHED_COUNT]++;
  6224. +#endif
  6225. + __napi_schedule(&priv->lro_napi);
  6226. + }
  6227. + }
  6228. +
  6229. + break;
  6230. +
  6231. + case EVENT_TXDONE_IND:
  6232. + case EVENT_HIGH_RX_WM:
  6233. + default:
  6234. + break;
  6235. + }
  6236. +
  6237. + return 0;
  6238. +}
  6239. +
  6240. +/** pfe_eth_open
  6241. + */
  6242. +static int pfe_eth_open(struct net_device *dev)
  6243. +{
  6244. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6245. + struct hif_client_s *client;
  6246. + int rc;
  6247. +
  6248. + netif_info(priv, ifup, dev, "%s\n", __func__);
  6249. +
  6250. + /* Register client driver with HIF */
  6251. + client = &priv->client;
  6252. + memset(client, 0, sizeof(*client));
  6253. + client->id = PFE_CL_GEM0 + priv->id;
  6254. + client->tx_qn = emac_txq_cnt;
  6255. + client->rx_qn = EMAC_RXQ_CNT;
  6256. + client->priv = priv;
  6257. + client->pfe = priv->pfe;
  6258. + client->event_handler = pfe_eth_event_handler;
  6259. +
  6260. + /* FIXME : For now hif lib sets all tx and rx queues to same size */
  6261. + client->tx_qsize = EMAC_TXQ_DEPTH;
  6262. + client->rx_qsize = EMAC_RXQ_DEPTH;
  6263. +
  6264. + if ((rc = hif_lib_client_register(client))) {
  6265. + netdev_err(dev, "%s: hif_lib_client_register(%d) failed\n", __func__, client->id);
  6266. + goto err0;
  6267. + }
  6268. +
  6269. + netif_info(priv, drv, dev, "%s: registered client: %p\n", __func__, client);
  6270. +
  6271. +#if defined(CONFIG_PLATFORM_C2000)
  6272. + /* Enable gemac tx clock */
  6273. + clk_enable(priv->gemtx_clk);
  6274. +#endif
  6275. +
  6276. + pfe_gemac_init(priv);
  6277. +
  6278. + if (!is_valid_ether_addr(dev->dev_addr)) {
  6279. + netdev_err(dev, "%s: invalid MAC address\n", __func__);
  6280. + rc = -EADDRNOTAVAIL;
  6281. + goto err1;
  6282. + }
  6283. +
  6284. + gemac_set_laddrN( priv->EMAC_baseaddr, ( MAC_ADDR *)dev->dev_addr, 1 );
  6285. +
  6286. + napi_enable(&priv->high_napi);
  6287. + napi_enable(&priv->low_napi);
  6288. + napi_enable(&priv->lro_napi);
  6289. +
  6290. + rc = pfe_eth_start(priv);
  6291. +
  6292. + netif_tx_wake_all_queues(dev);
  6293. +
  6294. + //pfe_ctrl_set_eth_state(priv->id, 1, dev->dev_addr);
  6295. +
  6296. + priv->tx_timer.expires = jiffies + ( COMCERTO_TX_RECOVERY_TIMEOUT_MS * HZ )/1000;
  6297. + add_timer(&priv->tx_timer);
  6298. +
  6299. + return rc;
  6300. +
  6301. +err1:
  6302. + hif_lib_client_unregister(&priv->client);
  6303. +#if defined(CONFIG_PLATFORM_C2000)
  6304. + clk_disable(priv->gemtx_clk);
  6305. +#endif
  6306. +
  6307. +err0:
  6308. + return rc;
  6309. +}
  6310. +/*
  6311. + * pfe_eth_shutdown
  6312. + */
  6313. +int pfe_eth_shutdown( struct net_device *dev, int wake)
  6314. +{
  6315. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6316. + int i, qstatus;
  6317. + unsigned long next_poll = jiffies + 1, end = jiffies + (TX_POLL_TIMEOUT_MS * HZ) / 1000;
  6318. + int tx_pkts, prv_tx_pkts;
  6319. +
  6320. + netif_info(priv, ifdown, dev, "%s\n", __func__);
  6321. +
  6322. + del_timer_sync(&priv->tx_timer);
  6323. +
  6324. + for(i = 0; i < emac_txq_cnt; i++)
  6325. + hrtimer_cancel(&priv->fast_tx_timeout[i].timer);
  6326. +
  6327. + netif_tx_stop_all_queues(dev);
  6328. +
  6329. + do {
  6330. + tx_pkts = 0;
  6331. + pfe_eth_flush_tx(priv, 1);
  6332. +
  6333. + for (i = 0; i < emac_txq_cnt; i++)
  6334. + tx_pkts += hif_lib_tx_pending(&priv->client, i);
  6335. +
  6336. + if (tx_pkts) {
  6337. + /*Don't wait forever, break if we cross max timeout */
  6338. + if (time_after(jiffies, end)) {
  6339. + printk(KERN_ERR "(%s)Tx is not complete after %dmsec\n", dev->name, TX_POLL_TIMEOUT_MS);
  6340. + break;
  6341. + }
  6342. +
  6343. + printk("%s : (%s) Waiting for tx packets to free. Pending tx pkts = %d.\n", __func__, dev->name, tx_pkts);
  6344. + if (need_resched())
  6345. + schedule();
  6346. + }
  6347. +
  6348. + } while(tx_pkts);
  6349. +
  6350. + end = jiffies + (TX_POLL_TIMEOUT_MS * HZ) / 1000;
  6351. + /*Disable transmit in PFE before disabling GEMAC */
  6352. + //pfe_ctrl_set_eth_state(priv->id, 0, NULL);
  6353. +
  6354. + prv_tx_pkts = tmu_pkts_processed(priv->id);
  6355. + /*Wait till TMU transmits all pending packets
  6356. + * poll tmu_qstatus and pkts processed by TMU for every 10ms
  6357. + * Consider TMU is busy, If we see TMU qeueu pending or any packets processed by TMU
  6358. + */
  6359. + while(1) {
  6360. +
  6361. + if (time_after(jiffies, next_poll)) {
  6362. +
  6363. + tx_pkts = tmu_pkts_processed(priv->id);
  6364. + qstatus = tmu_qstatus(priv->id) & 0x7ffff;
  6365. +
  6366. + if(!qstatus && (tx_pkts == prv_tx_pkts)) {
  6367. + break;
  6368. + }
  6369. + /*Don't wait forever, break if we cross max timeout(TX_POLL_TIMEOUT_MS) */
  6370. + if (time_after(jiffies, end)) {
  6371. + printk(KERN_ERR "TMU%d is busy after %dmsec\n", priv->id, TX_POLL_TIMEOUT_MS);
  6372. + break;
  6373. + }
  6374. + prv_tx_pkts = tx_pkts;
  6375. + next_poll++;
  6376. + }
  6377. + if (need_resched())
  6378. + schedule();
  6379. +
  6380. +
  6381. + }
  6382. + /* Wait for some more time to complete transmitting packet if any */
  6383. + next_poll = jiffies + 1;
  6384. + while(1) {
  6385. + if (time_after(jiffies, next_poll))
  6386. + break;
  6387. + if (need_resched())
  6388. + schedule();
  6389. + }
  6390. +
  6391. + pfe_eth_stop(dev, wake);
  6392. +
  6393. + napi_disable(&priv->lro_napi);
  6394. + napi_disable(&priv->low_napi);
  6395. + napi_disable(&priv->high_napi);
  6396. +
  6397. +#if defined(CONFIG_PLATFORM_C2000)
  6398. + /* Disable gemac tx clock */
  6399. + clk_disable(priv->gemtx_clk);
  6400. +#endif
  6401. +
  6402. + hif_lib_client_unregister(&priv->client);
  6403. +
  6404. + return 0;
  6405. +}
  6406. +
  6407. +/* pfe_eth_close
  6408. + *
  6409. + */
  6410. +static int pfe_eth_close( struct net_device *dev )
  6411. +{
  6412. + pfe_eth_shutdown(dev, 0);
  6413. +
  6414. + return 0;
  6415. +}
  6416. +
  6417. +/* pfe_eth_suspend
  6418. + *
  6419. + * return value : 1 if netdevice is configured to wakeup system
  6420. + * 0 otherwise
  6421. + */
  6422. +int pfe_eth_suspend(struct net_device *dev)
  6423. +{
  6424. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6425. + int retval = 0;
  6426. +
  6427. + if (priv->wol) {
  6428. + gemac_set_wol(priv->EMAC_baseaddr, priv->wol);
  6429. + retval = 1;
  6430. + }
  6431. + pfe_eth_shutdown(dev, priv->wol);
  6432. +
  6433. + return retval;
  6434. +}
  6435. +
  6436. +/** pfe_eth_resume
  6437. + *
  6438. + */
  6439. +int pfe_eth_resume(struct net_device *dev)
  6440. +{
  6441. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6442. +
  6443. + if (priv->wol)
  6444. + gemac_set_wol(priv->EMAC_baseaddr, 0);
  6445. +
  6446. + return pfe_eth_open(dev);
  6447. +}
  6448. +
  6449. +#if defined(CONFIG_PLATFORM_C2000)
  6450. +/** pfe_eth_set_device_wakeup
  6451. + *
  6452. + * Called when a netdevice changes its wol status.
  6453. + * Scans state of all interfaces and updae PFE device
  6454. + * wakeable state
  6455. + */
  6456. +static void pfe_eth_set_device_wakeup(struct pfe *pfe)
  6457. +{
  6458. + int i;
  6459. + int wake = 0;
  6460. +
  6461. + for(i = 0; i < NUM_GEMAC_SUPPORT; i++)
  6462. + wake |= pfe->eth.eth_priv[i]->wol;
  6463. +
  6464. + device_set_wakeup_enable(pfe->dev, wake);
  6465. + //TODO Find correct IRQ mapping.
  6466. + //TODO interface with PMU
  6467. + //int irq_set_irq_wake(unsigned int irq, unsigned int on)
  6468. +}
  6469. +#endif
  6470. +/** pfe_eth_get_queuenum
  6471. + *
  6472. + */
  6473. +static int pfe_eth_get_queuenum( struct pfe_eth_priv_s *priv, struct sk_buff *skb )
  6474. +{
  6475. + int queuenum = 0;
  6476. + unsigned long flags;
  6477. +
  6478. + /* Get the Fast Path queue number */
  6479. + /* Use conntrack mark (if conntrack exists), then packet mark (if any), then fallback to default */
  6480. +#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK)
  6481. + if (skb->nfct) {
  6482. + enum ip_conntrack_info cinfo;
  6483. + struct nf_conn *ct;
  6484. + ct = nf_ct_get(skb, &cinfo);
  6485. +
  6486. + if (ct) {
  6487. + u_int32_t connmark;
  6488. + connmark = ct->mark;
  6489. +
  6490. + if ((connmark & 0x80000000) && priv->id != 0)
  6491. + connmark >>= 16;
  6492. +
  6493. + queuenum = connmark & EMAC_QUEUENUM_MASK;
  6494. + }
  6495. + }
  6496. + else /* continued after #endif ... */
  6497. +#endif
  6498. + if (skb->mark)
  6499. + queuenum = skb->mark & EMAC_QUEUENUM_MASK;
  6500. + else {
  6501. + spin_lock_irqsave(&priv->lock, flags);
  6502. + queuenum = priv->default_priority & EMAC_QUEUENUM_MASK;
  6503. + spin_unlock_irqrestore(&priv->lock, flags);
  6504. + }
  6505. +
  6506. + return queuenum;
  6507. +}
  6508. +
  6509. +
  6510. +
  6511. +/** pfe_eth_might_stop_tx
  6512. + *
  6513. + */
  6514. +static int pfe_eth_might_stop_tx(struct pfe_eth_priv_s *priv, int queuenum, struct netdev_queue *tx_queue, unsigned int n_desc, unsigned int n_segs)
  6515. +{
  6516. + int tried = 0;
  6517. + ktime_t kt;
  6518. +
  6519. +try_again:
  6520. + if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc)
  6521. + || (hif_lib_tx_avail(&priv->client, queuenum) < n_desc)
  6522. + || (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) {
  6523. +
  6524. + if (!tried) {
  6525. + hif_tx_unlock(&pfe->hif);
  6526. + pfe_eth_flush_txQ(priv, queuenum, 1, n_desc);
  6527. + hif_lib_update_credit(&priv->client, queuenum);
  6528. + tried = 1;
  6529. + hif_tx_lock(&pfe->hif);
  6530. + goto try_again;
  6531. + }
  6532. +#ifdef PFE_ETH_TX_STATS
  6533. + if (__hif_tx_avail(&pfe->hif) < n_desc)
  6534. + priv->stop_queue_hif[queuenum]++;
  6535. + else if (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) {
  6536. + priv->stop_queue_hif_client[queuenum]++;
  6537. + }
  6538. + else if (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs) {
  6539. + priv->stop_queue_credit[queuenum]++;
  6540. + }
  6541. + priv->stop_queue_total[queuenum]++;
  6542. +#endif
  6543. + netif_tx_stop_queue(tx_queue);
  6544. +
  6545. + kt = ktime_set(0, COMCERTO_TX_FAST_RECOVERY_TIMEOUT_MS * NSEC_PER_MSEC);
  6546. + hrtimer_start(&priv->fast_tx_timeout[queuenum].timer, kt, HRTIMER_MODE_REL);
  6547. + return -1;
  6548. + }
  6549. + else {
  6550. + return 0;
  6551. + }
  6552. +}
  6553. +
  6554. +#define SA_MAX_OP 2
  6555. +/** pfe_hif_send_packet
  6556. + *
  6557. + * At this level if TX fails we drop the packet
  6558. + */
  6559. +static void pfe_hif_send_packet( struct sk_buff *skb, struct pfe_eth_priv_s *priv, int queuenum)
  6560. +{
  6561. + struct skb_shared_info *sh = skb_shinfo(skb);
  6562. + unsigned int nr_frags;
  6563. + u32 ctrl = 0;
  6564. +
  6565. + netif_info(priv, tx_queued, priv->dev, "%s\n", __func__);
  6566. +
  6567. + if (skb_is_gso(skb)) {
  6568. + priv->stats.tx_dropped++;
  6569. + return;
  6570. + }
  6571. +
  6572. + if (skb->ip_summed == CHECKSUM_PARTIAL) {
  6573. + if (skb->len > 1522) {
  6574. + skb->ip_summed = 0;
  6575. + ctrl = 0;
  6576. +
  6577. + if (pfe_compute_csum(skb)){
  6578. + kfree_skb(skb);
  6579. + return;
  6580. + }
  6581. + }
  6582. + else
  6583. + ctrl = HIF_CTRL_TX_CHECKSUM;
  6584. + }
  6585. +
  6586. + nr_frags = sh->nr_frags;
  6587. +
  6588. + if (nr_frags) {
  6589. + skb_frag_t *f;
  6590. + int i;
  6591. +
  6592. + __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data, skb_headlen(skb), ctrl, HIF_FIRST_BUFFER, skb);
  6593. +
  6594. + for (i = 0; i < nr_frags - 1; i++) {
  6595. + f = &sh->frags[i];
  6596. + __hif_lib_xmit_pkt(&priv->client, queuenum, skb_frag_address(f), skb_frag_size(f), 0x0, 0x0, skb);
  6597. + }
  6598. +
  6599. + f = &sh->frags[i];
  6600. +
  6601. + __hif_lib_xmit_pkt(&priv->client, queuenum, skb_frag_address(f), skb_frag_size(f), 0x0, HIF_LAST_BUFFER|HIF_DATA_VALID, skb);
  6602. +
  6603. + netif_info(priv, tx_queued, priv->dev, "%s: pkt sent successfully skb:%p nr_frags:%d len:%d\n", __func__, skb, nr_frags, skb->len);
  6604. + }
  6605. + else {
  6606. + __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data, skb->len, ctrl, HIF_FIRST_BUFFER | HIF_LAST_BUFFER | HIF_DATA_VALID, skb);
  6607. + netif_info(priv, tx_queued, priv->dev, "%s: pkt sent successfully skb:%p len:%d\n", __func__, skb, skb->len);
  6608. + }
  6609. + hif_tx_dma_start();
  6610. + priv->stats.tx_packets++;
  6611. + priv->stats.tx_bytes += skb->len;
  6612. + hif_lib_tx_credit_use(pfe, priv->id, queuenum, 1);
  6613. +}
  6614. +
  6615. +/** pfe_eth_flush_txQ
  6616. + */
  6617. +static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int txQ_num, int from_tx, int n_desc)
  6618. +{
  6619. + struct sk_buff *skb;
  6620. + struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->dev, txQ_num);
  6621. + int count = max(TX_FREE_MAX_COUNT, n_desc);
  6622. + unsigned int flags;
  6623. +
  6624. + netif_info(priv, tx_done, priv->dev, "%s\n", __func__);
  6625. +
  6626. + if (!from_tx)
  6627. + __netif_tx_lock_bh(tx_queue);
  6628. +
  6629. + /* Clean HIF and client queue */
  6630. + while (count && (skb = hif_lib_tx_get_next_complete(&priv->client, txQ_num, &flags, count))) {
  6631. +
  6632. + /* FIXME : Invalid data can be skipped in hif_lib itself */
  6633. + if (flags & HIF_DATA_VALID) {
  6634. + dev_kfree_skb_any(skb);
  6635. +
  6636. + }
  6637. + // When called from the timer, flush all descriptors
  6638. + if (from_tx)
  6639. + count--;
  6640. + }
  6641. +
  6642. + if (!from_tx)
  6643. + __netif_tx_unlock_bh(tx_queue);
  6644. +}
  6645. +
  6646. +/** pfe_eth_flush_tx
  6647. + */
  6648. +static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv, int force)
  6649. +{
  6650. + int ii;
  6651. +
  6652. + netif_info(priv, tx_done, priv->dev, "%s\n", __func__);
  6653. +
  6654. + for (ii = 0; ii < emac_txq_cnt; ii++) {
  6655. + if (force || (time_after(jiffies, priv->client.tx_q[ii].jiffies_last_packet + (COMCERTO_TX_RECOVERY_TIMEOUT_MS * HZ)/1000))) {
  6656. + pfe_eth_flush_txQ(priv, ii, 0, 0); //We will release everything we can based on from_tx param, so the count param can be set to any value
  6657. + hif_lib_update_credit(&priv->client, ii);
  6658. + }
  6659. + }
  6660. +}
  6661. +
  6662. +void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int *n_segs)
  6663. +{
  6664. + struct skb_shared_info *sh = skb_shinfo(skb);
  6665. +
  6666. + // Scattered data
  6667. + if (sh->nr_frags) {
  6668. + *n_desc = sh->nr_frags + 1;
  6669. + *n_segs = 1;
  6670. + }
  6671. + // Regular case
  6672. + else {
  6673. + *n_desc = 1;
  6674. + *n_segs = 1;
  6675. + }
  6676. + return;
  6677. +}
  6678. +
  6679. +/** pfe_eth_send_packet
  6680. + */
  6681. +static int pfe_eth_send_packet(struct sk_buff *skb, struct net_device *dev)
  6682. +{
  6683. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6684. + int txQ_num = skb_get_queue_mapping(skb);
  6685. + int n_desc, n_segs, count;
  6686. + struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->dev, txQ_num);
  6687. +
  6688. + netif_info(priv, tx_queued, dev, "%s\n", __func__);
  6689. +
  6690. + if ((!skb_is_gso(skb)) && (skb_headroom(skb) < (PFE_PKT_HEADER_SZ + sizeof(unsigned long)))) {
  6691. +
  6692. + netif_warn(priv, tx_err, priv->dev, "%s: copying skb\n", __func__);
  6693. +
  6694. + if (pskb_expand_head(skb, (PFE_PKT_HEADER_SZ + sizeof(unsigned long)), 0, GFP_ATOMIC)) {
  6695. + /* No need to re-transmit, no way to recover*/
  6696. + kfree_skb(skb);
  6697. + priv->stats.tx_dropped++;
  6698. + return NETDEV_TX_OK;
  6699. + }
  6700. + }
  6701. +
  6702. + pfe_tx_get_req_desc(skb, &n_desc, &n_segs);
  6703. +
  6704. + hif_tx_lock(&pfe->hif);
  6705. + if(unlikely(pfe_eth_might_stop_tx(priv, txQ_num, tx_queue, n_desc, n_segs))) {
  6706. +#ifdef PFE_ETH_TX_STATS
  6707. + if(priv->was_stopped[txQ_num]) {
  6708. + priv->clean_fail[txQ_num]++;
  6709. + priv->was_stopped[txQ_num] = 0;
  6710. + }
  6711. +#endif
  6712. + hif_tx_unlock(&pfe->hif);
  6713. + return NETDEV_TX_BUSY;
  6714. + }
  6715. +
  6716. + pfe_hif_send_packet(skb, priv, txQ_num);
  6717. +
  6718. + hif_tx_unlock(&pfe->hif);
  6719. +
  6720. + dev->trans_start = jiffies;
  6721. +
  6722. + // Recycle buffers if a socket's send buffer becomes half full or if the HIF client queue starts filling up
  6723. + if (((count = (hif_lib_tx_pending(&priv->client, txQ_num) - HIF_CL_TX_FLUSH_MARK)) > 0)
  6724. + || (skb->sk && ((sk_wmem_alloc_get(skb->sk) << 1) > skb->sk->sk_sndbuf)))
  6725. + pfe_eth_flush_txQ(priv, txQ_num, 1, count);
  6726. +
  6727. +#ifdef PFE_ETH_TX_STATS
  6728. + priv->was_stopped[txQ_num] = 0;
  6729. +#endif
  6730. +
  6731. + return NETDEV_TX_OK;
  6732. +}
  6733. +
  6734. +/** pfe_eth_select_queue
  6735. + *
  6736. + */
  6737. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
  6738. +static u16 pfe_eth_select_queue( struct net_device *dev, struct sk_buff *skb,
  6739. + void *accel_priv, select_queue_fallback_t fallback)
  6740. +#else
  6741. +static u16 pfe_eth_select_queue( struct net_device *dev, struct sk_buff *skb )
  6742. +#endif
  6743. +{
  6744. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6745. +
  6746. + return pfe_eth_get_queuenum(priv, skb);
  6747. +}
  6748. +
  6749. +
  6750. +/** pfe_eth_get_stats
  6751. + */
  6752. +static struct net_device_stats *pfe_eth_get_stats(struct net_device *dev)
  6753. +{
  6754. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6755. +
  6756. + netif_info(priv, drv, dev, "%s\n", __func__);
  6757. +
  6758. + return &priv->stats;
  6759. +}
  6760. +
  6761. +
  6762. +/** pfe_eth_change_mtu
  6763. + */
  6764. +static int pfe_eth_change_mtu(struct net_device *dev, int new_mtu)
  6765. +{
  6766. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6767. + int oldsize = dev->mtu ;
  6768. + int frame_size = new_mtu + ETH_HLEN +4;
  6769. +
  6770. + netif_info(priv, drv, dev, "%s\n", __func__);
  6771. +
  6772. + if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
  6773. + netif_err(priv, drv, dev, "Invalid MTU setting\n");
  6774. + return -EINVAL;
  6775. + }
  6776. +
  6777. + if ((new_mtu > 1500) && (dev->features & NETIF_F_TSO))
  6778. + {
  6779. + priv->usr_features = dev->features;
  6780. + if (dev->features & NETIF_F_TSO)
  6781. + {
  6782. + netdev_err(dev, "MTU cannot be set to more than 1500 while TSO is enabled. disabling TSO.\n");
  6783. + dev->features &= ~(NETIF_F_TSO);
  6784. + }
  6785. + }
  6786. + else if ((dev->mtu > 1500) && (new_mtu <= 1500))
  6787. + {
  6788. + if (priv->usr_features & NETIF_F_TSO)
  6789. + {
  6790. + priv->usr_features &= ~(NETIF_F_TSO);
  6791. + dev->features |= NETIF_F_TSO;
  6792. + netdev_err(dev, "MTU is <= 1500, Enabling TSO feature.\n");
  6793. + }
  6794. + }
  6795. +
  6796. + /* Only stop and start the controller if it isn't already
  6797. + * stopped, and we changed something */
  6798. + if ((oldsize != new_mtu) && (dev->flags & IFF_UP)){
  6799. + netdev_err(dev, "Can not change MTU - fast_path must be disabled and ifconfig down must be issued first\n");
  6800. +
  6801. + return -EINVAL;
  6802. + }
  6803. +
  6804. + dev->mtu = new_mtu;
  6805. +
  6806. + return 0;
  6807. +}
  6808. +
  6809. +/** pfe_eth_set_mac_address
  6810. + */
  6811. +static int pfe_eth_set_mac_address(struct net_device *dev, void *addr)
  6812. +{
  6813. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6814. + struct sockaddr *sa = addr;
  6815. +
  6816. + netif_info(priv, drv, dev, "%s\n", __func__);
  6817. +
  6818. + if (!is_valid_ether_addr(sa->sa_data))
  6819. + return -EADDRNOTAVAIL;
  6820. +
  6821. + memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
  6822. +
  6823. + gemac_set_laddrN(priv->EMAC_baseaddr, (MAC_ADDR *)dev->dev_addr, 1);
  6824. +
  6825. + return 0;
  6826. +
  6827. +}
  6828. +
  6829. +/** pfe_eth_enet_addr_byte_mac
  6830. + */
  6831. +int pfe_eth_enet_addr_byte_mac(u8 * enet_byte_addr, MAC_ADDR *enet_addr)
  6832. +{
  6833. + if ((enet_byte_addr == NULL) || (enet_addr == NULL))
  6834. + {
  6835. + return -1;
  6836. + }
  6837. + else
  6838. + {
  6839. + enet_addr->bottom = enet_byte_addr[0] |
  6840. + (enet_byte_addr[1] << 8) |
  6841. + (enet_byte_addr[2] << 16) |
  6842. + (enet_byte_addr[3] << 24);
  6843. + enet_addr->top = enet_byte_addr[4] |
  6844. + (enet_byte_addr[5] << 8);
  6845. + return 0;
  6846. + }
  6847. +}
  6848. +
  6849. +
  6850. +
  6851. +/** pfe_eth_set_multi
  6852. + */
  6853. +static void pfe_eth_set_multi(struct net_device *dev)
  6854. +{
  6855. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6856. + MAC_ADDR hash_addr; /* hash register structure */
  6857. + MAC_ADDR spec_addr; /* specific mac address register structure */
  6858. + int result; /* index into hash register to set.. */
  6859. + int uc_count = 0;
  6860. + struct netdev_hw_addr *ha;
  6861. +
  6862. + if (dev->flags & IFF_PROMISC) {
  6863. + netif_info(priv, drv, dev, "entering promiscuous mode\n");
  6864. +
  6865. + priv->promisc = 1;
  6866. + gemac_enable_copy_all(priv->EMAC_baseaddr);
  6867. + } else {
  6868. + priv->promisc = 0;
  6869. + gemac_disable_copy_all(priv->EMAC_baseaddr);
  6870. + }
  6871. +
  6872. + /* Enable broadcast frame reception if required. */
  6873. + if (dev->flags & IFF_BROADCAST) {
  6874. + gemac_allow_broadcast(priv->EMAC_baseaddr);
  6875. + } else {
  6876. + netif_info(priv, drv, dev, "disabling broadcast frame reception\n");
  6877. +
  6878. + gemac_no_broadcast(priv->EMAC_baseaddr);
  6879. + }
  6880. +
  6881. + if (dev->flags & IFF_ALLMULTI) {
  6882. + /* Set the hash to rx all multicast frames */
  6883. + hash_addr.bottom = 0xFFFFFFFF;
  6884. + hash_addr.top = 0xFFFFFFFF;
  6885. + gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
  6886. + gemac_enable_multicast(priv->EMAC_baseaddr);
  6887. + netdev_for_each_uc_addr(ha, dev) {
  6888. + if(uc_count >= MAX_UC_SPEC_ADDR_REG) break;
  6889. + pfe_eth_enet_addr_byte_mac(ha->addr, &spec_addr);
  6890. + gemac_set_laddrN(priv->EMAC_baseaddr, &spec_addr, uc_count + 2);
  6891. + uc_count++;
  6892. + }
  6893. + } else if ((netdev_mc_count(dev) > 0) || (netdev_uc_count(dev))) {
  6894. + u8 *addr;
  6895. +
  6896. + hash_addr.bottom = 0;
  6897. + hash_addr.top = 0;
  6898. +
  6899. + netdev_for_each_mc_addr(ha, dev) {
  6900. + addr = ha->addr;
  6901. +
  6902. + netif_info(priv, drv, dev, "adding multicast address %X:%X:%X:%X:%X:%X to gem filter\n",
  6903. + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
  6904. +
  6905. + result = pfe_eth_get_hash(addr);
  6906. +
  6907. + if (result >= EMAC_HASH_REG_BITS) {
  6908. + break;
  6909. + } else {
  6910. + if (result < 32) {
  6911. + hash_addr.bottom |= (1 << result);
  6912. + } else {
  6913. + hash_addr.top |= (1 << (result - 32));
  6914. + }
  6915. + }
  6916. +
  6917. + }
  6918. +
  6919. + uc_count = -1;
  6920. + netdev_for_each_uc_addr(ha, dev) {
  6921. + addr = ha->addr;
  6922. +
  6923. + if(++uc_count < MAX_UC_SPEC_ADDR_REG)
  6924. + {
  6925. + netdev_info(dev, "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem filter\n",
  6926. + addr[0], addr[1], addr[2],
  6927. + addr[3], addr[4], addr[5]);
  6928. +
  6929. + pfe_eth_enet_addr_byte_mac(addr, &spec_addr);
  6930. + gemac_set_laddrN(priv->EMAC_baseaddr, &spec_addr, uc_count + 2);
  6931. + }
  6932. + else
  6933. + {
  6934. + netif_info(priv, drv, dev, "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem hash\n",
  6935. + addr[0], addr[1], addr[2],
  6936. + addr[3], addr[4], addr[5]);
  6937. +
  6938. + result = pfe_eth_get_hash(addr);
  6939. + if (result >= EMAC_HASH_REG_BITS) {
  6940. + break;
  6941. + } else {
  6942. + if (result < 32)
  6943. + hash_addr.bottom |= (1 << result);
  6944. + else
  6945. + hash_addr.top |= (1 << (result - 32));
  6946. + }
  6947. +
  6948. +
  6949. + }
  6950. + }
  6951. +
  6952. + gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
  6953. + if(netdev_mc_count(dev))
  6954. + gemac_enable_multicast(priv->EMAC_baseaddr);
  6955. + else
  6956. + gemac_disable_multicast(priv->EMAC_baseaddr);
  6957. + }
  6958. +
  6959. + if(netdev_uc_count(dev) >= MAX_UC_SPEC_ADDR_REG)
  6960. + gemac_enable_unicast(priv->EMAC_baseaddr);
  6961. + else
  6962. + {
  6963. + /* Check if there are any specific address HW registers that need
  6964. + * to be flushed
  6965. + * */
  6966. + for(uc_count = netdev_uc_count(dev); uc_count < MAX_UC_SPEC_ADDR_REG; uc_count++)
  6967. + gemac_clear_laddrN(priv->EMAC_baseaddr, uc_count + 2);
  6968. +
  6969. + gemac_disable_unicast(priv->EMAC_baseaddr);
  6970. + }
  6971. +
  6972. + if (dev->flags & IFF_LOOPBACK) {
  6973. + gemac_set_loop(priv->EMAC_baseaddr, LB_LOCAL);
  6974. + }
  6975. +
  6976. + return;
  6977. +}
  6978. +
  6979. +/** pfe_eth_set_features
  6980. + */
  6981. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
  6982. +static int pfe_eth_set_features(struct net_device *dev, netdev_features_t features)
  6983. +#else
  6984. +static int pfe_eth_set_features(struct net_device *dev, u32 features)
  6985. +#endif
  6986. +{
  6987. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  6988. + int rc = 0;
  6989. +
  6990. + if (features & NETIF_F_RXCSUM)
  6991. + gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
  6992. + else
  6993. + gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
  6994. + return rc;
  6995. +}
  6996. +
  6997. +/** pfe_eth_fix_features
  6998. + */
  6999. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
  7000. +static netdev_features_t pfe_eth_fix_features(struct net_device *dev, netdev_features_t features)
  7001. +#else
  7002. +static unsigned int pfe_eth_fix_features(struct net_device *dev,u32 features)
  7003. +#endif
  7004. +{
  7005. + struct pfe_eth_priv_s *priv = netdev_priv(dev);
  7006. +
  7007. + if (dev->mtu > 1500)
  7008. + {
  7009. + if (features & (NETIF_F_TSO))
  7010. + {
  7011. + priv->usr_features |= NETIF_F_TSO;
  7012. + features &= ~(NETIF_F_TSO);
  7013. + netdev_err(dev, "TSO cannot be enabled when the MTU is larger than 1500. Please set the MTU to 1500 or lower first.\n");
  7014. + }
  7015. + }
  7016. +
  7017. + return features;
  7018. +}
  7019. +
  7020. +/** pfe_eth_tx_timeout
  7021. + */
  7022. +void pfe_eth_tx_timeout(unsigned long data )
  7023. +{
  7024. + struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)data;
  7025. +
  7026. + netif_info(priv, timer, priv->dev, "%s\n", __func__);
  7027. +
  7028. + pfe_eth_flush_tx(priv, 0);
  7029. +
  7030. + priv->tx_timer.expires = jiffies + ( COMCERTO_TX_RECOVERY_TIMEOUT_MS * HZ )/1000;
  7031. + add_timer(&priv->tx_timer);
  7032. +}
  7033. +
  7034. +/** pfe_eth_fast_tx_timeout
  7035. + */
  7036. +static enum hrtimer_restart pfe_eth_fast_tx_timeout(struct hrtimer *timer)
  7037. +{
  7038. + struct pfe_eth_fast_timer *fast_tx_timeout = container_of(timer, struct pfe_eth_fast_timer, timer);
  7039. + struct pfe_eth_priv_s *priv = container_of(fast_tx_timeout->base, struct pfe_eth_priv_s, fast_tx_timeout);
  7040. + struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->dev, fast_tx_timeout->queuenum);
  7041. +
  7042. + if(netif_tx_queue_stopped(tx_queue)) {
  7043. +#ifdef PFE_ETH_TX_STATS
  7044. + priv->was_stopped[fast_tx_timeout->queuenum] = 1;
  7045. +#endif
  7046. + netif_tx_wake_queue(tx_queue);
  7047. + }
  7048. +
  7049. + return HRTIMER_NORESTART;
  7050. +}
  7051. +
  7052. +/** pfe_eth_fast_tx_timeout_init
  7053. + */
  7054. +static void pfe_eth_fast_tx_timeout_init(struct pfe_eth_priv_s *priv)
  7055. +{
  7056. + int i;
  7057. + for (i = 0; i < emac_txq_cnt; i++) {
  7058. + priv->fast_tx_timeout[i].queuenum = i;
  7059. + hrtimer_init(&priv->fast_tx_timeout[i].timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  7060. + priv->fast_tx_timeout[i].timer.function = pfe_eth_fast_tx_timeout;
  7061. + priv->fast_tx_timeout[i].base = priv->fast_tx_timeout;
  7062. + }
  7063. +}
  7064. +
  7065. +static struct sk_buff *pfe_eth_rx_skb(struct net_device *dev, struct pfe_eth_priv_s *priv, unsigned int qno)
  7066. +{
  7067. + void *buf_addr;
  7068. + unsigned int rx_ctrl;
  7069. + unsigned int desc_ctrl = 0;
  7070. + struct hif_ipsec_hdr *ipsec_hdr = NULL;
  7071. + struct sk_buff *skb;
  7072. + struct sk_buff *skb_frag, *skb_frag_last = NULL;
  7073. + int length = 0, offset;
  7074. +
  7075. + skb = priv->skb_inflight[qno];
  7076. +
  7077. + if (skb && (skb_frag_last = skb_shinfo(skb)->frag_list)) {
  7078. + while (skb_frag_last->next)
  7079. + skb_frag_last = skb_frag_last->next;
  7080. + }
  7081. +
  7082. + while (!(desc_ctrl & CL_DESC_LAST)) {
  7083. +
  7084. + buf_addr = hif_lib_receive_pkt(&priv->client, qno, &length, &offset, &rx_ctrl, &desc_ctrl, (void **)&ipsec_hdr);
  7085. + if (!buf_addr)
  7086. + goto incomplete;
  7087. +
  7088. +#ifdef PFE_ETH_NAPI_STATS
  7089. + priv->napi_counters[NAPI_DESC_COUNT]++;
  7090. +#endif
  7091. +
  7092. + /* First frag */
  7093. + if (desc_ctrl & CL_DESC_FIRST) {
  7094. +#if defined(CONFIG_PLATFORM_EMULATION) || defined(CONFIG_PLATFORM_PCI)
  7095. + skb = dev_alloc_skb(PFE_BUF_SIZE);
  7096. + if (unlikely(!skb)) {
  7097. + goto pkt_drop;
  7098. + }
  7099. +
  7100. + skb_copy_to_linear_data(skb, buf_addr, length + offset);
  7101. + kfree(buf_addr);
  7102. +#else
  7103. +#if defined(CONFIG_COMCERTO_ZONE_DMA_NCNB)
  7104. + skb = alloc_skb(length + offset + 32, GFP_ATOMIC);
  7105. +#else
  7106. + skb = alloc_skb_header(PFE_BUF_SIZE, buf_addr, GFP_ATOMIC);
  7107. +#endif
  7108. + if (unlikely(!skb)) {
  7109. + goto pkt_drop;
  7110. + }
  7111. +#endif
  7112. + skb_reserve(skb, offset);
  7113. +#if defined(CONFIG_COMCERTO_ZONE_DMA_NCNB)
  7114. + __memcpy(skb->data, buf_addr + offset, length);
  7115. + if (ipsec_hdr) {
  7116. + sah_local = *(unsigned int *)&ipsec_hdr->sa_handle[0];
  7117. + }
  7118. + kfree(buf_addr);
  7119. +#endif
  7120. + skb_put(skb, length);
  7121. + skb->dev = dev;
  7122. +
  7123. + if ((dev->features & NETIF_F_RXCSUM) && (rx_ctrl & HIF_CTRL_RX_CHECKSUMMED))
  7124. + skb->ip_summed = CHECKSUM_UNNECESSARY;
  7125. + else
  7126. + skb_checksum_none_assert(skb);
  7127. +
  7128. + } else {
  7129. +
  7130. + /* Next frags */
  7131. + if (unlikely(!skb)) {
  7132. + printk(KERN_ERR "%s: NULL skb_inflight\n", __func__);
  7133. + goto pkt_drop;
  7134. + }
  7135. +
  7136. +#if defined(CONFIG_COMCERTO_ZONE_DMA_NCNB)
  7137. + skb_frag = alloc_skb(length + offset + 32, GFP_ATOMIC);
  7138. +#else
  7139. + skb_frag = alloc_skb_header(PFE_BUF_SIZE, buf_addr, GFP_ATOMIC);
  7140. +#endif
  7141. + if (unlikely(!skb_frag)) {
  7142. + kfree(buf_addr);
  7143. + goto pkt_drop;
  7144. + }
  7145. +
  7146. + skb_reserve(skb_frag, offset);
  7147. +#if defined(CONFIG_COMCERTO_ZONE_DMA_NCNB)
  7148. + __memcpy(skb_frag->data, buf_addr + offset, length);
  7149. + kfree(buf_addr);
  7150. +#endif
  7151. + skb_put(skb_frag, length);
  7152. +
  7153. + skb_frag->dev = dev;
  7154. +
  7155. + if (skb_shinfo(skb)->frag_list)
  7156. + skb_frag_last->next = skb_frag;
  7157. + else
  7158. + skb_shinfo(skb)->frag_list = skb_frag;
  7159. +
  7160. + skb->truesize += skb_frag->truesize;
  7161. + skb->data_len += length;
  7162. + skb->len += length;
  7163. + skb_frag_last = skb_frag;
  7164. + }
  7165. + }
  7166. +
  7167. + priv->skb_inflight[qno] = NULL;
  7168. + return skb;
  7169. +
  7170. +incomplete:
  7171. + priv->skb_inflight[qno] = skb;
  7172. + return NULL;
  7173. +
  7174. +pkt_drop:
  7175. + priv->skb_inflight[qno] = NULL;
  7176. +
  7177. + if (skb) {
  7178. + kfree_skb(skb);
  7179. + } else {
  7180. + kfree(buf_addr);
  7181. + }
  7182. +
  7183. + priv->stats.rx_errors++;
  7184. +
  7185. + return NULL;
  7186. +}
  7187. +
  7188. +
  7189. +/** pfe_eth_poll
  7190. + */
  7191. +static int pfe_eth_poll(struct pfe_eth_priv_s *priv, struct napi_struct *napi, unsigned int qno, int budget)
  7192. +{
  7193. + struct net_device *dev = priv->dev;
  7194. + struct sk_buff *skb;
  7195. + int work_done = 0;
  7196. + unsigned int len;
  7197. +
  7198. + netif_info(priv, intr, priv->dev, "%s\n", __func__);
  7199. +
  7200. +#ifdef PFE_ETH_NAPI_STATS
  7201. + priv->napi_counters[NAPI_POLL_COUNT]++;
  7202. +#endif
  7203. +
  7204. + do {
  7205. + skb = pfe_eth_rx_skb(dev, priv, qno);
  7206. +
  7207. + if (!skb)
  7208. + break;
  7209. +
  7210. + len = skb->len;
  7211. +
  7212. + /* Packet will be processed */
  7213. + skb->protocol = eth_type_trans(skb, dev);
  7214. +
  7215. + netif_receive_skb(skb);
  7216. +
  7217. + priv->stats.rx_packets++;
  7218. + priv->stats.rx_bytes += len;
  7219. +
  7220. + dev->last_rx = jiffies;
  7221. +
  7222. + work_done++;
  7223. +
  7224. +#ifdef PFE_ETH_NAPI_STATS
  7225. + priv->napi_counters[NAPI_PACKET_COUNT]++;
  7226. +#endif
  7227. +
  7228. + } while (work_done < budget);
  7229. +
  7230. + /* If no Rx receive nor cleanup work was done, exit polling mode.
  7231. + * No more netif_running(dev) check is required here , as this is checked in
  7232. + * net/core/dev.c ( 2.6.33.5 kernel specific).
  7233. + */
  7234. + if (work_done < budget) {
  7235. + napi_complete(napi);
  7236. +
  7237. + hif_lib_event_handler_start(&priv->client, EVENT_RX_PKT_IND, qno);
  7238. + }
  7239. +#ifdef PFE_ETH_NAPI_STATS
  7240. + else
  7241. + priv->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
  7242. +#endif
  7243. +
  7244. + return work_done;
  7245. +}
  7246. +
  7247. +/** pfe_eth_lro_poll
  7248. + */
  7249. +static int pfe_eth_lro_poll(struct napi_struct *napi, int budget)
  7250. +{
  7251. + struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, lro_napi);
  7252. +
  7253. + netif_info(priv, intr, priv->dev, "%s\n", __func__);
  7254. +
  7255. + return pfe_eth_poll(priv, napi, 2, budget);
  7256. +}
  7257. +
  7258. +
  7259. +/** pfe_eth_low_poll
  7260. + */
  7261. +static int pfe_eth_low_poll(struct napi_struct *napi, int budget)
  7262. +{
  7263. + struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, low_napi);
  7264. +
  7265. + netif_info(priv, intr, priv->dev, "%s\n", __func__);
  7266. +
  7267. + return pfe_eth_poll(priv, napi, 1, budget);
  7268. +}
  7269. +
  7270. +/** pfe_eth_high_poll
  7271. + */
  7272. +static int pfe_eth_high_poll(struct napi_struct *napi, int budget )
  7273. +{
  7274. + struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, high_napi);
  7275. +
  7276. + netif_info(priv, intr, priv->dev, "%s\n", __func__);
  7277. +
  7278. + return pfe_eth_poll(priv, napi, 0, budget);
  7279. +}
  7280. +
  7281. +static const struct net_device_ops pfe_netdev_ops = {
  7282. + .ndo_open = pfe_eth_open,
  7283. + .ndo_stop = pfe_eth_close,
  7284. + .ndo_start_xmit = pfe_eth_send_packet,
  7285. + .ndo_select_queue = pfe_eth_select_queue,
  7286. + .ndo_get_stats = pfe_eth_get_stats,
  7287. + .ndo_change_mtu = pfe_eth_change_mtu,
  7288. + .ndo_set_mac_address = pfe_eth_set_mac_address,
  7289. + .ndo_set_rx_mode = pfe_eth_set_multi,
  7290. + .ndo_set_features = pfe_eth_set_features,
  7291. + .ndo_fix_features = pfe_eth_fix_features,
  7292. + .ndo_validate_addr = eth_validate_addr,
  7293. +};
  7294. +
  7295. +
  7296. +/** pfe_eth_init_one
  7297. + */
  7298. +
  7299. +static int pfe_eth_init_one( struct pfe *pfe, int id )
  7300. +{
  7301. + struct net_device *dev = NULL;
  7302. + struct pfe_eth_priv_s *priv = NULL;
  7303. + struct comcerto_eth_platform_data *einfo;
  7304. + struct comcerto_mdio_platform_data *minfo;
  7305. + struct comcerto_pfe_platform_data *pfe_info;
  7306. + int err;
  7307. +
  7308. + /* Extract pltform data */
  7309. +#if defined(CONFIG_PLATFORM_EMULATION) || defined(CONFIG_PLATFORM_PCI)
  7310. + pfe_info = (struct comcerto_pfe_platform_data *) &comcerto_pfe_pdata;
  7311. +#else
  7312. + pfe_info = (struct comcerto_pfe_platform_data *) pfe->dev->platform_data;
  7313. +#endif
  7314. + if (!pfe_info) {
  7315. + printk(KERN_ERR "%s: pfe missing additional platform data\n", __func__);
  7316. + err = -ENODEV;
  7317. + goto err0;
  7318. + }
  7319. +
  7320. + einfo = (struct comcerto_eth_platform_data *) pfe_info->comcerto_eth_pdata;
  7321. +
  7322. + /* einfo never be NULL, but no harm in having this check */
  7323. + if (!einfo) {
  7324. + printk(KERN_ERR "%s: pfe missing additional gemacs platform data\n", __func__);
  7325. + err = -ENODEV;
  7326. + goto err0;
  7327. + }
  7328. +
  7329. + minfo = (struct comcerto_mdio_platform_data *) pfe_info->comcerto_mdio_pdata;
  7330. +
  7331. + /* einfo never be NULL, but no harm in having this check */
  7332. + if (!minfo) {
  7333. + printk(KERN_ERR "%s: pfe missing additional mdios platform data\n", __func__);
  7334. + err = -ENODEV;
  7335. + goto err0;
  7336. + }
  7337. +
  7338. + /*
  7339. + * FIXME: Need to check some flag in "einfo" to know whether
  7340. + * GEMAC is enabled Or not.
  7341. + */
  7342. +
  7343. + /* Create an ethernet device instance */
  7344. + dev = alloc_etherdev_mq(sizeof (*priv), emac_txq_cnt);
  7345. +
  7346. + if (!dev) {
  7347. + printk(KERN_ERR "%s: gemac %d device allocation failed\n", __func__, einfo[id].gem_id);
  7348. + err = -ENOMEM;
  7349. + goto err0;
  7350. + }
  7351. +
  7352. + priv = netdev_priv(dev);
  7353. + priv->dev = dev;
  7354. + priv->id = einfo[id].gem_id;
  7355. + priv->pfe = pfe;
  7356. +
  7357. +#if defined(CONFIG_PLATFORM_C2000)
  7358. + /* get gemac tx clock */
  7359. + priv->gemtx_clk = clk_get(NULL, "gemtx");
  7360. +
  7361. + if (IS_ERR(priv->gemtx_clk)) {
  7362. + printk(KERN_ERR "%s: Unable to get the clock for gemac %d\n", __func__, priv->id);
  7363. + err = -ENODEV;
  7364. + goto err1;
  7365. + }
  7366. +#endif
  7367. +
  7368. + pfe->eth.eth_priv[id] = priv;
  7369. +
  7370. + /* Set the info in the priv to the current info */
  7371. + priv->einfo = &einfo[id];
  7372. + priv->EMAC_baseaddr = cbus_emac_base[id];
  7373. + priv->PHY_baseaddr = cbus_emac_base[0];
  7374. + priv->mdio_muxval = einfo[id].mdio_muxval;
  7375. + priv->GPI_baseaddr = cbus_gpi_base[id];
  7376. +
  7377. + /* FIXME : For now TMU queue numbers hardcoded, later should be taken from pfe.h */
  7378. +#define HIF_GEMAC_TMUQ_BASE 6
  7379. + priv->low_tmuQ = HIF_GEMAC_TMUQ_BASE + (id * 2);
  7380. + priv->high_tmuQ = priv->low_tmuQ + 1;
  7381. +
  7382. + spin_lock_init(&priv->lock);
  7383. + priv->tx_timer.data = (unsigned long)priv;
  7384. + priv->tx_timer.function = pfe_eth_tx_timeout;
  7385. + priv->tx_timer.expires = jiffies + ( COMCERTO_TX_RECOVERY_TIMEOUT_MS * HZ )/1000;
  7386. + init_timer(&priv->tx_timer);
  7387. +
  7388. + pfe_eth_fast_tx_timeout_init(priv);
  7389. +
  7390. + /* Copy the station address into the dev structure, */
  7391. + memcpy(dev->dev_addr, einfo[id].mac_addr, ETH_ALEN);
  7392. +
  7393. + /* Initialize mdio */
  7394. + if (minfo[id].enabled) {
  7395. + if ((err = pfe_eth_mdio_init(priv, &minfo[id]))) {
  7396. + netdev_err(dev, "%s: pfe_eth_mdio_init() failed\n", __func__);
  7397. + goto err2;
  7398. + }
  7399. + }
  7400. +
  7401. + dev->mtu = 1500;
  7402. +
  7403. + /* supported features */
  7404. + dev->hw_features = NETIF_F_SG;
  7405. + /* Enable after checksum offload is validated
  7406. + dev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
  7407. + NETIF_F_SG; */
  7408. +
  7409. + /* enabled by default */
  7410. + dev->features = dev->hw_features;
  7411. +
  7412. + priv->usr_features = dev->features;
  7413. +
  7414. + dev->netdev_ops = &pfe_netdev_ops;
  7415. +
  7416. + dev->ethtool_ops = &pfe_ethtool_ops;
  7417. +
  7418. + /* Enable basic messages by default */
  7419. + priv->msg_enable = NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK | NETIF_MSG_PROBE;
  7420. +
  7421. + netif_napi_add(dev, &priv->low_napi, pfe_eth_low_poll, HIF_RX_POLL_WEIGHT - 16);
  7422. + netif_napi_add(dev, &priv->high_napi, pfe_eth_high_poll, HIF_RX_POLL_WEIGHT - 16);
  7423. + netif_napi_add(dev, &priv->lro_napi, pfe_eth_lro_poll, HIF_RX_POLL_WEIGHT - 16);
  7424. +
  7425. + err = register_netdev(dev);
  7426. +
  7427. + if (err) {
  7428. + netdev_err(dev, "register_netdev() failed\n");
  7429. + goto err3;
  7430. + }
  7431. +
  7432. + if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) {
  7433. + err = pfe_phy_init(dev);
  7434. + if (err) {
  7435. + netdev_err(dev, "%s: pfe_phy_init() failed\n", __func__);
  7436. + goto err4;
  7437. + }
  7438. + }
  7439. +
  7440. +
  7441. + /* Create all the sysfs files */
  7442. + if(pfe_eth_sysfs_init(dev))
  7443. + goto err4;
  7444. +
  7445. + netif_info(priv, probe, dev, "%s: created interface, baseaddr: %p\n", __func__, priv->EMAC_baseaddr);
  7446. +
  7447. + return 0;
  7448. +err4:
  7449. + unregister_netdev(dev);
  7450. +err3:
  7451. + pfe_eth_mdio_exit(priv->mii_bus);
  7452. +err2:
  7453. +#if defined(CONFIG_PLATFORM_C2000)
  7454. + clk_put(priv->gemtx_clk);
  7455. +err1:
  7456. +#endif
  7457. + free_netdev(priv->dev);
  7458. +
  7459. +err0:
  7460. + return err;
  7461. +}
  7462. +
  7463. +/** pfe_eth_init
  7464. + */
  7465. +int pfe_eth_init(struct pfe *pfe)
  7466. +{
  7467. + int ii = 0;
  7468. + int err;
  7469. +
  7470. + printk(KERN_INFO "%s\n", __func__);
  7471. +
  7472. + cbus_emac_base[0] = EMAC1_BASE_ADDR;
  7473. + cbus_emac_base[1] = EMAC2_BASE_ADDR;
  7474. +
  7475. + cbus_gpi_base[0] = EGPI1_BASE_ADDR;
  7476. + cbus_gpi_base[1] = EGPI2_BASE_ADDR;
  7477. +
  7478. +#if !defined(CONFIG_PLATFORM_LS1012A)
  7479. + cbus_emac_base[2] = EMAC3_BASE_ADDR;
  7480. + cbus_gpi_base[2] = EGPI3_BASE_ADDR;
  7481. +#endif
  7482. +
  7483. + for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
  7484. + if ((err = pfe_eth_init_one(pfe, ii)))
  7485. + goto err0;
  7486. + }
  7487. +
  7488. + return 0;
  7489. +
  7490. +err0:
  7491. + while(ii--){
  7492. + pfe_eth_exit_one( pfe->eth.eth_priv[ii] );
  7493. + }
  7494. +
  7495. + /* Register three network devices in the kernel */
  7496. + return err;
  7497. +}
  7498. +
  7499. +/** pfe_eth_exit_one
  7500. + */
  7501. +static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv)
  7502. +{
  7503. + netif_info(priv, probe, priv->dev, "%s\n", __func__);
  7504. +
  7505. + pfe_eth_sysfs_exit(priv->dev);
  7506. +
  7507. +#if defined(CONFIG_PLATFORM_C2000)
  7508. + clk_put(priv->gemtx_clk);
  7509. +#endif
  7510. +
  7511. + unregister_netdev(priv->dev);
  7512. +
  7513. + pfe_eth_mdio_exit(priv->mii_bus);
  7514. +
  7515. + if (!(priv->einfo->phy_flags & GEMAC_NO_PHY))
  7516. + pfe_phy_exit(priv->dev);
  7517. +
  7518. + free_netdev(priv->dev);
  7519. +}
  7520. +
  7521. +/** pfe_eth_exit
  7522. + */
  7523. +void pfe_eth_exit(struct pfe *pfe)
  7524. +{
  7525. + int ii;
  7526. +
  7527. + printk(KERN_INFO "%s\n", __func__);
  7528. +
  7529. + for(ii = 0; ii < NUM_GEMAC_SUPPORT; ii++ ) {
  7530. + /*
  7531. + * FIXME: Need to check some flag in "einfo" to know whether
  7532. + * GEMAC is enabled Or not.
  7533. + */
  7534. +
  7535. + pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
  7536. + }
  7537. +}
  7538. +
  7539. --- /dev/null
  7540. +++ b/drivers/staging/fsl_ppfe/pfe_eth.h
  7541. @@ -0,0 +1,384 @@
  7542. +/*
  7543. + *
  7544. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  7545. + *
  7546. + * This program is free software; you can redistribute it and/or modify
  7547. + * it under the terms of the GNU General Public License as published by
  7548. + * the Free Software Foundation; either version 2 of the License, or
  7549. + * (at your option) any later version.
  7550. + *
  7551. + * This program is distributed in the hope that it will be useful,
  7552. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7553. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7554. + * GNU General Public License for more details.
  7555. + *
  7556. + * You should have received a copy of the GNU General Public License
  7557. + * along with this program; if not, write to the Free Software
  7558. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  7559. + */
  7560. +
  7561. +#ifndef _PFE_ETH_H_
  7562. +#define _PFE_ETH_H_
  7563. +#include <linux/kernel.h>
  7564. +#include <linux/netdevice.h>
  7565. +#include <linux/etherdevice.h>
  7566. +#include <linux/ethtool.h>
  7567. +#include <linux/mii.h>
  7568. +#include <linux/phy.h>
  7569. +#include <linux/clk.h>
  7570. +#include <linux/interrupt.h>
  7571. +#include <linux/time.h>
  7572. +
  7573. +#define PFE_ETH_NAPI_STATS
  7574. +#define PFE_ETH_TX_STATS
  7575. +
  7576. +#define PFE_ETH_FRAGS_MAX (65536/HIF_RX_PKT_MIN_SIZE)
  7577. +#define LRO_LEN_COUNT_MAX 32
  7578. +#define LRO_NB_COUNT_MAX 32
  7579. +
  7580. +#if defined(CONFIG_PLATFORM_PCI) || defined(CONFIG_PLATFORM_EMULATION) || defined(CONFIG_PLATFORM_LS1012A)
  7581. +
  7582. +#define CONFIG_COMCERTO_GEMAC 1
  7583. +
  7584. +#define CONFIG_COMCERTO_USE_MII 1
  7585. +#define CONFIG_COMCERTO_USE_RMII 2
  7586. +#define CONFIG_COMCERTO_USE_GMII 4
  7587. +#define CONFIG_COMCERTO_USE_RGMII 8
  7588. +#define CONFIG_COMCERTO_USE_SGMII 16
  7589. +
  7590. +#define GEMAC_SW_CONF (1 << 8) | (1 << 11) // GEMAC configured by SW
  7591. +#define GEMAC_PHY_CONF 0 // GEMAC configured by phy lines (not for MII/GMII)
  7592. +#define GEMAC_SW_FULL_DUPLEX (1 << 9)
  7593. +#define GEMAC_SW_SPEED_10M (0 << 12)
  7594. +#define GEMAC_SW_SPEED_100M (1 << 12)
  7595. +#define GEMAC_SW_SPEED_1G (2 << 12)
  7596. +
  7597. +#define GEMAC_NO_PHY (1 << 0) // set if no phy connected to MAC (ex ethernet switch). In this case use MAC fixed configuration
  7598. +#define GEMAC_PHY_RGMII_ADD_DELAY (1 << 1)
  7599. +
  7600. +/* gemac to interface name assignment */
  7601. +#define GEMAC0_ITF_NAME "eth5"
  7602. +#define GEMAC1_ITF_NAME "eth6"
  7603. +#define GEMAC2_ITF_NAME "eth7"
  7604. +
  7605. +#define GEMAC0_MAC { 0x00, 0xED, 0xCD, 0xEF, 0xAA, 0xCC }
  7606. +#define GEMAC1_MAC { 0x00, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E }
  7607. +
  7608. +struct comcerto_eth_platform_data {
  7609. + /* device specific information */
  7610. + u32 device_flags;
  7611. + char name[16];
  7612. +
  7613. +
  7614. + /* board specific information */
  7615. + u32 mii_config;
  7616. + u32 gemac_mode;
  7617. + u32 phy_flags;
  7618. + u32 gem_id;
  7619. + u32 bus_id;
  7620. + u32 phy_id;
  7621. + u32 mdio_muxval;
  7622. + u8 mac_addr[ETH_ALEN];
  7623. +};
  7624. +
  7625. +struct comcerto_mdio_platform_data {
  7626. + int enabled;
  7627. + int irq[32];
  7628. + u32 phy_mask;
  7629. + int mdc_div;
  7630. +};
  7631. +
  7632. +struct comcerto_pfe_platform_data
  7633. +{
  7634. + struct comcerto_eth_platform_data comcerto_eth_pdata[3];
  7635. + struct comcerto_mdio_platform_data comcerto_mdio_pdata[3];
  7636. +};
  7637. +#if !defined(CONFIG_PLATFORM_LS1012A)
  7638. +static struct comcerto_pfe_platform_data comcerto_pfe_pdata = {
  7639. + .comcerto_eth_pdata[0] = {
  7640. + .name = GEMAC0_ITF_NAME,
  7641. + .device_flags = CONFIG_COMCERTO_GEMAC,
  7642. + .mii_config = CONFIG_COMCERTO_USE_MII,
  7643. + .gemac_mode = GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX | GEMAC_SW_SPEED_100M,
  7644. +#if defined(CONFIG_PLATFORM_EMULATION) || defined(CONFIG_PLATFORM_PCI)
  7645. + .phy_flags = GEMAC_NO_PHY,
  7646. +#else
  7647. + .phy_flags = GEMAC_PHY_RGMII_ADD_DELAY,
  7648. +#endif
  7649. + .bus_id = 0,
  7650. + .phy_id = 0,
  7651. + .gem_id = 0,
  7652. + .mac_addr = (u8[])GEMAC0_MAC,
  7653. + },
  7654. +
  7655. + .comcerto_eth_pdata[1] = {
  7656. + .name = GEMAC1_ITF_NAME,
  7657. + .device_flags = CONFIG_COMCERTO_GEMAC,
  7658. + .mii_config = CONFIG_COMCERTO_USE_RGMII,
  7659. + .gemac_mode = GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX | GEMAC_SW_SPEED_1G,
  7660. + .phy_flags = GEMAC_NO_PHY,
  7661. + .gem_id = 1,
  7662. + .mac_addr = (u8[])GEMAC1_MAC,
  7663. + },
  7664. +
  7665. + .comcerto_eth_pdata[2] = {
  7666. + .name = GEMAC2_ITF_NAME,
  7667. + },
  7668. +
  7669. + .comcerto_mdio_pdata[0] = {
  7670. + .enabled = 1,
  7671. + .phy_mask = 0xFFFFFFFE,
  7672. + .mdc_div = 96,
  7673. + .irq = {
  7674. + [0] = PHY_POLL,
  7675. + },
  7676. + },
  7677. +};
  7678. +#endif
  7679. +#endif
  7680. +
  7681. +#if defined(CONFIG_PLATFORM_LS1012A)
  7682. +#define NUM_GEMAC_SUPPORT 2
  7683. +#define DRV_NAME "ls1012a-geth"
  7684. +#else
  7685. +#define NUM_GEMAC_SUPPORT 3
  7686. +#define DRV_NAME "c2000-geth"
  7687. +#endif
  7688. +#define COMCERTO_INFOSTR_LEN 32
  7689. +#define COMCERTO_TX_RECOVERY_TIMEOUT_MS 500
  7690. +#define COMCERTO_TX_FAST_RECOVERY_TIMEOUT_MS 3
  7691. +#define TX_POLL_TIMEOUT_MS 1000
  7692. +
  7693. +#define EMAC_TXQ_CNT 16
  7694. +#define EMAC_TXQ_DEPTH (HIF_TX_DESC_NT)
  7695. +
  7696. +#define JUMBO_FRAME_SIZE 10258
  7697. +/**
  7698. + * Client Tx queue threshold, for txQ flush condition.
  7699. + * It must be smaller than the queue size (in case we ever change it in the future).
  7700. + */
  7701. +#define HIF_CL_TX_FLUSH_MARK 32
  7702. +
  7703. +/**
  7704. + * Max number of TX resources (HIF descriptors or skbs) that will be released
  7705. + * in a single go during batch recycling.
  7706. + * Should be lower than the flush mark so the SW can provide the HW with a
  7707. + * continuous stream of packets instead of bursts.
  7708. + */
  7709. +#define TX_FREE_MAX_COUNT 16
  7710. +#define EMAC_RXQ_CNT 3
  7711. +#define EMAC_RXQ_DEPTH HIF_RX_DESC_NT /* make sure clients can receive a full burst of packets */
  7712. +#define EMAC_RMON_TXBYTES_POS 0x00
  7713. +#define EMAC_RMON_RXBYTES_POS 0x14
  7714. +
  7715. +#define EMAC_QUEUENUM_MASK (emac_txq_cnt - 1)
  7716. +#define EMAC_MDIO_TIMEOUT 1000
  7717. +#define MAX_UC_SPEC_ADDR_REG 31
  7718. +
  7719. +
  7720. +/* The set of statistics registers implemented in the Cadence MAC.
  7721. + * The statistics registers implemented are a subset of all the statistics
  7722. + * available, but contains all the compulsory ones.
  7723. + * For full descriptions on the registers, refer to the Cadence MAC programmers
  7724. + * guide or the IEEE 802.3 specifications.
  7725. + */
  7726. +struct gemac_stats{
  7727. + u32 octets_tx_bot; /* Lower 32-bits for number of octets tx'd */
  7728. + u32 octets_tx_top; /* Upper 16-bits for number of octets tx'd */
  7729. + u32 frames_tx; /* Number of frames transmitted OK */
  7730. + u32 broadcast_tx; /* Number of broadcast frames transmitted */
  7731. + u32 multicast_tx; /* Number of multicast frames transmitted */
  7732. + u32 pause_tx; /* Number of pause frames transmitted. */
  7733. + u32 frame64_tx; /* Number of 64byte frames transmitted */
  7734. + u32 frame65_127_tx; /* Number of 65-127 byte frames transmitted */
  7735. + u32 frame128_255_tx; /* Number of 128-255 byte frames transmitted */
  7736. + u32 frame256_511_tx; /* Number of 256-511 byte frames transmitted */
  7737. + u32 frame512_1023_tx; /* Number of 512-1023 byte frames transmitted */
  7738. + u32 frame1024_1518_tx; /* Number of 1024-1518 byte frames transmitted*/
  7739. + u32 frame1519_tx; /* Number of frames greater than 1518 bytes tx*/
  7740. + u32 tx_urun; /* Transmit underrun errors due to DMA */
  7741. + u32 single_col; /* Number of single collision frames */
  7742. + u32 multi_col; /* Number of multi collision frames */
  7743. + u32 excess_col; /* Number of excessive collision frames. */
  7744. + u32 late_col; /* Collisions occuring after slot time */
  7745. + u32 def_tx; /* Frames deferred due to crs */
  7746. + u32 crs_errors; /* Errors caused by crs not being asserted. */
  7747. + u32 octets_rx_bot; /* Lower 32-bits for number of octets rx'd */
  7748. + u32 octets_rx_top; /* Upper 16-bits for number of octets rx'd */
  7749. + u32 frames_rx; /* Number of frames received OK */
  7750. + u32 broadcast_rx; /* Number of broadcast frames received */
  7751. + u32 multicast_rx; /* Number of multicast frames received */
  7752. + u32 pause_rx; /* Number of pause frames received. */
  7753. + u32 frame64_rx; /* Number of 64byte frames received */
  7754. + u32 frame65_127_rx; /* Number of 65-127 byte frames received */
  7755. + u32 frame128_255_rx; /* Number of 128-255 byte frames received */
  7756. + u32 frame256_511_rx; /* Number of 256-511 byte frames received */
  7757. + u32 frame512_1023_rx; /* Number of 512-1023 byte frames received */
  7758. + u32 frame1024_1518_rx; /* Number of 1024-1518 byte frames received*/
  7759. + u32 frame1519_rx; /* Number of frames greater than 1518 bytes rx*/
  7760. + u32 usize_frames; /* Frames received less than min of 64 bytes */
  7761. + u32 excess_length; /* Number of excessive length frames rx */
  7762. + u32 jabbers; /* Excessive length + crc or align errors. */
  7763. + u32 fcs_errors; /* Number of frames received with crc errors */
  7764. + u32 length_check_errors;/* Number of frames with incorrect length */
  7765. + u32 rx_symbol_errors; /* Number of times rx_er asserted during rx */
  7766. + u32 align_errors; /* Frames received without integer no. bytes */
  7767. + u32 rx_res_errors; /* Number of times buffers ran out during rx */
  7768. + u32 rx_orun; /* Receive overrun errors due to DMA */
  7769. + u32 ip_cksum; /* IP header checksum errors */
  7770. + u32 tcp_cksum; /* TCP checksum errors */
  7771. + u32 udp_cksum; /* UDP checksum errors */
  7772. +};
  7773. +
  7774. +#define EMAC_REG_SPACE sizeof(struct gemac_reg)
  7775. +#define EMAC_RMON_LEN (sizeof(struct gemac_stats)/sizeof(u32))
  7776. +
  7777. +
  7778. +struct pfe_eth_fast_timer {
  7779. + int queuenum;
  7780. + struct hrtimer timer;
  7781. + void * base;
  7782. +};
  7783. +
  7784. +typedef struct pfe_eth_priv_s
  7785. +{
  7786. + struct pfe *pfe;
  7787. + struct hif_client_s client;
  7788. + struct napi_struct lro_napi;
  7789. + struct napi_struct low_napi;
  7790. + struct napi_struct high_napi;
  7791. + int low_tmuQ;
  7792. + int high_tmuQ;
  7793. + struct net_device_stats stats;
  7794. + struct net_device *dev;
  7795. + int id;
  7796. + int promisc;
  7797. + unsigned int msg_enable;
  7798. + unsigned int usr_features;
  7799. +
  7800. + spinlock_t lock;
  7801. + unsigned int event_status;
  7802. + int irq;
  7803. + void* EMAC_baseaddr;
  7804. + void* PHY_baseaddr; /* This points to the EMAC base from where we access PHY */
  7805. + void* GPI_baseaddr;
  7806. + int mdio_muxval;
  7807. + /* PHY stuff */
  7808. + struct phy_device *phydev;
  7809. + int oldspeed;
  7810. + int oldduplex;
  7811. + int oldlink;
  7812. + /* mdio info */
  7813. + int mdc_div;
  7814. + struct mii_bus *mii_bus;
  7815. + struct clk *gemtx_clk;
  7816. + int wol;
  7817. +
  7818. + int default_priority;
  7819. + struct timer_list tx_timer;
  7820. + struct pfe_eth_fast_timer fast_tx_timeout[EMAC_TXQ_CNT];
  7821. +
  7822. + struct comcerto_eth_platform_data *einfo;
  7823. + struct sk_buff *skb_inflight[EMAC_RXQ_CNT + 6];
  7824. +
  7825. +#ifdef PFE_ETH_LRO_STATS
  7826. + unsigned int lro_len_counters[LRO_LEN_COUNT_MAX];
  7827. + unsigned int lro_nb_counters[LRO_NB_COUNT_MAX]; //TODO change to exact max number when RX scatter done
  7828. +#endif
  7829. +
  7830. +
  7831. +#ifdef PFE_ETH_TX_STATS
  7832. + unsigned int stop_queue_total[EMAC_TXQ_CNT];
  7833. + unsigned int stop_queue_hif[EMAC_TXQ_CNT];
  7834. + unsigned int stop_queue_hif_client[EMAC_TXQ_CNT];
  7835. + unsigned int stop_queue_credit[EMAC_TXQ_CNT];
  7836. + unsigned int clean_fail[EMAC_TXQ_CNT];
  7837. + unsigned int was_stopped[EMAC_TXQ_CNT];
  7838. +#endif
  7839. +
  7840. +#ifdef PFE_ETH_NAPI_STATS
  7841. + unsigned int napi_counters[NAPI_MAX_COUNT];
  7842. +#endif
  7843. + unsigned int frags_inflight[EMAC_RXQ_CNT + 6];
  7844. +
  7845. +}pfe_eth_priv_t;
  7846. +
  7847. +struct pfe_eth {
  7848. + struct pfe_eth_priv_s *eth_priv[3];
  7849. +};
  7850. +
  7851. +int pfe_eth_init(struct pfe *pfe);
  7852. +void pfe_eth_exit(struct pfe *pfe);
  7853. +int pfe_eth_suspend(struct net_device *dev);
  7854. +int pfe_eth_resume(struct net_device *dev);
  7855. +int pfe_eth_mdio_reset(struct mii_bus *bus);
  7856. +
  7857. +/** pfe_compute_csum
  7858. + *
  7859. + */
  7860. +static int inline pfe_compute_csum(struct sk_buff *skb)
  7861. +{
  7862. + struct skb_shared_info *sh;
  7863. + unsigned int nr_frags;
  7864. + skb_frag_t *f;
  7865. + u32 csum = 0;
  7866. + int i;
  7867. + int len;
  7868. +
  7869. + /* Make sure that no intermediate buffers/fragments are odd byte aligned */
  7870. + if (skb_is_nonlinear(skb)) {
  7871. + int linearize = 0;
  7872. +
  7873. + sh = skb_shinfo(skb);
  7874. + nr_frags = sh->nr_frags;
  7875. + len = skb_headlen(skb) - skb_transport_offset(skb);
  7876. +
  7877. + if (len & 0x1) {
  7878. + linearize = 1;
  7879. + //printk("#1 Odd length %d\n", len);
  7880. + }
  7881. + else {
  7882. + for (i = 0; i < nr_frags - 1; i++) {
  7883. + f = &sh->frags[i];
  7884. + len = skb_frag_size(f);
  7885. +
  7886. + if (len & 0x1) {
  7887. + linearize = 1;
  7888. + //printk("#2 %d Odd length %d\n", i, len);
  7889. + break;
  7890. + }
  7891. + }
  7892. + }
  7893. +
  7894. + if (linearize)
  7895. + if (skb_linearize(skb))
  7896. + return -1;
  7897. + }
  7898. +
  7899. + /* Compute checksum */
  7900. + if (!skb_is_nonlinear(skb)) {
  7901. + *(u16*)(skb_transport_header(skb) + skb->csum_offset) = csum_fold(csum_partial(skb_transport_header(skb), skb->len - skb_transport_offset(skb), 0));
  7902. + }
  7903. + else {
  7904. + sh = skb_shinfo(skb);
  7905. + nr_frags = sh->nr_frags;
  7906. +
  7907. + if (nr_frags) {
  7908. + csum = csum_partial(skb_transport_header(skb), skb_headlen(skb) - skb_transport_offset(skb), 0);
  7909. +
  7910. + for (i = 0; i < nr_frags - 1; i++) {
  7911. + f = &sh->frags[i];
  7912. + csum = csum_partial(skb_frag_address(f), skb_frag_size(f), csum);
  7913. + }
  7914. +
  7915. + f = &sh->frags[i];
  7916. + *(u16*)(skb_transport_header(skb) + skb->csum_offset) = csum_fold(csum_partial(skb_frag_address(f), skb_frag_size(f), csum));
  7917. + }
  7918. + }
  7919. +
  7920. + return 0;
  7921. +}
  7922. +
  7923. +
  7924. +
  7925. +#endif /* _PFE_ETH_H_ */
  7926. --- /dev/null
  7927. +++ b/drivers/staging/fsl_ppfe/pfe_firmware.c
  7928. @@ -0,0 +1,322 @@
  7929. +/*
  7930. + *
  7931. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  7932. + *
  7933. + * This program is free software; you can redistribute it and/or modify
  7934. + * it under the terms of the GNU General Public License as published by
  7935. + * the Free Software Foundation; either version 2 of the License, or
  7936. + * (at your option) any later version.
  7937. + *
  7938. + * This program is distributed in the hope that it will be useful,
  7939. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7940. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7941. + * GNU General Public License for more details.
  7942. + *
  7943. + * You should have received a copy of the GNU General Public License
  7944. + * along with this program; if not, write to the Free Software
  7945. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  7946. + */
  7947. +
  7948. +/** @file
  7949. + * Contains all the functions to handle parsing and loading of PE firmware files.
  7950. + */
  7951. +#include <linux/firmware.h>
  7952. +
  7953. +#include "pfe_mod.h"
  7954. +#include "pfe_firmware.h"
  7955. +#include "pfe/pfe.h"
  7956. +
  7957. +static Elf32_Shdr * get_elf_section_header(const struct firmware *fw, const char *section)
  7958. +{
  7959. + Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *)fw->data;
  7960. + Elf32_Shdr *shdr, *shdr_shstr;
  7961. + Elf32_Off e_shoff = be32_to_cpu(elf_hdr->e_shoff);
  7962. + Elf32_Half e_shentsize = be16_to_cpu(elf_hdr->e_shentsize);
  7963. + Elf32_Half e_shnum = be16_to_cpu(elf_hdr->e_shnum);
  7964. + Elf32_Half e_shstrndx = be16_to_cpu(elf_hdr->e_shstrndx);
  7965. + Elf32_Off shstr_offset;
  7966. + Elf32_Word sh_name;
  7967. + const char *name;
  7968. + int i;
  7969. +
  7970. + /* Section header strings */
  7971. + shdr_shstr = (Elf32_Shdr *)(fw->data + e_shoff + e_shstrndx * e_shentsize);
  7972. + shstr_offset = be32_to_cpu(shdr_shstr->sh_offset);
  7973. +
  7974. + for (i = 0; i < e_shnum; i++) {
  7975. + shdr = (Elf32_Shdr *)(fw->data + e_shoff + i * e_shentsize);
  7976. +
  7977. + sh_name = be32_to_cpu(shdr->sh_name);
  7978. +
  7979. + name = (const char *)(fw->data + shstr_offset + sh_name);
  7980. +
  7981. + if (!strcmp(name, section))
  7982. + return shdr;
  7983. + }
  7984. +
  7985. + printk(KERN_ERR "%s: didn't find section %s\n", __func__, section);
  7986. +
  7987. + return NULL;
  7988. +}
  7989. +
  7990. +static unsigned long get_elf_section(const struct firmware *fw, const char *section)
  7991. +{
  7992. + Elf32_Shdr *shdr = get_elf_section_header(fw, section);
  7993. +
  7994. + if (shdr)
  7995. + return be32_to_cpu(shdr->sh_addr);
  7996. + else
  7997. + return -1;
  7998. +}
  7999. +
  8000. +#if defined(CFG_DIAGS)
  8001. +static int pfe_get_diags_info(const struct firmware *fw, struct pfe_diags_info *diags_info)
  8002. +{
  8003. + Elf32_Shdr *shdr;
  8004. + unsigned long offset, size;
  8005. +
  8006. + shdr = get_elf_section_header(fw, ".pfe_diags_str");
  8007. + if (shdr)
  8008. + {
  8009. + offset = be32_to_cpu(shdr->sh_offset);
  8010. + size = be32_to_cpu(shdr->sh_size);
  8011. + diags_info->diags_str_base = be32_to_cpu(shdr->sh_addr);
  8012. + diags_info->diags_str_size = size;
  8013. + diags_info->diags_str_array = pfe_kmalloc(size, GFP_KERNEL);
  8014. + memcpy(diags_info->diags_str_array, fw->data+offset, size);
  8015. +
  8016. + return 0;
  8017. + } else
  8018. + {
  8019. + return -1;
  8020. + }
  8021. +}
  8022. +#endif
  8023. +
  8024. +static void pfe_check_version_info(const struct firmware *fw)
  8025. +{
  8026. + static char *version = NULL;
  8027. +
  8028. + Elf32_Shdr *shdr = get_elf_section_header(fw, ".version");
  8029. +
  8030. + if (shdr)
  8031. + {
  8032. + if(!version)
  8033. + {
  8034. + /* this is the first fw we load, use its version string as reference (whatever it is) */
  8035. + version = (char *)(fw->data + be32_to_cpu(shdr->sh_offset));
  8036. +
  8037. + printk(KERN_INFO "PFE binary version: %s\n", version);
  8038. + }
  8039. + else
  8040. + {
  8041. + /* already have loaded at least one firmware, check sequence can start now */
  8042. + if(strcmp(version, (char *)(fw->data + be32_to_cpu(shdr->sh_offset))))
  8043. + {
  8044. + printk(KERN_INFO "WARNING: PFE firmware binaries from incompatible version\n");
  8045. + }
  8046. + }
  8047. + }
  8048. + else
  8049. + {
  8050. + /* version cannot be verified, a potential issue that should be reported */
  8051. + printk(KERN_INFO "WARNING: PFE firmware binaries from incompatible version\n");
  8052. + }
  8053. +}
  8054. +
  8055. +/** PFE elf firmware loader.
  8056. +* Loads an elf firmware image into a list of PE's (specified using a bitmask)
  8057. +*
  8058. +* @param pe_mask Mask of PE id's to load firmware to
  8059. +* @param fw Pointer to the firmware image
  8060. +*
  8061. +* @return 0 on sucess, a negative value on error
  8062. +*
  8063. +*/
  8064. +int pfe_load_elf(int pe_mask, const struct firmware *fw, struct pfe *pfe)
  8065. +{
  8066. + Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *)fw->data;
  8067. + Elf32_Half sections = be16_to_cpu(elf_hdr->e_shnum);
  8068. + Elf32_Shdr *shdr = (Elf32_Shdr *) (fw->data + be32_to_cpu(elf_hdr->e_shoff));
  8069. + int id, section;
  8070. + int rc;
  8071. +
  8072. + printk(KERN_INFO "%s\n", __func__);
  8073. +
  8074. + /* Some sanity checks */
  8075. + if (strncmp(&elf_hdr->e_ident[EI_MAG0], ELFMAG, SELFMAG))
  8076. + {
  8077. + printk(KERN_ERR "%s: incorrect elf magic number\n", __func__);
  8078. + return -EINVAL;
  8079. + }
  8080. +
  8081. + if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32)
  8082. + {
  8083. + printk(KERN_ERR "%s: incorrect elf class(%x)\n", __func__, elf_hdr->e_ident[EI_CLASS]);
  8084. + return -EINVAL;
  8085. + }
  8086. +
  8087. + if (elf_hdr->e_ident[EI_DATA] != ELFDATA2MSB)
  8088. + {
  8089. + printk(KERN_ERR "%s: incorrect elf data(%x)\n", __func__, elf_hdr->e_ident[EI_DATA]);
  8090. + return -EINVAL;
  8091. + }
  8092. +
  8093. + if (be16_to_cpu(elf_hdr->e_type) != ET_EXEC)
  8094. + {
  8095. + printk(KERN_ERR "%s: incorrect elf file type(%x)\n", __func__, be16_to_cpu(elf_hdr->e_type));
  8096. + return -EINVAL;
  8097. + }
  8098. +
  8099. + for (section = 0; section < sections; section++, shdr++)
  8100. + {
  8101. + if (!(be32_to_cpu(shdr->sh_flags) & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)))
  8102. + continue;
  8103. +
  8104. + for (id = 0; id < MAX_PE; id++)
  8105. + if (pe_mask & (1 << id))
  8106. + {
  8107. + rc = pe_load_elf_section(id, fw->data, shdr, pfe->dev);
  8108. + if (rc < 0)
  8109. + goto err;
  8110. + }
  8111. + }
  8112. +
  8113. + pfe_check_version_info(fw);
  8114. +
  8115. + return 0;
  8116. +
  8117. +err:
  8118. + return rc;
  8119. +}
  8120. +
  8121. +
  8122. +/** PFE firmware initialization.
  8123. +* Loads different firmware files from filesystem.
  8124. +* Initializes PE IMEM/DMEM and UTIL-PE DDR
  8125. +* Initializes control path symbol addresses (by looking them up in the elf firmware files
  8126. +* Takes PE's out of reset
  8127. +*
  8128. +* @return 0 on sucess, a negative value on error
  8129. +*
  8130. +*/
  8131. +int pfe_firmware_init(struct pfe *pfe)
  8132. +{
  8133. + const struct firmware *class_fw, *tmu_fw;
  8134. + int rc = 0;
  8135. +#if !defined(CONFIG_UTIL_DISABLED)
  8136. + const char* util_fw_name;
  8137. + const struct firmware *util_fw;
  8138. +#endif
  8139. +
  8140. + printk(KERN_INFO "%s\n", __func__);
  8141. +
  8142. + if (request_firmware(&class_fw, CLASS_FIRMWARE_FILENAME, pfe->dev)) {
  8143. + printk(KERN_ERR "%s: request firmware %s failed\n", __func__, CLASS_FIRMWARE_FILENAME);
  8144. + rc = -ETIMEDOUT;
  8145. + goto err0;
  8146. + }
  8147. +
  8148. + if (request_firmware(&tmu_fw, TMU_FIRMWARE_FILENAME, pfe->dev)) {
  8149. + printk(KERN_ERR "%s: request firmware %s failed\n", __func__, TMU_FIRMWARE_FILENAME);
  8150. + rc = -ETIMEDOUT;
  8151. + goto err1;
  8152. + }
  8153. +#if !defined(CONFIG_UTIL_DISABLED)
  8154. +#if defined(CONFIG_PLATFORM_C2000)
  8155. + util_fw_name = (system_rev == 0) ? UTIL_REVA0_FIRMWARE_FILENAME : UTIL_FIRMWARE_FILENAME;
  8156. +#else
  8157. + util_fw_name = UTIL_FIRMWARE_FILENAME;
  8158. +#endif
  8159. +
  8160. + if (request_firmware(&util_fw, util_fw_name, pfe->dev)) {
  8161. + printk(KERN_ERR "%s: request firmware %s failed\n", __func__, util_fw_name);
  8162. + rc = -ETIMEDOUT;
  8163. + goto err2;
  8164. + }
  8165. +#endif
  8166. + rc = pfe_load_elf(CLASS_MASK, class_fw, pfe);
  8167. + if (rc < 0) {
  8168. + printk(KERN_ERR "%s: class firmware load failed\n", __func__);
  8169. + goto err3;
  8170. + }
  8171. +
  8172. + pfe->ctrl.class_dmem_sh = get_elf_section(class_fw, ".dmem_sh");
  8173. + pfe->ctrl.class_pe_lmem_sh = get_elf_section(class_fw, ".pe_lmem_sh");
  8174. +
  8175. +#if defined(CFG_DIAGS)
  8176. + rc = pfe_get_diags_info(class_fw, &pfe->diags.class_diags_info);
  8177. + if (rc < 0) {
  8178. + printk (KERN_WARNING "PFE diags won't be available for class PEs\n");
  8179. + rc = 0;
  8180. + }
  8181. +#endif
  8182. +
  8183. + printk(KERN_INFO "%s: class firmware loaded %#lx %#lx\n", __func__, pfe->ctrl.class_dmem_sh, pfe->ctrl.class_pe_lmem_sh);
  8184. +
  8185. + rc = pfe_load_elf(TMU_MASK, tmu_fw, pfe);
  8186. + if (rc < 0) {
  8187. + printk(KERN_ERR "%s: tmu firmware load failed\n", __func__);
  8188. + goto err3;
  8189. + }
  8190. +
  8191. + pfe->ctrl.tmu_dmem_sh = get_elf_section(tmu_fw, ".dmem_sh");
  8192. +
  8193. + printk(KERN_INFO "%s: tmu firmware loaded %#lx\n", __func__, pfe->ctrl.tmu_dmem_sh);
  8194. +
  8195. +#if !defined(CONFIG_UTIL_DISABLED)
  8196. + rc = pfe_load_elf(UTIL_MASK, util_fw, pfe);
  8197. + if (rc < 0) {
  8198. + printk(KERN_ERR "%s: util firmware load failed\n", __func__);
  8199. + goto err3;
  8200. + }
  8201. +
  8202. + pfe->ctrl.util_dmem_sh = get_elf_section(util_fw, ".dmem_sh");
  8203. + pfe->ctrl.util_ddr_sh = get_elf_section(util_fw, ".ddr_sh");
  8204. +
  8205. +#if defined(CFG_DIAGS)
  8206. + rc = pfe_get_diags_info(util_fw, &pfe->diags.util_diags_info);
  8207. + if (rc < 0) {
  8208. + printk(KERN_WARNING "PFE diags won't be available for util PE\n");
  8209. + rc = 0;
  8210. + }
  8211. +#endif
  8212. +
  8213. + printk(KERN_INFO "%s: util firmware loaded %#lx\n", __func__, pfe->ctrl.util_dmem_sh);
  8214. +
  8215. + util_enable();
  8216. +#endif
  8217. +
  8218. + tmu_enable(0xf);
  8219. + class_enable();
  8220. +
  8221. +err3:
  8222. +#if !defined(CONFIG_UTIL_DISABLED)
  8223. + release_firmware(util_fw);
  8224. +
  8225. +err2:
  8226. +#endif
  8227. + release_firmware(tmu_fw);
  8228. +
  8229. +err1:
  8230. + release_firmware(class_fw);
  8231. +
  8232. +err0:
  8233. + return rc;
  8234. +}
  8235. +
  8236. +/** PFE firmware cleanup
  8237. +* Puts PE's in reset
  8238. +*
  8239. +*
  8240. +*/
  8241. +void pfe_firmware_exit(struct pfe *pfe)
  8242. +{
  8243. + printk(KERN_INFO "%s\n", __func__);
  8244. +
  8245. + class_disable();
  8246. + tmu_disable(0xf);
  8247. +#if !defined(CONFIG_UTIL_DISABLED)
  8248. + util_disable();
  8249. +#endif
  8250. +}
  8251. --- /dev/null
  8252. +++ b/drivers/staging/fsl_ppfe/pfe_firmware.h
  8253. @@ -0,0 +1,41 @@
  8254. +/*
  8255. + *
  8256. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  8257. + *
  8258. + * This program is free software; you can redistribute it and/or modify
  8259. + * it under the terms of the GNU General Public License as published by
  8260. + * the Free Software Foundation; either version 2 of the License, or
  8261. + * (at your option) any later version.
  8262. + *
  8263. + * This program is distributed in the hope that it will be useful,
  8264. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8265. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8266. + * GNU General Public License for more details.
  8267. + *
  8268. + * You should have received a copy of the GNU General Public License
  8269. + * along with this program; if not, write to the Free Software
  8270. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  8271. + */
  8272. +
  8273. +#ifndef _PFE_FIRMWARE_H_
  8274. +#define _PFE_FIRMWARE_H_
  8275. +
  8276. +#if defined(CONFIG_PLATFORM_C2000)
  8277. +#define CLASS_FIRMWARE_FILENAME "class_c2000.elf"
  8278. +#define TMU_FIRMWARE_FILENAME "tmu_c2000.elf"
  8279. +#define UTIL_FIRMWARE_FILENAME "util_c2000.elf"
  8280. +#define UTIL_REVA0_FIRMWARE_FILENAME "util_c2000_revA0.elf"
  8281. +#else
  8282. +#define CLASS_FIRMWARE_FILENAME "ppfe_class_ls1012a.elf"
  8283. +#define TMU_FIRMWARE_FILENAME "ppfe_tmu_ls1012a.elf"
  8284. +#endif
  8285. +
  8286. +#define PFE_FW_CHECK_PASS 0
  8287. +#define PFE_FW_CHECK_FAIL 1
  8288. +#define NUM_PFE_FW 3
  8289. +
  8290. +int pfe_firmware_init(struct pfe *pfe);
  8291. +void pfe_firmware_exit(struct pfe *pfe);
  8292. +
  8293. +#endif /* _PFE_FIRMWARE_H_ */
  8294. +
  8295. --- /dev/null
  8296. +++ b/drivers/staging/fsl_ppfe/pfe_hal.c
  8297. @@ -0,0 +1,2217 @@
  8298. +/*
  8299. + *
  8300. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  8301. + *
  8302. + * This program is free software; you can redistribute it and/or modify
  8303. + * it under the terms of the GNU General Public License as published by
  8304. + * the Free Software Foundation; either version 2 of the License, or
  8305. + * (at your option) any later version.
  8306. + *
  8307. + * This program is distributed in the hope that it will be useful,
  8308. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8309. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8310. + * GNU General Public License for more details.
  8311. + *
  8312. + * You should have received a copy of the GNU General Public License
  8313. + * along with this program; if not, write to the Free Software
  8314. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  8315. + */
  8316. +
  8317. +
  8318. +#include "pfe_ctrl_hal.h"
  8319. +#include "pfe/pfe.h"
  8320. +
  8321. +void *cbus_base_addr;
  8322. +void *ddr_base_addr;
  8323. +unsigned long ddr_phys_base_addr;
  8324. +unsigned int ddr_size;
  8325. +
  8326. +static struct pe_info pe[MAX_PE];
  8327. +
  8328. +/** Initializes the PFE library.
  8329. +* Must be called before using any of the library functions.
  8330. +*
  8331. +* @param[in] cbus_base CBUS virtual base address (as mapped in the host CPU address space)
  8332. +* @param[in] ddr_base PFE DDR range virtual base address (as mapped in the host CPU address space)
  8333. +* @param[in] ddr_phys_base PFE DDR range physical base address (as mapped in platform)
  8334. +* @param[in] size PFE DDR range size (as defined by the host software)
  8335. +*/
  8336. +void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, unsigned int size)
  8337. +{
  8338. + cbus_base_addr = cbus_base;
  8339. + ddr_base_addr = ddr_base;
  8340. + ddr_phys_base_addr = ddr_phys_base;
  8341. + ddr_size = size;
  8342. +
  8343. + pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0);
  8344. + pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0);
  8345. + pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE;
  8346. + pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
  8347. + pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
  8348. + pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
  8349. +
  8350. + pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1);
  8351. + pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1);
  8352. + pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE;
  8353. + pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
  8354. + pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
  8355. + pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
  8356. +
  8357. + pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2);
  8358. + pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2);
  8359. + pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE;
  8360. + pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
  8361. + pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
  8362. + pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
  8363. +
  8364. + pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3);
  8365. + pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3);
  8366. + pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE;
  8367. + pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
  8368. + pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
  8369. + pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
  8370. +
  8371. +#if !defined(CONFIG_PLATFORM_PCI)
  8372. + pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4);
  8373. + pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4);
  8374. + pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE;
  8375. + pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
  8376. + pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
  8377. + pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
  8378. +
  8379. + pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5);
  8380. + pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5);
  8381. + pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE;
  8382. + pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
  8383. + pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
  8384. + pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
  8385. +#endif
  8386. + pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0);
  8387. + pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0);
  8388. + pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE;
  8389. + pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
  8390. + pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
  8391. + pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
  8392. +
  8393. +#if !defined(CONFIG_TMU_DUMMY)
  8394. + pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1);
  8395. + pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1);
  8396. + pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE;
  8397. + pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
  8398. + pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
  8399. + pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
  8400. +
  8401. +#if !defined(CONFIG_PLATFORM_LS1012A)
  8402. + pe[TMU2_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(2);
  8403. + pe[TMU2_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(2);
  8404. + pe[TMU2_ID].pmem_size = TMU_IMEM_SIZE;
  8405. + pe[TMU2_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
  8406. + pe[TMU2_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
  8407. + pe[TMU2_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
  8408. +#endif
  8409. +
  8410. + pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3);
  8411. + pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3);
  8412. + pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE;
  8413. + pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
  8414. + pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
  8415. + pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
  8416. +#endif
  8417. +
  8418. +#if !defined(CONFIG_UTIL_DISABLED)
  8419. + pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR;
  8420. + pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA;
  8421. + pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR;
  8422. + pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA;
  8423. +#endif
  8424. +}
  8425. +
  8426. +
  8427. +/** Writes a buffer to PE internal memory from the host
  8428. + * through indirect access registers.
  8429. + *
  8430. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., UTIL_ID)
  8431. + * @param[in] src Buffer source address
  8432. + * @param[in] mem_access_addr DMEM destination address (must be 32bit aligned)
  8433. + * @param[in] len Number of bytes to copy
  8434. + */
  8435. +void pe_mem_memcpy_to32(int id, u32 mem_access_addr, const void *src, unsigned int len)
  8436. +{
  8437. + u32 offset = 0, val, addr;
  8438. + unsigned int len32 = len >> 2;
  8439. + int i;
  8440. +
  8441. + addr = mem_access_addr | PE_MEM_ACCESS_WRITE | PE_MEM_ACCESS_BYTE_ENABLE(0, 4);
  8442. +
  8443. + for (i = 0; i < len32; i++, offset += 4, src += 4) {
  8444. + val = *(u32 *)src;
  8445. + writel(cpu_to_be32(val), pe[id].mem_access_wdata);
  8446. + writel(addr + offset, pe[id].mem_access_addr);
  8447. + }
  8448. +
  8449. + if ((len = (len & 0x3))) {
  8450. + val = 0;
  8451. +
  8452. + addr = (mem_access_addr | PE_MEM_ACCESS_WRITE | PE_MEM_ACCESS_BYTE_ENABLE(0, len)) + offset;
  8453. +
  8454. + for (i = 0; i < len; i++, src++)
  8455. + val |= (*(u8 *)src) << (8 * i);
  8456. +
  8457. + writel(cpu_to_be32(val), pe[id].mem_access_wdata);
  8458. + writel(addr, pe[id].mem_access_addr);
  8459. + }
  8460. +}
  8461. +
  8462. +/** Writes a buffer to PE internal data memory (DMEM) from the host
  8463. + * through indirect access registers.
  8464. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., UTIL_ID)
  8465. + * @param[in] src Buffer source address
  8466. + * @param[in] dst DMEM destination address (must be 32bit aligned)
  8467. + * @param[in] len Number of bytes to copy
  8468. + */
  8469. +void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
  8470. +{
  8471. + pe_mem_memcpy_to32(id, pe[id].dmem_base_addr | dst | PE_MEM_ACCESS_DMEM, src, len);
  8472. +}
  8473. +
  8474. +
  8475. +/** Writes a buffer to PE internal program memory (PMEM) from the host
  8476. + * through indirect access registers.
  8477. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., TMU3_ID)
  8478. + * @param[in] src Buffer source address
  8479. + * @param[in] dst PMEM destination address (must be 32bit aligned)
  8480. + * @param[in] len Number of bytes to copy
  8481. + */
  8482. +void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
  8483. +{
  8484. + pe_mem_memcpy_to32(id, pe[id].pmem_base_addr | (dst & (pe[id].pmem_size - 1)) | PE_MEM_ACCESS_IMEM, src, len);
  8485. +}
  8486. +
  8487. +
  8488. +/** Reads PE internal program memory (IMEM) from the host
  8489. + * through indirect access registers.
  8490. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., TMU3_ID)
  8491. + * @param[in] addr PMEM read address (must be aligned on size)
  8492. + * @param[in] size Number of bytes to read (maximum 4, must not cross 32bit boundaries)
  8493. + * @return the data read (in PE endianess, i.e BE).
  8494. + */
  8495. +u32 pe_pmem_read(int id, u32 addr, u8 size)
  8496. +{
  8497. + u32 offset = addr & 0x3;
  8498. + u32 mask = 0xffffffff >> ((4 - size) << 3);
  8499. + u32 val;
  8500. +
  8501. + addr = pe[id].pmem_base_addr | ((addr & ~0x3) & (pe[id].pmem_size - 1)) | PE_MEM_ACCESS_IMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
  8502. +
  8503. + writel(addr, pe[id].mem_access_addr);
  8504. + val = be32_to_cpu(readl(pe[id].mem_access_rdata));
  8505. +
  8506. + return (val >> (offset << 3)) & mask;
  8507. +}
  8508. +
  8509. +
  8510. +/** Writes PE internal data memory (DMEM) from the host
  8511. + * through indirect access registers.
  8512. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., UTIL_ID)
  8513. + * @param[in] addr DMEM write address (must be aligned on size)
  8514. + * @param[in] val Value to write (in PE endianess, i.e BE)
  8515. + * @param[in] size Number of bytes to write (maximum 4, must not cross 32bit boundaries)
  8516. + */
  8517. +void pe_dmem_write(int id, u32 val, u32 addr, u8 size)
  8518. +{
  8519. + u32 offset = addr & 0x3;
  8520. +
  8521. + addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_WRITE | PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
  8522. +
  8523. + /* Indirect access interface is byte swapping data being written */
  8524. + writel(cpu_to_be32(val << (offset << 3)), pe[id].mem_access_wdata);
  8525. + writel(addr, pe[id].mem_access_addr);
  8526. +}
  8527. +
  8528. +
  8529. +/** Reads PE internal data memory (DMEM) from the host
  8530. + * through indirect access registers.
  8531. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., UTIL_ID)
  8532. + * @param[in] addr DMEM read address (must be aligned on size)
  8533. + * @param[in] size Number of bytes to read (maximum 4, must not cross 32bit boundaries)
  8534. + * @return the data read (in PE endianess, i.e BE).
  8535. + */
  8536. +u32 pe_dmem_read(int id, u32 addr, u8 size)
  8537. +{
  8538. + u32 offset = addr & 0x3;
  8539. + u32 mask = 0xffffffff >> ((4 - size) << 3);
  8540. + u32 val;
  8541. +
  8542. + addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
  8543. +
  8544. + writel(addr, pe[id].mem_access_addr);
  8545. +
  8546. + /* Indirect access interface is byte swapping data being read */
  8547. + val = be32_to_cpu(readl(pe[id].mem_access_rdata));
  8548. +
  8549. + return (val >> (offset << 3)) & mask;
  8550. +}
  8551. +
  8552. +
  8553. +/** This function is used to write to CLASS internal bus peripherals (ccu, pe-lem) from the host
  8554. +* through indirect access registers.
  8555. +* @param[in] val value to write
  8556. +* @param[in] addr Address to write to (must be aligned on size)
  8557. +* @param[in] size Number of bytes to write (1, 2 or 4)
  8558. +*
  8559. +*/
  8560. +void class_bus_write(u32 val, u32 addr, u8 size)
  8561. +{
  8562. + u32 offset = addr & 0x3;
  8563. +
  8564. + writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
  8565. +
  8566. + addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | PE_MEM_ACCESS_WRITE | (size << 24);
  8567. +
  8568. + writel(cpu_to_be32(val << (offset << 3)), CLASS_BUS_ACCESS_WDATA);
  8569. + writel(addr, CLASS_BUS_ACCESS_ADDR);
  8570. +}
  8571. +
  8572. +
  8573. +/** Reads from CLASS internal bus peripherals (ccu, pe-lem) from the host
  8574. +* through indirect access registers.
  8575. +* @param[in] addr Address to read from (must be aligned on size)
  8576. +* @param[in] size Number of bytes to read (1, 2 or 4)
  8577. +* @return the read data
  8578. +*
  8579. +*/
  8580. +u32 class_bus_read(u32 addr, u8 size)
  8581. +{
  8582. + u32 offset = addr & 0x3;
  8583. + u32 mask = 0xffffffff >> ((4 - size) << 3);
  8584. + u32 val;
  8585. +
  8586. + writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
  8587. +
  8588. + addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | (size << 24);
  8589. +
  8590. + writel(addr, CLASS_BUS_ACCESS_ADDR);
  8591. + val = be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA));
  8592. +
  8593. + return (val >> (offset << 3)) & mask;
  8594. +}
  8595. +
  8596. +
  8597. +/** Writes data to the cluster memory (PE_LMEM)
  8598. +* @param[in] dst PE LMEM destination address (must be 32bit aligned)
  8599. +* @param[in] src Buffer source address
  8600. +* @param[in] len Number of bytes to copy
  8601. +*/
  8602. +void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len)
  8603. +{
  8604. + u32 len32 = len >> 2;
  8605. + int i;
  8606. +
  8607. + for (i = 0; i < len32; i++, src += 4, dst += 4)
  8608. + class_bus_write(*(u32 *)src, dst, 4);
  8609. +
  8610. + if (len & 0x2)
  8611. + {
  8612. + class_bus_write(*(u16 *)src, dst, 2);
  8613. + src += 2;
  8614. + dst += 2;
  8615. + }
  8616. +
  8617. + if (len & 0x1)
  8618. + {
  8619. + class_bus_write(*(u8 *)src, dst, 1);
  8620. + src++;
  8621. + dst++;
  8622. + }
  8623. +}
  8624. +
  8625. +/** Writes value to the cluster memory (PE_LMEM)
  8626. +* @param[in] dst PE LMEM destination address (must be 32bit aligned)
  8627. +* @param[in] val Value to write
  8628. +* @param[in] len Number of bytes to write
  8629. +*/
  8630. +void class_pe_lmem_memset(u32 dst, int val, unsigned int len)
  8631. +{
  8632. + u32 len32 = len >> 2;
  8633. + int i;
  8634. +
  8635. + val = val | (val << 8) | (val << 16) | (val << 24);
  8636. +
  8637. + for (i = 0; i < len32; i++, dst += 4)
  8638. + class_bus_write(val, dst, 4);
  8639. +
  8640. + if (len & 0x2)
  8641. + {
  8642. + class_bus_write(val, dst, 2);
  8643. + dst += 2;
  8644. + }
  8645. +
  8646. + if (len & 0x1)
  8647. + {
  8648. + class_bus_write(val, dst, 1);
  8649. + dst++;
  8650. + }
  8651. +}
  8652. +
  8653. +#if !defined(CONFIG_UTIL_DISABLED)
  8654. +
  8655. +/** Writes UTIL program memory (DDR) from the host.
  8656. + *
  8657. + * @param[in] addr Address to write (virtual, must be aligned on size)
  8658. + * @param[in] val Value to write (in PE endianess, i.e BE)
  8659. + * @param[in] size Number of bytes to write (2 or 4)
  8660. + */
  8661. +static void util_pmem_write(u32 val, void *addr, u8 size)
  8662. +{
  8663. + void *addr64 = (void *)((unsigned long)addr & ~0x7);
  8664. + unsigned long off = 8 - ((unsigned long)addr & 0x7) - size;
  8665. +
  8666. + //IMEM should be loaded as a 64bit swapped value in a 64bit aligned location
  8667. + if (size == 4)
  8668. + writel(be32_to_cpu(val), addr64 + off);
  8669. + else
  8670. + writew(be16_to_cpu((u16)val), addr64 + off);
  8671. +}
  8672. +
  8673. +
  8674. +/** Writes a buffer to UTIL program memory (DDR) from the host.
  8675. + *
  8676. + * @param[in] dst Address to write (virtual, must be at least 16bit aligned)
  8677. + * @param[in] src Buffer to write (in PE endianess, i.e BE, must have same alignment as dst)
  8678. + * @param[in] len Number of bytes to write (must be at least 16bit aligned)
  8679. + */
  8680. +static void util_pmem_memcpy(void *dst, const void *src, unsigned int len)
  8681. +{
  8682. + unsigned int len32;
  8683. + int i;
  8684. +
  8685. + if ((unsigned long)src & 0x2) {
  8686. + util_pmem_write(*(u16 *)src, dst, 2);
  8687. + src += 2;
  8688. + dst += 2;
  8689. + len -= 2;
  8690. + }
  8691. +
  8692. + len32 = len >> 2;
  8693. +
  8694. + for (i = 0; i < len32; i++, dst += 4, src += 4)
  8695. + util_pmem_write(*(u32 *)src, dst, 4);
  8696. +
  8697. + if (len & 0x2)
  8698. + util_pmem_write(*(u16 *)src, dst, len & 0x2);
  8699. +}
  8700. +#endif
  8701. +
  8702. +/** Loads an elf section into pmem
  8703. + * Code needs to be at least 16bit aligned and only PROGBITS sections are supported
  8704. + *
  8705. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., TMU3_ID)
  8706. + * @param[in] data pointer to the elf firmware
  8707. + * @param[in] shdr pointer to the elf section header
  8708. + *
  8709. + */
  8710. +static int pe_load_pmem_section(int id, const void *data, Elf32_Shdr *shdr)
  8711. +{
  8712. + u32 offset = be32_to_cpu(shdr->sh_offset);
  8713. + u32 addr = be32_to_cpu(shdr->sh_addr);
  8714. + u32 size = be32_to_cpu(shdr->sh_size);
  8715. + u32 type = be32_to_cpu(shdr->sh_type);
  8716. +
  8717. +#if !defined(CONFIG_UTIL_DISABLED)
  8718. + if (id == UTIL_ID)
  8719. + {
  8720. + printk(KERN_ERR "%s: unsuported pmem section for UTIL\n", __func__);
  8721. + return -EINVAL;
  8722. + }
  8723. +#endif
  8724. +
  8725. + if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3))
  8726. + {
  8727. + printk(KERN_ERR "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
  8728. + __func__, addr, (unsigned long) data + offset);
  8729. +
  8730. + return -EINVAL;
  8731. + }
  8732. +
  8733. + if (addr & 0x1)
  8734. + {
  8735. + printk(KERN_ERR "%s: load address(%x) is not 16bit aligned\n", __func__, addr);
  8736. + return -EINVAL;
  8737. + }
  8738. +
  8739. + if (size & 0x1)
  8740. + {
  8741. + printk(KERN_ERR "%s: load size(%x) is not 16bit aligned\n", __func__, size);
  8742. + return -EINVAL;
  8743. + }
  8744. +
  8745. + switch (type)
  8746. + {
  8747. + case SHT_PROGBITS:
  8748. + pe_pmem_memcpy_to32(id, addr, data + offset, size);
  8749. +
  8750. + break;
  8751. +
  8752. + default:
  8753. + printk(KERN_ERR "%s: unsuported section type(%x)\n", __func__, type);
  8754. + return -EINVAL;
  8755. + break;
  8756. + }
  8757. +
  8758. + return 0;
  8759. +}
  8760. +
  8761. +
  8762. +/** Loads an elf section into dmem
  8763. + * Data needs to be at least 32bit aligned, NOBITS sections are correctly initialized to 0
  8764. + *
  8765. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., UTIL_ID)
  8766. + * @param[in] data pointer to the elf firmware
  8767. + * @param[in] shdr pointer to the elf section header
  8768. + *
  8769. + */
  8770. +static int pe_load_dmem_section(int id, const void *data, Elf32_Shdr *shdr)
  8771. +{
  8772. + u32 offset = be32_to_cpu(shdr->sh_offset);
  8773. + u32 addr = be32_to_cpu(shdr->sh_addr);
  8774. + u32 size = be32_to_cpu(shdr->sh_size);
  8775. + u32 type = be32_to_cpu(shdr->sh_type);
  8776. + u32 size32 = size >> 2;
  8777. + int i;
  8778. +
  8779. + if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3))
  8780. + {
  8781. + printk(KERN_ERR "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
  8782. + __func__, addr, (unsigned long)data + offset);
  8783. +
  8784. + return -EINVAL;
  8785. + }
  8786. +
  8787. + if (addr & 0x3)
  8788. + {
  8789. + printk(KERN_ERR "%s: load address(%x) is not 32bit aligned\n", __func__, addr);
  8790. + return -EINVAL;
  8791. + }
  8792. +
  8793. + switch (type)
  8794. + {
  8795. + case SHT_PROGBITS:
  8796. + pe_dmem_memcpy_to32(id, addr, data + offset, size);
  8797. + break;
  8798. +
  8799. + case SHT_NOBITS:
  8800. + for (i = 0; i < size32; i++, addr += 4)
  8801. + pe_dmem_write(id, 0, addr, 4);
  8802. +
  8803. + if (size & 0x3)
  8804. + pe_dmem_write(id, 0, addr, size & 0x3);
  8805. +
  8806. + break;
  8807. +
  8808. + default:
  8809. + printk(KERN_ERR "%s: unsuported section type(%x)\n", __func__, type);
  8810. + return -EINVAL;
  8811. + break;
  8812. + }
  8813. +
  8814. + return 0;
  8815. +}
  8816. +
  8817. +
  8818. +/** Loads an elf section into DDR
  8819. + * Data needs to be at least 32bit aligned, NOBITS sections are correctly initialized to 0
  8820. + *
  8821. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., UTIL_ID)
  8822. + * @param[in] data pointer to the elf firmware
  8823. + * @param[in] shdr pointer to the elf section header
  8824. + *
  8825. + */
  8826. +static int pe_load_ddr_section(int id, const void *data, Elf32_Shdr *shdr, struct device *dev)
  8827. +{
  8828. + u32 offset = be32_to_cpu(shdr->sh_offset);
  8829. + u32 addr = be32_to_cpu(shdr->sh_addr);
  8830. + u32 size = be32_to_cpu(shdr->sh_size);
  8831. + u32 type = be32_to_cpu(shdr->sh_type);
  8832. + u32 flags = be32_to_cpu(shdr->sh_flags);
  8833. +
  8834. + switch (type)
  8835. + {
  8836. + case SHT_PROGBITS:
  8837. + if (flags & SHF_EXECINSTR)
  8838. + {
  8839. + if (id <= CLASS_MAX_ID)
  8840. + {
  8841. + /* DO the loading only once in DDR */
  8842. + if (id == CLASS0_ID)
  8843. + {
  8844. + printk(KERN_ERR "%s: load address(%x) and elf file address(%lx) rcvd\n", __func__, addr, (unsigned long)data + offset);
  8845. + if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3))
  8846. + {
  8847. + printk(KERN_ERR "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
  8848. + __func__, addr, (unsigned long)data + offset);
  8849. +
  8850. + return -EINVAL;
  8851. + }
  8852. +
  8853. + if (addr & 0x1)
  8854. + {
  8855. + printk(KERN_ERR "%s: load address(%x) is not 16bit aligned\n", __func__, addr);
  8856. + return -EINVAL;
  8857. + }
  8858. +
  8859. + if (size & 0x1)
  8860. + {
  8861. + printk(KERN_ERR "%s: load length(%x) is not 16bit aligned\n", __func__, size);
  8862. + return -EINVAL;
  8863. + }
  8864. + memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data + offset, size);
  8865. + }
  8866. + }
  8867. +#if !defined(CONFIG_UTIL_DISABLED)
  8868. + else if (id == UTIL_ID)
  8869. + {
  8870. + if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3))
  8871. + {
  8872. + printk(KERN_ERR "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
  8873. + __func__, addr, (unsigned long)data + offset);
  8874. +
  8875. + return -EINVAL;
  8876. + }
  8877. +
  8878. + if (addr & 0x1)
  8879. + {
  8880. + printk(KERN_ERR "%s: load address(%x) is not 16bit aligned\n", __func__, addr);
  8881. + return -EINVAL;
  8882. + }
  8883. +
  8884. + if (size & 0x1)
  8885. + {
  8886. + printk(KERN_ERR "%s: load length(%x) is not 16bit aligned\n", __func__, size);
  8887. + return -EINVAL;
  8888. + }
  8889. +
  8890. + util_pmem_memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data + offset, size);
  8891. + }
  8892. +#endif
  8893. + else
  8894. + {
  8895. + printk(KERN_ERR "%s: unsuported ddr section type(%x) for PE(%d)\n", __func__, type, id);
  8896. + return -EINVAL;
  8897. + }
  8898. +
  8899. + }
  8900. + else
  8901. + {
  8902. + memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data + offset, size);
  8903. + }
  8904. +
  8905. + break;
  8906. +
  8907. + case SHT_NOBITS:
  8908. + memset(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), 0, size);
  8909. +
  8910. + break;
  8911. +
  8912. + default:
  8913. + printk(KERN_ERR "%s: unsuported section type(%x)\n", __func__, type);
  8914. + return -EINVAL;
  8915. + break;
  8916. + }
  8917. +
  8918. + return 0;
  8919. +}
  8920. +
  8921. +
  8922. +/** Loads an elf section into pe lmem
  8923. + * Data needs to be at least 32bit aligned, NOBITS sections are correctly initialized to 0
  8924. + *
  8925. + * @param[in] id PE identification (CLASS0_ID,..., CLASS5_ID)
  8926. + * @param[in] data pointer to the elf firmware
  8927. + * @param[in] shdr pointer to the elf section header
  8928. + *
  8929. + */
  8930. +static int pe_load_pe_lmem_section(int id, const void *data, Elf32_Shdr *shdr)
  8931. +{
  8932. + u32 offset = be32_to_cpu(shdr->sh_offset);
  8933. + u32 addr = be32_to_cpu(shdr->sh_addr);
  8934. + u32 size = be32_to_cpu(shdr->sh_size);
  8935. + u32 type = be32_to_cpu(shdr->sh_type);
  8936. +
  8937. + if (id > CLASS_MAX_ID)
  8938. + {
  8939. + printk(KERN_ERR "%s: unsuported pe-lmem section type(%x) for PE(%d)\n", __func__, type, id);
  8940. + return -EINVAL;
  8941. + }
  8942. +
  8943. + if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3))
  8944. + {
  8945. + printk(KERN_ERR "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
  8946. + __func__, addr, (unsigned long)data + offset);
  8947. +
  8948. + return -EINVAL;
  8949. + }
  8950. +
  8951. + if (addr & 0x3)
  8952. + {
  8953. + printk(KERN_ERR "%s: load address(%x) is not 32bit aligned\n", __func__, addr);
  8954. + return -EINVAL;
  8955. + }
  8956. +
  8957. + switch (type)
  8958. + {
  8959. + case SHT_PROGBITS:
  8960. + class_pe_lmem_memcpy_to32(addr, data + offset, size);
  8961. + break;
  8962. +
  8963. + case SHT_NOBITS:
  8964. + class_pe_lmem_memset(addr, 0, size);
  8965. + break;
  8966. +
  8967. + default:
  8968. + printk(KERN_ERR "%s: unsuported section type(%x)\n", __func__, type);
  8969. + return -EINVAL;
  8970. + break;
  8971. + }
  8972. +
  8973. + return 0;
  8974. +}
  8975. +
  8976. +
  8977. +/** Loads an elf section into a PE
  8978. + * For now only supports loading a section to dmem (all PE's), pmem (class and tmu PE's),
  8979. + * DDDR (util PE code)
  8980. + *
  8981. + * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., UTIL_ID)
  8982. + * @param[in] data pointer to the elf firmware
  8983. + * @param[in] shdr pointer to the elf section header
  8984. + *
  8985. + */
  8986. +int pe_load_elf_section(int id, const void *data, Elf32_Shdr *shdr, struct device *dev)
  8987. +{
  8988. + u32 addr = be32_to_cpu(shdr->sh_addr);
  8989. + u32 size = be32_to_cpu(shdr->sh_size);
  8990. +
  8991. + if (IS_DMEM(addr, size))
  8992. + return pe_load_dmem_section(id, data, shdr);
  8993. + else if (IS_PMEM(addr, size))
  8994. + return pe_load_pmem_section(id, data, shdr);
  8995. + else if (IS_PFE_LMEM(addr, size))
  8996. + return 0; /* FIXME */
  8997. + else if (IS_PHYS_DDR(addr, size))
  8998. + return pe_load_ddr_section(id, data, shdr, dev);
  8999. + else if (IS_PE_LMEM(addr, size))
  9000. + return pe_load_pe_lmem_section(id, data, shdr);
  9001. + else {
  9002. + printk(KERN_ERR "%s: unsuported memory range(%x)\n", __func__, addr);
  9003. +// return -EINVAL;
  9004. + }
  9005. +
  9006. + return 0;
  9007. +}
  9008. +
  9009. +
  9010. +/**************************** BMU ***************************/
  9011. +
  9012. +/** Initializes a BMU block.
  9013. +* @param[in] base BMU block base address
  9014. +* @param[in] cfg BMU configuration
  9015. +*/
  9016. +void bmu_init(void *base, BMU_CFG *cfg)
  9017. +{
  9018. + bmu_disable(base);
  9019. +
  9020. + bmu_set_config(base, cfg);
  9021. +
  9022. + bmu_reset(base);
  9023. +}
  9024. +
  9025. +/** Resets a BMU block.
  9026. +* @param[in] base BMU block base address
  9027. +*/
  9028. +void bmu_reset(void *base)
  9029. +{
  9030. + writel(CORE_SW_RESET, base + BMU_CTRL);
  9031. +
  9032. + /* Wait for self clear */
  9033. + while (readl(base + BMU_CTRL) & CORE_SW_RESET) ;
  9034. +}
  9035. +
  9036. +/** Enabled a BMU block.
  9037. +* @param[in] base BMU block base address
  9038. +*/
  9039. +void bmu_enable(void *base)
  9040. +{
  9041. + writel (CORE_ENABLE, base + BMU_CTRL);
  9042. +}
  9043. +
  9044. +/** Disables a BMU block.
  9045. +* @param[in] base BMU block base address
  9046. +*/
  9047. +void bmu_disable(void *base)
  9048. +{
  9049. + writel (CORE_DISABLE, base + BMU_CTRL);
  9050. +}
  9051. +
  9052. +/** Sets the configuration of a BMU block.
  9053. +* @param[in] base BMU block base address
  9054. +* @param[in] cfg BMU configuration
  9055. +*/
  9056. +void bmu_set_config(void *base, BMU_CFG *cfg)
  9057. +{
  9058. + writel (cfg->baseaddr, base + BMU_UCAST_BASE_ADDR);
  9059. + writel (cfg->count & 0xffff, base + BMU_UCAST_CONFIG);
  9060. + writel (cfg->size & 0xffff, base + BMU_BUF_SIZE);
  9061. +// writel (BMU1_THRES_CNT, base + BMU_THRES);
  9062. +
  9063. + /* Interrupts are never used */
  9064. +// writel (0x0, base + BMU_INT_SRC);
  9065. + writel (0x0, base + BMU_INT_ENABLE);
  9066. +}
  9067. +#if defined(CONFIG_PLATFORM_C2000)
  9068. +/**************************** GEMAC ***************************/
  9069. +
  9070. +/** Enable Rx Checksum Engine. With this enabled, Frame with bad IP,
  9071. + * TCP or UDP checksums are discarded
  9072. + *
  9073. + * @param[in] base GEMAC base address.
  9074. + */
  9075. +void gemac_enable_rx_checksum_offload(void *base)
  9076. +{
  9077. + writel(readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_CHKSUM_RX, base + EMAC_NETWORK_CONFIG);
  9078. + writel(readl(CLASS_L4_CHKSUM_ADDR) | IPV4_CHKSUM_DROP, CLASS_L4_CHKSUM_ADDR);
  9079. +}
  9080. +
  9081. +/** Disable Rx Checksum Engine.
  9082. + *
  9083. + * @param[in] base GEMAC base address.
  9084. + */
  9085. +void gemac_disable_rx_checksum_offload(void *base)
  9086. +{
  9087. + writel(readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_CHKSUM_RX, base + EMAC_NETWORK_CONFIG);
  9088. + writel(readl(CLASS_L4_CHKSUM_ADDR) & ~IPV4_CHKSUM_DROP, CLASS_L4_CHKSUM_ADDR);
  9089. +}
  9090. +
  9091. +/** Setup the MII Mgmt clock speed.
  9092. + * @param[in] base GEMAC base address (GEMAC0, GEMAC1, GEMAC2)
  9093. + * @param[in] mdc_div MII clock dividor
  9094. + */
  9095. +void gemac_set_mdc_div(void *base, int mdc_div)
  9096. +{
  9097. + u32 val = readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_MDC_DIV_MASK;
  9098. + u32 div;
  9099. +
  9100. + switch (mdc_div) {
  9101. + case 8:
  9102. + div = 0;
  9103. + break;
  9104. +
  9105. + case 16:
  9106. + div = 1;
  9107. + break;
  9108. +
  9109. + case 32:
  9110. + div = 2;
  9111. + break;
  9112. +
  9113. + case 48:
  9114. + div = 3;
  9115. + break;
  9116. +
  9117. + default:
  9118. + case 64:
  9119. + div = 4;
  9120. + break;
  9121. +
  9122. + case 96:
  9123. + div = 5;
  9124. + break;
  9125. +
  9126. + case 128:
  9127. + div = 6;
  9128. + break;
  9129. +
  9130. + case 224:
  9131. + div = 7;
  9132. + break;
  9133. + }
  9134. +
  9135. + val |= div << 18;
  9136. +
  9137. + writel(val, base + EMAC_NETWORK_CONFIG);
  9138. +}
  9139. +
  9140. +/** GEMAC set speed.
  9141. +* @param[in] base GEMAC base address
  9142. +* @param[in] speed GEMAC speed (10, 100 or 1000 Mbps)
  9143. +*/
  9144. +void gemac_set_speed(void *base, MAC_SPEED gem_speed)
  9145. +{
  9146. + u32 val = readl(base + EMAC_NETWORK_CONFIG);
  9147. +
  9148. + val = val & ~EMAC_SPEED_MASK;
  9149. +
  9150. + switch (gem_speed)
  9151. + {
  9152. + case SPEED_10M:
  9153. + val &= (~EMAC_PCS_ENABLE);
  9154. + break;
  9155. +
  9156. + case SPEED_100M:
  9157. + val = val | EMAC_SPEED_100;
  9158. + val &= (~EMAC_PCS_ENABLE);
  9159. + break;
  9160. +
  9161. + case SPEED_1000M:
  9162. + val = val | EMAC_SPEED_1000;
  9163. + val &= (~EMAC_PCS_ENABLE);
  9164. + break;
  9165. +
  9166. + case SPEED_1000M_PCS:
  9167. + val = val | EMAC_SPEED_1000;
  9168. + val |= EMAC_PCS_ENABLE;
  9169. + break;
  9170. +
  9171. + default:
  9172. + val = val | EMAC_SPEED_100;
  9173. + val &= (~EMAC_PCS_ENABLE);
  9174. + break;
  9175. + }
  9176. +
  9177. + writel (val, base + EMAC_NETWORK_CONFIG);
  9178. +}
  9179. +
  9180. +/** GEMAC set duplex.
  9181. +* @param[in] base GEMAC base address
  9182. +* @param[in] duplex GEMAC duplex mode (Full, Half)
  9183. +*/
  9184. +void gemac_set_duplex(void *base, int duplex)
  9185. +{
  9186. + u32 val = readl(base + EMAC_NETWORK_CONFIG);
  9187. +
  9188. + if (duplex == DUPLEX_HALF)
  9189. + val = (val & ~EMAC_DUPLEX_MASK) | EMAC_HALF_DUP;
  9190. + else
  9191. + val = (val & ~EMAC_DUPLEX_MASK) | EMAC_FULL_DUP;
  9192. +
  9193. + writel (val, base + EMAC_NETWORK_CONFIG);
  9194. +}
  9195. +
  9196. +/** GEMAC set mode.
  9197. +* @param[in] base GEMAC base address
  9198. +* @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII)
  9199. +*/
  9200. +
  9201. +#if defined(CONFIG_IP_ALIGNED)
  9202. +#define IP_ALIGNED_BITVAL EMAC_TWO_BYTES_IP_ALIGN
  9203. +#else
  9204. +#define IP_ALIGNED_BITVAL 0
  9205. +#endif
  9206. +
  9207. +void gemac_set_mode(void *base, int mode)
  9208. +{
  9209. + switch (mode)
  9210. + {
  9211. + case GMII:
  9212. + writel ((readl(base + EMAC_CONTROL) & ~EMAC_MODE_MASK) | EMAC_GMII_MODE_ENABLE | IP_ALIGNED_BITVAL, base + EMAC_CONTROL);
  9213. + writel (readl(base + EMAC_NETWORK_CONFIG) & (~EMAC_SGMII_MODE_ENABLE), base + EMAC_NETWORK_CONFIG);
  9214. + break;
  9215. +
  9216. + case RGMII:
  9217. + writel ((readl(base + EMAC_CONTROL) & ~EMAC_MODE_MASK) | EMAC_RGMII_MODE_ENABLE | IP_ALIGNED_BITVAL, base + EMAC_CONTROL);
  9218. + writel (readl(base + EMAC_NETWORK_CONFIG) & (~EMAC_SGMII_MODE_ENABLE), base + EMAC_NETWORK_CONFIG);
  9219. + break;
  9220. +
  9221. + case RMII:
  9222. + writel ((readl(base + EMAC_CONTROL) & ~EMAC_MODE_MASK) | EMAC_RMII_MODE_ENABLE | IP_ALIGNED_BITVAL, base + EMAC_CONTROL);
  9223. + writel (readl(base + EMAC_NETWORK_CONFIG) & (~EMAC_SGMII_MODE_ENABLE), base + EMAC_NETWORK_CONFIG);
  9224. + break;
  9225. +
  9226. + case MII:
  9227. + writel ((readl(base + EMAC_CONTROL) & ~EMAC_MODE_MASK) | EMAC_MII_MODE_ENABLE | IP_ALIGNED_BITVAL, base + EMAC_CONTROL);
  9228. + writel (readl(base + EMAC_NETWORK_CONFIG) & (~EMAC_SGMII_MODE_ENABLE), base + EMAC_NETWORK_CONFIG);
  9229. + break;
  9230. +
  9231. + case SGMII:
  9232. + writel ((readl(base + EMAC_CONTROL) & ~EMAC_MODE_MASK) | (EMAC_RMII_MODE_DISABLE | EMAC_RGMII_MODE_DISABLE) | IP_ALIGNED_BITVAL, base + EMAC_CONTROL);
  9233. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_SGMII_MODE_ENABLE, base + EMAC_NETWORK_CONFIG);
  9234. + break;
  9235. +
  9236. + default:
  9237. + writel ((readl(base + EMAC_CONTROL) & ~EMAC_MODE_MASK) | EMAC_MII_MODE_ENABLE | IP_ALIGNED_BITVAL, base + EMAC_CONTROL);
  9238. + writel (readl(base + EMAC_NETWORK_CONFIG) & (~EMAC_SGMII_MODE_ENABLE), base + EMAC_NETWORK_CONFIG);
  9239. + break;
  9240. + }
  9241. +}
  9242. +/** GEMAC Enable MDIO: Activate the Management interface. This is required to program the PHY
  9243. + * @param[in] base GEMAC base address
  9244. + */
  9245. +void gemac_enable_mdio(void *base)
  9246. +{
  9247. + u32 data;
  9248. +
  9249. + data = readl(base + EMAC_NETWORK_CONTROL);
  9250. + data |= EMAC_MDIO_EN;
  9251. + writel(data, base + EMAC_NETWORK_CONTROL);
  9252. +}
  9253. +
  9254. +/** GEMAC Disable MDIO: Disable the Management interface.
  9255. + * @param[in] base GEMAC base address
  9256. + */
  9257. +void gemac_disable_mdio(void *base)
  9258. +{
  9259. + u32 data;
  9260. +
  9261. + data = readl(base + EMAC_NETWORK_CONTROL);
  9262. + data &= ~EMAC_MDIO_EN;
  9263. + writel(data, base + EMAC_NETWORK_CONTROL);
  9264. +}
  9265. +
  9266. +
  9267. +/** GEMAC reset function.
  9268. +* @param[in] base GEMAC base address
  9269. +*/
  9270. +void gemac_reset(void *base)
  9271. +{
  9272. +}
  9273. +
  9274. +/** GEMAC enable function.
  9275. +* @param[in] base GEMAC base address
  9276. +*/
  9277. +void gemac_enable(void *base)
  9278. +{
  9279. + writel (readl(base + EMAC_NETWORK_CONTROL) | EMAC_TX_ENABLE | EMAC_RX_ENABLE, base + EMAC_NETWORK_CONTROL);
  9280. +}
  9281. +
  9282. +/** GEMAC disable function.
  9283. +* @param[in] base GEMAC base address
  9284. +*/
  9285. +void gemac_disable(void *base)
  9286. +{
  9287. + writel (readl(base + EMAC_NETWORK_CONTROL) & ~(EMAC_TX_ENABLE | EMAC_RX_ENABLE), base + EMAC_NETWORK_CONTROL);
  9288. +}
  9289. +
  9290. +/** GEMAC TX disable function.
  9291. +* @param[in] base GEMAC base address
  9292. +*/
  9293. +void gemac_tx_disable(void *base)
  9294. +{
  9295. + writel (readl(base + EMAC_NETWORK_CONTROL) & ~(EMAC_TX_ENABLE), base + EMAC_NETWORK_CONTROL);
  9296. +}
  9297. +
  9298. +/** GEMAC set mac address configuration.
  9299. +* @param[in] base GEMAC base address
  9300. +* @param[in] addr MAC address to be configured
  9301. +*/
  9302. +void gemac_set_address(void *base, SPEC_ADDR *addr)
  9303. +{
  9304. + writel(addr->one.bottom, base + EMAC_SPEC1_ADD_BOT);
  9305. + writel(addr->one.top, base + EMAC_SPEC1_ADD_TOP);
  9306. + writel(addr->two.bottom, base + EMAC_SPEC2_ADD_BOT);
  9307. + writel(addr->two.top, base + EMAC_SPEC2_ADD_TOP);
  9308. + writel(addr->three.bottom, base + EMAC_SPEC3_ADD_BOT);
  9309. + writel(addr->three.top, base + EMAC_SPEC3_ADD_TOP);
  9310. + writel(addr->four.bottom, base + EMAC_SPEC4_ADD_BOT);
  9311. + writel(addr->four.top, base + EMAC_SPEC4_ADD_TOP);
  9312. +}
  9313. +
  9314. +/** GEMAC get mac address configuration.
  9315. +* @param[in] base GEMAC base address
  9316. +*
  9317. +* @return MAC addresses configured
  9318. +*/
  9319. +SPEC_ADDR gemac_get_address(void *base)
  9320. +{
  9321. + SPEC_ADDR addr;
  9322. +
  9323. + addr.one.bottom = readl(base + EMAC_SPEC1_ADD_BOT);
  9324. + addr.one.top = readl(base + EMAC_SPEC1_ADD_TOP);
  9325. + addr.two.bottom = readl(base + EMAC_SPEC2_ADD_BOT);
  9326. + addr.two.top = readl(base + EMAC_SPEC2_ADD_TOP);
  9327. + addr.three.bottom = readl(base + EMAC_SPEC3_ADD_BOT);
  9328. + addr.three.top = readl(base + EMAC_SPEC3_ADD_TOP);
  9329. + addr.four.bottom = readl(base + EMAC_SPEC4_ADD_BOT);
  9330. + addr.four.top = readl(base + EMAC_SPEC4_ADD_TOP);
  9331. +
  9332. + return addr;
  9333. +}
  9334. +
  9335. +/** Sets the hash register of the MAC.
  9336. + * This register is used for matching unicast and multicast frames.
  9337. + *
  9338. + * @param[in] base GEMAC base address.
  9339. + * @param[in] hash 64-bit hash to be configured.
  9340. + */
  9341. +void gemac_set_hash( void *base, MAC_ADDR *hash )
  9342. +{
  9343. + writel(hash->bottom, base + EMAC_HASH_BOT);
  9344. + writel(hash->top, base + EMAC_HASH_TOP);
  9345. +}
  9346. +
  9347. +/** Get the current value hash register of the MAC.
  9348. + * This register is used for matching unicast and multicast frames.
  9349. + *
  9350. + * @param[in] base GEMAC base address
  9351. +
  9352. + * @returns 64-bit hash.
  9353. + */
  9354. +MAC_ADDR gemac_get_hash( void *base )
  9355. +{
  9356. + MAC_ADDR hash;
  9357. +
  9358. + hash.bottom = readl(base + EMAC_HASH_BOT);
  9359. + hash.top = readl(base + EMAC_HASH_TOP);
  9360. +
  9361. + return hash;
  9362. +}
  9363. +
  9364. +/** GEMAC set specific local addresses of the MAC.
  9365. +* Rather than setting up all four specific addresses, this function sets them up individually.
  9366. +*
  9367. +* @param[in] base GEMAC base address
  9368. +* @param[in] addr MAC address to be configured
  9369. +*/
  9370. +void gemac_set_laddr1(void *base, MAC_ADDR *address)
  9371. +{
  9372. + writel(address->bottom, base + EMAC_SPEC1_ADD_BOT);
  9373. + writel(address->top, base + EMAC_SPEC1_ADD_TOP);
  9374. +}
  9375. +
  9376. +
  9377. +void gemac_set_laddr2(void *base, MAC_ADDR *address)
  9378. +{
  9379. + writel(address->bottom, base + EMAC_SPEC2_ADD_BOT);
  9380. + writel(address->top, base + EMAC_SPEC2_ADD_TOP);
  9381. +}
  9382. +
  9383. +
  9384. +void gemac_set_laddr3(void *base, MAC_ADDR *address)
  9385. +{
  9386. + writel(address->bottom, base + EMAC_SPEC3_ADD_BOT);
  9387. + writel(address->top, base + EMAC_SPEC3_ADD_TOP);
  9388. +}
  9389. +
  9390. +
  9391. +void gemac_set_laddr4(void *base, MAC_ADDR *address)
  9392. +{
  9393. + writel(address->bottom, base + EMAC_SPEC4_ADD_BOT);
  9394. + writel(address->top, base + EMAC_SPEC4_ADD_TOP);
  9395. +}
  9396. +
  9397. +void gemac_set_laddrN(void *base, MAC_ADDR *address, unsigned int entry_index)
  9398. +{
  9399. + if( (entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX) )
  9400. + return;
  9401. +
  9402. + entry_index = entry_index - 1;
  9403. +
  9404. + if (entry_index < 4)
  9405. + {
  9406. + writel(address->bottom, base + (entry_index * 8) + EMAC_SPEC1_ADD_BOT);
  9407. + writel(address->top, base + (entry_index * 8) + EMAC_SPEC1_ADD_TOP);
  9408. + }
  9409. + else
  9410. + {
  9411. + writel(address->bottom, base + ((entry_index - 4) * 8) + EMAC_SPEC5_ADD_BOT);
  9412. + writel(address->top, base + ((entry_index - 4) * 8) + EMAC_SPEC5_ADD_TOP);
  9413. + }
  9414. +}
  9415. +
  9416. +/** Get specific local addresses of the MAC.
  9417. +* This allows returning of a single specific address stored in the MAC.
  9418. +* @param[in] base GEMAC base address
  9419. +*
  9420. +* @return Specific MAC address 1
  9421. +*
  9422. +*/
  9423. +MAC_ADDR gem_get_laddr1(void *base)
  9424. +{
  9425. + MAC_ADDR addr;
  9426. + addr.bottom = readl(base + EMAC_SPEC1_ADD_BOT);
  9427. + addr.top = readl(base + EMAC_SPEC1_ADD_TOP);
  9428. + return addr;
  9429. +}
  9430. +
  9431. +
  9432. +MAC_ADDR gem_get_laddr2(void *base)
  9433. +{
  9434. + MAC_ADDR addr;
  9435. + addr.bottom = readl(base + EMAC_SPEC2_ADD_BOT);
  9436. + addr.top = readl(base + EMAC_SPEC2_ADD_TOP);
  9437. + return addr;
  9438. +}
  9439. +
  9440. +
  9441. +MAC_ADDR gem_get_laddr3(void *base)
  9442. +{
  9443. + MAC_ADDR addr;
  9444. + addr.bottom = readl(base + EMAC_SPEC3_ADD_BOT);
  9445. + addr.top = readl(base + EMAC_SPEC3_ADD_TOP);
  9446. + return addr;
  9447. +}
  9448. +
  9449. +
  9450. +MAC_ADDR gem_get_laddr4(void *base)
  9451. +{
  9452. + MAC_ADDR addr;
  9453. + addr.bottom = readl(base + EMAC_SPEC4_ADD_BOT);
  9454. + addr.top = readl(base + EMAC_SPEC4_ADD_TOP);
  9455. + return addr;
  9456. +}
  9457. +
  9458. +MAC_ADDR gem_get_laddrN(void *base, unsigned int entry_index)
  9459. +{
  9460. + MAC_ADDR addr = {0xffffffff, 0xffffffff};
  9461. +
  9462. + if( (entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX) )
  9463. + return addr;
  9464. +
  9465. + entry_index = entry_index - 1;
  9466. +
  9467. + if (entry_index < 4)
  9468. + {
  9469. + addr.bottom = readl(base + (entry_index * 8) + EMAC_SPEC1_ADD_BOT);
  9470. + addr.top = readl(base + (entry_index * 8) + EMAC_SPEC1_ADD_TOP);
  9471. + }
  9472. + else
  9473. + {
  9474. + addr.bottom = readl(base + ((entry_index - 4) * 8) + EMAC_SPEC5_ADD_BOT);
  9475. + addr.top = readl(base + ((entry_index - 4) * 8) + EMAC_SPEC5_ADD_TOP);
  9476. + }
  9477. +
  9478. + return addr;
  9479. +}
  9480. +
  9481. +/** Clear specific local addresses of the MAC.
  9482. + * @param[in] base GEMAC base address
  9483. + */
  9484. +
  9485. +void gemac_clear_laddr1(void *base)
  9486. +{
  9487. + writel(0, base + EMAC_SPEC1_ADD_BOT);
  9488. +}
  9489. +
  9490. +void gemac_clear_laddr2(void *base)
  9491. +{
  9492. + writel(0, base + EMAC_SPEC2_ADD_BOT);
  9493. +}
  9494. +
  9495. +void gemac_clear_laddr3(void *base)
  9496. +{
  9497. + writel(0, base + EMAC_SPEC3_ADD_BOT);
  9498. +}
  9499. +
  9500. +void gemac_clear_laddr4(void *base)
  9501. +{
  9502. + writel(0, base + EMAC_SPEC4_ADD_BOT);
  9503. +}
  9504. +
  9505. +void gemac_clear_laddrN(void *base, unsigned int entry_index)
  9506. +{
  9507. + if( (entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX) )
  9508. + return;
  9509. +
  9510. + entry_index = entry_index - 1;
  9511. +
  9512. + if ( entry_index < 4 )
  9513. + writel(0, base + (entry_index * 8) + EMAC_SPEC1_ADD_BOT);
  9514. + else
  9515. + writel(0, base + ((entry_index - 4) * 8) + EMAC_SPEC5_ADD_BOT);
  9516. +}
  9517. +
  9518. +/** Set the loopback mode of the MAC. This can be either no loopback for normal
  9519. + * operation, local loopback through MAC internal loopback module or PHY
  9520. + * loopback for external loopback through a PHY. This asserts the external loop
  9521. + * pin.
  9522. + *
  9523. + * @param[in] base GEMAC base address.
  9524. + * @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC Loopback,
  9525. + * LB_EXT - PHY Loopback.
  9526. + */
  9527. +void gemac_set_loop( void *base, MAC_LOOP gem_loop )
  9528. +{
  9529. + switch (gem_loop) {
  9530. + case LB_LOCAL:
  9531. + writel(readl(base + EMAC_NETWORK_CONTROL) & (~EMAC_LB_PHY),
  9532. + base + EMAC_NETWORK_CONTROL);
  9533. + writel(readl(base + EMAC_NETWORK_CONTROL) | (EMAC_LB_MAC),
  9534. + base + EMAC_NETWORK_CONTROL);
  9535. + break;
  9536. + case LB_EXT:
  9537. + writel(readl(base + EMAC_NETWORK_CONTROL) & (~EMAC_LB_MAC),
  9538. + base + EMAC_NETWORK_CONTROL);
  9539. + writel(readl(base + EMAC_NETWORK_CONTROL) | (EMAC_LB_PHY),
  9540. + base + EMAC_NETWORK_CONTROL);
  9541. + break;
  9542. + default:
  9543. + writel(readl(base + EMAC_NETWORK_CONTROL) & (~(EMAC_LB_MAC | EMAC_LB_PHY)),
  9544. + base + EMAC_NETWORK_CONTROL);
  9545. + }
  9546. +}
  9547. +
  9548. +/** GEMAC allow frames
  9549. + * @param[in] base GEMAC base address
  9550. + */
  9551. +void gemac_enable_copy_all(void *base)
  9552. +{
  9553. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_COPY_ALL, base + EMAC_NETWORK_CONFIG);
  9554. +}
  9555. +
  9556. +/** GEMAC do not allow frames
  9557. + * @param[in] base GEMAC base address
  9558. +*/
  9559. +void gemac_disable_copy_all(void *base)
  9560. +{
  9561. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_COPY_ALL, base + EMAC_NETWORK_CONFIG);
  9562. +}
  9563. +
  9564. +/** GEMAC allow broadcast function.
  9565. +* @param[in] base GEMAC base address
  9566. +*/
  9567. +void gemac_allow_broadcast(void *base)
  9568. +{
  9569. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_NO_BROADCAST, base + EMAC_NETWORK_CONFIG);
  9570. +}
  9571. +
  9572. +/** GEMAC no broadcast function.
  9573. +* @param[in] base GEMAC base address
  9574. +*/
  9575. +void gemac_no_broadcast(void *base)
  9576. +{
  9577. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_NO_BROADCAST, base + EMAC_NETWORK_CONFIG);
  9578. +}
  9579. +
  9580. +/** GEMAC enable unicast function.
  9581. +* @param[in] base GEMAC base address
  9582. +*/
  9583. +void gemac_enable_unicast(void *base)
  9584. +{
  9585. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_UNICAST, base + EMAC_NETWORK_CONFIG);
  9586. +}
  9587. +
  9588. +/** GEMAC disable unicast function.
  9589. +* @param[in] base GEMAC base address
  9590. +*/
  9591. +void gemac_disable_unicast(void *base)
  9592. +{
  9593. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_UNICAST, base + EMAC_NETWORK_CONFIG);
  9594. +}
  9595. +
  9596. +/** GEMAC enable multicast function.
  9597. +* @param[in] base GEMAC base address
  9598. +*/
  9599. +void gemac_enable_multicast(void *base)
  9600. +{
  9601. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_MULTICAST, base + EMAC_NETWORK_CONFIG);
  9602. +}
  9603. +
  9604. +/** GEMAC disable multicast function.
  9605. +* @param[in] base GEMAC base address
  9606. +*/
  9607. +void gemac_disable_multicast(void *base)
  9608. +{
  9609. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_MULTICAST, base + EMAC_NETWORK_CONFIG);
  9610. +}
  9611. +
  9612. +/** GEMAC enable fcs rx function.
  9613. +* @param[in] base GEMAC base address
  9614. +*/
  9615. +void gemac_enable_fcs_rx(void *base)
  9616. +{
  9617. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_FCS_RX, base + EMAC_NETWORK_CONFIG);
  9618. +}
  9619. +
  9620. +/** GEMAC disable fcs rx function.
  9621. +* @param[in] base GEMAC base address
  9622. +*/
  9623. +void gemac_disable_fcs_rx(void *base)
  9624. +{
  9625. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_FCS_RX, base + EMAC_NETWORK_CONFIG);
  9626. +}
  9627. +
  9628. +/** GEMAC enable 1536 rx function.
  9629. +* @param[in] base GEMAC base address
  9630. +*/
  9631. +void gemac_enable_1536_rx(void *base)
  9632. +{
  9633. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_1536_RX, base + EMAC_NETWORK_CONFIG);
  9634. +}
  9635. +
  9636. +/** GEMAC disable 1536 rx function.
  9637. +* @param[in] base GEMAC base address
  9638. +*/
  9639. +void gemac_disable_1536_rx(void *base)
  9640. +{
  9641. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_1536_RX, base + EMAC_NETWORK_CONFIG);
  9642. +}
  9643. +
  9644. +/** GEMAC enable jumbo function.
  9645. +* @param[in] base GEMAC base address
  9646. +*/
  9647. +void gemac_enable_rx_jmb(void *base)
  9648. +{
  9649. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_JUMBO_FRAME, base + EMAC_NETWORK_CONFIG);
  9650. +}
  9651. +
  9652. +/** GEMAC disable jumbo function.
  9653. +* @param[in] base GEMAC base address
  9654. +*/
  9655. +void gemac_disable_rx_jmb(void *base)
  9656. +{
  9657. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_JUMBO_FRAME, base + EMAC_NETWORK_CONFIG);
  9658. +}
  9659. +
  9660. +/** GEMAC enable stacked vlan function.
  9661. +* @param[in] base GEMAC base address
  9662. +*/
  9663. +void gemac_enable_stacked_vlan(void *base)
  9664. +{
  9665. + writel (readl(base + EMAC_STACKED_VLAN_REG) | EMAC_ENABLE_STACKED_VLAN, base + EMAC_STACKED_VLAN_REG);
  9666. +}
  9667. +
  9668. +/** GEMAC enable stacked vlan function.
  9669. +* @param[in] base GEMAC base address
  9670. +*/
  9671. +void gemac_disable_stacked_vlan(void *base)
  9672. +{
  9673. + writel (readl(base + EMAC_STACKED_VLAN_REG) & ~EMAC_ENABLE_STACKED_VLAN, base + EMAC_STACKED_VLAN_REG);
  9674. +}
  9675. +
  9676. +/** GEMAC enable pause rx function.
  9677. +* @param[in] base GEMAC base address
  9678. +*/
  9679. +void gemac_enable_pause_rx(void *base)
  9680. +{
  9681. + writel (readl(base + EMAC_NETWORK_CONFIG) | EMAC_ENABLE_PAUSE_RX, base + EMAC_NETWORK_CONFIG);
  9682. +}
  9683. +
  9684. +/** GEMAC disable pause rx function.
  9685. +* @param[in] base GEMAC base address
  9686. +*/
  9687. +void gemac_disable_pause_rx(void *base)
  9688. +{
  9689. + writel (readl(base + EMAC_NETWORK_CONFIG) & ~EMAC_ENABLE_PAUSE_RX, base + EMAC_NETWORK_CONFIG);
  9690. +}
  9691. +
  9692. +/** GEMAC wol configuration
  9693. +* @param[in] base GEMAC base address
  9694. +* @param[in] wol_conf WoL register configuration
  9695. +*/
  9696. +void gemac_set_wol(void *base, u32 wol_conf)
  9697. +{
  9698. + writel(wol_conf, base + EMAC_WOL);
  9699. +}
  9700. +
  9701. +/** Sets Gemac bus width to 64bit
  9702. + * @param[in] base GEMAC base address
  9703. + * @param[in] width gemac bus width to be set possible values are 32/64/128
  9704. + * */
  9705. +void gemac_set_bus_width(void *base, int width)
  9706. +{
  9707. + u32 val = readl(base + EMAC_NETWORK_CONFIG);
  9708. + switch(width)
  9709. + {
  9710. + case 32:
  9711. + val = (val & ~EMAC_DATA_BUS_WIDTH_MASK) | EMAC_DATA_BUS_WIDTH_32;
  9712. + case 128:
  9713. + val = (val & ~EMAC_DATA_BUS_WIDTH_MASK) | EMAC_DATA_BUS_WIDTH_128;
  9714. + case 64:
  9715. + default:
  9716. + val = (val & ~EMAC_DATA_BUS_WIDTH_MASK) | EMAC_DATA_BUS_WIDTH_64;
  9717. +
  9718. + }
  9719. + writel (val, base + EMAC_NETWORK_CONFIG);
  9720. +}
  9721. +
  9722. +/** Sets Gemac configuration.
  9723. +* @param[in] base GEMAC base address
  9724. +* @param[in] cfg GEMAC configuration
  9725. +*/
  9726. +void gemac_set_config(void *base, GEMAC_CFG *cfg)
  9727. +{
  9728. + gemac_set_mode(base, cfg->mode);
  9729. +
  9730. + gemac_set_speed(base, cfg->speed);
  9731. +
  9732. + gemac_set_duplex(base,cfg->duplex);
  9733. +}
  9734. +#elif defined(CONFIG_PLATFORM_LS1012A)
  9735. +/**************************** MTIP GEMAC ***************************/
  9736. +
  9737. +/** Enable Rx Checksum Engine. With this enabled, Frame with bad IP,
  9738. + * TCP or UDP checksums are discarded
  9739. + *
  9740. + * @param[in] base GEMAC base address.
  9741. + */
  9742. +void gemac_enable_rx_checksum_offload(void *base)
  9743. +{
  9744. + /*Do not find configuration to do this */
  9745. +}
  9746. +
  9747. +/** Disable Rx Checksum Engine.
  9748. + *
  9749. + * @param[in] base GEMAC base address.
  9750. + */
  9751. +void gemac_disable_rx_checksum_offload(void *base)
  9752. +{
  9753. + /*Do not find configuration to do this */
  9754. +}
  9755. +
  9756. +/** GEMAC set speed.
  9757. +* @param[in] base GEMAC base address
  9758. +* @param[in] speed GEMAC speed (10, 100 or 1000 Mbps)
  9759. +*/
  9760. +void gemac_set_speed(void *base, MAC_SPEED gem_speed)
  9761. +{
  9762. + u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED;
  9763. + u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T;
  9764. +
  9765. + switch (gem_speed)
  9766. + {
  9767. + case SPEED_10M:
  9768. + rcr |= EMAC_RCNTRL_RMII_10T;
  9769. + break;
  9770. +
  9771. +
  9772. + case SPEED_1000M:
  9773. + ecr |= EMAC_ECNTRL_SPEED;
  9774. + break;
  9775. +
  9776. + case SPEED_100M:
  9777. + default:
  9778. + /*It is in 100M mode */
  9779. + break;
  9780. + }
  9781. + writel(ecr, (base + EMAC_ECNTRL_REG));
  9782. + writel(rcr, (base + EMAC_RCNTRL_REG));
  9783. +}
  9784. +
  9785. +/** GEMAC set duplex.
  9786. +* @param[in] base GEMAC base address
  9787. +* @param[in] duplex GEMAC duplex mode (Full, Half)
  9788. +*/
  9789. +void gemac_set_duplex(void *base, int duplex)
  9790. +{
  9791. +
  9792. + if (duplex == DUPLEX_HALF) {
  9793. + printk("%s() TODO\n", __func__);
  9794. + writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base + EMAC_TCNTRL_REG);
  9795. + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base + EMAC_RCNTRL_REG));
  9796. + }else{
  9797. + writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base + EMAC_TCNTRL_REG);
  9798. + writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base + EMAC_RCNTRL_REG));
  9799. + }
  9800. +}
  9801. +
  9802. +/** GEMAC set mode.
  9803. +* @param[in] base GEMAC base address
  9804. +* @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII)
  9805. +*/
  9806. +void gemac_set_mode(void *base, int mode)
  9807. +{
  9808. + u32 val = readl(base + EMAC_RCNTRL_REG);
  9809. +
  9810. + /*Remove loopbank*/
  9811. + val &= ~EMAC_RCNTRL_LOOP;
  9812. +
  9813. + /*Enable flow control and MII mode*/
  9814. + val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE);
  9815. +
  9816. + writel(val, base + EMAC_RCNTRL_REG);
  9817. +}
  9818. +
  9819. +/** GEMAC enable function.
  9820. +* @param[in] base GEMAC base address
  9821. +*/
  9822. +void gemac_enable(void *base)
  9823. +{
  9824. + writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base + EMAC_ECNTRL_REG);
  9825. +}
  9826. +
  9827. +/** GEMAC disable function.
  9828. +* @param[in] base GEMAC base address
  9829. +*/
  9830. +void gemac_disable(void *base)
  9831. +{
  9832. + writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base + EMAC_ECNTRL_REG);
  9833. +}
  9834. +
  9835. +/** GEMAC TX disable function.
  9836. +* @param[in] base GEMAC base address
  9837. +*/
  9838. +void gemac_tx_disable(void *base)
  9839. +{
  9840. + writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base + EMAC_TCNTRL_REG);
  9841. +}
  9842. +
  9843. +/** Sets the hash register of the MAC.
  9844. + * This register is used for matching unicast and multicast frames.
  9845. + *
  9846. + * @param[in] base GEMAC base address.
  9847. + * @param[in] hash 64-bit hash to be configured.
  9848. + */
  9849. +void gemac_set_hash( void *base, MAC_ADDR *hash )
  9850. +{
  9851. + writel(hash->bottom, base + EMAC_GALR);
  9852. + writel(hash->top, base + EMAC_GAUR);
  9853. +}
  9854. +
  9855. +void gemac_set_laddrN(void *base, MAC_ADDR *address, unsigned int entry_index)
  9856. +{
  9857. + if( (entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX) )
  9858. + return;
  9859. +
  9860. + entry_index = entry_index - 1;
  9861. + if (entry_index < 1) {
  9862. + writel(htonl(address->bottom), base + EMAC_PHY_ADDR_LOW);
  9863. + writel((htonl(address->top) | 0x8808), base + EMAC_PHY_ADDR_HIGH);
  9864. + }
  9865. + else
  9866. + {
  9867. + /* TODO for other entry_index */
  9868. + /*printk("%s for entry_index %d \n",__func__, entry_index); */
  9869. + writel(htonl(address->bottom), base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0);
  9870. + writel((htonl(address->top) | 0x8808), base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1);
  9871. + }
  9872. +
  9873. +}
  9874. +
  9875. +void gemac_clear_laddrN(void *base, unsigned int entry_index)
  9876. +{
  9877. + if( (entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX) )
  9878. + return;
  9879. +
  9880. + entry_index = entry_index - 1;
  9881. + if (entry_index < 1) {
  9882. + writel(0, base + EMAC_PHY_ADDR_LOW);
  9883. + writel(0, base + EMAC_PHY_ADDR_HIGH);
  9884. + }
  9885. + else
  9886. + {
  9887. + writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0);
  9888. + writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1);
  9889. + }
  9890. +
  9891. +
  9892. +}
  9893. +
  9894. +/** Set the loopback mode of the MAC. This can be either no loopback for normal
  9895. + * operation, local loopback through MAC internal loopback module or PHY
  9896. + * loopback for external loopback through a PHY. This asserts the external loop
  9897. + * pin.
  9898. + *
  9899. + * @param[in] base GEMAC base address.
  9900. + * @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC Loopback,
  9901. + * LB_EXT - PHY Loopback.
  9902. + */
  9903. +void gemac_set_loop( void *base, MAC_LOOP gem_loop )
  9904. +{
  9905. + printk("%s()\n", __func__);
  9906. + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base + EMAC_RCNTRL_REG));
  9907. +}
  9908. +
  9909. +
  9910. +/** GEMAC allow frames
  9911. + * @param[in] base GEMAC base address
  9912. + */
  9913. +void gemac_enable_copy_all(void *base)
  9914. +{
  9915. + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base + EMAC_RCNTRL_REG));
  9916. +}
  9917. +
  9918. +/** GEMAC do not allow frames
  9919. + * @param[in] base GEMAC base address
  9920. +*/
  9921. +void gemac_disable_copy_all(void *base)
  9922. +{
  9923. + writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base + EMAC_RCNTRL_REG));
  9924. +}
  9925. +
  9926. +/** GEMAC allow broadcast function.
  9927. +* @param[in] base GEMAC base address
  9928. +*/
  9929. +void gemac_allow_broadcast(void *base)
  9930. +{
  9931. + writel (readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base + EMAC_RCNTRL_REG);
  9932. +}
  9933. +
  9934. +/** GEMAC no broadcast function.
  9935. +* @param[in] base GEMAC base address
  9936. +*/
  9937. +void gemac_no_broadcast(void *base)
  9938. +{
  9939. + writel (readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base + EMAC_RCNTRL_REG);
  9940. +}
  9941. +
  9942. +/** GEMAC enable unicast function.
  9943. +* @param[in] base GEMAC base address
  9944. +*/
  9945. +void gemac_enable_unicast(void *base)
  9946. +{
  9947. + return;
  9948. +}
  9949. +
  9950. +/** GEMAC disable unicast function.
  9951. +* @param[in] base GEMAC base address
  9952. +*/
  9953. +void gemac_disable_unicast(void *base)
  9954. +{
  9955. + return;
  9956. +}
  9957. +
  9958. +/** GEMAC enable multicast function.
  9959. +* @param[in] base GEMAC base address
  9960. +*/
  9961. +void gemac_enable_multicast(void *base)
  9962. +{
  9963. + return;
  9964. +}
  9965. +
  9966. +/** GEMAC disable multicast function.
  9967. +* @param[in] base GEMAC base address
  9968. +*/
  9969. +void gemac_disable_multicast(void *base)
  9970. +{
  9971. + /* TODO how to disable multicast? */
  9972. + return;
  9973. +}
  9974. +
  9975. +/** GEMAC enable fcs rx function.
  9976. +* @param[in] base GEMAC base address
  9977. +*/
  9978. +void gemac_enable_fcs_rx(void *base)
  9979. +{
  9980. + /*Do not find configuration to do this */
  9981. +}
  9982. +
  9983. +/** GEMAC disable fcs rx function.
  9984. +* @param[in] base GEMAC base address
  9985. +*/
  9986. +void gemac_disable_fcs_rx(void *base)
  9987. +{
  9988. + /*Do not find configuration to do this */
  9989. +}
  9990. +
  9991. +
  9992. +/** GEMAC enable 1536 rx function.
  9993. +* @param[in] base GEMAC base address
  9994. +*/
  9995. +void gemac_enable_1536_rx(void *base)
  9996. +{
  9997. + /* Set 1536 as Maximum frame length */
  9998. + writel (readl(base + EMAC_RCNTRL_REG) | (1536 << 16), base + EMAC_RCNTRL_REG);
  9999. +}
  10000. +
  10001. +/** GEMAC enable jumbo function.
  10002. +* @param[in] base GEMAC base address
  10003. +*/
  10004. +void gemac_enable_rx_jmb(void *base)
  10005. +{
  10006. + /*TODO what is the jumbo size supported by MTIP */
  10007. + writel (readl(base + EMAC_RCNTRL_REG) | (JUMBO_FRAME_SIZE << 16), base + EMAC_RCNTRL_REG);
  10008. +}
  10009. +
  10010. +/** GEMAC enable stacked vlan function.
  10011. +* @param[in] base GEMAC base address
  10012. +*/
  10013. +void gemac_enable_stacked_vlan(void *base)
  10014. +{
  10015. + /* MTIP doesn't support stacked vlan */
  10016. + return;
  10017. +}
  10018. +
  10019. +/** GEMAC enable pause rx function.
  10020. +* @param[in] base GEMAC base address
  10021. +*/
  10022. +void gemac_enable_pause_rx(void *base)
  10023. +{
  10024. + writel (readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE, base + EMAC_RCNTRL_REG);
  10025. +}
  10026. +
  10027. +/** GEMAC disable pause rx function.
  10028. +* @param[in] base GEMAC base address
  10029. +*/
  10030. +void gemac_disable_pause_rx(void *base)
  10031. +{
  10032. + writel (readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE, base + EMAC_RCNTRL_REG);
  10033. +}
  10034. +
  10035. +/** GEMAC wol configuration
  10036. +* @param[in] base GEMAC base address
  10037. +* @param[in] wol_conf WoL register configuration
  10038. +*/
  10039. +void gemac_set_wol(void *base, u32 wol_conf)
  10040. +{
  10041. + printk("%s() TODO\n", __func__);
  10042. +}
  10043. +
  10044. +/** Sets Gemac bus width to 64bit
  10045. + * @param[in] base GEMAC base address
  10046. + * @param[in] width gemac bus width to be set possible values are 32/64/128
  10047. + * */
  10048. +void gemac_set_bus_width(void *base, int width)
  10049. +{
  10050. +}
  10051. +
  10052. +/** Sets Gemac configuration.
  10053. +* @param[in] base GEMAC base address
  10054. +* @param[in] cfg GEMAC configuration
  10055. +*/
  10056. +void gemac_set_config(void *base, GEMAC_CFG *cfg)
  10057. +{
  10058. +
  10059. + /*GEMAC config taken from VLSI */
  10060. + writel(0x00000004, base + EMAC_TFWR_STR_FWD);
  10061. + writel(0x00000005, base + EMAC_RX_SECTIOM_FULL);
  10062. + writel(0x00003fff, base + EMAC_TRUNC_FL);
  10063. + writel(0x00000030, base + EMAC_TX_SECTION_EMPTY);
  10064. + writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG);
  10065. +
  10066. + gemac_set_mode(base, cfg->mode);
  10067. +
  10068. + gemac_set_speed(base, cfg->speed);
  10069. +
  10070. + gemac_set_duplex(base,cfg->duplex);
  10071. +}
  10072. +
  10073. +
  10074. +#endif //CONFIG_PLATFORM_LS1012A)
  10075. +
  10076. +
  10077. +
  10078. +/**************************** GPI ***************************/
  10079. +
  10080. +/** Initializes a GPI block.
  10081. +* @param[in] base GPI base address
  10082. +* @param[in] cfg GPI configuration
  10083. +*/
  10084. +void gpi_init(void *base, GPI_CFG *cfg)
  10085. +{
  10086. + gpi_reset(base);
  10087. +
  10088. + gpi_disable(base);
  10089. +
  10090. + gpi_set_config(base, cfg);
  10091. +}
  10092. +
  10093. +/** Resets a GPI block.
  10094. +* @param[in] base GPI base address
  10095. +*/
  10096. +void gpi_reset(void *base)
  10097. +{
  10098. + writel (CORE_SW_RESET, base + GPI_CTRL);
  10099. +}
  10100. +
  10101. +/** Enables a GPI block.
  10102. +* @param[in] base GPI base address
  10103. +*/
  10104. +void gpi_enable(void *base)
  10105. +{
  10106. + writel (CORE_ENABLE, base + GPI_CTRL);
  10107. +}
  10108. +
  10109. +/** Disables a GPI block.
  10110. +* @param[in] base GPI base address
  10111. +*/
  10112. +void gpi_disable(void *base)
  10113. +{
  10114. + writel (CORE_DISABLE, base + GPI_CTRL);
  10115. +}
  10116. +
  10117. +
  10118. +/** Sets the configuration of a GPI block.
  10119. +* @param[in] base GPI base address
  10120. +* @param[in] cfg GPI configuration
  10121. +*/
  10122. +void gpi_set_config(void *base, GPI_CFG *cfg)
  10123. +{
  10124. + writel (CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base + GPI_LMEM_ALLOC_ADDR);
  10125. + writel (CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base + GPI_LMEM_FREE_ADDR);
  10126. + writel (CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base + GPI_DDR_ALLOC_ADDR);
  10127. + writel (CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base + GPI_DDR_FREE_ADDR);
  10128. + writel (CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR);
  10129. + writel (DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET);
  10130. + writel (LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET);
  10131. + writel (0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET);
  10132. + writel (0, base + GPI_DDR_SEC_BUF_DATA_OFFSET);
  10133. + writel ((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE);
  10134. + writel ((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE);
  10135. +
  10136. + writel (((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) | GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG);
  10137. + writel (cfg->tmlf_txthres, base + GPI_TMLF_TX);
  10138. + writel (cfg->aseq_len, base + GPI_DTX_ASEQ);
  10139. + writel (1, base + GPI_TOE_CHKSUM_EN);
  10140. +}
  10141. +
  10142. +/**************************** CLASSIFIER ***************************/
  10143. +
  10144. +/** Initializes CLASSIFIER block.
  10145. +* @param[in] cfg CLASSIFIER configuration
  10146. +*/
  10147. +void class_init(CLASS_CFG *cfg)
  10148. +{
  10149. + class_reset();
  10150. +
  10151. + class_disable();
  10152. +
  10153. + class_set_config(cfg);
  10154. +}
  10155. +
  10156. +/** Resets CLASSIFIER block.
  10157. +*
  10158. +*/
  10159. +void class_reset(void)
  10160. +{
  10161. + writel(CORE_SW_RESET, CLASS_TX_CTRL);
  10162. +}
  10163. +
  10164. +/** Enables all CLASS-PE's cores.
  10165. +*
  10166. +*/
  10167. +void class_enable(void)
  10168. +{
  10169. + writel(CORE_ENABLE, CLASS_TX_CTRL);
  10170. +}
  10171. +
  10172. +/** Disables all CLASS-PE's cores.
  10173. +*
  10174. +*/
  10175. +void class_disable(void)
  10176. +{
  10177. + writel(CORE_DISABLE, CLASS_TX_CTRL);
  10178. +}
  10179. +
  10180. +/** Sets the configuration of the CLASSIFIER block.
  10181. +* @param[in] cfg CLASSIFIER configuration
  10182. +*/
  10183. +void class_set_config(CLASS_CFG *cfg)
  10184. +{
  10185. + u32 val;
  10186. +
  10187. + /* Initialize route table */
  10188. + if (!cfg->resume)
  10189. + memset(DDR_PHYS_TO_VIRT(cfg->route_table_baseaddr), 0, (1 << cfg->route_table_hash_bits) * CLASS_ROUTE_SIZE);
  10190. +
  10191. +#if !defined(LS1012A_PFE_RESET_WA)
  10192. + writel(cfg->pe_sys_clk_ratio, CLASS_PE_SYS_CLK_RATIO);
  10193. +#endif
  10194. +
  10195. + writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, CLASS_HDR_SIZE);
  10196. + writel(LMEM_BUF_SIZE, CLASS_LMEM_BUF_SIZE);
  10197. + writel(CLASS_ROUTE_ENTRY_SIZE(CLASS_ROUTE_SIZE) | CLASS_ROUTE_HASH_SIZE(cfg->route_table_hash_bits), CLASS_ROUTE_HASH_ENTRY_SIZE);
  10198. + writel(HIF_PKT_CLASS_EN| HIF_PKT_OFFSET(sizeof(struct hif_hdr)), CLASS_HIF_PARSE);
  10199. +
  10200. + val = HASH_CRC_PORT_IP | QB2BUS_LE;
  10201. +
  10202. +#if defined(CONFIG_IP_ALIGNED)
  10203. + val |= IP_ALIGNED;
  10204. +#endif
  10205. +
  10206. + /* Class PE packet steering will only work if TOE mode, bridge fetch or
  10207. + * route fetch are enabled (see class/qb_fet.v). Route fetch would trigger
  10208. + * additional memory copies (likely from DDR because of hash table size, which
  10209. + * cannot be reduced because PE software still relies on hash value computed
  10210. + * in HW), so when not in TOE mode we simply enable HW bridge fetch even
  10211. + * though we don't use it.
  10212. + */
  10213. + if (cfg->toe_mode)
  10214. + val |= CLASS_TOE;
  10215. + else
  10216. + val |= HW_BRIDGE_FETCH;
  10217. +
  10218. + writel(val, CLASS_ROUTE_MULTI);
  10219. +
  10220. + writel(DDR_PHYS_TO_PFE(cfg->route_table_baseaddr), CLASS_ROUTE_TABLE_BASE);
  10221. + writel(CLASS_PE0_RO_DM_ADDR0_VAL, CLASS_PE0_RO_DM_ADDR0);
  10222. + writel(CLASS_PE0_RO_DM_ADDR1_VAL, CLASS_PE0_RO_DM_ADDR1);
  10223. + writel(CLASS_PE0_QB_DM_ADDR0_VAL, CLASS_PE0_QB_DM_ADDR0);
  10224. + writel(CLASS_PE0_QB_DM_ADDR1_VAL, CLASS_PE0_QB_DM_ADDR1);
  10225. + writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR), CLASS_TM_INQ_ADDR);
  10226. +
  10227. + writel(23, CLASS_AFULL_THRES);
  10228. + writel(23, CLASS_TSQ_FIFO_THRES);
  10229. +
  10230. + writel(24, CLASS_MAX_BUF_CNT);
  10231. + writel(24, CLASS_TSQ_MAX_CNT);
  10232. +}
  10233. +
  10234. +/**************************** TMU ***************************/
  10235. +
  10236. +void tmu_reset(void)
  10237. +{
  10238. + writel(SW_RESET, TMU_CTRL);
  10239. +}
  10240. +
  10241. +/** Initializes TMU block.
  10242. +* @param[in] cfg TMU configuration
  10243. +*/
  10244. +void tmu_init(TMU_CFG *cfg)
  10245. +{
  10246. + int q, phyno;
  10247. +
  10248. + tmu_disable(0xF);
  10249. + mdelay(10);
  10250. +
  10251. +#if !defined(LS1012A_PFE_RESET_WA)
  10252. + /* keep in soft reset */
  10253. + writel(SW_RESET, TMU_CTRL);
  10254. +#endif
  10255. + writel(0x3, TMU_SYS_GENERIC_CONTROL);
  10256. + writel(750, TMU_INQ_WATERMARK);
  10257. + writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR + GPI_INQ_PKTPTR), TMU_PHY0_INQ_ADDR);
  10258. + writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR + GPI_INQ_PKTPTR), TMU_PHY1_INQ_ADDR);
  10259. +#if !defined(CONFIG_PLATFORM_LS1012A)
  10260. + writel(CBUS_VIRT_TO_PFE(EGPI3_BASE_ADDR + GPI_INQ_PKTPTR), TMU_PHY2_INQ_ADDR);
  10261. +#endif
  10262. + writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR + GPI_INQ_PKTPTR), TMU_PHY3_INQ_ADDR);
  10263. + writel(CBUS_VIRT_TO_PFE(HIF_NOCPY_RX_INQ0_PKTPTR), TMU_PHY4_INQ_ADDR);
  10264. + writel(CBUS_VIRT_TO_PFE(UTIL_INQ_PKTPTR), TMU_PHY5_INQ_ADDR);
  10265. + writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), TMU_BMU_INQ_ADDR);
  10266. +
  10267. + writel(0x3FF, TMU_TDQ0_SCH_CTRL); // enabling all 10 schedulers [9:0] of each TDQ
  10268. + writel(0x3FF, TMU_TDQ1_SCH_CTRL);
  10269. +#if !defined(CONFIG_PLATFORM_LS1012A)
  10270. + writel(0x3FF, TMU_TDQ2_SCH_CTRL);
  10271. +#endif
  10272. + writel(0x3FF, TMU_TDQ3_SCH_CTRL);
  10273. +
  10274. +#if !defined(LS1012A_PFE_RESET_WA)
  10275. + writel(cfg->pe_sys_clk_ratio, TMU_PE_SYS_CLK_RATIO);
  10276. +#endif
  10277. +
  10278. +#if !defined(LS1012A_PFE_RESET_WA)
  10279. + writel(DDR_PHYS_TO_PFE(cfg->llm_base_addr), TMU_LLM_BASE_ADDR); // Extra packet pointers will be stored from this address onwards
  10280. +
  10281. + writel(cfg->llm_queue_len, TMU_LLM_QUE_LEN);
  10282. + writel(5, TMU_TDQ_IIFG_CFG);
  10283. + writel(DDR_BUF_SIZE, TMU_BMU_BUF_SIZE);
  10284. +
  10285. + writel(0x0, TMU_CTRL);
  10286. +
  10287. + /* MEM init */
  10288. + printk(KERN_INFO "%s: mem init\n", __func__);
  10289. + writel(MEM_INIT, TMU_CTRL);
  10290. +
  10291. + while(!(readl(TMU_CTRL) & MEM_INIT_DONE)) ;
  10292. +
  10293. + /* LLM init */
  10294. + printk(KERN_INFO "%s: lmem init\n", __func__);
  10295. + writel(LLM_INIT, TMU_CTRL);
  10296. +
  10297. + while(!(readl(TMU_CTRL) & LLM_INIT_DONE)) ;
  10298. +#endif
  10299. + // set up each queue for tail drop
  10300. + for (phyno = 0; phyno < 4; phyno++)
  10301. + {
  10302. +#if defined(CONFIG_PLATFORM_LS1012A)
  10303. + if(phyno == 2) continue;
  10304. +#endif
  10305. + for (q = 0; q < 16; q++)
  10306. + {
  10307. + u32 qdepth;
  10308. + writel((phyno << 8) | q, TMU_TEQ_CTRL);
  10309. + writel(1 << 22, TMU_TEQ_QCFG); //Enable tail drop
  10310. +
  10311. + if (phyno == 3)
  10312. + qdepth = DEFAULT_TMU3_QDEPTH;
  10313. + else
  10314. + qdepth = (q == 0) ? DEFAULT_Q0_QDEPTH : DEFAULT_MAX_QDEPTH;
  10315. +
  10316. + // LOG: 68855
  10317. + // The following is a workaround for the reordered packet and BMU2 buffer leakage issue.
  10318. + if (CHIP_REVISION() == 0)
  10319. + qdepth = 31;
  10320. +
  10321. + writel(qdepth << 18, TMU_TEQ_HW_PROB_CFG2);
  10322. + writel(qdepth >> 14, TMU_TEQ_HW_PROB_CFG3);
  10323. + }
  10324. + }
  10325. +
  10326. +#ifdef CFG_LRO
  10327. + /* Set TMU-3 queue 5 (LRO) in no-drop mode */
  10328. + writel((3 << 8) | TMU_QUEUE_LRO, TMU_TEQ_CTRL);
  10329. + writel(0, TMU_TEQ_QCFG);
  10330. +#endif
  10331. +
  10332. + writel(0x05, TMU_TEQ_DISABLE_DROPCHK);
  10333. +
  10334. + writel(0x0, TMU_CTRL);
  10335. +}
  10336. +
  10337. +/** Enables TMU-PE cores.
  10338. +* @param[in] pe_mask TMU PE mask
  10339. +*/
  10340. +void tmu_enable(u32 pe_mask)
  10341. +{
  10342. + writel(readl(TMU_TX_CTRL) | (pe_mask & 0xF), TMU_TX_CTRL);
  10343. +}
  10344. +
  10345. +/** Disables TMU cores.
  10346. +* @param[in] pe_mask TMU PE mask
  10347. +*/
  10348. +void tmu_disable(u32 pe_mask)
  10349. +{
  10350. + writel(readl(TMU_TX_CTRL) & ~(pe_mask & 0xF), TMU_TX_CTRL);
  10351. +}
  10352. +/** This will return the tmu queue status
  10353. + * @param[in] if_id gem interface id or TMU index
  10354. + * @return returns the bit mask of busy queues, zero means all queues are empty
  10355. + */
  10356. +u32 tmu_qstatus(u32 if_id)
  10357. +{
  10358. + return cpu_to_be32(pe_dmem_read(TMU0_ID+if_id, PESTATUS_ADDR_TMU + offsetof(PE_STATUS, tmu_qstatus), 4));
  10359. +}
  10360. +
  10361. +u32 tmu_pkts_processed(u32 if_id)
  10362. +{
  10363. + return cpu_to_be32(pe_dmem_read(TMU0_ID+if_id, PESTATUS_ADDR_TMU + offsetof(PE_STATUS, rx), 4));
  10364. +}
  10365. +/**************************** UTIL ***************************/
  10366. +
  10367. +/** Resets UTIL block.
  10368. +*/
  10369. +void util_reset(void)
  10370. +{
  10371. + writel(CORE_SW_RESET, UTIL_TX_CTRL);
  10372. +}
  10373. +
  10374. +/** Initializes UTIL block.
  10375. +* @param[in] cfg UTIL configuration
  10376. +*/
  10377. +void util_init(UTIL_CFG *cfg)
  10378. +{
  10379. + writel(cfg->pe_sys_clk_ratio, UTIL_PE_SYS_CLK_RATIO);
  10380. +}
  10381. +
  10382. +/** Enables UTIL-PE core.
  10383. +*
  10384. +*/
  10385. +void util_enable(void)
  10386. +{
  10387. + writel(CORE_ENABLE, UTIL_TX_CTRL);
  10388. +}
  10389. +
  10390. +/** Disables UTIL-PE core.
  10391. +*
  10392. +*/
  10393. +void util_disable(void)
  10394. +{
  10395. + writel(CORE_DISABLE, UTIL_TX_CTRL);
  10396. +}
  10397. +
  10398. +/**************************** HIF ***************************/
  10399. +
  10400. +/** Initializes HIF no copy block.
  10401. +*
  10402. +*/
  10403. +void hif_nocpy_init(void)
  10404. +{
  10405. + writel(4, HIF_NOCPY_TX_PORT_NO);
  10406. + writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), HIF_NOCPY_LMEM_ALLOC_ADDR);
  10407. + writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), HIF_NOCPY_CLASS_ADDR);
  10408. + writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR), HIF_NOCPY_TMU_PORT0_ADDR);
  10409. + writel(HIF_RX_POLL_CTRL_CYCLE<<16|HIF_TX_POLL_CTRL_CYCLE, HIF_NOCPY_POLL_CTRL);
  10410. +}
  10411. +
  10412. +/** Enable hif_nocpy tx DMA and interrupt
  10413. +*
  10414. +*/
  10415. +void hif_nocpy_tx_enable(void)
  10416. +{
  10417. + /*TODO not sure poll_cntrl_en is required or not */
  10418. + writel( HIF_CTRL_DMA_EN, HIF_NOCPY_TX_CTRL);
  10419. + //writel((readl(HIF_NOCPY_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN), HIF_NOCPY_INT_ENABLE);
  10420. +}
  10421. +
  10422. +/** Disable hif_nocpy tx DMA and interrupt
  10423. +*
  10424. +*/
  10425. +void hif_nocpy_tx_disable(void)
  10426. +{
  10427. + u32 hif_int;
  10428. +
  10429. + writel(0, HIF_NOCPY_TX_CTRL);
  10430. +
  10431. + hif_int = readl(HIF_NOCPY_INT_ENABLE);
  10432. + hif_int &= HIF_TXPKT_INT_EN;
  10433. + writel(hif_int, HIF_NOCPY_INT_ENABLE);
  10434. +}
  10435. +
  10436. +/** Enable hif rx DMA and interrupt
  10437. +*
  10438. +*/
  10439. +void hif_nocpy_rx_enable(void)
  10440. +{
  10441. + hif_nocpy_rx_dma_start();
  10442. + writel((readl(HIF_NOCPY_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN), HIF_NOCPY_INT_ENABLE);
  10443. +}
  10444. +
  10445. +/** Disable hif_nocpy rx DMA and interrupt
  10446. +*
  10447. +*/
  10448. +void hif_nocpy_rx_disable(void)
  10449. +{
  10450. + u32 hif_int;
  10451. +
  10452. + writel(0, HIF_NOCPY_RX_CTRL);
  10453. +
  10454. + hif_int = readl(HIF_NOCPY_INT_ENABLE);
  10455. + hif_int &= HIF_RXPKT_INT_EN;
  10456. + writel(hif_int, HIF_NOCPY_INT_ENABLE);
  10457. +
  10458. +}
  10459. +/** Initializes HIF copy block.
  10460. +*
  10461. +*/
  10462. +void hif_init(void)
  10463. +{
  10464. + /*Initialize HIF registers*/
  10465. + writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE, HIF_POLL_CTRL);
  10466. +}
  10467. +
  10468. +/** Enable hif tx DMA and interrupt
  10469. +*
  10470. +*/
  10471. +void hif_tx_enable(void)
  10472. +{
  10473. + /*TODO not sure poll_cntrl_en is required or not */
  10474. + writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL);
  10475. + writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN), HIF_INT_ENABLE);
  10476. +}
  10477. +
  10478. +/** Disable hif tx DMA and interrupt
  10479. +*
  10480. +*/
  10481. +void hif_tx_disable(void)
  10482. +{
  10483. + u32 hif_int;
  10484. +
  10485. + writel(0, HIF_TX_CTRL);
  10486. +
  10487. + hif_int = readl(HIF_INT_ENABLE);
  10488. + hif_int &= HIF_TXPKT_INT_EN;
  10489. + writel(hif_int, HIF_INT_ENABLE);
  10490. +}
  10491. +
  10492. +/** Enable hif rx DMA and interrupt
  10493. +*
  10494. +*/
  10495. +void hif_rx_enable(void)
  10496. +{
  10497. + hif_rx_dma_start();
  10498. + writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN), HIF_INT_ENABLE);
  10499. +}
  10500. +
  10501. +/** Disable hif rx DMA and interrupt
  10502. +*
  10503. +*/
  10504. +void hif_rx_disable(void)
  10505. +{
  10506. + u32 hif_int;
  10507. +
  10508. + writel(0, HIF_RX_CTRL);
  10509. +
  10510. + hif_int = readl(HIF_INT_ENABLE);
  10511. + hif_int &= HIF_RXPKT_INT_EN;
  10512. + writel(hif_int, HIF_INT_ENABLE);
  10513. +
  10514. +}
  10515. --- /dev/null
  10516. +++ b/drivers/staging/fsl_ppfe/pfe_hif.c
  10517. @@ -0,0 +1,939 @@
  10518. +/*
  10519. + *
  10520. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  10521. + *
  10522. + * This program is free software; you can redistribute it and/or modify
  10523. + * it under the terms of the GNU General Public License as published by
  10524. + * the Free Software Foundation; either version 2 of the License, or
  10525. + * (at your option) any later version.
  10526. + *
  10527. + * This program is distributed in the hope that it will be useful,
  10528. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10529. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10530. + * GNU General Public License for more details.
  10531. + *
  10532. + * You should have received a copy of the GNU General Public License
  10533. + * along with this program; if not, write to the Free Software
  10534. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  10535. + */
  10536. +
  10537. +#ifdef __KERNEL__
  10538. +#include <linux/kernel.h>
  10539. +#include <linux/interrupt.h>
  10540. +#include <linux/dma-mapping.h>
  10541. +#include <linux/dmapool.h>
  10542. +#include <linux/sched.h>
  10543. +#include <linux/module.h>
  10544. +#include <linux/list.h>
  10545. +#include <linux/kthread.h>
  10546. +#include <linux/slab.h>
  10547. +
  10548. +#include <asm/io.h>
  10549. +#include <asm/irq.h>
  10550. +#else
  10551. +#include "platform.h"
  10552. +#endif
  10553. +
  10554. +
  10555. +#include "pfe_mod.h"
  10556. +#if 0
  10557. +#define DMA_MAP_SINGLE(dev, vaddr, size, direction) dma_map_single(dev, vaddr, size, direction)
  10558. +#define DMA_UNMAP_SINGLE(dev, vaddr, size, direction) dma_unmap_single(dev, vaddr, size, direction)
  10559. +void ct_flush(void *addr, u32 size)
  10560. +{
  10561. + dma_map_single(pfe->dev, addr, size, DMA_TO_DEVICE);
  10562. +}
  10563. +#else
  10564. +#define DMA_UNMAP_SINGLE(dev, vaddr, size, direction)
  10565. +#define DMA_MAP_SINGLE(dev, vaddr, size, direction) virt_to_phys(vaddr)
  10566. +#define ct_flush(addr, sz)
  10567. +#endif
  10568. +
  10569. +#define HIF_INT_MASK (HIF_INT | HIF_RXPKT_INT)
  10570. +
  10571. +#define inc_cl_idx(idxname) idxname = (idxname+1) & (queue->size-1)
  10572. +#define inc_hif_rxidx(idxname) idxname = (idxname+1) & (hif->RxRingSize-1)
  10573. +#define inc_hif_txidx(idxname) idxname = (idxname+1) & (hif->TxRingSize-1)
  10574. +
  10575. +unsigned char napi_first_batch = 0;
  10576. +
  10577. +static int pfe_hif_alloc_descr(struct pfe_hif *hif)
  10578. +{
  10579. +#if !defined(CONFIG_PLATFORM_PCI)
  10580. + void *addr;
  10581. + dma_addr_t dma_addr;
  10582. + int err = 0;
  10583. +
  10584. + printk(KERN_INFO "%s\n", __func__);
  10585. + addr = dma_alloc_coherent(pfe->dev,
  10586. + HIF_RX_DESC_NT * sizeof(struct hif_desc) + HIF_TX_DESC_NT * sizeof(struct hif_desc),
  10587. + &dma_addr, GFP_KERNEL);
  10588. +
  10589. + if (!addr) {
  10590. + printk(KERN_ERR "%s: Could not allocate buffer descriptors!\n", __func__);
  10591. + err = -ENOMEM;
  10592. + goto err0;
  10593. + }
  10594. +
  10595. + hif->descr_baseaddr_p = dma_addr;
  10596. + hif->descr_baseaddr_v = addr;
  10597. +#else
  10598. + hif->descr_baseaddr_p = pfe->ddr_phys_baseaddr + HIF_DESC_BASEADDR;
  10599. + hif->descr_baseaddr_v = pfe->ddr_baseaddr + HIF_DESC_BASEADDR;
  10600. +#endif
  10601. + hif->RxRingSize = HIF_RX_DESC_NT;
  10602. + hif->TxRingSize = HIF_TX_DESC_NT;
  10603. +
  10604. + return 0;
  10605. +
  10606. +err0:
  10607. + return err;
  10608. +}
  10609. +
  10610. +static void pfe_hif_free_descr(struct pfe_hif *hif)
  10611. +{
  10612. + printk(KERN_INFO "%s\n", __func__);
  10613. +#if !defined(CONFIG_PLATFORM_PCI)
  10614. + dma_free_coherent(pfe->dev,
  10615. + hif->RxRingSize * sizeof(struct hif_desc) + hif->TxRingSize * sizeof(struct hif_desc),
  10616. + hif->descr_baseaddr_v, hif->descr_baseaddr_p);
  10617. +#endif
  10618. +}
  10619. +void pfe_hif_desc_dump(struct pfe_hif *hif)
  10620. +{
  10621. + struct hif_desc *desc;
  10622. + unsigned long desc_p;
  10623. + int ii=0;
  10624. +
  10625. + printk(KERN_INFO "%s\n", __func__);
  10626. +
  10627. + desc = hif->RxBase;
  10628. + desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v + hif->descr_baseaddr_p);
  10629. +
  10630. + printk("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p);
  10631. + for (ii = 0; ii < hif->RxRingSize; ii++) {
  10632. + printk(KERN_INFO "status: %08x, ctrl: %08x, data: %08x, next: %x\n",
  10633. + desc->status, desc->ctrl, desc->data, desc->next);
  10634. + desc++;
  10635. + }
  10636. +
  10637. + desc = hif->TxBase;
  10638. + desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v + hif->descr_baseaddr_p);
  10639. +
  10640. + printk("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p);
  10641. + for (ii = 0; ii < hif->TxRingSize; ii++) {
  10642. + printk(KERN_INFO "status: %08x, ctrl: %08x, data: %08x, next: %x\n",
  10643. + desc->status, desc->ctrl, desc->data, desc->next);
  10644. + desc++;
  10645. + }
  10646. +
  10647. +}
  10648. +
  10649. +/* pfe_hif_release_buffers
  10650. + *
  10651. + */
  10652. +static void pfe_hif_release_buffers(struct pfe_hif *hif)
  10653. +{
  10654. + struct hif_desc *desc;
  10655. + int i = 0;
  10656. +
  10657. + hif->RxBase = hif->descr_baseaddr_v;
  10658. +
  10659. + printk(KERN_INFO "%s\n", __func__);
  10660. + /*Free Rx buffers */
  10661. +#if !defined(CONFIG_PLATFORM_PCI)
  10662. + desc = hif->RxBase;
  10663. + for (i = 0; i < hif->RxRingSize; i++) {
  10664. + if (desc->data) {
  10665. + if ((i < hif->shm->rx_buf_pool_cnt) && (hif->shm->rx_buf_pool[i] == NULL)) {
  10666. + //dma_unmap_single(hif->dev, desc->data, hif->rx_buf_len[i], DMA_FROM_DEVICE);
  10667. + DMA_UNMAP_SINGLE(hif->dev, desc->data, hif->rx_buf_len[i], DMA_FROM_DEVICE);
  10668. + hif->shm->rx_buf_pool[i] = hif->rx_buf_addr[i];
  10669. + }
  10670. + else {
  10671. + /*TODO This should not happen*/
  10672. + printk(KERN_ERR "%s: buffer pool already full\n", __func__);
  10673. + }
  10674. + }
  10675. +
  10676. + desc->data = 0;
  10677. + desc->status = 0;
  10678. + desc->ctrl = 0;
  10679. + desc++;
  10680. + }
  10681. +#endif
  10682. +}
  10683. +
  10684. +
  10685. +/*
  10686. + * pfe_hif_init_buffers
  10687. + * This function initializes the HIF Rx/Tx ring descriptors and
  10688. + * initialize Rx queue with buffers.
  10689. + */
  10690. +static int pfe_hif_init_buffers(struct pfe_hif *hif)
  10691. +{
  10692. + struct hif_desc *desc, *first_desc_p;
  10693. + u32 data;
  10694. + int i = 0;
  10695. +
  10696. + printk(KERN_INFO "%s\n", __func__);
  10697. +
  10698. + /* Check enough Rx buffers available in the shared memory */
  10699. + if (hif->shm->rx_buf_pool_cnt < hif->RxRingSize)
  10700. + return -ENOMEM;
  10701. +
  10702. + hif->RxBase = hif->descr_baseaddr_v;
  10703. + memset(hif->RxBase, 0, hif->RxRingSize * sizeof(struct hif_desc));
  10704. +
  10705. + /*Initialize Rx descriptors */
  10706. + desc = hif->RxBase;
  10707. + first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p;
  10708. +
  10709. + for (i = 0; i < hif->RxRingSize; i++) {
  10710. + /* Initialize Rx buffers from the shared memory */
  10711. +
  10712. +#if defined(CONFIG_PLATFORM_PCI)
  10713. + data = pfe->ddr_phys_baseaddr + HIF_RX_PKT_DDR_BASEADDR + i * DDR_BUF_SIZE;
  10714. +#else
  10715. + data = (u32)DMA_MAP_SINGLE(hif->dev, hif->shm->rx_buf_pool[i], pfe_pkt_size, DMA_FROM_DEVICE);
  10716. + hif->rx_buf_addr[i] = hif->shm->rx_buf_pool[i];
  10717. + hif->rx_buf_len[i] = pfe_pkt_size;
  10718. + // printk("#%d %p %p %d\n", i, data, hif->rx_buf_addr[i], hif->rx_buf_len[i]);
  10719. + hif->shm->rx_buf_pool[i] = NULL;
  10720. +#endif
  10721. + if (likely(dma_mapping_error(hif->dev, data) == 0)) {
  10722. + desc->data = DDR_PHYS_TO_PFE(data);
  10723. + } else {
  10724. + printk(KERN_ERR "%s : low on mem\n", __func__);
  10725. +
  10726. + goto err;
  10727. + }
  10728. +
  10729. + desc->status = 0;
  10730. + wmb();
  10731. + desc->ctrl = BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR |
  10732. + BD_CTRL_DESC_EN | BD_BUF_LEN(pfe_pkt_size);
  10733. + /* Chain descriptors */
  10734. + desc->next = (u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1);
  10735. + desc++;
  10736. + }
  10737. +
  10738. + /* Overwrite last descriptor to chain it to first one*/
  10739. + desc--;
  10740. + desc->next = (u32)DDR_PHYS_TO_PFE(first_desc_p);
  10741. +
  10742. + hif->RxtocleanIndex = 0;
  10743. +
  10744. + /*Initialize Rx buffer descriptor ring base address */
  10745. + writel(DDR_PHYS_TO_PFE(hif->descr_baseaddr_p), HIF_RX_BDP_ADDR);
  10746. +
  10747. + hif->TxBase = hif->RxBase + hif->RxRingSize;
  10748. + first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p + hif->RxRingSize;
  10749. + memset(hif->TxBase, 0, hif->TxRingSize * sizeof(struct hif_desc));
  10750. +
  10751. + /*Initialize tx descriptors */
  10752. + desc = hif->TxBase;
  10753. +
  10754. + for (i = 0; i < hif->TxRingSize; i++) {
  10755. + /* Chain descriptors */
  10756. + desc->next = (u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1);
  10757. +#if defined(CONFIG_PLATFORM_PCI)
  10758. + desc->data = pfe->ddr_phys_baseaddr + HIF_TX_PKT_DDR_BASEADDR + i * DDR_BUF_SIZE;
  10759. +#endif
  10760. + desc->ctrl = 0;
  10761. + desc++;
  10762. + }
  10763. +
  10764. + /* Overwrite last descriptor to chain it to first one */
  10765. + desc--;
  10766. + desc->next = (u32)DDR_PHYS_TO_PFE(first_desc_p);
  10767. + hif->TxAvail = hif->TxRingSize;
  10768. + hif->Txtosend = 0;
  10769. + hif->Txtoclean = 0;
  10770. + hif->Txtoflush = 0;
  10771. +
  10772. + /*Initialize Tx buffer descriptor ring base address */
  10773. + writel((u32)DDR_PHYS_TO_PFE(first_desc_p), HIF_TX_BDP_ADDR);
  10774. +
  10775. + return 0;
  10776. +
  10777. +err:
  10778. + pfe_hif_release_buffers(hif);
  10779. + return -ENOMEM;
  10780. +}
  10781. +
  10782. +/* pfe_hif_client_register
  10783. + *
  10784. + * This function used to register a client driver with the HIF driver.
  10785. + *
  10786. + * Return value:
  10787. + * 0 - on Successful registration
  10788. + */
  10789. +static int pfe_hif_client_register(struct pfe_hif *hif, u32 client_id, struct hif_client_shm *client_shm)
  10790. +{
  10791. + struct hif_client *client = &hif->client[client_id];
  10792. + u32 i, cnt;
  10793. + struct rx_queue_desc *rx_qbase;
  10794. + struct tx_queue_desc *tx_qbase;
  10795. + struct hif_rx_queue *rx_queue;
  10796. + struct hif_tx_queue *tx_queue;
  10797. + int err = 0;
  10798. +
  10799. + printk(KERN_INFO "%s\n", __func__);
  10800. +
  10801. + spin_lock_bh(&hif->tx_lock);
  10802. +
  10803. + if (test_bit(client_id, &hif->shm->gClient_status[0])) {
  10804. + printk(KERN_ERR "%s: client %d already registered\n", __func__, client_id);
  10805. + err = -1;
  10806. + goto unlock;
  10807. + }
  10808. +
  10809. + memset(client, 0, sizeof(struct hif_client));
  10810. +
  10811. + /*Initialize client Rx queues baseaddr, size */
  10812. +
  10813. + cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl);
  10814. + /*Check if client is requesting for more queues than supported */
  10815. + if (cnt > HIF_CLIENT_QUEUES_MAX)
  10816. + cnt = HIF_CLIENT_QUEUES_MAX;
  10817. +
  10818. + client->rx_qn = cnt;
  10819. + rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase;
  10820. + for (i = 0; i < cnt; i++)
  10821. + {
  10822. + rx_queue = &client->rx_q[i];
  10823. + rx_queue->base = rx_qbase + i * client_shm->rx_qsize;
  10824. + rx_queue->size = client_shm->rx_qsize;
  10825. + rx_queue->write_idx = 0;
  10826. + }
  10827. +
  10828. + /*Initialize client Tx queues baseaddr, size */
  10829. + cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl);
  10830. +
  10831. + /*Check if client is requesting for more queues than supported */
  10832. + if (cnt > HIF_CLIENT_QUEUES_MAX)
  10833. + cnt = HIF_CLIENT_QUEUES_MAX;
  10834. +
  10835. + client->tx_qn = cnt;
  10836. + tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase;
  10837. + for (i = 0; i < cnt; i++)
  10838. + {
  10839. + tx_queue = &client->tx_q[i];
  10840. + tx_queue->base = tx_qbase + i * client_shm->tx_qsize;
  10841. + tx_queue->size = client_shm->tx_qsize;
  10842. + tx_queue->ack_idx = 0;
  10843. + }
  10844. +
  10845. + set_bit(client_id, &hif->shm->gClient_status[0]);
  10846. +
  10847. +unlock:
  10848. + spin_unlock_bh(&hif->tx_lock);
  10849. +
  10850. + return err;
  10851. +}
  10852. +
  10853. +
  10854. +/* pfe_hif_client_unregister
  10855. + *
  10856. + * This function used to unregister a client from the HIF driver.
  10857. + *
  10858. + */
  10859. +static void pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id)
  10860. +{
  10861. + printk(KERN_INFO "%s\n", __func__);
  10862. +
  10863. + /* Mark client as no longer available (which prevents further packet receive for this client) */
  10864. + spin_lock_bh(&hif->tx_lock);
  10865. +
  10866. + if (!test_bit(client_id, &hif->shm->gClient_status[0])) {
  10867. + printk(KERN_ERR "%s: client %d not registered\n", __func__, client_id);
  10868. +
  10869. + spin_unlock_bh(&hif->tx_lock);
  10870. + return;
  10871. + }
  10872. +
  10873. + clear_bit(client_id, &hif->shm->gClient_status[0]);
  10874. +
  10875. + spin_unlock_bh(&hif->tx_lock);
  10876. +}
  10877. +
  10878. +/* client_put_rxpacket-
  10879. + * This functions puts the Rx pkt in the given client Rx queue.
  10880. + * It actually swap the Rx pkt in the client Rx descriptor buffer
  10881. + * and returns the free buffer from it.
  10882. + *
  10883. + * If the funtion returns NULL means client Rx queue is full and
  10884. + * packet couldn't send to client queue.
  10885. + */
  10886. +static void *client_put_rxpacket(struct hif_rx_queue *queue, void *pkt, u32 len, u32 flags, u32 client_ctrl, u32 *rem_len)
  10887. +{
  10888. + void *free_pkt = NULL;
  10889. + struct rx_queue_desc *desc = queue->base + queue->write_idx;
  10890. +
  10891. + if (desc->ctrl & CL_DESC_OWN) {
  10892. +#if defined(CONFIG_PLATFORM_PCI)
  10893. + memcpy(desc->data, pkt, len);
  10894. + free_pkt = PFE_HOST_TO_PCI(pkt);
  10895. + smp_wmb();
  10896. + desc->ctrl = CL_DESC_BUF_LEN(len) | flags;
  10897. + inc_cl_idx(queue->write_idx);
  10898. +#else
  10899. + //TODO: move allocations after Rx loop to improve instruction cache locality
  10900. + if (page_mode) {
  10901. + int rem_page_size = PAGE_SIZE - PRESENT_OFST_IN_PAGE(pkt);
  10902. + int cur_pkt_size = ROUND_MIN_RX_SIZE(len + pfe_pkt_headroom);
  10903. + *rem_len = (rem_page_size - cur_pkt_size);
  10904. + //printk("%p rem_len %d cur_len %d buf_len %d\n", pkt, rem_page_size, cur_pkt_size, *rem_len);
  10905. + if (*rem_len)
  10906. + {
  10907. + free_pkt = pkt + cur_pkt_size;
  10908. + get_page(virt_to_page(free_pkt));
  10909. + } else {
  10910. + free_pkt = (void *)__get_free_page(GFP_ATOMIC | GFP_DMA_PFE);
  10911. + *rem_len = pfe_pkt_size;
  10912. + }
  10913. + } else {
  10914. + free_pkt = kmalloc(PFE_BUF_SIZE, GFP_ATOMIC | GFP_DMA_PFE);
  10915. + *rem_len = PFE_BUF_SIZE - pfe_pkt_headroom;
  10916. + }
  10917. +
  10918. + if (free_pkt) {
  10919. + desc->data = pkt;
  10920. + desc->client_ctrl = client_ctrl;
  10921. + smp_wmb();
  10922. + desc->ctrl = CL_DESC_BUF_LEN(len) | flags;
  10923. + inc_cl_idx(queue->write_idx);
  10924. + free_pkt += pfe_pkt_headroom;
  10925. + }
  10926. +#endif
  10927. + }
  10928. +
  10929. + return free_pkt;
  10930. +}
  10931. +
  10932. +
  10933. +/* pfe_hif_rx_process-
  10934. + * This function does pfe hif rx queue processing.
  10935. + * Dequeue packet from Rx queue and send it to corresponding client queue
  10936. + */
  10937. +static int pfe_hif_rx_process(struct pfe_hif *hif, int budget)
  10938. +{
  10939. + struct hif_desc *desc;
  10940. + struct hif_hdr *pkt_hdr;
  10941. + struct __hif_hdr hif_hdr;
  10942. + void *free_buf;
  10943. + int rtc, len, rx_processed = 0;
  10944. + struct __hif_desc local_desc;
  10945. + int flags;
  10946. + unsigned int desc_p;
  10947. + unsigned int buf_size = 0;
  10948. +
  10949. + spin_lock_bh(&hif->lock);
  10950. +
  10951. + rtc = hif->RxtocleanIndex;
  10952. +
  10953. + while (rx_processed < budget)
  10954. + {
  10955. + /*TODO may need to implement rx process budget */
  10956. + desc = hif->RxBase + rtc;
  10957. +
  10958. + __memcpy12(&local_desc, desc);
  10959. +
  10960. + /* ACK pending Rx interrupt */
  10961. + if (local_desc.ctrl & BD_CTRL_DESC_EN) {
  10962. + writel(HIF_INT_MASK, HIF_INT_SRC);
  10963. +
  10964. + if(rx_processed == 0)
  10965. + {
  10966. + if(napi_first_batch == 1)
  10967. + {
  10968. + desc_p = hif->descr_baseaddr_p + ((unsigned long int)(desc) - (unsigned long int)hif->descr_baseaddr_v);
  10969. +#if defined(CONFIG_PLATFORM_C2000)
  10970. + outer_inv_range(desc_p, (desc_p + 16));
  10971. +#endif
  10972. + napi_first_batch = 0;
  10973. + }
  10974. + }
  10975. +
  10976. + __memcpy12(&local_desc, desc);
  10977. +
  10978. + if (local_desc.ctrl & BD_CTRL_DESC_EN)
  10979. + break;
  10980. + }
  10981. +
  10982. + napi_first_batch = 0;
  10983. +
  10984. +#ifdef HIF_NAPI_STATS
  10985. + hif->napi_counters[NAPI_DESC_COUNT]++;
  10986. +#endif
  10987. + len = BD_BUF_LEN(local_desc.ctrl);
  10988. +#if defined(CONFIG_PLATFORM_PCI)
  10989. + pkt_hdr = &hif_hdr;
  10990. + memcpy(pkt_hdr, (void *)PFE_PCI_TO_HOST(local_desc.data), sizeof(struct hif_hdr));
  10991. +#else
  10992. + //dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data), hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
  10993. + DMA_UNMAP_SINGLE(hif->dev, DDR_PFE_TO_PHYS(local_desc.data), hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
  10994. +
  10995. + pkt_hdr = (struct hif_hdr *)hif->rx_buf_addr[rtc];
  10996. +
  10997. + /* Track last HIF header received */
  10998. + if (!hif->started) {
  10999. + hif->started = 1;
  11000. +
  11001. + __memcpy8(&hif_hdr, pkt_hdr);
  11002. +
  11003. + hif->qno = hif_hdr.hdr.qNo;
  11004. + hif->client_id = hif_hdr.hdr.client_id;
  11005. + hif->client_ctrl = (hif_hdr.hdr.client_ctrl1 << 16) | hif_hdr.hdr.client_ctrl;
  11006. + flags = CL_DESC_FIRST;
  11007. +
  11008. +// printk(KERN_INFO "start of packet: id %d, q %d, len %d, flags %x %x\n", hif->client_id, hif->qno, len, local_desc.ctrl, hif->client_ctrl);
  11009. + }
  11010. + else {
  11011. +// printk(KERN_INFO "continuation: id %d, q %d, len %d, flags %x\n", hif->client_id, hif->qno, len, local_desc.ctrl);
  11012. + flags = 0;
  11013. + }
  11014. +
  11015. + if (local_desc.ctrl & BD_CTRL_LIFM)
  11016. + flags |= CL_DESC_LAST;
  11017. +#endif
  11018. + /* Check for valid client id and still registered */
  11019. + if ((hif->client_id >= HIF_CLIENTS_MAX) || !(test_bit(hif->client_id, &hif->shm->gClient_status[0]))) {
  11020. + if (printk_ratelimit())
  11021. + printk(KERN_ERR "%s: packet with invalid client id %d qNo %d\n", __func__, hif->client_id, hif->qno);
  11022. +
  11023. +#if defined(CONFIG_PLATFORM_PCI)
  11024. + free_buf = local_desc.data;
  11025. +#else
  11026. + free_buf = pkt_hdr;
  11027. +#endif
  11028. + goto pkt_drop;
  11029. + }
  11030. +
  11031. + /* Check to valid queue number */
  11032. + if (hif->client[hif->client_id].rx_qn <= hif->qno) {
  11033. + printk(KERN_INFO "%s: packet with invalid queue: %d\n", __func__, hif->qno);
  11034. + hif->qno = 0;
  11035. + }
  11036. +
  11037. +#if defined(CONFIG_PLATFORM_PCI)
  11038. + free_buf = client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno],
  11039. + (void *)PFE_PCI_TO_HOST(desc->data), len, flags, hif->client_ctrl, &buf_zize);
  11040. +#else
  11041. + free_buf = client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno],
  11042. + (void *)pkt_hdr, len, flags, hif->client_ctrl, &buf_size);
  11043. +#endif
  11044. +
  11045. + hif_lib_indicate_client(hif->client_id, EVENT_RX_PKT_IND, hif->qno);
  11046. +
  11047. + if (unlikely(!free_buf)) {
  11048. +#ifdef HIF_NAPI_STATS
  11049. + hif->napi_counters[NAPI_CLIENT_FULL_COUNT]++;
  11050. +#endif
  11051. + /* If we want to keep in polling mode to retry later, we need to tell napi that we consumed
  11052. + the full budget or we will hit a livelock scenario. The core code keeps this napi instance
  11053. + at the head of the list and none of the other instances get to run */
  11054. + rx_processed = budget;
  11055. +
  11056. + if (flags & CL_DESC_FIRST)
  11057. + hif->started = 0;
  11058. +
  11059. + break;
  11060. + }
  11061. +
  11062. + pkt_drop:
  11063. +#if defined(CONFIG_PLATFORM_PCI)
  11064. + desc->data = (u32)free_buf;
  11065. +#else
  11066. + /*Fill free buffer in the descriptor */
  11067. + hif->rx_buf_addr[rtc] = free_buf;
  11068. + hif->rx_buf_len[rtc] = min(pfe_pkt_size, buf_size);
  11069. + desc->data = DDR_PHYS_TO_PFE((u32)DMA_MAP_SINGLE(hif->dev, free_buf, hif->rx_buf_len[rtc], DMA_FROM_DEVICE));
  11070. + //printk("#%p %p %d\n", desc->data, hif->rx_buf_addr[rtc], hif->rx_buf_len[rtc]);
  11071. +#endif
  11072. + wmb();
  11073. + desc->ctrl = BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR |
  11074. + BD_CTRL_DESC_EN | BD_BUF_LEN(hif->rx_buf_len[rtc]);
  11075. +
  11076. + inc_hif_rxidx(rtc);
  11077. +
  11078. + if (local_desc.ctrl & BD_CTRL_LIFM) {
  11079. + if (!(hif->client_ctrl & HIF_CTRL_RX_CONTINUED)) {
  11080. + rx_processed++;
  11081. +
  11082. +#ifdef HIF_NAPI_STATS
  11083. + hif->napi_counters[NAPI_PACKET_COUNT]++;
  11084. +#endif
  11085. + }
  11086. + hif->started = 0;
  11087. + }
  11088. + }
  11089. +
  11090. + hif->RxtocleanIndex = rtc;
  11091. + spin_unlock_bh(&hif->lock);
  11092. +
  11093. + /* we made some progress, re-start rx dma in case it stopped */
  11094. + hif_rx_dma_start();
  11095. +
  11096. + return rx_processed;
  11097. +}
  11098. +
  11099. +
  11100. +/* client_ack_txpacket-
  11101. + * This function ack the Tx packet in the give client Tx queue by resetting
  11102. + * ownership bit in the descriptor.
  11103. + */
  11104. +static int client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no)
  11105. +{
  11106. + struct hif_tx_queue *queue = &hif->client[client_id].tx_q[q_no];
  11107. + struct tx_queue_desc *desc = queue->base + queue->ack_idx;
  11108. +
  11109. + if (desc->ctrl & CL_DESC_OWN) {
  11110. + /*TODO Do we need to match the pkt address also? */
  11111. + desc->ctrl &= ~CL_DESC_OWN;
  11112. + inc_cl_idx(queue->ack_idx);
  11113. +
  11114. + return 0;
  11115. + }
  11116. + else {
  11117. + /*This should not happen */
  11118. + printk(KERN_ERR "%s: %d %d %d %d %d %p %d\n", __func__, hif->Txtosend, hif->Txtoclean, hif->TxAvail, client_id, q_no, queue, queue->ack_idx);
  11119. + BUG();
  11120. + return 1;
  11121. + }
  11122. +}
  11123. +
  11124. +void __hif_tx_done_process(struct pfe_hif *hif, int count)
  11125. +{
  11126. + struct hif_desc *desc;
  11127. + struct hif_desc_sw *desc_sw;
  11128. + int ttc, tx_avl;
  11129. +
  11130. + ttc = hif->Txtoclean;
  11131. + tx_avl = hif->TxAvail;
  11132. +
  11133. + while ((tx_avl < hif->TxRingSize) && count--) {
  11134. + desc = hif->TxBase + ttc;
  11135. +
  11136. + if (desc->ctrl & BD_CTRL_DESC_EN)
  11137. + break;
  11138. +
  11139. + desc_sw = &hif->tx_sw_queue[ttc];
  11140. +
  11141. + if (desc_sw->data) {
  11142. +#if !defined(CONFIG_PLATFORM_PCI)
  11143. + //dmap_unmap_single(hif->dev, desc_sw->data, desc_sw->len, DMA_TO_DEVICE);
  11144. + DMA_UNMAP_SINGLE(hif->dev, desc_sw->data, desc_sw->len, DMA_TO_DEVICE);
  11145. +#endif
  11146. + }
  11147. + client_ack_txpacket(hif, desc_sw->client_id, desc_sw->q_no);
  11148. +
  11149. + inc_hif_txidx(ttc);
  11150. + tx_avl++;
  11151. + }
  11152. +
  11153. + hif->Txtoclean = ttc;
  11154. + hif->TxAvail = tx_avl;
  11155. +}
  11156. +
  11157. +
  11158. +/* __hif_xmit_pkt -
  11159. + * This function puts one packet in the HIF Tx queue
  11160. + */
  11161. +void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, void *data, u32 len, unsigned int flags)
  11162. +{
  11163. + struct hif_desc *desc;
  11164. + struct hif_desc_sw *desc_sw;
  11165. +
  11166. +#if defined(CONFIG_PLATFORM_EMULATION)
  11167. + {
  11168. + struct hif_queue *queue = &hif->client[client_id].rx_q[0];
  11169. + struct queue_desc *qdesc = queue->base + queue->write_idx;
  11170. + void *buf;
  11171. +
  11172. + printk("%s: packet loop backed client_id:%d qno:%d data : %p len:%d\n", __func__, client_id, q_no, data, len);
  11173. +#if 1
  11174. + if (qdesc->ctrl & CL_DESC_OWN) {
  11175. + buf = (void *)qdesc->data;
  11176. + memcpy(buf, data, len);
  11177. + wmb();
  11178. + qdesc->ctrl = CL_DESC_BUF_LEN(len);
  11179. + inc_cl_idx(queue->write_idx);
  11180. + printk("%s: packet loop backed..\n", __func__);
  11181. + hif_lib_indicate_client(client_id, EVENT_RX_PKT_IND, q_no);
  11182. + client_ack_txpacket(&hif->client[client_id].tx_q[q_no]);
  11183. + }
  11184. +#endif
  11185. + }
  11186. +
  11187. +#else
  11188. + desc = hif->TxBase + hif->Txtosend;
  11189. + desc_sw = &hif->tx_sw_queue[hif->Txtosend];
  11190. +
  11191. + desc_sw->len = len;
  11192. + desc_sw->client_id = client_id;
  11193. + desc_sw->q_no = q_no;
  11194. + desc_sw->flags = flags;
  11195. +
  11196. +#if !defined(CONFIG_PLATFORM_PCI)
  11197. + if (flags & HIF_DONT_DMA_MAP) {
  11198. + desc_sw->data = 0;
  11199. + desc->data = (u32)DDR_PHYS_TO_PFE(data);
  11200. + } else {
  11201. + desc_sw->data = DMA_MAP_SINGLE(hif->dev, data, len, DMA_TO_DEVICE);
  11202. + desc->data = (u32)DDR_PHYS_TO_PFE(desc_sw->data);
  11203. + }
  11204. +#else
  11205. +#define ALIGN32(x) ((x) & ~0x3)
  11206. + memcpy(PFE_PCI_TO_HOST(desc->data), data, ALIGN32(len+0x3));
  11207. +#endif
  11208. +
  11209. + inc_hif_txidx(hif->Txtosend);
  11210. + hif->TxAvail--;
  11211. +
  11212. + /* For TSO we skip actual TX until the last descriptor */
  11213. + /* This reduce the number of required wmb() */
  11214. + if ((flags & HIF_TSO) && (!((flags & HIF_DATA_VALID) && (flags & HIF_LAST_BUFFER))))
  11215. + goto skip_tx;
  11216. +
  11217. + wmb();
  11218. +
  11219. + do {
  11220. + desc_sw = &hif->tx_sw_queue[hif->Txtoflush];
  11221. + desc = hif->TxBase + hif->Txtoflush;
  11222. +
  11223. + if (desc_sw->flags & HIF_LAST_BUFFER) {
  11224. + if ((desc_sw->client_id < PFE_CL_VWD0) || (desc_sw->client_id > (PFE_CL_VWD0 + MAX_VAP_SUPPORT)))
  11225. + desc->ctrl = BD_CTRL_LIFM | BD_CTRL_BRFETCH_DISABLE |
  11226. + BD_CTRL_RTFETCH_DISABLE | BD_CTRL_PARSE_DISABLE |
  11227. + BD_CTRL_DESC_EN | BD_BUF_LEN(desc_sw->len);
  11228. + else {
  11229. +
  11230. + desc->ctrl = BD_CTRL_LIFM | BD_CTRL_DESC_EN | BD_BUF_LEN(desc_sw->len);
  11231. + }
  11232. + }
  11233. + else
  11234. + desc->ctrl = BD_CTRL_DESC_EN | BD_BUF_LEN(desc_sw->len);
  11235. +
  11236. + inc_hif_txidx(hif->Txtoflush);
  11237. + }
  11238. + while (hif->Txtoflush != hif->Txtosend);
  11239. +
  11240. +skip_tx:
  11241. + return;
  11242. +
  11243. +#endif
  11244. +}
  11245. +
  11246. +
  11247. +int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, void *data, unsigned int len)
  11248. +{
  11249. + int rc = 0;
  11250. +
  11251. + spin_lock_bh(&hif->tx_lock);
  11252. +
  11253. + if (!hif->TxAvail)
  11254. + rc = 1;
  11255. + else {
  11256. + __hif_xmit_pkt(hif, client_id, q_no, data, len, HIF_FIRST_BUFFER | HIF_LAST_BUFFER);
  11257. + hif_tx_dma_start();
  11258. + }
  11259. + if (hif->TxAvail < (hif->TxRingSize >> 1))
  11260. + __hif_tx_done_process(hif, TX_FREE_MAX_COUNT);
  11261. +
  11262. + spin_unlock_bh(&hif->tx_lock);
  11263. +
  11264. + return rc;
  11265. +}
  11266. +
  11267. +/* hif_isr-
  11268. + * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block
  11269. + */
  11270. +static irqreturn_t hif_isr(int irq, void *dev_id)
  11271. +{
  11272. + struct pfe_hif *hif = (struct pfe_hif *) dev_id;
  11273. + int int_status;
  11274. +
  11275. + /*Read hif interrupt source register */
  11276. + int_status = readl_relaxed(HIF_INT_SRC);
  11277. +
  11278. + if ((int_status & HIF_INT) == 0)
  11279. + return(IRQ_NONE);
  11280. +
  11281. + int_status &= ~(HIF_INT);
  11282. +
  11283. + if (int_status & HIF_RXPKT_INT) {
  11284. + int_status &= ~(HIF_RXPKT_INT);
  11285. +
  11286. + /* Disable interrupts */
  11287. + writel_relaxed(0, HIF_INT_ENABLE);
  11288. +
  11289. + napi_first_batch = 1;
  11290. +
  11291. + if (napi_schedule_prep(&hif->napi))
  11292. + {
  11293. +#ifdef HIF_NAPI_STATS
  11294. + hif->napi_counters[NAPI_SCHED_COUNT]++;
  11295. +#endif
  11296. + __napi_schedule(&hif->napi);
  11297. + }
  11298. + }
  11299. +
  11300. + if (int_status) {
  11301. + printk(KERN_INFO "%s : Invalid interrupt : %d\n", __func__, int_status);
  11302. + writel(int_status, HIF_INT_SRC);
  11303. + }
  11304. +
  11305. + return IRQ_HANDLED;
  11306. +}
  11307. +
  11308. +
  11309. +void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2)
  11310. +{
  11311. + unsigned int client_id = data1;
  11312. +
  11313. + if (client_id >= HIF_CLIENTS_MAX)
  11314. + {
  11315. + printk(KERN_ERR "%s: client id %d out of bounds\n", __func__, client_id);
  11316. + return;
  11317. + }
  11318. +
  11319. + switch (req) {
  11320. + case REQUEST_CL_REGISTER:
  11321. + /* Request for register a client */
  11322. + printk(KERN_INFO "%s: register client_id %d\n", __func__, client_id);
  11323. + pfe_hif_client_register(hif, client_id, (struct hif_client_shm *)&hif->shm->client[client_id]);
  11324. + break;
  11325. +
  11326. + case REQUEST_CL_UNREGISTER:
  11327. + printk(KERN_INFO "%s: unregister client_id %d\n", __func__, client_id);
  11328. +
  11329. + /* Request for unregister a client */
  11330. + pfe_hif_client_unregister(hif, client_id);
  11331. +
  11332. + break;
  11333. +
  11334. + default:
  11335. + printk(KERN_ERR "%s: unsupported request %d\n", __func__, req);
  11336. + break;
  11337. + }
  11338. +
  11339. + /*TODO check for TMU queue resume request */
  11340. +
  11341. + /*Process client Tx queues
  11342. + * Currently we don't have checking for tx pending*/
  11343. +}
  11344. +
  11345. +/** pfe_hif_rx_poll
  11346. + * This function is NAPI poll function to process HIF Rx queue.
  11347. + */
  11348. +static int pfe_hif_rx_poll(struct napi_struct *napi, int budget)
  11349. +{
  11350. + struct pfe_hif *hif = container_of(napi, struct pfe_hif, napi);
  11351. + int work_done;
  11352. +
  11353. +#ifdef HIF_NAPI_STATS
  11354. + hif->napi_counters[NAPI_POLL_COUNT]++;
  11355. +#endif
  11356. +
  11357. + work_done = pfe_hif_rx_process(hif, budget);
  11358. +
  11359. + if (work_done < budget)
  11360. + {
  11361. + napi_complete(napi);
  11362. + writel_relaxed(HIF_INT_MASK, HIF_INT_ENABLE);
  11363. + }
  11364. +#ifdef HIF_NAPI_STATS
  11365. + else
  11366. + hif->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
  11367. +#endif
  11368. +
  11369. + return work_done;
  11370. +}
  11371. +
  11372. +/* pfe_hif_init
  11373. + * This function initializes the baseaddresses and irq, etc.
  11374. + */
  11375. +int pfe_hif_init(struct pfe *pfe)
  11376. +{
  11377. + struct pfe_hif *hif = &pfe->hif;
  11378. + int err;
  11379. +
  11380. + printk(KERN_INFO "%s\n", __func__);
  11381. +
  11382. + hif->dev = pfe->dev;
  11383. + hif->irq = pfe->hif_irq;
  11384. +
  11385. + if ((err = pfe_hif_alloc_descr(hif))) {
  11386. + goto err0;
  11387. + }
  11388. +
  11389. + if (pfe_hif_init_buffers(hif)) {
  11390. + printk(KERN_ERR "%s: Could not initialize buffer descriptors\n", __func__);
  11391. + err = -ENOMEM;
  11392. + goto err1;
  11393. + }
  11394. +
  11395. + /* Initilize NAPI for Rx processing */
  11396. + init_dummy_netdev(&hif->dummy_dev);
  11397. + netif_napi_add(&hif->dummy_dev, &hif->napi, pfe_hif_rx_poll, HIF_RX_POLL_WEIGHT);
  11398. + napi_enable(&hif->napi);
  11399. +
  11400. + spin_lock_init(&hif->tx_lock);
  11401. + spin_lock_init(&hif->lock);
  11402. +
  11403. + hif_init();
  11404. + hif_rx_enable();
  11405. + hif_tx_enable();
  11406. +
  11407. + /* Disable tx done interrupt */
  11408. + writel(HIF_INT_MASK, HIF_INT_ENABLE);
  11409. +
  11410. + gpi_enable(HGPI_BASE_ADDR);
  11411. +
  11412. +#ifdef __KERNEL__
  11413. + err = request_irq(hif->irq, hif_isr, 0, "pfe_hif", hif);
  11414. + if (err) {
  11415. + printk(KERN_ERR "%s: failed to get the hif IRQ = %d\n", __func__, hif->irq);
  11416. + goto err1;
  11417. + }
  11418. +#else
  11419. + /*TODO register interrupts */
  11420. +#endif
  11421. +
  11422. + return 0;
  11423. +err1:
  11424. + pfe_hif_free_descr(hif);
  11425. +err0:
  11426. + return err;
  11427. +}
  11428. +
  11429. +/* pfe_hif_exit-
  11430. + */
  11431. +void pfe_hif_exit(struct pfe *pfe)
  11432. +{
  11433. + struct pfe_hif *hif = &pfe->hif;
  11434. +
  11435. + printk(KERN_INFO "%s\n", __func__);
  11436. +
  11437. + spin_lock_bh(&hif->lock);
  11438. + hif->shm->gClient_status[0] = 0;
  11439. + hif->shm->gClient_status[1] = 0; /* Make sure all clients are disabled */
  11440. +
  11441. + spin_unlock_bh(&hif->lock);
  11442. +
  11443. + /*Disable Rx/Tx */
  11444. + gpi_disable(HGPI_BASE_ADDR);
  11445. + hif_rx_disable();
  11446. + hif_tx_disable();
  11447. +
  11448. + napi_disable(&hif->napi);
  11449. + netif_napi_del(&hif->napi);
  11450. +
  11451. +#ifdef __KERNEL__
  11452. + free_irq(hif->irq, hif);
  11453. +#endif
  11454. + pfe_hif_release_buffers(hif);
  11455. + pfe_hif_free_descr(hif);
  11456. +}
  11457. --- /dev/null
  11458. +++ b/drivers/staging/fsl_ppfe/pfe_hif.h
  11459. @@ -0,0 +1,322 @@
  11460. +/*
  11461. + *
  11462. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  11463. + *
  11464. + * This program is free software; you can redistribute it and/or modify
  11465. + * it under the terms of the GNU General Public License as published by
  11466. + * the Free Software Foundation; either version 2 of the License, or
  11467. + * (at your option) any later version.
  11468. + *
  11469. + * This program is distributed in the hope that it will be useful,
  11470. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11471. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11472. + * GNU General Public License for more details.
  11473. + *
  11474. + * You should have received a copy of the GNU General Public License
  11475. + * along with this program; if not, write to the Free Software
  11476. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  11477. + */
  11478. +
  11479. +#ifndef _PFE_HIF_H_
  11480. +#define _PFE_HIF_H_
  11481. +
  11482. +#include <linux/netdevice.h>
  11483. +
  11484. +#define HIF_NAPI_STATS
  11485. +
  11486. +#define HIF_CLIENT_QUEUES_MAX 16
  11487. +#define HIF_RX_POLL_WEIGHT 64
  11488. +
  11489. +#define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */
  11490. +#define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1)
  11491. +#define ROUND_MIN_RX_SIZE(_sz) ((_sz + (HIF_RX_PKT_MIN_SIZE - 1)) & HIF_RX_PKT_MIN_SIZE_MASK)
  11492. +#define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)_buf & (PAGE_SIZE - 1)) & HIF_RX_PKT_MIN_SIZE_MASK)
  11493. +
  11494. +enum {
  11495. + NAPI_SCHED_COUNT = 0,
  11496. + NAPI_POLL_COUNT,
  11497. + NAPI_PACKET_COUNT,
  11498. + NAPI_DESC_COUNT,
  11499. + NAPI_FULL_BUDGET_COUNT,
  11500. + NAPI_CLIENT_FULL_COUNT,
  11501. + NAPI_MAX_COUNT
  11502. +};
  11503. +
  11504. +
  11505. +/* XXX HIF_TX_DESC_NT value should be always greter than 4,
  11506. + * Otherwise HIF_TX_POLL_MARK will become zero.
  11507. + */
  11508. +#if defined(CONFIG_PLATFORM_PCI)
  11509. +#define HIF_RX_DESC_NT 4
  11510. +#define HIF_TX_DESC_NT 4
  11511. +#else
  11512. +#if defined(CONFIG_COMCERTO_64K_PAGES)
  11513. +#define HIF_RX_DESC_NT 64
  11514. +#else
  11515. +#define HIF_RX_DESC_NT 256
  11516. +#endif
  11517. +#define HIF_TX_DESC_NT 2048
  11518. +#endif
  11519. +
  11520. +#define HIF_FIRST_BUFFER (1 << 0)
  11521. +#define HIF_LAST_BUFFER (1 << 1)
  11522. +#define HIF_DONT_DMA_MAP (1 << 2) //TODO merge it with TSO
  11523. +#define HIF_DATA_VALID (1 << 3)
  11524. +#define HIF_TSO (1 << 4)
  11525. +
  11526. +#define MAX_VAP_SUPPORT 3
  11527. +#define MAX_WIFI_VAPS MAX_VAP_SUPPORT
  11528. +
  11529. +enum {
  11530. + PFE_CL_GEM0 = 0,
  11531. + PFE_CL_GEM1,
  11532. + PFE_CL_GEM2,
  11533. + PFE_CL_VWD0,
  11534. + PFE_CL_VWD_LAST = PFE_CL_VWD0 + MAX_VAP_SUPPORT,
  11535. + PFE_CL_PCAP0,
  11536. + HIF_CLIENTS_MAX
  11537. +};
  11538. +
  11539. +/*structure to store client queue info */
  11540. +struct hif_rx_queue {
  11541. + struct rx_queue_desc *base;
  11542. + u32 size;
  11543. + u32 write_idx;
  11544. +};
  11545. +
  11546. +struct hif_tx_queue {
  11547. + struct tx_queue_desc *base;
  11548. + u32 size;
  11549. + u32 ack_idx;
  11550. +};
  11551. +
  11552. +/*Structure to store the client info */
  11553. +struct hif_client {
  11554. + int rx_qn;
  11555. + struct hif_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX];
  11556. + int tx_qn;
  11557. + struct hif_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX];
  11558. +};
  11559. +
  11560. +/*HIF hardware buffer descriptor */
  11561. +struct hif_desc {
  11562. + volatile u32 ctrl;
  11563. + volatile u32 status;
  11564. + volatile u32 data;
  11565. + volatile u32 next;
  11566. +};
  11567. +
  11568. +struct __hif_desc {
  11569. + u32 ctrl;
  11570. + u32 status;
  11571. + u32 data;
  11572. +};
  11573. +
  11574. +struct hif_desc_sw {
  11575. + dma_addr_t data;
  11576. + u16 len;
  11577. + u8 client_id;
  11578. + u8 q_no;
  11579. + u16 flags;
  11580. +};
  11581. +
  11582. +struct hif_hdr {
  11583. + u8 client_id;
  11584. + u8 qNo;
  11585. + u16 client_ctrl;
  11586. + u16 client_ctrl1;
  11587. +};
  11588. +
  11589. +struct __hif_hdr {
  11590. + union {
  11591. + struct hif_hdr hdr;
  11592. + u32 word[2];
  11593. + };
  11594. +};
  11595. +
  11596. +struct hif_lro_hdr {
  11597. + u16 data_offset;
  11598. + u16 mss;
  11599. +};
  11600. +
  11601. +struct hif_ipsec_hdr {
  11602. + u16 sa_handle[2];
  11603. +}__attribute__((packed));
  11604. +
  11605. +#define MAX_TSO_BUF_DESCS 5
  11606. +struct hif_tso_buf_desc {
  11607. + u32 addr;
  11608. + u32 ctrl;
  11609. +#define TSO_CTRL_LAST_BUFFER (1 << 31)
  11610. +};
  11611. +
  11612. +struct hif_tso_hdr {
  11613. + struct hif_hdr pkt_hdr;
  11614. + u16 ip_off;
  11615. + u16 ip_id;
  11616. + u16 ip_len;
  11617. + u16 tcp_off;
  11618. + u32 tcp_seq;
  11619. +} __attribute__((packed));
  11620. +
  11621. +struct hif_tso_hdr_nocpy {
  11622. + struct hif_tso_hdr tso_hdr;
  11623. + struct hif_tso_buf_desc bdesc[MAX_TSO_BUF_DESCS];
  11624. +} __attribute__((packed));
  11625. +
  11626. +struct hif_pcap_hdr {
  11627. + u8 ifindex;
  11628. + u8 unused;
  11629. + u16 seqno;
  11630. + u32 timestamp;
  11631. +}__attribute__((packed));
  11632. +
  11633. +/* HIF_CTRL_TX... defines */
  11634. +#define HIF_CTRL_TX_TSO_NOCPY (1 << 8)
  11635. +#define HIF_CTRL_TX_IPSEC_OUT (1 << 7)
  11636. +#define HIF_CTRL_TX_OWN_MAC (1 << 6)
  11637. +#define HIF_CTRL_TX_TSO_END (1 << 5)
  11638. +#define HIF_CTRL_TX_TSO6 (1 << 4)
  11639. +#define HIF_CTRL_TX_TSO (1 << 3)
  11640. +#define HIF_CTRL_TX_CHECKSUM (1 << 2)
  11641. +#define HIF_CTRL_TX_CSUM_VALIDATE (1 << 1)
  11642. +#define HIF_CTRL_TX_WIFI (1 << 0)
  11643. +
  11644. +/* HIF_CTRL_RX... defines */
  11645. +#define HIF_CTRL_RX_OFFSET_OFST (24)
  11646. +#define HIF_CTRL_RX_PE_ID_OFST (16)
  11647. +#define HIF_CTRL_RX_IPSEC_IN (1 << 4)
  11648. +#define HIF_CTRL_RX_WIFI_EXPT (1 << 3)
  11649. +#define HIF_CTRL_RX_CHECKSUMMED (1 << 2)
  11650. +#define HIF_CTRL_RX_CONTINUED (1 << 1)
  11651. +#define HIF_CTRL_RX_WIFI_HEADROOM (1 << 0)
  11652. +
  11653. +#define HIF_CTRL_VAPID_OFST (8)
  11654. +
  11655. +struct pfe_hif {
  11656. + /* To store registered clients in hif layer */
  11657. + struct hif_client client[HIF_CLIENTS_MAX];
  11658. + struct hif_shm *shm;
  11659. + int irq;
  11660. +
  11661. + void *descr_baseaddr_v;
  11662. + unsigned long descr_baseaddr_p;
  11663. +
  11664. + struct hif_desc *RxBase;
  11665. + u32 RxRingSize;
  11666. + u32 RxtocleanIndex;
  11667. + void *rx_buf_addr[HIF_RX_DESC_NT];
  11668. + int rx_buf_len[HIF_RX_DESC_NT];
  11669. + unsigned int qno;
  11670. + unsigned int client_id;
  11671. + unsigned int client_ctrl;
  11672. + unsigned int started;
  11673. +
  11674. + struct hif_desc *TxBase;
  11675. + u32 TxRingSize;
  11676. + u32 Txtosend;
  11677. + u32 Txtoclean;
  11678. + u32 TxAvail;
  11679. + u32 Txtoflush;
  11680. + struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT];
  11681. + struct hif_tso_hdr_nocpy *tso_hdr_v;
  11682. + dma_addr_t tso_hdr_p;
  11683. +
  11684. + spinlock_t tx_lock;
  11685. + spinlock_t lock;
  11686. + struct net_device dummy_dev;
  11687. + struct napi_struct napi;
  11688. + struct device *dev;
  11689. +
  11690. +#ifdef CONFIG_HOTPLUG_CPU
  11691. + struct notifier_block cpu_notify;
  11692. +#endif
  11693. +
  11694. +#ifdef HIF_NAPI_STATS
  11695. + unsigned int napi_counters[NAPI_MAX_COUNT];
  11696. +#endif
  11697. +};
  11698. +
  11699. +void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, void *data, u32 len, unsigned int flags);
  11700. +int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, void *data, unsigned int len);
  11701. +void __hif_tx_done_process(struct pfe_hif *hif, int count);
  11702. +void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2);
  11703. +int pfe_hif_init(struct pfe *pfe);
  11704. +void pfe_hif_exit(struct pfe *pfe);
  11705. +
  11706. +static inline void hif_tx_done_process(struct pfe_hif *hif, int count)
  11707. +{
  11708. + spin_lock_bh(&hif->tx_lock);
  11709. + __hif_tx_done_process(hif, count);
  11710. + spin_unlock_bh(&hif->tx_lock);
  11711. +}
  11712. +
  11713. +static inline void hif_tx_lock(struct pfe_hif *hif)
  11714. +{
  11715. + spin_lock_bh(&hif->tx_lock);
  11716. +}
  11717. +
  11718. +static inline void hif_tx_unlock(struct pfe_hif *hif)
  11719. +{
  11720. + spin_unlock_bh(&hif->tx_lock);
  11721. +}
  11722. +
  11723. +static inline int __hif_tx_avail(struct pfe_hif *hif)
  11724. +{
  11725. + return hif->TxAvail;
  11726. +}
  11727. +
  11728. +#if defined(CONFIG_PLATFORM_C2000)
  11729. +static inline void __memcpy8(void *dst, void *src)
  11730. +{
  11731. + asm volatile ( "ldm %1, {r9, r10}\n\t"
  11732. + "stm %0, {r9, r10}\n\t"
  11733. + :
  11734. + : "r" (dst), "r" (src)
  11735. + : "r9", "r10", "memory"
  11736. + );
  11737. +}
  11738. +
  11739. +static inline void __memcpy12(void *dst, void *src)
  11740. +{
  11741. + asm volatile ( "ldm %1, {r8, r9, r10}\n\t"
  11742. + "stm %0, {r8, r9, r10}\n\t"
  11743. + :
  11744. + : "r" (dst), "r" (src)
  11745. + : "r8", "r9", "r10", "memory"
  11746. + );
  11747. +}
  11748. +
  11749. +static inline void __memcpy16(void *dst, void *src)
  11750. +{
  11751. + asm volatile ( "ldm %1, {r7, r8, r9, r10}\n\t"
  11752. + "stm %0, {r7, r8, r9, r10}\n\t"
  11753. + :
  11754. + : "r"(dst), "r"(src)
  11755. + : "r7", "r8", "r9", "r10", "memory"
  11756. + );
  11757. +}
  11758. +
  11759. +#define HIF_MEMCPY_BURSTSIZE 32 /*__memcpy copy 32byte in a burst*/
  11760. +static inline void __memcpy(void *dst, void *src, unsigned int len)
  11761. +{
  11762. + void *end = src + len;
  11763. +
  11764. + dst = (void *)((unsigned long)dst & ~0x3);
  11765. + src = (void *)((unsigned long)src & ~0x3);
  11766. +
  11767. + while (src < end) {
  11768. + asm volatile ( "ldm %1!, {r3, r4, r5, r6, r7, r8, r9, r10}\n\t"
  11769. + "stm %0!, {r3, r4, r5, r6, r7, r8, r9, r10}\n\t"
  11770. + : "+r"(dst), "+r"(src)
  11771. + :
  11772. + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "memory"
  11773. + );
  11774. + }
  11775. +}
  11776. +#else
  11777. +#define __memcpy8(dst, src) memcpy(dst, src, 8)
  11778. +#define __memcpy12(dst, src) memcpy(dst, src, 12)
  11779. +#define __memcpy(dst, src, len) memcpy(dst, src, len)
  11780. +#endif
  11781. +#endif /* _PFE_HIF_H_ */
  11782. --- /dev/null
  11783. +++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
  11784. @@ -0,0 +1,658 @@
  11785. +/*
  11786. + *
  11787. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  11788. + *
  11789. + * This program is free software; you can redistribute it and/or modify
  11790. + * it under the terms of the GNU General Public License as published by
  11791. + * the Free Software Foundation; either version 2 of the License, or
  11792. + * (at your option) any later version.
  11793. + *
  11794. + * This program is distributed in the hope that it will be useful,
  11795. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11796. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11797. + * GNU General Public License for more details.
  11798. + *
  11799. + * You should have received a copy of the GNU General Public License
  11800. + * along with this program; if not, write to the Free Software
  11801. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  11802. + */
  11803. +
  11804. +#include <linux/version.h>
  11805. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  11806. +#include <asm/system.h>
  11807. +#endif
  11808. +#include <linux/kernel.h>
  11809. +#include <linux/slab.h>
  11810. +#include <linux/interrupt.h>
  11811. +#include <linux/workqueue.h>
  11812. +#include <linux/dma-mapping.h>
  11813. +#include <linux/dmapool.h>
  11814. +#include <linux/sched.h>
  11815. +#include <linux/skbuff.h>
  11816. +#include <linux/moduleparam.h>
  11817. +#include <linux/cpu.h>
  11818. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  11819. +//#include <asm/system_info.h>
  11820. +#endif
  11821. +
  11822. +#include "pfe_mod.h"
  11823. +#include "pfe_hif.h"
  11824. +#include "pfe_hif_lib.h"
  11825. +#include "pfe_ctrl_hal.h"
  11826. +
  11827. +
  11828. +unsigned int lro_mode = 0;
  11829. +unsigned int page_mode = 0;
  11830. +unsigned int tx_qos = 0;
  11831. +unsigned int pfe_pkt_size;
  11832. +unsigned int pfe_pkt_headroom;
  11833. +unsigned int emac_txq_cnt;
  11834. +
  11835. +/** @pfe_hal_lib.c.
  11836. + * Common functions used by HIF client drivers
  11837. + */
  11838. +
  11839. +/*HIF shared memory Global variable */
  11840. +struct hif_shm ghif_shm;
  11841. +
  11842. +/* TMU tx transmitted packets counter, 1 per TMU */
  11843. +unsigned int TMU_DMEM_SH(tx_trans)[EMAC_TXQ_CNT];
  11844. +
  11845. +/* Cleanup the HIF shared memory, release HIF rx_buffer_pool.
  11846. + * This function should be called after pfe_hif_exit
  11847. + *
  11848. + * @param[in] hif_shm Shared memory address location in DDR
  11849. + */
  11850. +static void pfe_hif_shm_clean(struct hif_shm *hif_shm)
  11851. +{
  11852. + int i;
  11853. + void *pkt;
  11854. +
  11855. + for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
  11856. + pkt = hif_shm->rx_buf_pool[i];
  11857. + if (pkt) {
  11858. + hif_shm->rx_buf_pool[i] = NULL;
  11859. + pkt -= pfe_pkt_headroom;
  11860. +
  11861. + if (page_mode) {
  11862. + put_page(virt_to_page(pkt));
  11863. + } else
  11864. + kfree(pkt);
  11865. + }
  11866. + }
  11867. +}
  11868. +
  11869. +/* Initialize shared memory used between HIF driver and clients,
  11870. + * allocate rx_buffer_pool required for HIF Rx descriptors.
  11871. + * This function should be called before initializing HIF driver.
  11872. + *
  11873. + * @param[in] hif_shm Shared memory address location in DDR
  11874. + * @rerurn 0 - on succes, <0 on fail to initialize
  11875. + */
  11876. +static int pfe_hif_shm_init(struct hif_shm *hif_shm)
  11877. +{
  11878. + int i;
  11879. + void *pkt;
  11880. +
  11881. + memset(hif_shm, 0, sizeof(struct hif_shm));
  11882. + hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT;
  11883. +
  11884. + for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
  11885. + if (page_mode) {
  11886. + pkt = (void *)__get_free_page(GFP_KERNEL | GFP_DMA_PFE);
  11887. + } else
  11888. + pkt = kmalloc(PFE_BUF_SIZE, GFP_KERNEL | GFP_DMA_PFE);
  11889. +
  11890. + if (pkt)
  11891. + hif_shm->rx_buf_pool[i] = pkt + pfe_pkt_headroom;
  11892. + else
  11893. + goto err0;
  11894. + }
  11895. +
  11896. + return 0;
  11897. +
  11898. +err0:
  11899. + printk(KERN_ERR "%s Low memory\n", __func__);
  11900. + pfe_hif_shm_clean(hif_shm);
  11901. + return -ENOMEM;
  11902. +}
  11903. +
  11904. +/*This function sends indication to HIF driver
  11905. + *
  11906. + * @param[in] hif hif context
  11907. + **/
  11908. +static void hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int data2)
  11909. +{
  11910. + //TODO : If we separate HIF and HIF LIB, then send req and data through shared memory.
  11911. +
  11912. + hif_process_client_req(hif, req, data1, data2);
  11913. +}
  11914. +
  11915. +void hif_lib_indicate_client(int client_id, int event_type, int qno)
  11916. +{
  11917. + struct hif_client_s *client = pfe->hif_client[client_id];
  11918. +
  11919. + /*
  11920. + * TODO : Right now, all events are queue number based. So we are masking events per queue
  11921. + * basis. Later if we add any events those do not depend on queue number, then we may
  11922. + * may need may need to add masking per event.
  11923. + */
  11924. + if (!client || (event_type >= HIF_EVENT_MAX) || (qno >= HIF_CLIENT_QUEUES_MAX) )
  11925. + return;
  11926. +
  11927. + if (!test_and_set_bit(qno, &client->queue_mask[event_type])) {
  11928. + client->event_handler(client->priv, event_type, qno);
  11929. + }
  11930. +
  11931. +}
  11932. +
  11933. +
  11934. +/*This function releases Rx queue descriptors memory and pre-filled buffers
  11935. + *
  11936. + * @param[in] client hif_client context
  11937. + */
  11938. +static void hif_lib_client_release_rx_buffers(struct hif_client_s *client)
  11939. +{
  11940. + struct rx_queue_desc *desc;
  11941. + int qno, ii;
  11942. + void *buf;
  11943. +
  11944. + for (qno = 0; qno < client->rx_qn; qno++) {
  11945. + desc = client->rx_q[qno].base;
  11946. +
  11947. + for (ii = 0; ii < client->rx_q[qno].size; ii++) {
  11948. + buf = (void *)desc->data;
  11949. + if (buf) {
  11950. + buf -= pfe_pkt_headroom;
  11951. +
  11952. + if (page_mode)
  11953. + free_page((unsigned long)buf);
  11954. + else
  11955. + kfree(buf);
  11956. +
  11957. + desc->ctrl = 0;
  11958. + }
  11959. +
  11960. + desc++;
  11961. + }
  11962. + }
  11963. +
  11964. + kfree(client->rx_qbase);
  11965. +}
  11966. +
  11967. +
  11968. +/*This function allocates memory for the rxq descriptors and pre-fill rx queues
  11969. + * with buffers.
  11970. + * @param[in] client client context
  11971. + * @param[in] q_size size of the rxQ, all queues are of same size
  11972. + */
  11973. +static int hif_lib_client_init_rx_buffers(struct hif_client_s *client, int q_size)
  11974. +{
  11975. + struct rx_queue_desc *desc;
  11976. + struct hif_client_rx_queue *queue;
  11977. + int ii, qno;
  11978. +
  11979. + /*Allocate memory for the client queues */
  11980. + client->rx_qbase = kzalloc(client->rx_qn * q_size * sizeof(struct rx_queue_desc), GFP_KERNEL);
  11981. + if (!client->rx_qbase){
  11982. + goto err;
  11983. + }
  11984. +
  11985. + for (qno = 0; qno < client->rx_qn; qno++) {
  11986. + queue = &client->rx_q[qno];
  11987. +
  11988. + queue->base = client->rx_qbase + qno * q_size * sizeof(struct rx_queue_desc);
  11989. + queue->size = q_size;
  11990. + queue->read_idx = 0;
  11991. + queue->write_idx = 0;
  11992. +
  11993. + dbg_print_info("rx queue: %d, base: %p, size: %d \n", qno, queue->base, queue->size);
  11994. + }
  11995. +
  11996. + for (qno = 0; qno < client->rx_qn; qno++) {
  11997. + queue = &client->rx_q[qno];
  11998. + desc = queue->base;
  11999. +
  12000. + for (ii = 0; ii < queue->size; ii++) {
  12001. + desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN;
  12002. + desc++;
  12003. + }
  12004. + }
  12005. +
  12006. + return 0;
  12007. +
  12008. +err:
  12009. + return 1;
  12010. +}
  12011. +
  12012. +#define inc_cl_idx(idxname) idxname = (idxname+1) & (queue->size-1)
  12013. +
  12014. +static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue)
  12015. +{
  12016. + dbg_print_info( "%s\n", __func__);
  12017. +
  12018. + /* Check if there are any pending packets. Client must flush the tx queues
  12019. + before unregistering, by calling by calling hif_lib_tx_get_next_complete() */
  12020. + /* Hif no longer calls since we are no longer registered */
  12021. +
  12022. + if (queue->tx_pending)
  12023. + printk(KERN_ERR "%s: pending transmit packets\n", __func__);
  12024. +}
  12025. +
  12026. +static void hif_lib_client_release_tx_buffers(struct hif_client_s *client)
  12027. +{
  12028. + int qno;
  12029. +
  12030. + dbg_print_info("%s\n", __func__);
  12031. +
  12032. + for (qno = 0; qno < client->tx_qn; qno++) {
  12033. + hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]);
  12034. + }
  12035. +
  12036. + kfree(client->tx_qbase);
  12037. +}
  12038. +
  12039. +static int hif_lib_client_init_tx_buffers(struct hif_client_s *client, int q_size)
  12040. +{
  12041. + struct hif_client_tx_queue *queue;
  12042. + int qno;
  12043. +
  12044. + client->tx_qbase = kzalloc(client->tx_qn * q_size * sizeof(struct tx_queue_desc), GFP_KERNEL);
  12045. + if (!client->tx_qbase) {
  12046. + return 1;
  12047. + }
  12048. +
  12049. + for (qno = 0; qno < client->tx_qn; qno++) {
  12050. + queue = &client->tx_q[qno];
  12051. +
  12052. + queue->base = client->tx_qbase + qno * q_size * sizeof(struct tx_queue_desc);
  12053. + queue->size = q_size;
  12054. + queue->read_idx = 0;
  12055. + queue->write_idx = 0;
  12056. + queue->tx_pending = 0;
  12057. + queue->nocpy_flag = 0;
  12058. + queue->prev_tmu_tx_pkts = 0;
  12059. + queue->done_tmu_tx_pkts = 0;
  12060. +
  12061. + dbg_print_info("tx queue: %d, base: %p, size: %d \n", qno, queue->base, queue->size);
  12062. + }
  12063. +
  12064. + return 0;
  12065. +}
  12066. +
  12067. +static int hif_lib_event_dummy( void *priv, int event_type, int qno)
  12068. +{
  12069. + return 0;
  12070. +}
  12071. +
  12072. +int hif_lib_client_register(struct hif_client_s *client)
  12073. +{
  12074. + struct hif_shm *hif_shm;
  12075. + struct hif_client_shm *client_shm;
  12076. + int err, i;
  12077. +// int loop_cnt = 0;
  12078. +
  12079. + dbg_print_info("%s\n", __func__);
  12080. +
  12081. + /*Allocate memory before spin_lock*/
  12082. + if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) {
  12083. + err = -ENOMEM;
  12084. + goto err_rx;
  12085. + }
  12086. +
  12087. + if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) {
  12088. + err = -ENOMEM;
  12089. + goto err_tx;
  12090. + }
  12091. +
  12092. + spin_lock_bh(&pfe->hif.lock);
  12093. + if (!(client->pfe) || (client->id >= HIF_CLIENTS_MAX) || (pfe->hif_client[client->id])) {
  12094. + err = -EINVAL;
  12095. + goto err;
  12096. + }
  12097. +
  12098. + hif_shm = client->pfe->hif.shm;
  12099. +
  12100. + if (!client->event_handler)
  12101. + client->event_handler = hif_lib_event_dummy;
  12102. +
  12103. + /*Initialize client specific shared memory */
  12104. + client_shm = (struct hif_client_shm *)&hif_shm->client[client->id];
  12105. + client_shm->rx_qbase = (unsigned long int)client->rx_qbase;
  12106. + client_shm->rx_qsize = client->rx_qsize;
  12107. + client_shm->tx_qbase = (unsigned long int)client->tx_qbase;
  12108. + client_shm->tx_qsize = client->tx_qsize;
  12109. + client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) | (client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST);
  12110. +// spin_lock_init(&client->rx_lock);
  12111. +
  12112. + for (i = 0; i < HIF_EVENT_MAX; i++) {
  12113. + client->queue_mask[i] = 0; /* By default all events are unmasked */
  12114. + }
  12115. +
  12116. + /*Indicate to HIF driver*/
  12117. + hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_REGISTER, client->id, 0);
  12118. +
  12119. + dbg_print_info("%s: client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d\n",
  12120. + __func__, client, client->id, client->tx_qsize, client->rx_qsize);
  12121. +
  12122. + client->cpu_id = -1;
  12123. +
  12124. + pfe->hif_client[client->id] = client;
  12125. + spin_unlock_bh(&pfe->hif.lock);
  12126. +
  12127. + return 0;
  12128. +
  12129. +err:
  12130. + spin_unlock_bh(&pfe->hif.lock);
  12131. + hif_lib_client_release_tx_buffers(client);
  12132. +
  12133. +err_tx:
  12134. + hif_lib_client_release_rx_buffers(client);
  12135. +
  12136. +err_rx:
  12137. + return err;
  12138. +}
  12139. +
  12140. +int hif_lib_client_unregister(struct hif_client_s *client)
  12141. +{
  12142. + struct pfe *pfe = client->pfe;
  12143. + u32 client_id = client->id;
  12144. +
  12145. + printk(KERN_INFO "%s : client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d\n",
  12146. + __func__, client, client->id, client->tx_qsize, client->rx_qsize);
  12147. +
  12148. +
  12149. + spin_lock_bh(&pfe->hif.lock);
  12150. + hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0);
  12151. +
  12152. + hif_lib_client_release_tx_buffers(client);
  12153. + hif_lib_client_release_rx_buffers(client);
  12154. + pfe->hif_client[client_id] = NULL;
  12155. + spin_unlock_bh(&pfe->hif.lock);
  12156. +
  12157. + return 0;
  12158. +}
  12159. +
  12160. +int hif_lib_event_handler_start(struct hif_client_s *client, int event, int qno)
  12161. +{
  12162. + struct hif_client_rx_queue *queue = &client->rx_q[qno];
  12163. + struct rx_queue_desc *desc = queue->base + queue->read_idx;
  12164. +
  12165. + if ((event >= HIF_EVENT_MAX) || ( qno >= HIF_CLIENT_QUEUES_MAX)) {
  12166. + dbg_print_info("%s: Unsupported event : %d queue number : %d\n", __func__, event, qno);
  12167. + return -1;
  12168. + }
  12169. +
  12170. + test_and_clear_bit(qno, &client->queue_mask[event]);
  12171. +
  12172. + switch (event) {
  12173. + case EVENT_RX_PKT_IND:
  12174. + if (!(desc->ctrl & CL_DESC_OWN))
  12175. + hif_lib_indicate_client(client->id, EVENT_RX_PKT_IND, qno);
  12176. + break;
  12177. +
  12178. + case EVENT_HIGH_RX_WM:
  12179. + case EVENT_TXDONE_IND:
  12180. + default:
  12181. + break;
  12182. + }
  12183. +
  12184. + return 0;
  12185. +}
  12186. +
  12187. +
  12188. +/*This function gets one packet from the specified client queue
  12189. + * It also refill the rx buffer */
  12190. +void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int *ofst, unsigned int *rx_ctrl, unsigned int *desc_ctrl, void **priv_data)
  12191. +{
  12192. + struct hif_client_rx_queue *queue = &client->rx_q[qno];
  12193. + struct rx_queue_desc *desc;
  12194. + void *pkt = NULL;
  12195. +
  12196. + //printk(KERN_INFO "%s\n", __func__);
  12197. +#if defined(CONFIG_PLATFORM_EMULATION)
  12198. + printk(KERN_INFO "%s:qno:%d cid:%d desc:%p rdidx:%d \n",
  12199. + __func__, qno, client->id, desc,
  12200. + queue->read_idx);
  12201. +#endif
  12202. +
  12203. + /* Following lock is to protect rx queue access from, hif_lib_event_handler_start.
  12204. + * In general below lock is not required, because hif_lib_xmit_pkt and
  12205. + * hif_lib_event_handler_start are called from napi poll and which is not
  12206. + * re-entrant. But if some client use in different way this lock is required.
  12207. + */
  12208. + //spin_lock_irqsave(&client->rx_lock, flags);
  12209. + desc = queue->base + queue->read_idx;
  12210. + if (!(desc->ctrl & CL_DESC_OWN)) {
  12211. + pkt = desc->data - pfe_pkt_headroom;
  12212. +
  12213. + *rx_ctrl = desc->client_ctrl;
  12214. + *desc_ctrl = desc->ctrl;
  12215. +
  12216. + if (desc->ctrl & CL_DESC_FIRST) {
  12217. + u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST;
  12218. +
  12219. + if (size) {
  12220. + *len = CL_DESC_BUF_LEN(desc->ctrl) - PFE_PKT_HEADER_SZ - size;
  12221. + *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ + size;
  12222. + *priv_data = desc->data + PFE_PKT_HEADER_SZ;
  12223. + } else {
  12224. + *len = CL_DESC_BUF_LEN(desc->ctrl) - PFE_PKT_HEADER_SZ;
  12225. + *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ;
  12226. + *priv_data = NULL;
  12227. + }
  12228. +
  12229. + } else {
  12230. + *len = CL_DESC_BUF_LEN(desc->ctrl);
  12231. + *ofst = pfe_pkt_headroom;
  12232. + }
  12233. +
  12234. + desc->data = NULL; // Needed so we don't free a buffer/page twice on module_exit
  12235. + smp_wmb();
  12236. +
  12237. + desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN;
  12238. + inc_cl_idx(queue->read_idx);
  12239. + }
  12240. +
  12241. + //spin_unlock_irqrestore(&client->rx_lock, flags);
  12242. + return pkt;
  12243. +}
  12244. +
  12245. +static inline void hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int client_id, unsigned int qno, u32 client_ctrl)
  12246. +{
  12247. + /* Optimize the write since the destinaton may be non-cacheable */
  12248. + if (!((unsigned long)pkt_hdr & 0x3)) {
  12249. + ((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) | client_id;
  12250. + } else {
  12251. + ((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF);
  12252. + ((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF);
  12253. + }
  12254. +}
  12255. +
  12256. +/*This function puts the given packet in the specific client queue */
  12257. +void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, unsigned int len, u32 client_ctrl, unsigned int flags, void *client_data)
  12258. +{
  12259. + struct hif_client_tx_queue *queue = &client->tx_q[qno];
  12260. + struct tx_queue_desc *desc = queue->base + queue->write_idx;
  12261. +
  12262. + //printk(KERN_INFO "%s\n",__func__);
  12263. +
  12264. + /* First buffer */
  12265. + if (flags & HIF_FIRST_BUFFER)
  12266. + {
  12267. + data -= sizeof(struct hif_hdr);
  12268. + len += sizeof(struct hif_hdr);
  12269. +
  12270. + hif_hdr_write(data, client->id, qno, client_ctrl);
  12271. + }
  12272. +
  12273. + desc->data = client_data;
  12274. + desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags);
  12275. +
  12276. + __hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags);
  12277. +
  12278. + inc_cl_idx(queue->write_idx);
  12279. + queue->tx_pending++;
  12280. + queue->jiffies_last_packet = jiffies;
  12281. +
  12282. +}
  12283. +
  12284. +/*This function puts the given packet in the specific client queue */
  12285. +int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, unsigned int len, u32 client_ctrl, void *client_data)
  12286. +{
  12287. + struct hif_client_tx_queue *queue = &client->tx_q[qno];
  12288. + struct tx_queue_desc *desc = queue->base + queue->write_idx;
  12289. +
  12290. + //printk(KERN_INFO "%s\n",__func__);
  12291. +
  12292. + if (queue->tx_pending < queue->size) {
  12293. + /*Construct pkt header */
  12294. +
  12295. + data -= sizeof(struct hif_hdr);
  12296. + len += sizeof(struct hif_hdr);
  12297. +
  12298. + hif_hdr_write(data, client->id, qno, client_ctrl);
  12299. +
  12300. + desc->data = client_data;
  12301. + desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(HIF_FIRST_BUFFER | HIF_LAST_BUFFER | HIF_DATA_VALID);
  12302. +
  12303. + if (hif_xmit_pkt(&pfe->hif, client->id, qno, data, len))
  12304. + return 1;
  12305. +
  12306. + inc_cl_idx(queue->write_idx);
  12307. + queue->tx_pending++;
  12308. + queue->jiffies_last_packet = jiffies;
  12309. +
  12310. + return 0;
  12311. + }
  12312. +
  12313. + dbg_print_info("%s Tx client %d qno %d is full\n",__func__, client->id, qno);
  12314. + return 1;
  12315. +}
  12316. +
  12317. +void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, unsigned int *flags, int count)
  12318. +{
  12319. + struct hif_client_tx_queue *queue = &client->tx_q[qno];
  12320. + struct tx_queue_desc *desc = queue->base + queue->read_idx;
  12321. +
  12322. + dbg_print_info("%s: qno : %d rd_indx: %d pending:%d\n",__func__, qno, queue->read_idx, queue->tx_pending);
  12323. +
  12324. + if (!queue->tx_pending )
  12325. + return NULL;
  12326. +
  12327. + if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) {
  12328. + u32 tmu_tx_pkts = be32_to_cpu(pe_dmem_read(TMU0_ID + client->id, virt_to_tmu_dmem(&tx_trans[qno]), 4));
  12329. +
  12330. + if (queue->prev_tmu_tx_pkts > tmu_tx_pkts)
  12331. + queue->done_tmu_tx_pkts = UINT_MAX - queue->prev_tmu_tx_pkts + tmu_tx_pkts;
  12332. + else
  12333. + queue->done_tmu_tx_pkts = tmu_tx_pkts - queue->prev_tmu_tx_pkts;
  12334. +
  12335. + queue->prev_tmu_tx_pkts = tmu_tx_pkts;
  12336. +
  12337. + if (!queue->done_tmu_tx_pkts) {
  12338. + return NULL;
  12339. + }
  12340. + }
  12341. +
  12342. + if (desc->ctrl & CL_DESC_OWN) {
  12343. + hif_tx_done_process(&pfe->hif, count);
  12344. +
  12345. + //Check again, if packets done in tx queue.
  12346. + if (desc->ctrl & CL_DESC_OWN)
  12347. + return NULL;
  12348. + }
  12349. +
  12350. + inc_cl_idx(queue->read_idx);
  12351. + queue->tx_pending--;
  12352. +
  12353. + *flags = CL_DESC_GET_FLAGS(desc->ctrl);
  12354. +
  12355. + if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER))
  12356. + queue->done_tmu_tx_pkts--;
  12357. +
  12358. +
  12359. + return desc->data;
  12360. +}
  12361. +
  12362. +//FIXME: TMU queues length mapping needs to be declared in shared PFE/PFE_CTRL header
  12363. +static void hif_lib_tmu_credit_init(struct pfe *pfe)
  12364. +{
  12365. + int i, q;
  12366. +
  12367. + for (i = 0; i < NUM_GEMAC_SUPPORT; i++)
  12368. + for (q = 0; q < emac_txq_cnt; q++) {
  12369. + pfe->tmu_credit.tx_credit_max[i][q] = (q == 0) ? DEFAULT_Q0_QDEPTH : DEFAULT_MAX_QDEPTH;
  12370. + pfe->tmu_credit.tx_credit[i][q] = pfe->tmu_credit.tx_credit_max[i][q];
  12371. + }
  12372. +}
  12373. +/** __hif_lib_update_credit
  12374. + *
  12375. + * @param[in] client hif client context
  12376. + * @param[in] queue queue number in match with TMU
  12377. + */
  12378. +void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue)
  12379. +{
  12380. + unsigned int tmu_tx_packets, tmp;
  12381. +
  12382. + if (tx_qos) {
  12383. + tmu_tx_packets = be32_to_cpu(pe_dmem_read(TMU0_ID + client->id, virt_to_tmu_dmem(&tx_trans[queue]), 4));
  12384. +
  12385. + // tx_packets counter overflowed
  12386. + if (tmu_tx_packets > pfe->tmu_credit.tx_packets[client->id][queue]) {
  12387. + tmp = UINT_MAX - tmu_tx_packets + pfe->tmu_credit.tx_packets[client->id][queue];
  12388. + pfe->tmu_credit.tx_credit[client->id][queue] = pfe->tmu_credit.tx_credit_max[client->id][queue] - tmp;
  12389. + }
  12390. + // TMU tx <= pfe_eth tx, normal case or both OF since last time
  12391. + else
  12392. + pfe->tmu_credit.tx_credit[client->id][queue] = pfe->tmu_credit.tx_credit_max[client->id][queue] - (pfe->tmu_credit.tx_packets[client->id][queue] - tmu_tx_packets);
  12393. + }
  12394. +}
  12395. +
  12396. +/** hif_lib_update_credit
  12397. + *
  12398. + * @param[in] client hif client context
  12399. + * @param[in] queue queue number in match with TMU
  12400. + */
  12401. +void hif_lib_update_credit(struct hif_client_s *client, unsigned int queue)
  12402. +{
  12403. + spin_lock_bh(&pfe->hif.tx_lock);
  12404. + __hif_lib_update_credit(client, queue);
  12405. + spin_unlock_bh(&pfe->hif.tx_lock);
  12406. +}
  12407. +
  12408. +int pfe_hif_lib_init(struct pfe *pfe)
  12409. +{
  12410. + int rc;
  12411. +
  12412. + printk(KERN_INFO "%s\n", __func__);
  12413. +
  12414. + if (lro_mode) {
  12415. + page_mode = 1;
  12416. + pfe_pkt_size = min(PAGE_SIZE, MAX_PFE_PKT_SIZE);
  12417. + pfe_pkt_headroom = 0;
  12418. + } else {
  12419. + page_mode = 0;
  12420. + pfe_pkt_size = PFE_PKT_SIZE;
  12421. + pfe_pkt_headroom = PFE_PKT_HEADROOM;
  12422. + }
  12423. +
  12424. + if (tx_qos)
  12425. + emac_txq_cnt = EMAC_TXQ_CNT / 2;
  12426. + else
  12427. + emac_txq_cnt = EMAC_TXQ_CNT;
  12428. +
  12429. + hif_lib_tmu_credit_init(pfe);
  12430. + pfe->hif.shm = &ghif_shm;
  12431. + rc = pfe_hif_shm_init(pfe->hif.shm);
  12432. +
  12433. + return rc;
  12434. +}
  12435. +
  12436. +
  12437. +void pfe_hif_lib_exit(struct pfe *pfe)
  12438. +{
  12439. + printk(KERN_INFO "%s\n", __func__);
  12440. +
  12441. + pfe_hif_shm_clean(pfe->hif.shm);
  12442. +}
  12443. --- /dev/null
  12444. +++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
  12445. @@ -0,0 +1,219 @@
  12446. +/*
  12447. + *
  12448. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  12449. + *
  12450. + * This program is free software; you can redistribute it and/or modify
  12451. + * it under the terms of the GNU General Public License as published by
  12452. + * the Free Software Foundation; either version 2 of the License, or
  12453. + * (at your option) any later version.
  12454. + *
  12455. + * This program is distributed in the hope that it will be useful,
  12456. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12457. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12458. + * GNU General Public License for more details.
  12459. + *
  12460. + * You should have received a copy of the GNU General Public License
  12461. + * along with this program; if not, write to the Free Software
  12462. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  12463. + */
  12464. +
  12465. +#ifndef _PFE_HIF_LIB_H_
  12466. +#define _PFE_HIF_LIB_H_
  12467. +
  12468. +#include "pfe_hif.h"
  12469. +
  12470. +#ifdef HIF_LIB_DEBUG
  12471. +#define dbg_print_info( fmt, args...) \
  12472. + printk(KERN_INFO fmt, ##args)
  12473. +#else
  12474. +#define dbg_print_info( fmt, args...)
  12475. +#endif
  12476. +
  12477. +#define HIF_CL_REQ_TIMEOUT 10
  12478. +
  12479. +#if defined(CONFIG_COMCERTO_ZONE_DMA_NCNB)
  12480. +#define GFP_DMA_PFE (GFP_DMA_NCNB | __GFP_NOWARN)
  12481. +#else
  12482. +#define GFP_DMA_PFE 0
  12483. +#endif
  12484. +
  12485. +enum {
  12486. + REQUEST_CL_REGISTER = 0,
  12487. + REQUEST_CL_UNREGISTER,
  12488. + HIF_REQUEST_MAX
  12489. +};
  12490. +
  12491. +enum {
  12492. + EVENT_HIGH_RX_WM = 0, /* Event to indicate that client rx queue is reached water mark level */
  12493. + EVENT_RX_PKT_IND, /* Event to indicate that, packet recieved for client */
  12494. + EVENT_TXDONE_IND, /* Event to indicate that, packet tx done for client */
  12495. + HIF_EVENT_MAX
  12496. +};
  12497. +
  12498. +/*structure to store client queue info */
  12499. +
  12500. +/*structure to store client queue info */
  12501. +struct hif_client_rx_queue {
  12502. + struct rx_queue_desc *base;
  12503. + u32 size;
  12504. + u32 read_idx;
  12505. + u32 write_idx;
  12506. +};
  12507. +
  12508. +struct hif_client_tx_queue {
  12509. + struct tx_queue_desc *base;
  12510. + u32 size;
  12511. + u32 read_idx;
  12512. + u32 write_idx;
  12513. + u32 tx_pending;
  12514. + unsigned long jiffies_last_packet;
  12515. + u32 nocpy_flag;
  12516. + u32 prev_tmu_tx_pkts;
  12517. + u32 done_tmu_tx_pkts;
  12518. + u32 cur_tso_hdr_p;
  12519. + int tso_buf_cnt;
  12520. +};
  12521. +
  12522. +struct hif_client_s
  12523. +{
  12524. + int id;
  12525. + int tx_qn;
  12526. + int rx_qn;
  12527. + void *rx_qbase;
  12528. + void *tx_qbase;
  12529. + /* FIXME tx/rx_qsize fields can be removed after per queue depth is supported*/
  12530. + int tx_qsize;
  12531. + int rx_qsize;
  12532. + int cpu_id;
  12533. +
  12534. +// spinlock_t rx_lock;
  12535. + struct hif_client_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX];
  12536. + struct hif_client_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX];
  12537. + int (*event_handler)(void *priv, int event, int data);
  12538. + unsigned long queue_mask[HIF_EVENT_MAX];
  12539. + struct pfe *pfe;
  12540. + void *priv;
  12541. +};
  12542. +
  12543. +
  12544. +/* Client specific shared memory
  12545. + * It contains number of Rx/Tx queues, base addresses and queue sizes */
  12546. +struct hif_client_shm {
  12547. + u32 ctrl; /*0-7: number of Rx queues, 8-15: number of tx queues */
  12548. + unsigned long rx_qbase; /*Rx queue base address */
  12549. + u32 rx_qsize; /*each Rx queue size, all Rx queues are of same size */
  12550. + unsigned long tx_qbase; /* Tx queue base address */
  12551. + u32 tx_qsize; /*each Tx queue size, all Tx queues are of same size */
  12552. +};
  12553. +
  12554. +/*Client shared memory ctrl bit description */
  12555. +#define CLIENT_CTRL_RX_Q_CNT_OFST 0
  12556. +#define CLIENT_CTRL_TX_Q_CNT_OFST 8
  12557. +#define CLIENT_CTRL_RX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_RX_Q_CNT_OFST) & 0xFF)
  12558. +#define CLIENT_CTRL_TX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_TX_Q_CNT_OFST) & 0xFF)
  12559. +
  12560. +
  12561. +
  12562. +/*Shared memory used to communicate between HIF driver and host/client drivers
  12563. + * Before starting the hif driver rx_buf_pool ans rx_buf_pool_cnt should be
  12564. + * initialized with host buffers and buffers count in the pool.
  12565. + * rx_buf_pool_cnt should be >= HIF_RX_DESC_NT.
  12566. + *
  12567. + */
  12568. +struct hif_shm {
  12569. + u32 rx_buf_pool_cnt; /*Number of rx buffers available*/
  12570. + void *rx_buf_pool[HIF_RX_DESC_NT];/*Rx buffers required to initialize HIF rx descriptors */
  12571. + unsigned long gClient_status[2]; /*Global client status bit mask */
  12572. + u32 hif_qfull; /*TODO Client-id that caused for the TMU3 queue stop */
  12573. + u32 hif_qresume; /*TODO */
  12574. + struct hif_client_shm client[HIF_CLIENTS_MAX]; /* Client specific shared memory */
  12575. +};
  12576. +
  12577. +
  12578. +#define CL_DESC_OWN (1 << 31) /* This sets owner ship to HIF driver */
  12579. +#define CL_DESC_LAST (1 << 30) /* This indicates last packet for multi buffers handling */
  12580. +#define CL_DESC_FIRST (1 << 29) /* This indicates first packet for multi buffers handling */
  12581. +#define CL_DESC_BUF_LEN(x) ((x) & 0xFFFF)
  12582. +#define CL_DESC_FLAGS(x) (((x) & 0xF) << 16)
  12583. +#define CL_DESC_GET_FLAGS(x) (((x) >> 16) & 0xF)
  12584. +
  12585. +struct rx_queue_desc {
  12586. + void *data;
  12587. + u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
  12588. + u32 client_ctrl;
  12589. +};
  12590. +
  12591. +struct tx_queue_desc {
  12592. + void *data;
  12593. + u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
  12594. +};
  12595. +
  12596. +/* HIF Rx is not working properly for 2-byte aligned buffers and
  12597. + * ip_header should be 4byte aligned for better iperformance.
  12598. + * "ip_header = 64 + 6(hif_header) + 14 (MAC Header)" will be 4byte aligned.
  12599. + */
  12600. +#define PFE_PKT_HEADER_SZ sizeof(struct hif_hdr)
  12601. +#define PFE_BUF_SIZE 2048 /* must be big enough for headroom, pkt size and skb shared info */
  12602. +#define PFE_PKT_HEADROOM 128
  12603. +#define SKB_SHARED_INFO_SIZE 256 /* At least sizeof(struct skb_shared_info) bytes */
  12604. +
  12605. +//#define PFE_PKT_SIZE 1544 /* maximum ethernet packet size */
  12606. +#define PFE_PKT_SIZE (PFE_BUF_SIZE - PFE_PKT_HEADROOM - SKB_SHARED_INFO_SIZE) /* maximum ethernet packet size after reassembly offload*/
  12607. +#define MAX_L2_HDR_SIZE 14 /* Not correct for VLAN/PPPoE */
  12608. +#define MAX_L3_HDR_SIZE 20 /* Not correct for IPv6 */
  12609. +#define MAX_L4_HDR_SIZE 60 /* TCP with maximum options */
  12610. +#define MAX_HDR_SIZE (MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE + MAX_L4_HDR_SIZE)
  12611. +#define MAX_WIFI_HDR_SIZE (MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE + 6)
  12612. +#define MAX_PFE_PKT_SIZE 16380UL /* Used in page mode to clamp packet size to the maximum supported by the hif hw interface (<16KiB) */
  12613. +
  12614. +extern unsigned int pfe_pkt_size;
  12615. +extern unsigned int pfe_pkt_headroom;
  12616. +extern unsigned int page_mode;
  12617. +extern unsigned int lro_mode;
  12618. +extern unsigned int tx_qos;
  12619. +extern unsigned int emac_txq_cnt;
  12620. +
  12621. +int pfe_hif_lib_init(struct pfe *pfe);
  12622. +void pfe_hif_lib_exit(struct pfe *pfe);
  12623. +int hif_lib_client_register(struct hif_client_s *client);
  12624. +int hif_lib_client_unregister(struct hif_client_s *client);
  12625. +void __hif_lib_xmit_tso_hdr(struct hif_client_s *client, unsigned int qno, u32 client_ctrl, unsigned int ip_off, unsigned int ip_id, unsigned int ip_len, unsigned int tcp_off, unsigned int tcp_seq);
  12626. +void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, unsigned int len, u32 client_ctrl, unsigned int flags, void *client_data);
  12627. +int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, unsigned int len, u32 client_ctrl, void *client_data);
  12628. +void hif_lib_indicate_client(int cl_id, int event, int data);
  12629. +int hif_lib_event_handler_start( struct hif_client_s *client, int event, int data );
  12630. +int hif_lib_tmu_queue_start( struct hif_client_s *client, int qno );
  12631. +int hif_lib_tmu_queue_stop( struct hif_client_s *client, int qno );
  12632. +void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, unsigned int *flags, int count);
  12633. +void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int *ofst, unsigned int *rx_ctrl, unsigned int *desc_ctrl, void **priv_data);
  12634. +void hif_lib_update_credit(struct hif_client_s *client, unsigned int qno);
  12635. +void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue);
  12636. +void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id);
  12637. +void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int enable);
  12638. +static inline int hif_lib_tx_avail(struct hif_client_s *client, unsigned int qno)
  12639. +{
  12640. + struct hif_client_tx_queue *queue = &client->tx_q[qno];
  12641. +
  12642. + return (queue->size - queue->tx_pending);
  12643. +}
  12644. +
  12645. +static inline int hif_lib_get_tx_wrIndex(struct hif_client_s *client, unsigned int qno)
  12646. +{
  12647. + struct hif_client_tx_queue *queue = &client->tx_q[qno];
  12648. +
  12649. + return queue->write_idx;
  12650. +}
  12651. +
  12652. +
  12653. +static inline int hif_lib_tx_pending(struct hif_client_s *client, unsigned int qno)
  12654. +{
  12655. + struct hif_client_tx_queue *queue = &client->tx_q[qno];
  12656. +
  12657. + return queue->tx_pending;
  12658. +}
  12659. +
  12660. +#define hif_lib_tx_credit_avail(pfe, id, qno) pfe->tmu_credit.tx_credit[id][qno]
  12661. +#define hif_lib_tx_credit_max(pfe, id, qno) pfe->tmu_credit.tx_credit_max[id][qno]
  12662. +#define hif_lib_tx_credit_use(pfe, id, qno, credit) do {if (tx_qos) {pfe->tmu_credit.tx_credit[id][qno]-= credit; pfe->tmu_credit.tx_packets[id][qno]+=credit;}} while (0)
  12663. +
  12664. +#endif /* _PFE_HIF_LIB_H_ */
  12665. --- /dev/null
  12666. +++ b/drivers/staging/fsl_ppfe/pfe_hw.c
  12667. @@ -0,0 +1,188 @@
  12668. +/*
  12669. + *
  12670. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  12671. + *
  12672. + * This program is free software; you can redistribute it and/or modify
  12673. + * it under the terms of the GNU General Public License as published by
  12674. + * the Free Software Foundation; either version 2 of the License, or
  12675. + * (at your option) any later version.
  12676. + *
  12677. + * This program is distributed in the hope that it will be useful,
  12678. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12679. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12680. + * GNU General Public License for more details.
  12681. + *
  12682. + * You should have received a copy of the GNU General Public License
  12683. + * along with this program; if not, write to the Free Software
  12684. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  12685. + */
  12686. +
  12687. +#include "pfe_mod.h"
  12688. +#include "pfe_hw.h"
  12689. +
  12690. +/* Functions to handle most of pfe hw register initialization */
  12691. +
  12692. +int pfe_hw_init(struct pfe *pfe, int resume)
  12693. +{
  12694. + CLASS_CFG class_cfg = {
  12695. + .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
  12696. + .route_table_baseaddr = pfe->ddr_phys_baseaddr + ROUTE_TABLE_BASEADDR,
  12697. + .route_table_hash_bits = ROUTE_TABLE_HASH_BITS,
  12698. + };
  12699. +
  12700. + TMU_CFG tmu_cfg = {
  12701. + .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
  12702. + .llm_base_addr = pfe->ddr_phys_baseaddr + TMU_LLM_BASEADDR,
  12703. + .llm_queue_len = TMU_LLM_QUEUE_LEN,
  12704. + };
  12705. +
  12706. +#if !defined(CONFIG_UTIL_DISABLED)
  12707. + UTIL_CFG util_cfg = {
  12708. + .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
  12709. + };
  12710. +#endif
  12711. +
  12712. + BMU_CFG bmu1_cfg = {
  12713. + .baseaddr = CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR + BMU1_LMEM_BASEADDR),
  12714. + .count = BMU1_BUF_COUNT,
  12715. + .size = BMU1_BUF_SIZE,
  12716. + };
  12717. +
  12718. + BMU_CFG bmu2_cfg = {
  12719. + .baseaddr = DDR_PHYS_TO_PFE(pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR),
  12720. + .count = BMU2_BUF_COUNT,
  12721. + .size = BMU2_BUF_SIZE,
  12722. + };
  12723. +
  12724. + GPI_CFG egpi1_cfg = {
  12725. + .lmem_rtry_cnt = EGPI1_LMEM_RTRY_CNT,
  12726. + .tmlf_txthres = EGPI1_TMLF_TXTHRES,
  12727. + .aseq_len = EGPI1_ASEQ_LEN,
  12728. + };
  12729. +
  12730. + GPI_CFG egpi2_cfg = {
  12731. + .lmem_rtry_cnt = EGPI2_LMEM_RTRY_CNT,
  12732. + .tmlf_txthres = EGPI2_TMLF_TXTHRES,
  12733. + .aseq_len = EGPI2_ASEQ_LEN,
  12734. + };
  12735. +
  12736. +#if defined(CONFIG_PLATFORM_C2000)
  12737. + GPI_CFG egpi3_cfg = {
  12738. + .lmem_rtry_cnt = EGPI3_LMEM_RTRY_CNT,
  12739. + .tmlf_txthres = EGPI3_TMLF_TXTHRES,
  12740. + .aseq_len = EGPI3_ASEQ_LEN,
  12741. + };
  12742. +#endif
  12743. +
  12744. + GPI_CFG hgpi_cfg = {
  12745. + .lmem_rtry_cnt = HGPI_LMEM_RTRY_CNT,
  12746. + .tmlf_txthres = HGPI_TMLF_TXTHRES,
  12747. + .aseq_len = HGPI_ASEQ_LEN,
  12748. + };
  12749. +
  12750. + printk(KERN_INFO "%s\n", __func__);
  12751. +
  12752. +#if defined(CONFIG_PLATFORM_LS1012A) && !defined(LS1012A_PFE_RESET_WA)
  12753. + /* LS1012A needs this to make PE work correctly */
  12754. + writel(0x3, CLASS_PE_SYS_CLK_RATIO);
  12755. + writel(0x3, TMU_PE_SYS_CLK_RATIO);
  12756. + writel(0x3, UTIL_PE_SYS_CLK_RATIO);
  12757. + udelay(10);
  12758. +#endif
  12759. +
  12760. + printk(KERN_INFO "CLASS version: %x\n", readl(CLASS_VERSION));
  12761. + printk(KERN_INFO "TMU version: %x\n", readl(TMU_VERSION));
  12762. +
  12763. + printk(KERN_INFO "BMU1 version: %x\n", readl(BMU1_BASE_ADDR + BMU_VERSION));
  12764. + printk(KERN_INFO "BMU2 version: %x\n", readl(BMU2_BASE_ADDR + BMU_VERSION));
  12765. +#if defined(CONFIG_PLATFORM_C2000)
  12766. + printk(KERN_INFO "EMAC1 network cfg: %x\n", readl(EMAC1_BASE_ADDR + EMAC_NETWORK_CONFIG));
  12767. + printk(KERN_INFO "EMAC2 network cfg: %x\n", readl(EMAC2_BASE_ADDR + EMAC_NETWORK_CONFIG));
  12768. +#if !defined(CONFIG_PLATFORM_PCI)
  12769. + printk(KERN_INFO "EMAC3 network cfg: %x\n", readl(EMAC3_BASE_ADDR + EMAC_NETWORK_CONFIG));
  12770. +#endif
  12771. +#else
  12772. + //TODO print MTIP config
  12773. +#endif
  12774. +
  12775. + printk(KERN_INFO "EGPI1 version: %x\n", readl(EGPI1_BASE_ADDR + GPI_VERSION));
  12776. + printk(KERN_INFO "EGPI2 version: %x\n", readl(EGPI2_BASE_ADDR + GPI_VERSION));
  12777. +#if !defined(CONFIG_PLATFORM_PCI) && !defined(CONFIG_PLATFORM_LS1012A)
  12778. + printk(KERN_INFO "EGPI3 version: %x\n", readl(EGPI3_BASE_ADDR + GPI_VERSION));
  12779. +#endif
  12780. + printk(KERN_INFO "HGPI version: %x\n", readl(HGPI_BASE_ADDR + GPI_VERSION));
  12781. +
  12782. +#if !defined(CONFIG_PLATFORM_PCI)
  12783. + printk(KERN_INFO "GPT version: %x\n", readl(CBUS_GPT_VERSION));
  12784. +#endif
  12785. +
  12786. + printk(KERN_INFO "HIF version: %x\n", readl(HIF_VERSION));
  12787. + printk(KERN_INFO "HIF NOPCY version: %x\n", readl(HIF_NOCPY_VERSION));
  12788. +
  12789. +#if !defined(CONFIG_UTIL_DISABLED)
  12790. + printk(KERN_INFO "UTIL version: %x\n", readl(UTIL_VERSION));
  12791. +#endif
  12792. + while(!(readl(TMU_CTRL) & ECC_MEM_INIT_DONE)) ;
  12793. +
  12794. + hif_rx_disable();
  12795. + hif_tx_disable();
  12796. +
  12797. + bmu_init(BMU1_BASE_ADDR, &bmu1_cfg);
  12798. +
  12799. + printk(KERN_INFO "bmu_init(1) done\n");
  12800. +
  12801. + bmu_init(BMU2_BASE_ADDR, &bmu2_cfg);
  12802. +
  12803. + printk(KERN_INFO "bmu_init(2) done\n");
  12804. +
  12805. + class_cfg.resume = resume ? 1 : 0;
  12806. +
  12807. + class_init(&class_cfg);
  12808. +
  12809. + printk(KERN_INFO "class_init() done\n");
  12810. +
  12811. + tmu_init(&tmu_cfg);
  12812. +
  12813. + printk(KERN_INFO "tmu_init() done\n");
  12814. +#if !defined(CONFIG_UTIL_DISABLED)
  12815. + util_init(&util_cfg);
  12816. +
  12817. + printk(KERN_INFO "util_init() done\n");
  12818. +#endif
  12819. + gpi_init(EGPI1_BASE_ADDR, &egpi1_cfg);
  12820. +
  12821. + printk(KERN_INFO "gpi_init(1) done\n");
  12822. +
  12823. + gpi_init(EGPI2_BASE_ADDR, &egpi2_cfg);
  12824. +
  12825. + printk(KERN_INFO "gpi_init(2) done\n");
  12826. +#if !defined(CONFIG_PLATFORM_PCI) && !defined(CONFIG_PLATFORM_LS1012A)
  12827. + gpi_init(EGPI3_BASE_ADDR, &egpi3_cfg);
  12828. +
  12829. + printk(KERN_INFO "gpi_init(3) done\n");
  12830. +#endif
  12831. + gpi_init(HGPI_BASE_ADDR, &hgpi_cfg);
  12832. +
  12833. + printk(KERN_INFO "gpi_init(hif) done\n");
  12834. +
  12835. + bmu_enable(BMU1_BASE_ADDR);
  12836. +
  12837. + printk(KERN_INFO "bmu_enable(1) done\n");
  12838. +
  12839. + bmu_enable(BMU2_BASE_ADDR);
  12840. +
  12841. + printk(KERN_INFO "bmu_enable(2) done\n");
  12842. +
  12843. + return 0;
  12844. +}
  12845. +
  12846. +void pfe_hw_exit(struct pfe *pfe)
  12847. +{
  12848. + printk(KERN_INFO "%s\n", __func__);
  12849. +
  12850. + bmu_disable(BMU1_BASE_ADDR);
  12851. + bmu_reset(BMU1_BASE_ADDR);
  12852. +
  12853. + bmu_disable(BMU2_BASE_ADDR);
  12854. + bmu_reset(BMU2_BASE_ADDR);
  12855. +}
  12856. --- /dev/null
  12857. +++ b/drivers/staging/fsl_ppfe/pfe_hw.h
  12858. @@ -0,0 +1,32 @@
  12859. +/*
  12860. + *
  12861. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  12862. + *
  12863. + * This program is free software; you can redistribute it and/or modify
  12864. + * it under the terms of the GNU General Public License as published by
  12865. + * the Free Software Foundation; either version 2 of the License, or
  12866. + * (at your option) any later version.
  12867. + *
  12868. + * This program is distributed in the hope that it will be useful,
  12869. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12870. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12871. + * GNU General Public License for more details.
  12872. + *
  12873. + * You should have received a copy of the GNU General Public License
  12874. + * along with this program; if not, write to the Free Software
  12875. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  12876. + */
  12877. +
  12878. +#ifndef _PFE_HW_H_
  12879. +#define _PFE_HW_H_
  12880. +
  12881. +#if !defined(CONFIG_PLATFORM_PCI)
  12882. +#define PE_SYS_CLK_RATIO 1 /* SYS/AXI = 250MHz, HFE = 500MHz */
  12883. +#else
  12884. +#define PE_SYS_CLK_RATIO 0 /* SYS = 40MHz, HFE = 40MHz */
  12885. +#endif
  12886. +
  12887. +int pfe_hw_init(struct pfe *pfe, int resume);
  12888. +void pfe_hw_exit(struct pfe *pfe);
  12889. +
  12890. +#endif /* _PFE_HW_H_ */
  12891. --- /dev/null
  12892. +++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
  12893. @@ -0,0 +1,341 @@
  12894. +/*
  12895. + *
  12896. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  12897. + *
  12898. + * This program is free software; you can redistribute it and/or modify
  12899. + * it under the terms of the GNU General Public License as published by
  12900. + * the Free Software Foundation; either version 2 of the License, or
  12901. + * (at your option) any later version.
  12902. + *
  12903. + * This program is distributed in the hope that it will be useful,
  12904. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12905. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12906. + * GNU General Public License for more details.
  12907. + *
  12908. + * You should have received a copy of the GNU General Public License
  12909. + * along with this program; if not, write to the Free Software
  12910. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  12911. + */
  12912. +
  12913. +#include <linux/module.h>
  12914. +#include <linux/device.h>
  12915. +#include <linux/of_net.h>
  12916. +#include <linux/of_address.h>
  12917. +#include <linux/platform_device.h>
  12918. +#include <linux/slab.h>
  12919. +#include <linux/clk.h>
  12920. +#include <linux/mfd/syscon.h>
  12921. +#include <linux/regmap.h>
  12922. +
  12923. +
  12924. +#include "pfe_mod.h"
  12925. +
  12926. +struct comcerto_pfe_platform_data pfe_platform_data;
  12927. +
  12928. +
  12929. +
  12930. +static int pfe_get_gemac_if_proprties(struct device_node *parent, int port, int if_cnt,
  12931. + struct comcerto_pfe_platform_data *pdata)
  12932. +{
  12933. + struct device_node *gem = NULL, *phy = NULL;
  12934. + int size;
  12935. + int ii = 0, phy_id = 0;
  12936. + const u32 *addr;
  12937. + const void *mac_addr;
  12938. +
  12939. + for (ii = 0; ii < if_cnt; ii++) {
  12940. + gem = of_get_next_child(parent, gem);
  12941. + if (!gem)
  12942. + goto err;
  12943. + addr = of_get_property(gem, "reg", &size);
  12944. + if (addr && (be32_to_cpup(addr) == port))
  12945. + break;
  12946. + }
  12947. +
  12948. + if (ii >= if_cnt) {
  12949. + printk(KERN_ERR "%s:%d Failed to find interface = %d\n", __func__, __LINE__, if_cnt);
  12950. + goto err;
  12951. + }
  12952. +
  12953. + pdata->comcerto_eth_pdata[port].gem_id = port;
  12954. +
  12955. + mac_addr = of_get_mac_address(gem);
  12956. +
  12957. + if (mac_addr) {
  12958. + memcpy(pdata->comcerto_eth_pdata[port].mac_addr, mac_addr, ETH_ALEN);
  12959. + }
  12960. +
  12961. + if ((pdata->comcerto_eth_pdata[port].mii_config = of_get_phy_mode(gem)) < 0)
  12962. + printk(KERN_ERR "%s:%d Incorrect Phy mode....\n", __func__, __LINE__);
  12963. +
  12964. +
  12965. + addr = of_get_property(gem, "fsl,gemac-bus-id", &size);
  12966. + if (!addr)
  12967. + printk(KERN_ERR "%s:%d Invalid gemac-bus-id....\n", __func__, __LINE__);
  12968. + else
  12969. + pdata->comcerto_eth_pdata[port].bus_id = be32_to_cpup(addr);
  12970. +
  12971. + addr = of_get_property(gem, "fsl,gemac-phy-id", &size);
  12972. + if (!addr)
  12973. + printk(KERN_ERR "%s:%d Invalid gemac-phy-id....\n", __func__, __LINE__);
  12974. + else
  12975. + phy_id = pdata->comcerto_eth_pdata[port].phy_id = be32_to_cpup(addr);
  12976. +
  12977. + addr = of_get_property(gem, "fsl,mdio-mux-val", &size);
  12978. + if (!addr)
  12979. + printk(KERN_ERR "%s: Invalid mdio-mux-val....\n", __func__);
  12980. + else
  12981. + phy_id = pdata->comcerto_eth_pdata[port].mdio_muxval= be32_to_cpup(addr);
  12982. +
  12983. +
  12984. + addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size);
  12985. + if (!addr)
  12986. + printk(KERN_ERR "%s:%d Invalid pfe-phy-if-flags....\n", __func__, __LINE__);
  12987. + else
  12988. + pdata->comcerto_eth_pdata[port].phy_flags = be32_to_cpup(addr);
  12989. +
  12990. + addr = of_get_property(gem, "fsl,pfe-gemac-mode", &size);
  12991. + if (!addr)
  12992. + printk(KERN_ERR "%s:%d Invalid pfe-gemac-mode....\n", __func__, __LINE__);
  12993. + else
  12994. + pdata->comcerto_eth_pdata[port].gemac_mode = be32_to_cpup(addr);
  12995. +
  12996. +
  12997. + /* If PHY is enabled, read mdio properties */
  12998. + if (pdata->comcerto_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
  12999. + goto done;
  13000. +
  13001. + phy = of_get_next_child(gem, NULL);
  13002. +
  13003. + addr = of_get_property(phy, "reg", &size);
  13004. +
  13005. + if (!addr)
  13006. + printk(KERN_ERR "%s:%d Invalid phy enable flag....\n", __func__, __LINE__);
  13007. + else
  13008. + pdata->comcerto_mdio_pdata[port].enabled = be32_to_cpup(addr);
  13009. +
  13010. + addr = of_get_property (phy, "fsl,mdio-phy-mask", &size);
  13011. + if (!addr)
  13012. + printk(KERN_ERR "%s:%d Unable to read mdio-phy-mask....\n", __func__, __LINE__);
  13013. + else
  13014. + pdata->comcerto_mdio_pdata[port].phy_mask= be32_to_cpup(addr);
  13015. + pdata->comcerto_mdio_pdata[port].irq[0] = PHY_POLL;
  13016. +
  13017. +done:
  13018. +
  13019. + return 0;
  13020. +
  13021. +err:
  13022. + return -1;
  13023. +}
  13024. +/**
  13025. + * pfe_platform_probe -
  13026. + *
  13027. + *
  13028. + */
  13029. +static int pfe_platform_probe(struct platform_device *pdev)
  13030. +{
  13031. + struct resource res;
  13032. + int ii, rc, interface_count = 0, size = 0;
  13033. + const u32 *prop;
  13034. + struct device_node *np;
  13035. +
  13036. + np = pdev->dev.of_node;
  13037. +
  13038. + if (!np) {
  13039. + printk(KERN_ERR "Invalid device node\n");
  13040. + return -EINVAL;
  13041. + }
  13042. +
  13043. + pfe = kzalloc(sizeof(struct pfe), GFP_KERNEL);
  13044. + if (!pfe) {
  13045. + rc = -ENOMEM;
  13046. + goto err_alloc;
  13047. + }
  13048. +
  13049. + platform_set_drvdata(pdev, pfe);
  13050. +
  13051. + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
  13052. +
  13053. + if (of_address_to_resource(np, 2, &res))
  13054. + {
  13055. + rc = -ENOMEM;
  13056. + printk(KERN_ERR "failed to get ddr resource\n");
  13057. + goto err_ddr;
  13058. + }
  13059. +
  13060. +
  13061. + pfe->ddr_phys_baseaddr = res.start;
  13062. + pfe->ddr_size = resource_size(&res);
  13063. +
  13064. + //pfe->ddr_baseaddr = ioremap(res.start, resource_size(&res));
  13065. + pfe->ddr_baseaddr = phys_to_virt(res.start);
  13066. + if (!pfe->ddr_baseaddr) {
  13067. + printk(KERN_ERR "ioremap() ddr failed\n");
  13068. + rc = -ENOMEM;
  13069. + goto err_ddr;
  13070. + }
  13071. +
  13072. + /*printk("%s:%d : DDR Res : Phy addr:len = %x:%x Mapped addr : %x\n", __func__, __LINE__,
  13073. + pfe->ddr_phys_baseaddr, pfe->ddr_size, pfe->ddr_baseaddr);*/
  13074. +
  13075. + pfe->scfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,"fsl,pfe-scfg");
  13076. + if (IS_ERR(pfe->scfg)) {
  13077. + dev_err(&pdev->dev, "No syscfg phandle specified\n");
  13078. + return PTR_ERR(pfe->scfg);
  13079. + }
  13080. + /*printk("%s scfg %p\n",__func__,pfe->scfg);*/
  13081. +
  13082. +
  13083. +#if 1
  13084. + if (!(pfe->cbus_baseaddr = of_iomap(np, 1)))
  13085. + {
  13086. + rc = -ENOMEM;
  13087. + printk(KERN_ERR "failed to get axi resource\n");
  13088. + goto err_axi;
  13089. + }
  13090. +
  13091. + /*printk("%s:%d : AXI Mapped addr : %lx\n", __func__, __LINE__, pfe->cbus_baseaddr);
  13092. + printk("%s:%d : AXI Mapped addr : phys %lx\n", __func__, __LINE__, virt_to_phys(pfe->cbus_baseaddr));*/
  13093. +#else
  13094. +
  13095. + if (of_address_to_resource(np, 1, &res))
  13096. + {
  13097. + rc = -ENOMEM;
  13098. + printk(KERN_ERR "failed to get AXI resource\n");
  13099. + goto err_iram;
  13100. + }
  13101. + pfe->cbus_baseaddr = ioremap(res.start, resource_size(&res));
  13102. + if (!pfe->cbus_baseaddr) {
  13103. + printk(KERN_INFO "ioremap() AXI failed %lx %x\n", res.start, resource_size(&res));
  13104. + rc = -ENOMEM;
  13105. + goto err_iram;
  13106. + }
  13107. + printk("%s:%d : AXI Mapped addr : %x PHY addr = %x\n", __func__, __LINE__, pfe->cbus_baseaddr, res.start);
  13108. +#endif
  13109. +
  13110. + pfe->hif_irq = platform_get_irq(pdev, 0);
  13111. + if (pfe->hif_irq < 0) {
  13112. + printk(KERN_ERR "platform_get_irq_byname(hif) failed\n");
  13113. + rc = pfe->hif_irq;
  13114. + goto err_hif_irq;
  13115. + }
  13116. + /*printk("hif_irq: %d \n", pfe->hif_irq);*/
  13117. +
  13118. + /* Read interface count */
  13119. + prop = of_get_property(np, "fsl,pfe-num-interfaces", &size);
  13120. + if (!prop) {
  13121. + printk(KERN_ERR "Failed to read number of interfaces\n");
  13122. + rc = -ENXIO;
  13123. + goto err_prop;
  13124. + }
  13125. +
  13126. + interface_count = be32_to_cpup(prop);
  13127. + /*printk(KERN_INFO "%s:%d Number of interfaces : %d\n", __func__, __LINE__, interface_count);*/
  13128. + if (interface_count <= 0) {
  13129. + printk(KERN_ERR "No ethernet interface count : %d\n", interface_count);
  13130. + rc = -ENXIO;
  13131. + goto err_prop;
  13132. + }
  13133. +
  13134. + for (ii = 0; ii < interface_count; ii++) {
  13135. + pfe_get_gemac_if_proprties(np, ii, interface_count, &pfe_platform_data);
  13136. + }
  13137. +
  13138. +
  13139. + pfe->dev = &pdev->dev;
  13140. +
  13141. + pfe->dev->platform_data = &pfe_platform_data;
  13142. +
  13143. + //FIXME get the correct clock from dts
  13144. + pfe->ctrl.sys_clk = 250000; // save sys_clk value as KHz
  13145. +
  13146. + rc = pfe_probe(pfe);
  13147. + if (rc < 0)
  13148. + goto err_probe;
  13149. +
  13150. + return 0;
  13151. +
  13152. +err_probe:
  13153. +err_prop:
  13154. + /*TODO complet the code */
  13155. +err_hif_irq:
  13156. + iounmap(pfe->cbus_baseaddr);
  13157. +
  13158. +err_axi:
  13159. + iounmap(pfe->ddr_baseaddr);
  13160. +
  13161. +err_ddr:
  13162. + platform_set_drvdata(pdev, NULL);
  13163. +
  13164. + kfree(pfe);
  13165. +
  13166. +err_alloc:
  13167. + return rc;
  13168. +}
  13169. +
  13170. +
  13171. +/**
  13172. + * pfe_platform_remove -
  13173. + *
  13174. + *
  13175. + */
  13176. +static int pfe_platform_remove(struct platform_device *pdev)
  13177. +{
  13178. + struct pfe *pfe = platform_get_drvdata(pdev);
  13179. + int rc;
  13180. +
  13181. + printk(KERN_INFO "%s\n", __func__);
  13182. +
  13183. + rc = pfe_remove(pfe);
  13184. +
  13185. + iounmap(pfe->cbus_baseaddr);
  13186. + iounmap(pfe->ddr_baseaddr);
  13187. +
  13188. + platform_set_drvdata(pdev, NULL);
  13189. +
  13190. + kfree(pfe);
  13191. +
  13192. + return rc;
  13193. +}
  13194. +
  13195. +static struct of_device_id pfe_match[] = {
  13196. + {
  13197. + .compatible = "fsl,pfe",
  13198. + },
  13199. + {},
  13200. +};
  13201. +MODULE_DEVICE_TABLE(of, pfe_match);
  13202. +
  13203. +static struct platform_driver pfe_platform_driver = {
  13204. + .probe = pfe_platform_probe,
  13205. + .remove = pfe_platform_remove,
  13206. + .driver = {
  13207. + .name = "pfe",
  13208. + .of_match_table = pfe_match,
  13209. + },
  13210. +};
  13211. +
  13212. +#if 0
  13213. +static int __init pfe_module_init(void)
  13214. +{
  13215. + printk(KERN_INFO "%s\n", __func__);
  13216. +
  13217. + return platform_driver_register(&pfe_platform_driver);
  13218. +}
  13219. +
  13220. +
  13221. +static void __exit pfe_module_exit(void)
  13222. +{
  13223. + platform_driver_unregister(&pfe_platform_driver);
  13224. +
  13225. + printk(KERN_INFO "%s\n", __func__);
  13226. +}
  13227. +module_init(pfe_module_init);
  13228. +module_exit(pfe_module_exit);
  13229. +#endif
  13230. +
  13231. +module_platform_driver(pfe_platform_driver);
  13232. +MODULE_LICENSE("GPL");
  13233. +MODULE_DESCRIPTION("PFE Ethernet driver");
  13234. +MODULE_AUTHOR("NXP DNCPE");
  13235. --- /dev/null
  13236. +++ b/drivers/staging/fsl_ppfe/pfe_mod.c
  13237. @@ -0,0 +1,140 @@
  13238. +/*
  13239. + *
  13240. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  13241. + *
  13242. + * This program is free software; you can redistribute it and/or modify
  13243. + * it under the terms of the GNU General Public License as published by
  13244. + * the Free Software Foundation; either version 2 of the License, or
  13245. + * (at your option) any later version.
  13246. + *
  13247. + * This program is distributed in the hope that it will be useful,
  13248. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13249. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13250. + * GNU General Public License for more details.
  13251. + *
  13252. + * You should have received a copy of the GNU General Public License
  13253. + * along with this program; if not, write to the Free Software
  13254. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13255. + */
  13256. +
  13257. +#include <linux/dma-mapping.h>
  13258. +#include "pfe_mod.h"
  13259. +
  13260. +struct pfe *pfe;
  13261. +
  13262. +/**
  13263. + * pfe_probe -
  13264. + *
  13265. + *
  13266. + */
  13267. +int pfe_probe(struct pfe *pfe)
  13268. +{
  13269. + int rc;
  13270. +
  13271. +
  13272. + if (DDR_MAX_SIZE > pfe->ddr_size) {
  13273. + printk(KERN_ERR "%s: required DDR memory (%x) above platform ddr memory (%x)\n", __func__, DDR_MAX_SIZE, pfe->ddr_size);
  13274. + rc = -ENOMEM;
  13275. + goto err_hw;
  13276. + }
  13277. +
  13278. + if (((int) (pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR) & (8*SZ_1M - 1)) != 0) {
  13279. + printk(KERN_ERR "%s: BMU2 base address (0x%x) must be aligned on 8MB boundary\n", __func__, (int) pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR);
  13280. + rc = -ENOMEM;
  13281. + goto err_hw;
  13282. + }
  13283. +
  13284. +
  13285. + printk(KERN_INFO "cbus_baseaddr: %lx, ddr_baseaddr: %lx, ddr_phys_baseaddr: %lx, ddr_size: %x\n",
  13286. + (unsigned long)pfe->cbus_baseaddr, (unsigned long)pfe->ddr_baseaddr,
  13287. + pfe->ddr_phys_baseaddr, pfe->ddr_size);
  13288. +
  13289. + pfe_lib_init(pfe->cbus_baseaddr, pfe->ddr_baseaddr, pfe->ddr_phys_baseaddr, pfe->ddr_size);
  13290. +
  13291. + rc = pfe_hw_init(pfe, 0);
  13292. + if (rc < 0)
  13293. + goto err_hw;
  13294. +
  13295. + rc = pfe_hif_lib_init(pfe);
  13296. + if (rc < 0)
  13297. + goto err_hif_lib;
  13298. +
  13299. + rc = pfe_hif_init(pfe);
  13300. + if (rc < 0)
  13301. + goto err_hif;
  13302. +
  13303. + rc = pfe_firmware_init(pfe);
  13304. + if (rc < 0)
  13305. + goto err_firmware;
  13306. +
  13307. + rc = pfe_ctrl_init(pfe);
  13308. + if (rc < 0)
  13309. + goto err_ctrl;
  13310. +
  13311. + rc = pfe_eth_init(pfe);
  13312. + if (rc < 0)
  13313. + goto err_eth;
  13314. +
  13315. + rc = pfe_sysfs_init(pfe);
  13316. + if(rc < 0)
  13317. + goto err_sysfs;
  13318. +
  13319. + rc = pfe_debugfs_init(pfe);
  13320. + if (rc < 0)
  13321. + goto err_debugfs;
  13322. +
  13323. + return 0;
  13324. +
  13325. +err_debugfs:
  13326. + pfe_sysfs_exit(pfe);
  13327. +
  13328. +err_sysfs:
  13329. + pfe_eth_exit(pfe);
  13330. +
  13331. +err_eth:
  13332. + pfe_ctrl_exit(pfe);
  13333. +
  13334. +err_ctrl:
  13335. + pfe_firmware_exit(pfe);
  13336. +
  13337. +err_firmware:
  13338. + pfe_hif_exit(pfe);
  13339. +
  13340. +err_hif:
  13341. + pfe_hif_lib_exit(pfe);
  13342. +
  13343. +err_hif_lib:
  13344. + pfe_hw_exit(pfe);
  13345. +
  13346. +err_hw:
  13347. + return rc;
  13348. +}
  13349. +
  13350. +
  13351. +/**
  13352. + * pfe_remove -
  13353. + *
  13354. + *
  13355. + */
  13356. +int pfe_remove(struct pfe *pfe)
  13357. +{
  13358. + printk(KERN_INFO "%s\n", __func__);
  13359. +
  13360. + pfe_debugfs_exit(pfe);
  13361. +
  13362. + pfe_sysfs_exit(pfe);
  13363. +
  13364. + pfe_eth_exit(pfe);
  13365. +
  13366. + pfe_ctrl_exit(pfe);
  13367. +
  13368. + pfe_firmware_exit(pfe);
  13369. +
  13370. + pfe_hif_exit(pfe);
  13371. +
  13372. + pfe_hif_lib_exit(pfe);
  13373. +
  13374. + pfe_hw_exit(pfe);
  13375. +
  13376. + return 0;
  13377. +}
  13378. --- /dev/null
  13379. +++ b/drivers/staging/fsl_ppfe/pfe_mod.h
  13380. @@ -0,0 +1,163 @@
  13381. +/*
  13382. + *
  13383. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  13384. + *
  13385. + * This program is free software; you can redistribute it and/or modify
  13386. + * it under the terms of the GNU General Public License as published by
  13387. + * the Free Software Foundation; either version 2 of the License, or
  13388. + * (at your option) any later version.
  13389. + *
  13390. + * This program is distributed in the hope that it will be useful,
  13391. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13392. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13393. + * GNU General Public License for more details.
  13394. + *
  13395. + * You should have received a copy of the GNU General Public License
  13396. + * along with this program; if not, write to the Free Software
  13397. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13398. + */
  13399. +
  13400. +#ifndef _PFE_MOD_H_
  13401. +#define _PFE_MOD_H_
  13402. +
  13403. +#include <linux/device.h>
  13404. +#include <linux/elf.h>
  13405. +
  13406. +struct pfe;
  13407. +
  13408. +#include "config.h"
  13409. +#include "pfe_hw.h"
  13410. +#include "pfe_firmware.h"
  13411. +#include "pfe_ctrl.h"
  13412. +#include "pfe_hif.h"
  13413. +#include "pfe_hif_lib.h"
  13414. +#include "pfe_eth.h"
  13415. +#include "pfe_sysfs.h"
  13416. +#include "pfe_perfmon.h"
  13417. +#include "pfe_debugfs.h"
  13418. +
  13419. +struct pfe_tmu_credit {
  13420. + /* Number of allowed TX packet in-flight, matches TMU queue size */
  13421. + unsigned int tx_credit[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
  13422. + unsigned int tx_credit_max[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
  13423. + unsigned int tx_packets[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
  13424. +};
  13425. +
  13426. +struct pfe {
  13427. + struct regmap *scfg;
  13428. + unsigned long ddr_phys_baseaddr;
  13429. + void *ddr_baseaddr;
  13430. + unsigned int ddr_size;
  13431. + void *cbus_baseaddr;
  13432. + void *apb_baseaddr;
  13433. + unsigned long iram_phys_baseaddr;
  13434. + void *iram_baseaddr;
  13435. + unsigned long ipsec_phys_baseaddr;
  13436. + void *ipsec_baseaddr;
  13437. + int hif_irq;
  13438. + int hif_client_irq;
  13439. + struct device *dev;
  13440. + struct dentry *dentry;
  13441. + struct pfe_ctrl ctrl;
  13442. + struct pfe_hif hif;
  13443. + struct pfe_eth eth;
  13444. + struct hif_client_s *hif_client[HIF_CLIENTS_MAX];
  13445. +#if defined(CFG_DIAGS)
  13446. + struct pfe_diags diags;
  13447. +#endif
  13448. + struct pfe_tmu_credit tmu_credit;
  13449. + struct pfe_cpumon cpumon;
  13450. + struct pfe_memmon memmon;
  13451. + int wake;
  13452. + struct clk * hfe_clock;
  13453. +};
  13454. +
  13455. +extern struct pfe *pfe;
  13456. +
  13457. +int pfe_probe(struct pfe *pfe);
  13458. +int pfe_remove(struct pfe *pfe);
  13459. +
  13460. +#ifndef SZ_1K
  13461. +#define SZ_1K 1024
  13462. +#endif
  13463. +
  13464. +#ifndef SZ_1M
  13465. +#define SZ_1M (1024 * 1024)
  13466. +#endif
  13467. +
  13468. +/* DDR Mapping */
  13469. +#if !defined(CONFIG_PLATFORM_PCI)
  13470. +#define ROUTE_TABLE_BASEADDR 0
  13471. +#define ROUTE_TABLE_HASH_BITS 15 /**< 32K entries */
  13472. +#define ROUTE_TABLE_SIZE ((1 << ROUTE_TABLE_HASH_BITS) * CLASS_ROUTE_SIZE)
  13473. +#define BMU2_DDR_BASEADDR (ROUTE_TABLE_BASEADDR + ROUTE_TABLE_SIZE)
  13474. +#define BMU2_BUF_COUNT (4096 - 256) /**< This is to get a total DDR size of 12MiB */
  13475. +#define BMU2_DDR_SIZE (DDR_BUF_SIZE * BMU2_BUF_COUNT)
  13476. +#define UTIL_CODE_BASEADDR (BMU2_DDR_BASEADDR + BMU2_DDR_SIZE)
  13477. +#define UTIL_CODE_SIZE (128 * SZ_1K)
  13478. +#define UTIL_DDR_DATA_BASEADDR (UTIL_CODE_BASEADDR + UTIL_CODE_SIZE)
  13479. +#define UTIL_DDR_DATA_SIZE (64 * SZ_1K)
  13480. +#define CLASS_DDR_DATA_BASEADDR (UTIL_DDR_DATA_BASEADDR + UTIL_DDR_DATA_SIZE)
  13481. +#define CLASS_DDR_DATA_SIZE (32 * SZ_1K)
  13482. +#define TMU_DDR_DATA_BASEADDR (CLASS_DDR_DATA_BASEADDR + CLASS_DDR_DATA_SIZE)
  13483. +#define TMU_DDR_DATA_SIZE (32 * SZ_1K)
  13484. +#define TMU_LLM_BASEADDR (TMU_DDR_DATA_BASEADDR + TMU_DDR_DATA_SIZE)
  13485. +#define TMU_LLM_QUEUE_LEN (8 * 512) /**< Must be power of two and at least 16 * 8 = 128 bytes */
  13486. +#define TMU_LLM_SIZE (4 * 16 * TMU_LLM_QUEUE_LEN) /**< (4 TMU's x 16 queues x queue_len) */
  13487. +
  13488. +#define DDR_MAX_SIZE (TMU_LLM_BASEADDR + TMU_LLM_SIZE)
  13489. +
  13490. +#else
  13491. +
  13492. +#define UTIL_CODE_BASEADDR 0
  13493. +#if defined(CONFIG_UTIL_DISABLED)
  13494. +#define UTIL_CODE_SIZE (0 * SZ_1K)
  13495. +#else
  13496. +#define UTIL_CODE_SIZE (8 * SZ_1K)
  13497. +#endif
  13498. +#define UTIL_DDR_DATA_BASEADDR (UTIL_CODE_BASEADDR + UTIL_CODE_SIZE)
  13499. +#define UTIL_DDR_DATA_SIZE (0 * SZ_1K)
  13500. +#define CLASS_DDR_DATA_BASEADDR (UTIL_DDR_DATA_BASEADDR + UTIL_DDR_DATA_SIZE)
  13501. +#define CLASS_DDR_DATA_SIZE (0 * SZ_1K)
  13502. +#define TMU_DDR_DATA_BASEADDR (CLASS_DDR_DATA_BASEADDR + CLASS_DDR_DATA_SIZE)
  13503. +#define TMU_DDR_DATA_SIZE (0 * SZ_1K)
  13504. +#define ROUTE_TABLE_BASEADDR (TMU_DDR_DATA_BASEADDR + TMU_DDR_DATA_SIZE)
  13505. +#define ROUTE_TABLE_HASH_BITS 5 /**< 32 entries */
  13506. +#define ROUTE_TABLE_SIZE ((1 << ROUTE_TABLE_HASH_BITS) * CLASS_ROUTE_SIZE)
  13507. +#define BMU2_DDR_BASEADDR (ROUTE_TABLE_BASEADDR + ROUTE_TABLE_SIZE)
  13508. +#define BMU2_BUF_COUNT 16
  13509. +#define BMU2_DDR_SIZE (DDR_BUF_SIZE * BMU2_BUF_COUNT)
  13510. +#define TMU_LLM_BASEADDR (BMU2_DDR_BASEADDR + BMU2_DDR_SIZE)
  13511. +#define TMU_LLM_QUEUE_LEN (16 * 8) /**< Must be power of two and at least 16 * 8 = 128 bytes */
  13512. +#define TMU_LLM_SIZE (4 * 16 * TMU_LLM_QUEUE_LEN) /**< (4 TMU's x 16 queues x queue_len) */
  13513. +#define HIF_DESC_BASEADDR (TMU_LLM_BASEADDR + TMU_LLM_SIZE)
  13514. +#define HIF_RX_DESC_SIZE (16*HIF_RX_DESC_NT)
  13515. +#define HIF_TX_DESC_SIZE (16*HIF_TX_DESC_NT)
  13516. +#define HIF_DESC_SIZE (HIF_RX_DESC_SIZE + HIF_TX_DESC_SIZE)
  13517. +#define HIF_RX_PKT_DDR_BASEADDR (HIF_DESC_BASEADDR + HIF_DESC_SIZE)
  13518. +#define HIF_RX_PKT_DDR_SIZE (HIF_RX_DESC_NT * DDR_BUF_SIZE)
  13519. +#define HIF_TX_PKT_DDR_BASEADDR (HIF_RX_PKT_DDR_BASEADDR + HIF_RX_PKT_DDR_SIZE)
  13520. +#define HIF_TX_PKT_DDR_SIZE (HIF_TX_DESC_NT * DDR_BUF_SIZE)
  13521. +#define ROUTE_BASEADDR (HIF_TX_PKT_DDR_BASEADDR + HIF_TX_PKT_DDR_SIZE)
  13522. +#define ROUTE_SIZE (2 * CLASS_ROUTE_SIZE)
  13523. +
  13524. +#define DDR_MAX_SIZE (ROUTE_BASEADDR + ROUTE_SIZE)
  13525. +
  13526. +#define PFE_HOST_TO_PCI(addr) (((u32)addr)- ((u32)DDR_BASE_ADDR))
  13527. +#define PFE_PCI_TO_HOST(addr) (((u32)addr)+ ((u32)DDR_BASE_ADDR))
  13528. +#endif
  13529. +
  13530. +/* IRAM Mapping */
  13531. +#define IPSEC_IRAM_BASEADDR 0
  13532. +#define IPSEC_IRAM_SIZE 0x2000
  13533. +
  13534. +/* LMEM Mapping */
  13535. +#define BMU1_LMEM_BASEADDR 0
  13536. +#define BMU1_BUF_COUNT 256
  13537. +#define BMU1_LMEM_SIZE (LMEM_BUF_SIZE * BMU1_BUF_COUNT)
  13538. +#define IPSEC_LMEM_BASEADDR (BMU1_LMEM_BASEADDR + BMU1_LMEM_SIZE)
  13539. +#define IPSEC_LMEM_SIZE (30 * 1024)
  13540. +
  13541. +
  13542. +
  13543. +#endif /* _PFE_MOD_H */
  13544. --- /dev/null
  13545. +++ b/drivers/staging/fsl_ppfe/pfe_perfmon.c
  13546. @@ -0,0 +1,175 @@
  13547. +/*
  13548. + *
  13549. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  13550. + *
  13551. + * This program is free software; you can redistribute it and/or modify
  13552. + * it under the terms of the GNU General Public License as published by
  13553. + * the Free Software Foundation; either version 2 of the License, or
  13554. + * (at your option) any later version.
  13555. + *
  13556. + * This program is distributed in the hope that it will be useful,
  13557. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13558. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13559. + * GNU General Public License for more details.
  13560. + *
  13561. + * You should have received a copy of the GNU General Public License
  13562. + * along with this program; if not, write to the Free Software
  13563. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13564. + */
  13565. +
  13566. +/* PFE performance monitoring functions */
  13567. +
  13568. +#include "pfe_ctrl_hal.h"
  13569. +#include "pfe_perfmon.h"
  13570. +
  13571. +static TIMER_ENTRY cpumon_timer;
  13572. +
  13573. +u32 CLASS_DMEM_SH2(cpu_ticks[2]);
  13574. +u32 TMU_DMEM_SH2(cpu_ticks[2]);
  13575. +#if !defined(CONFIG_UTIL_DISABLED)
  13576. +u32 UTIL_DMEM_SH2(cpu_ticks[2]);
  13577. +#endif
  13578. +
  13579. +#define compute_active_pct(total_ticks, active_ticks) ((active_ticks * 100 + (total_ticks >> 1)) / total_ticks)
  13580. +
  13581. +static void cpumon_timer_handler(void)
  13582. +{
  13583. + int id;
  13584. + u32 dmem_addr;
  13585. + u32 ticks[2];
  13586. + u32 total, active;
  13587. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  13588. + struct pfe_cpumon *cpumon = &pfe->cpumon;
  13589. +
  13590. + // Process class PE's
  13591. + total = active = 0;
  13592. + dmem_addr = virt_to_class_dmem(&class_cpu_ticks[0]);
  13593. + for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
  13594. + {
  13595. + cpumon->cpu_usage_pct[id] = 0;
  13596. + if (pe_sync_stop(ctrl, (1 << id)) < 0)
  13597. + continue;
  13598. + ticks[0] = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4));
  13599. + ticks[1] = be32_to_cpu(pe_dmem_read(id, dmem_addr + 4, 4));
  13600. + pe_dmem_write(id, 0, dmem_addr, 4);
  13601. + pe_dmem_write(id, 0, dmem_addr + 4, 4);
  13602. + pe_start(ctrl, (1 << id));
  13603. + ticks[0] >>= 8; // divide both values by 256, so multiply by 100 won't overflow
  13604. + ticks[1] >>= 8;
  13605. + total += ticks[0];
  13606. + active += ticks[1];
  13607. + if (ticks[0] != 0)
  13608. + cpumon->cpu_usage_pct[id] = compute_active_pct(ticks[0], ticks[1]);
  13609. + }
  13610. + if (total != 0)
  13611. + cpumon->class_usage_pct = compute_active_pct(total, active);
  13612. + else
  13613. + cpumon->class_usage_pct = 0;
  13614. +
  13615. + // Process TMU PE's
  13616. + total = active = 0;
  13617. + dmem_addr = virt_to_tmu_dmem(&tmu_cpu_ticks[0]);
  13618. + for (id = TMU0_ID; id <= TMU_MAX_ID; id++)
  13619. + {
  13620. +#if defined(CONFIG_PLATFORM_LS1012A)
  13621. + if(id == TMU2_ID) continue;
  13622. +#endif
  13623. + cpumon->cpu_usage_pct[id] = 0;
  13624. + if (pe_sync_stop(ctrl, (1 << id)) < 0)
  13625. + continue;
  13626. + ticks[0] = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4));
  13627. + ticks[1] = be32_to_cpu(pe_dmem_read(id, dmem_addr + 4, 4));
  13628. + pe_dmem_write(id, 0, dmem_addr, 4);
  13629. + pe_dmem_write(id, 0, dmem_addr + 4, 4);
  13630. + pe_start(ctrl, (1 << id));
  13631. + ticks[0] >>= 8; // divide both values by 256, so multiply by 100 won't overflow
  13632. + ticks[1] >>= 8;
  13633. + if (ticks[0] != 0)
  13634. + cpumon->cpu_usage_pct[id] = compute_active_pct(ticks[0], ticks[1]);
  13635. + }
  13636. +#if !defined(CONFIG_UTIL_DISABLED)
  13637. + // Process Util PE
  13638. + dmem_addr = virt_to_util_dmem(&util_cpu_ticks[0]);
  13639. + cpumon->cpu_usage_pct[UTIL_ID] = 0;
  13640. + if (pe_sync_stop(ctrl, (1 << UTIL_ID)) < 0)
  13641. + return;
  13642. + ticks[0] = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr, 4));
  13643. + ticks[1] = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr + 4, 4));
  13644. + pe_dmem_write(UTIL_ID, 0, dmem_addr, 4);
  13645. + pe_dmem_write(UTIL_ID, 0, dmem_addr + 4, 4);
  13646. + pe_start(ctrl, (1 << UTIL_ID));
  13647. + ticks[0] >>= 8; // divide both values by 256, so multiply by 100 won't overflow
  13648. + ticks[1] >>= 8;
  13649. + if (ticks[0] != 0)
  13650. + cpumon->cpu_usage_pct[UTIL_ID] = compute_active_pct(ticks[0], ticks[1]);
  13651. +#endif
  13652. +}
  13653. +
  13654. +static int pfe_cpumon_init(struct pfe *pfe)
  13655. +{
  13656. + timer_init(&cpumon_timer, cpumon_timer_handler);
  13657. + timer_add(&cpumon_timer, CT_CPUMON_INTERVAL);
  13658. + return 0;
  13659. +}
  13660. +
  13661. +static void pfe_cpumon_exit(struct pfe *pfe)
  13662. +{
  13663. + timer_del(&cpumon_timer);
  13664. +}
  13665. +
  13666. +
  13667. +/*********************************************************************************/
  13668. +
  13669. +// Memory monitor functions
  13670. +
  13671. +void * pfe_kmalloc(size_t size, int flags)
  13672. +{
  13673. + struct pfe_memmon *memmon = &pfe->memmon;
  13674. + void *ptr;
  13675. + ptr = kmalloc(size, flags);
  13676. + if (ptr)
  13677. + memmon->kernel_memory_allocated += ksize(ptr);
  13678. + return ptr;
  13679. +}
  13680. +
  13681. +void * pfe_kzalloc(size_t size, int flags)
  13682. +{
  13683. + struct pfe_memmon *memmon = &pfe->memmon;
  13684. + void *ptr;
  13685. + ptr = kzalloc(size, flags);
  13686. + if (ptr)
  13687. + memmon->kernel_memory_allocated += ksize(ptr);
  13688. + return ptr;
  13689. +}
  13690. +
  13691. +void pfe_kfree(void *ptr)
  13692. +{
  13693. + struct pfe_memmon *memmon = &pfe->memmon;
  13694. + memmon->kernel_memory_allocated -= ksize(ptr);
  13695. + kfree(ptr);
  13696. +}
  13697. +
  13698. +static int pfe_memmon_init(struct pfe *pfe)
  13699. +{
  13700. + return 0;
  13701. +}
  13702. +
  13703. +static void pfe_memmon_exit(struct pfe *pfe)
  13704. +{
  13705. +}
  13706. +
  13707. +/*********************************************************************************/
  13708. +
  13709. +
  13710. +int pfe_perfmon_init(struct pfe *pfe)
  13711. +{
  13712. + pfe_cpumon_init(pfe);
  13713. + pfe_memmon_init(pfe);
  13714. + return 0;
  13715. +}
  13716. +
  13717. +void pfe_perfmon_exit(struct pfe *pfe)
  13718. +{
  13719. + pfe_cpumon_exit(pfe);
  13720. + pfe_memmon_exit(pfe);
  13721. +}
  13722. --- /dev/null
  13723. +++ b/drivers/staging/fsl_ppfe/pfe_perfmon.h
  13724. @@ -0,0 +1,41 @@
  13725. +/*
  13726. + *
  13727. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  13728. + *
  13729. + * This program is free software; you can redistribute it and/or modify
  13730. + * it under the terms of the GNU General Public License as published by
  13731. + * the Free Software Foundation; either version 2 of the License, or
  13732. + * (at your option) any later version.
  13733. + *
  13734. + * This program is distributed in the hope that it will be useful,
  13735. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13736. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13737. + * GNU General Public License for more details.
  13738. + *
  13739. + * You should have received a copy of the GNU General Public License
  13740. + * along with this program; if not, write to the Free Software
  13741. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13742. + */
  13743. +
  13744. +#ifndef _PFE_PERFMON_H_
  13745. +#define _PFE_PERFMON_H_
  13746. +
  13747. +#define CT_CPUMON_INTERVAL (1 * TIMER_TICKS_PER_SEC)
  13748. +
  13749. +struct pfe_cpumon {
  13750. + u32 cpu_usage_pct[MAX_PE];
  13751. + u32 class_usage_pct;
  13752. +};
  13753. +
  13754. +struct pfe_memmon {
  13755. + u32 kernel_memory_allocated;
  13756. +};
  13757. +
  13758. +void * pfe_kmalloc(size_t size, int flags);
  13759. +void * pfe_kzalloc(size_t size, int flags);
  13760. +void pfe_kfree(void *ptr);
  13761. +
  13762. +int pfe_perfmon_init(struct pfe *pfe);
  13763. +void pfe_perfmon_exit(struct pfe *pfe);
  13764. +
  13765. +#endif /* _PFE_PERFMON_H_ */
  13766. --- /dev/null
  13767. +++ b/drivers/staging/fsl_ppfe/pfe_platform.c
  13768. @@ -0,0 +1,358 @@
  13769. +/*
  13770. + *
  13771. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  13772. + *
  13773. + * This program is free software; you can redistribute it and/or modify
  13774. + * it under the terms of the GNU General Public License as published by
  13775. + * the Free Software Foundation; either version 2 of the License, or
  13776. + * (at your option) any later version.
  13777. + *
  13778. + * This program is distributed in the hope that it will be useful,
  13779. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13780. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13781. + * GNU General Public License for more details.
  13782. + *
  13783. + * You should have received a copy of the GNU General Public License
  13784. + * along with this program; if not, write to the Free Software
  13785. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13786. + */
  13787. +
  13788. +#include <linux/module.h>
  13789. +#include <linux/platform_device.h>
  13790. +#include <linux/slab.h>
  13791. +#include <linux/clk.h>
  13792. +
  13793. +#include "pfe_mod.h"
  13794. +
  13795. +/**
  13796. + * pfe_platform_probe -
  13797. + *
  13798. + *
  13799. + */
  13800. +static int pfe_platform_probe(struct platform_device *pdev)
  13801. +{
  13802. + struct resource *r;
  13803. + int rc;
  13804. + struct clk *clk_axi;
  13805. +
  13806. + printk(KERN_INFO "%s\n", __func__);
  13807. +
  13808. + pfe = kzalloc(sizeof(struct pfe), GFP_KERNEL);
  13809. + if (!pfe) {
  13810. + rc = -ENOMEM;
  13811. + goto err_alloc;
  13812. + }
  13813. +
  13814. + platform_set_drvdata(pdev, pfe);
  13815. +
  13816. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ddr");
  13817. + if (!r) {
  13818. + printk(KERN_INFO "platform_get_resource_byname(ddr) failed\n");
  13819. + rc = -ENXIO;
  13820. + goto err_ddr;
  13821. + }
  13822. +
  13823. + pfe->ddr_phys_baseaddr = r->start;
  13824. + pfe->ddr_size = resource_size(r);
  13825. +
  13826. + pfe->ddr_baseaddr = ioremap(r->start, resource_size(r));
  13827. + if (!pfe->ddr_baseaddr) {
  13828. + printk(KERN_INFO "ioremap() ddr failed\n");
  13829. + rc = -ENOMEM;
  13830. + goto err_ddr;
  13831. + }
  13832. +
  13833. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "axi");
  13834. + if (!r) {
  13835. + printk(KERN_INFO "platform_get_resource_byname(axi) failed\n");
  13836. + rc = -ENXIO;
  13837. + goto err_axi;
  13838. + }
  13839. +
  13840. + pfe->cbus_baseaddr = ioremap(r->start, resource_size(r));
  13841. + if (!pfe->cbus_baseaddr) {
  13842. + printk(KERN_INFO "ioremap() axi failed\n");
  13843. + rc = -ENOMEM;
  13844. + goto err_axi;
  13845. + }
  13846. +
  13847. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb");
  13848. + if (!r) {
  13849. + printk(KERN_INFO "platform_get_resource_byname(apb) failed\n");
  13850. + rc = -ENXIO;
  13851. + goto err_apb;
  13852. + }
  13853. +
  13854. + pfe->apb_baseaddr = ioremap(r->start, resource_size(r));
  13855. + if (!pfe->apb_baseaddr) {
  13856. + printk(KERN_INFO "ioremap() apb failed\n");
  13857. + rc = -ENOMEM;
  13858. + goto err_apb;
  13859. + }
  13860. +
  13861. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iram");
  13862. + if (!r) {
  13863. + printk(KERN_INFO "platform_get_resource_byname(iram) failed\n");
  13864. + rc = -ENXIO;
  13865. + goto err_iram;
  13866. + }
  13867. +
  13868. + pfe->iram_phys_baseaddr = r->start;
  13869. + pfe->iram_baseaddr = ioremap(r->start, resource_size(r));
  13870. + if (!pfe->iram_baseaddr) {
  13871. + printk(KERN_INFO "ioremap() iram failed\n");
  13872. + rc = -ENOMEM;
  13873. + goto err_iram;
  13874. + }
  13875. +
  13876. + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipsec");
  13877. + if (!r) {
  13878. + printk(KERN_INFO "platform_get_resource_byname(ipsec) failed\n");
  13879. + rc = -ENXIO;
  13880. + goto err_ipsec;
  13881. + }
  13882. +
  13883. + pfe->ipsec_phys_baseaddr = r->start;
  13884. + /* Just map only initial 1MB , as its enough to access espah engine
  13885. + */
  13886. + //pfe->ipsec_baseaddr = ioremap(r->start, resource_size(r));
  13887. + pfe->ipsec_baseaddr = ioremap(r->start, 1*1024*1024);
  13888. + if (!pfe->ipsec_baseaddr) {
  13889. + printk(KERN_INFO "ioremap() ipsec failed\n");
  13890. + rc = -ENOMEM;
  13891. + goto err_ipsec;
  13892. + }
  13893. +
  13894. + printk(KERN_INFO "ipsec: baseaddr :%x --- %x\n", (u32)pfe->ipsec_phys_baseaddr, (u32)pfe->ipsec_baseaddr);
  13895. +
  13896. + pfe->hif_irq = platform_get_irq_byname(pdev, "hif");
  13897. + if (pfe->hif_irq < 0) {
  13898. + printk(KERN_INFO "platform_get_irq_byname(hif) failed\n");
  13899. + rc = pfe->hif_irq;
  13900. + goto err_hif_irq;
  13901. + }
  13902. +
  13903. +#if 0
  13904. + pfe->hif_client_irq = platform_get_irq_byname(pdev, "hif_client");
  13905. + if (pfe->hif_client_irq < 0) {
  13906. + printk(KERN_INFO "platform_get_irq_byname(hif_client) failed\n");
  13907. + rc = pfe->hif_client_irq;
  13908. + goto err_hif_irq;
  13909. + }
  13910. +#endif
  13911. +
  13912. + pfe->dev = &pdev->dev;
  13913. +
  13914. +
  13915. + /* Get the system clock */
  13916. + clk_axi = clk_get(NULL,"axi");
  13917. + if (IS_ERR(clk_axi)) {
  13918. + printk(KERN_INFO "clk_get call failed\n");
  13919. + rc = -ENXIO;
  13920. + goto err_clk;
  13921. + }
  13922. +
  13923. + /* HFE core clock */
  13924. + pfe->hfe_clock = clk_get(NULL, "hfe_core");
  13925. + if (IS_ERR(pfe->hfe_clock)) {
  13926. + printk(KERN_INFO "clk_get call failed\n");
  13927. + rc = -ENXIO;
  13928. + goto err_hfe_clock;
  13929. + }
  13930. +
  13931. + clk_disable(pfe->hfe_clock);
  13932. + c2000_block_reset(COMPONENT_PFE_SYS, 1);
  13933. + mdelay(1);
  13934. + c2000_block_reset(COMPONENT_PFE_SYS, 0);
  13935. + clk_enable(pfe->hfe_clock);
  13936. +
  13937. + pfe->ctrl.clk_axi = clk_axi;
  13938. + pfe->ctrl.sys_clk = clk_get_rate(clk_axi) / 1000; // save sys_clk value as KHz
  13939. +
  13940. + rc = pfe_probe(pfe);
  13941. + if (rc < 0)
  13942. + goto err_probe;
  13943. +
  13944. + return 0;
  13945. +
  13946. +err_probe:
  13947. + clk_put(pfe->hfe_clock);
  13948. +err_hfe_clock:
  13949. + clk_put(clk_axi);
  13950. +err_clk:
  13951. +err_hif_irq:
  13952. + iounmap(pfe->ipsec_baseaddr);
  13953. +err_ipsec:
  13954. + iounmap(pfe->iram_baseaddr);
  13955. +err_iram:
  13956. + iounmap(pfe->apb_baseaddr);
  13957. +
  13958. +err_apb:
  13959. + iounmap(pfe->cbus_baseaddr);
  13960. +
  13961. +err_axi:
  13962. + iounmap(pfe->ddr_baseaddr);
  13963. +
  13964. +err_ddr:
  13965. + platform_set_drvdata(pdev, NULL);
  13966. +
  13967. + kfree(pfe);
  13968. +
  13969. +err_alloc:
  13970. + return rc;
  13971. +}
  13972. +
  13973. +
  13974. +/**
  13975. + * pfe_platform_remove -
  13976. + *
  13977. + *
  13978. + */
  13979. +static int pfe_platform_remove(struct platform_device *pdev)
  13980. +{
  13981. + struct pfe *pfe = platform_get_drvdata(pdev);
  13982. + int rc;
  13983. +
  13984. + printk(KERN_INFO "%s\n", __func__);
  13985. +
  13986. + rc = pfe_remove(pfe);
  13987. +
  13988. + c2000_block_reset(COMPONENT_PFE_SYS, 1);
  13989. + clk_disable(pfe->hfe_clock);
  13990. + clk_put(pfe->hfe_clock);
  13991. + clk_put(pfe->ctrl.clk_axi);
  13992. + iounmap(pfe->ipsec_baseaddr);
  13993. + iounmap(pfe->iram_baseaddr);
  13994. + iounmap(pfe->apb_baseaddr);
  13995. + iounmap(pfe->cbus_baseaddr);
  13996. + iounmap(pfe->ddr_baseaddr);
  13997. +
  13998. + platform_set_drvdata(pdev, NULL);
  13999. +
  14000. + kfree(pfe);
  14001. +
  14002. + return rc;
  14003. +}
  14004. +
  14005. +#ifdef CONFIG_PM
  14006. +
  14007. +#ifdef CONFIG_PM_SLEEP
  14008. +static int pfe_platform_suspend(struct device *dev)
  14009. +{
  14010. + struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
  14011. + struct net_device *netdev;
  14012. + int i;
  14013. +
  14014. + printk(KERN_INFO "%s\n", __func__);
  14015. +
  14016. + pfe->wake = 0;
  14017. +
  14018. + for (i = 0; i < (NUM_GEMAC_SUPPORT - 1); i++ ) {
  14019. + netdev = pfe->eth.eth_priv[i]->dev;
  14020. +
  14021. + netif_device_detach(netdev);
  14022. +
  14023. + if (netif_running(netdev))
  14024. + if(pfe_eth_suspend(netdev))
  14025. + pfe->wake =1;
  14026. + }
  14027. +
  14028. + /* Shutdown PFE only if we're not waking up the system */
  14029. + if (!pfe->wake) {
  14030. + pfe_ctrl_suspend(&pfe->ctrl);
  14031. + pfe_hif_exit(pfe);
  14032. + pfe_hif_lib_exit(pfe);
  14033. +
  14034. + class_disable();
  14035. + tmu_disable(0xf);
  14036. +#if !defined(CONFIG_UTIL_DISABLED)
  14037. + util_disable();
  14038. +#endif
  14039. + pfe_hw_exit(pfe);
  14040. + c2000_block_reset(COMPONENT_PFE_SYS, 1);
  14041. + clk_disable(pfe->hfe_clock);
  14042. + }
  14043. +
  14044. + return 0;
  14045. +}
  14046. +
  14047. +static int pfe_platform_resume(struct device *dev)
  14048. +{
  14049. + struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
  14050. + struct net_device *netdev;
  14051. + int i;
  14052. +
  14053. + printk(KERN_INFO "%s\n", __func__);
  14054. +
  14055. + if (!pfe->wake) {
  14056. + /* Sequence follows VLSI recommendation (bug 71927) */
  14057. + c2000_block_reset(COMPONENT_PFE_SYS, 1);
  14058. + mdelay(1);
  14059. + c2000_block_reset(COMPONENT_PFE_SYS, 0);
  14060. + clk_enable(pfe->hfe_clock);
  14061. +
  14062. + pfe_hw_init(pfe, 1);
  14063. + pfe_hif_lib_init(pfe);
  14064. + pfe_hif_init(pfe);
  14065. +#if !defined(CONFIG_UTIL_DISABLED)
  14066. + util_enable();
  14067. +#endif
  14068. + tmu_enable(0xf);
  14069. + class_enable();
  14070. + pfe_ctrl_resume(&pfe->ctrl);
  14071. + }
  14072. +
  14073. + for(i = 0; i < (NUM_GEMAC_SUPPORT - 1); i++) {
  14074. + netdev = pfe->eth.eth_priv[i]->dev;
  14075. +
  14076. + if (pfe->eth.eth_priv[i]->mii_bus)
  14077. + pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus);
  14078. +
  14079. + if (netif_running(netdev))
  14080. + pfe_eth_resume(netdev);
  14081. +
  14082. + netif_device_attach(netdev);
  14083. + }
  14084. + return 0;
  14085. +}
  14086. +#else
  14087. +#define pfe_platform_suspend NULL
  14088. +#define pfe_platform_resume NULL
  14089. +#endif
  14090. +
  14091. +static const struct dev_pm_ops pfe_platform_pm_ops = {
  14092. + SET_SYSTEM_SLEEP_PM_OPS(pfe_platform_suspend, pfe_platform_resume)
  14093. +};
  14094. +
  14095. +#endif
  14096. +
  14097. +static struct platform_driver pfe_platform_driver = {
  14098. + .probe = pfe_platform_probe,
  14099. + .remove = pfe_platform_remove,
  14100. + .driver = {
  14101. + .name = "pfe",
  14102. +#ifdef CONFIG_PM
  14103. + .pm = &pfe_platform_pm_ops,
  14104. +#endif
  14105. + },
  14106. +};
  14107. +
  14108. +
  14109. +static int __init pfe_module_init(void)
  14110. +{
  14111. + printk(KERN_INFO "%s\n", __func__);
  14112. +
  14113. + return platform_driver_register(&pfe_platform_driver);
  14114. +}
  14115. +
  14116. +
  14117. +static void __exit pfe_module_exit(void)
  14118. +{
  14119. + platform_driver_unregister(&pfe_platform_driver);
  14120. +
  14121. + printk(KERN_INFO "%s\n", __func__);
  14122. +}
  14123. +
  14124. +MODULE_LICENSE("GPL");
  14125. +module_init(pfe_module_init);
  14126. +module_exit(pfe_module_exit);
  14127. --- /dev/null
  14128. +++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
  14129. @@ -0,0 +1,855 @@
  14130. +/*
  14131. + * (C) Copyright 2011
  14132. + * Author : Freescale Semiconductor, Inc.
  14133. + *
  14134. + * See file CREDITS for list of people who contributed to this
  14135. + * project.
  14136. + *
  14137. + * This program is free software; you can redistribute it and/or
  14138. + * modify it under the terms of the GNU General Public License as
  14139. + * published by the Free Software Foundation; either version 2 of
  14140. + * the License, or (at your option) any later version.
  14141. + *
  14142. + * This program is distributed in the hope that it will be useful,
  14143. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14144. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14145. + * GNU General Public License for more details.
  14146. + *
  14147. + * You should have received a copy of the GNU General Public License
  14148. + * along with this program; if not, write to the Free Software
  14149. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  14150. + * MA 02111-1307 USA
  14151. + * */
  14152. +
  14153. +#include <linux/module.h>
  14154. +#include <linux/platform_device.h>
  14155. +
  14156. +#include "pfe_mod.h"
  14157. +#include "pfe_ctrl_hal.h"
  14158. +
  14159. +#define PE_EXCEPTION_DUMP_ADDRESS 0x1fa8
  14160. +#define NUM_QUEUES 16
  14161. +
  14162. +static char register_name[20][5] = {
  14163. + "EPC", "ECAS", "EID", "ED",
  14164. + "r0", "r1", "r2", "r3",
  14165. + "r4", "r5", "r6", "r7",
  14166. + "r8", "r9", "r10", "r11",
  14167. + "r12", "r13", "r14", "r15",
  14168. +};
  14169. +
  14170. +static char exception_name[14][20] = {
  14171. + "Reset",
  14172. + "HardwareFailure",
  14173. + "NMI",
  14174. + "InstBreakpoint",
  14175. + "DataBreakpoint",
  14176. + "Unsupported",
  14177. + "PrivilegeViolation",
  14178. + "InstBusError",
  14179. + "DataBusError",
  14180. + "AlignmentError",
  14181. + "ArithmeticError",
  14182. + "SystemCall",
  14183. + "MemoryManagement",
  14184. + "Interrupt",
  14185. +};
  14186. +
  14187. +static unsigned long class_do_clear = 0;
  14188. +static unsigned long tmu_do_clear = 0;
  14189. +#if !defined(CONFIG_UTIL_DISABLED)
  14190. +static unsigned long util_do_clear = 0;
  14191. +#endif
  14192. +
  14193. +u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset);
  14194. +
  14195. +static ssize_t display_pe_status(char *buf, int id, u32 dmem_addr, unsigned long do_clear)
  14196. +{
  14197. + ssize_t len = 0;
  14198. + u32 val;
  14199. + char statebuf[5];
  14200. + struct pfe_cpumon *cpumon = &pfe->cpumon;
  14201. + u32 debug_indicator;
  14202. + u32 debug[20];
  14203. +
  14204. + *(u32 *)statebuf = pe_dmem_read(id, dmem_addr, 4);
  14205. + dmem_addr += 4;
  14206. +
  14207. + statebuf[4] = '\0';
  14208. + len += sprintf(buf + len, "state=%4s ", statebuf);
  14209. +
  14210. + val = pe_dmem_read(id, dmem_addr, 4);
  14211. + dmem_addr += 4;
  14212. + len += sprintf(buf + len, "ctr=%08x ", cpu_to_be32(val));
  14213. +
  14214. + val = pe_dmem_read(id, dmem_addr, 4);
  14215. + if (do_clear && val)
  14216. + pe_dmem_write(id, 0, dmem_addr, 4);
  14217. + dmem_addr += 4;
  14218. + len += sprintf(buf + len, "rx=%u ", cpu_to_be32(val));
  14219. +
  14220. + val = pe_dmem_read(id, dmem_addr, 4);
  14221. + if (do_clear && val)
  14222. + pe_dmem_write(id, 0, dmem_addr, 4);
  14223. + dmem_addr += 4;
  14224. + if (id >= TMU0_ID && id <= TMU_MAX_ID)
  14225. + len += sprintf(buf + len, "qstatus=%x", cpu_to_be32(val));
  14226. + else
  14227. + len += sprintf(buf + len, "tx=%u", cpu_to_be32(val));
  14228. +
  14229. + val = pe_dmem_read(id, dmem_addr, 4);
  14230. + if (do_clear && val)
  14231. + pe_dmem_write(id, 0, dmem_addr, 4);
  14232. + dmem_addr += 4;
  14233. + if (val)
  14234. + len += sprintf(buf + len, " drop=%u", cpu_to_be32(val));
  14235. +
  14236. + len += sprintf(buf + len, " load=%d%%", cpumon->cpu_usage_pct[id]);
  14237. +
  14238. + len += sprintf(buf + len, "\n");
  14239. +
  14240. + debug_indicator = pe_dmem_read(id, dmem_addr, 4);
  14241. + dmem_addr += 4;
  14242. + if (!strncmp((char *)&debug_indicator, "DBUG", 4))
  14243. + {
  14244. + int j, last = 0;
  14245. + for (j = 0; j < 16; j++)
  14246. + {
  14247. + debug[j] = pe_dmem_read(id, dmem_addr, 4);
  14248. + if (debug[j])
  14249. + {
  14250. + if (do_clear)
  14251. + pe_dmem_write(id, 0, dmem_addr, 4);
  14252. + last = j + 1;
  14253. + }
  14254. + dmem_addr += 4;
  14255. + }
  14256. + for (j = 0; j < last; j++)
  14257. + {
  14258. + len += sprintf(buf + len, "%08x%s", cpu_to_be32(debug[j]),
  14259. + (j & 0x7) == 0x7 || j == last - 1 ? "\n" : " ");
  14260. + }
  14261. + }
  14262. +
  14263. + if (!strncmp(statebuf, "DEAD", 4))
  14264. + {
  14265. + u32 i, dump = PE_EXCEPTION_DUMP_ADDRESS;
  14266. +
  14267. + len += sprintf(buf + len, "Exception details:\n");
  14268. + for (i = 0; i < 20; i++) {
  14269. + debug[i] = pe_dmem_read(id, dump, 4);
  14270. + dump +=4;
  14271. + if (i == 2)
  14272. + len += sprintf(buf + len, "%4s = %08x (=%s) ", register_name[i], cpu_to_be32(debug[i]), exception_name[min((u32) cpu_to_be32(debug[i]), (u32)13)]);
  14273. + else
  14274. + len += sprintf(buf + len, "%4s = %08x%s", register_name[i], cpu_to_be32(debug[i]),
  14275. + (i & 0x3) == 0x3 || i == 19 ? "\n" : " ");
  14276. + }
  14277. + }
  14278. +
  14279. + return len;
  14280. +}
  14281. +
  14282. +static ssize_t class_phy_stats(char *buf, int phy)
  14283. +{
  14284. + ssize_t len = 0;
  14285. + int off1 = phy * 0x28;
  14286. + int off2 = phy * 0x10;
  14287. +
  14288. + if (phy == 3)
  14289. + off1 = CLASS_PHY4_RX_PKTS - CLASS_PHY1_RX_PKTS;
  14290. +
  14291. + len += sprintf(buf + len, "phy: %d\n", phy);
  14292. + len += sprintf(buf + len, " rx: %10u, tx: %10u, intf: %10u, ipv4: %10u, ipv6: %10u\n",
  14293. + readl(CLASS_PHY1_RX_PKTS + off1), readl(CLASS_PHY1_TX_PKTS + off1),
  14294. + readl(CLASS_PHY1_INTF_MATCH_PKTS + off1), readl(CLASS_PHY1_V4_PKTS + off1),
  14295. + readl(CLASS_PHY1_V6_PKTS + off1));
  14296. +
  14297. + len += sprintf(buf + len, " icmp: %10u, igmp: %10u, tcp: %10u, udp: %10u\n",
  14298. + readl(CLASS_PHY1_ICMP_PKTS + off2), readl(CLASS_PHY1_IGMP_PKTS + off2),
  14299. + readl(CLASS_PHY1_TCP_PKTS + off2), readl(CLASS_PHY1_UDP_PKTS + off2));
  14300. +
  14301. + len += sprintf(buf + len, " err\n");
  14302. + len += sprintf(buf + len, " lp: %10u, intf: %10u, l3: %10u, chcksum: %10u, ttl: %10u\n",
  14303. + readl(CLASS_PHY1_LP_FAIL_PKTS + off1), readl(CLASS_PHY1_INTF_FAIL_PKTS + off1),
  14304. + readl(CLASS_PHY1_L3_FAIL_PKTS + off1), readl(CLASS_PHY1_CHKSUM_ERR_PKTS + off1),
  14305. + readl(CLASS_PHY1_TTL_ERR_PKTS + off1));
  14306. +
  14307. + return len;
  14308. +}
  14309. +
  14310. +/** qm_read_drop_stat
  14311. + * This function is used to read the drop statistics from the TMU
  14312. + * hw drop counter. Since the hw counter is always cleared afer
  14313. + * reading, this function maintains the previous drop count, and
  14314. + * adds the new value to it. That value can be retrieved by
  14315. + * passing a pointer to it with the total_drops arg.
  14316. + *
  14317. + * @param tmu TMU number (0 - 3)
  14318. + * @param queue queue number (0 - 15)
  14319. + * @param total_drops pointer to location to store total drops (or NULL)
  14320. + * @param do_reset if TRUE, clear total drops after updating
  14321. + *
  14322. + */
  14323. +
  14324. +u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset)
  14325. +{
  14326. + static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES];
  14327. + u32 val;
  14328. + writel((tmu << 8) | queue, TMU_TEQ_CTRL);
  14329. + writel((tmu << 8) | queue, TMU_LLM_CTRL);
  14330. + val = readl(TMU_TEQ_DROP_STAT);
  14331. + qtotal[tmu][queue] += val;
  14332. + if (total_drops)
  14333. + *total_drops = qtotal[tmu][queue];
  14334. + if (do_reset)
  14335. + qtotal[tmu][queue] = 0;
  14336. + return val;
  14337. +}
  14338. +
  14339. +static ssize_t tmu_queue_stats(char *buf, int tmu, int queue)
  14340. +{
  14341. + ssize_t len = 0;
  14342. + u32 drops;
  14343. +
  14344. + len += sprintf(buf + len, "%d-%02d, ", tmu, queue);
  14345. +
  14346. + drops = qm_read_drop_stat(tmu, queue, NULL, 0);
  14347. +
  14348. + /* Select queue */
  14349. + writel((tmu << 8) | queue, TMU_TEQ_CTRL);
  14350. + writel((tmu << 8) | queue, TMU_LLM_CTRL);
  14351. +
  14352. + len += sprintf(buf + len, "(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n",
  14353. + drops, readl(TMU_TEQ_TRANS_STAT),
  14354. + readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR),
  14355. + readl(TMU_LLM_QUE_DROPCNT));
  14356. +
  14357. + return len;
  14358. +}
  14359. +
  14360. +
  14361. +static ssize_t tmu_queues(char *buf, int tmu)
  14362. +{
  14363. + ssize_t len = 0;
  14364. + int queue;
  14365. +
  14366. + for (queue = 0; queue < 16; queue++)
  14367. + len += tmu_queue_stats(buf + len, tmu, queue);
  14368. +
  14369. + return len;
  14370. +}
  14371. +
  14372. +static ssize_t tmu_ctx(char *buf, int tmu)
  14373. +{
  14374. + ssize_t len = 0;
  14375. + int i;
  14376. + u32 val, tmu_context_addr = TMU_CONTEXT_ADDR;
  14377. +
  14378. + len += sprintf(buf+len, " TMU %d \n", TMU0_ID+tmu);
  14379. + for (i = 1; i <= 160 ; i++, tmu_context_addr += 4)
  14380. + {
  14381. + val = pe_dmem_read(TMU0_ID+tmu, tmu_context_addr , 4);
  14382. + if (i == 5)
  14383. + len += sprintf(buf+len, "\nShapers: Each shaper structure is 8 bytes and there are 10 shapers\n");
  14384. +
  14385. + if (i == 25)
  14386. + len += sprintf(buf+len, "\nScheduler: Each scheduler structure is 48 bytes and there are 8 schedulers\n");
  14387. + if (i == 121)
  14388. + len += sprintf(buf+len, "\nQueue: Each queue structure is 2 bytes and there are 16 queues\n");
  14389. +
  14390. + if (i == 129)
  14391. + len += sprintf(buf+len, "\nqlenmasks array for 16 queues\n");
  14392. + if (i == 145)
  14393. + len += sprintf(buf+len, "\nqresultmap array for 16 queues\n");
  14394. + if (i%8 == 0)
  14395. + len += sprintf(buf+len, "%08x \n", cpu_to_be32(val));
  14396. + else
  14397. + len += sprintf(buf+len, "%08x ", cpu_to_be32(val));
  14398. + }
  14399. +
  14400. + len += sprintf(buf+len, "\n");
  14401. +
  14402. + return len;
  14403. +}
  14404. +
  14405. +static ssize_t block_version(char *buf, void *addr)
  14406. +{
  14407. + ssize_t len = 0;
  14408. + u32 val;
  14409. +
  14410. + val = readl(addr);
  14411. + len += sprintf(buf + len, "revision: %x, version: %x, id: %x\n", (val >> 24) & 0xff, (val >> 16) & 0xff, val & 0xffff);
  14412. +
  14413. + return len;
  14414. +}
  14415. +
  14416. +static ssize_t bmu(char *buf, int id, void *base)
  14417. +{
  14418. + ssize_t len = 0;
  14419. +
  14420. + len += sprintf(buf + len, "bmu: %d\n ", id);
  14421. +
  14422. + len += block_version(buf + len, base + BMU_VERSION);
  14423. +
  14424. + len += sprintf(buf + len, " buf size: %x\n", (1 << readl(base + BMU_BUF_SIZE)));
  14425. + len += sprintf(buf + len, " buf count: %x\n", readl(base + BMU_BUF_CNT));
  14426. + len += sprintf(buf + len, " buf rem: %x\n", readl(base + BMU_REM_BUF_CNT));
  14427. + len += sprintf(buf + len, " buf curr: %x\n", readl(base + BMU_CURR_BUF_CNT));
  14428. + len += sprintf(buf + len, " free err: %x\n", readl(base + BMU_FREE_ERR_ADDR));
  14429. +
  14430. + return len;
  14431. +}
  14432. +
  14433. +static ssize_t gpi(char *buf, int id, void *base)
  14434. +{
  14435. + ssize_t len = 0;
  14436. + u32 val;
  14437. +
  14438. + len += sprintf(buf + len, "gpi%d:\n ", id);
  14439. + len += block_version(buf + len, base + GPI_VERSION);
  14440. +
  14441. + len += sprintf(buf + len, " tx under stick: %x\n", readl(base + GPI_FIFO_STATUS));
  14442. + val = readl(base + GPI_FIFO_DEBUG);
  14443. + len += sprintf(buf + len, " tx pkts: %x\n", (val >> 23) & 0x3f);
  14444. + len += sprintf(buf + len, " rx pkts: %x\n", (val >> 18) & 0x3f);
  14445. + len += sprintf(buf + len, " tx bytes: %x\n", (val >> 9) & 0x1ff);
  14446. + len += sprintf(buf + len, " rx bytes: %x\n", (val >> 0) & 0x1ff);
  14447. + len += sprintf(buf + len, " overrun: %x\n", readl(base + GPI_OVERRUN_DROPCNT));
  14448. +
  14449. + return len;
  14450. +}
  14451. +
  14452. +static ssize_t pfe_set_class(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  14453. +{
  14454. + class_do_clear = simple_strtoul(buf, NULL, 0);
  14455. + return count;
  14456. +}
  14457. +
  14458. +static ssize_t pfe_show_class(struct device *dev, struct device_attribute *attr, char *buf)
  14459. +{
  14460. + ssize_t len = 0;
  14461. + int id;
  14462. + u32 val;
  14463. + struct pfe_cpumon *cpumon = &pfe->cpumon;
  14464. +
  14465. + len += block_version(buf + len, CLASS_VERSION);
  14466. +
  14467. + for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
  14468. + {
  14469. + len += sprintf(buf + len, "%d: ", id - CLASS0_ID);
  14470. +
  14471. + val = readl(CLASS_PE0_DEBUG + id * 4);
  14472. + len += sprintf(buf + len, "pc=1%04x ", val & 0xffff);
  14473. +
  14474. + len += display_pe_status(buf + len, id, PESTATUS_ADDR_CLASS, class_do_clear);
  14475. + }
  14476. + len += sprintf(buf + len, "aggregate load=%d%%\n\n", cpumon->class_usage_pct);
  14477. +
  14478. + len += sprintf(buf + len, "pe status: 0x%x\n", readl(CLASS_PE_STATUS));
  14479. + len += sprintf(buf + len, "max buf cnt: 0x%x afull thres: 0x%x\n", readl(CLASS_MAX_BUF_CNT), readl(CLASS_AFULL_THRES));
  14480. + len += sprintf(buf + len, "tsq max cnt: 0x%x tsq fifo thres: 0x%x\n", readl(CLASS_TSQ_MAX_CNT), readl(CLASS_TSQ_FIFO_THRES));
  14481. + len += sprintf(buf + len, "state: 0x%x\n", readl(CLASS_STATE));
  14482. +
  14483. + len += class_phy_stats(buf + len, 0);
  14484. + len += class_phy_stats(buf + len, 1);
  14485. + len += class_phy_stats(buf + len, 2);
  14486. + len += class_phy_stats(buf + len, 3);
  14487. +
  14488. + return len;
  14489. +}
  14490. +
  14491. +static ssize_t pfe_set_tmu(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  14492. +{
  14493. + tmu_do_clear = simple_strtoul(buf, NULL, 0);
  14494. + return count;
  14495. +}
  14496. +
  14497. +static ssize_t pfe_show_tmu(struct device *dev, struct device_attribute *attr, char *buf)
  14498. +{
  14499. + ssize_t len = 0;
  14500. + int id;
  14501. + u32 val;
  14502. +
  14503. + len += block_version(buf + len, TMU_VERSION);
  14504. +
  14505. + for (id = TMU0_ID; id <= TMU_MAX_ID; id++)
  14506. + {
  14507. +#if defined(CONFIG_PLATFORM_LS1012A)
  14508. + if(id == TMU2_ID) continue;
  14509. +#endif
  14510. + len += sprintf(buf + len, "%d: ", id - TMU0_ID);
  14511. +
  14512. + len += display_pe_status(buf + len, id, PESTATUS_ADDR_TMU, tmu_do_clear);
  14513. + }
  14514. +
  14515. + len += sprintf(buf + len, "pe status: %x\n", readl(TMU_PE_STATUS));
  14516. + len += sprintf(buf + len, "inq fifo cnt: %x\n", readl(TMU_PHY_INQ_FIFO_CNT));
  14517. + val = readl(TMU_INQ_STAT);
  14518. + len += sprintf(buf + len, "inq wr ptr: %x\n", val & 0x3ff);
  14519. + len += sprintf(buf + len, "inq rd ptr: %x\n", val >> 10);
  14520. +
  14521. +
  14522. + return len;
  14523. +}
  14524. +
  14525. +
  14526. +static unsigned long drops_do_clear = 0;
  14527. +static u32 CLASS_DMEM_SH2(drop_counter)[CLASS_NUM_DROP_COUNTERS];
  14528. +#if !defined(CONFIG_UTIL_DISABLED)
  14529. +static u32 UTIL_DMEM_SH2(drop_counter)[UTIL_NUM_DROP_COUNTERS];
  14530. +#endif
  14531. +
  14532. +char *class_drop_description[CLASS_NUM_DROP_COUNTERS] = {
  14533. + "ICC",
  14534. + "Host Pkt Error",
  14535. + "Rx Error",
  14536. + "IPsec Outbound",
  14537. + "IPsec Inbound",
  14538. + "EXPT IPsec Error",
  14539. + "Reassembly",
  14540. + "Fragmenter",
  14541. + "NAT-T",
  14542. + "Socket",
  14543. + "Multicast",
  14544. + "NAT-PT",
  14545. + "Tx Disabled",
  14546. +};
  14547. +
  14548. +#if !defined(CONFIG_UTIL_DISABLED)
  14549. +char *util_drop_description[UTIL_NUM_DROP_COUNTERS] = {
  14550. + "IPsec Outbound",
  14551. + "IPsec Inbound",
  14552. + "IPsec Rate Limiter",
  14553. + "Fragmenter",
  14554. + "Socket",
  14555. + "Tx Disabled",
  14556. + "Rx Error",
  14557. +};
  14558. +#endif
  14559. +
  14560. +static ssize_t pfe_set_drops(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  14561. +{
  14562. + drops_do_clear = simple_strtoul(buf, NULL, 0);
  14563. + return count;
  14564. +}
  14565. +
  14566. +static u32 tmu_drops[4][16];
  14567. +static ssize_t pfe_show_drops(struct device *dev, struct device_attribute *attr, char *buf)
  14568. +{
  14569. + ssize_t len = 0;
  14570. + int id, dropnum;
  14571. + int tmu, queue;
  14572. + u32 val;
  14573. + u32 dmem_addr;
  14574. + int num_class_drops = 0, num_tmu_drops = 0, num_util_drops = 0;
  14575. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  14576. +
  14577. + memset(class_drop_counter, 0, sizeof(class_drop_counter));
  14578. + for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
  14579. + {
  14580. + if (drops_do_clear)
  14581. + pe_sync_stop(ctrl, (1 << id));
  14582. + for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS; dropnum++)
  14583. + {
  14584. + dmem_addr = virt_to_class_dmem(&class_drop_counter[dropnum]);
  14585. + val = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4));
  14586. + class_drop_counter[dropnum] += val;
  14587. + num_class_drops += val;
  14588. + if (drops_do_clear)
  14589. + pe_dmem_write(id, 0, dmem_addr, 4);
  14590. + }
  14591. + if (drops_do_clear)
  14592. + pe_start(ctrl, (1 << id));
  14593. + }
  14594. +
  14595. +#if !defined(CONFIG_UTIL_DISABLED)
  14596. + if (drops_do_clear)
  14597. + pe_sync_stop(ctrl, (1 << UTIL_ID));
  14598. + for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++)
  14599. + {
  14600. + dmem_addr = virt_to_util_dmem(&util_drop_counter[dropnum]);
  14601. + val = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr, 4));
  14602. + util_drop_counter[dropnum] = val;
  14603. + num_util_drops += val;
  14604. + if (drops_do_clear)
  14605. + pe_dmem_write(UTIL_ID, 0, dmem_addr, 4);
  14606. + }
  14607. + if (drops_do_clear)
  14608. + pe_start(ctrl, (1 << UTIL_ID));
  14609. +#endif
  14610. + for (tmu = 0; tmu < 4; tmu++)
  14611. + {
  14612. + for (queue = 0; queue < 16; queue++)
  14613. + {
  14614. + qm_read_drop_stat(tmu, queue, &tmu_drops[tmu][queue], drops_do_clear);
  14615. + num_tmu_drops += tmu_drops[tmu][queue];
  14616. + }
  14617. + }
  14618. +
  14619. + if (num_class_drops == 0 && num_util_drops == 0 && num_tmu_drops == 0)
  14620. + len += sprintf(buf + len, "No PE drops\n\n");
  14621. +
  14622. + if (num_class_drops > 0)
  14623. + {
  14624. + len += sprintf(buf + len, "Class PE drops --\n");
  14625. + for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS; dropnum++)
  14626. + {
  14627. + if (class_drop_counter[dropnum] > 0)
  14628. + len += sprintf(buf + len, " %s: %d\n", class_drop_description[dropnum], class_drop_counter[dropnum]);
  14629. + }
  14630. + len += sprintf(buf + len, "\n");
  14631. + }
  14632. +
  14633. +#if !defined(CONFIG_UTIL_DISABLED)
  14634. + if (num_util_drops > 0)
  14635. + {
  14636. + len += sprintf(buf + len, "Util PE drops --\n");
  14637. + for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++)
  14638. + {
  14639. + if (util_drop_counter[dropnum] > 0)
  14640. + len += sprintf(buf + len, " %s: %d\n", util_drop_description[dropnum], util_drop_counter[dropnum]);
  14641. + }
  14642. + len += sprintf(buf + len, "\n");
  14643. + }
  14644. +#endif
  14645. + if (num_tmu_drops > 0)
  14646. + {
  14647. + len += sprintf(buf + len, "TMU drops --\n");
  14648. + for (tmu = 0; tmu < 4; tmu++)
  14649. + {
  14650. + for (queue = 0; queue < 16; queue++)
  14651. + {
  14652. + if (tmu_drops[tmu][queue] > 0)
  14653. + len += sprintf(buf + len, " TMU%d-Q%d: %d\n", tmu, queue, tmu_drops[tmu][queue]);
  14654. + }
  14655. + }
  14656. + len += sprintf(buf + len, "\n");
  14657. + }
  14658. +
  14659. + return len;
  14660. +}
  14661. +
  14662. +static ssize_t pfe_show_tmu0_queues(struct device *dev, struct device_attribute *attr, char *buf)
  14663. +{
  14664. + return tmu_queues(buf, 0);
  14665. +}
  14666. +
  14667. +static ssize_t pfe_show_tmu1_queues(struct device *dev, struct device_attribute *attr, char *buf)
  14668. +{
  14669. + return tmu_queues(buf, 1);
  14670. +}
  14671. +
  14672. +static ssize_t pfe_show_tmu2_queues(struct device *dev, struct device_attribute *attr, char *buf)
  14673. +{
  14674. + return tmu_queues(buf, 2);
  14675. +}
  14676. +
  14677. +static ssize_t pfe_show_tmu3_queues(struct device *dev, struct device_attribute *attr, char *buf)
  14678. +{
  14679. + return tmu_queues(buf, 3);
  14680. +}
  14681. +
  14682. +static ssize_t pfe_show_tmu0_ctx(struct device *dev, struct device_attribute *attr, char *buf)
  14683. +{
  14684. + return tmu_ctx(buf, 0);
  14685. +}
  14686. +static ssize_t pfe_show_tmu1_ctx(struct device *dev, struct device_attribute *attr, char *buf)
  14687. +{
  14688. + return tmu_ctx(buf, 1);
  14689. +}
  14690. +static ssize_t pfe_show_tmu2_ctx(struct device *dev, struct device_attribute *attr, char *buf)
  14691. +{
  14692. + return tmu_ctx(buf, 2);
  14693. +}
  14694. +
  14695. +static ssize_t pfe_show_tmu3_ctx(struct device *dev, struct device_attribute *attr, char *buf)
  14696. +{
  14697. + return tmu_ctx(buf, 3);
  14698. +}
  14699. +
  14700. +
  14701. +#if !defined(CONFIG_UTIL_DISABLED)
  14702. +static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  14703. +{
  14704. + util_do_clear = simple_strtoul(buf, NULL, 0);
  14705. + return count;
  14706. +}
  14707. +
  14708. +static ssize_t pfe_show_util(struct device *dev, struct device_attribute *attr, char *buf)
  14709. +{
  14710. + ssize_t len = 0;
  14711. + struct pfe_ctrl *ctrl = &pfe->ctrl;
  14712. +
  14713. +
  14714. + len += block_version(buf + len, UTIL_VERSION);
  14715. +
  14716. + pe_sync_stop(ctrl, (1 << UTIL_ID));
  14717. + len += display_pe_status(buf + len, UTIL_ID, PESTATUS_ADDR_UTIL, util_do_clear);
  14718. + pe_start(ctrl, (1 << UTIL_ID));
  14719. +
  14720. + len += sprintf(buf + len, "pe status: %x\n", readl(UTIL_PE_STATUS));
  14721. + len += sprintf(buf + len, "max buf cnt: %x\n", readl(UTIL_MAX_BUF_CNT));
  14722. + len += sprintf(buf + len, "tsq max cnt: %x\n", readl(UTIL_TSQ_MAX_CNT));
  14723. +
  14724. + return len;
  14725. +}
  14726. +#endif
  14727. +
  14728. +static ssize_t pfe_show_bmu(struct device *dev, struct device_attribute *attr, char *buf)
  14729. +{
  14730. + ssize_t len = 0;
  14731. +
  14732. + len += bmu(buf + len, 1, BMU1_BASE_ADDR);
  14733. + len += bmu(buf + len, 2, BMU2_BASE_ADDR);
  14734. +
  14735. + return len;
  14736. +}
  14737. +
  14738. +static ssize_t pfe_show_hif(struct device *dev, struct device_attribute *attr, char *buf)
  14739. +{
  14740. + ssize_t len = 0;
  14741. +
  14742. + len += sprintf(buf + len, "hif:\n ");
  14743. + len += block_version(buf + len, HIF_VERSION);
  14744. +
  14745. + len += sprintf(buf + len, " tx curr bd: %x\n", readl(HIF_TX_CURR_BD_ADDR));
  14746. + len += sprintf(buf + len, " tx status: %x\n", readl(HIF_TX_STATUS));
  14747. + len += sprintf(buf + len, " tx dma status: %x\n", readl(HIF_TX_DMA_STATUS));
  14748. +
  14749. + len += sprintf(buf + len, " rx curr bd: %x\n", readl(HIF_RX_CURR_BD_ADDR));
  14750. + len += sprintf(buf + len, " rx status: %x\n", readl(HIF_RX_STATUS));
  14751. + len += sprintf(buf + len, " rx dma status: %x\n", readl(HIF_RX_DMA_STATUS));
  14752. +
  14753. + len += sprintf(buf + len, "hif nocopy:\n ");
  14754. + len += block_version(buf + len, HIF_NOCPY_VERSION);
  14755. +
  14756. + len += sprintf(buf + len, " tx curr bd: %x\n", readl(HIF_NOCPY_TX_CURR_BD_ADDR));
  14757. + len += sprintf(buf + len, " tx status: %x\n", readl(HIF_NOCPY_TX_STATUS));
  14758. + len += sprintf(buf + len, " tx dma status: %x\n", readl(HIF_NOCPY_TX_DMA_STATUS));
  14759. +
  14760. + len += sprintf(buf + len, " rx curr bd: %x\n", readl(HIF_NOCPY_RX_CURR_BD_ADDR));
  14761. + len += sprintf(buf + len, " rx status: %x\n", readl(HIF_NOCPY_RX_STATUS));
  14762. + len += sprintf(buf + len, " rx dma status: %x\n", readl(HIF_NOCPY_RX_DMA_STATUS));
  14763. +
  14764. + return len;
  14765. +}
  14766. +
  14767. +
  14768. +static ssize_t pfe_show_gpi(struct device *dev, struct device_attribute *attr, char *buf)
  14769. +{
  14770. + ssize_t len = 0;
  14771. +
  14772. + len += gpi(buf + len, 0, EGPI1_BASE_ADDR);
  14773. + len += gpi(buf + len, 1, EGPI2_BASE_ADDR);
  14774. +#if !defined(CONFIG_PLATFORM_LS1012A)
  14775. + len += gpi(buf + len, 2, EGPI3_BASE_ADDR);
  14776. +#endif
  14777. + len += gpi(buf + len, 3, HGPI_BASE_ADDR);
  14778. +
  14779. + return len;
  14780. +}
  14781. +
  14782. +static ssize_t pfe_show_pfemem(struct device *dev, struct device_attribute *attr, char *buf)
  14783. +{
  14784. + ssize_t len = 0;
  14785. + struct pfe_memmon *memmon = &pfe->memmon;
  14786. +
  14787. + len += sprintf(buf + len, "Kernel Memory: %d Bytes (%d KB)\n", memmon->kernel_memory_allocated, (memmon->kernel_memory_allocated + 1023) / 1024);
  14788. +
  14789. + return len;
  14790. +}
  14791. +
  14792. +#ifdef HIF_NAPI_STATS
  14793. +static ssize_t pfe_show_hif_napi_stats(struct device *dev, struct device_attribute *attr, char *buf)
  14794. +{
  14795. + struct platform_device *pdev = to_platform_device(dev);
  14796. + struct pfe *pfe = platform_get_drvdata(pdev);
  14797. + ssize_t len = 0;
  14798. +
  14799. + len += sprintf(buf + len, "sched: %u\n", pfe->hif.napi_counters[NAPI_SCHED_COUNT]);
  14800. + len += sprintf(buf + len, "poll: %u\n", pfe->hif.napi_counters[NAPI_POLL_COUNT]);
  14801. + len += sprintf(buf + len, "packet: %u\n", pfe->hif.napi_counters[NAPI_PACKET_COUNT]);
  14802. + len += sprintf(buf + len, "budget: %u\n", pfe->hif.napi_counters[NAPI_FULL_BUDGET_COUNT]);
  14803. + len += sprintf(buf + len, "desc: %u\n", pfe->hif.napi_counters[NAPI_DESC_COUNT]);
  14804. + len += sprintf(buf + len, "full: %u\n", pfe->hif.napi_counters[NAPI_CLIENT_FULL_COUNT]);
  14805. +
  14806. + return len;
  14807. +}
  14808. +
  14809. +static ssize_t pfe_set_hif_napi_stats(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  14810. +{
  14811. + struct platform_device *pdev = to_platform_device(dev);
  14812. + struct pfe *pfe = platform_get_drvdata(pdev);
  14813. +
  14814. + memset(pfe->hif.napi_counters, 0, sizeof(pfe->hif.napi_counters));
  14815. +
  14816. + return count;
  14817. +}
  14818. +
  14819. +static DEVICE_ATTR(hif_napi_stats, 0644, pfe_show_hif_napi_stats, pfe_set_hif_napi_stats);
  14820. +#endif
  14821. +
  14822. +
  14823. +static DEVICE_ATTR(class, 0644, pfe_show_class, pfe_set_class);
  14824. +static DEVICE_ATTR(tmu, 0644, pfe_show_tmu, pfe_set_tmu);
  14825. +#if !defined(CONFIG_UTIL_DISABLED)
  14826. +static DEVICE_ATTR(util, 0644, pfe_show_util, pfe_set_util);
  14827. +#endif
  14828. +static DEVICE_ATTR(bmu, 0444, pfe_show_bmu, NULL);
  14829. +static DEVICE_ATTR(hif, 0444, pfe_show_hif, NULL);
  14830. +static DEVICE_ATTR(gpi, 0444, pfe_show_gpi, NULL);
  14831. +static DEVICE_ATTR(drops, 0644, pfe_show_drops, pfe_set_drops);
  14832. +static DEVICE_ATTR(tmu0_queues, 0444, pfe_show_tmu0_queues, NULL);
  14833. +static DEVICE_ATTR(tmu1_queues, 0444, pfe_show_tmu1_queues, NULL);
  14834. +static DEVICE_ATTR(tmu2_queues, 0444, pfe_show_tmu2_queues, NULL);
  14835. +static DEVICE_ATTR(tmu3_queues, 0444, pfe_show_tmu3_queues, NULL);
  14836. +static DEVICE_ATTR(tmu0_ctx, 0444, pfe_show_tmu0_ctx, NULL);
  14837. +static DEVICE_ATTR(tmu1_ctx, 0444, pfe_show_tmu1_ctx, NULL);
  14838. +static DEVICE_ATTR(tmu2_ctx, 0444, pfe_show_tmu2_ctx, NULL);
  14839. +static DEVICE_ATTR(tmu3_ctx, 0444, pfe_show_tmu3_ctx, NULL);
  14840. +static DEVICE_ATTR(pfemem, 0444, pfe_show_pfemem, NULL);
  14841. +
  14842. +
  14843. +int pfe_sysfs_init(struct pfe *pfe)
  14844. +{
  14845. + if (device_create_file(pfe->dev, &dev_attr_class))
  14846. + goto err_class;
  14847. +
  14848. + if (device_create_file(pfe->dev, &dev_attr_tmu))
  14849. + goto err_tmu;
  14850. +
  14851. +#if !defined(CONFIG_UTIL_DISABLED)
  14852. + if (device_create_file(pfe->dev, &dev_attr_util))
  14853. + goto err_util;
  14854. +#endif
  14855. +
  14856. + if (device_create_file(pfe->dev, &dev_attr_bmu))
  14857. + goto err_bmu;
  14858. +
  14859. + if (device_create_file(pfe->dev, &dev_attr_hif))
  14860. + goto err_hif;
  14861. +
  14862. + if (device_create_file(pfe->dev, &dev_attr_gpi))
  14863. + goto err_gpi;
  14864. +
  14865. + if (device_create_file(pfe->dev, &dev_attr_drops))
  14866. + goto err_drops;
  14867. +
  14868. + if (device_create_file(pfe->dev, &dev_attr_tmu0_queues))
  14869. + goto err_tmu0_queues;
  14870. +
  14871. + if (device_create_file(pfe->dev, &dev_attr_tmu1_queues))
  14872. + goto err_tmu1_queues;
  14873. +
  14874. + if (device_create_file(pfe->dev, &dev_attr_tmu2_queues))
  14875. + goto err_tmu2_queues;
  14876. +
  14877. + if (device_create_file(pfe->dev, &dev_attr_tmu3_queues))
  14878. + goto err_tmu3_queues;
  14879. +
  14880. + if (device_create_file(pfe->dev, &dev_attr_tmu0_ctx))
  14881. + goto err_tmu0_ctx;
  14882. +
  14883. + if (device_create_file(pfe->dev, &dev_attr_tmu1_ctx))
  14884. + goto err_tmu1_ctx;
  14885. +
  14886. + if (device_create_file(pfe->dev, &dev_attr_tmu2_ctx))
  14887. + goto err_tmu2_ctx;
  14888. +
  14889. + if (device_create_file(pfe->dev, &dev_attr_tmu3_ctx))
  14890. + goto err_tmu3_ctx;
  14891. +
  14892. + if (device_create_file(pfe->dev, &dev_attr_pfemem))
  14893. + goto err_pfemem;
  14894. +
  14895. +#ifdef HIF_NAPI_STATS
  14896. + if (device_create_file(pfe->dev, &dev_attr_hif_napi_stats))
  14897. + goto err_hif_napi_stats;
  14898. +#endif
  14899. +
  14900. + return 0;
  14901. +
  14902. +#ifdef HIF_NAPI_STATS
  14903. +err_hif_napi_stats:
  14904. + device_remove_file(pfe->dev, &dev_attr_pfemem);
  14905. +#endif
  14906. +
  14907. +err_pfemem:
  14908. + device_remove_file(pfe->dev, &dev_attr_tmu3_ctx);
  14909. +
  14910. +err_tmu3_ctx:
  14911. + device_remove_file(pfe->dev, &dev_attr_tmu2_ctx);
  14912. +
  14913. +err_tmu2_ctx:
  14914. + device_remove_file(pfe->dev, &dev_attr_tmu1_ctx);
  14915. +
  14916. +err_tmu1_ctx:
  14917. + device_remove_file(pfe->dev, &dev_attr_tmu0_ctx);
  14918. +
  14919. +err_tmu0_ctx:
  14920. + device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
  14921. +
  14922. +err_tmu3_queues:
  14923. + device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
  14924. +
  14925. +err_tmu2_queues:
  14926. + device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
  14927. +
  14928. +err_tmu1_queues:
  14929. + device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
  14930. +
  14931. +err_tmu0_queues:
  14932. + device_remove_file(pfe->dev, &dev_attr_drops);
  14933. +
  14934. +err_drops:
  14935. + device_remove_file(pfe->dev, &dev_attr_gpi);
  14936. +
  14937. +err_gpi:
  14938. + device_remove_file(pfe->dev, &dev_attr_hif);
  14939. +
  14940. +err_hif:
  14941. + device_remove_file(pfe->dev, &dev_attr_bmu);
  14942. +
  14943. +err_bmu:
  14944. +#if !defined(CONFIG_UTIL_DISABLED)
  14945. + device_remove_file(pfe->dev, &dev_attr_util);
  14946. +
  14947. +err_util:
  14948. +#endif
  14949. + device_remove_file(pfe->dev, &dev_attr_tmu);
  14950. +
  14951. +err_tmu:
  14952. + device_remove_file(pfe->dev, &dev_attr_class);
  14953. +
  14954. +err_class:
  14955. + return -1;
  14956. +}
  14957. +
  14958. +
  14959. +void pfe_sysfs_exit(struct pfe *pfe)
  14960. +{
  14961. +#ifdef HIF_NAPI_STATS
  14962. + device_remove_file(pfe->dev, &dev_attr_hif_napi_stats);
  14963. +#endif
  14964. +
  14965. + device_remove_file(pfe->dev, &dev_attr_pfemem);
  14966. + device_remove_file(pfe->dev, &dev_attr_tmu3_ctx);
  14967. + device_remove_file(pfe->dev, &dev_attr_tmu2_ctx);
  14968. + device_remove_file(pfe->dev, &dev_attr_tmu1_ctx);
  14969. + device_remove_file(pfe->dev, &dev_attr_tmu0_ctx);
  14970. + device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
  14971. + device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
  14972. + device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
  14973. + device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
  14974. + device_remove_file(pfe->dev, &dev_attr_drops);
  14975. + device_remove_file(pfe->dev, &dev_attr_gpi);
  14976. + device_remove_file(pfe->dev, &dev_attr_hif);
  14977. + device_remove_file(pfe->dev, &dev_attr_bmu);
  14978. +#if !defined(CONFIG_UTIL_DISABLED)
  14979. + device_remove_file(pfe->dev, &dev_attr_util);
  14980. +#endif
  14981. + device_remove_file(pfe->dev, &dev_attr_tmu);
  14982. + device_remove_file(pfe->dev, &dev_attr_class);
  14983. +}
  14984. +
  14985. --- /dev/null
  14986. +++ b/drivers/staging/fsl_ppfe/pfe_sysfs.h
  14987. @@ -0,0 +1,34 @@
  14988. +/*
  14989. + *
  14990. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  14991. + *
  14992. + * This program is free software; you can redistribute it and/or modify
  14993. + * it under the terms of the GNU General Public License as published by
  14994. + * the Free Software Foundation; either version 2 of the License, or
  14995. + * (at your option) any later version.
  14996. + *
  14997. + * This program is distributed in the hope that it will be useful,
  14998. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14999. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15000. + * GNU General Public License for more details.
  15001. + *
  15002. + * You should have received a copy of the GNU General Public License
  15003. + * along with this program; if not, write to the Free Software
  15004. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15005. + */
  15006. +
  15007. +#ifndef _PFE_SYSFS_H_
  15008. +#define _PFE_SYSFS_H_
  15009. +
  15010. +#include <linux/proc_fs.h>
  15011. +
  15012. +#define PESTATUS_ADDR_CLASS 0x800
  15013. +#define PESTATUS_ADDR_TMU 0x80
  15014. +#define PESTATUS_ADDR_UTIL 0x0
  15015. +
  15016. +#define TMU_CONTEXT_ADDR 0x3c8
  15017. +#define IPSEC_CNTRS_ADDR 0x840
  15018. +
  15019. +int pfe_sysfs_init(struct pfe *pfe);
  15020. +void pfe_sysfs_exit(struct pfe *pfe);
  15021. +#endif /* _PFE_SYSFS_H_ */
  15022. --- /dev/null
  15023. +++ b/drivers/staging/fsl_ppfe/platform.h
  15024. @@ -0,0 +1,25 @@
  15025. +/*
  15026. + *
  15027. + * Copyright (C) 2007 Freescale Semiconductor, Inc.
  15028. + *
  15029. + * This program is free software; you can redistribute it and/or modify
  15030. + * it under the terms of the GNU General Public License as published by
  15031. + * the Free Software Foundation; either version 2 of the License, or
  15032. + * (at your option) any later version.
  15033. + *
  15034. + * This program is distributed in the hope that it will be useful,
  15035. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15036. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15037. + * GNU General Public License for more details.
  15038. + *
  15039. + * You should have received a copy of the GNU General Public License
  15040. + * along with this program; if not, write to the Free Software
  15041. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15042. + */
  15043. +
  15044. +#ifndef _PLATFORM_H_
  15045. +#define _PLATFORM_H_
  15046. +
  15047. +#define virt_to_phys(virt) ((unsigned long)virt)
  15048. +
  15049. +#endif /* _PLATFORM_H_ */
  15050. --- a/include/linux/skbuff.h
  15051. +++ b/include/linux/skbuff.h
  15052. @@ -863,6 +863,17 @@ static inline struct sk_buff *alloc_skb_
  15053. return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE);
  15054. }
  15055. +extern struct sk_buff *__alloc_skb_header(unsigned int size, void *data,
  15056. + gfp_t gfp_mask,
  15057. + int fclone,
  15058. + int node);
  15059. +static inline struct sk_buff *alloc_skb_header(unsigned int size,
  15060. + u8 *data,
  15061. + gfp_t priority)
  15062. +{
  15063. + return __alloc_skb_header(size, data, priority, 0, -1);
  15064. +}
  15065. +
  15066. struct sk_buff *__alloc_skb_head(gfp_t priority, int node);
  15067. static inline struct sk_buff *alloc_skb_head(gfp_t priority)
  15068. {
  15069. --- a/net/core/skbuff.c
  15070. +++ b/net/core/skbuff.c
  15071. @@ -283,6 +283,90 @@ nodata:
  15072. EXPORT_SYMBOL(__alloc_skb);
  15073. /**
  15074. + * __alloc_skb_header - allocate a network buffer
  15075. + * @size: size to allocate
  15076. + * @gfp_mask: allocation mask
  15077. + * @fclone: allocate from fclone cache instead of head cache
  15078. + * and allocate a cloned (child) skb
  15079. + *
  15080. + * Allocate a new &sk_buff. The returned buffer has no headroom and a
  15081. + * tail room of size bytes. The object has a reference count of one.
  15082. + * The return is the buffer. On a failure the return is %NULL.
  15083. + *
  15084. + * Buffers may only be allocated from interrupts using a @gfp_mask of
  15085. + * %GFP_ATOMIC.
  15086. + */
  15087. +struct sk_buff *__alloc_skb_header(unsigned int size, void *data,
  15088. + gfp_t gfp_mask, int fclone, int node)
  15089. +{
  15090. + struct kmem_cache *cache;
  15091. + struct skb_shared_info *shinfo;
  15092. + struct sk_buff *skb;
  15093. +
  15094. + cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
  15095. +
  15096. + if (size <= SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) {
  15097. + skb = NULL;
  15098. + goto out;
  15099. + }
  15100. +
  15101. + /* Get the HEAD */
  15102. + skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
  15103. + if (!skb)
  15104. + goto out;
  15105. + prefetchw(skb);
  15106. +
  15107. + /* kmalloc might give us more room than requested.
  15108. + * Put skb_shared_info exactly at the end of allocated zone,
  15109. + * to allow max possible filling before reallocation.
  15110. + */
  15111. + size = SKB_WITH_OVERHEAD(ksize(data));
  15112. + prefetchw(data + size);
  15113. +
  15114. + /* Only clear those fields we need to clear, not those that we will
  15115. + * actually initialise below. Hence, don't put any more fields after
  15116. + * the tail pointer in struct sk_buff!
  15117. + */
  15118. + memset(skb, 0, offsetof(struct sk_buff, tail));
  15119. + /* Account for allocated memory : skb + skb->head */
  15120. + skb->truesize = SKB_TRUESIZE(size);
  15121. + atomic_set(&skb->users, 1);
  15122. + skb->head = data;
  15123. + skb->data = data;
  15124. + skb_reset_tail_pointer(skb);
  15125. + skb->end = skb->tail + size;
  15126. +#ifdef NET_SKBUFF_DATA_USES_OFFSET
  15127. + skb->mac_header = ~0U;
  15128. +#endif
  15129. +
  15130. +#if defined(CONFIG_COMCERTO_CUSTOM_SKB_LAYOUT)
  15131. + skb->mspd_data = NULL;
  15132. + skb->mspd_len = 0;
  15133. +#endif
  15134. +
  15135. + /* make sure we initialize shinfo sequentially */
  15136. + shinfo = skb_shinfo(skb);
  15137. + memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
  15138. + atomic_set(&shinfo->dataref, 1);
  15139. + kmemcheck_annotate_variable(shinfo->destructor_arg);
  15140. +
  15141. + if (fclone) {
  15142. + struct sk_buff *child = skb + 1;
  15143. + atomic_t *fclone_ref = (atomic_t *)(child + 1);
  15144. +
  15145. + kmemcheck_annotate_bitfield(child, flags1);
  15146. + kmemcheck_annotate_bitfield(child, flags2);
  15147. + skb->fclone = SKB_FCLONE_ORIG;
  15148. + atomic_set(fclone_ref, 1);
  15149. +
  15150. + child->fclone = SKB_FCLONE_UNAVAILABLE;
  15151. + }
  15152. +out:
  15153. + return skb;
  15154. +}
  15155. +EXPORT_SYMBOL(__alloc_skb_header);
  15156. +
  15157. +/**
  15158. * __build_skb - build a network buffer
  15159. * @data: data buffer provided by caller
  15160. * @frag_size: size of data, or 0 if head was kmalloced