1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297 |
- From 667f0792b6f6d000c10f21c29c397c84cbe77f4a Mon Sep 17 00:00:00 2001
- From: Yangbo Lu <[email protected]>
- Date: Wed, 17 Jan 2018 15:11:45 +0800
- Subject: [PATCH 10/30] fsl-mc: layerscape support
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- This is an integrated patch for layerscape mc-bus support.
- Signed-off-by: Stuart Yoder <[email protected]>
- Signed-off-by: Bharat Bhushan <[email protected]>
- Signed-off-by: Arnd Bergmann <[email protected]>
- Signed-off-by: Laurentiu Tudor <[email protected]>
- Signed-off-by: Roy Pledge <[email protected]>
- Signed-off-by: Shiva Kerdel <[email protected]>
- Signed-off-by: Nipun Gupta <[email protected]>
- Signed-off-by: Ioana Ciornei <[email protected]>
- Signed-off-by: Horia Geantă <[email protected]>
- Signed-off-by: Yangbo Lu <[email protected]>
- ---
- drivers/staging/fsl-mc/bus/Kconfig | 41 +-
- drivers/staging/fsl-mc/bus/Makefile | 10 +-
- drivers/staging/fsl-mc/bus/dpbp-cmd.h | 80 ++
- drivers/staging/fsl-mc/bus/dpbp.c | 450 +--------
- drivers/staging/fsl-mc/bus/dpcon-cmd.h | 85 ++
- drivers/staging/fsl-mc/bus/dpcon.c | 317 ++++++
- drivers/staging/fsl-mc/bus/dpio/Makefile | 11 +
- .../{include/dpcon-cmd.h => bus/dpio/dpio-cmd.h} | 73 +-
- drivers/staging/fsl-mc/bus/dpio/dpio-driver.c | 296 ++++++
- drivers/staging/fsl-mc/bus/dpio/dpio-service.c | 693 +++++++++++++
- drivers/staging/fsl-mc/bus/dpio/dpio.c | 224 +++++
- drivers/staging/fsl-mc/bus/dpio/dpio.h | 109 ++
- drivers/staging/fsl-mc/bus/dpio/qbman-portal.c | 1049 ++++++++++++++++++++
- drivers/staging/fsl-mc/bus/dpio/qbman-portal.h | 662 ++++++++++++
- drivers/staging/fsl-mc/bus/dpio/qbman_debug.c | 853 ++++++++++++++++
- drivers/staging/fsl-mc/bus/dpio/qbman_debug.h | 136 +++
- drivers/staging/fsl-mc/bus/dpio/qbman_private.h | 171 ++++
- drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 112 +--
- drivers/staging/fsl-mc/bus/dpmcp.c | 374 +------
- drivers/staging/fsl-mc/bus/dpmcp.h | 127 +--
- drivers/staging/fsl-mc/bus/dpmng-cmd.h | 14 +-
- drivers/staging/fsl-mc/bus/dpmng.c | 37 +-
- drivers/staging/fsl-mc/bus/dprc-cmd.h | 82 +-
- drivers/staging/fsl-mc/bus/dprc-driver.c | 38 +-
- drivers/staging/fsl-mc/bus/dprc.c | 629 +-----------
- drivers/staging/fsl-mc/bus/fsl-mc-allocator.c | 78 +-
- drivers/staging/fsl-mc/bus/fsl-mc-bus.c | 318 +++---
- drivers/staging/fsl-mc/bus/fsl-mc-iommu.c | 104 ++
- drivers/staging/fsl-mc/bus/fsl-mc-msi.c | 2 +-
- drivers/staging/fsl-mc/bus/fsl-mc-private.h | 6 +-
- .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 10 +-
- drivers/staging/fsl-mc/bus/mc-io.c | 4 +-
- drivers/staging/fsl-mc/bus/mc-ioctl.h | 22 +
- drivers/staging/fsl-mc/bus/mc-restool.c | 405 ++++++++
- drivers/staging/fsl-mc/bus/mc-sys.c | 14 +-
- drivers/staging/fsl-mc/include/dpaa2-fd.h | 706 +++++++++++++
- drivers/staging/fsl-mc/include/dpaa2-global.h | 202 ++++
- drivers/staging/fsl-mc/include/dpaa2-io.h | 190 ++++
- drivers/staging/fsl-mc/include/dpbp-cmd.h | 185 ----
- drivers/staging/fsl-mc/include/dpbp.h | 158 +--
- drivers/staging/fsl-mc/include/dpcon.h | 115 +++
- drivers/staging/fsl-mc/include/dpmng.h | 16 +-
- drivers/staging/fsl-mc/include/dpopr.h | 110 ++
- drivers/staging/fsl-mc/include/dprc.h | 470 +++------
- drivers/staging/fsl-mc/include/mc-bus.h | 7 +-
- drivers/staging/fsl-mc/include/mc-cmd.h | 44 +-
- drivers/staging/fsl-mc/include/mc-sys.h | 3 +-
- drivers/staging/fsl-mc/include/mc.h | 17 +-
- 48 files changed, 7247 insertions(+), 2612 deletions(-)
- create mode 100644 drivers/staging/fsl-mc/bus/dpbp-cmd.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpcon-cmd.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpcon.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/Makefile
- rename drivers/staging/fsl-mc/{include/dpcon-cmd.h => bus/dpio/dpio-cmd.h} (64%)
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio-driver.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio-service.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman-portal.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_debug.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_debug.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_private.h
- create mode 100644 drivers/staging/fsl-mc/bus/fsl-mc-iommu.c
- create mode 100644 drivers/staging/fsl-mc/bus/mc-ioctl.h
- create mode 100644 drivers/staging/fsl-mc/bus/mc-restool.c
- create mode 100644 drivers/staging/fsl-mc/include/dpaa2-fd.h
- create mode 100644 drivers/staging/fsl-mc/include/dpaa2-global.h
- create mode 100644 drivers/staging/fsl-mc/include/dpaa2-io.h
- delete mode 100644 drivers/staging/fsl-mc/include/dpbp-cmd.h
- create mode 100644 drivers/staging/fsl-mc/include/dpcon.h
- create mode 100644 drivers/staging/fsl-mc/include/dpopr.h
- --- a/drivers/staging/fsl-mc/bus/Kconfig
- +++ b/drivers/staging/fsl-mc/bus/Kconfig
- @@ -1,25 +1,40 @@
- #
- -# Freescale Management Complex (MC) bus drivers
- +# DPAA2 fsl-mc bus
- #
- -# Copyright (C) 2014 Freescale Semiconductor, Inc.
- +# Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- #
- # This file is released under the GPLv2
- #
-
- config FSL_MC_BUS
- - bool "Freescale Management Complex (MC) bus driver"
- - depends on OF && ARM64
- + bool "QorIQ DPAA2 fsl-mc bus driver"
- + depends on OF && ARCH_LAYERSCAPE
- select GENERIC_MSI_IRQ_DOMAIN
- help
- - Driver to enable the bus infrastructure for the Freescale
- - QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
- - module of the QorIQ LS2 SoCs, that does resource management
- - for hardware building-blocks in the SoC that can be used
- - to dynamically create networking hardware objects such as
- - network interfaces (NICs), crypto accelerator instances,
- - or L2 switches.
- + Driver to enable the bus infrastructure for the QorIQ DPAA2
- + architecture. The fsl-mc bus driver handles discovery of
- + DPAA2 objects (which are represented as Linux devices) and
- + binding objects to drivers.
-
- - Only enable this option when building the kernel for
- - Freescale QorQIQ LS2xxxx SoCs.
- +config FSL_MC_DPIO
- + tristate "QorIQ DPAA2 DPIO driver"
- + depends on FSL_MC_BUS
- + help
- + Driver for the DPAA2 DPIO object. A DPIO provides queue and
- + buffer management facilities for software to interact with
- + other DPAA2 objects. This driver does not expose the DPIO
- + objects individually, but groups them under a service layer
- + API.
-
- +config FSL_QBMAN_DEBUG
- + tristate "Freescale QBMAN Debug APIs"
- + depends on FSL_MC_DPIO
- + help
- + QBMan debug assistant APIs.
-
- +config FSL_MC_RESTOOL
- + tristate "Freescale Management Complex (MC) restool driver"
- + depends on FSL_MC_BUS
- + help
- + Driver that provides kernel support for the Freescale Management
- + Complex resource manager user-space tool.
- --- a/drivers/staging/fsl-mc/bus/Makefile
- +++ b/drivers/staging/fsl-mc/bus/Makefile
- @@ -17,4 +17,12 @@ mc-bus-driver-objs := fsl-mc-bus.o \
- fsl-mc-msi.o \
- irq-gic-v3-its-fsl-mc-msi.o \
- dpmcp.o \
- - dpbp.o
- + dpbp.o \
- + dpcon.o \
- + fsl-mc-iommu.o
- +
- +# MC DPIO driver
- +obj-$(CONFIG_FSL_MC_DPIO) += dpio/
- +
- +# MC restool kernel support
- +obj-$(CONFIG_FSL_MC_RESTOOL) += mc-restool.o
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpbp-cmd.h
- @@ -0,0 +1,80 @@
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef _FSL_DPBP_CMD_H
- +#define _FSL_DPBP_CMD_H
- +
- +/* DPBP Version */
- +#define DPBP_VER_MAJOR 3
- +#define DPBP_VER_MINOR 2
- +
- +/* Command versioning */
- +#define DPBP_CMD_BASE_VERSION 1
- +#define DPBP_CMD_ID_OFFSET 4
- +
- +#define DPBP_CMD(id) ((id << DPBP_CMD_ID_OFFSET) | DPBP_CMD_BASE_VERSION)
- +
- +/* Command IDs */
- +#define DPBP_CMDID_CLOSE DPBP_CMD(0x800)
- +#define DPBP_CMDID_OPEN DPBP_CMD(0x804)
- +#define DPBP_CMDID_GET_API_VERSION DPBP_CMD(0xa04)
- +
- +#define DPBP_CMDID_ENABLE DPBP_CMD(0x002)
- +#define DPBP_CMDID_DISABLE DPBP_CMD(0x003)
- +#define DPBP_CMDID_GET_ATTR DPBP_CMD(0x004)
- +#define DPBP_CMDID_RESET DPBP_CMD(0x005)
- +#define DPBP_CMDID_IS_ENABLED DPBP_CMD(0x006)
- +
- +struct dpbp_cmd_open {
- + __le32 dpbp_id;
- +};
- +
- +struct dpbp_cmd_destroy {
- + __le32 object_id;
- +};
- +
- +#define DPBP_ENABLE 0x1
- +
- +struct dpbp_rsp_is_enabled {
- + u8 enabled;
- +};
- +
- +struct dpbp_rsp_get_attributes {
- + /* response word 0 */
- + __le16 pad;
- + __le16 bpid;
- + __le32 id;
- + /* response word 1 */
- + __le16 version_major;
- + __le16 version_minor;
- +};
- +
- +#endif /* _FSL_DPBP_CMD_H */
- --- a/drivers/staging/fsl-mc/bus/dpbp.c
- +++ b/drivers/staging/fsl-mc/bus/dpbp.c
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2016 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -11,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -32,7 +32,8 @@
- #include "../include/mc-sys.h"
- #include "../include/mc-cmd.h"
- #include "../include/dpbp.h"
- -#include "../include/dpbp-cmd.h"
- +
- +#include "dpbp-cmd.h"
-
- /**
- * dpbp_open() - Open a control session for the specified object.
- @@ -105,74 +106,6 @@ int dpbp_close(struct fsl_mc_io *mc_io,
- EXPORT_SYMBOL(dpbp_close);
-
- /**
- - * dpbp_create() - Create the DPBP object.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @cfg: Configuration structure
- - * @token: Returned token; use in subsequent API calls
- - *
- - * Create the DPBP object, allocate required resources and
- - * perform required initialization.
- - *
- - * The object can be created either by declaring it in the
- - * DPL file, or by calling this function.
- - * This function returns a unique authentication token,
- - * associated with the specific object ID and the specific MC
- - * portal; this token must be used in all subsequent calls to
- - * this specific object. For objects that are created using the
- - * DPL file, call dpbp_open function to get an authentication
- - * token first.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_create(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - const struct dpbp_cfg *cfg,
- - u16 *token)
- -{
- - struct mc_command cmd = { 0 };
- - int err;
- -
- - (void)(cfg); /* unused */
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE,
- - cmd_flags, 0);
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - *token = mc_cmd_hdr_read_token(&cmd);
- -
- - return 0;
- -}
- -
- -/**
- - * dpbp_destroy() - Destroy the DPBP object and release all its resources.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - *
- - * Return: '0' on Success; error code otherwise.
- - */
- -int dpbp_destroy(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token)
- -{
- - struct mc_command cmd = { 0 };
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
- - cmd_flags, token);
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- * dpbp_enable() - Enable the DPBP.
- * @mc_io: Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- @@ -250,6 +183,7 @@ int dpbp_is_enabled(struct fsl_mc_io *mc
-
- return 0;
- }
- +EXPORT_SYMBOL(dpbp_is_enabled);
-
- /**
- * dpbp_reset() - Reset the DPBP, returns the object to initial state.
- @@ -272,310 +206,7 @@ int dpbp_reset(struct fsl_mc_io *mc_io,
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
- }
- -
- -/**
- - * dpbp_set_irq() - Set IRQ information for the DPBP to trigger an interrupt.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: Identifies the interrupt index to configure
- - * @irq_cfg: IRQ configuration
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_set_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - struct dpbp_irq_cfg *irq_cfg)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_set_irq *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_set_irq *)cmd.params;
- - cmd_params->irq_index = irq_index;
- - cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
- - cmd_params->irq_addr = cpu_to_le64(irq_cfg->addr);
- - cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dpbp_get_irq() - Get IRQ information from the DPBP.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: The interrupt index to configure
- - * @type: Interrupt type: 0 represents message interrupt
- - * type (both irq_addr and irq_val are valid)
- - * @irq_cfg: IRQ attributes
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_get_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - int *type,
- - struct dpbp_irq_cfg *irq_cfg)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_get_irq *cmd_params;
- - struct dpbp_rsp_get_irq *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_get_irq *)cmd.params;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpbp_rsp_get_irq *)cmd.params;
- - irq_cfg->val = le32_to_cpu(rsp_params->irq_val);
- - irq_cfg->addr = le64_to_cpu(rsp_params->irq_addr);
- - irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num);
- - *type = le32_to_cpu(rsp_params->type);
- -
- - return 0;
- -}
- -
- -/**
- - * dpbp_set_irq_enable() - Set overall interrupt state.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: The interrupt index to configure
- - * @en: Interrupt state - enable = 1, disable = 0
- - *
- - * Allows GPP software to control when interrupts are generated.
- - * Each interrupt can have up to 32 causes. The enable/disable control's the
- - * overall interrupt state. if the interrupt is disabled no causes will cause
- - * an interrupt.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_set_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 en)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_set_irq_enable *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_set_irq_enable *)cmd.params;
- - cmd_params->enable = en & DPBP_ENABLE;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dpbp_get_irq_enable() - Get overall interrupt state
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: The interrupt index to configure
- - * @en: Returned interrupt state - enable = 1, disable = 0
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_get_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 *en)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_get_irq_enable *cmd_params;
- - struct dpbp_rsp_get_irq_enable *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_ENABLE,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_get_irq_enable *)cmd.params;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpbp_rsp_get_irq_enable *)cmd.params;
- - *en = rsp_params->enabled & DPBP_ENABLE;
- - return 0;
- -}
- -
- -/**
- - * dpbp_set_irq_mask() - Set interrupt mask.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: The interrupt index to configure
- - * @mask: Event mask to trigger interrupt;
- - * each bit:
- - * 0 = ignore event
- - * 1 = consider event for asserting IRQ
- - *
- - * Every interrupt can have up to 32 causes and the interrupt model supports
- - * masking/unmasking each cause independently
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_set_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 mask)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_set_irq_mask *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_set_irq_mask *)cmd.params;
- - cmd_params->mask = cpu_to_le32(mask);
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dpbp_get_irq_mask() - Get interrupt mask.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: The interrupt index to configure
- - * @mask: Returned event mask to trigger interrupt
- - *
- - * Every interrupt can have up to 32 causes and the interrupt model supports
- - * masking/unmasking each cause independently
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_get_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *mask)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_get_irq_mask *cmd_params;
- - struct dpbp_rsp_get_irq_mask *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_MASK,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_get_irq_mask *)cmd.params;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpbp_rsp_get_irq_mask *)cmd.params;
- - *mask = le32_to_cpu(rsp_params->mask);
- -
- - return 0;
- -}
- -
- -/**
- - * dpbp_get_irq_status() - Get the current status of any pending interrupts.
- - *
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: The interrupt index to configure
- - * @status: Returned interrupts status - one bit per cause:
- - * 0 = no interrupt pending
- - * 1 = interrupt pending
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_get_irq_status(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *status)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_get_irq_status *cmd_params;
- - struct dpbp_rsp_get_irq_status *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_get_irq_status *)cmd.params;
- - cmd_params->status = cpu_to_le32(*status);
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpbp_rsp_get_irq_status *)cmd.params;
- - *status = le32_to_cpu(rsp_params->status);
- -
- - return 0;
- -}
- -
- -/**
- - * dpbp_clear_irq_status() - Clear a pending interrupt's status
- - *
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @irq_index: The interrupt index to configure
- - * @status: Bits to clear (W1C) - one bit per cause:
- - * 0 = don't change
- - * 1 = clear status bit
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_clear_irq_status(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 status)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_cmd_clear_irq_status *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_clear_irq_status *)cmd.params;
- - cmd_params->status = cpu_to_le32(status);
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- +EXPORT_SYMBOL(dpbp_reset);
-
- /**
- * dpbp_get_attributes - Retrieve DPBP attributes.
- @@ -609,83 +240,40 @@ int dpbp_get_attributes(struct fsl_mc_io
- rsp_params = (struct dpbp_rsp_get_attributes *)cmd.params;
- attr->bpid = le16_to_cpu(rsp_params->bpid);
- attr->id = le32_to_cpu(rsp_params->id);
- - attr->version.major = le16_to_cpu(rsp_params->version_major);
- - attr->version.minor = le16_to_cpu(rsp_params->version_minor);
-
- return 0;
- }
- EXPORT_SYMBOL(dpbp_get_attributes);
-
- /**
- - * dpbp_set_notifications() - Set notifications towards software
- - * @mc_io: Pointer to MC portal's I/O object
- + * dpbp_get_api_version - Get Data Path Buffer Pool API version
- + * @mc_io: Pointer to Mc portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @cfg: notifications configuration
- + * @major_ver: Major version of Buffer Pool API
- + * @minor_ver: Minor version of Buffer Pool API
- *
- * Return: '0' on Success; Error code otherwise.
- */
- -int dpbp_set_notifications(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dpbp_notification_cfg *cfg)
- +int dpbp_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver)
- {
- struct mc_command cmd = { 0 };
- - struct dpbp_cmd_set_notifications *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_NOTIFICATIONS,
- - cmd_flags, token);
- - cmd_params = (struct dpbp_cmd_set_notifications *)cmd.params;
- - cmd_params->depletion_entry = cpu_to_le32(cfg->depletion_entry);
- - cmd_params->depletion_exit = cpu_to_le32(cfg->depletion_exit);
- - cmd_params->surplus_entry = cpu_to_le32(cfg->surplus_entry);
- - cmd_params->surplus_exit = cpu_to_le32(cfg->surplus_exit);
- - cmd_params->options = cpu_to_le16(cfg->options);
- - cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
- - cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dpbp_get_notifications() - Get the notifications configuration
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPBP object
- - * @cfg: notifications configuration
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpbp_get_notifications(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dpbp_notification_cfg *cfg)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpbp_rsp_get_notifications *rsp_params;
- int err;
-
- /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_NOTIFICATIONS,
- - cmd_flags,
- - token);
- + cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_API_VERSION,
- + cmd_flags, 0);
-
- - /* send command to mc*/
- + /* send command to mc */
- err = mc_send_command(mc_io, &cmd);
- if (err)
- return err;
-
- /* retrieve response parameters */
- - rsp_params = (struct dpbp_rsp_get_notifications *)cmd.params;
- - cfg->depletion_entry = le32_to_cpu(rsp_params->depletion_entry);
- - cfg->depletion_exit = le32_to_cpu(rsp_params->depletion_exit);
- - cfg->surplus_entry = le32_to_cpu(rsp_params->surplus_entry);
- - cfg->surplus_exit = le32_to_cpu(rsp_params->surplus_exit);
- - cfg->options = le16_to_cpu(rsp_params->options);
- - cfg->message_ctx = le64_to_cpu(rsp_params->message_ctx);
- - cfg->message_iova = le64_to_cpu(rsp_params->message_iova);
- + mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
-
- return 0;
- }
- +EXPORT_SYMBOL(dpbp_get_api_version);
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpcon-cmd.h
- @@ -0,0 +1,85 @@
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef _FSL_DPCON_CMD_H
- +#define _FSL_DPCON_CMD_H
- +
- +/* DPCON Version */
- +#define DPCON_VER_MAJOR 3
- +#define DPCON_VER_MINOR 2
- +
- +/* Command versioning */
- +#define DPCON_CMD_BASE_VERSION 1
- +#define DPCON_CMD_ID_OFFSET 4
- +
- +#define DPCON_CMD(id) (((id) << DPCON_CMD_ID_OFFSET) | DPCON_CMD_BASE_VERSION)
- +
- +/* Command IDs */
- +#define DPCON_CMDID_CLOSE DPCON_CMD(0x800)
- +#define DPCON_CMDID_OPEN DPCON_CMD(0x808)
- +#define DPCON_CMDID_GET_API_VERSION DPCON_CMD(0xa08)
- +
- +#define DPCON_CMDID_ENABLE DPCON_CMD(0x002)
- +#define DPCON_CMDID_DISABLE DPCON_CMD(0x003)
- +#define DPCON_CMDID_GET_ATTR DPCON_CMD(0x004)
- +#define DPCON_CMDID_RESET DPCON_CMD(0x005)
- +#define DPCON_CMDID_IS_ENABLED DPCON_CMD(0x006)
- +
- +#define DPCON_CMDID_SET_NOTIFICATION DPCON_CMD(0x100)
- +
- +struct dpcon_cmd_open {
- + __le32 dpcon_id;
- +};
- +
- +#define DPCON_ENABLE 1
- +
- +struct dpcon_rsp_is_enabled {
- + u8 enabled;
- +};
- +
- +struct dpcon_rsp_get_attr {
- + /* response word 0 */
- + __le32 id;
- + __le16 qbman_ch_id;
- + u8 num_priorities;
- + u8 pad;
- +};
- +
- +struct dpcon_cmd_set_notification {
- + /* cmd word 0 */
- + __le32 dpio_id;
- + u8 priority;
- + u8 pad[3];
- + /* cmd word 1 */
- + __le64 user_ctx;
- +};
- +
- +#endif /* _FSL_DPCON_CMD_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpcon.c
- @@ -0,0 +1,317 @@
- +/* Copyright 2013-2016 Freescale Semiconductor Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#include "../include/mc-sys.h"
- +#include "../include/mc-cmd.h"
- +#include "../include/dpcon.h"
- +
- +#include "dpcon-cmd.h"
- +
- +/**
- + * dpcon_open() - Open a control session for the specified object
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @dpcon_id: DPCON unique ID
- + * @token: Returned token; use in subsequent API calls
- + *
- + * This function can be used to open a control session for an
- + * already created object; an object may have been declared in
- + * the DPL or by calling the dpcon_create() function.
- + * This function returns a unique authentication token,
- + * associated with the specific object ID and the specific MC
- + * portal; this token must be used in all subsequent commands for
- + * this specific object.
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpcon_open(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + int dpcon_id,
- + u16 *token)
- +{
- + struct mc_command cmd = { 0 };
- + struct dpcon_cmd_open *dpcon_cmd;
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_OPEN,
- + cmd_flags,
- + 0);
- + dpcon_cmd = (struct dpcon_cmd_open *)cmd.params;
- + dpcon_cmd->dpcon_id = cpu_to_le32(dpcon_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + *token = mc_cmd_hdr_read_token(&cmd);
- +
- + return 0;
- +}
- +EXPORT_SYMBOL(dpcon_open);
- +
- +/**
- + * dpcon_close() - Close the control session of the object
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPCON object
- + *
- + * After this function is called, no further operations are
- + * allowed on the object without opening a new control session.
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpcon_close(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_CLOSE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +EXPORT_SYMBOL(dpcon_close);
- +
- +/**
- + * dpcon_enable() - Enable the DPCON
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPCON object
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpcon_enable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_ENABLE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +EXPORT_SYMBOL(dpcon_enable);
- +
- +/**
- + * dpcon_disable() - Disable the DPCON
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPCON object
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpcon_disable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_DISABLE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +EXPORT_SYMBOL(dpcon_disable);
- +
- +/**
- + * dpcon_is_enabled() - Check if the DPCON is enabled.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPCON object
- + * @en: Returns '1' if object is enabled; '0' otherwise
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpcon_is_enabled(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + int *en)
- +{
- + struct mc_command cmd = { 0 };
- + struct dpcon_rsp_is_enabled *dpcon_rsp;
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_IS_ENABLED,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + dpcon_rsp = (struct dpcon_rsp_is_enabled *)cmd.params;
- + *en = dpcon_rsp->enabled & DPCON_ENABLE;
- +
- + return 0;
- +}
- +EXPORT_SYMBOL(dpcon_is_enabled);
- +
- +/**
- + * dpcon_reset() - Reset the DPCON, returns the object to initial state.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPCON object
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpcon_reset(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_RESET,
- + cmd_flags, token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +EXPORT_SYMBOL(dpcon_reset);
- +
- +/**
- + * dpcon_get_attributes() - Retrieve DPCON attributes.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPCON object
- + * @attr: Object's attributes
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpcon_get_attributes(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dpcon_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + struct dpcon_rsp_get_attr *dpcon_rsp;
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_ATTR,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + dpcon_rsp = (struct dpcon_rsp_get_attr *)cmd.params;
- + attr->id = le32_to_cpu(dpcon_rsp->id);
- + attr->qbman_ch_id = le16_to_cpu(dpcon_rsp->qbman_ch_id);
- + attr->num_priorities = dpcon_rsp->num_priorities;
- +
- + return 0;
- +}
- +EXPORT_SYMBOL(dpcon_get_attributes);
- +
- +/**
- + * dpcon_set_notification() - Set DPCON notification destination
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPCON object
- + * @cfg: Notification parameters
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpcon_set_notification(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dpcon_notification_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + struct dpcon_cmd_set_notification *dpcon_cmd;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_SET_NOTIFICATION,
- + cmd_flags,
- + token);
- + dpcon_cmd = (struct dpcon_cmd_set_notification *)cmd.params;
- + dpcon_cmd->dpio_id = cpu_to_le32(cfg->dpio_id);
- + dpcon_cmd->priority = cfg->priority;
- + dpcon_cmd->user_ctx = cpu_to_le64(cfg->user_ctx);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +EXPORT_SYMBOL(dpcon_set_notification);
- +
- +/**
- + * dpcon_get_api_version - Get Data Path Concentrator API version
- + * @mc_io: Pointer to MC portal's DPCON object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @major_ver: Major version of DPCON API
- + * @minor_ver: Minor version of DPCON API
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpcon_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_API_VERSION,
- + cmd_flags, 0);
- +
- + /* send command to mc */
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
- +
- + return 0;
- +}
- +EXPORT_SYMBOL(dpcon_get_api_version);
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/Makefile
- @@ -0,0 +1,11 @@
- +#
- +# QorIQ DPAA2 DPIO driver
- +#
- +
- +subdir-ccflags-y := -Werror
- +
- +obj-$(CONFIG_FSL_MC_DPIO) += fsl-mc-dpio.o
- +
- +fsl-mc-dpio-objs := dpio.o qbman-portal.o dpio-service.o dpio-driver.o
- +
- +obj-$(CONFIG_FSL_QBMAN_DEBUG) += qbman_debug.o
- --- a/drivers/staging/fsl-mc/include/dpcon-cmd.h
- +++ /dev/null
- @@ -1,62 +0,0 @@
- -/* Copyright 2013-2015 Freescale Semiconductor Inc.
- - *
- - * Redistribution and use in source and binary forms, with or without
- - * modification, are permitted provided that the following conditions are met:
- - * * Redistributions of source code must retain the above copyright
- - * notice, this list of conditions and the following disclaimer.
- - * * Redistributions in binary form must reproduce the above copyright
- - * notice, this list of conditions and the following disclaimer in the
- - * documentation and/or other materials provided with the distribution.
- - * * Neither the name of the above-listed copyright holders nor the
- - * names of any contributors may be used to endorse or promote products
- - * derived from this software without specific prior written permission.
- - *
- - *
- - * ALTERNATIVELY, this software may be distributed under the terms of the
- - * GNU General Public License ("GPL") as published by the Free Software
- - * Foundation, either version 2 of that License or (at your option) any
- - * later version.
- - *
- - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- - * POSSIBILITY OF SUCH DAMAGE.
- - */
- -#ifndef _FSL_DPCON_CMD_H
- -#define _FSL_DPCON_CMD_H
- -
- -/* DPCON Version */
- -#define DPCON_VER_MAJOR 2
- -#define DPCON_VER_MINOR 1
- -
- -/* Command IDs */
- -#define DPCON_CMDID_CLOSE 0x800
- -#define DPCON_CMDID_OPEN 0x808
- -#define DPCON_CMDID_CREATE 0x908
- -#define DPCON_CMDID_DESTROY 0x900
- -
- -#define DPCON_CMDID_ENABLE 0x002
- -#define DPCON_CMDID_DISABLE 0x003
- -#define DPCON_CMDID_GET_ATTR 0x004
- -#define DPCON_CMDID_RESET 0x005
- -#define DPCON_CMDID_IS_ENABLED 0x006
- -
- -#define DPCON_CMDID_SET_IRQ 0x010
- -#define DPCON_CMDID_GET_IRQ 0x011
- -#define DPCON_CMDID_SET_IRQ_ENABLE 0x012
- -#define DPCON_CMDID_GET_IRQ_ENABLE 0x013
- -#define DPCON_CMDID_SET_IRQ_MASK 0x014
- -#define DPCON_CMDID_GET_IRQ_MASK 0x015
- -#define DPCON_CMDID_GET_IRQ_STATUS 0x016
- -#define DPCON_CMDID_CLEAR_IRQ_STATUS 0x017
- -
- -#define DPCON_CMDID_SET_NOTIFICATION 0x100
- -
- -#endif /* _FSL_DPCON_CMD_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h
- @@ -0,0 +1,75 @@
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef _FSL_DPIO_CMD_H
- +#define _FSL_DPIO_CMD_H
- +
- +/* DPIO Version */
- +#define DPIO_VER_MAJOR 4
- +#define DPIO_VER_MINOR 2
- +
- +/* Command Versioning */
- +
- +#define DPIO_CMD_ID_OFFSET 4
- +#define DPIO_CMD_BASE_VERSION 1
- +
- +#define DPIO_CMD(id) (((id) << DPIO_CMD_ID_OFFSET) | DPIO_CMD_BASE_VERSION)
- +
- +/* Command IDs */
- +#define DPIO_CMDID_CLOSE DPIO_CMD(0x800)
- +#define DPIO_CMDID_OPEN DPIO_CMD(0x803)
- +#define DPIO_CMDID_GET_API_VERSION DPIO_CMD(0xa03)
- +#define DPIO_CMDID_ENABLE DPIO_CMD(0x002)
- +#define DPIO_CMDID_DISABLE DPIO_CMD(0x003)
- +#define DPIO_CMDID_GET_ATTR DPIO_CMD(0x004)
- +
- +struct dpio_cmd_open {
- + __le32 dpio_id;
- +};
- +
- +#define DPIO_CHANNEL_MODE_MASK 0x3
- +
- +struct dpio_rsp_get_attr {
- + /* cmd word 0 */
- + __le32 id;
- + __le16 qbman_portal_id;
- + u8 num_priorities;
- + u8 channel_mode;
- + /* cmd word 1 */
- + __le64 qbman_portal_ce_addr;
- + /* cmd word 2 */
- + __le64 qbman_portal_ci_addr;
- + /* cmd word 3 */
- + __le32 qbman_version;
- +};
- +
- +#endif /* _FSL_DPIO_CMD_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/dpio-driver.c
- @@ -0,0 +1,296 @@
- +/*
- + * Copyright 2014-2016 Freescale Semiconductor Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +#include <linux/types.h>
- +#include <linux/init.h>
- +#include <linux/module.h>
- +#include <linux/platform_device.h>
- +#include <linux/interrupt.h>
- +#include <linux/msi.h>
- +#include <linux/dma-mapping.h>
- +#include <linux/delay.h>
- +
- +#include "../../include/mc.h"
- +#include "../../include/dpaa2-io.h"
- +
- +#include "qbman-portal.h"
- +#include "dpio.h"
- +#include "dpio-cmd.h"
- +
- +MODULE_LICENSE("Dual BSD/GPL");
- +MODULE_AUTHOR("Freescale Semiconductor, Inc");
- +MODULE_DESCRIPTION("DPIO Driver");
- +
- +struct dpio_priv {
- + struct dpaa2_io *io;
- +};
- +
- +static irqreturn_t dpio_irq_handler(int irq_num, void *arg)
- +{
- + struct device *dev = (struct device *)arg;
- + struct dpio_priv *priv = dev_get_drvdata(dev);
- +
- + return dpaa2_io_irq(priv->io);
- +}
- +
- +static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev)
- +{
- + struct fsl_mc_device_irq *irq;
- +
- + irq = dpio_dev->irqs[0];
- +
- + /* clear the affinity hint */
- + irq_set_affinity_hint(irq->msi_desc->irq, NULL);
- +}
- +
- +static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
- +{
- + struct dpio_priv *priv;
- + int error;
- + struct fsl_mc_device_irq *irq;
- + cpumask_t mask;
- +
- + priv = dev_get_drvdata(&dpio_dev->dev);
- +
- + irq = dpio_dev->irqs[0];
- + error = devm_request_irq(&dpio_dev->dev,
- + irq->msi_desc->irq,
- + dpio_irq_handler,
- + 0,
- + dev_name(&dpio_dev->dev),
- + &dpio_dev->dev);
- + if (error < 0) {
- + dev_err(&dpio_dev->dev,
- + "devm_request_irq() failed: %d\n",
- + error);
- + return error;
- + }
- +
- + /* set the affinity hint */
- + cpumask_clear(&mask);
- + cpumask_set_cpu(cpu, &mask);
- + if (irq_set_affinity_hint(irq->msi_desc->irq, &mask))
- + dev_err(&dpio_dev->dev,
- + "irq_set_affinity failed irq %d cpu %d\n",
- + irq->msi_desc->irq, cpu);
- +
- + return 0;
- +}
- +
- +static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev)
- +{
- + struct dpio_attr dpio_attrs;
- + struct dpaa2_io_desc desc;
- + struct dpio_priv *priv;
- + int err = -ENOMEM;
- + struct device *dev = &dpio_dev->dev;
- + static int next_cpu = -1;
- +
- + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- + if (!priv)
- + goto err_priv_alloc;
- +
- + dev_set_drvdata(dev, priv);
- +
- + err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io);
- + if (err) {
- + dev_dbg(dev, "MC portal allocation failed\n");
- + err = -EPROBE_DEFER;
- + goto err_mcportal;
- + }
- +
- + err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
- + &dpio_dev->mc_handle);
- + if (err) {
- + dev_err(dev, "dpio_open() failed\n");
- + goto err_open;
- + }
- +
- + err = dpio_get_attributes(dpio_dev->mc_io, 0, dpio_dev->mc_handle,
- + &dpio_attrs);
- + if (err) {
- + dev_err(dev, "dpio_get_attributes() failed %d\n", err);
- + goto err_get_attr;
- + }
- + desc.qman_version = dpio_attrs.qbman_version;
- +
- + err = dpio_enable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
- + if (err) {
- + dev_err(dev, "dpio_enable() failed %d\n", err);
- + goto err_get_attr;
- + }
- +
- + /* initialize DPIO descriptor */
- + desc.receives_notifications = dpio_attrs.num_priorities ? 1 : 0;
- + desc.has_8prio = dpio_attrs.num_priorities == 8 ? 1 : 0;
- + desc.dpio_id = dpio_dev->obj_desc.id;
- +
- + /* get the cpu to use for the affinity hint */
- + if (next_cpu == -1)
- + next_cpu = cpumask_first(cpu_online_mask);
- + else
- + next_cpu = cpumask_next(next_cpu, cpu_online_mask);
- +
- + if (!cpu_possible(next_cpu)) {
- + dev_err(dev, "probe failed. Number of DPIOs exceeds NR_CPUS.\n");
- + err = -ERANGE;
- + goto err_allocate_irqs;
- + }
- + desc.cpu = next_cpu;
- +
- + /*
- + * Set the CENA regs to be the cache enabled area of the portal to
- + * achieve the best performance.
- + */
- + desc.regs_cena = ioremap_cache_ns(dpio_dev->regions[0].start,
- + resource_size(&dpio_dev->regions[0]));
- + desc.regs_cinh = ioremap(dpio_dev->regions[1].start,
- + resource_size(&dpio_dev->regions[1]));
- +
- + err = fsl_mc_allocate_irqs(dpio_dev);
- + if (err) {
- + dev_err(dev, "fsl_mc_allocate_irqs failed. err=%d\n", err);
- + goto err_allocate_irqs;
- + }
- +
- + err = register_dpio_irq_handlers(dpio_dev, desc.cpu);
- + if (err)
- + goto err_register_dpio_irq;
- +
- + priv->io = dpaa2_io_create(&desc);
- + if (!priv->io) {
- + dev_err(dev, "dpaa2_io_create failed\n");
- + goto err_dpaa2_io_create;
- + }
- +
- + dev_info(dev, "probed\n");
- + dev_dbg(dev, " receives_notifications = %d\n",
- + desc.receives_notifications);
- + dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
- + fsl_mc_portal_free(dpio_dev->mc_io);
- +
- + return 0;
- +
- +err_dpaa2_io_create:
- + unregister_dpio_irq_handlers(dpio_dev);
- +err_register_dpio_irq:
- + fsl_mc_free_irqs(dpio_dev);
- +err_allocate_irqs:
- + dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
- +err_get_attr:
- + dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
- +err_open:
- + fsl_mc_portal_free(dpio_dev->mc_io);
- +err_mcportal:
- + dev_set_drvdata(dev, NULL);
- +err_priv_alloc:
- + return err;
- +}
- +
- +/* Tear down interrupts for a given DPIO object */
- +static void dpio_teardown_irqs(struct fsl_mc_device *dpio_dev)
- +{
- + unregister_dpio_irq_handlers(dpio_dev);
- + fsl_mc_free_irqs(dpio_dev);
- +}
- +
- +static int dpaa2_dpio_remove(struct fsl_mc_device *dpio_dev)
- +{
- + struct device *dev;
- + struct dpio_priv *priv;
- + int err;
- +
- + dev = &dpio_dev->dev;
- + priv = dev_get_drvdata(dev);
- +
- + dpaa2_io_down(priv->io);
- +
- + dpio_teardown_irqs(dpio_dev);
- +
- + err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io);
- + if (err) {
- + dev_err(dev, "MC portal allocation failed\n");
- + goto err_mcportal;
- + }
- +
- + err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
- + &dpio_dev->mc_handle);
- + if (err) {
- + dev_err(dev, "dpio_open() failed\n");
- + goto err_open;
- + }
- +
- + dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
- +
- + dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
- +
- + fsl_mc_portal_free(dpio_dev->mc_io);
- +
- + dev_set_drvdata(dev, NULL);
- +
- + return 0;
- +
- +err_open:
- + fsl_mc_portal_free(dpio_dev->mc_io);
- +err_mcportal:
- + return err;
- +}
- +
- +static const struct fsl_mc_device_id dpaa2_dpio_match_id_table[] = {
- + {
- + .vendor = FSL_MC_VENDOR_FREESCALE,
- + .obj_type = "dpio",
- + },
- + { .vendor = 0x0 }
- +};
- +
- +static struct fsl_mc_driver dpaa2_dpio_driver = {
- + .driver = {
- + .name = KBUILD_MODNAME,
- + .owner = THIS_MODULE,
- + },
- + .probe = dpaa2_dpio_probe,
- + .remove = dpaa2_dpio_remove,
- + .match_id_table = dpaa2_dpio_match_id_table
- +};
- +
- +static int dpio_driver_init(void)
- +{
- + return fsl_mc_driver_register(&dpaa2_dpio_driver);
- +}
- +
- +static void dpio_driver_exit(void)
- +{
- + fsl_mc_driver_unregister(&dpaa2_dpio_driver);
- +}
- +module_init(dpio_driver_init);
- +module_exit(dpio_driver_exit);
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/dpio-service.c
- @@ -0,0 +1,693 @@
- +/*
- + * Copyright 2014-2016 Freescale Semiconductor Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +#include <linux/types.h>
- +#include "../../include/mc.h"
- +#include "../../include/dpaa2-io.h"
- +#include <linux/init.h>
- +#include <linux/module.h>
- +#include <linux/platform_device.h>
- +#include <linux/interrupt.h>
- +#include <linux/dma-mapping.h>
- +#include <linux/slab.h>
- +
- +#include "dpio.h"
- +#include "qbman-portal.h"
- +#include "qbman_debug.h"
- +
- +struct dpaa2_io {
- + atomic_t refs;
- + struct dpaa2_io_desc dpio_desc;
- + struct qbman_swp_desc swp_desc;
- + struct qbman_swp *swp;
- + struct list_head node;
- + /* protect against multiple management commands */
- + spinlock_t lock_mgmt_cmd;
- + /* protect notifications list */
- + spinlock_t lock_notifications;
- + struct list_head notifications;
- +};
- +
- +struct dpaa2_io_store {
- + unsigned int max;
- + dma_addr_t paddr;
- + struct dpaa2_dq *vaddr;
- + void *alloced_addr; /* unaligned value from kmalloc() */
- + unsigned int idx; /* position of the next-to-be-returned entry */
- + struct qbman_swp *swp; /* portal used to issue VDQCR */
- + struct device *dev; /* device used for DMA mapping */
- +};
- +
- +/* keep a per cpu array of DPIOs for fast access */
- +static struct dpaa2_io *dpio_by_cpu[NR_CPUS];
- +static struct list_head dpio_list = LIST_HEAD_INIT(dpio_list);
- +static DEFINE_SPINLOCK(dpio_list_lock);
- +
- +static inline struct dpaa2_io *service_select_by_cpu(struct dpaa2_io *d,
- + int cpu)
- +{
- + if (d)
- + return d;
- +
- + if (unlikely(cpu >= (int)num_possible_cpus()))
- + return NULL;
- +
- + /*
- + * If cpu == -1, choose the current cpu, with no guarantees about
- + * potentially being migrated away.
- + */
- + if (cpu < 0)
- + cpu = smp_processor_id();
- +
- + /* If a specific cpu was requested, pick it up immediately */
- + return dpio_by_cpu[cpu];
- +}
- +
- +static inline struct dpaa2_io *service_select(struct dpaa2_io *d)
- +{
- + if (d)
- + return d;
- +
- + d = service_select_by_cpu(d, -1);
- + if (d)
- + return d;
- +
- + spin_lock(&dpio_list_lock);
- + d = list_entry(dpio_list.next, struct dpaa2_io, node);
- + list_del(&d->node);
- + list_add_tail(&d->node, &dpio_list);
- + spin_unlock(&dpio_list_lock);
- +
- + return d;
- +}
- +
- +/**
- + * dpaa2_io_create() - create a dpaa2_io object.
- + * @desc: the dpaa2_io descriptor
- + *
- + * Activates a "struct dpaa2_io" corresponding to the given config of an actual
- + * DPIO object.
- + *
- + * Return a valid dpaa2_io object for success, or NULL for failure.
- + */
- +struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc)
- +{
- + struct dpaa2_io *obj = kmalloc(sizeof(*obj), GFP_KERNEL);
- +
- + if (!obj)
- + return NULL;
- +
- + /* check if CPU is out of range (-1 means any cpu) */
- + if (desc->cpu >= (int)num_possible_cpus()) {
- + kfree(obj);
- + return NULL;
- + }
- +
- + atomic_set(&obj->refs, 1);
- + obj->dpio_desc = *desc;
- + obj->swp_desc.cena_bar = obj->dpio_desc.regs_cena;
- + obj->swp_desc.cinh_bar = obj->dpio_desc.regs_cinh;
- + obj->swp_desc.qman_version = obj->dpio_desc.qman_version;
- + obj->swp = qbman_swp_init(&obj->swp_desc);
- +
- + if (!obj->swp) {
- + kfree(obj);
- + return NULL;
- + }
- +
- + INIT_LIST_HEAD(&obj->node);
- + spin_lock_init(&obj->lock_mgmt_cmd);
- + spin_lock_init(&obj->lock_notifications);
- + INIT_LIST_HEAD(&obj->notifications);
- +
- + /* For now only enable DQRR interrupts */
- + qbman_swp_interrupt_set_trigger(obj->swp,
- + QBMAN_SWP_INTERRUPT_DQRI);
- + qbman_swp_interrupt_clear_status(obj->swp, 0xffffffff);
- + if (obj->dpio_desc.receives_notifications)
- + qbman_swp_push_set(obj->swp, 0, 1);
- +
- + spin_lock(&dpio_list_lock);
- + list_add_tail(&obj->node, &dpio_list);
- + if (desc->cpu >= 0 && !dpio_by_cpu[desc->cpu])
- + dpio_by_cpu[desc->cpu] = obj;
- + spin_unlock(&dpio_list_lock);
- +
- + return obj;
- +}
- +EXPORT_SYMBOL(dpaa2_io_create);
- +
- +/**
- + * dpaa2_io_down() - release the dpaa2_io object.
- + * @d: the dpaa2_io object to be released.
- + *
- + * The "struct dpaa2_io" type can represent an individual DPIO object (as
- + * described by "struct dpaa2_io_desc") or an instance of a "DPIO service",
- + * which can be used to group/encapsulate multiple DPIO objects. In all cases,
- + * each handle obtained should be released using this function.
- + */
- +void dpaa2_io_down(struct dpaa2_io *d)
- +{
- + if (!atomic_dec_and_test(&d->refs))
- + return;
- + kfree(d);
- +}
- +EXPORT_SYMBOL(dpaa2_io_down);
- +
- +#define DPAA_POLL_MAX 32
- +
- +/**
- + * dpaa2_io_irq() - ISR for DPIO interrupts
- + *
- + * @obj: the given DPIO object.
- + *
- + * Return IRQ_HANDLED for success or IRQ_NONE if there
- + * were no pending interrupts.
- + */
- +irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj)
- +{
- + const struct dpaa2_dq *dq;
- + int max = 0;
- + struct qbman_swp *swp;
- + u32 status;
- +
- + swp = obj->swp;
- + status = qbman_swp_interrupt_read_status(swp);
- + if (!status)
- + return IRQ_NONE;
- +
- + dq = qbman_swp_dqrr_next(swp);
- + while (dq) {
- + if (qbman_result_is_SCN(dq)) {
- + struct dpaa2_io_notification_ctx *ctx;
- + u64 q64;
- +
- + q64 = qbman_result_SCN_ctx(dq);
- + ctx = (void *)q64;
- + ctx->cb(ctx);
- + } else {
- + pr_crit("fsl-mc-dpio: Unrecognised/ignored DQRR entry\n");
- + }
- + qbman_swp_dqrr_consume(swp, dq);
- + ++max;
- + if (max > DPAA_POLL_MAX)
- + goto done;
- + dq = qbman_swp_dqrr_next(swp);
- + }
- +done:
- + qbman_swp_interrupt_clear_status(swp, status);
- + qbman_swp_interrupt_set_inhibit(swp, 0);
- + return IRQ_HANDLED;
- +}
- +EXPORT_SYMBOL(dpaa2_io_irq);
- +
- +/**
- + * dpaa2_io_service_register() - Prepare for servicing of FQDAN or CDAN
- + * notifications on the given DPIO service.
- + * @d: the given DPIO service.
- + * @ctx: the notification context.
- + *
- + * The caller should make the MC command to attach a DPAA2 object to
- + * a DPIO after this function completes successfully. In that way:
- + * (a) The DPIO service is "ready" to handle a notification arrival
- + * (which might happen before the "attach" command to MC has
- + * returned control of execution back to the caller)
- + * (b) The DPIO service can provide back to the caller the 'dpio_id' and
- + * 'qman64' parameters that it should pass along in the MC command
- + * in order for the object to be configured to produce the right
- + * notification fields to the DPIO service.
- + *
- + * Return 0 for success, or -ENODEV for failure.
- + */
- +int dpaa2_io_service_register(struct dpaa2_io *d,
- + struct dpaa2_io_notification_ctx *ctx)
- +{
- + unsigned long irqflags;
- +
- + d = service_select_by_cpu(d, ctx->desired_cpu);
- + if (!d)
- + return -ENODEV;
- +
- + ctx->dpio_id = d->dpio_desc.dpio_id;
- + ctx->qman64 = (u64)ctx;
- + ctx->dpio_private = d;
- + spin_lock_irqsave(&d->lock_notifications, irqflags);
- + list_add(&ctx->node, &d->notifications);
- + spin_unlock_irqrestore(&d->lock_notifications, irqflags);
- +
- + /* Enable the generation of CDAN notifications */
- + if (ctx->is_cdan)
- + qbman_swp_CDAN_set_context_enable(d->swp,
- + (u16)ctx->id,
- + ctx->qman64);
- + return 0;
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_register);
- +
- +/**
- + * dpaa2_io_service_deregister - The opposite of 'register'.
- + * @service: the given DPIO service.
- + * @ctx: the notification context.
- + *
- + * This function should be called only after sending the MC command to
- + * to detach the notification-producing device from the DPIO.
- + */
- +void dpaa2_io_service_deregister(struct dpaa2_io *service,
- + struct dpaa2_io_notification_ctx *ctx)
- +{
- + struct dpaa2_io *d = ctx->dpio_private;
- + unsigned long irqflags;
- +
- + if (ctx->is_cdan)
- + qbman_swp_CDAN_disable(d->swp, (u16)ctx->id);
- +
- + spin_lock_irqsave(&d->lock_notifications, irqflags);
- + list_del(&ctx->node);
- + spin_unlock_irqrestore(&d->lock_notifications, irqflags);
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_deregister);
- +
- +/**
- + * dpaa2_io_service_rearm() - Rearm the notification for the given DPIO service.
- + * @d: the given DPIO service.
- + * @ctx: the notification context.
- + *
- + * Once a FQDAN/CDAN has been produced, the corresponding FQ/channel is
- + * considered "disarmed". Ie. the user can issue pull dequeue operations on that
- + * traffic source for as long as it likes. Eventually it may wish to "rearm"
- + * that source to allow it to produce another FQDAN/CDAN, that's what this
- + * function achieves.
- + *
- + * Return 0 for success.
- + */
- +int dpaa2_io_service_rearm(struct dpaa2_io *d,
- + struct dpaa2_io_notification_ctx *ctx)
- +{
- + unsigned long irqflags;
- + int err;
- +
- + d = service_select_by_cpu(d, ctx->desired_cpu);
- + if (!unlikely(d))
- + return -ENODEV;
- +
- + spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
- + if (ctx->is_cdan)
- + err = qbman_swp_CDAN_enable(d->swp, (u16)ctx->id);
- + else
- + err = qbman_swp_fq_schedule(d->swp, ctx->id);
- + spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
- +
- + return err;
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_rearm);
- +
- +/**
- + * dpaa2_io_service_pull_fq() - pull dequeue functions from a fq.
- + * @d: the given DPIO service.
- + * @fqid: the given frame queue id.
- + * @s: the dpaa2_io_store object for the result.
- + *
- + * Return 0 for success, or error code for failure.
- + */
- +int dpaa2_io_service_pull_fq(struct dpaa2_io *d, u32 fqid,
- + struct dpaa2_io_store *s)
- +{
- + struct qbman_pull_desc pd;
- + int err;
- +
- + qbman_pull_desc_clear(&pd);
- + qbman_pull_desc_set_storage(&pd, s->vaddr, s->paddr, 1);
- + qbman_pull_desc_set_numframes(&pd, (u8)s->max);
- + qbman_pull_desc_set_fq(&pd, fqid);
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- + s->swp = d->swp;
- + err = qbman_swp_pull(d->swp, &pd);
- + if (err)
- + s->swp = NULL;
- +
- + return err;
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_pull_fq);
- +
- +/**
- + * dpaa2_io_service_pull_channel() - pull dequeue functions from a channel.
- + * @d: the given DPIO service.
- + * @channelid: the given channel id.
- + * @s: the dpaa2_io_store object for the result.
- + *
- + * Return 0 for success, or error code for failure.
- + */
- +int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid,
- + struct dpaa2_io_store *s)
- +{
- + struct qbman_pull_desc pd;
- + int err;
- +
- + qbman_pull_desc_clear(&pd);
- + qbman_pull_desc_set_storage(&pd, s->vaddr, s->paddr, 1);
- + qbman_pull_desc_set_numframes(&pd, (u8)s->max);
- + qbman_pull_desc_set_channel(&pd, channelid, qbman_pull_type_prio);
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- +
- + s->swp = d->swp;
- + err = qbman_swp_pull(d->swp, &pd);
- + if (err)
- + s->swp = NULL;
- +
- + return err;
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_pull_channel);
- +
- +/**
- + * dpaa2_io_service_enqueue_fq() - Enqueue a frame to a frame queue.
- + * @d: the given DPIO service.
- + * @fqid: the given frame queue id.
- + * @fd: the frame descriptor which is enqueued.
- + *
- + * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready,
- + * or -ENODEV if there is no dpio service.
- + */
- +int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d,
- + u32 fqid,
- + const struct dpaa2_fd *fd)
- +{
- + struct qbman_eq_desc ed;
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- +
- + qbman_eq_desc_clear(&ed);
- + qbman_eq_desc_set_no_orp(&ed, 0);
- + qbman_eq_desc_set_fq(&ed, fqid);
- +
- + return qbman_swp_enqueue(d->swp, &ed, fd);
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq);
- +
- +/**
- + * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
- + * @d: the given DPIO service.
- + * @qdid: the given queuing destination id.
- + * @prio: the given queuing priority.
- + * @qdbin: the given queuing destination bin.
- + * @fd: the frame descriptor which is enqueued.
- + *
- + * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
- + * or -ENODEV if there is no dpio service.
- + */
- +int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d,
- + u32 qdid, u8 prio, u16 qdbin,
- + const struct dpaa2_fd *fd)
- +{
- + struct qbman_eq_desc ed;
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- +
- + qbman_eq_desc_clear(&ed);
- + qbman_eq_desc_set_no_orp(&ed, 0);
- + qbman_eq_desc_set_qd(&ed, qdid, qdbin, prio);
- +
- + return qbman_swp_enqueue(d->swp, &ed, fd);
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_enqueue_qd);
- +
- +/**
- + * dpaa2_io_service_release() - Release buffers to a buffer pool.
- + * @d: the given DPIO object.
- + * @bpid: the buffer pool id.
- + * @buffers: the buffers to be released.
- + * @num_buffers: the number of the buffers to be released.
- + *
- + * Return 0 for success, and negative error code for failure.
- + */
- +int dpaa2_io_service_release(struct dpaa2_io *d,
- + u32 bpid,
- + const u64 *buffers,
- + unsigned int num_buffers)
- +{
- + struct qbman_release_desc rd;
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- +
- + qbman_release_desc_clear(&rd);
- + qbman_release_desc_set_bpid(&rd, bpid);
- +
- + return qbman_swp_release(d->swp, &rd, buffers, num_buffers);
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_release);
- +
- +/**
- + * dpaa2_io_service_acquire() - Acquire buffers from a buffer pool.
- + * @d: the given DPIO object.
- + * @bpid: the buffer pool id.
- + * @buffers: the buffer addresses for acquired buffers.
- + * @num_buffers: the expected number of the buffers to acquire.
- + *
- + * Return a negative error code if the command failed, otherwise it returns
- + * the number of buffers acquired, which may be less than the number requested.
- + * Eg. if the buffer pool is empty, this will return zero.
- + */
- +int dpaa2_io_service_acquire(struct dpaa2_io *d,
- + u32 bpid,
- + u64 *buffers,
- + unsigned int num_buffers)
- +{
- + unsigned long irqflags;
- + int err;
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- +
- + spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
- + err = qbman_swp_acquire(d->swp, bpid, buffers, num_buffers);
- + spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
- +
- + return err;
- +}
- +EXPORT_SYMBOL(dpaa2_io_service_acquire);
- +
- +/*
- + * 'Stores' are reusable memory blocks for holding dequeue results, and to
- + * assist with parsing those results.
- + */
- +
- +/**
- + * dpaa2_io_store_create() - Create the dma memory storage for dequeue result.
- + * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
- + * @dev: the device to allow mapping/unmapping the DMAable region.
- + *
- + * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)".
- + * The 'dpaa2_io_store' returned is a DPIO service managed object.
- + *
- + * Return pointer to dpaa2_io_store struct for successfuly created storage
- + * memory, or NULL on error.
- + */
- +struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
- + struct device *dev)
- +{
- + struct dpaa2_io_store *ret;
- + size_t size;
- +
- + if (!max_frames || (max_frames > 16))
- + return NULL;
- +
- + ret = kmalloc(sizeof(*ret), GFP_KERNEL);
- + if (!ret)
- + return NULL;
- +
- + ret->max = max_frames;
- + size = max_frames * sizeof(struct dpaa2_dq) + 64;
- + ret->alloced_addr = kzalloc(size, GFP_KERNEL);
- + if (!ret->alloced_addr) {
- + kfree(ret);
- + return NULL;
- + }
- +
- + ret->vaddr = PTR_ALIGN(ret->alloced_addr, 64);
- + ret->paddr = dma_map_single(dev, ret->vaddr,
- + sizeof(struct dpaa2_dq) * max_frames,
- + DMA_FROM_DEVICE);
- + if (dma_mapping_error(dev, ret->paddr)) {
- + kfree(ret->alloced_addr);
- + kfree(ret);
- + return NULL;
- + }
- +
- + ret->idx = 0;
- + ret->dev = dev;
- +
- + return ret;
- +}
- +EXPORT_SYMBOL(dpaa2_io_store_create);
- +
- +/**
- + * dpaa2_io_store_destroy() - Frees the dma memory storage for dequeue
- + * result.
- + * @s: the storage memory to be destroyed.
- + */
- +void dpaa2_io_store_destroy(struct dpaa2_io_store *s)
- +{
- + dma_unmap_single(s->dev, s->paddr, sizeof(struct dpaa2_dq) * s->max,
- + DMA_FROM_DEVICE);
- + kfree(s->alloced_addr);
- + kfree(s);
- +}
- +EXPORT_SYMBOL(dpaa2_io_store_destroy);
- +
- +/**
- + * dpaa2_io_store_next() - Determine when the next dequeue result is available.
- + * @s: the dpaa2_io_store object.
- + * @is_last: indicate whether this is the last frame in the pull command.
- + *
- + * When an object driver performs dequeues to a dpaa2_io_store, this function
- + * can be used to determine when the next frame result is available. Once
- + * this function returns non-NULL, a subsequent call to it will try to find
- + * the next dequeue result.
- + *
- + * Note that if a pull-dequeue has a NULL result because the target FQ/channel
- + * was empty, then this function will also return NULL (rather than expecting
- + * the caller to always check for this. As such, "is_last" can be used to
- + * differentiate between "end-of-empty-dequeue" and "still-waiting".
- + *
- + * Return dequeue result for a valid dequeue result, or NULL for empty dequeue.
- + */
- +struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last)
- +{
- + int match;
- + struct dpaa2_dq *ret = &s->vaddr[s->idx];
- +
- + match = qbman_result_has_new_result(s->swp, ret);
- + if (!match) {
- + *is_last = 0;
- + return NULL;
- + }
- +
- + s->idx++;
- +
- + if (dpaa2_dq_is_pull_complete(ret)) {
- + *is_last = 1;
- + s->idx = 0;
- + /*
- + * If we get an empty dequeue result to terminate a zero-results
- + * vdqcr, return NULL to the caller rather than expecting him to
- + * check non-NULL results every time.
- + */
- + if (!(dpaa2_dq_flags(ret) & DPAA2_DQ_STAT_VALIDFRAME))
- + ret = NULL;
- + } else {
- + *is_last = 0;
- + }
- +
- + return ret;
- +}
- +EXPORT_SYMBOL(dpaa2_io_store_next);
- +
- +#ifdef CONFIG_FSL_QBMAN_DEBUG
- +/**
- + * dpaa2_io_query_fq_count() - Get the frame and byte count for a given fq.
- + * @d: the given DPIO object.
- + * @fqid: the id of frame queue to be queried.
- + * @fcnt: the queried frame count.
- + * @bcnt: the queried byte count.
- + *
- + * Knowing the FQ count at run-time can be useful in debugging situations.
- + * The instantaneous frame- and byte-count are hereby returned.
- + *
- + * Return 0 for a successful query, and negative error code if query fails.
- + */
- +int dpaa2_io_query_fq_count(struct dpaa2_io *d, uint32_t fqid,
- + u32 *fcnt, u32 *bcnt)
- +{
- + struct qbman_attr state;
- + struct qbman_swp *swp;
- + unsigned long irqflags;
- + int ret;
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- +
- + swp = d->swp;
- + spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
- + ret = qbman_fq_query_state(swp, fqid, &state);
- + spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
- + if (ret)
- + return ret;
- + *fcnt = qbman_fq_state_frame_count(&state);
- + *bcnt = qbman_fq_state_byte_count(&state);
- +
- + return 0;
- +}
- +EXPORT_SYMBOL(dpaa2_io_query_fq_count);
- +
- +/**
- + * dpaa2_io_query_bp_count() - Query the number of buffers currenty in a
- + * buffer pool.
- + * @d: the given DPIO object.
- + * @bpid: the index of buffer pool to be queried.
- + * @num: the queried number of buffers in the buffer pool.
- + *
- + * Return 0 for a sucessful query, and negative error code if query fails.
- + */
- +int dpaa2_io_query_bp_count(struct dpaa2_io *d, uint32_t bpid, u32 *num)
- +{
- + struct qbman_attr state;
- + struct qbman_swp *swp;
- + unsigned long irqflags;
- + int ret;
- +
- + d = service_select(d);
- + if (!d)
- + return -ENODEV;
- +
- + swp = d->swp;
- + spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
- + ret = qbman_bp_query(swp, bpid, &state);
- + spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
- + if (ret)
- + return ret;
- + *num = qbman_bp_info_num_free_bufs(&state);
- + return 0;
- +}
- +EXPORT_SYMBOL(dpaa2_io_query_bp_count);
- +#endif
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/dpio.c
- @@ -0,0 +1,224 @@
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#include "../../include/mc-sys.h"
- +#include "../../include/mc-cmd.h"
- +
- +#include "dpio.h"
- +#include "dpio-cmd.h"
- +
- +/*
- + * Data Path I/O Portal API
- + * Contains initialization APIs and runtime control APIs for DPIO
- + */
- +
- +/**
- + * dpio_open() - Open a control session for the specified object
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @dpio_id: DPIO unique ID
- + * @token: Returned token; use in subsequent API calls
- + *
- + * This function can be used to open a control session for an
- + * already created object; an object may have been declared in
- + * the DPL or by calling the dpio_create() function.
- + * This function returns a unique authentication token,
- + * associated with the specific object ID and the specific MC
- + * portal; this token must be used in all subsequent commands for
- + * this specific object.
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpio_open(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + int dpio_id,
- + u16 *token)
- +{
- + struct mc_command cmd = { 0 };
- + struct dpio_cmd_open *dpio_cmd;
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
- + cmd_flags,
- + 0);
- + dpio_cmd = (struct dpio_cmd_open *)cmd.params;
- + dpio_cmd->dpio_id = cpu_to_le32(dpio_id);
- +
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + *token = mc_cmd_hdr_read_token(&cmd);
- +
- + return 0;
- +}
- +
- +/**
- + * dpio_close() - Close the control session of the object
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPIO object
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpio_close(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
- + cmd_flags,
- + token);
- +
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +/**
- + * dpio_enable() - Enable the DPIO, allow I/O portal operations.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPIO object
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpio_enable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
- + cmd_flags,
- + token);
- +
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +/**
- + * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPIO object
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpio_disable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
- + cmd_flags,
- + token);
- +
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +/**
- + * dpio_get_attributes() - Retrieve DPIO attributes
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPIO object
- + * @attr: Returned object's attributes
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpio_get_attributes(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dpio_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + struct dpio_rsp_get_attr *dpio_rsp;
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
- + cmd_flags,
- + token);
- +
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + dpio_rsp = (struct dpio_rsp_get_attr *)cmd.params;
- + attr->id = le32_to_cpu(dpio_rsp->id);
- + attr->qbman_portal_id = le16_to_cpu(dpio_rsp->qbman_portal_id);
- + attr->num_priorities = dpio_rsp->num_priorities;
- + attr->channel_mode = dpio_rsp->channel_mode & DPIO_CHANNEL_MODE_MASK;
- + attr->qbman_portal_ce_offset =
- + le64_to_cpu(dpio_rsp->qbman_portal_ce_addr);
- + attr->qbman_portal_ci_offset =
- + le64_to_cpu(dpio_rsp->qbman_portal_ci_addr);
- + attr->qbman_version = le32_to_cpu(dpio_rsp->qbman_version);
- +
- + return 0;
- +}
- +
- +/**
- + * dpio_get_api_version - Get Data Path I/O API version
- + * @mc_io: Pointer to MC portal's DPIO object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @major_ver: Major version of DPIO API
- + * @minor_ver: Minor version of DPIO API
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpio_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
- + cmd_flags, 0);
- +
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
- +
- + return 0;
- +}
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/dpio.h
- @@ -0,0 +1,109 @@
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef __FSL_DPIO_H
- +#define __FSL_DPIO_H
- +
- +struct fsl_mc_io;
- +
- +int dpio_open(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + int dpio_id,
- + u16 *token);
- +
- +int dpio_close(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token);
- +
- +/**
- + * enum dpio_channel_mode - DPIO notification channel mode
- + * @DPIO_NO_CHANNEL: No support for notification channel
- + * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
- + * dedicated channel in the DPIO; user should point the queue's
- + * destination in the relevant interface to this DPIO
- + */
- +enum dpio_channel_mode {
- + DPIO_NO_CHANNEL = 0,
- + DPIO_LOCAL_CHANNEL = 1,
- +};
- +
- +/**
- + * struct dpio_cfg - Structure representing DPIO configuration
- + * @channel_mode: Notification channel mode
- + * @num_priorities: Number of priorities for the notification channel (1-8);
- + * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
- + */
- +struct dpio_cfg {
- + enum dpio_channel_mode channel_mode;
- + u8 num_priorities;
- +};
- +
- +int dpio_enable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token);
- +
- +int dpio_disable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token);
- +
- +/**
- + * struct dpio_attr - Structure representing DPIO attributes
- + * @id: DPIO object ID
- + * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
- + * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
- + * @qbman_portal_id: Software portal ID
- + * @channel_mode: Notification channel mode
- + * @num_priorities: Number of priorities for the notification channel (1-8);
- + * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
- + * @qbman_version: QBMAN version
- + */
- +struct dpio_attr {
- + int id;
- + u64 qbman_portal_ce_offset;
- + u64 qbman_portal_ci_offset;
- + u16 qbman_portal_id;
- + enum dpio_channel_mode channel_mode;
- + u8 num_priorities;
- + u32 qbman_version;
- +};
- +
- +int dpio_get_attributes(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dpio_attr *attr);
- +
- +int dpio_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver);
- +
- +#endif /* __FSL_DPIO_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
- @@ -0,0 +1,1049 @@
- +/*
- + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +#include <asm/cacheflush.h>
- +#include <linux/io.h>
- +#include <linux/slab.h>
- +#include "../../include/dpaa2-global.h"
- +
- +#include "qbman-portal.h"
- +
- +struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
- +struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
- +
- +#define QMAN_REV_4000 0x04000000
- +#define QMAN_REV_4100 0x04010000
- +#define QMAN_REV_4101 0x04010001
- +#define QMAN_REV_MASK 0xffff0000
- +
- +/* All QBMan command and result structures use this "valid bit" encoding */
- +#define QB_VALID_BIT ((u32)0x80)
- +
- +/* QBMan portal management command codes */
- +#define QBMAN_MC_ACQUIRE 0x30
- +#define QBMAN_WQCHAN_CONFIGURE 0x46
- +
- +/* CINH register offsets */
- +#define QBMAN_CINH_SWP_EQAR 0x8c0
- +#define QBMAN_CINH_SWP_DQPI 0xa00
- +#define QBMAN_CINH_SWP_DCAP 0xac0
- +#define QBMAN_CINH_SWP_SDQCR 0xb00
- +#define QBMAN_CINH_SWP_RAR 0xcc0
- +#define QBMAN_CINH_SWP_ISR 0xe00
- +#define QBMAN_CINH_SWP_IER 0xe40
- +#define QBMAN_CINH_SWP_ISDR 0xe80
- +#define QBMAN_CINH_SWP_IIR 0xec0
- +
- +/* CENA register offsets */
- +#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((u32)(n) << 6))
- +#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((u32)(n) << 6))
- +#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((u32)(n) << 6))
- +#define QBMAN_CENA_SWP_CR 0x600
- +#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((u32)(vb) >> 1))
- +#define QBMAN_CENA_SWP_VDQCR 0x780
- +
- +/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
- +#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)(p) & 0x1ff) >> 6)
- +
- +/* Define token used to determine if response written to memory is valid */
- +#define QMAN_DQ_TOKEN_VALID 1
- +
- +/* SDQCR attribute codes */
- +#define QB_SDQCR_FC_SHIFT 29
- +#define QB_SDQCR_FC_MASK 0x1
- +#define QB_SDQCR_DCT_SHIFT 24
- +#define QB_SDQCR_DCT_MASK 0x3
- +#define QB_SDQCR_TOK_SHIFT 16
- +#define QB_SDQCR_TOK_MASK 0xff
- +#define QB_SDQCR_SRC_SHIFT 0
- +#define QB_SDQCR_SRC_MASK 0xffff
- +
- +/* opaque token for static dequeues */
- +#define QMAN_SDQCR_TOKEN 0xbb
- +
- +enum qbman_sdqcr_dct {
- + qbman_sdqcr_dct_null = 0,
- + qbman_sdqcr_dct_prio_ics,
- + qbman_sdqcr_dct_active_ics,
- + qbman_sdqcr_dct_active
- +};
- +
- +enum qbman_sdqcr_fc {
- + qbman_sdqcr_fc_one = 0,
- + qbman_sdqcr_fc_up_to_3 = 1
- +};
- +
- +#define dccvac(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
- +#define dcivac(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
- +static inline void qbman_inval_prefetch(struct qbman_swp *p, uint32_t offset)
- +{
- + dcivac(p->addr_cena + offset);
- + prefetch(p->addr_cena + offset);
- +}
- +
- +/* Portal Access */
- +
- +static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset)
- +{
- + return readl_relaxed(p->addr_cinh + offset);
- +}
- +
- +static inline void qbman_write_register(struct qbman_swp *p, u32 offset,
- + u32 value)
- +{
- + writel_relaxed(value, p->addr_cinh + offset);
- +}
- +
- +static inline void *qbman_get_cmd(struct qbman_swp *p, u32 offset)
- +{
- + return p->addr_cena + offset;
- +}
- +
- +#define QBMAN_CINH_SWP_CFG 0xd00
- +
- +#define SWP_CFG_DQRR_MF_SHIFT 20
- +#define SWP_CFG_EST_SHIFT 16
- +#define SWP_CFG_WN_SHIFT 14
- +#define SWP_CFG_RPM_SHIFT 12
- +#define SWP_CFG_DCM_SHIFT 10
- +#define SWP_CFG_EPM_SHIFT 8
- +#define SWP_CFG_SD_SHIFT 5
- +#define SWP_CFG_SP_SHIFT 4
- +#define SWP_CFG_SE_SHIFT 3
- +#define SWP_CFG_DP_SHIFT 2
- +#define SWP_CFG_DE_SHIFT 1
- +#define SWP_CFG_EP_SHIFT 0
- +
- +static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm,
- + u8 epm, int sd, int sp, int se,
- + int dp, int de, int ep)
- +{
- + return cpu_to_le32 (max_fill << SWP_CFG_DQRR_MF_SHIFT |
- + est << SWP_CFG_EST_SHIFT |
- + wn << SWP_CFG_WN_SHIFT |
- + rpm << SWP_CFG_RPM_SHIFT |
- + dcm << SWP_CFG_DCM_SHIFT |
- + epm << SWP_CFG_EPM_SHIFT |
- + sd << SWP_CFG_SD_SHIFT |
- + sp << SWP_CFG_SP_SHIFT |
- + se << SWP_CFG_SE_SHIFT |
- + dp << SWP_CFG_DP_SHIFT |
- + de << SWP_CFG_DE_SHIFT |
- + ep << SWP_CFG_EP_SHIFT);
- +}
- +
- +/**
- + * qbman_swp_init() - Create a functional object representing the given
- + * QBMan portal descriptor.
- + * @d: the given qbman swp descriptor
- + *
- + * Return qbman_swp portal for success, NULL if the object cannot
- + * be created.
- + */
- +struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
- +{
- + struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
- + u32 reg;
- +
- + if (!p)
- + return NULL;
- + p->desc = d;
- + p->mc.valid_bit = QB_VALID_BIT;
- + p->sdq = 0;
- + p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT;
- + p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT;
- + p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT;
- +
- + atomic_set(&p->vdq.available, 1);
- + p->vdq.valid_bit = QB_VALID_BIT;
- + p->dqrr.next_idx = 0;
- + p->dqrr.valid_bit = QB_VALID_BIT;
- +
- + if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_4100) {
- + p->dqrr.dqrr_size = 4;
- + p->dqrr.reset_bug = 1;
- + } else {
- + p->dqrr.dqrr_size = 8;
- + p->dqrr.reset_bug = 0;
- + }
- +
- + p->addr_cena = d->cena_bar;
- + p->addr_cinh = d->cinh_bar;
- +
- + reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
- + 0, /* Writes cacheable */
- + 0, /* EQCR_CI stashing threshold */
- + 3, /* RPM: Valid bit mode, RCR in array mode */
- + 2, /* DCM: Discrete consumption ack mode */
- + 3, /* EPM: Valid bit mode, EQCR in array mode */
- + 0, /* mem stashing drop enable == FALSE */
- + 1, /* mem stashing priority == TRUE */
- + 0, /* mem stashing enable == FALSE */
- + 1, /* dequeue stashing priority == TRUE */
- + 0, /* dequeue stashing enable == FALSE */
- + 0); /* EQCR_CI stashing priority == FALSE */
- +
- + qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg);
- + reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG);
- + if (!reg) {
- + pr_err("qbman: the portal is not enabled!\n");
- + return NULL;
- + }
- +
- + /*
- + * SDQCR needs to be initialized to 0 when no channels are
- + * being dequeued from or else the QMan HW will indicate an
- + * error. The values that were calculated above will be
- + * applied when dequeues from a specific channel are enabled.
- + */
- + qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0);
- + return p;
- +}
- +
- +/**
- + * qbman_swp_finish() - Create and destroy a functional object representing
- + * the given QBMan portal descriptor.
- + * @p: the qbman_swp object to be destroyed
- + */
- +void qbman_swp_finish(struct qbman_swp *p)
- +{
- + kfree(p);
- +}
- +
- +/**
- + * qbman_swp_interrupt_read_status()
- + * @p: the given software portal
- + *
- + * Return the value in the SWP_ISR register.
- + */
- +u32 qbman_swp_interrupt_read_status(struct qbman_swp *p)
- +{
- + return qbman_read_register(p, QBMAN_CINH_SWP_ISR);
- +}
- +
- +/**
- + * qbman_swp_interrupt_clear_status()
- + * @p: the given software portal
- + * @mask: The mask to clear in SWP_ISR register
- + */
- +void qbman_swp_interrupt_clear_status(struct qbman_swp *p, u32 mask)
- +{
- + qbman_write_register(p, QBMAN_CINH_SWP_ISR, mask);
- +}
- +
- +/**
- + * qbman_swp_interrupt_get_trigger() - read interrupt enable register
- + * @p: the given software portal
- + *
- + * Return the value in the SWP_IER register.
- + */
- +u32 qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
- +{
- + return qbman_read_register(p, QBMAN_CINH_SWP_IER);
- +}
- +
- +/**
- + * qbman_swp_interrupt_set_trigger() - enable interrupts for a swp
- + * @p: the given software portal
- + * @mask: The mask of bits to enable in SWP_IER
- + */
- +void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, u32 mask)
- +{
- + qbman_write_register(p, QBMAN_CINH_SWP_IER, mask);
- +}
- +
- +/**
- + * qbman_swp_interrupt_get_inhibit() - read interrupt mask register
- + * @p: the given software portal object
- + *
- + * Return the value in the SWP_IIR register.
- + */
- +int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
- +{
- + return qbman_read_register(p, QBMAN_CINH_SWP_IIR);
- +}
- +
- +/**
- + * qbman_swp_interrupt_set_inhibit() - write interrupt mask register
- + * @p: the given software portal object
- + * @mask: The mask to set in SWP_IIR register
- + */
- +void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
- +{
- + qbman_write_register(p, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
- +}
- +
- +/*
- + * Different management commands all use this common base layer of code to issue
- + * commands and poll for results.
- + */
- +
- +/*
- + * Returns a pointer to where the caller should fill in their management command
- + * (caller should ignore the verb byte)
- + */
- +void *qbman_swp_mc_start(struct qbman_swp *p)
- +{
- + return qbman_get_cmd(p, QBMAN_CENA_SWP_CR);
- +}
- +
- +/*
- + * Commits merges in the caller-supplied command verb (which should not include
- + * the valid-bit) and submits the command to hardware
- + */
- +void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb)
- +{
- + u8 *v = cmd;
- +
- + dma_wmb();
- + *v = cmd_verb | p->mc.valid_bit;
- + dccvac(cmd);
- +}
- +
- +/*
- + * Checks for a completed response (returns non-NULL if only if the response
- + * is complete).
- + */
- +void *qbman_swp_mc_result(struct qbman_swp *p)
- +{
- + u32 *ret, verb;
- +
- + qbman_inval_prefetch(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
- + ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
- +
- + /* Remove the valid-bit - command completed if the rest is non-zero */
- + verb = ret[0] & ~QB_VALID_BIT;
- + if (!verb)
- + return NULL;
- + p->mc.valid_bit ^= QB_VALID_BIT;
- + return ret;
- +}
- +
- +#define QB_ENQUEUE_CMD_OPTIONS_SHIFT 0
- +enum qb_enqueue_commands {
- + enqueue_empty = 0,
- + enqueue_response_always = 1,
- + enqueue_rejects_to_fq = 2
- +};
- +
- +#define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2
- +#define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
- +#define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4
- +
- +/**
- + * qbman_eq_desc_clear() - Clear the contents of a descriptor to
- + * default/starting state.
- + */
- +void qbman_eq_desc_clear(struct qbman_eq_desc *d)
- +{
- + memset(d, 0, sizeof(*d));
- +}
- +
- +/**
- + * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
- + * @d: the enqueue descriptor.
- + * @response_success: 1 = enqueue with response always; 0 = enqueue with
- + * rejections returned on a FQ.
- + */
- +void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
- +{
- + d->verb &= ~(1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT);
- + if (respond_success)
- + d->verb |= enqueue_response_always;
- + else
- + d->verb |= enqueue_rejects_to_fq;
- +}
- +
- +/*
- + * Exactly one of the following descriptor "targets" should be set. (Calling any
- + * one of these will replace the effect of any prior call to one of these.)
- + * -enqueue to a frame queue
- + * -enqueue to a queuing destination
- + */
- +
- +/**
- + * qbman_eq_desc_set_fq() - set the FQ for the enqueue command
- + * @d: the enqueue descriptor
- + * @fqid: the id of the frame queue to be enqueued
- + */
- +void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid)
- +{
- + d->verb &= ~(1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT);
- + d->tgtid = cpu_to_le32(fqid);
- +}
- +
- +/**
- + * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command
- + * @d: the enqueue descriptor
- + * @qdid: the id of the queuing destination to be enqueued
- + * @qd_bin: the queuing destination bin
- + * @qd_prio: the queuing destination priority
- + */
- +void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
- + u32 qd_bin, u32 qd_prio)
- +{
- + d->verb |= 1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT;
- + d->tgtid = cpu_to_le32(qdid);
- + d->qdbin = cpu_to_le16(qd_bin);
- + d->qpri = qd_prio;
- +}
- +
- +#define EQAR_IDX(eqar) ((eqar) & 0x7)
- +#define EQAR_VB(eqar) ((eqar) & 0x80)
- +#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
- +
- +/**
- + * qbman_swp_enqueue() - Issue an enqueue command
- + * @s: the software portal used for enqueue
- + * @d: the enqueue descriptor
- + * @fd: the frame descriptor to be enqueued
- + *
- + * Please note that 'fd' should only be NULL if the "action" of the
- + * descriptor is "orp_hole" or "orp_nesn".
- + *
- + * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
- + */
- +int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
- + const struct dpaa2_fd *fd)
- +{
- + struct qbman_eq_desc *p;
- + u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR);
- +
- + if (!EQAR_SUCCESS(eqar))
- + return -EBUSY;
- +
- + p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
- + memcpy(&p->dca, &d->dca, 31);
- + memcpy(&p->fd, fd, sizeof(*fd));
- +
- + /* Set the verb byte, have to substitute in the valid-bit */
- + dma_wmb();
- + p->verb = d->verb | EQAR_VB(eqar);
- + dccvac(p);
- +
- + return 0;
- +}
- +
- +/* Static (push) dequeue */
- +
- +/**
- + * qbman_swp_push_get() - Get the push dequeue setup
- + * @p: the software portal object
- + * @channel_idx: the channel index to query
- + * @enabled: returned boolean to show whether the push dequeue is enabled
- + * for the given channel
- + */
- +void qbman_swp_push_get(struct qbman_swp *s, u8 channel_idx, int *enabled)
- +{
- + u16 src = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
- +
- + WARN_ON(channel_idx > 15);
- + *enabled = src | (1 << channel_idx);
- +}
- +
- +/**
- + * qbman_swp_push_set() - Enable or disable push dequeue
- + * @p: the software portal object
- + * @channel_idx: the channel index (0 to 15)
- + * @enable: enable or disable push dequeue
- + */
- +void qbman_swp_push_set(struct qbman_swp *s, u8 channel_idx, int enable)
- +{
- + u16 dqsrc;
- +
- + WARN_ON(channel_idx > 15);
- + if (enable)
- + s->sdq |= 1 << channel_idx;
- + else
- + s->sdq &= ~(1 << channel_idx);
- +
- + /* Read make the complete src map. If no channels are enabled
- + * the SDQCR must be 0 or else QMan will assert errors
- + */
- + dqsrc = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
- + if (dqsrc != 0)
- + qbman_write_register(s, QBMAN_CINH_SWP_SDQCR, s->sdq);
- + else
- + qbman_write_register(s, QBMAN_CINH_SWP_SDQCR, 0);
- +}
- +
- +#define QB_VDQCR_VERB_DCT_SHIFT 0
- +#define QB_VDQCR_VERB_DT_SHIFT 2
- +#define QB_VDQCR_VERB_RLS_SHIFT 4
- +#define QB_VDQCR_VERB_WAE_SHIFT 5
- +
- +enum qb_pull_dt_e {
- + qb_pull_dt_channel,
- + qb_pull_dt_workqueue,
- + qb_pull_dt_framequeue
- +};
- +
- +/**
- + * qbman_pull_desc_clear() - Clear the contents of a descriptor to
- + * default/starting state
- + * @d: the pull dequeue descriptor to be cleared
- + */
- +void qbman_pull_desc_clear(struct qbman_pull_desc *d)
- +{
- + memset(d, 0, sizeof(*d));
- +}
- +
- +/**
- + * qbman_pull_desc_set_storage()- Set the pull dequeue storage
- + * @d: the pull dequeue descriptor to be set
- + * @storage: the pointer of the memory to store the dequeue result
- + * @storage_phys: the physical address of the storage memory
- + * @stash: to indicate whether write allocate is enabled
- + *
- + * If not called, or if called with 'storage' as NULL, the result pull dequeues
- + * will produce results to DQRR. If 'storage' is non-NULL, then results are
- + * produced to the given memory location (using the DMA address which
- + * the caller provides in 'storage_phys'), and 'stash' controls whether or not
- + * those writes to main-memory express a cache-warming attribute.
- + */
- +void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
- + struct dpaa2_dq *storage,
- + dma_addr_t storage_phys,
- + int stash)
- +{
- + /* save the virtual address */
- + d->rsp_addr_virt = (u64)storage;
- +
- + if (!storage) {
- + d->verb &= ~(1 << QB_VDQCR_VERB_RLS_SHIFT);
- + return;
- + }
- + d->verb |= 1 << QB_VDQCR_VERB_RLS_SHIFT;
- + if (stash)
- + d->verb |= 1 << QB_VDQCR_VERB_WAE_SHIFT;
- + else
- + d->verb &= ~(1 << QB_VDQCR_VERB_WAE_SHIFT);
- +
- + d->rsp_addr = cpu_to_le64(storage_phys);
- +}
- +
- +/**
- + * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued
- + * @d: the pull dequeue descriptor to be set
- + * @numframes: number of frames to be set, must be between 1 and 16, inclusive
- + */
- +void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, u8 numframes)
- +{
- + d->numf = numframes - 1;
- +}
- +
- +void qbman_pull_desc_set_token(struct qbman_pull_desc *d, u8 token)
- +{
- + d->tok = token;
- +}
- +
- +/*
- + * Exactly one of the following descriptor "actions" should be set. (Calling any
- + * one of these will replace the effect of any prior call to one of these.)
- + * - pull dequeue from the given frame queue (FQ)
- + * - pull dequeue from any FQ in the given work queue (WQ)
- + * - pull dequeue from any FQ in any WQ in the given channel
- + */
- +
- +/**
- + * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues
- + * @fqid: the frame queue index of the given FQ
- + */
- +void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, u32 fqid)
- +{
- + d->verb |= 1 << QB_VDQCR_VERB_DCT_SHIFT;
- + d->verb |= qb_pull_dt_framequeue << QB_VDQCR_VERB_DT_SHIFT;
- + d->dq_src = cpu_to_le32(fqid);
- +}
- +
- +/**
- + * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues
- + * @wqid: composed of channel id and wqid within the channel
- + * @dct: the dequeue command type
- + */
- +void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid,
- + enum qbman_pull_type_e dct)
- +{
- + d->verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
- + d->verb |= qb_pull_dt_workqueue << QB_VDQCR_VERB_DT_SHIFT;
- + d->dq_src = cpu_to_le32(wqid);
- +}
- +
- +/**
- + * qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
- + * dequeues
- + * @chid: the channel id to be dequeued
- + * @dct: the dequeue command type
- + */
- +void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
- + enum qbman_pull_type_e dct)
- +{
- + d->verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
- + d->verb |= qb_pull_dt_channel << QB_VDQCR_VERB_DT_SHIFT;
- + d->dq_src = cpu_to_le32(chid);
- +}
- +
- +/**
- + * qbman_swp_pull() - Issue the pull dequeue command
- + * @s: the software portal object
- + * @d: the software portal descriptor which has been configured with
- + * the set of qbman_pull_desc_set_*() calls
- + *
- + * Return 0 for success, and -EBUSY if the software portal is not ready
- + * to do pull dequeue.
- + */
- +int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
- +{
- + struct qbman_pull_desc *p;
- +
- + if (!atomic_dec_and_test(&s->vdq.available)) {
- + atomic_inc(&s->vdq.available);
- + return -EBUSY;
- + }
- + s->vdq.storage = (void *)d->rsp_addr_virt;
- + p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
- + p->numf = d->numf;
- + p->tok = QMAN_DQ_TOKEN_VALID;
- + p->dq_src = d->dq_src;
- + p->rsp_addr = d->rsp_addr;
- + p->rsp_addr_virt = d->rsp_addr_virt;
- + dma_wmb();
- +
- + /* Set the verb byte, have to substitute in the valid-bit */
- + p->verb = d->verb | s->vdq.valid_bit;
- + s->vdq.valid_bit ^= QB_VALID_BIT;
- + dccvac(p);
- +
- + return 0;
- +}
- +
- +#define QMAN_DQRR_PI_MASK 0xf
- +
- +/**
- + * qbman_swp_dqrr_next() - Get an valid DQRR entry
- + * @s: the software portal object
- + *
- + * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
- + * only once, so repeated calls can return a sequence of DQRR entries, without
- + * requiring they be consumed immediately or in any particular order.
- + */
- +const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
- +{
- + u32 verb;
- + u32 response_verb;
- + u32 flags;
- + struct dpaa2_dq *p;
- +
- + /* Before using valid-bit to detect if something is there, we have to
- + * handle the case of the DQRR reset bug...
- + */
- + if (unlikely(s->dqrr.reset_bug)) {
- + /*
- + * We pick up new entries by cache-inhibited producer index,
- + * which means that a non-coherent mapping would require us to
- + * invalidate and read *only* once that PI has indicated that
- + * there's an entry here. The first trip around the DQRR ring
- + * will be much less efficient than all subsequent trips around
- + * it...
- + */
- + u8 pi = qbman_read_register(s, QBMAN_CINH_SWP_DQPI) &
- + QMAN_DQRR_PI_MASK;
- +
- + /* there are new entries if pi != next_idx */
- + if (pi == s->dqrr.next_idx)
- + return NULL;
- +
- + /*
- + * if next_idx is/was the last ring index, and 'pi' is
- + * different, we can disable the workaround as all the ring
- + * entries have now been DMA'd to so valid-bit checking is
- + * repaired. Note: this logic needs to be based on next_idx
- + * (which increments one at a time), rather than on pi (which
- + * can burst and wrap-around between our snapshots of it).
- + */
- + if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) {
- + pr_debug("next_idx=%d, pi=%d, clear reset bug\n",
- + s->dqrr.next_idx, pi);
- + s->dqrr.reset_bug = 0;
- + }
- + qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
- + }
- +
- + p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
- + verb = p->dq.verb;
- +
- + /*
- + * If the valid-bit isn't of the expected polarity, nothing there. Note,
- + * in the DQRR reset bug workaround, we shouldn't need to skip these
- + * check, because we've already determined that a new entry is available
- + * and we've invalidated the cacheline before reading it, so the
- + * valid-bit behaviour is repaired and should tell us what we already
- + * knew from reading PI.
- + */
- + if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
- + qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
- + return NULL;
- + }
- + /*
- + * There's something there. Move "next_idx" attention to the next ring
- + * entry (and prefetch it) before returning what we found.
- + */
- + s->dqrr.next_idx++;
- + s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */
- + if (!s->dqrr.next_idx)
- + s->dqrr.valid_bit ^= QB_VALID_BIT;
- +
- + /*
- + * If this is the final response to a volatile dequeue command
- + * indicate that the vdq is available
- + */
- + flags = p->dq.stat;
- + response_verb = verb & QBMAN_RESULT_MASK;
- + if ((response_verb == QBMAN_RESULT_DQ) &&
- + (flags & DPAA2_DQ_STAT_VOLATILE) &&
- + (flags & DPAA2_DQ_STAT_EXPIRED))
- + atomic_inc(&s->vdq.available);
- +
- + qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
- +
- + return p;
- +}
- +
- +/**
- + * qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from
- + * qbman_swp_dqrr_next().
- + * @s: the software portal object
- + * @dq: the DQRR entry to be consumed
- + */
- +void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq)
- +{
- + qbman_write_register(s, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
- +}
- +
- +/**
- + * qbman_result_has_new_result() - Check and get the dequeue response from the
- + * dq storage memory set in pull dequeue command
- + * @s: the software portal object
- + * @dq: the dequeue result read from the memory
- + *
- + * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
- + * dequeue result.
- + *
- + * Only used for user-provided storage of dequeue results, not DQRR. For
- + * efficiency purposes, the driver will perform any required endianness
- + * conversion to ensure that the user's dequeue result storage is in host-endian
- + * format. As such, once the user has called qbman_result_has_new_result() and
- + * been returned a valid dequeue result, they should not call it again on
- + * the same memory location (except of course if another dequeue command has
- + * been executed to produce a new result to that location).
- + */
- +int qbman_result_has_new_result(struct qbman_swp *s, const struct dpaa2_dq *dq)
- +{
- + if (dq->dq.tok != QMAN_DQ_TOKEN_VALID)
- + return 0;
- +
- + /*
- + * Set token to be 0 so we will detect change back to 1
- + * next time the looping is traversed. Const is cast away here
- + * as we want users to treat the dequeue responses as read only.
- + */
- + ((struct dpaa2_dq *)dq)->dq.tok = 0;
- +
- + /*
- + * Determine whether VDQCR is available based on whether the
- + * current result is sitting in the first storage location of
- + * the busy command.
- + */
- + if (s->vdq.storage == dq) {
- + s->vdq.storage = NULL;
- + atomic_inc(&s->vdq.available);
- + }
- +
- + return 1;
- +}
- +
- +/**
- + * qbman_release_desc_clear() - Clear the contents of a descriptor to
- + * default/starting state.
- + */
- +void qbman_release_desc_clear(struct qbman_release_desc *d)
- +{
- + memset(d, 0, sizeof(*d));
- + d->verb = 1 << 5; /* Release Command Valid */
- +}
- +
- +/**
- + * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
- + */
- +void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid)
- +{
- + d->bpid = cpu_to_le16(bpid);
- +}
- +
- +/**
- + * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
- + * interrupt source should be asserted after the release command is completed.
- + */
- +void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
- +{
- + if (enable)
- + d->verb |= 1 << 6;
- + else
- + d->verb &= ~(1 << 6);
- +}
- +
- +#define RAR_IDX(rar) ((rar) & 0x7)
- +#define RAR_VB(rar) ((rar) & 0x80)
- +#define RAR_SUCCESS(rar) ((rar) & 0x100)
- +
- +/**
- + * qbman_swp_release() - Issue a buffer release command
- + * @s: the software portal object
- + * @d: the release descriptor
- + * @buffers: a pointer pointing to the buffer address to be released
- + * @num_buffers: number of buffers to be released, must be less than 8
- + *
- + * Return 0 for success, -EBUSY if the release command ring is not ready.
- + */
- +int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
- + const u64 *buffers, unsigned int num_buffers)
- +{
- + int i;
- + struct qbman_release_desc *p;
- + u32 rar;
- +
- + if (!num_buffers || (num_buffers > 7))
- + return -EINVAL;
- +
- + rar = qbman_read_register(s, QBMAN_CINH_SWP_RAR);
- + if (!RAR_SUCCESS(rar))
- + return -EBUSY;
- +
- + /* Start the release command */
- + p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
- + /* Copy the caller's buffer pointers to the command */
- + for (i = 0; i < num_buffers; i++)
- + p->buf[i] = cpu_to_le64(buffers[i]);
- + p->bpid = d->bpid;
- +
- + /*
- + * Set the verb byte, have to substitute in the valid-bit and the number
- + * of buffers.
- + */
- + dma_wmb();
- + p->verb = d->verb | RAR_VB(rar) | num_buffers;
- + dccvac(p);
- +
- + return 0;
- +}
- +
- +struct qbman_acquire_desc {
- + u8 verb;
- + u8 reserved;
- + u16 bpid;
- + u8 num;
- + u8 reserved2[59];
- +};
- +
- +struct qbman_acquire_rslt {
- + u8 verb;
- + u8 rslt;
- + u16 reserved;
- + u8 num;
- + u8 reserved2[3];
- + u64 buf[7];
- +};
- +
- +/**
- + * qbman_swp_acquire() - Issue a buffer acquire command
- + * @s: the software portal object
- + * @bpid: the buffer pool index
- + * @buffers: a pointer pointing to the acquired buffer addresses
- + * @num_buffers: number of buffers to be acquired, must be less than 8
- + *
- + * Return 0 for success, or negative error code if the acquire command
- + * fails.
- + */
- +int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
- + unsigned int num_buffers)
- +{
- + struct qbman_acquire_desc *p;
- + struct qbman_acquire_rslt *r;
- + int i;
- +
- + if (!num_buffers || (num_buffers > 7))
- + return -EINVAL;
- +
- + /* Start the management command */
- + p = qbman_swp_mc_start(s);
- +
- + if (!p)
- + return -EBUSY;
- +
- + /* Encode the caller-provided attributes */
- + p->bpid = cpu_to_le16(bpid);
- + p->num = num_buffers;
- +
- + /* Complete the management command */
- + r = qbman_swp_mc_complete(s, p, QBMAN_MC_ACQUIRE);
- + if (unlikely(!r)) {
- + pr_err("qbman: acquire from BPID %d failed, no response\n",
- + bpid);
- + return -EIO;
- + }
- +
- + /* Decode the outcome */
- + WARN_ON((r->verb & 0x7f) != QBMAN_MC_ACQUIRE);
- +
- + /* Determine success or failure */
- + if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("qbman: acquire from BPID 0x%x failed, code=0x%02x\n",
- + bpid, r->rslt);
- + return -EIO;
- + }
- +
- + WARN_ON(r->num > num_buffers);
- +
- + /* Copy the acquired buffers to the caller's array */
- + for (i = 0; i < r->num; i++)
- + buffers[i] = le64_to_cpu(r->buf[i]);
- +
- + return (int)r->num;
- +}
- +
- +struct qbman_alt_fq_state_desc {
- + u8 verb;
- + u8 reserved[3];
- + u32 fqid;
- + u8 reserved2[56];
- +};
- +
- +struct qbman_alt_fq_state_rslt {
- + u8 verb;
- + u8 rslt;
- + u8 reserved[62];
- +};
- +
- +#define ALT_FQ_FQID_MASK 0x00FFFFFF
- +
- +int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
- + u8 alt_fq_verb)
- +{
- + struct qbman_alt_fq_state_desc *p;
- + struct qbman_alt_fq_state_rslt *r;
- +
- + /* Start the management command */
- + p = qbman_swp_mc_start(s);
- + if (!p)
- + return -EBUSY;
- +
- + p->fqid = cpu_to_le32(fqid) & ALT_FQ_FQID_MASK;
- +
- + /* Complete the management command */
- + r = qbman_swp_mc_complete(s, p, alt_fq_verb);
- + if (unlikely(!r)) {
- + pr_err("qbman: mgmt cmd failed, no response (verb=0x%x)\n",
- + alt_fq_verb);
- + return -EIO;
- + }
- +
- + /* Decode the outcome */
- + WARN_ON((r->verb & QBMAN_RESULT_MASK) != alt_fq_verb);
- +
- + /* Determine success or failure */
- + if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("qbman: ALT FQID %d failed: verb = 0x%08x code = 0x%02x\n",
- + fqid, r->verb, r->rslt);
- + return -EIO;
- + }
- +
- + return 0;
- +}
- +
- +struct qbman_cdan_ctrl_desc {
- + u8 verb;
- + u8 reserved;
- + u16 ch;
- + u8 we;
- + u8 ctrl;
- + u16 reserved2;
- + u64 cdan_ctx;
- + u8 reserved3[48];
- +
- +};
- +
- +struct qbman_cdan_ctrl_rslt {
- + u8 verb;
- + u8 rslt;
- + u16 ch;
- + u8 reserved[60];
- +};
- +
- +int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid,
- + u8 we_mask, u8 cdan_en,
- + u64 ctx)
- +{
- + struct qbman_cdan_ctrl_desc *p = NULL;
- + struct qbman_cdan_ctrl_rslt *r = NULL;
- +
- + /* Start the management command */
- + p = qbman_swp_mc_start(s);
- + if (!p)
- + return -EBUSY;
- +
- + /* Encode the caller-provided attributes */
- + p->ch = cpu_to_le16(channelid);
- + p->we = we_mask;
- + if (cdan_en)
- + p->ctrl = 1;
- + else
- + p->ctrl = 0;
- + p->cdan_ctx = cpu_to_le64(ctx);
- +
- + /* Complete the management command */
- + r = qbman_swp_mc_complete(s, p, QBMAN_WQCHAN_CONFIGURE);
- + if (unlikely(!r)) {
- + pr_err("qbman: wqchan config failed, no response\n");
- + return -EIO;
- + }
- +
- + WARN_ON((r->verb & 0x7f) != QBMAN_WQCHAN_CONFIGURE);
- +
- + /* Determine success or failure */
- + if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("qbman: CDAN cQID %d failed: code = 0x%02x\n",
- + channelid, r->rslt);
- + return -EIO;
- + }
- +
- + return 0;
- +}
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h
- @@ -0,0 +1,662 @@
- +/*
- + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef __FSL_QBMAN_PORTAL_H
- +#define __FSL_QBMAN_PORTAL_H
- +
- +#include "qbman_private.h"
- +#include "../../include/dpaa2-fd.h"
- +
- +struct dpaa2_dq;
- +struct qbman_swp;
- +
- +/* qbman software portal descriptor structure */
- +struct qbman_swp_desc {
- + void *cena_bar; /* Cache-enabled portal base address */
- + void *cinh_bar; /* Cache-inhibited portal base address */
- + u32 qman_version;
- +};
- +
- +#define QBMAN_SWP_INTERRUPT_EQRI 0x01
- +#define QBMAN_SWP_INTERRUPT_EQDI 0x02
- +#define QBMAN_SWP_INTERRUPT_DQRI 0x04
- +#define QBMAN_SWP_INTERRUPT_RCRI 0x08
- +#define QBMAN_SWP_INTERRUPT_RCDI 0x10
- +#define QBMAN_SWP_INTERRUPT_VDCI 0x20
- +
- +/* the structure for pull dequeue descriptor */
- +struct qbman_pull_desc {
- + u8 verb;
- + u8 numf;
- + u8 tok;
- + u8 reserved;
- + u32 dq_src;
- + u64 rsp_addr;
- + u64 rsp_addr_virt;
- + u8 padding[40];
- +};
- +
- +enum qbman_pull_type_e {
- + /* dequeue with priority precedence, respect intra-class scheduling */
- + qbman_pull_type_prio = 1,
- + /* dequeue with active FQ precedence, respect ICS */
- + qbman_pull_type_active,
- + /* dequeue with active FQ precedence, no ICS */
- + qbman_pull_type_active_noics
- +};
- +
- +/* Definitions for parsing dequeue entries */
- +#define QBMAN_RESULT_MASK 0x7f
- +#define QBMAN_RESULT_DQ 0x60
- +#define QBMAN_RESULT_FQRN 0x21
- +#define QBMAN_RESULT_FQRNI 0x22
- +#define QBMAN_RESULT_FQPN 0x24
- +#define QBMAN_RESULT_FQDAN 0x25
- +#define QBMAN_RESULT_CDAN 0x26
- +#define QBMAN_RESULT_CSCN_MEM 0x27
- +#define QBMAN_RESULT_CGCU 0x28
- +#define QBMAN_RESULT_BPSCN 0x29
- +#define QBMAN_RESULT_CSCN_WQ 0x2a
- +
- +/* QBMan FQ management command codes */
- +#define QBMAN_FQ_SCHEDULE 0x48
- +#define QBMAN_FQ_FORCE 0x49
- +#define QBMAN_FQ_XON 0x4d
- +#define QBMAN_FQ_XOFF 0x4e
- +
- +/* structure of enqueue descriptor */
- +struct qbman_eq_desc {
- + u8 verb;
- + u8 dca;
- + u16 seqnum;
- + u16 orpid;
- + u16 reserved1;
- + u32 tgtid;
- + u32 tag;
- + u16 qdbin;
- + u8 qpri;
- + u8 reserved[3];
- + u8 wae;
- + u8 rspid;
- + u64 rsp_addr;
- + u8 fd[32];
- +};
- +
- +/* buffer release descriptor */
- +struct qbman_release_desc {
- + u8 verb;
- + u8 reserved;
- + u16 bpid;
- + u32 reserved2;
- + u64 buf[7];
- +};
- +
- +/* Management command result codes */
- +#define QBMAN_MC_RSLT_OK 0xf0
- +
- +#define CODE_CDAN_WE_EN 0x1
- +#define CODE_CDAN_WE_CTX 0x4
- +
- +/* portal data structure */
- +struct qbman_swp {
- + const struct qbman_swp_desc *desc;
- + void __iomem *addr_cena;
- + void __iomem *addr_cinh;
- +
- + /* Management commands */
- + struct {
- + u32 valid_bit; /* 0x00 or 0x80 */
- + } mc;
- +
- + /* Push dequeues */
- + u32 sdq;
- +
- + /* Volatile dequeues */
- + struct {
- + atomic_t available; /* indicates if a command can be sent */
- + u32 valid_bit; /* 0x00 or 0x80 */
- + struct dpaa2_dq *storage; /* NULL if DQRR */
- + } vdq;
- +
- + /* DQRR */
- + struct {
- + u32 next_idx;
- + u32 valid_bit;
- + u8 dqrr_size;
- + int reset_bug; /* indicates dqrr reset workaround is needed */
- + } dqrr;
- +};
- +
- +struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
- +void qbman_swp_finish(struct qbman_swp *p);
- +u32 qbman_swp_interrupt_read_status(struct qbman_swp *p);
- +void qbman_swp_interrupt_clear_status(struct qbman_swp *p, u32 mask);
- +u32 qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
- +void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, u32 mask);
- +int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
- +void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
- +
- +void qbman_swp_push_get(struct qbman_swp *p, u8 channel_idx, int *enabled);
- +void qbman_swp_push_set(struct qbman_swp *p, u8 channel_idx, int enable);
- +
- +void qbman_pull_desc_clear(struct qbman_pull_desc *d);
- +void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
- + struct dpaa2_dq *storage,
- + dma_addr_t storage_phys,
- + int stash);
- +void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, u8 numframes);
- +void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, u32 fqid);
- +void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid,
- + enum qbman_pull_type_e dct);
- +void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
- + enum qbman_pull_type_e dct);
- +
- +int qbman_swp_pull(struct qbman_swp *p, struct qbman_pull_desc *d);
- +
- +const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s);
- +void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq);
- +
- +int qbman_result_has_new_result(struct qbman_swp *p, const struct dpaa2_dq *dq);
- +
- +void qbman_eq_desc_clear(struct qbman_eq_desc *d);
- +void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
- +void qbman_eq_desc_set_token(struct qbman_eq_desc *d, u8 token);
- +void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid);
- +void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
- + u32 qd_bin, u32 qd_prio);
- +
- +int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d,
- + const struct dpaa2_fd *fd);
- +
- +void qbman_release_desc_clear(struct qbman_release_desc *d);
- +void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid);
- +void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
- +
- +int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
- + const u64 *buffers, unsigned int num_buffers);
- +int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
- + unsigned int num_buffers);
- +int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
- + u8 alt_fq_verb);
- +int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid,
- + u8 we_mask, u8 cdan_en,
- + u64 ctx);
- +
- +void *qbman_swp_mc_start(struct qbman_swp *p);
- +void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb);
- +void *qbman_swp_mc_result(struct qbman_swp *p);
- +
- +/**
- + * qbman_result_is_DQ() - check if the dequeue result is a dequeue response
- + * @dq: the dequeue result to be checked
- + *
- + * DQRR entries may contain non-dequeue results, ie. notifications
- + */
- +static inline int qbman_result_is_DQ(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_DQ);
- +}
- +
- +/**
- + * qbman_result_is_SCN() - Check the dequeue result is notification or not
- + * @dq: the dequeue result to be checked
- + *
- + */
- +static inline int qbman_result_is_SCN(const struct dpaa2_dq *dq)
- +{
- + return !qbman_result_is_DQ(dq);
- +}
- +
- +/* FQ Data Availability */
- +static inline int qbman_result_is_FQDAN(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQDAN);
- +}
- +
- +/* Channel Data Availability */
- +static inline int qbman_result_is_CDAN(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CDAN);
- +}
- +
- +/* Congestion State Change */
- +static inline int qbman_result_is_CSCN(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CSCN_WQ);
- +}
- +
- +/* Buffer Pool State Change */
- +static inline int qbman_result_is_BPSCN(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_BPSCN);
- +}
- +
- +/* Congestion Group Count Update */
- +static inline int qbman_result_is_CGCU(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CGCU);
- +}
- +
- +/* Retirement */
- +static inline int qbman_result_is_FQRN(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQRN);
- +}
- +
- +/* Retirement Immediate */
- +static inline int qbman_result_is_FQRNI(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQRNI);
- +}
- +
- + /* Park */
- +static inline int qbman_result_is_FQPN(const struct dpaa2_dq *dq)
- +{
- + return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQPN);
- +}
- +
- +/**
- + * qbman_result_SCN_state() - Get the state field in State-change notification
- + */
- +static inline u8 qbman_result_SCN_state(const struct dpaa2_dq *scn)
- +{
- + return scn->scn.state;
- +}
- +
- +#define SCN_RID_MASK 0x00FFFFFF
- +
- +/**
- + * qbman_result_SCN_rid() - Get the resource id in State-change notification
- + */
- +static inline u32 qbman_result_SCN_rid(const struct dpaa2_dq *scn)
- +{
- + return le32_to_cpu(scn->scn.rid_tok) & SCN_RID_MASK;
- +}
- +
- +/**
- + * qbman_result_SCN_ctx() - Get the context data in State-change notification
- + */
- +static inline u64 qbman_result_SCN_ctx(const struct dpaa2_dq *scn)
- +{
- + return le64_to_cpu(scn->scn.ctx);
- +}
- +
- +/**
- + * qbman_swp_fq_schedule() - Move the fq to the scheduled state
- + * @s: the software portal object
- + * @fqid: the index of frame queue to be scheduled
- + *
- + * There are a couple of different ways that a FQ can end up parked state,
- + * This schedules it.
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_fq_schedule(struct qbman_swp *s, u32 fqid)
- +{
- + return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
- +}
- +
- +/**
- + * qbman_swp_fq_force() - Force the FQ to fully scheduled state
- + * @s: the software portal object
- + * @fqid: the index of frame queue to be forced
- + *
- + * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
- + * and thus be available for selection by any channel-dequeuing behaviour (push
- + * or pull). If the FQ is subsequently "dequeued" from the channel and is still
- + * empty at the time this happens, the resulting dq_entry will have no FD.
- + * (qbman_result_DQ_fd() will return NULL.)
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_fq_force(struct qbman_swp *s, u32 fqid)
- +{
- + return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
- +}
- +
- +/**
- + * qbman_swp_fq_xon() - sets FQ flow-control to XON
- + * @s: the software portal object
- + * @fqid: the index of frame queue
- + *
- + * This setting doesn't affect enqueues to the FQ, just dequeues.
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_fq_xon(struct qbman_swp *s, u32 fqid)
- +{
- + return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
- +}
- +
- +/**
- + * qbman_swp_fq_xoff() - sets FQ flow-control to XOFF
- + * @s: the software portal object
- + * @fqid: the index of frame queue
- + *
- + * This setting doesn't affect enqueues to the FQ, just dequeues.
- + * XOFF FQs will remain in the tenatively-scheduled state, even when
- + * non-empty, meaning they won't be selected for scheduled dequeuing.
- + * If a FQ is changed to XOFF after it had already become truly-scheduled
- + * to a channel, and a pull dequeue of that channel occurs that selects
- + * that FQ for dequeuing, then the resulting dq_entry will have no FD.
- + * (qbman_result_DQ_fd() will return NULL.)
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_fq_xoff(struct qbman_swp *s, u32 fqid)
- +{
- + return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
- +}
- +
- +/* If the user has been allocated a channel object that is going to generate
- + * CDANs to another channel, then the qbman_swp_CDAN* functions will be
- + * necessary.
- + *
- + * CDAN-enabled channels only generate a single CDAN notification, after which
- + * they need to be reenabled before they'll generate another. The idea is
- + * that pull dequeuing will occur in reaction to the CDAN, followed by a
- + * reenable step. Each function generates a distinct command to hardware, so a
- + * combination function is provided if the user wishes to modify the "context"
- + * (which shows up in each CDAN message) each time they reenable, as a single
- + * command to hardware.
- + */
- +
- +/**
- + * qbman_swp_CDAN_set_context() - Set CDAN context
- + * @s: the software portal object
- + * @channelid: the channel index
- + * @ctx: the context to be set in CDAN
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_CDAN_set_context(struct qbman_swp *s, u16 channelid,
- + u64 ctx)
- +{
- + return qbman_swp_CDAN_set(s, channelid,
- + CODE_CDAN_WE_CTX,
- + 0, ctx);
- +}
- +
- +/**
- + * qbman_swp_CDAN_enable() - Enable CDAN for the channel
- + * @s: the software portal object
- + * @channelid: the index of the channel to generate CDAN
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_CDAN_enable(struct qbman_swp *s, u16 channelid)
- +{
- + return qbman_swp_CDAN_set(s, channelid,
- + CODE_CDAN_WE_EN,
- + 1, 0);
- +}
- +
- +/**
- + * qbman_swp_CDAN_disable() - disable CDAN for the channel
- + * @s: the software portal object
- + * @channelid: the index of the channel to generate CDAN
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_CDAN_disable(struct qbman_swp *s, u16 channelid)
- +{
- + return qbman_swp_CDAN_set(s, channelid,
- + CODE_CDAN_WE_EN,
- + 0, 0);
- +}
- +
- +/**
- + * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
- + * @s: the software portal object
- + * @channelid: the index of the channel to generate CDAN
- + * @ctx:i the context set in CDAN
- + *
- + * Return 0 for success, or negative error code for failure.
- + */
- +static inline int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s,
- + u16 channelid,
- + u64 ctx)
- +{
- + return qbman_swp_CDAN_set(s, channelid,
- + CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
- + 1, ctx);
- +}
- +
- +/* Wraps up submit + poll-for-result */
- +static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
- + u8 cmd_verb)
- +{
- + int loopvar = 1000;
- +
- + qbman_swp_mc_submit(swp, cmd, cmd_verb);
- +
- + do {
- + cmd = qbman_swp_mc_result(swp);
- + } while (!cmd && loopvar--);
- +
- + WARN_ON(!loopvar);
- +
- + return cmd;
- +}
- +
- +/* ------------ */
- +/* qb_attr_code */
- +/* ------------ */
- +
- +/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
- + * is either serving as a configuration command or a query result. The
- + * representation is inherently little-endian, as the indexing of the words is
- + * itself little-endian in nature and layerscape is little endian for anything
- + * that crosses a word boundary too (64-bit fields are the obvious examples).
- + */
- +struct qb_attr_code {
- + unsigned int word; /* which u32[] array member encodes the field */
- + unsigned int lsoffset; /* encoding offset from ls-bit */
- + unsigned int width; /* encoding width. (bool must be 1.) */
- +};
- +
- +/* Some pre-defined codes */
- +extern struct qb_attr_code code_generic_verb;
- +extern struct qb_attr_code code_generic_rslt;
- +
- +/* Macros to define codes */
- +#define QB_CODE(a, b, c) { a, b, c}
- +#define QB_CODE_NULL \
- + QB_CODE((unsigned int)-1, (unsigned int)-1, (unsigned int)-1)
- +
- +/* Rotate a code "ms", meaning that it moves from less-significant bytes to
- + * more-significant, from less-significant words to more-significant, etc. The
- + * "ls" version does the inverse, from more-significant towards
- + * less-significant.
- + */
- +static inline void qb_attr_code_rotate_ms(struct qb_attr_code *code,
- + unsigned int bits)
- +{
- + code->lsoffset += bits;
- + while (code->lsoffset > 31) {
- + code->word++;
- + code->lsoffset -= 32;
- + }
- +}
- +
- +static inline void qb_attr_code_rotate_ls(struct qb_attr_code *code,
- + unsigned int bits)
- +{
- + /* Don't be fooled, this trick should work because the types are
- + * unsigned. So the case that interests the while loop (the rotate has
- + * gone too far and the word count needs to compensate for it), is
- + * manifested when lsoffset is negative. But that equates to a really
- + * large unsigned value, starting with lots of "F"s. As such, we can
- + * continue adding 32 back to it until it wraps back round above zero,
- + * to a value of 31 or less...
- + */
- + code->lsoffset -= bits;
- + while (code->lsoffset > 31) {
- + code->word--;
- + code->lsoffset += 32;
- + }
- +}
- +
- +/* Implement a loop of code rotations until 'expr' evaluates to FALSE (0). */
- +#define qb_attr_code_for_ms(code, bits, expr) \
- + for (; expr; qb_attr_code_rotate_ms(code, bits))
- +#define qb_attr_code_for_ls(code, bits, expr) \
- + for (; expr; qb_attr_code_rotate_ls(code, bits))
- +
- +static inline void word_copy(void *d, const void *s, unsigned int cnt)
- +{
- + u32 *dd = d;
- + const u32 *ss = s;
- +
- + while (cnt--)
- + *(dd++) = *(ss++);
- +}
- +
- +/*
- + * Currently, the CENA support code expects each 32-bit word to be written in
- + * host order, and these are converted to hardware (little-endian) order on
- + * command submission. However, 64-bit quantities are must be written (and read)
- + * as two 32-bit words with the least-significant word first, irrespective of
- + * host endianness.
- + */
- +static inline void u64_to_le32_copy(void *d, const u64 *s,
- + unsigned int cnt)
- +{
- + u32 *dd = d;
- + const u32 *ss = (const u32 *)s;
- +
- + while (cnt--) {
- + /*
- + * TBD: the toolchain was choking on the use of 64-bit types up
- + * until recently so this works entirely with 32-bit variables.
- + * When 64-bit types become usable again, investigate better
- + * ways of doing this.
- + */
- +#if defined(__BIG_ENDIAN)
- + *(dd++) = ss[1];
- + *(dd++) = ss[0];
- + ss += 2;
- +#else
- + *(dd++) = *(ss++);
- + *(dd++) = *(ss++);
- +#endif
- + }
- +}
- +
- +static inline void u64_from_le32_copy(u64 *d, const void *s,
- + unsigned int cnt)
- +{
- + const u32 *ss = s;
- + u32 *dd = (u32 *)d;
- +
- + while (cnt--) {
- +#if defined(__BIG_ENDIAN)
- + dd[1] = *(ss++);
- + dd[0] = *(ss++);
- + dd += 2;
- +#else
- + *(dd++) = *(ss++);
- + *(dd++) = *(ss++);
- +#endif
- + }
- +}
- +
- +/* decode a field from a cacheline */
- +static inline u32 qb_attr_code_decode(const struct qb_attr_code *code,
- + const u32 *cacheline)
- +{
- + return d32_u32(code->lsoffset, code->width, cacheline[code->word]);
- +}
- +
- +static inline u64 qb_attr_code_decode_64(const struct qb_attr_code *code,
- + const u64 *cacheline)
- +{
- + u64 res;
- +
- + u64_from_le32_copy(&res, &cacheline[code->word / 2], 1);
- + return res;
- +}
- +
- +/* encode a field to a cacheline */
- +static inline void qb_attr_code_encode(const struct qb_attr_code *code,
- + u32 *cacheline, u32 val)
- +{
- + cacheline[code->word] =
- + r32_u32(code->lsoffset, code->width, cacheline[code->word])
- + | e32_u32(code->lsoffset, code->width, val);
- +}
- +
- +static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
- + u64 *cacheline, u64 val)
- +{
- + u64_to_le32_copy(&cacheline[code->word / 2], &val, 1);
- +}
- +
- +/* Small-width signed values (two's-complement) will decode into medium-width
- + * positives. (Eg. for an 8-bit signed field, which stores values from -128 to
- + * +127, a setting of -7 would appear to decode to the 32-bit unsigned value
- + * 249. Likewise -120 would decode as 136.) This function allows the caller to
- + * "re-sign" such fields to 32-bit signed. (Eg. -7, which was 249 with an 8-bit
- + * encoding, will become 0xfffffff9 if you cast the return value to u32).
- + */
- +static inline int32_t qb_attr_code_makesigned(const struct qb_attr_code *code,
- + u32 val)
- +{
- + WARN_ON(val >= (1 << code->width));
- + /* If the high bit was set, it was encoding a negative */
- + if (val >= (1 << (code->width - 1)))
- + return (int32_t)0 - (int32_t)(((u32)1 << code->width) -
- + val);
- + /* Otherwise, it was encoding a positive */
- + return (int32_t)val;
- +}
- +
- +/* ---------------------- */
- +/* Descriptors/cachelines */
- +/* ---------------------- */
- +
- +/* To avoid needless dynamic allocation, the driver API often gives the caller
- + * a "descriptor" type that the caller can instantiate however they like.
- + * Ultimately though, it is just a cacheline of binary storage (or something
- + * smaller when it is known that the descriptor doesn't need all 64 bytes) for
- + * holding pre-formatted pieces of hardware commands. The performance-critical
- + * code can then copy these descriptors directly into hardware command
- + * registers more efficiently than trying to construct/format commands
- + * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
- + * order for the compiler to know its size, but the internal details are not
- + * exposed. The following macro is used within the driver for converting *any*
- + * descriptor pointer to a usable array pointer. The use of a macro (instead of
- + * an inline) is necessary to work with different descriptor types and to work
- + * correctly with const and non-const inputs (and similarly-qualified outputs).
- + */
- +#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
- +
- +#endif /* __FSL_QBMAN_PORTAL_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/qbman_debug.c
- @@ -0,0 +1,853 @@
- +/* Copyright (C) 2015 Freescale Semiconductor, Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +#include <linux/errno.h>
- +
- +#include "../../include/dpaa2-global.h"
- +#include "qbman-portal.h"
- +#include "qbman_debug.h"
- +
- +/* QBMan portal management command code */
- +#define QBMAN_BP_QUERY 0x32
- +#define QBMAN_FQ_QUERY 0x44
- +#define QBMAN_FQ_QUERY_NP 0x45
- +#define QBMAN_CGR_QUERY 0x51
- +#define QBMAN_WRED_QUERY 0x54
- +#define QBMAN_CGR_STAT_QUERY 0x55
- +#define QBMAN_CGR_STAT_QUERY_CLR 0x56
- +
- +enum qbman_attr_usage_e {
- + qbman_attr_usage_fq,
- + qbman_attr_usage_bpool,
- + qbman_attr_usage_cgr,
- +};
- +
- +struct int_qbman_attr {
- + u32 words[32];
- + enum qbman_attr_usage_e usage;
- +};
- +
- +#define attr_type_set(a, e) \
- +{ \
- + struct qbman_attr *__attr = a; \
- + enum qbman_attr_usage_e __usage = e; \
- + ((struct int_qbman_attr *)__attr)->usage = __usage; \
- +}
- +
- +#define ATTR32(d) (&(d)->dont_manipulate_directly[0])
- +#define ATTR32_1(d) (&(d)->dont_manipulate_directly[16])
- +
- +static struct qb_attr_code code_bp_bpid = QB_CODE(0, 16, 16);
- +static struct qb_attr_code code_bp_bdi = QB_CODE(1, 16, 1);
- +static struct qb_attr_code code_bp_va = QB_CODE(1, 17, 1);
- +static struct qb_attr_code code_bp_wae = QB_CODE(1, 18, 1);
- +static struct qb_attr_code code_bp_swdet = QB_CODE(4, 0, 16);
- +static struct qb_attr_code code_bp_swdxt = QB_CODE(4, 16, 16);
- +static struct qb_attr_code code_bp_hwdet = QB_CODE(5, 0, 16);
- +static struct qb_attr_code code_bp_hwdxt = QB_CODE(5, 16, 16);
- +static struct qb_attr_code code_bp_swset = QB_CODE(6, 0, 16);
- +static struct qb_attr_code code_bp_swsxt = QB_CODE(6, 16, 16);
- +static struct qb_attr_code code_bp_vbpid = QB_CODE(7, 0, 14);
- +static struct qb_attr_code code_bp_icid = QB_CODE(7, 16, 15);
- +static struct qb_attr_code code_bp_pl = QB_CODE(7, 31, 1);
- +static struct qb_attr_code code_bp_bpscn_addr_lo = QB_CODE(8, 0, 32);
- +static struct qb_attr_code code_bp_bpscn_addr_hi = QB_CODE(9, 0, 32);
- +static struct qb_attr_code code_bp_bpscn_ctx_lo = QB_CODE(10, 0, 32);
- +static struct qb_attr_code code_bp_bpscn_ctx_hi = QB_CODE(11, 0, 32);
- +static struct qb_attr_code code_bp_hw_targ = QB_CODE(12, 0, 16);
- +static struct qb_attr_code code_bp_state = QB_CODE(1, 24, 3);
- +static struct qb_attr_code code_bp_fill = QB_CODE(2, 0, 32);
- +static struct qb_attr_code code_bp_hdptr = QB_CODE(3, 0, 32);
- +static struct qb_attr_code code_bp_sdcnt = QB_CODE(13, 0, 8);
- +static struct qb_attr_code code_bp_hdcnt = QB_CODE(13, 1, 8);
- +static struct qb_attr_code code_bp_sscnt = QB_CODE(13, 2, 8);
- +
- +void qbman_bp_attr_clear(struct qbman_attr *a)
- +{
- + memset(a, 0, sizeof(*a));
- + attr_type_set(a, qbman_attr_usage_bpool);
- +}
- +
- +int qbman_bp_query(struct qbman_swp *s, u32 bpid,
- + struct qbman_attr *a)
- +{
- + u32 *p;
- + u32 verb, rslt;
- + u32 *attr = ATTR32(a);
- +
- + qbman_bp_attr_clear(a);
- +
- + /* Start the management command */
- + p = qbman_swp_mc_start(s);
- + if (!p)
- + return -EBUSY;
- +
- + /* Encode the caller-provided attributes */
- + qb_attr_code_encode(&code_bp_bpid, p, bpid);
- +
- + /* Complete the management command */
- + p = qbman_swp_mc_complete(s, p, QBMAN_BP_QUERY);
- +
- + /* Decode the outcome */
- + verb = qb_attr_code_decode(&code_generic_verb, p);
- + rslt = qb_attr_code_decode(&code_generic_rslt, p);
- + WARN_ON(verb != QBMAN_BP_QUERY);
- +
- + /* Determine success or failure */
- + if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("Query of BPID 0x%x failed, code=0x%02x\n", bpid, rslt);
- + return -EIO;
- + }
- +
- + /* For the query, word[0] of the result contains only the
- + * verb/rslt fields, so skip word[0].
- + */
- + word_copy(&attr[1], &p[1], 15);
- + return 0;
- +}
- +
- +void qbman_bp_attr_get_bdi(struct qbman_attr *a, int *bdi, int *va, int *wae)
- +{
- + u32 *p = ATTR32(a);
- +
- + *bdi = !!qb_attr_code_decode(&code_bp_bdi, p);
- + *va = !!qb_attr_code_decode(&code_bp_va, p);
- + *wae = !!qb_attr_code_decode(&code_bp_wae, p);
- +}
- +
- +static u32 qbman_bp_thresh_to_value(u32 val)
- +{
- + return (val & 0xff) << ((val & 0xf00) >> 8);
- +}
- +
- +void qbman_bp_attr_get_swdet(struct qbman_attr *a, u32 *swdet)
- +{
- + u32 *p = ATTR32(a);
- +
- + *swdet = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swdet,
- + p));
- +}
- +
- +void qbman_bp_attr_get_swdxt(struct qbman_attr *a, u32 *swdxt)
- +{
- + u32 *p = ATTR32(a);
- +
- + *swdxt = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swdxt,
- + p));
- +}
- +
- +void qbman_bp_attr_get_hwdet(struct qbman_attr *a, u32 *hwdet)
- +{
- + u32 *p = ATTR32(a);
- +
- + *hwdet = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_hwdet,
- + p));
- +}
- +
- +void qbman_bp_attr_get_hwdxt(struct qbman_attr *a, u32 *hwdxt)
- +{
- + u32 *p = ATTR32(a);
- +
- + *hwdxt = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_hwdxt,
- + p));
- +}
- +
- +void qbman_bp_attr_get_swset(struct qbman_attr *a, u32 *swset)
- +{
- + u32 *p = ATTR32(a);
- +
- + *swset = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swset,
- + p));
- +}
- +
- +void qbman_bp_attr_get_swsxt(struct qbman_attr *a, u32 *swsxt)
- +{
- + u32 *p = ATTR32(a);
- +
- + *swsxt = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swsxt,
- + p));
- +}
- +
- +void qbman_bp_attr_get_vbpid(struct qbman_attr *a, u32 *vbpid)
- +{
- + u32 *p = ATTR32(a);
- +
- + *vbpid = qb_attr_code_decode(&code_bp_vbpid, p);
- +}
- +
- +void qbman_bp_attr_get_icid(struct qbman_attr *a, u32 *icid, int *pl)
- +{
- + u32 *p = ATTR32(a);
- +
- + *icid = qb_attr_code_decode(&code_bp_icid, p);
- + *pl = !!qb_attr_code_decode(&code_bp_pl, p);
- +}
- +
- +void qbman_bp_attr_get_bpscn_addr(struct qbman_attr *a, u64 *bpscn_addr)
- +{
- + u32 *p = ATTR32(a);
- +
- + *bpscn_addr = ((u64)qb_attr_code_decode(&code_bp_bpscn_addr_hi,
- + p) << 32) |
- + (u64)qb_attr_code_decode(&code_bp_bpscn_addr_lo,
- + p);
- +}
- +
- +void qbman_bp_attr_get_bpscn_ctx(struct qbman_attr *a, u64 *bpscn_ctx)
- +{
- + u32 *p = ATTR32(a);
- +
- + *bpscn_ctx = ((u64)qb_attr_code_decode(&code_bp_bpscn_ctx_hi, p)
- + << 32) |
- + (u64)qb_attr_code_decode(&code_bp_bpscn_ctx_lo,
- + p);
- +}
- +
- +void qbman_bp_attr_get_hw_targ(struct qbman_attr *a, u32 *hw_targ)
- +{
- + u32 *p = ATTR32(a);
- +
- + *hw_targ = qb_attr_code_decode(&code_bp_hw_targ, p);
- +}
- +
- +int qbman_bp_info_has_free_bufs(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return !(int)(qb_attr_code_decode(&code_bp_state, p) & 0x1);
- +}
- +
- +int qbman_bp_info_is_depleted(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return (int)(qb_attr_code_decode(&code_bp_state, p) & 0x2);
- +}
- +
- +int qbman_bp_info_is_surplus(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return (int)(qb_attr_code_decode(&code_bp_state, p) & 0x4);
- +}
- +
- +u32 qbman_bp_info_num_free_bufs(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return qb_attr_code_decode(&code_bp_fill, p);
- +}
- +
- +u32 qbman_bp_info_hdptr(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return qb_attr_code_decode(&code_bp_hdptr, p);
- +}
- +
- +u32 qbman_bp_info_sdcnt(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return qb_attr_code_decode(&code_bp_sdcnt, p);
- +}
- +
- +u32 qbman_bp_info_hdcnt(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return qb_attr_code_decode(&code_bp_hdcnt, p);
- +}
- +
- +u32 qbman_bp_info_sscnt(struct qbman_attr *a)
- +{
- + u32 *p = ATTR32(a);
- +
- + return qb_attr_code_decode(&code_bp_sscnt, p);
- +}
- +
- +static struct qb_attr_code code_fq_fqid = QB_CODE(1, 0, 24);
- +static struct qb_attr_code code_fq_cgrid = QB_CODE(2, 16, 16);
- +static struct qb_attr_code code_fq_destwq = QB_CODE(3, 0, 15);
- +static struct qb_attr_code code_fq_fqctrl = QB_CODE(3, 24, 8);
- +static struct qb_attr_code code_fq_icscred = QB_CODE(4, 0, 15);
- +static struct qb_attr_code code_fq_tdthresh = QB_CODE(4, 16, 13);
- +static struct qb_attr_code code_fq_oa_len = QB_CODE(5, 0, 12);
- +static struct qb_attr_code code_fq_oa_ics = QB_CODE(5, 14, 1);
- +static struct qb_attr_code code_fq_oa_cgr = QB_CODE(5, 15, 1);
- +static struct qb_attr_code code_fq_mctl_bdi = QB_CODE(5, 24, 1);
- +static struct qb_attr_code code_fq_mctl_ff = QB_CODE(5, 25, 1);
- +static struct qb_attr_code code_fq_mctl_va = QB_CODE(5, 26, 1);
- +static struct qb_attr_code code_fq_mctl_ps = QB_CODE(5, 27, 1);
- +static struct qb_attr_code code_fq_ctx_lower32 = QB_CODE(6, 0, 32);
- +static struct qb_attr_code code_fq_ctx_upper32 = QB_CODE(7, 0, 32);
- +static struct qb_attr_code code_fq_icid = QB_CODE(8, 0, 15);
- +static struct qb_attr_code code_fq_pl = QB_CODE(8, 15, 1);
- +static struct qb_attr_code code_fq_vfqid = QB_CODE(9, 0, 24);
- +static struct qb_attr_code code_fq_erfqid = QB_CODE(10, 0, 24);
- +
- +void qbman_fq_attr_clear(struct qbman_attr *a)
- +{
- + memset(a, 0, sizeof(*a));
- + attr_type_set(a, qbman_attr_usage_fq);
- +}
- +
- +/* FQ query function for programmable fields */
- +int qbman_fq_query(struct qbman_swp *s, u32 fqid, struct qbman_attr *desc)
- +{
- + u32 *p;
- + u32 verb, rslt;
- + u32 *d = ATTR32(desc);
- +
- + qbman_fq_attr_clear(desc);
- +
- + p = qbman_swp_mc_start(s);
- + if (!p)
- + return -EBUSY;
- + qb_attr_code_encode(&code_fq_fqid, p, fqid);
- + p = qbman_swp_mc_complete(s, p, QBMAN_FQ_QUERY);
- +
- + /* Decode the outcome */
- + verb = qb_attr_code_decode(&code_generic_verb, p);
- + rslt = qb_attr_code_decode(&code_generic_rslt, p);
- + WARN_ON(verb != QBMAN_FQ_QUERY);
- +
- + /* Determine success or failure */
- + if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("Query of FQID 0x%x failed, code=0x%02x\n",
- + fqid, rslt);
- + return -EIO;
- + }
- + /*
- + * For the configure, word[0] of the command contains only the WE-mask.
- + * For the query, word[0] of the result contains only the verb/rslt
- + * fields. Skip word[0] in the latter case.
- + */
- + word_copy(&d[1], &p[1], 15);
- + return 0;
- +}
- +
- +void qbman_fq_attr_get_fqctrl(struct qbman_attr *d, u32 *fqctrl)
- +{
- + u32 *p = ATTR32(d);
- +
- + *fqctrl = qb_attr_code_decode(&code_fq_fqctrl, p);
- +}
- +
- +void qbman_fq_attr_get_cgrid(struct qbman_attr *d, u32 *cgrid)
- +{
- + u32 *p = ATTR32(d);
- +
- + *cgrid = qb_attr_code_decode(&code_fq_cgrid, p);
- +}
- +
- +void qbman_fq_attr_get_destwq(struct qbman_attr *d, u32 *destwq)
- +{
- + u32 *p = ATTR32(d);
- +
- + *destwq = qb_attr_code_decode(&code_fq_destwq, p);
- +}
- +
- +void qbman_fq_attr_get_icscred(struct qbman_attr *d, u32 *icscred)
- +{
- + u32 *p = ATTR32(d);
- +
- + *icscred = qb_attr_code_decode(&code_fq_icscred, p);
- +}
- +
- +static struct qb_attr_code code_tdthresh_exp = QB_CODE(0, 0, 5);
- +static struct qb_attr_code code_tdthresh_mant = QB_CODE(0, 5, 8);
- +static u32 qbman_thresh_to_value(u32 val)
- +{
- + u32 m, e;
- +
- + m = qb_attr_code_decode(&code_tdthresh_mant, &val);
- + e = qb_attr_code_decode(&code_tdthresh_exp, &val);
- + return m << e;
- +}
- +
- +void qbman_fq_attr_get_tdthresh(struct qbman_attr *d, u32 *tdthresh)
- +{
- + u32 *p = ATTR32(d);
- +
- + *tdthresh = qbman_thresh_to_value(qb_attr_code_decode(&code_fq_tdthresh,
- + p));
- +}
- +
- +void qbman_fq_attr_get_oa(struct qbman_attr *d,
- + int *oa_ics, int *oa_cgr, int32_t *oa_len)
- +{
- + u32 *p = ATTR32(d);
- +
- + *oa_ics = !!qb_attr_code_decode(&code_fq_oa_ics, p);
- + *oa_cgr = !!qb_attr_code_decode(&code_fq_oa_cgr, p);
- + *oa_len = qb_attr_code_makesigned(&code_fq_oa_len,
- + qb_attr_code_decode(&code_fq_oa_len, p));
- +}
- +
- +void qbman_fq_attr_get_mctl(struct qbman_attr *d,
- + int *bdi, int *ff, int *va, int *ps)
- +{
- + u32 *p = ATTR32(d);
- +
- + *bdi = !!qb_attr_code_decode(&code_fq_mctl_bdi, p);
- + *ff = !!qb_attr_code_decode(&code_fq_mctl_ff, p);
- + *va = !!qb_attr_code_decode(&code_fq_mctl_va, p);
- + *ps = !!qb_attr_code_decode(&code_fq_mctl_ps, p);
- +}
- +
- +void qbman_fq_attr_get_ctx(struct qbman_attr *d, u32 *hi, u32 *lo)
- +{
- + u32 *p = ATTR32(d);
- +
- + *hi = qb_attr_code_decode(&code_fq_ctx_upper32, p);
- + *lo = qb_attr_code_decode(&code_fq_ctx_lower32, p);
- +}
- +
- +void qbman_fq_attr_get_icid(struct qbman_attr *d, u32 *icid, int *pl)
- +{
- + u32 *p = ATTR32(d);
- +
- + *icid = qb_attr_code_decode(&code_fq_icid, p);
- + *pl = !!qb_attr_code_decode(&code_fq_pl, p);
- +}
- +
- +void qbman_fq_attr_get_vfqid(struct qbman_attr *d, u32 *vfqid)
- +{
- + u32 *p = ATTR32(d);
- +
- + *vfqid = qb_attr_code_decode(&code_fq_vfqid, p);
- +}
- +
- +void qbman_fq_attr_get_erfqid(struct qbman_attr *d, u32 *erfqid)
- +{
- + u32 *p = ATTR32(d);
- +
- + *erfqid = qb_attr_code_decode(&code_fq_erfqid, p);
- +}
- +
- +/* Query FQ Non-Programmalbe Fields */
- +static struct qb_attr_code code_fq_np_state = QB_CODE(0, 16, 3);
- +static struct qb_attr_code code_fq_np_fe = QB_CODE(0, 19, 1);
- +static struct qb_attr_code code_fq_np_x = QB_CODE(0, 20, 1);
- +static struct qb_attr_code code_fq_np_r = QB_CODE(0, 21, 1);
- +static struct qb_attr_code code_fq_np_oe = QB_CODE(0, 22, 1);
- +static struct qb_attr_code code_fq_np_frm_cnt = QB_CODE(6, 0, 24);
- +static struct qb_attr_code code_fq_np_byte_cnt = QB_CODE(7, 0, 32);
- +
- +int qbman_fq_query_state(struct qbman_swp *s, u32 fqid,
- + struct qbman_attr *state)
- +{
- + u32 *p;
- + u32 verb, rslt;
- + u32 *d = ATTR32(state);
- +
- + qbman_fq_attr_clear(state);
- +
- + p = qbman_swp_mc_start(s);
- + if (!p)
- + return -EBUSY;
- + qb_attr_code_encode(&code_fq_fqid, p, fqid);
- + p = qbman_swp_mc_complete(s, p, QBMAN_FQ_QUERY_NP);
- +
- + /* Decode the outcome */
- + verb = qb_attr_code_decode(&code_generic_verb, p);
- + rslt = qb_attr_code_decode(&code_generic_rslt, p);
- + WARN_ON(verb != QBMAN_FQ_QUERY_NP);
- +
- + /* Determine success or failure */
- + if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("Query NP fields of FQID 0x%x failed, code=0x%02x\n",
- + fqid, rslt);
- + return -EIO;
- + }
- + word_copy(&d[0], &p[0], 16);
- + return 0;
- +}
- +
- +u32 qbman_fq_state_schedstate(const struct qbman_attr *state)
- +{
- + const u32 *p = ATTR32(state);
- +
- + return qb_attr_code_decode(&code_fq_np_state, p);
- +}
- +
- +int qbman_fq_state_force_eligible(const struct qbman_attr *state)
- +{
- + const u32 *p = ATTR32(state);
- +
- + return !!qb_attr_code_decode(&code_fq_np_fe, p);
- +}
- +
- +int qbman_fq_state_xoff(const struct qbman_attr *state)
- +{
- + const u32 *p = ATTR32(state);
- +
- + return !!qb_attr_code_decode(&code_fq_np_x, p);
- +}
- +
- +int qbman_fq_state_retirement_pending(const struct qbman_attr *state)
- +{
- + const u32 *p = ATTR32(state);
- +
- + return !!qb_attr_code_decode(&code_fq_np_r, p);
- +}
- +
- +int qbman_fq_state_overflow_error(const struct qbman_attr *state)
- +{
- + const u32 *p = ATTR32(state);
- +
- + return !!qb_attr_code_decode(&code_fq_np_oe, p);
- +}
- +
- +u32 qbman_fq_state_frame_count(const struct qbman_attr *state)
- +{
- + const u32 *p = ATTR32(state);
- +
- + return qb_attr_code_decode(&code_fq_np_frm_cnt, p);
- +}
- +
- +u32 qbman_fq_state_byte_count(const struct qbman_attr *state)
- +{
- + const u32 *p = ATTR32(state);
- +
- + return qb_attr_code_decode(&code_fq_np_byte_cnt, p);
- +}
- +
- +/* Query CGR */
- +static struct qb_attr_code code_cgr_cgid = QB_CODE(0, 16, 16);
- +static struct qb_attr_code code_cgr_cscn_wq_en_enter = QB_CODE(2, 0, 1);
- +static struct qb_attr_code code_cgr_cscn_wq_en_exit = QB_CODE(2, 1, 1);
- +static struct qb_attr_code code_cgr_cscn_wq_icd = QB_CODE(2, 2, 1);
- +static struct qb_attr_code code_cgr_mode = QB_CODE(3, 16, 2);
- +static struct qb_attr_code code_cgr_rej_cnt_mode = QB_CODE(3, 18, 1);
- +static struct qb_attr_code code_cgr_cscn_bdi = QB_CODE(3, 19, 1);
- +static struct qb_attr_code code_cgr_cscn_wr_en_enter = QB_CODE(3, 24, 1);
- +static struct qb_attr_code code_cgr_cscn_wr_en_exit = QB_CODE(3, 25, 1);
- +static struct qb_attr_code code_cgr_cg_wr_ae = QB_CODE(3, 26, 1);
- +static struct qb_attr_code code_cgr_cscn_dcp_en = QB_CODE(3, 27, 1);
- +static struct qb_attr_code code_cgr_cg_wr_va = QB_CODE(3, 28, 1);
- +static struct qb_attr_code code_cgr_i_cnt_wr_en = QB_CODE(4, 0, 1);
- +static struct qb_attr_code code_cgr_i_cnt_wr_bnd = QB_CODE(4, 1, 5);
- +static struct qb_attr_code code_cgr_td_en = QB_CODE(4, 8, 1);
- +static struct qb_attr_code code_cgr_cs_thres = QB_CODE(4, 16, 13);
- +static struct qb_attr_code code_cgr_cs_thres_x = QB_CODE(5, 0, 13);
- +static struct qb_attr_code code_cgr_td_thres = QB_CODE(5, 16, 13);
- +static struct qb_attr_code code_cgr_cscn_tdcp = QB_CODE(6, 0, 16);
- +static struct qb_attr_code code_cgr_cscn_wqid = QB_CODE(6, 16, 16);
- +static struct qb_attr_code code_cgr_cscn_vcgid = QB_CODE(7, 0, 16);
- +static struct qb_attr_code code_cgr_cg_icid = QB_CODE(7, 16, 15);
- +static struct qb_attr_code code_cgr_cg_pl = QB_CODE(7, 31, 1);
- +static struct qb_attr_code code_cgr_cg_wr_addr_lo = QB_CODE(8, 0, 32);
- +static struct qb_attr_code code_cgr_cg_wr_addr_hi = QB_CODE(9, 0, 32);
- +static struct qb_attr_code code_cgr_cscn_ctx_lo = QB_CODE(10, 0, 32);
- +static struct qb_attr_code code_cgr_cscn_ctx_hi = QB_CODE(11, 0, 32);
- +
- +void qbman_cgr_attr_clear(struct qbman_attr *a)
- +{
- + memset(a, 0, sizeof(*a));
- + attr_type_set(a, qbman_attr_usage_cgr);
- +}
- +
- +int qbman_cgr_query(struct qbman_swp *s, u32 cgid, struct qbman_attr *attr)
- +{
- + u32 *p;
- + u32 verb, rslt;
- + u32 *d[2];
- + int i;
- + u32 query_verb;
- +
- + d[0] = ATTR32(attr);
- + d[1] = ATTR32_1(attr);
- +
- + qbman_cgr_attr_clear(attr);
- +
- + for (i = 0; i < 2; i++) {
- + p = qbman_swp_mc_start(s);
- + if (!p)
- + return -EBUSY;
- + query_verb = i ? QBMAN_WRED_QUERY : QBMAN_CGR_QUERY;
- +
- + qb_attr_code_encode(&code_cgr_cgid, p, cgid);
- + p = qbman_swp_mc_complete(s, p, p[0] | query_verb);
- +
- + /* Decode the outcome */
- + verb = qb_attr_code_decode(&code_generic_verb, p);
- + rslt = qb_attr_code_decode(&code_generic_rslt, p);
- + WARN_ON(verb != query_verb);
- +
- + /* Determine success or failure */
- + if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("Query CGID 0x%x failed,", cgid);
- + pr_err(" verb=0x%02x, code=0x%02x\n", verb, rslt);
- + return -EIO;
- + }
- + /* For the configure, word[0] of the command contains only the
- + * verb/cgid. For the query, word[0] of the result contains
- + * only the verb/rslt fields. Skip word[0] in the latter case.
- + */
- + word_copy(&d[i][1], &p[1], 15);
- + }
- + return 0;
- +}
- +
- +void qbman_cgr_attr_get_ctl1(struct qbman_attr *d, int *cscn_wq_en_enter,
- + int *cscn_wq_en_exit, int *cscn_wq_icd)
- + {
- + u32 *p = ATTR32(d);
- + *cscn_wq_en_enter = !!qb_attr_code_decode(&code_cgr_cscn_wq_en_enter,
- + p);
- + *cscn_wq_en_exit = !!qb_attr_code_decode(&code_cgr_cscn_wq_en_exit, p);
- + *cscn_wq_icd = !!qb_attr_code_decode(&code_cgr_cscn_wq_icd, p);
- +}
- +
- +void qbman_cgr_attr_get_mode(struct qbman_attr *d, u32 *mode,
- + int *rej_cnt_mode, int *cscn_bdi)
- +{
- + u32 *p = ATTR32(d);
- + *mode = qb_attr_code_decode(&code_cgr_mode, p);
- + *rej_cnt_mode = !!qb_attr_code_decode(&code_cgr_rej_cnt_mode, p);
- + *cscn_bdi = !!qb_attr_code_decode(&code_cgr_cscn_bdi, p);
- +}
- +
- +void qbman_cgr_attr_get_ctl2(struct qbman_attr *d, int *cscn_wr_en_enter,
- + int *cscn_wr_en_exit, int *cg_wr_ae,
- + int *cscn_dcp_en, int *cg_wr_va)
- +{
- + u32 *p = ATTR32(d);
- + *cscn_wr_en_enter = !!qb_attr_code_decode(&code_cgr_cscn_wr_en_enter,
- + p);
- + *cscn_wr_en_exit = !!qb_attr_code_decode(&code_cgr_cscn_wr_en_exit, p);
- + *cg_wr_ae = !!qb_attr_code_decode(&code_cgr_cg_wr_ae, p);
- + *cscn_dcp_en = !!qb_attr_code_decode(&code_cgr_cscn_dcp_en, p);
- + *cg_wr_va = !!qb_attr_code_decode(&code_cgr_cg_wr_va, p);
- +}
- +
- +void qbman_cgr_attr_get_iwc(struct qbman_attr *d, int *i_cnt_wr_en,
- + u32 *i_cnt_wr_bnd)
- +{
- + u32 *p = ATTR32(d);
- + *i_cnt_wr_en = !!qb_attr_code_decode(&code_cgr_i_cnt_wr_en, p);
- + *i_cnt_wr_bnd = qb_attr_code_decode(&code_cgr_i_cnt_wr_bnd, p);
- +}
- +
- +void qbman_cgr_attr_get_tdc(struct qbman_attr *d, int *td_en)
- +{
- + u32 *p = ATTR32(d);
- + *td_en = !!qb_attr_code_decode(&code_cgr_td_en, p);
- +}
- +
- +void qbman_cgr_attr_get_cs_thres(struct qbman_attr *d, u32 *cs_thres)
- +{
- + u32 *p = ATTR32(d);
- + *cs_thres = qbman_thresh_to_value(qb_attr_code_decode(
- + &code_cgr_cs_thres, p));
- +}
- +
- +void qbman_cgr_attr_get_cs_thres_x(struct qbman_attr *d,
- + u32 *cs_thres_x)
- +{
- + u32 *p = ATTR32(d);
- + *cs_thres_x = qbman_thresh_to_value(qb_attr_code_decode(
- + &code_cgr_cs_thres_x, p));
- +}
- +
- +void qbman_cgr_attr_get_td_thres(struct qbman_attr *d, u32 *td_thres)
- +{
- + u32 *p = ATTR32(d);
- + *td_thres = qbman_thresh_to_value(qb_attr_code_decode(
- + &code_cgr_td_thres, p));
- +}
- +
- +void qbman_cgr_attr_get_cscn_tdcp(struct qbman_attr *d, u32 *cscn_tdcp)
- +{
- + u32 *p = ATTR32(d);
- + *cscn_tdcp = qb_attr_code_decode(&code_cgr_cscn_tdcp, p);
- +}
- +
- +void qbman_cgr_attr_get_cscn_wqid(struct qbman_attr *d, u32 *cscn_wqid)
- +{
- + u32 *p = ATTR32(d);
- + *cscn_wqid = qb_attr_code_decode(&code_cgr_cscn_wqid, p);
- +}
- +
- +void qbman_cgr_attr_get_cscn_vcgid(struct qbman_attr *d,
- + u32 *cscn_vcgid)
- +{
- + u32 *p = ATTR32(d);
- + *cscn_vcgid = qb_attr_code_decode(&code_cgr_cscn_vcgid, p);
- +}
- +
- +void qbman_cgr_attr_get_cg_icid(struct qbman_attr *d, u32 *icid,
- + int *pl)
- +{
- + u32 *p = ATTR32(d);
- + *icid = qb_attr_code_decode(&code_cgr_cg_icid, p);
- + *pl = !!qb_attr_code_decode(&code_cgr_cg_pl, p);
- +}
- +
- +void qbman_cgr_attr_get_cg_wr_addr(struct qbman_attr *d,
- + u64 *cg_wr_addr)
- +{
- + u32 *p = ATTR32(d);
- + *cg_wr_addr = ((u64)qb_attr_code_decode(&code_cgr_cg_wr_addr_hi,
- + p) << 32) |
- + (u64)qb_attr_code_decode(&code_cgr_cg_wr_addr_lo,
- + p);
- +}
- +
- +void qbman_cgr_attr_get_cscn_ctx(struct qbman_attr *d, u64 *cscn_ctx)
- +{
- + u32 *p = ATTR32(d);
- + *cscn_ctx = ((u64)qb_attr_code_decode(&code_cgr_cscn_ctx_hi, p)
- + << 32) |
- + (u64)qb_attr_code_decode(&code_cgr_cscn_ctx_lo, p);
- +}
- +
- +#define WRED_EDP_WORD(n) (18 + (n) / 4)
- +#define WRED_EDP_OFFSET(n) (8 * ((n) % 4))
- +#define WRED_PARM_DP_WORD(n) ((n) + 20)
- +#define WRED_WE_EDP(n) (16 + (n) * 2)
- +#define WRED_WE_PARM_DP(n) (17 + (n) * 2)
- +void qbman_cgr_attr_wred_get_edp(struct qbman_attr *d, u32 idx,
- + int *edp)
- +{
- + u32 *p = ATTR32(d);
- + struct qb_attr_code code_wred_edp = QB_CODE(WRED_EDP_WORD(idx),
- + WRED_EDP_OFFSET(idx), 8);
- + *edp = (int)qb_attr_code_decode(&code_wred_edp, p);
- +}
- +
- +void qbman_cgr_attr_wred_dp_decompose(u32 dp, u64 *minth,
- + u64 *maxth, u8 *maxp)
- +{
- + u8 ma, mn, step_i, step_s, pn;
- +
- + ma = (u8)(dp >> 24);
- + mn = (u8)(dp >> 19) & 0x1f;
- + step_i = (u8)(dp >> 11);
- + step_s = (u8)(dp >> 6) & 0x1f;
- + pn = (u8)dp & 0x3f;
- +
- + *maxp = ((pn << 2) * 100) / 256;
- +
- + if (mn == 0)
- + *maxth = ma;
- + else
- + *maxth = ((ma + 256) * (1 << (mn - 1)));
- +
- + if (step_s == 0)
- + *minth = *maxth - step_i;
- + else
- + *minth = *maxth - (256 + step_i) * (1 << (step_s - 1));
- +}
- +
- +void qbman_cgr_attr_wred_get_parm_dp(struct qbman_attr *d, u32 idx,
- + u32 *dp)
- +{
- + u32 *p = ATTR32(d);
- + struct qb_attr_code code_wred_parm_dp = QB_CODE(WRED_PARM_DP_WORD(idx),
- + 0, 8);
- + *dp = qb_attr_code_decode(&code_wred_parm_dp, p);
- +}
- +
- +/* Query CGR/CCGR/CQ statistics */
- +static struct qb_attr_code code_cgr_stat_ct = QB_CODE(4, 0, 32);
- +static struct qb_attr_code code_cgr_stat_frame_cnt_lo = QB_CODE(4, 0, 32);
- +static struct qb_attr_code code_cgr_stat_frame_cnt_hi = QB_CODE(5, 0, 8);
- +static struct qb_attr_code code_cgr_stat_byte_cnt_lo = QB_CODE(6, 0, 32);
- +static struct qb_attr_code code_cgr_stat_byte_cnt_hi = QB_CODE(7, 0, 16);
- +static int qbman_cgr_statistics_query(struct qbman_swp *s, u32 cgid,
- + int clear, u32 command_type,
- + u64 *frame_cnt, u64 *byte_cnt)
- +{
- + u32 *p;
- + u32 verb, rslt;
- + u32 query_verb;
- + u32 hi, lo;
- +
- + p = qbman_swp_mc_start(s);
- + if (!p)
- + return -EBUSY;
- +
- + qb_attr_code_encode(&code_cgr_cgid, p, cgid);
- + if (command_type < 2)
- + qb_attr_code_encode(&code_cgr_stat_ct, p, command_type);
- + query_verb = clear ?
- + QBMAN_CGR_STAT_QUERY_CLR : QBMAN_CGR_STAT_QUERY;
- + p = qbman_swp_mc_complete(s, p, p[0] | query_verb);
- +
- + /* Decode the outcome */
- + verb = qb_attr_code_decode(&code_generic_verb, p);
- + rslt = qb_attr_code_decode(&code_generic_rslt, p);
- + WARN_ON(verb != query_verb);
- +
- + /* Determine success or failure */
- + if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
- + pr_err("Query statistics of CGID 0x%x failed,", cgid);
- + pr_err(" verb=0x%02x code=0x%02x\n", verb, rslt);
- + return -EIO;
- + }
- +
- + if (*frame_cnt) {
- + hi = qb_attr_code_decode(&code_cgr_stat_frame_cnt_hi, p);
- + lo = qb_attr_code_decode(&code_cgr_stat_frame_cnt_lo, p);
- + *frame_cnt = ((u64)hi << 32) | (u64)lo;
- + }
- + if (*byte_cnt) {
- + hi = qb_attr_code_decode(&code_cgr_stat_byte_cnt_hi, p);
- + lo = qb_attr_code_decode(&code_cgr_stat_byte_cnt_lo, p);
- + *byte_cnt = ((u64)hi << 32) | (u64)lo;
- + }
- +
- + return 0;
- +}
- +
- +int qbman_cgr_reject_statistics(struct qbman_swp *s, u32 cgid, int clear,
- + u64 *frame_cnt, u64 *byte_cnt)
- +{
- + return qbman_cgr_statistics_query(s, cgid, clear, 0xff,
- + frame_cnt, byte_cnt);
- +}
- +
- +int qbman_ccgr_reject_statistics(struct qbman_swp *s, u32 cgid, int clear,
- + u64 *frame_cnt, u64 *byte_cnt)
- +{
- + return qbman_cgr_statistics_query(s, cgid, clear, 1,
- + frame_cnt, byte_cnt);
- +}
- +
- +int qbman_cq_dequeue_statistics(struct qbman_swp *s, u32 cgid, int clear,
- + u64 *frame_cnt, u64 *byte_cnt)
- +{
- + return qbman_cgr_statistics_query(s, cgid, clear, 0,
- + frame_cnt, byte_cnt);
- +}
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/qbman_debug.h
- @@ -0,0 +1,136 @@
- +/* Copyright (C) 2015 Freescale Semiconductor, Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +struct qbman_attr {
- + u32 dont_manipulate_directly[40];
- +};
- +
- +/* Buffer pool query commands */
- +int qbman_bp_query(struct qbman_swp *s, u32 bpid,
- + struct qbman_attr *a);
- +void qbman_bp_attr_get_bdi(struct qbman_attr *a, int *bdi, int *va, int *wae);
- +void qbman_bp_attr_get_swdet(struct qbman_attr *a, u32 *swdet);
- +void qbman_bp_attr_get_swdxt(struct qbman_attr *a, u32 *swdxt);
- +void qbman_bp_attr_get_hwdet(struct qbman_attr *a, u32 *hwdet);
- +void qbman_bp_attr_get_hwdxt(struct qbman_attr *a, u32 *hwdxt);
- +void qbman_bp_attr_get_swset(struct qbman_attr *a, u32 *swset);
- +void qbman_bp_attr_get_swsxt(struct qbman_attr *a, u32 *swsxt);
- +void qbman_bp_attr_get_vbpid(struct qbman_attr *a, u32 *vbpid);
- +void qbman_bp_attr_get_icid(struct qbman_attr *a, u32 *icid, int *pl);
- +void qbman_bp_attr_get_bpscn_addr(struct qbman_attr *a, u64 *bpscn_addr);
- +void qbman_bp_attr_get_bpscn_ctx(struct qbman_attr *a, u64 *bpscn_ctx);
- +void qbman_bp_attr_get_hw_targ(struct qbman_attr *a, u32 *hw_targ);
- +int qbman_bp_info_has_free_bufs(struct qbman_attr *a);
- +int qbman_bp_info_is_depleted(struct qbman_attr *a);
- +int qbman_bp_info_is_surplus(struct qbman_attr *a);
- +u32 qbman_bp_info_num_free_bufs(struct qbman_attr *a);
- +u32 qbman_bp_info_hdptr(struct qbman_attr *a);
- +u32 qbman_bp_info_sdcnt(struct qbman_attr *a);
- +u32 qbman_bp_info_hdcnt(struct qbman_attr *a);
- +u32 qbman_bp_info_sscnt(struct qbman_attr *a);
- +
- +/* FQ query function for programmable fields */
- +int qbman_fq_query(struct qbman_swp *s, u32 fqid,
- + struct qbman_attr *desc);
- +void qbman_fq_attr_get_fqctrl(struct qbman_attr *d, u32 *fqctrl);
- +void qbman_fq_attr_get_cgrid(struct qbman_attr *d, u32 *cgrid);
- +void qbman_fq_attr_get_destwq(struct qbman_attr *d, u32 *destwq);
- +void qbman_fq_attr_get_icscred(struct qbman_attr *d, u32 *icscred);
- +void qbman_fq_attr_get_tdthresh(struct qbman_attr *d, u32 *tdthresh);
- +void qbman_fq_attr_get_oa(struct qbman_attr *d,
- + int *oa_ics, int *oa_cgr, int32_t *oa_len);
- +void qbman_fq_attr_get_mctl(struct qbman_attr *d,
- + int *bdi, int *ff, int *va, int *ps);
- +void qbman_fq_attr_get_ctx(struct qbman_attr *d, u32 *hi, u32 *lo);
- +void qbman_fq_attr_get_icid(struct qbman_attr *d, u32 *icid, int *pl);
- +void qbman_fq_attr_get_vfqid(struct qbman_attr *d, u32 *vfqid);
- +void qbman_fq_attr_get_erfqid(struct qbman_attr *d, u32 *erfqid);
- +
- +/* FQ query command for non-programmable fields*/
- +enum qbman_fq_schedstate_e {
- + qbman_fq_schedstate_oos = 0,
- + qbman_fq_schedstate_retired,
- + qbman_fq_schedstate_tentatively_scheduled,
- + qbman_fq_schedstate_truly_scheduled,
- + qbman_fq_schedstate_parked,
- + qbman_fq_schedstate_held_active,
- +};
- +
- +int qbman_fq_query_state(struct qbman_swp *s, u32 fqid,
- + struct qbman_attr *state);
- +u32 qbman_fq_state_schedstate(const struct qbman_attr *state);
- +int qbman_fq_state_force_eligible(const struct qbman_attr *state);
- +int qbman_fq_state_xoff(const struct qbman_attr *state);
- +int qbman_fq_state_retirement_pending(const struct qbman_attr *state);
- +int qbman_fq_state_overflow_error(const struct qbman_attr *state);
- +u32 qbman_fq_state_frame_count(const struct qbman_attr *state);
- +u32 qbman_fq_state_byte_count(const struct qbman_attr *state);
- +
- +/* CGR query */
- +int qbman_cgr_query(struct qbman_swp *s, u32 cgid,
- + struct qbman_attr *attr);
- +void qbman_cgr_attr_get_ctl1(struct qbman_attr *d, int *cscn_wq_en_enter,
- + int *cscn_wq_en_exit, int *cscn_wq_icd);
- +void qbman_cgr_attr_get_mode(struct qbman_attr *d, u32 *mode,
- + int *rej_cnt_mode, int *cscn_bdi);
- +void qbman_cgr_attr_get_ctl2(struct qbman_attr *d, int *cscn_wr_en_enter,
- + int *cscn_wr_en_exit, int *cg_wr_ae,
- + int *cscn_dcp_en, int *cg_wr_va);
- +void qbman_cgr_attr_get_iwc(struct qbman_attr *d, int *i_cnt_wr_en,
- + u32 *i_cnt_wr_bnd);
- +void qbman_cgr_attr_get_tdc(struct qbman_attr *d, int *td_en);
- +void qbman_cgr_attr_get_cs_thres(struct qbman_attr *d, u32 *cs_thres);
- +void qbman_cgr_attr_get_cs_thres_x(struct qbman_attr *d,
- + u32 *cs_thres_x);
- +void qbman_cgr_attr_get_td_thres(struct qbman_attr *d, u32 *td_thres);
- +void qbman_cgr_attr_get_cscn_tdcp(struct qbman_attr *d, u32 *cscn_tdcp);
- +void qbman_cgr_attr_get_cscn_wqid(struct qbman_attr *d, u32 *cscn_wqid);
- +void qbman_cgr_attr_get_cscn_vcgid(struct qbman_attr *d,
- + u32 *cscn_vcgid);
- +void qbman_cgr_attr_get_cg_icid(struct qbman_attr *d, u32 *icid,
- + int *pl);
- +void qbman_cgr_attr_get_cg_wr_addr(struct qbman_attr *d,
- + u64 *cg_wr_addr);
- +void qbman_cgr_attr_get_cscn_ctx(struct qbman_attr *d, u64 *cscn_ctx);
- +void qbman_cgr_attr_wred_get_edp(struct qbman_attr *d, u32 idx,
- + int *edp);
- +void qbman_cgr_attr_wred_dp_decompose(u32 dp, u64 *minth,
- + u64 *maxth, u8 *maxp);
- +void qbman_cgr_attr_wred_get_parm_dp(struct qbman_attr *d, u32 idx,
- + u32 *dp);
- +
- +/* CGR/CCGR/CQ statistics query */
- +int qbman_cgr_reject_statistics(struct qbman_swp *s, u32 cgid, int clear,
- + u64 *frame_cnt, u64 *byte_cnt);
- +int qbman_ccgr_reject_statistics(struct qbman_swp *s, u32 cgid, int clear,
- + u64 *frame_cnt, u64 *byte_cnt);
- +int qbman_cq_dequeue_statistics(struct qbman_swp *s, u32 cgid, int clear,
- + u64 *frame_cnt, u64 *byte_cnt);
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/dpio/qbman_private.h
- @@ -0,0 +1,171 @@
- +/* Copyright (C) 2014 Freescale Semiconductor, Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +
- +/* Perform extra checking */
- +#define QBMAN_CHECKING
- +
- +/* To maximise the amount of logic that is common between the Linux driver and
- + * other targets (such as the embedded MC firmware), we pivot here between the
- + * inclusion of two platform-specific headers.
- + *
- + * The first, qbman_sys_decl.h, includes any and all required system headers as
- + * well as providing any definitions for the purposes of compatibility. The
- + * second, qbman_sys.h, is where platform-specific routines go.
- + *
- + * The point of the split is that the platform-independent code (including this
- + * header) may depend on platform-specific declarations, yet other
- + * platform-specific routines may depend on platform-independent definitions.
- + */
- +
- +#define QMAN_REV_4000 0x04000000
- +#define QMAN_REV_4100 0x04010000
- +#define QMAN_REV_4101 0x04010001
- +
- +/* When things go wrong, it is a convenient trick to insert a few FOO()
- + * statements in the code to trace progress. TODO: remove this once we are
- + * hacking the code less actively.
- + */
- +#define FOO() fsl_os_print("FOO: %s:%d\n", __FILE__, __LINE__)
- +
- +/* Any time there is a register interface which we poll on, this provides a
- + * "break after x iterations" scheme for it. It's handy for debugging, eg.
- + * where you don't want millions of lines of log output from a polling loop
- + * that won't, because such things tend to drown out the earlier log output
- + * that might explain what caused the problem. (NB: put ";" after each macro!)
- + * TODO: we should probably remove this once we're done sanitising the
- + * simulator...
- + */
- +#define DBG_POLL_START(loopvar) (loopvar = 1000)
- +#define DBG_POLL_CHECK(loopvar) \
- + do {if (!((loopvar)--)) WARN_ON(1); } while (0)
- +
- +/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
- + * and widths, these macro-generated encode/decode/isolate/remove inlines can
- + * be used.
- + *
- + * Eg. to "d"ecode a 14-bit field out of a register (into a "u16" type),
- + * where the field is located 3 bits "up" from the least-significant bit of the
- + * register (ie. the field location within the 32-bit register corresponds to a
- + * mask of 0x0001fff8), you would do;
- + * u16 field = d32_u16(3, 14, reg_value);
- + *
- + * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
- + * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
- + * operator) into a register at bit location 0x00080000 (19 bits "in" from the
- + * LS bit), do;
- + * reg_value |= e32_int(19, 1, !!field);
- + *
- + * If you wish to read-modify-write a register, such that you leave the 14-bit
- + * field as-is but have all other fields set to zero, then "i"solate the 14-bit
- + * value using;
- + * reg_value = i32_u16(3, 14, reg_value);
- + *
- + * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
- + * zero) but leaving all other fields as-is;
- + * reg_val = r32_int(19, 1, reg_value);
- + *
- + */
- +#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
- + (u32)((1 << width) - 1))
- +#define DECLARE_CODEC32(t) \
- +static inline u32 e32_##t(u32 lsoffset, u32 width, t val) \
- +{ \
- + WARN_ON(width > (sizeof(t) * 8)); \
- + return ((u32)val & MAKE_MASK32(width)) << lsoffset; \
- +} \
- +static inline t d32_##t(u32 lsoffset, u32 width, u32 val) \
- +{ \
- + WARN_ON(width > (sizeof(t) * 8)); \
- + return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
- +} \
- +static inline u32 i32_##t(u32 lsoffset, u32 width, \
- + u32 val) \
- +{ \
- + WARN_ON(width > (sizeof(t) * 8)); \
- + return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
- +} \
- +static inline u32 r32_##t(u32 lsoffset, u32 width, \
- + u32 val) \
- +{ \
- + WARN_ON(width > (sizeof(t) * 8)); \
- + return ~(MAKE_MASK32(width) << lsoffset) & val; \
- +}
- +DECLARE_CODEC32(u32)
- +DECLARE_CODEC32(u16)
- +DECLARE_CODEC32(u8)
- +DECLARE_CODEC32(int)
- +
- + /*********************/
- + /* Debugging assists */
- + /*********************/
- +
- +static inline void __hexdump(unsigned long start, unsigned long end,
- + unsigned long p, size_t sz,
- + const unsigned char *c)
- +{
- + while (start < end) {
- + unsigned int pos = 0;
- + char buf[64];
- + int nl = 0;
- +
- + pos += sprintf(buf + pos, "%08lx: ", start);
- + do {
- + if ((start < p) || (start >= (p + sz)))
- + pos += sprintf(buf + pos, "..");
- + else
- + pos += sprintf(buf + pos, "%02x", *(c++));
- + if (!(++start & 15)) {
- + buf[pos++] = '\n';
- + nl = 1;
- + } else {
- + nl = 0;
- + if (!(start & 1))
- + buf[pos++] = ' ';
- + if (!(start & 3))
- + buf[pos++] = ' ';
- + }
- + } while (start & 15);
- + if (!nl)
- + buf[pos++] = '\n';
- + buf[pos] = '\0';
- + pr_info("%s", buf);
- + }
- +}
- +
- +static inline void hexdump(const void *ptr, size_t sz)
- +{
- + unsigned long p = (unsigned long)ptr;
- + unsigned long start = p & ~15ul;
- + unsigned long end = (p + sz + 15) & ~15ul;
- + const unsigned char *c = ptr;
- +
- + __hexdump(start, end, p, sz, c);
- +}
- --- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
- +++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2016 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -11,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -33,108 +33,24 @@
- #define _FSL_DPMCP_CMD_H
-
- /* Minimal supported DPMCP Version */
- -#define DPMCP_MIN_VER_MAJOR 3
- -#define DPMCP_MIN_VER_MINOR 0
- -
- -/* Command IDs */
- -#define DPMCP_CMDID_CLOSE 0x800
- -#define DPMCP_CMDID_OPEN 0x80b
- -#define DPMCP_CMDID_CREATE 0x90b
- -#define DPMCP_CMDID_DESTROY 0x900
- -
- -#define DPMCP_CMDID_GET_ATTR 0x004
- -#define DPMCP_CMDID_RESET 0x005
- -
- -#define DPMCP_CMDID_SET_IRQ 0x010
- -#define DPMCP_CMDID_GET_IRQ 0x011
- -#define DPMCP_CMDID_SET_IRQ_ENABLE 0x012
- -#define DPMCP_CMDID_GET_IRQ_ENABLE 0x013
- -#define DPMCP_CMDID_SET_IRQ_MASK 0x014
- -#define DPMCP_CMDID_GET_IRQ_MASK 0x015
- -#define DPMCP_CMDID_GET_IRQ_STATUS 0x016
- -
- -struct dpmcp_cmd_open {
- - __le32 dpmcp_id;
- -};
- -
- -struct dpmcp_cmd_create {
- - __le32 portal_id;
- -};
- -
- -struct dpmcp_cmd_set_irq {
- - /* cmd word 0 */
- - u8 irq_index;
- - u8 pad[3];
- - __le32 irq_val;
- - /* cmd word 1 */
- - __le64 irq_addr;
- - /* cmd word 2 */
- - __le32 irq_num;
- -};
- -
- -struct dpmcp_cmd_get_irq {
- - __le32 pad;
- - u8 irq_index;
- -};
- -
- -struct dpmcp_rsp_get_irq {
- - /* cmd word 0 */
- - __le32 irq_val;
- - __le32 pad;
- - /* cmd word 1 */
- - __le64 irq_paddr;
- - /* cmd word 2 */
- - __le32 irq_num;
- - __le32 type;
- -};
- +#define DPMCP_MIN_VER_MAJOR 3
- +#define DPMCP_MIN_VER_MINOR 0
-
- -#define DPMCP_ENABLE 0x1
- +/* Command versioning */
- +#define DPMCP_CMD_BASE_VERSION 1
- +#define DPMCP_CMD_ID_OFFSET 4
-
- -struct dpmcp_cmd_set_irq_enable {
- - u8 enable;
- - u8 pad[3];
- - u8 irq_index;
- -};
- +#define DPMCP_CMD(id) ((id << DPMCP_CMD_ID_OFFSET) | DPMCP_CMD_BASE_VERSION)
-
- -struct dpmcp_cmd_get_irq_enable {
- - __le32 pad;
- - u8 irq_index;
- -};
- -
- -struct dpmcp_rsp_get_irq_enable {
- - u8 enabled;
- -};
- -
- -struct dpmcp_cmd_set_irq_mask {
- - __le32 mask;
- - u8 irq_index;
- -};
- -
- -struct dpmcp_cmd_get_irq_mask {
- - __le32 pad;
- - u8 irq_index;
- -};
- -
- -struct dpmcp_rsp_get_irq_mask {
- - __le32 mask;
- -};
- +/* Command IDs */
- +#define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800)
- +#define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b)
- +#define DPMCP_CMDID_GET_API_VERSION DPMCP_CMD(0xa0b)
-
- -struct dpmcp_cmd_get_irq_status {
- - __le32 status;
- - u8 irq_index;
- -};
- +#define DPMCP_CMDID_RESET DPMCP_CMD(0x005)
-
- -struct dpmcp_rsp_get_irq_status {
- - __le32 status;
- -};
- -
- -struct dpmcp_rsp_get_attributes {
- - /* response word 0 */
- - __le32 pad;
- - __le32 id;
- - /* response word 1 */
- - __le16 version_major;
- - __le16 version_minor;
- +struct dpmcp_cmd_open {
- + __le32 dpmcp_id;
- };
-
- #endif /* _FSL_DPMCP_CMD_H */
- --- a/drivers/staging/fsl-mc/bus/dpmcp.c
- +++ b/drivers/staging/fsl-mc/bus/dpmcp.c
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2016 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -11,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -104,76 +104,6 @@ int dpmcp_close(struct fsl_mc_io *mc_io,
- }
-
- /**
- - * dpmcp_create() - Create the DPMCP object.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @cfg: Configuration structure
- - * @token: Returned token; use in subsequent API calls
- - *
- - * Create the DPMCP object, allocate required resources and
- - * perform required initialization.
- - *
- - * The object can be created either by declaring it in the
- - * DPL file, or by calling this function.
- - * This function returns a unique authentication token,
- - * associated with the specific object ID and the specific MC
- - * portal; this token must be used in all subsequent calls to
- - * this specific object. For objects that are created using the
- - * DPL file, call dpmcp_open function to get an authentication
- - * token first.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_create(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - const struct dpmcp_cfg *cfg,
- - u16 *token)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_create *cmd_params;
- -
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE,
- - cmd_flags, 0);
- - cmd_params = (struct dpmcp_cmd_create *)cmd.params;
- - cmd_params->portal_id = cpu_to_le32(cfg->portal_id);
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - *token = mc_cmd_hdr_read_token(&cmd);
- -
- - return 0;
- -}
- -
- -/**
- - * dpmcp_destroy() - Destroy the DPMCP object and release all its resources.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - *
- - * Return: '0' on Success; error code otherwise.
- - */
- -int dpmcp_destroy(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token)
- -{
- - struct mc_command cmd = { 0 };
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY,
- - cmd_flags, token);
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- * dpmcp_reset() - Reset the DPMCP, returns the object to initial state.
- * @mc_io: Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- @@ -196,309 +126,33 @@ int dpmcp_reset(struct fsl_mc_io *mc_io,
- }
-
- /**
- - * dpmcp_set_irq() - Set IRQ information for the DPMCP to trigger an interrupt.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @irq_index: Identifies the interrupt index to configure
- - * @irq_cfg: IRQ configuration
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_set_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - struct dpmcp_irq_cfg *irq_cfg)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_set_irq *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ,
- - cmd_flags, token);
- - cmd_params = (struct dpmcp_cmd_set_irq *)cmd.params;
- - cmd_params->irq_index = irq_index;
- - cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
- - cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
- - cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dpmcp_get_irq() - Get IRQ information from the DPMCP.
- - * @mc_io: Pointer to MC portal's I/O object
- + * dpmcp_get_api_version - Get Data Path Management Command Portal API version
- + * @mc_io: Pointer to Mc portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @irq_index: The interrupt index to configure
- - * @type: Interrupt type: 0 represents message interrupt
- - * type (both irq_addr and irq_val are valid)
- - * @irq_cfg: IRQ attributes
- + * @major_ver: Major version of Data Path Management Command Portal API
- + * @minor_ver: Minor version of Data Path Management Command Portal API
- *
- * Return: '0' on Success; Error code otherwise.
- */
- -int dpmcp_get_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - int *type,
- - struct dpmcp_irq_cfg *irq_cfg)
- +int dpmcp_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver)
- {
- struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_get_irq *cmd_params;
- - struct dpmcp_rsp_get_irq *rsp_params;
- int err;
-
- /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ,
- - cmd_flags, token);
- - cmd_params = (struct dpmcp_cmd_get_irq *)cmd.params;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpmcp_rsp_get_irq *)cmd.params;
- - irq_cfg->val = le32_to_cpu(rsp_params->irq_val);
- - irq_cfg->paddr = le64_to_cpu(rsp_params->irq_paddr);
- - irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num);
- - *type = le32_to_cpu(rsp_params->type);
- - return 0;
- -}
- -
- -/**
- - * dpmcp_set_irq_enable() - Set overall interrupt state.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @irq_index: The interrupt index to configure
- - * @en: Interrupt state - enable = 1, disable = 0
- - *
- - * Allows GPP software to control when interrupts are generated.
- - * Each interrupt can have up to 32 causes. The enable/disable control's the
- - * overall interrupt state. if the interrupt is disabled no causes will cause
- - * an interrupt.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 en)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_set_irq_enable *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_ENABLE,
- - cmd_flags, token);
- - cmd_params = (struct dpmcp_cmd_set_irq_enable *)cmd.params;
- - cmd_params->enable = en & DPMCP_ENABLE;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dpmcp_get_irq_enable() - Get overall interrupt state
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @irq_index: The interrupt index to configure
- - * @en: Returned interrupt state - enable = 1, disable = 0
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 *en)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_get_irq_enable *cmd_params;
- - struct dpmcp_rsp_get_irq_enable *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_ENABLE,
- - cmd_flags, token);
- - cmd_params = (struct dpmcp_cmd_get_irq_enable *)cmd.params;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpmcp_rsp_get_irq_enable *)cmd.params;
- - *en = rsp_params->enabled & DPMCP_ENABLE;
- - return 0;
- -}
- -
- -/**
- - * dpmcp_set_irq_mask() - Set interrupt mask.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @irq_index: The interrupt index to configure
- - * @mask: Event mask to trigger interrupt;
- - * each bit:
- - * 0 = ignore event
- - * 1 = consider event for asserting IRQ
- - *
- - * Every interrupt can have up to 32 causes and the interrupt model supports
- - * masking/unmasking each cause independently
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 mask)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_set_irq_mask *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_MASK,
- - cmd_flags, token);
- - cmd_params = (struct dpmcp_cmd_set_irq_mask *)cmd.params;
- - cmd_params->mask = cpu_to_le32(mask);
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dpmcp_get_irq_mask() - Get interrupt mask.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @irq_index: The interrupt index to configure
- - * @mask: Returned event mask to trigger interrupt
- - *
- - * Every interrupt can have up to 32 causes and the interrupt model supports
- - * masking/unmasking each cause independently
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *mask)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_get_irq_mask *cmd_params;
- - struct dpmcp_rsp_get_irq_mask *rsp_params;
- -
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_MASK,
- - cmd_flags, token);
- - cmd_params = (struct dpmcp_cmd_get_irq_mask *)cmd.params;
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpmcp_rsp_get_irq_mask *)cmd.params;
- - *mask = le32_to_cpu(rsp_params->mask);
- -
- - return 0;
- -}
- -
- -/**
- - * dpmcp_get_irq_status() - Get the current status of any pending interrupts.
- - *
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @irq_index: The interrupt index to configure
- - * @status: Returned interrupts status - one bit per cause:
- - * 0 = no interrupt pending
- - * 1 = interrupt pending
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_get_irq_status(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *status)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_cmd_get_irq_status *cmd_params;
- - struct dpmcp_rsp_get_irq_status *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_STATUS,
- - cmd_flags, token);
- - cmd_params = (struct dpmcp_cmd_get_irq_status *)cmd.params;
- - cmd_params->status = cpu_to_le32(*status);
- - cmd_params->irq_index = irq_index;
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpmcp_rsp_get_irq_status *)cmd.params;
- - *status = le32_to_cpu(rsp_params->status);
- -
- - return 0;
- -}
- -
- -/**
- - * dpmcp_get_attributes - Retrieve DPMCP attributes.
- - *
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPMCP object
- - * @attr: Returned object's attributes
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmcp_get_attributes(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dpmcp_attr *attr)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmcp_rsp_get_attributes *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_ATTR,
- - cmd_flags, token);
- + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_API_VERSION,
- + cmd_flags, 0);
-
- - /* send command to mc*/
- + /* send command to mc */
- err = mc_send_command(mc_io, &cmd);
- if (err)
- return err;
-
- /* retrieve response parameters */
- - rsp_params = (struct dpmcp_rsp_get_attributes *)cmd.params;
- - attr->id = le32_to_cpu(rsp_params->id);
- - attr->version.major = le16_to_cpu(rsp_params->version_major);
- - attr->version.minor = le16_to_cpu(rsp_params->version_minor);
- + mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
-
- return 0;
- }
- --- a/drivers/staging/fsl-mc/bus/dpmcp.h
- +++ b/drivers/staging/fsl-mc/bus/dpmcp.h
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2015 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -11,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -32,128 +32,29 @@
- #ifndef __FSL_DPMCP_H
- #define __FSL_DPMCP_H
-
- -/* Data Path Management Command Portal API
- +/*
- + * Data Path Management Command Portal API
- * Contains initialization APIs and runtime control APIs for DPMCP
- */
-
- struct fsl_mc_io;
-
- int dpmcp_open(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- + u32 cmd_flags,
- int dpmcp_id,
- - uint16_t *token);
- -
- -/* Get portal ID from pool */
- -#define DPMCP_GET_PORTAL_ID_FROM_POOL (-1)
- + u16 *token);
-
- int dpmcp_close(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token);
- + u32 cmd_flags,
- + u16 token);
-
- -/**
- - * struct dpmcp_cfg - Structure representing DPMCP configuration
- - * @portal_id: Portal ID; 'DPMCP_GET_PORTAL_ID_FROM_POOL' to get the portal ID
- - * from pool
- - */
- -struct dpmcp_cfg {
- - int portal_id;
- -};
- -
- -int dpmcp_create(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - const struct dpmcp_cfg *cfg,
- - uint16_t *token);
- -
- -int dpmcp_destroy(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token);
- +int dpmcp_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver);
-
- int dpmcp_reset(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token);
- -
- -/* IRQ */
- -/* IRQ Index */
- -#define DPMCP_IRQ_INDEX 0
- -/* irq event - Indicates that the link state changed */
- -#define DPMCP_IRQ_EVENT_CMD_DONE 0x00000001
- -
- -/**
- - * struct dpmcp_irq_cfg - IRQ configuration
- - * @paddr: Address that must be written to signal a message-based interrupt
- - * @val: Value to write into irq_addr address
- - * @irq_num: A user defined number associated with this IRQ
- - */
- -struct dpmcp_irq_cfg {
- - uint64_t paddr;
- - uint32_t val;
- - int irq_num;
- -};
- -
- -int dpmcp_set_irq(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - uint8_t irq_index,
- - struct dpmcp_irq_cfg *irq_cfg);
- -
- -int dpmcp_get_irq(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - uint8_t irq_index,
- - int *type,
- - struct dpmcp_irq_cfg *irq_cfg);
- -
- -int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - uint8_t irq_index,
- - uint8_t en);
- -
- -int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - uint8_t irq_index,
- - uint8_t *en);
- -
- -int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - uint8_t irq_index,
- - uint32_t mask);
- -
- -int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - uint8_t irq_index,
- - uint32_t *mask);
- -
- -int dpmcp_get_irq_status(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - uint8_t irq_index,
- - uint32_t *status);
- -
- -/**
- - * struct dpmcp_attr - Structure representing DPMCP attributes
- - * @id: DPMCP object ID
- - * @version: DPMCP version
- - */
- -struct dpmcp_attr {
- - int id;
- - /**
- - * struct version - Structure representing DPMCP version
- - * @major: DPMCP major version
- - * @minor: DPMCP minor version
- - */
- - struct {
- - uint16_t major;
- - uint16_t minor;
- - } version;
- -};
- -
- -int dpmcp_get_attributes(struct fsl_mc_io *mc_io,
- - uint32_t cmd_flags,
- - uint16_t token,
- - struct dpmcp_attr *attr);
- + u32 cmd_flags,
- + u16 token);
-
- #endif /* __FSL_DPMCP_H */
- --- a/drivers/staging/fsl-mc/bus/dpmng-cmd.h
- +++ b/drivers/staging/fsl-mc/bus/dpmng-cmd.h
- @@ -12,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -41,13 +40,14 @@
- #ifndef __FSL_DPMNG_CMD_H
- #define __FSL_DPMNG_CMD_H
-
- -/* Command IDs */
- -#define DPMNG_CMDID_GET_CONT_ID 0x830
- -#define DPMNG_CMDID_GET_VERSION 0x831
- +/* Command versioning */
- +#define DPMNG_CMD_BASE_VERSION 1
- +#define DPMNG_CMD_ID_OFFSET 4
-
- -struct dpmng_rsp_get_container_id {
- - __le32 container_id;
- -};
- +#define DPMNG_CMD(id) ((id << DPMNG_CMD_ID_OFFSET) | DPMNG_CMD_BASE_VERSION)
- +
- +/* Command IDs */
- +#define DPMNG_CMDID_GET_VERSION DPMNG_CMD(0x831)
-
- struct dpmng_rsp_get_version {
- __le32 revision;
- --- a/drivers/staging/fsl-mc/bus/dpmng.c
- +++ b/drivers/staging/fsl-mc/bus/dpmng.c
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2016 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -11,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -72,36 +72,3 @@ int mc_get_version(struct fsl_mc_io *mc_
- }
- EXPORT_SYMBOL(mc_get_version);
-
- -/**
- - * dpmng_get_container_id() - Get container ID associated with a given portal.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @container_id: Requested container ID
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dpmng_get_container_id(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - int *container_id)
- -{
- - struct mc_command cmd = { 0 };
- - struct dpmng_rsp_get_container_id *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_CONT_ID,
- - cmd_flags,
- - 0);
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dpmng_rsp_get_container_id *)cmd.params;
- - *container_id = le32_to_cpu(rsp_params->container_id);
- -
- - return 0;
- -}
- -
- --- a/drivers/staging/fsl-mc/bus/dprc-cmd.h
- +++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h
- @@ -12,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -42,48 +41,39 @@
- #define _FSL_DPRC_CMD_H
-
- /* Minimal supported DPRC Version */
- -#define DPRC_MIN_VER_MAJOR 5
- +#define DPRC_MIN_VER_MAJOR 6
- #define DPRC_MIN_VER_MINOR 0
-
- -/* Command IDs */
- -#define DPRC_CMDID_CLOSE 0x800
- -#define DPRC_CMDID_OPEN 0x805
- -#define DPRC_CMDID_CREATE 0x905
- -
- -#define DPRC_CMDID_GET_ATTR 0x004
- -#define DPRC_CMDID_RESET_CONT 0x005
- -
- -#define DPRC_CMDID_SET_IRQ 0x010
- -#define DPRC_CMDID_GET_IRQ 0x011
- -#define DPRC_CMDID_SET_IRQ_ENABLE 0x012
- -#define DPRC_CMDID_GET_IRQ_ENABLE 0x013
- -#define DPRC_CMDID_SET_IRQ_MASK 0x014
- -#define DPRC_CMDID_GET_IRQ_MASK 0x015
- -#define DPRC_CMDID_GET_IRQ_STATUS 0x016
- -#define DPRC_CMDID_CLEAR_IRQ_STATUS 0x017
- -
- -#define DPRC_CMDID_CREATE_CONT 0x151
- -#define DPRC_CMDID_DESTROY_CONT 0x152
- -#define DPRC_CMDID_SET_RES_QUOTA 0x155
- -#define DPRC_CMDID_GET_RES_QUOTA 0x156
- -#define DPRC_CMDID_ASSIGN 0x157
- -#define DPRC_CMDID_UNASSIGN 0x158
- -#define DPRC_CMDID_GET_OBJ_COUNT 0x159
- -#define DPRC_CMDID_GET_OBJ 0x15A
- -#define DPRC_CMDID_GET_RES_COUNT 0x15B
- -#define DPRC_CMDID_GET_RES_IDS 0x15C
- -#define DPRC_CMDID_GET_OBJ_REG 0x15E
- -#define DPRC_CMDID_SET_OBJ_IRQ 0x15F
- -#define DPRC_CMDID_GET_OBJ_IRQ 0x160
- -#define DPRC_CMDID_SET_OBJ_LABEL 0x161
- -#define DPRC_CMDID_GET_OBJ_DESC 0x162
- -
- -#define DPRC_CMDID_CONNECT 0x167
- -#define DPRC_CMDID_DISCONNECT 0x168
- -#define DPRC_CMDID_GET_POOL 0x169
- -#define DPRC_CMDID_GET_POOL_COUNT 0x16A
- +/* Command versioning */
- +#define DPRC_CMD_BASE_VERSION 1
- +#define DPRC_CMD_ID_OFFSET 4
-
- -#define DPRC_CMDID_GET_CONNECTION 0x16C
- +#define DPRC_CMD(id) ((id << DPRC_CMD_ID_OFFSET) | DPRC_CMD_BASE_VERSION)
- +
- +/* Command IDs */
- +#define DPRC_CMDID_CLOSE DPRC_CMD(0x800)
- +#define DPRC_CMDID_OPEN DPRC_CMD(0x805)
- +#define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05)
- +
- +#define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004)
- +#define DPRC_CMDID_RESET_CONT DPRC_CMD(0x005)
- +
- +#define DPRC_CMDID_SET_IRQ DPRC_CMD(0x010)
- +#define DPRC_CMDID_GET_IRQ DPRC_CMD(0x011)
- +#define DPRC_CMDID_SET_IRQ_ENABLE DPRC_CMD(0x012)
- +#define DPRC_CMDID_GET_IRQ_ENABLE DPRC_CMD(0x013)
- +#define DPRC_CMDID_SET_IRQ_MASK DPRC_CMD(0x014)
- +#define DPRC_CMDID_GET_IRQ_MASK DPRC_CMD(0x015)
- +#define DPRC_CMDID_GET_IRQ_STATUS DPRC_CMD(0x016)
- +#define DPRC_CMDID_CLEAR_IRQ_STATUS DPRC_CMD(0x017)
- +
- +#define DPRC_CMDID_GET_CONT_ID DPRC_CMD(0x830)
- +#define DPRC_CMDID_GET_OBJ_COUNT DPRC_CMD(0x159)
- +#define DPRC_CMDID_GET_OBJ DPRC_CMD(0x15A)
- +#define DPRC_CMDID_GET_RES_COUNT DPRC_CMD(0x15B)
- +#define DPRC_CMDID_GET_OBJ_REG DPRC_CMD(0x15E)
- +#define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F)
- +#define DPRC_CMDID_GET_OBJ_IRQ DPRC_CMD(0x160)
-
- struct dprc_cmd_open {
- __le32 container_id;
- @@ -199,9 +189,6 @@ struct dprc_rsp_get_attributes {
- /* response word 1 */
- __le32 options;
- __le32 portal_id;
- - /* response word 2 */
- - __le16 version_major;
- - __le16 version_minor;
- };
-
- struct dprc_cmd_set_res_quota {
- @@ -367,11 +354,16 @@ struct dprc_cmd_get_obj_region {
-
- struct dprc_rsp_get_obj_region {
- /* response word 0 */
- - __le64 pad;
- + __le64 pad0;
- /* response word 1 */
- - __le64 base_addr;
- + __le32 base_addr;
- + __le32 pad1;
- /* response word 2 */
- __le32 size;
- + u8 type;
- + u8 pad2[3];
- + /* response word 3 */
- + __le32 flags;
- };
-
- struct dprc_cmd_set_obj_label {
- --- a/drivers/staging/fsl-mc/bus/dprc-driver.c
- +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
- @@ -1,7 +1,7 @@
- /*
- * Freescale data path resource container (DPRC) driver
- *
- - * Copyright (C) 2014 Freescale Semiconductor, Inc.
- + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Author: German Rivera <[email protected]>
- *
- * This file is licensed under the terms of the GNU General Public
- @@ -160,6 +160,8 @@ static void check_plugged_state_change(s
- * dprc_add_new_devices - Adds devices to the logical bus for a DPRC
- *
- * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
- + * @driver_override: driver override to apply to new objects found in the
- + * DPRC, or NULL, if none.
- * @obj_desc_array: array of device descriptors for child devices currently
- * present in the physical DPRC.
- * @num_child_objects_in_mc: number of entries in obj_desc_array
- @@ -169,6 +171,7 @@ static void check_plugged_state_change(s
- * in the physical DPRC.
- */
- static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
- + const char *driver_override,
- struct dprc_obj_desc *obj_desc_array,
- int num_child_objects_in_mc)
- {
- @@ -188,11 +191,12 @@ static void dprc_add_new_devices(struct
- child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev);
- if (child_dev) {
- check_plugged_state_change(child_dev, obj_desc);
- + put_device(&child_dev->dev);
- continue;
- }
-
- error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev,
- - &child_dev);
- + driver_override, &child_dev);
- if (error < 0)
- continue;
- }
- @@ -202,6 +206,8 @@ static void dprc_add_new_devices(struct
- * dprc_scan_objects - Discover objects in a DPRC
- *
- * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
- + * @driver_override: driver override to apply to new objects found in the
- + * DPRC, or NULL, if none.
- * @total_irq_count: total number of IRQs needed by objects in the DPRC.
- *
- * Detects objects added and removed from a DPRC and synchronizes the
- @@ -217,6 +223,7 @@ static void dprc_add_new_devices(struct
- * of the device drivers for the non-allocatable devices.
- */
- int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
- + const char *driver_override,
- unsigned int *total_irq_count)
- {
- int num_child_objects;
- @@ -297,7 +304,7 @@ int dprc_scan_objects(struct fsl_mc_devi
- dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
- num_child_objects);
-
- - dprc_add_new_devices(mc_bus_dev, child_obj_desc_array,
- + dprc_add_new_devices(mc_bus_dev, driver_override, child_obj_desc_array,
- num_child_objects);
-
- if (child_obj_desc_array)
- @@ -328,7 +335,7 @@ int dprc_scan_container(struct fsl_mc_de
- * Discover objects in the DPRC:
- */
- mutex_lock(&mc_bus->scan_mutex);
- - error = dprc_scan_objects(mc_bus_dev, &irq_count);
- + error = dprc_scan_objects(mc_bus_dev, NULL, &irq_count);
- mutex_unlock(&mc_bus->scan_mutex);
- if (error < 0)
- goto error;
- @@ -415,7 +422,7 @@ static irqreturn_t dprc_irq0_handler_thr
- DPRC_IRQ_EVENT_OBJ_CREATED)) {
- unsigned int irq_count;
-
- - error = dprc_scan_objects(mc_dev, &irq_count);
- + error = dprc_scan_objects(mc_dev, NULL, &irq_count);
- if (error < 0) {
- /*
- * If the error is -ENXIO, we ignore it, as it indicates
- @@ -505,7 +512,7 @@ static int register_dprc_irq_handler(str
- dprc_irq0_handler,
- dprc_irq0_handler_thread,
- IRQF_NO_SUSPEND | IRQF_ONESHOT,
- - "FSL MC DPRC irq0",
- + dev_name(&mc_dev->dev),
- &mc_dev->dev);
- if (error < 0) {
- dev_err(&mc_dev->dev,
- @@ -597,6 +604,7 @@ static int dprc_probe(struct fsl_mc_devi
- struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
- bool mc_io_created = false;
- bool msi_domain_set = false;
- + u16 major_ver, minor_ver;
-
- if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
- return -EINVAL;
- @@ -669,13 +677,21 @@ static int dprc_probe(struct fsl_mc_devi
- goto error_cleanup_open;
- }
-
- - if (mc_bus->dprc_attr.version.major < DPRC_MIN_VER_MAJOR ||
- - (mc_bus->dprc_attr.version.major == DPRC_MIN_VER_MAJOR &&
- - mc_bus->dprc_attr.version.minor < DPRC_MIN_VER_MINOR)) {
- + error = dprc_get_api_version(mc_dev->mc_io, 0,
- + &major_ver,
- + &minor_ver);
- + if (error < 0) {
- + dev_err(&mc_dev->dev, "dprc_get_api_version() failed: %d\n",
- + error);
- + goto error_cleanup_open;
- + }
- +
- + if (major_ver < DPRC_MIN_VER_MAJOR ||
- + (major_ver == DPRC_MIN_VER_MAJOR &&
- + minor_ver < DPRC_MIN_VER_MINOR)) {
- dev_err(&mc_dev->dev,
- "ERROR: DPRC version %d.%d not supported\n",
- - mc_bus->dprc_attr.version.major,
- - mc_bus->dprc_attr.version.minor);
- + major_ver, minor_ver);
- error = -ENOTSUPP;
- goto error_cleanup_open;
- }
- --- a/drivers/staging/fsl-mc/bus/dprc.c
- +++ b/drivers/staging/fsl-mc/bus/dprc.c
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2016 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -11,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -100,93 +100,6 @@ int dprc_close(struct fsl_mc_io *mc_io,
- EXPORT_SYMBOL(dprc_close);
-
- /**
- - * dprc_create_container() - Create child container
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @cfg: Child container configuration
- - * @child_container_id: Returned child container ID
- - * @child_portal_offset: Returned child portal offset from MC portal base
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_create_container(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dprc_cfg *cfg,
- - int *child_container_id,
- - u64 *child_portal_offset)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_create_container *cmd_params;
- - struct dprc_rsp_create_container *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd_params = (struct dprc_cmd_create_container *)cmd.params;
- - cmd_params->options = cpu_to_le32(cfg->options);
- - cmd_params->icid = cpu_to_le16(cfg->icid);
- - cmd_params->portal_id = cpu_to_le32(cfg->portal_id);
- - strncpy(cmd_params->label, cfg->label, 16);
- - cmd_params->label[15] = '\0';
- -
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT,
- - cmd_flags, token);
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dprc_rsp_create_container *)cmd.params;
- - *child_container_id = le32_to_cpu(rsp_params->child_container_id);
- - *child_portal_offset = le64_to_cpu(rsp_params->child_portal_addr);
- -
- - return 0;
- -}
- -
- -/**
- - * dprc_destroy_container() - Destroy child container.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @child_container_id: ID of the container to destroy
- - *
- - * This function terminates the child container, so following this call the
- - * child container ID becomes invalid.
- - *
- - * Notes:
- - * - All resources and objects of the destroyed container are returned to the
- - * parent container or destroyed if were created be the destroyed container.
- - * - This function destroy all the child containers of the specified
- - * container prior to destroying the container itself.
- - *
- - * warning: Only the parent container is allowed to destroy a child policy
- - * Container 0 can't be destroyed
- - *
- - * Return: '0' on Success; Error code otherwise.
- - *
- - */
- -int dprc_destroy_container(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_destroy_container *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_DESTROY_CONT,
- - cmd_flags, token);
- - cmd_params = (struct dprc_cmd_destroy_container *)cmd.params;
- - cmd_params->child_container_id = cpu_to_le32(child_container_id);
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- * dprc_reset_container - Reset child container.
- * @mc_io: Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- @@ -565,279 +478,6 @@ int dprc_get_attributes(struct fsl_mc_io
- attr->icid = le16_to_cpu(rsp_params->icid);
- attr->options = le32_to_cpu(rsp_params->options);
- attr->portal_id = le32_to_cpu(rsp_params->portal_id);
- - attr->version.major = le16_to_cpu(rsp_params->version_major);
- - attr->version.minor = le16_to_cpu(rsp_params->version_minor);
- -
- - return 0;
- -}
- -
- -/**
- - * dprc_set_res_quota() - Set allocation policy for a specific resource/object
- - * type in a child container
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @child_container_id: ID of the child container
- - * @type: Resource/object type
- - * @quota: Sets the maximum number of resources of the selected type
- - * that the child container is allowed to allocate from its parent;
- - * when quota is set to -1, the policy is the same as container's
- - * general policy.
- - *
- - * Allocation policy determines whether or not a container may allocate
- - * resources from its parent. Each container has a 'global' allocation policy
- - * that is set when the container is created.
- - *
- - * This function sets allocation policy for a specific resource type.
- - * The default policy for all resource types matches the container's 'global'
- - * allocation policy.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - *
- - * @warning Only the parent container is allowed to change a child policy.
- - */
- -int dprc_set_res_quota(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id,
- - char *type,
- - u16 quota)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_set_res_quota *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_RES_QUOTA,
- - cmd_flags, token);
- - cmd_params = (struct dprc_cmd_set_res_quota *)cmd.params;
- - cmd_params->child_container_id = cpu_to_le32(child_container_id);
- - cmd_params->quota = cpu_to_le16(quota);
- - strncpy(cmd_params->type, type, 16);
- - cmd_params->type[15] = '\0';
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dprc_get_res_quota() - Gets the allocation policy of a specific
- - * resource/object type in a child container
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @child_container_id; ID of the child container
- - * @type: resource/object type
- - * @quota: Returnes the maximum number of resources of the selected type
- - * that the child container is allowed to allocate from the parent;
- - * when quota is set to -1, the policy is the same as container's
- - * general policy.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_get_res_quota(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id,
- - char *type,
- - u16 *quota)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_get_res_quota *cmd_params;
- - struct dprc_rsp_get_res_quota *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_QUOTA,
- - cmd_flags, token);
- - cmd_params = (struct dprc_cmd_get_res_quota *)cmd.params;
- - cmd_params->child_container_id = cpu_to_le32(child_container_id);
- - strncpy(cmd_params->type, type, 16);
- - cmd_params->type[15] = '\0';
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dprc_rsp_get_res_quota *)cmd.params;
- - *quota = le16_to_cpu(rsp_params->quota);
- -
- - return 0;
- -}
- -
- -/**
- - * dprc_assign() - Assigns objects or resource to a child container.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @container_id: ID of the child container
- - * @res_req: Describes the type and amount of resources to
- - * assign to the given container
- - *
- - * Assignment is usually done by a parent (this DPRC) to one of its child
- - * containers.
- - *
- - * According to the DPRC allocation policy, the assigned resources may be taken
- - * (allocated) from the container's ancestors, if not enough resources are
- - * available in the container itself.
- - *
- - * The type of assignment depends on the dprc_res_req options, as follows:
- - * - DPRC_RES_REQ_OPT_EXPLICIT: indicates that assigned resources should have
- - * the explicit base ID specified at the id_base_align field of res_req.
- - * - DPRC_RES_REQ_OPT_ALIGNED: indicates that the assigned resources should be
- - * aligned to the value given at id_base_align field of res_req.
- - * - DPRC_RES_REQ_OPT_PLUGGED: Relevant only for object assignment,
- - * and indicates that the object must be set to the plugged state.
- - *
- - * A container may use this function with its own ID in order to change a
- - * object state to plugged or unplugged.
- - *
- - * If IRQ information has been set in the child DPRC, it will signal an
- - * interrupt following every change in its object assignment.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_assign(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int container_id,
- - struct dprc_res_req *res_req)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_assign *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_ASSIGN,
- - cmd_flags, token);
- - cmd_params = (struct dprc_cmd_assign *)cmd.params;
- - cmd_params->container_id = cpu_to_le32(container_id);
- - cmd_params->options = cpu_to_le32(res_req->options);
- - cmd_params->num = cpu_to_le32(res_req->num);
- - cmd_params->id_base_align = cpu_to_le32(res_req->id_base_align);
- - strncpy(cmd_params->type, res_req->type, 16);
- - cmd_params->type[15] = '\0';
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dprc_unassign() - Un-assigns objects or resources from a child container
- - * and moves them into this (parent) DPRC.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @child_container_id: ID of the child container
- - * @res_req: Describes the type and amount of resources to un-assign from
- - * the child container
- - *
- - * Un-assignment of objects can succeed only if the object is not in the
- - * plugged or opened state.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_unassign(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id,
- - struct dprc_res_req *res_req)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_unassign *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_UNASSIGN,
- - cmd_flags,
- - token);
- - cmd_params = (struct dprc_cmd_unassign *)cmd.params;
- - cmd_params->child_container_id = cpu_to_le32(child_container_id);
- - cmd_params->options = cpu_to_le32(res_req->options);
- - cmd_params->num = cpu_to_le32(res_req->num);
- - cmd_params->id_base_align = cpu_to_le32(res_req->id_base_align);
- - strncpy(cmd_params->type, res_req->type, 16);
- - cmd_params->type[15] = '\0';
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dprc_get_pool_count() - Get the number of dprc's pools
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @mc_io: Pointer to MC portal's I/O object
- - * @token: Token of DPRC object
- - * @pool_count: Returned number of resource pools in the dprc
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_get_pool_count(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int *pool_count)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_rsp_get_pool_count *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL_COUNT,
- - cmd_flags, token);
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dprc_rsp_get_pool_count *)cmd.params;
- - *pool_count = le32_to_cpu(rsp_params->pool_count);
- -
- - return 0;
- -}
- -
- -/**
- - * dprc_get_pool() - Get the type (string) of a certain dprc's pool
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @pool_index; Index of the pool to be queried (< pool_count)
- - * @type: The type of the pool
- - *
- - * The pool types retrieved one by one by incrementing
- - * pool_index up to (not including) the value of pool_count returned
- - * from dprc_get_pool_count(). dprc_get_pool_count() must
- - * be called prior to dprc_get_pool().
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_get_pool(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int pool_index,
- - char *type)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_get_pool *cmd_params;
- - struct dprc_rsp_get_pool *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL,
- - cmd_flags,
- - token);
- - cmd_params = (struct dprc_cmd_get_pool *)cmd.params;
- - cmd_params->pool_index = cpu_to_le32(pool_index);
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dprc_rsp_get_pool *)cmd.params;
- - strncpy(type, rsp_params->type, 16);
- - type[15] = '\0';
-
- return 0;
- }
- @@ -934,64 +574,6 @@ int dprc_get_obj(struct fsl_mc_io *mc_io
- EXPORT_SYMBOL(dprc_get_obj);
-
- /**
- - * dprc_get_obj_desc() - Get object descriptor.
- - *
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @obj_type: The type of the object to get its descriptor.
- - * @obj_id: The id of the object to get its descriptor
- - * @obj_desc: The returned descriptor to fill and return to the user
- - *
- - * Return: '0' on Success; Error code otherwise.
- - *
- - */
- -int dprc_get_obj_desc(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *obj_type,
- - int obj_id,
- - struct dprc_obj_desc *obj_desc)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_get_obj_desc *cmd_params;
- - struct dprc_rsp_get_obj_desc *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_DESC,
- - cmd_flags,
- - token);
- - cmd_params = (struct dprc_cmd_get_obj_desc *)cmd.params;
- - cmd_params->obj_id = cpu_to_le32(obj_id);
- - strncpy(cmd_params->type, obj_type, 16);
- - cmd_params->type[15] = '\0';
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dprc_rsp_get_obj_desc *)cmd.params;
- - obj_desc->id = le32_to_cpu(rsp_params->id);
- - obj_desc->vendor = le16_to_cpu(rsp_params->vendor);
- - obj_desc->irq_count = rsp_params->irq_count;
- - obj_desc->region_count = rsp_params->region_count;
- - obj_desc->state = le32_to_cpu(rsp_params->state);
- - obj_desc->ver_major = le16_to_cpu(rsp_params->version_major);
- - obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor);
- - obj_desc->flags = le16_to_cpu(rsp_params->flags);
- - strncpy(obj_desc->type, rsp_params->type, 16);
- - obj_desc->type[15] = '\0';
- - strncpy(obj_desc->label, rsp_params->label, 16);
- - obj_desc->label[15] = '\0';
- -
- - return 0;
- -}
- -EXPORT_SYMBOL(dprc_get_obj_desc);
- -
- -/**
- * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt.
- * @mc_io: Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- @@ -1130,52 +712,6 @@ int dprc_get_res_count(struct fsl_mc_io
- EXPORT_SYMBOL(dprc_get_res_count);
-
- /**
- - * dprc_get_res_ids() - Obtains IDs of free resources in the container
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @type: pool type
- - * @range_desc: range descriptor
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_get_res_ids(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *type,
- - struct dprc_res_ids_range_desc *range_desc)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_get_res_ids *cmd_params;
- - struct dprc_rsp_get_res_ids *rsp_params;
- - int err;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS,
- - cmd_flags, token);
- - cmd_params = (struct dprc_cmd_get_res_ids *)cmd.params;
- - cmd_params->iter_status = range_desc->iter_status;
- - cmd_params->base_id = cpu_to_le32(range_desc->base_id);
- - cmd_params->last_id = cpu_to_le32(range_desc->last_id);
- - strncpy(cmd_params->type, type, 16);
- - cmd_params->type[15] = '\0';
- -
- - /* send command to mc*/
- - err = mc_send_command(mc_io, &cmd);
- - if (err)
- - return err;
- -
- - /* retrieve response parameters */
- - rsp_params = (struct dprc_rsp_get_res_ids *)cmd.params;
- - range_desc->iter_status = rsp_params->iter_status;
- - range_desc->base_id = le32_to_cpu(rsp_params->base_id);
- - range_desc->last_id = le32_to_cpu(rsp_params->last_id);
- -
- - return 0;
- -}
- -EXPORT_SYMBOL(dprc_get_res_ids);
- -
- -/**
- * dprc_get_obj_region() - Get region information for a specified object.
- * @mc_io: Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- @@ -1216,160 +752,66 @@ int dprc_get_obj_region(struct fsl_mc_io
-
- /* retrieve response parameters */
- rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params;
- - region_desc->base_offset = le64_to_cpu(rsp_params->base_addr);
- + region_desc->base_offset = le32_to_cpu(rsp_params->base_addr);
- region_desc->size = le32_to_cpu(rsp_params->size);
- + region_desc->type = rsp_params->type;
- + region_desc->flags = le32_to_cpu(rsp_params->flags);
-
- return 0;
- }
- EXPORT_SYMBOL(dprc_get_obj_region);
-
- /**
- - * dprc_set_obj_label() - Set object label.
- - * @mc_io: Pointer to MC portal's I/O object
- + * dprc_get_api_version - Get Data Path Resource Container API version
- + * @mc_io: Pointer to Mc portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @obj_type: Object's type
- - * @obj_id: Object's ID
- - * @label: The required label. The maximum length is 16 chars.
- + * @major_ver: Major version of Data Path Resource Container API
- + * @minor_ver: Minor version of Data Path Resource Container API
- *
- * Return: '0' on Success; Error code otherwise.
- */
- -int dprc_set_obj_label(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *obj_type,
- - int obj_id,
- - char *label)
- +int dprc_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver)
- {
- struct mc_command cmd = { 0 };
- - struct dprc_cmd_set_obj_label *cmd_params;
- + int err;
-
- /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_LABEL,
- - cmd_flags,
- - token);
- - cmd_params = (struct dprc_cmd_set_obj_label *)cmd.params;
- - cmd_params->obj_id = cpu_to_le32(obj_id);
- - strncpy(cmd_params->label, label, 16);
- - cmd_params->label[15] = '\0';
- - strncpy(cmd_params->obj_type, obj_type, 16);
- - cmd_params->obj_type[15] = '\0';
- + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION,
- + cmd_flags, 0);
-
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -EXPORT_SYMBOL(dprc_set_obj_label);
- -
- -/**
- - * dprc_connect() - Connect two endpoints to create a network link between them
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @endpoint1: Endpoint 1 configuration parameters
- - * @endpoint2: Endpoint 2 configuration parameters
- - * @cfg: Connection configuration. The connection configuration is ignored for
- - * connections made to DPMAC objects, where rate is retrieved from the
- - * MAC configuration.
- - *
- - * Return: '0' on Success; Error code otherwise.
- - */
- -int dprc_connect(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - const struct dprc_endpoint *endpoint1,
- - const struct dprc_endpoint *endpoint2,
- - const struct dprc_connection_cfg *cfg)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_connect *cmd_params;
- + /* send command to mc */
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
-
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT,
- - cmd_flags,
- - token);
- - cmd_params = (struct dprc_cmd_connect *)cmd.params;
- - cmd_params->ep1_id = cpu_to_le32(endpoint1->id);
- - cmd_params->ep1_interface_id = cpu_to_le32(endpoint1->if_id);
- - cmd_params->ep2_id = cpu_to_le32(endpoint2->id);
- - cmd_params->ep2_interface_id = cpu_to_le32(endpoint2->if_id);
- - strncpy(cmd_params->ep1_type, endpoint1->type, 16);
- - cmd_params->ep1_type[15] = '\0';
- - cmd_params->max_rate = cpu_to_le32(cfg->max_rate);
- - cmd_params->committed_rate = cpu_to_le32(cfg->committed_rate);
- - strncpy(cmd_params->ep2_type, endpoint2->type, 16);
- - cmd_params->ep2_type[15] = '\0';
- + /* retrieve response parameters */
- + mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
-
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- + return 0;
- }
-
- /**
- - * dprc_disconnect() - Disconnect one endpoint to remove its network connection
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @endpoint: Endpoint configuration parameters
- + * dprc_get_container_id - Get container ID associated with a given portal.
- + * @mc_io: Pointer to Mc portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @container_id: Requested container id
- *
- * Return: '0' on Success; Error code otherwise.
- */
- -int dprc_disconnect(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - const struct dprc_endpoint *endpoint)
- -{
- - struct mc_command cmd = { 0 };
- - struct dprc_cmd_disconnect *cmd_params;
- -
- - /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT,
- - cmd_flags,
- - token);
- - cmd_params = (struct dprc_cmd_disconnect *)cmd.params;
- - cmd_params->id = cpu_to_le32(endpoint->id);
- - cmd_params->interface_id = cpu_to_le32(endpoint->if_id);
- - strncpy(cmd_params->type, endpoint->type, 16);
- - cmd_params->type[15] = '\0';
- -
- - /* send command to mc*/
- - return mc_send_command(mc_io, &cmd);
- -}
- -
- -/**
- - * dprc_get_connection() - Get connected endpoint and link status if connection
- - * exists.
- - * @mc_io: Pointer to MC portal's I/O object
- - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- - * @token: Token of DPRC object
- - * @endpoint1: Endpoint 1 configuration parameters
- - * @endpoint2: Returned endpoint 2 configuration parameters
- - * @state: Returned link state:
- - * 1 - link is up;
- - * 0 - link is down;
- - * -1 - no connection (endpoint2 information is irrelevant)
- - *
- - * Return: '0' on Success; -ENAVAIL if connection does not exist.
- - */
- -int dprc_get_connection(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - const struct dprc_endpoint *endpoint1,
- - struct dprc_endpoint *endpoint2,
- - int *state)
- +int dprc_get_container_id(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + int *container_id)
- {
- struct mc_command cmd = { 0 };
- - struct dprc_cmd_get_connection *cmd_params;
- - struct dprc_rsp_get_connection *rsp_params;
- int err;
-
- /* prepare command */
- - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,
- + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
- cmd_flags,
- - token);
- - cmd_params = (struct dprc_cmd_get_connection *)cmd.params;
- - cmd_params->ep1_id = cpu_to_le32(endpoint1->id);
- - cmd_params->ep1_interface_id = cpu_to_le32(endpoint1->if_id);
- - strncpy(cmd_params->ep1_type, endpoint1->type, 16);
- - cmd_params->ep1_type[15] = '\0';
- + 0);
-
- /* send command to mc*/
- err = mc_send_command(mc_io, &cmd);
- @@ -1377,12 +819,7 @@ int dprc_get_connection(struct fsl_mc_io
- return err;
-
- /* retrieve response parameters */
- - rsp_params = (struct dprc_rsp_get_connection *)cmd.params;
- - endpoint2->id = le32_to_cpu(rsp_params->ep2_id);
- - endpoint2->if_id = le32_to_cpu(rsp_params->ep2_interface_id);
- - strncpy(endpoint2->type, rsp_params->ep2_type, 16);
- - endpoint2->type[15] = '\0';
- - *state = le32_to_cpu(rsp_params->state);
- + *container_id = (int)mc_cmd_read_object_id(&cmd);
-
- return 0;
- }
- --- a/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c
- +++ b/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c
- @@ -1,7 +1,7 @@
- /*
- - * Freescale MC object device allocator driver
- + * fsl-mc object allocator driver
- *
- - * Copyright (C) 2013 Freescale Semiconductor, Inc.
- + * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- @@ -12,9 +12,9 @@
- #include <linux/msi.h>
- #include "../include/mc-bus.h"
- #include "../include/mc-sys.h"
- -#include "../include/dpbp-cmd.h"
- -#include "../include/dpcon-cmd.h"
-
- +#include "dpbp-cmd.h"
- +#include "dpcon-cmd.h"
- #include "fsl-mc-private.h"
-
- #define FSL_MC_IS_ALLOCATABLE(_obj_type) \
- @@ -23,15 +23,12 @@
- strcmp(_obj_type, "dpcon") == 0)
-
- /**
- - * fsl_mc_resource_pool_add_device - add allocatable device to a resource
- - * pool of a given MC bus
- + * fsl_mc_resource_pool_add_device - add allocatable object to a resource
- + * pool of a given fsl-mc bus
- *
- - * @mc_bus: pointer to the MC bus
- - * @pool_type: MC bus pool type
- - * @mc_dev: Pointer to allocatable MC object device
- - *
- - * It adds an allocatable MC object device to a container's resource pool of
- - * the given resource type
- + * @mc_bus: pointer to the fsl-mc bus
- + * @pool_type: pool type
- + * @mc_dev: pointer to allocatable fsl-mc device
- */
- static int __must_check fsl_mc_resource_pool_add_device(struct fsl_mc_bus
- *mc_bus,
- @@ -95,10 +92,10 @@ out:
- * fsl_mc_resource_pool_remove_device - remove an allocatable device from a
- * resource pool
- *
- - * @mc_dev: Pointer to allocatable MC object device
- + * @mc_dev: pointer to allocatable fsl-mc device
- *
- - * It permanently removes an allocatable MC object device from the resource
- - * pool, the device is currently in, as long as it is in the pool's free list.
- + * It permanently removes an allocatable fsl-mc device from the resource
- + * pool. It's an error if the device is in use.
- */
- static int __must_check fsl_mc_resource_pool_remove_device(struct fsl_mc_device
- *mc_dev)
- @@ -255,17 +252,18 @@ out_unlock:
- EXPORT_SYMBOL_GPL(fsl_mc_resource_free);
-
- /**
- - * fsl_mc_object_allocate - Allocates a MC object device of the given
- - * pool type from a given MC bus
- + * fsl_mc_object_allocate - Allocates an fsl-mc object of the given
- + * pool type from a given fsl-mc bus instance
- *
- - * @mc_dev: MC device for which the MC object device is to be allocated
- - * @pool_type: MC bus resource pool type
- - * @new_mc_dev: Pointer to area where the pointer to the allocated
- - * MC object device is to be returned
- + * @mc_dev: fsl-mc device which is used in conjunction with the
- + * allocated object
- + * @pool_type: pool type
- + * @new_mc_dev: pointer to area where the pointer to the allocated device
- + * is to be returned
- *
- - * This function allocates a MC object device from the device's parent DPRC,
- - * from the corresponding MC bus' pool of allocatable MC object devices of
- - * the given resource type. mc_dev cannot be a DPRC itself.
- + * Allocatable objects are always used in conjunction with some functional
- + * device. This function allocates an object of the specified type from
- + * the DPRC containing the functional device.
- *
- * NOTE: pool_type must be different from FSL_MC_POOL_MCP, since MC
- * portals are allocated using fsl_mc_portal_allocate(), instead of
- @@ -312,10 +310,9 @@ error:
- EXPORT_SYMBOL_GPL(fsl_mc_object_allocate);
-
- /**
- - * fsl_mc_object_free - Returns an allocatable MC object device to the
- - * corresponding resource pool of a given MC bus.
- - *
- - * @mc_adev: Pointer to the MC object device
- + * fsl_mc_object_free - Returns an fsl-mc object to the resource
- + * pool where it came from.
- + * @mc_adev: Pointer to the fsl-mc device
- */
- void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
- {
- @@ -332,8 +329,14 @@ void fsl_mc_object_free(struct fsl_mc_de
- EXPORT_SYMBOL_GPL(fsl_mc_object_free);
-
- /*
- - * Initialize the interrupt pool associated with a MC bus.
- - * It allocates a block of IRQs from the GIC-ITS
- + * A DPRC and the devices in the DPRC all share the same GIC-ITS device
- + * ID. A block of IRQs is pre-allocated and maintained in a pool
- + * from which devices can allocate them when needed.
- + */
- +
- +/*
- + * Initialize the interrupt pool associated with an fsl-mc bus.
- + * It allocates a block of IRQs from the GIC-ITS.
- */
- int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
- unsigned int irq_count)
- @@ -395,7 +398,7 @@ cleanup_msi_irqs:
- EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
-
- /**
- - * Teardown the interrupt pool associated with an MC bus.
- + * Teardown the interrupt pool associated with an fsl-mc bus.
- * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
- */
- void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
- @@ -422,11 +425,7 @@ void fsl_mc_cleanup_irq_pool(struct fsl_
- EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);
-
- /**
- - * It allocates the IRQs required by a given MC object device. The
- - * IRQs are allocated from the interrupt pool associated with the
- - * MC bus that contains the device, if the device is not a DPRC device.
- - * Otherwise, the IRQs are allocated from the interrupt pool associated
- - * with the MC bus that represents the DPRC device itself.
- + * Allocate the IRQs required by a given fsl-mc device.
- */
- int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev)
- {
- @@ -495,8 +494,7 @@ error_resource_alloc:
- EXPORT_SYMBOL_GPL(fsl_mc_allocate_irqs);
-
- /*
- - * It frees the IRQs that were allocated for a MC object device, by
- - * returning them to the corresponding interrupt pool.
- + * Frees the IRQs that were allocated for an fsl-mc device.
- */
- void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
- {
- @@ -605,7 +603,7 @@ static int fsl_mc_allocator_probe(struct
- return error;
-
- dev_dbg(&mc_dev->dev,
- - "Allocatable MC object device bound to fsl_mc_allocator driver");
- + "Allocatable fsl-mc device bound to fsl_mc_allocator driver");
- return 0;
- }
-
- @@ -627,7 +625,7 @@ static int fsl_mc_allocator_remove(struc
- }
-
- dev_dbg(&mc_dev->dev,
- - "Allocatable MC object device unbound from fsl_mc_allocator driver");
- + "Allocatable fsl-mc device unbound from fsl_mc_allocator driver");
- return 0;
- }
-
- --- a/drivers/staging/fsl-mc/bus/fsl-mc-bus.c
- +++ b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c
- @@ -1,7 +1,7 @@
- /*
- * Freescale Management Complex (MC) bus driver
- *
- - * Copyright (C) 2014 Freescale Semiconductor, Inc.
- + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Author: German Rivera <[email protected]>
- *
- * This file is licensed under the terms of the GNU General Public
- @@ -9,6 +9,8 @@
- * warranty of any kind, whether express or implied.
- */
-
- +#define pr_fmt(fmt) "fsl-mc: " fmt
- +
- #include <linux/module.h>
- #include <linux/of_device.h>
- #include <linux/of_address.h>
- @@ -25,8 +27,6 @@
- #include "fsl-mc-private.h"
- #include "dprc-cmd.h"
-
- -static struct kmem_cache *mc_dev_cache;
- -
- /**
- * Default DMA mask for devices on a fsl-mc bus
- */
- @@ -34,7 +34,7 @@ static struct kmem_cache *mc_dev_cache;
-
- /**
- * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
- - * @root_mc_bus_dev: MC object device representing the root DPRC
- + * @root_mc_bus_dev: fsl-mc device representing the root DPRC
- * @num_translation_ranges: number of entries in addr_translation_ranges
- * @translation_ranges: array of bus to system address translation ranges
- */
- @@ -62,8 +62,8 @@ struct fsl_mc_addr_translation_range {
-
- /**
- * fsl_mc_bus_match - device to driver matching callback
- - * @dev: the MC object device structure to match against
- - * @drv: the device driver to search for matching MC object device id
- + * @dev: the fsl-mc device to match against
- + * @drv: the device driver to search for matching fsl-mc object type
- * structures
- *
- * Returns 1 on success, 0 otherwise.
- @@ -75,8 +75,11 @@ static int fsl_mc_bus_match(struct devic
- struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
- bool found = false;
-
- - if (WARN_ON(!fsl_mc_bus_exists()))
- + /* When driver_override is set, only bind to the matching driver */
- + if (mc_dev->driver_override) {
- + found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);
- goto out;
- + }
-
- if (!mc_drv->match_id_table)
- goto out;
- @@ -91,7 +94,7 @@ static int fsl_mc_bus_match(struct devic
-
- /*
- * Traverse the match_id table of the given driver, trying to find
- - * a matching for the given MC object device.
- + * a matching for the given device.
- */
- for (id = mc_drv->match_id_table; id->vendor != 0x0; id++) {
- if (id->vendor == mc_dev->obj_desc.vendor &&
- @@ -132,23 +135,141 @@ static ssize_t modalias_show(struct devi
- }
- static DEVICE_ATTR_RO(modalias);
-
- +static ssize_t rescan_store(struct device *dev,
- + struct device_attribute *attr,
- + const char *buf, size_t count)
- +{
- + unsigned long val;
- + unsigned int irq_count;
- + struct fsl_mc_device *root_mc_dev;
- + struct fsl_mc_bus *root_mc_bus;
- +
- + if (!fsl_mc_is_root_dprc(dev))
- + return -EINVAL;
- +
- + root_mc_dev = to_fsl_mc_device(dev);
- + root_mc_bus = to_fsl_mc_bus(root_mc_dev);
- +
- + if (kstrtoul(buf, 0, &val) < 0)
- + return -EINVAL;
- +
- + if (val) {
- + mutex_lock(&root_mc_bus->scan_mutex);
- + dprc_scan_objects(root_mc_dev, NULL, &irq_count);
- + mutex_unlock(&root_mc_bus->scan_mutex);
- + }
- +
- + return count;
- +}
- +static DEVICE_ATTR_WO(rescan);
- +
- +static ssize_t driver_override_store(struct device *dev,
- + struct device_attribute *attr,
- + const char *buf, size_t count)
- +{
- + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
- + const char *driver_override, *old = mc_dev->driver_override;
- + char *cp;
- +
- + if (WARN_ON(dev->bus != &fsl_mc_bus_type))
- + return -EINVAL;
- +
- + if (count >= (PAGE_SIZE - 1))
- + return -EINVAL;
- +
- + driver_override = kstrndup(buf, count, GFP_KERNEL);
- + if (!driver_override)
- + return -ENOMEM;
- +
- + cp = strchr(driver_override, '\n');
- + if (cp)
- + *cp = '\0';
- +
- + if (strlen(driver_override)) {
- + mc_dev->driver_override = driver_override;
- + } else {
- + kfree(driver_override);
- + mc_dev->driver_override = NULL;
- + }
- +
- + kfree(old);
- +
- + return count;
- +}
- +
- +static ssize_t driver_override_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
- +
- + return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override);
- +}
- +static DEVICE_ATTR_RW(driver_override);
- +
- static struct attribute *fsl_mc_dev_attrs[] = {
- &dev_attr_modalias.attr,
- + &dev_attr_rescan.attr,
- + &dev_attr_driver_override.attr,
- NULL,
- };
-
- ATTRIBUTE_GROUPS(fsl_mc_dev);
-
- +static int scan_fsl_mc_bus(struct device *dev, void *data)
- +{
- + unsigned int irq_count;
- + struct fsl_mc_device *root_mc_dev;
- + struct fsl_mc_bus *root_mc_bus;
- +
- + if (fsl_mc_is_root_dprc(dev)) {
- + root_mc_dev = to_fsl_mc_device(dev);
- + root_mc_bus = to_fsl_mc_bus(root_mc_dev);
- + mutex_lock(&root_mc_bus->scan_mutex);
- + dprc_scan_objects(root_mc_dev, NULL, &irq_count);
- + mutex_unlock(&root_mc_bus->scan_mutex);
- + }
- +
- + return 0;
- +}
- +
- +static ssize_t bus_rescan_store(struct bus_type *bus,
- + const char *buf, size_t count)
- +{
- + unsigned long val;
- +
- + if (kstrtoul(buf, 0, &val) < 0)
- + return -EINVAL;
- +
- + if (val)
- + bus_for_each_dev(bus, NULL, NULL, scan_fsl_mc_bus);
- +
- + return count;
- +}
- +static BUS_ATTR(rescan, (S_IWUSR | S_IWGRP), NULL, bus_rescan_store);
- +
- +static struct attribute *fsl_mc_bus_attrs[] = {
- + &bus_attr_rescan.attr,
- + NULL,
- +};
- +
- +static const struct attribute_group fsl_mc_bus_group = {
- + .attrs = fsl_mc_bus_attrs,
- +};
- +
- +static const struct attribute_group *fsl_mc_bus_groups[] = {
- + &fsl_mc_bus_group,
- + NULL,
- +};
- +
- struct bus_type fsl_mc_bus_type = {
- .name = "fsl-mc",
- .match = fsl_mc_bus_match,
- .uevent = fsl_mc_bus_uevent,
- .dev_groups = fsl_mc_dev_groups,
- + .bus_groups = fsl_mc_bus_groups,
- };
- EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
-
- -static atomic_t root_dprc_count = ATOMIC_INIT(0);
- -
- static int fsl_mc_driver_probe(struct device *dev)
- {
- struct fsl_mc_driver *mc_drv;
- @@ -164,8 +285,7 @@ static int fsl_mc_driver_probe(struct de
-
- error = mc_drv->probe(mc_dev);
- if (error < 0) {
- - dev_err(dev, "MC object device probe callback failed: %d\n",
- - error);
- + dev_err(dev, "%s failed: %d\n", __func__, error);
- return error;
- }
-
- @@ -183,9 +303,7 @@ static int fsl_mc_driver_remove(struct d
-
- error = mc_drv->remove(mc_dev);
- if (error < 0) {
- - dev_err(dev,
- - "MC object device remove callback failed: %d\n",
- - error);
- + dev_err(dev, "%s failed: %d\n", __func__, error);
- return error;
- }
-
- @@ -232,8 +350,6 @@ int __fsl_mc_driver_register(struct fsl_
- return error;
- }
-
- - pr_info("MC object device driver %s registered\n",
- - mc_driver->driver.name);
- return 0;
- }
- EXPORT_SYMBOL_GPL(__fsl_mc_driver_register);
- @@ -249,15 +365,6 @@ void fsl_mc_driver_unregister(struct fsl
- EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister);
-
- /**
- - * fsl_mc_bus_exists - check if a root dprc exists
- - */
- -bool fsl_mc_bus_exists(void)
- -{
- - return atomic_read(&root_dprc_count) > 0;
- -}
- -EXPORT_SYMBOL_GPL(fsl_mc_bus_exists);
- -
- -/**
- * fsl_mc_get_root_dprc - function to traverse to the root dprc
- */
- void fsl_mc_get_root_dprc(struct device *dev,
- @@ -315,21 +422,6 @@ static int get_dprc_icid(struct fsl_mc_i
- return error;
- }
-
- -static int get_dprc_version(struct fsl_mc_io *mc_io,
- - int container_id, u16 *major, u16 *minor)
- -{
- - struct dprc_attributes attr;
- - int error;
- -
- - error = get_dprc_attr(mc_io, container_id, &attr);
- - if (error == 0) {
- - *major = attr.version.major;
- - *minor = attr.version.minor;
- - }
- -
- - return error;
- -}
- -
- static int translate_mc_addr(struct fsl_mc_device *mc_dev,
- enum dprc_region_type mc_region_type,
- u64 mc_offset, phys_addr_t *phys_addr)
- @@ -451,18 +543,37 @@ bool fsl_mc_is_root_dprc(struct device *
- return dev == root_dprc_dev;
- }
-
- +static void fsl_mc_device_release(struct device *dev)
- +{
- + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
- + struct fsl_mc_bus *mc_bus = NULL;
- +
- + kfree(mc_dev->regions);
- +
- + if (strcmp(mc_dev->obj_desc.type, "dprc") == 0)
- + mc_bus = to_fsl_mc_bus(mc_dev);
- +
- + if (mc_bus)
- + kfree(mc_bus);
- + else
- + kfree(mc_dev);
- +}
- +
- /**
- - * Add a newly discovered MC object device to be visible in Linux
- + * Add a newly discovered fsl-mc device to be visible in Linux
- */
- int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
- struct fsl_mc_io *mc_io,
- struct device *parent_dev,
- + const char *driver_override,
- struct fsl_mc_device **new_mc_dev)
- {
- int error;
- struct fsl_mc_device *mc_dev = NULL;
- struct fsl_mc_bus *mc_bus = NULL;
- struct fsl_mc_device *parent_mc_dev;
- + struct device *fsl_mc_platform_dev;
- + struct device_node *fsl_mc_platform_node;
-
- if (dev_is_fsl_mc(parent_dev))
- parent_mc_dev = to_fsl_mc_device(parent_dev);
- @@ -473,7 +584,7 @@ int fsl_mc_device_add(struct dprc_obj_de
- /*
- * Allocate an MC bus device object:
- */
- - mc_bus = devm_kzalloc(parent_dev, sizeof(*mc_bus), GFP_KERNEL);
- + mc_bus = kzalloc(sizeof(*mc_bus), GFP_KERNEL);
- if (!mc_bus)
- return -ENOMEM;
-
- @@ -482,16 +593,30 @@ int fsl_mc_device_add(struct dprc_obj_de
- /*
- * Allocate a regular fsl_mc_device object:
- */
- - mc_dev = kmem_cache_zalloc(mc_dev_cache, GFP_KERNEL);
- + mc_dev = kzalloc(sizeof(*mc_dev), GFP_KERNEL);
- if (!mc_dev)
- return -ENOMEM;
- }
-
- mc_dev->obj_desc = *obj_desc;
- mc_dev->mc_io = mc_io;
- +
- + if (driver_override) {
- + /*
- + * We trust driver_override, so we don't need to use
- + * kstrndup() here
- + */
- + mc_dev->driver_override = kstrdup(driver_override, GFP_KERNEL);
- + if (!mc_dev->driver_override) {
- + error = -ENOMEM;
- + goto error_cleanup_dev;
- + }
- + }
- +
- device_initialize(&mc_dev->dev);
- mc_dev->dev.parent = parent_dev;
- mc_dev->dev.bus = &fsl_mc_bus_type;
- + mc_dev->dev.release = fsl_mc_device_release;
- dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id);
-
- if (strcmp(obj_desc->type, "dprc") == 0) {
- @@ -524,8 +649,6 @@ int fsl_mc_device_add(struct dprc_obj_de
- }
-
- mc_io2 = mc_io;
- -
- - atomic_inc(&root_dprc_count);
- }
-
- error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid);
- @@ -533,8 +656,8 @@ int fsl_mc_device_add(struct dprc_obj_de
- goto error_cleanup_dev;
- } else {
- /*
- - * A non-DPRC MC object device has to be a child of another
- - * MC object (specifically a DPRC object)
- + * A non-DPRC object has to be a child of a DPRC, use the
- + * parent's ICID and interrupt domain.
- */
- mc_dev->icid = parent_mc_dev->icid;
- mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
- @@ -556,9 +679,14 @@ int fsl_mc_device_add(struct dprc_obj_de
- goto error_cleanup_dev;
- }
-
- - /* Objects are coherent, unless 'no shareability' flag set. */
- - if (!(obj_desc->flags & DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY))
- - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true);
- + fsl_mc_platform_dev = &mc_dev->dev;
- + while (dev_is_fsl_mc(fsl_mc_platform_dev))
- + fsl_mc_platform_dev = fsl_mc_platform_dev->parent;
- + fsl_mc_platform_node = fsl_mc_platform_dev->of_node;
- +
- + /* Set up the iommu configuration for the devices. */
- + fsl_mc_dma_configure(mc_dev, fsl_mc_platform_node,
- + !(obj_desc->flags & DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY));
-
- /*
- * The device-specific probe callback will get invoked by device_add()
- @@ -571,9 +699,7 @@ int fsl_mc_device_add(struct dprc_obj_de
- goto error_cleanup_dev;
- }
-
- - (void)get_device(&mc_dev->dev);
- - dev_dbg(parent_dev, "Added MC object device %s\n",
- - dev_name(&mc_dev->dev));
- + dev_dbg(parent_dev, "added %s\n", dev_name(&mc_dev->dev));
-
- *new_mc_dev = mc_dev;
- return 0;
- @@ -581,47 +707,34 @@ int fsl_mc_device_add(struct dprc_obj_de
- error_cleanup_dev:
- kfree(mc_dev->regions);
- if (mc_bus)
- - devm_kfree(parent_dev, mc_bus);
- + kfree(mc_bus);
- else
- - kmem_cache_free(mc_dev_cache, mc_dev);
- + kfree(mc_dev);
-
- return error;
- }
- EXPORT_SYMBOL_GPL(fsl_mc_device_add);
-
- /**
- - * fsl_mc_device_remove - Remove a MC object device from being visible to
- + * fsl_mc_device_remove - Remove an fsl-mc device from being visible to
- * Linux
- *
- - * @mc_dev: Pointer to a MC object device object
- + * @mc_dev: Pointer to an fsl-mc device
- */
- void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
- {
- - struct fsl_mc_bus *mc_bus = NULL;
- -
- - kfree(mc_dev->regions);
- + kfree(mc_dev->driver_override);
- + mc_dev->driver_override = NULL;
-
- /*
- * The device-specific remove callback will get invoked by device_del()
- */
- device_del(&mc_dev->dev);
- - put_device(&mc_dev->dev);
-
- - if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) {
- - mc_bus = to_fsl_mc_bus(mc_dev);
- -
- - if (fsl_mc_is_root_dprc(&mc_dev->dev)) {
- - if (atomic_read(&root_dprc_count) > 0)
- - atomic_dec(&root_dprc_count);
- - else
- - WARN_ON(1);
- - }
- - }
- + if (strcmp(mc_dev->obj_desc.type, "dprc") != 0)
- + mc_dev->dev.iommu_fwspec = NULL;
-
- - if (mc_bus)
- - devm_kfree(mc_dev->dev.parent, mc_bus);
- - else
- - kmem_cache_free(mc_dev_cache, mc_dev);
- + put_device(&mc_dev->dev);
- }
- EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
-
- @@ -629,8 +742,7 @@ static int parse_mc_ranges(struct device
- int *paddr_cells,
- int *mc_addr_cells,
- int *mc_size_cells,
- - const __be32 **ranges_start,
- - u8 *num_ranges)
- + const __be32 **ranges_start)
- {
- const __be32 *prop;
- int range_tuple_cell_count;
- @@ -643,8 +755,6 @@ static int parse_mc_ranges(struct device
- dev_warn(dev,
- "missing or empty ranges property for device tree node '%s'\n",
- mc_node->name);
- -
- - *num_ranges = 0;
- return 0;
- }
-
- @@ -671,8 +781,7 @@ static int parse_mc_ranges(struct device
- return -EINVAL;
- }
-
- - *num_ranges = ranges_len / tuple_len;
- - return 0;
- + return ranges_len / tuple_len;
- }
-
- static int get_mc_addr_translation_ranges(struct device *dev,
- @@ -680,7 +789,7 @@ static int get_mc_addr_translation_range
- **ranges,
- u8 *num_ranges)
- {
- - int error;
- + int ret;
- int paddr_cells;
- int mc_addr_cells;
- int mc_size_cells;
- @@ -688,16 +797,16 @@ static int get_mc_addr_translation_range
- const __be32 *ranges_start;
- const __be32 *cell;
-
- - error = parse_mc_ranges(dev,
- + ret = parse_mc_ranges(dev,
- &paddr_cells,
- &mc_addr_cells,
- &mc_size_cells,
- - &ranges_start,
- - num_ranges);
- - if (error < 0)
- - return error;
- + &ranges_start);
- + if (ret < 0)
- + return ret;
-
- - if (!(*num_ranges)) {
- + *num_ranges = ret;
- + if (!ret) {
- /*
- * Missing or empty ranges property ("ranges;") for the
- * 'fsl,qoriq-mc' node. In this case, identity mapping
- @@ -749,8 +858,6 @@ static int fsl_mc_bus_probe(struct platf
- struct mc_version mc_version;
- struct resource res;
-
- - dev_info(&pdev->dev, "Root MC bus device probed");
- -
- mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
- if (!mc)
- return -ENOMEM;
- @@ -783,8 +890,7 @@ static int fsl_mc_bus_probe(struct platf
- goto error_cleanup_mc_io;
- }
-
- - dev_info(&pdev->dev,
- - "Freescale Management Complex Firmware version: %u.%u.%u\n",
- + dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
- mc_version.major, mc_version.minor, mc_version.revision);
-
- error = get_mc_addr_translation_ranges(&pdev->dev,
- @@ -793,16 +899,17 @@ static int fsl_mc_bus_probe(struct platf
- if (error < 0)
- goto error_cleanup_mc_io;
-
- - error = dpmng_get_container_id(mc_io, 0, &container_id);
- + error = dprc_get_container_id(mc_io, 0, &container_id);
- if (error < 0) {
- dev_err(&pdev->dev,
- - "dpmng_get_container_id() failed: %d\n", error);
- + "dprc_get_container_id() failed: %d\n", error);
- goto error_cleanup_mc_io;
- }
-
- memset(&obj_desc, 0, sizeof(struct dprc_obj_desc));
- - error = get_dprc_version(mc_io, container_id,
- - &obj_desc.ver_major, &obj_desc.ver_minor);
- + error = dprc_get_api_version(mc_io, 0,
- + &obj_desc.ver_major,
- + &obj_desc.ver_minor);
- if (error < 0)
- goto error_cleanup_mc_io;
-
- @@ -812,7 +919,8 @@ static int fsl_mc_bus_probe(struct platf
- obj_desc.irq_count = 1;
- obj_desc.region_count = 0;
-
- - error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
- + error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, NULL,
- + &mc_bus_dev);
- if (error < 0)
- goto error_cleanup_mc_io;
-
- @@ -840,7 +948,6 @@ static int fsl_mc_bus_remove(struct plat
- fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io);
- mc->root_mc_bus_dev->mc_io = NULL;
-
- - dev_info(&pdev->dev, "Root MC bus device removed");
- return 0;
- }
-
- @@ -865,22 +972,12 @@ static int __init fsl_mc_bus_driver_init
- {
- int error;
-
- - mc_dev_cache = kmem_cache_create("fsl_mc_device",
- - sizeof(struct fsl_mc_device), 0, 0,
- - NULL);
- - if (!mc_dev_cache) {
- - pr_err("Could not create fsl_mc_device cache\n");
- - return -ENOMEM;
- - }
- -
- error = bus_register(&fsl_mc_bus_type);
- if (error < 0) {
- - pr_err("fsl-mc bus type registration failed: %d\n", error);
- + pr_err("bus type registration failed: %d\n", error);
- goto error_cleanup_cache;
- }
-
- - pr_info("fsl-mc bus type registered\n");
- -
- error = platform_driver_register(&fsl_mc_bus_driver);
- if (error < 0) {
- pr_err("platform_driver_register() failed: %d\n", error);
- @@ -914,7 +1011,6 @@ error_cleanup_bus:
- bus_unregister(&fsl_mc_bus_type);
-
- error_cleanup_cache:
- - kmem_cache_destroy(mc_dev_cache);
- return error;
- }
- postcore_initcall(fsl_mc_bus_driver_init);
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/fsl-mc-iommu.c
- @@ -0,0 +1,104 @@
- +/*
- + * Copyright 2016-17 NXP
- + * Author: Nipun Gupta <[email protected]>
- + *
- + * This file is licensed under the terms of the GNU General Public
- + * License version 2. This program is licensed "as is" without any
- + * warranty of any kind, whether express or implied.
- + */
- +
- +#include <linux/iommu.h>
- +#include <linux/of.h>
- +#include <linux/of_iommu.h>
- +#include "../include/mc.h"
- +
- +/* Setup the IOMMU for the DPRC container */
- +static const struct iommu_ops
- +*fsl_mc_iommu_configure(struct fsl_mc_device *mc_dev,
- + struct device_node *fsl_mc_platform_node)
- +{
- + struct of_phandle_args iommu_spec;
- + const struct iommu_ops *ops;
- + u32 iommu_phandle;
- + struct device_node *iommu_node;
- + const __be32 *map = NULL;
- + int iommu_cells, map_len, ret;
- +
- + map = of_get_property(fsl_mc_platform_node, "iommu-map", &map_len);
- + if (!map)
- + return NULL;
- +
- + ops = mc_dev->dev.bus->iommu_ops;
- + if (!ops || !ops->of_xlate)
- + return NULL;
- +
- + iommu_phandle = be32_to_cpup(map + 1);
- + iommu_node = of_find_node_by_phandle(iommu_phandle);
- +
- + if (of_property_read_u32(iommu_node, "#iommu-cells", &iommu_cells)) {
- + pr_err("%s: missing #iommu-cells property\n", iommu_node->name);
- + return NULL;
- + }
- +
- + /* Initialize the fwspec */
- + ret = iommu_fwspec_init(&mc_dev->dev, &iommu_node->fwnode, ops);
- + if (ret)
- + return NULL;
- +
- + /*
- + * Fill in the required stream-id before calling the iommu's
- + * ops->xlate callback.
- + */
- + iommu_spec.np = iommu_node;
- + iommu_spec.args[0] = mc_dev->icid;
- + iommu_spec.args_count = 1;
- +
- + ret = ops->of_xlate(&mc_dev->dev, &iommu_spec);
- + if (ret)
- + return NULL;
- +
- + of_node_put(iommu_spec.np);
- +
- + return ops;
- +}
- +
- +/* Set up DMA configuration for fsl-mc devices */
- +void fsl_mc_dma_configure(struct fsl_mc_device *mc_dev,
- + struct device_node *fsl_mc_platform_node, int coherent)
- +{
- + const struct iommu_ops *ops;
- +
- + ops = fsl_mc_iommu_configure(mc_dev, fsl_mc_platform_node);
- +
- + mc_dev->dev.coherent_dma_mask = DMA_BIT_MASK(48);
- + mc_dev->dev.dma_mask = &mc_dev->dev.coherent_dma_mask;
- + arch_setup_dma_ops(&mc_dev->dev, 0,
- + mc_dev->dev.coherent_dma_mask + 1, ops, coherent);
- +}
- +
- +/* Macro to get the container device of a MC device */
- +#define fsl_mc_cont_dev(_dev) ((to_fsl_mc_device(_dev)->flags & \
- + FSL_MC_IS_DPRC) ? (_dev) : ((_dev)->parent))
- +
- +/* Macro to check if a device is a container device */
- +#define is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & FSL_MC_IS_DPRC)
- +
- +/* Get the IOMMU group for device on fsl-mc bus */
- +struct iommu_group *fsl_mc_device_group(struct device *dev)
- +{
- + struct device *cont_dev = fsl_mc_cont_dev(dev);
- + struct iommu_group *group;
- +
- + /* Container device is responsible for creating the iommu group */
- + if (is_cont_dev(dev)) {
- + group = iommu_group_alloc();
- + if (IS_ERR(group))
- + return NULL;
- + } else {
- + get_device(cont_dev);
- + group = iommu_group_get(cont_dev);
- + put_device(cont_dev);
- + }
- +
- + return group;
- +}
- --- a/drivers/staging/fsl-mc/bus/fsl-mc-msi.c
- +++ b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c
- @@ -1,7 +1,7 @@
- /*
- * Freescale Management Complex (MC) bus driver MSI support
- *
- - * Copyright (C) 2015 Freescale Semiconductor, Inc.
- + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
- * Author: German Rivera <[email protected]>
- *
- * This file is licensed under the terms of the GNU General Public
- --- a/drivers/staging/fsl-mc/bus/fsl-mc-private.h
- +++ b/drivers/staging/fsl-mc/bus/fsl-mc-private.h
- @@ -10,13 +10,15 @@
- #ifndef _FSL_MC_PRIVATE_H_
- #define _FSL_MC_PRIVATE_H_
-
- +#include "../include/mc.h"
- +#include "../include/mc-bus.h"
- +
- int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
- struct fsl_mc_io *mc_io,
- struct device *parent_dev,
- + const char *driver_override,
- struct fsl_mc_device **new_mc_dev);
-
- -void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
- -
- int __init dprc_driver_init(void);
-
- void dprc_driver_exit(void);
- --- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
- +++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
- @@ -1,7 +1,7 @@
- /*
- * Freescale Management Complex (MC) bus driver MSI support
- *
- - * Copyright (C) 2015 Freescale Semiconductor, Inc.
- + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
- * Author: German Rivera <[email protected]>
- *
- * This file is licensed under the terms of the GNU General Public
- @@ -20,7 +20,7 @@
- #include "fsl-mc-private.h"
-
- static struct irq_chip its_msi_irq_chip = {
- - .name = "fsl-mc-bus-msi",
- + .name = "ITS-fMSI",
- .irq_mask = irq_chip_mask_parent,
- .irq_unmask = irq_chip_unmask_parent,
- .irq_eoi = irq_chip_eoi_parent,
- @@ -52,7 +52,7 @@ static int its_fsl_mc_msi_prepare(struct
- return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
- }
-
- -static struct msi_domain_ops its_fsl_mc_msi_ops = {
- +static struct msi_domain_ops its_fsl_mc_msi_ops __ro_after_init = {
- .msi_prepare = its_fsl_mc_msi_prepare,
- };
-
- @@ -97,8 +97,8 @@ int __init its_fsl_mc_msi_init(void)
- continue;
- }
-
- - WARN_ON(mc_msi_domain->
- - host_data != &its_fsl_mc_msi_domain_info);
- + WARN_ON(mc_msi_domain->host_data !=
- + &its_fsl_mc_msi_domain_info);
-
- pr_info("fsl-mc MSI: %s domain created\n", np->full_name);
- }
- --- a/drivers/staging/fsl-mc/bus/mc-io.c
- +++ b/drivers/staging/fsl-mc/bus/mc-io.c
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2016 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -11,7 +12,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/mc-ioctl.h
- @@ -0,0 +1,22 @@
- +/*
- + * Freescale Management Complex (MC) ioclt interface
- + *
- + * Copyright (C) 2014 Freescale Semiconductor, Inc.
- + * Author: Lijun Pan <[email protected]>
- + *
- + * This file is licensed under the terms of the GNU General Public
- + * License version 2. This program is licensed "as is" without any
- + * warranty of any kind, whether express or implied.
- + */
- +#ifndef _FSL_MC_IOCTL_H_
- +#define _FSL_MC_IOCTL_H_
- +
- +#include <linux/ioctl.h>
- +#include "../include/mc-sys.h"
- +
- +#define RESTOOL_IOCTL_TYPE 'R'
- +
- +#define RESTOOL_SEND_MC_COMMAND \
- + _IOWR(RESTOOL_IOCTL_TYPE, 0xE0, struct mc_command)
- +
- +#endif /* _FSL_MC_IOCTL_H_ */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/bus/mc-restool.c
- @@ -0,0 +1,405 @@
- +/*
- + * Freescale Management Complex (MC) restool driver
- + *
- + * Copyright (C) 2014 Freescale Semiconductor, Inc.
- + * Author: Lijun Pan <[email protected]>
- + *
- + * This file is licensed under the terms of the GNU General Public
- + * License version 2. This program is licensed "as is" without any
- + * warranty of any kind, whether express or implied.
- + */
- +
- +#include "../include/mc.h"
- +#include <linux/module.h>
- +#include <linux/fs.h>
- +#include <linux/miscdevice.h>
- +#include <linux/mm.h>
- +#include <linux/slab.h>
- +#include <linux/uaccess.h>
- +#include <linux/mutex.h>
- +#include <linux/platform_device.h>
- +#include "mc-ioctl.h"
- +#include "../include/mc-sys.h"
- +#include "../include/mc-bus.h"
- +#include "../include/mc-cmd.h"
- +#include "../include/dpmng.h"
- +
- +/**
- + * Maximum number of DPRCs that can be opened at the same time
- + */
- +#define MAX_DPRC_HANDLES 64
- +
- +/**
- + * restool_misc - information associated with the newly added miscdevice
- + * @misc: newly created miscdevice associated with root dprc
- + * @miscdevt: device id of this miscdevice
- + * @list: a linked list node representing this miscdevcie
- + * @static_mc_io: pointer to the static MC I/O object used by the restool
- + * @dynamic_instance_count: number of dynamically created instances
- + * @static_instance_in_use: static instance is in use or not
- + * @mutex: mutex lock to serialze the open/release operations
- + * @dev: root dprc associated with this miscdevice
- + */
- +struct restool_misc {
- + struct miscdevice misc;
- + dev_t miscdevt;
- + struct list_head list;
- + struct fsl_mc_io *static_mc_io;
- + u32 dynamic_instance_count;
- + bool static_instance_in_use;
- + struct mutex mutex; /* serialze the open/release operations */
- + struct device *dev;
- +};
- +
- +/**
- + * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
- + * @root_mc_bus_dev: fsl-mc device representing the root DPRC
- + * @num_translation_ranges: number of entries in addr_translation_ranges
- + * @translation_ranges: array of bus to system address translation ranges
- + */
- +struct fsl_mc {
- + struct fsl_mc_device *root_mc_bus_dev;
- + u8 num_translation_ranges;
- + struct fsl_mc_addr_translation_range *translation_ranges;
- +};
- +
- +/*
- + * initialize a global list to link all
- + * the miscdevice nodes (struct restool_misc)
- + */
- +static LIST_HEAD(misc_list);
- +static DEFINE_MUTEX(misc_list_mutex);
- +
- +static int fsl_mc_restool_dev_open(struct inode *inode, struct file *filep)
- +{
- + struct fsl_mc_device *root_mc_dev;
- + int error;
- + struct fsl_mc_io *dynamic_mc_io = NULL;
- + struct restool_misc *restool_misc = NULL;
- + struct restool_misc *restool_misc_cursor;
- +
- + mutex_lock(&misc_list_mutex);
- +
- + list_for_each_entry(restool_misc_cursor, &misc_list, list) {
- + if (restool_misc_cursor->miscdevt == inode->i_rdev) {
- + restool_misc = restool_misc_cursor;
- + break;
- + }
- + }
- +
- + mutex_unlock(&misc_list_mutex);
- +
- + if (!restool_misc)
- + return -EINVAL;
- +
- + if (WARN_ON(!restool_misc->dev))
- + return -EINVAL;
- +
- + mutex_lock(&restool_misc->mutex);
- +
- + if (!restool_misc->static_instance_in_use) {
- + restool_misc->static_instance_in_use = true;
- + filep->private_data = restool_misc->static_mc_io;
- + } else {
- + dynamic_mc_io = kzalloc(sizeof(*dynamic_mc_io), GFP_KERNEL);
- + if (!dynamic_mc_io) {
- + error = -ENOMEM;
- + goto err_unlock;
- + }
- +
- + root_mc_dev = to_fsl_mc_device(restool_misc->dev);
- + error = fsl_mc_portal_allocate(root_mc_dev, 0, &dynamic_mc_io);
- + if (error < 0) {
- + pr_err("Not able to allocate MC portal\n");
- + goto free_dynamic_mc_io;
- + }
- + ++restool_misc->dynamic_instance_count;
- + filep->private_data = dynamic_mc_io;
- + }
- +
- + mutex_unlock(&restool_misc->mutex);
- +
- + return 0;
- +
- +free_dynamic_mc_io:
- + kfree(dynamic_mc_io);
- +err_unlock:
- + mutex_unlock(&restool_misc->mutex);
- +
- + return error;
- +}
- +
- +static int fsl_mc_restool_dev_release(struct inode *inode, struct file *filep)
- +{
- + struct fsl_mc_io *local_mc_io = filep->private_data;
- + struct restool_misc *restool_misc = NULL;
- + struct restool_misc *restool_misc_cursor;
- +
- + if (WARN_ON(!filep->private_data))
- + return -EINVAL;
- +
- + mutex_lock(&misc_list_mutex);
- +
- + list_for_each_entry(restool_misc_cursor, &misc_list, list) {
- + if (restool_misc_cursor->miscdevt == inode->i_rdev) {
- + restool_misc = restool_misc_cursor;
- + break;
- + }
- + }
- +
- + mutex_unlock(&misc_list_mutex);
- +
- + if (!restool_misc)
- + return -EINVAL;
- +
- + mutex_lock(&restool_misc->mutex);
- +
- + if (WARN_ON(restool_misc->dynamic_instance_count == 0 &&
- + !restool_misc->static_instance_in_use)) {
- + mutex_unlock(&restool_misc->mutex);
- + return -EINVAL;
- + }
- +
- + /* Globally clean up opened/untracked handles */
- + fsl_mc_portal_reset(local_mc_io);
- +
- + /*
- + * must check
- + * whether local_mc_io is dynamic or static instance
- + * Otherwise it will free up the reserved portal by accident
- + * or even not free up the dynamic allocated portal
- + * if 2 or more instances running concurrently
- + */
- + if (local_mc_io == restool_misc->static_mc_io) {
- + restool_misc->static_instance_in_use = false;
- + } else {
- + fsl_mc_portal_free(local_mc_io);
- + kfree(filep->private_data);
- + --restool_misc->dynamic_instance_count;
- + }
- +
- + filep->private_data = NULL;
- + mutex_unlock(&restool_misc->mutex);
- +
- + return 0;
- +}
- +
- +static int restool_send_mc_command(unsigned long arg,
- + struct fsl_mc_io *local_mc_io)
- +{
- + int error;
- + struct mc_command mc_cmd;
- +
- + if (copy_from_user(&mc_cmd, (void __user *)arg, sizeof(mc_cmd)))
- + return -EFAULT;
- +
- + /*
- + * Send MC command to the MC:
- + */
- + error = mc_send_command(local_mc_io, &mc_cmd);
- + if (error < 0)
- + return error;
- +
- + if (copy_to_user((void __user *)arg, &mc_cmd, sizeof(mc_cmd)))
- + return -EFAULT;
- +
- + return 0;
- +}
- +
- +static long
- +fsl_mc_restool_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
- +{
- + int error;
- +
- + switch (cmd) {
- + case RESTOOL_SEND_MC_COMMAND:
- + error = restool_send_mc_command(arg, file->private_data);
- + break;
- + default:
- + pr_err("%s: unexpected ioctl call number\n", __func__);
- + error = -EINVAL;
- + }
- +
- + return error;
- +}
- +
- +static const struct file_operations fsl_mc_restool_dev_fops = {
- + .owner = THIS_MODULE,
- + .open = fsl_mc_restool_dev_open,
- + .release = fsl_mc_restool_dev_release,
- + .unlocked_ioctl = fsl_mc_restool_dev_ioctl,
- +};
- +
- +static int restool_add_device_file(struct device *dev)
- +{
- + u32 name1 = 0;
- + char name2[20] = {0};
- + int error;
- + struct fsl_mc_device *root_mc_dev;
- + struct restool_misc *restool_misc;
- +
- + if (dev->bus == &platform_bus_type && dev->driver_data) {
- + if (sscanf(dev_name(dev), "%x.%s", &name1, name2) != 2)
- + return -EINVAL;
- +
- + if (strcmp(name2, "fsl-mc") == 0)
- + pr_debug("platform's root dprc name is: %s\n",
- + dev_name(&(((struct fsl_mc *)
- + (dev->driver_data))->root_mc_bus_dev->dev)));
- + }
- +
- + if (!fsl_mc_is_root_dprc(dev))
- + return 0;
- +
- + restool_misc = kzalloc(sizeof(*restool_misc), GFP_KERNEL);
- + if (!restool_misc)
- + return -ENOMEM;
- +
- + restool_misc->dev = dev;
- + root_mc_dev = to_fsl_mc_device(dev);
- + error = fsl_mc_portal_allocate(root_mc_dev, 0,
- + &restool_misc->static_mc_io);
- + if (error < 0) {
- + pr_err("Not able to allocate MC portal\n");
- + goto free_restool_misc;
- + }
- +
- + restool_misc->misc.minor = MISC_DYNAMIC_MINOR;
- + restool_misc->misc.name = dev_name(dev);
- + restool_misc->misc.fops = &fsl_mc_restool_dev_fops;
- +
- + error = misc_register(&restool_misc->misc);
- + if (error < 0) {
- + pr_err("misc_register() failed: %d\n", error);
- + goto free_portal;
- + }
- +
- + restool_misc->miscdevt = restool_misc->misc.this_device->devt;
- + mutex_init(&restool_misc->mutex);
- + mutex_lock(&misc_list_mutex);
- + list_add(&restool_misc->list, &misc_list);
- + mutex_unlock(&misc_list_mutex);
- +
- + pr_info("/dev/%s driver registered\n", dev_name(dev));
- +
- + return 0;
- +
- +free_portal:
- + fsl_mc_portal_free(restool_misc->static_mc_io);
- +free_restool_misc:
- + kfree(restool_misc);
- +
- + return error;
- +}
- +
- +static int restool_bus_notifier(struct notifier_block *nb,
- + unsigned long action, void *data)
- +{
- + int error;
- + struct device *dev = data;
- +
- + switch (action) {
- + case BUS_NOTIFY_ADD_DEVICE:
- + error = restool_add_device_file(dev);
- + if (error)
- + return error;
- + break;
- + case BUS_NOTIFY_DEL_DEVICE:
- + case BUS_NOTIFY_REMOVED_DEVICE:
- + case BUS_NOTIFY_BIND_DRIVER:
- + case BUS_NOTIFY_BOUND_DRIVER:
- + case BUS_NOTIFY_UNBIND_DRIVER:
- + case BUS_NOTIFY_UNBOUND_DRIVER:
- + break;
- + default:
- + pr_err("%s: unrecognized device action from %s\n", __func__,
- + dev_name(dev));
- + return -EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +static int add_to_restool(struct device *dev, void *data)
- +{
- + return restool_add_device_file(dev);
- +}
- +
- +static int __init fsl_mc_restool_driver_init(void)
- +{
- + int error;
- + struct notifier_block *nb;
- +
- + nb = kzalloc(sizeof(*nb), GFP_KERNEL);
- + if (!nb)
- + return -ENOMEM;
- +
- + nb->notifier_call = restool_bus_notifier;
- + error = bus_register_notifier(&fsl_mc_bus_type, nb);
- + if (error)
- + goto free_nb;
- +
- + /*
- + * This driver runs after fsl-mc bus driver runs.
- + * Hence, many of the root dprcs are already attached to fsl-mc bus
- + * In order to make sure we find all the root dprcs,
- + * we need to scan the fsl_mc_bus_type.
- + */
- + error = bus_for_each_dev(&fsl_mc_bus_type, NULL, NULL, add_to_restool);
- + if (error) {
- + bus_unregister_notifier(&fsl_mc_bus_type, nb);
- + kfree(nb);
- + pr_err("restool driver registration failure\n");
- + return error;
- + }
- +
- + return 0;
- +
- +free_nb:
- + kfree(nb);
- + return error;
- +}
- +
- +module_init(fsl_mc_restool_driver_init);
- +
- +static void __exit fsl_mc_restool_driver_exit(void)
- +{
- + struct restool_misc *restool_misc;
- + struct restool_misc *restool_misc_tmp;
- + char name1[20] = {0};
- + u32 name2 = 0;
- +
- + list_for_each_entry_safe(restool_misc, restool_misc_tmp,
- + &misc_list, list) {
- + if (sscanf(restool_misc->misc.name, "%4s.%u", name1, &name2)
- + != 2)
- + continue;
- +
- + pr_debug("name1=%s,name2=%u\n", name1, name2);
- + pr_debug("misc-device: %s\n", restool_misc->misc.name);
- + if (strcmp(name1, "dprc") != 0)
- + continue;
- +
- + if (WARN_ON(!restool_misc->static_mc_io))
- + return;
- +
- + if (WARN_ON(restool_misc->dynamic_instance_count != 0))
- + return;
- +
- + if (WARN_ON(restool_misc->static_instance_in_use))
- + return;
- +
- + misc_deregister(&restool_misc->misc);
- + pr_info("/dev/%s driver unregistered\n",
- + restool_misc->misc.name);
- + fsl_mc_portal_free(restool_misc->static_mc_io);
- + list_del(&restool_misc->list);
- + kfree(restool_misc);
- + }
- +}
- +
- +module_exit(fsl_mc_restool_driver_exit);
- +
- +MODULE_AUTHOR("Freescale Semiconductor Inc.");
- +MODULE_DESCRIPTION("Freescale's MC restool driver");
- +MODULE_LICENSE("GPL");
- --- a/drivers/staging/fsl-mc/bus/mc-sys.c
- +++ b/drivers/staging/fsl-mc/bus/mc-sys.c
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2014 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * I/O services to send MC commands to the MC hardware
- *
- @@ -13,7 +14,6 @@
- * names of any contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- - *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- @@ -46,7 +46,7 @@
- /**
- * Timeout in milliseconds to wait for the completion of an MC command
- */
- -#define MC_CMD_COMPLETION_TIMEOUT_MS 500
- +#define MC_CMD_COMPLETION_TIMEOUT_MS 15000
-
- /*
- * usleep_range() min and max values used to throttle down polling
- @@ -67,7 +67,7 @@ static u16 mc_cmd_hdr_read_cmdid(struct
- struct mc_cmd_header *hdr = (struct mc_cmd_header *)&cmd->header;
- u16 cmd_id = le16_to_cpu(hdr->cmd_id);
-
- - return (cmd_id & MC_CMD_HDR_CMDID_MASK) >> MC_CMD_HDR_CMDID_SHIFT;
- + return cmd_id;
- }
-
- static int mc_status_to_error(enum mc_cmd_status status)
- @@ -200,7 +200,7 @@ static int mc_polling_wait_preemptible(s
-
- if (time_after_eq(jiffies, jiffies_until_timeout)) {
- dev_dbg(mc_io->dev,
- - "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
- + "MC command timed out (portal: %#llx, dprc handle: %#x, command: %#x)\n",
- mc_io->portal_phys_addr,
- (unsigned int)mc_cmd_hdr_read_token(cmd),
- (unsigned int)mc_cmd_hdr_read_cmdid(cmd));
- @@ -240,7 +240,7 @@ static int mc_polling_wait_atomic(struct
- timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS;
- if (timeout_usecs == 0) {
- dev_dbg(mc_io->dev,
- - "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
- + "MC command timed out (portal: %#llx, dprc handle: %#x, command: %#x)\n",
- mc_io->portal_phys_addr,
- (unsigned int)mc_cmd_hdr_read_token(cmd),
- (unsigned int)mc_cmd_hdr_read_cmdid(cmd));
- @@ -294,7 +294,7 @@ int mc_send_command(struct fsl_mc_io *mc
-
- if (status != MC_CMD_STATUS_OK) {
- dev_dbg(mc_io->dev,
- - "MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n",
- + "MC command failed: portal: %#llx, dprc handle: %#x, command: %#x, status: %s (%#x)\n",
- mc_io->portal_phys_addr,
- (unsigned int)mc_cmd_hdr_read_token(cmd),
- (unsigned int)mc_cmd_hdr_read_cmdid(cmd),
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/include/dpaa2-fd.h
- @@ -0,0 +1,706 @@
- +/*
- + * Copyright 2014-2016 Freescale Semiconductor Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef __FSL_DPAA2_FD_H
- +#define __FSL_DPAA2_FD_H
- +
- +#include <linux/kernel.h>
- +
- +/**
- + * DOC: DPAA2 FD - Frame Descriptor APIs for DPAA2
- + *
- + * Frame Descriptors (FDs) are used to describe frame data in the DPAA2.
- + * Frames can be enqueued and dequeued to Frame Queues (FQs) which are consumed
- + * by the various DPAA accelerators (WRIOP, SEC, PME, DCE)
- + *
- + * There are three types of frames: single, scatter gather, and frame lists.
- + *
- + * The set of APIs in this file must be used to create, manipulate and
- + * query Frame Descriptors.
- + */
- +
- +/**
- + * struct dpaa2_fd - Struct describing FDs
- + * @words: for easier/faster copying the whole FD structure
- + * @addr: address in the FD
- + * @len: length in the FD
- + * @bpid: buffer pool ID
- + * @format_offset: format, offset, and short-length fields
- + * @frc: frame context
- + * @ctrl: control bits...including dd, sc, va, err, etc
- + * @flc: flow context address
- + *
- + * This structure represents the basic Frame Descriptor used in the system.
- + */
- +struct dpaa2_fd {
- + union {
- + u32 words[8];
- + struct dpaa2_fd_simple {
- + __le64 addr;
- + __le32 len;
- + __le16 bpid;
- + __le16 format_offset;
- + __le32 frc;
- + __le32 ctrl;
- + __le64 flc;
- + } simple;
- + };
- +};
- +
- +#define FD_SHORT_LEN_FLAG_MASK 0x1
- +#define FD_SHORT_LEN_FLAG_SHIFT 14
- +#define FD_SHORT_LEN_MASK 0x3FFFF
- +#define FD_OFFSET_MASK 0x0FFF
- +#define FD_FORMAT_MASK 0x3
- +#define FD_FORMAT_SHIFT 12
- +#define FD_BPID_MASK 0x3FFF
- +#define SG_SHORT_LEN_FLAG_MASK 0x1
- +#define SG_SHORT_LEN_FLAG_SHIFT 14
- +#define SG_SHORT_LEN_MASK 0x1FFFF
- +#define SG_OFFSET_MASK 0x0FFF
- +#define SG_FORMAT_MASK 0x3
- +#define SG_FORMAT_SHIFT 12
- +#define SG_BPID_MASK 0x3FFF
- +#define SG_FINAL_FLAG_MASK 0x1
- +#define SG_FINAL_FLAG_SHIFT 15
- +#define FL_SHORT_LEN_FLAG_MASK 0x1
- +#define FL_SHORT_LEN_FLAG_SHIFT 14
- +#define FL_SHORT_LEN_MASK 0x3FFFF
- +#define FL_OFFSET_MASK 0x0FFF
- +#define FL_FORMAT_MASK 0x3
- +#define FL_FORMAT_SHIFT 12
- +#define FL_BPID_MASK 0x3FFF
- +#define FL_FINAL_FLAG_MASK 0x1
- +#define FL_FINAL_FLAG_SHIFT 15
- +
- +/* Error bits in FD CTRL */
- +#define FD_CTRL_ERR_MASK 0x000000FF
- +#define FD_CTRL_UFD 0x00000004
- +#define FD_CTRL_SBE 0x00000008
- +#define FD_CTRL_FLC 0x00000010
- +#define FD_CTRL_FSE 0x00000020
- +#define FD_CTRL_FAERR 0x00000040
- +
- +/* Annotation bits in FD CTRL */
- +#define FD_CTRL_PTA 0x00800000
- +#define FD_CTRL_PTV1 0x00400000
- +
- +enum dpaa2_fd_format {
- + dpaa2_fd_single = 0,
- + dpaa2_fd_list,
- + dpaa2_fd_sg
- +};
- +
- +/**
- + * dpaa2_fd_get_addr() - get the addr field of frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the address in the frame descriptor.
- + */
- +static inline dma_addr_t dpaa2_fd_get_addr(const struct dpaa2_fd *fd)
- +{
- + return (dma_addr_t)le64_to_cpu(fd->simple.addr);
- +}
- +
- +/**
- + * dpaa2_fd_set_addr() - Set the addr field of frame descriptor
- + * @fd: the given frame descriptor
- + * @addr: the address needs to be set in frame descriptor
- + */
- +static inline void dpaa2_fd_set_addr(struct dpaa2_fd *fd, dma_addr_t addr)
- +{
- + fd->simple.addr = cpu_to_le64(addr);
- +}
- +
- +/**
- + * dpaa2_fd_get_frc() - Get the frame context in the frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the frame context field in the frame descriptor.
- + */
- +static inline u32 dpaa2_fd_get_frc(const struct dpaa2_fd *fd)
- +{
- + return le32_to_cpu(fd->simple.frc);
- +}
- +
- +/**
- + * dpaa2_fd_set_frc() - Set the frame context in the frame descriptor
- + * @fd: the given frame descriptor
- + * @frc: the frame context needs to be set in frame descriptor
- + */
- +static inline void dpaa2_fd_set_frc(struct dpaa2_fd *fd, u32 frc)
- +{
- + fd->simple.frc = cpu_to_le32(frc);
- +}
- +
- +/**
- + * dpaa2_fd_get_ctrl() - Get the control bits in the frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the control bits field in the frame descriptor.
- + */
- +static inline u32 dpaa2_fd_get_ctrl(const struct dpaa2_fd *fd)
- +{
- + return le32_to_cpu(fd->simple.ctrl);
- +}
- +
- +/**
- + * dpaa2_fd_set_ctrl() - Set the control bits in the frame descriptor
- + * @fd: the given frame descriptor
- + * @ctrl: the control bits to be set in the frame descriptor
- + */
- +static inline void dpaa2_fd_set_ctrl(struct dpaa2_fd *fd, u32 ctrl)
- +{
- + fd->simple.ctrl = cpu_to_le32(ctrl);
- +}
- +
- +/**
- + * dpaa2_fd_get_flc() - Get the flow context in the frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the flow context in the frame descriptor.
- + */
- +static inline dma_addr_t dpaa2_fd_get_flc(const struct dpaa2_fd *fd)
- +{
- + return (dma_addr_t)le64_to_cpu(fd->simple.flc);
- +}
- +
- +/**
- + * dpaa2_fd_set_flc() - Set the flow context field of frame descriptor
- + * @fd: the given frame descriptor
- + * @flc_addr: the flow context needs to be set in frame descriptor
- + */
- +static inline void dpaa2_fd_set_flc(struct dpaa2_fd *fd, dma_addr_t flc_addr)
- +{
- + fd->simple.flc = cpu_to_le64(flc_addr);
- +}
- +
- +static inline bool dpaa2_fd_short_len(const struct dpaa2_fd *fd)
- +{
- + return !!((le16_to_cpu(fd->simple.format_offset) >>
- + FD_SHORT_LEN_FLAG_SHIFT) & FD_SHORT_LEN_FLAG_MASK);
- +}
- +
- +/**
- + * dpaa2_fd_get_len() - Get the length in the frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the length field in the frame descriptor.
- + */
- +static inline u32 dpaa2_fd_get_len(const struct dpaa2_fd *fd)
- +{
- + if (dpaa2_fd_short_len(fd))
- + return le32_to_cpu(fd->simple.len) & FD_SHORT_LEN_MASK;
- +
- + return le32_to_cpu(fd->simple.len);
- +}
- +
- +/**
- + * dpaa2_fd_set_len() - Set the length field of frame descriptor
- + * @fd: the given frame descriptor
- + * @len: the length needs to be set in frame descriptor
- + */
- +static inline void dpaa2_fd_set_len(struct dpaa2_fd *fd, u32 len)
- +{
- + fd->simple.len = cpu_to_le32(len);
- +}
- +
- +/**
- + * dpaa2_fd_get_offset() - Get the offset field in the frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the offset.
- + */
- +static inline uint16_t dpaa2_fd_get_offset(const struct dpaa2_fd *fd)
- +{
- + return le16_to_cpu(fd->simple.format_offset) & FD_OFFSET_MASK;
- +}
- +
- +/**
- + * dpaa2_fd_set_offset() - Set the offset field of frame descriptor
- + * @fd: the given frame descriptor
- + * @offset: the offset needs to be set in frame descriptor
- + */
- +static inline void dpaa2_fd_set_offset(struct dpaa2_fd *fd, uint16_t offset)
- +{
- + fd->simple.format_offset &= cpu_to_le16(~FD_OFFSET_MASK);
- + fd->simple.format_offset |= cpu_to_le16(offset);
- +}
- +
- +/**
- + * dpaa2_fd_get_format() - Get the format field in the frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the format.
- + */
- +static inline enum dpaa2_fd_format dpaa2_fd_get_format(
- + const struct dpaa2_fd *fd)
- +{
- + return (enum dpaa2_fd_format)((le16_to_cpu(fd->simple.format_offset)
- + >> FD_FORMAT_SHIFT) & FD_FORMAT_MASK);
- +}
- +
- +/**
- + * dpaa2_fd_set_format() - Set the format field of frame descriptor
- + * @fd: the given frame descriptor
- + * @format: the format needs to be set in frame descriptor
- + */
- +static inline void dpaa2_fd_set_format(struct dpaa2_fd *fd,
- + enum dpaa2_fd_format format)
- +{
- + fd->simple.format_offset &=
- + cpu_to_le16(~(FD_FORMAT_MASK << FD_FORMAT_SHIFT));
- + fd->simple.format_offset |= cpu_to_le16(format << FD_FORMAT_SHIFT);
- +}
- +
- +/**
- + * dpaa2_fd_get_bpid() - Get the bpid field in the frame descriptor
- + * @fd: the given frame descriptor
- + *
- + * Return the buffer pool id.
- + */
- +static inline uint16_t dpaa2_fd_get_bpid(const struct dpaa2_fd *fd)
- +{
- + return le16_to_cpu(fd->simple.bpid) & FD_BPID_MASK;
- +}
- +
- +/**
- + * dpaa2_fd_set_bpid() - Set the bpid field of frame descriptor
- + * @fd: the given frame descriptor
- + * @bpid: buffer pool id to be set
- + */
- +static inline void dpaa2_fd_set_bpid(struct dpaa2_fd *fd, uint16_t bpid)
- +{
- + fd->simple.bpid &= cpu_to_le16(~(FD_BPID_MASK));
- + fd->simple.bpid |= cpu_to_le16(bpid);
- +}
- +
- +/**
- + * struct dpaa2_sg_entry - the scatter-gathering structure
- + * @addr: address of the sg entry
- + * @len: length in this sg entry
- + * @bpid: buffer pool id
- + * @format_offset: format and offset fields
- + */
- +struct dpaa2_sg_entry {
- + __le64 addr;
- + __le32 len;
- + __le16 bpid;
- + __le16 format_offset;
- +};
- +
- +enum dpaa2_sg_format {
- + dpaa2_sg_single = 0,
- + dpaa2_sg_frame_data,
- + dpaa2_sg_sgt_ext
- +};
- +
- +/* Accessors for SG entry fields */
- +
- +/**
- + * dpaa2_sg_get_addr() - Get the address from SG entry
- + * @sg: the given scatter-gathering object
- + *
- + * Return the address.
- + */
- +static inline dma_addr_t dpaa2_sg_get_addr(const struct dpaa2_sg_entry *sg)
- +{
- + return le64_to_cpu((dma_addr_t)sg->addr);
- +}
- +
- +/**
- + * dpaa2_sg_set_addr() - Set the address in SG entry
- + * @sg: the given scatter-gathering object
- + * @addr: the address to be set
- + */
- +static inline void dpaa2_sg_set_addr(struct dpaa2_sg_entry *sg, dma_addr_t addr)
- +{
- + sg->addr = cpu_to_le64(addr);
- +}
- +
- +static inline bool dpaa2_sg_short_len(const struct dpaa2_sg_entry *sg)
- +{
- + return !!((le16_to_cpu(sg->format_offset) >> SG_SHORT_LEN_FLAG_SHIFT)
- + & SG_SHORT_LEN_FLAG_MASK);
- +}
- +
- +/**
- + * dpaa2_sg_get_len() - Get the length in SG entry
- + * @sg: the given scatter-gathering object
- + *
- + * Return the length.
- + */
- +static inline u32 dpaa2_sg_get_len(const struct dpaa2_sg_entry *sg)
- +{
- + if (dpaa2_sg_short_len(sg))
- + return le32_to_cpu(sg->len) & SG_SHORT_LEN_MASK;
- +
- + return le32_to_cpu(sg->len);
- +}
- +
- +/**
- + * dpaa2_sg_set_len() - Set the length in SG entry
- + * @sg: the given scatter-gathering object
- + * @len: the length to be set
- + */
- +static inline void dpaa2_sg_set_len(struct dpaa2_sg_entry *sg, u32 len)
- +{
- + sg->len = cpu_to_le32(len);
- +}
- +
- +/**
- + * dpaa2_sg_get_offset() - Get the offset in SG entry
- + * @sg: the given scatter-gathering object
- + *
- + * Return the offset.
- + */
- +static inline u16 dpaa2_sg_get_offset(const struct dpaa2_sg_entry *sg)
- +{
- + return le16_to_cpu(sg->format_offset) & SG_OFFSET_MASK;
- +}
- +
- +/**
- + * dpaa2_sg_set_offset() - Set the offset in SG entry
- + * @sg: the given scatter-gathering object
- + * @offset: the offset to be set
- + */
- +static inline void dpaa2_sg_set_offset(struct dpaa2_sg_entry *sg,
- + u16 offset)
- +{
- + sg->format_offset &= cpu_to_le16(~SG_OFFSET_MASK);
- + sg->format_offset |= cpu_to_le16(offset);
- +}
- +
- +/**
- + * dpaa2_sg_get_format() - Get the SG format in SG entry
- + * @sg: the given scatter-gathering object
- + *
- + * Return the format.
- + */
- +static inline enum dpaa2_sg_format
- + dpaa2_sg_get_format(const struct dpaa2_sg_entry *sg)
- +{
- + return (enum dpaa2_sg_format)((le16_to_cpu(sg->format_offset)
- + >> SG_FORMAT_SHIFT) & SG_FORMAT_MASK);
- +}
- +
- +/**
- + * dpaa2_sg_set_format() - Set the SG format in SG entry
- + * @sg: the given scatter-gathering object
- + * @format: the format to be set
- + */
- +static inline void dpaa2_sg_set_format(struct dpaa2_sg_entry *sg,
- + enum dpaa2_sg_format format)
- +{
- + sg->format_offset &= cpu_to_le16(~(SG_FORMAT_MASK << SG_FORMAT_SHIFT));
- + sg->format_offset |= cpu_to_le16(format << SG_FORMAT_SHIFT);
- +}
- +
- +/**
- + * dpaa2_sg_get_bpid() - Get the buffer pool id in SG entry
- + * @sg: the given scatter-gathering object
- + *
- + * Return the bpid.
- + */
- +static inline u16 dpaa2_sg_get_bpid(const struct dpaa2_sg_entry *sg)
- +{
- + return le16_to_cpu(sg->bpid) & SG_BPID_MASK;
- +}
- +
- +/**
- + * dpaa2_sg_set_bpid() - Set the buffer pool id in SG entry
- + * @sg: the given scatter-gathering object
- + * @bpid: the bpid to be set
- + */
- +static inline void dpaa2_sg_set_bpid(struct dpaa2_sg_entry *sg, u16 bpid)
- +{
- + sg->bpid &= cpu_to_le16(~(SG_BPID_MASK));
- + sg->bpid |= cpu_to_le16(bpid);
- +}
- +
- +/**
- + * dpaa2_sg_is_final() - Check final bit in SG entry
- + * @sg: the given scatter-gathering object
- + *
- + * Return bool.
- + */
- +static inline bool dpaa2_sg_is_final(const struct dpaa2_sg_entry *sg)
- +{
- + return !!(le16_to_cpu(sg->format_offset) >> SG_FINAL_FLAG_SHIFT);
- +}
- +
- +/**
- + * dpaa2_sg_set_final() - Set the final bit in SG entry
- + * @sg: the given scatter-gathering object
- + * @final: the final boolean to be set
- + */
- +static inline void dpaa2_sg_set_final(struct dpaa2_sg_entry *sg, bool final)
- +{
- + sg->format_offset &= cpu_to_le16(~(SG_FINAL_FLAG_MASK
- + << SG_FINAL_FLAG_SHIFT));
- + sg->format_offset |= cpu_to_le16(final << SG_FINAL_FLAG_SHIFT);
- +}
- +
- +/**
- + * struct dpaa2_fl_entry - structure for frame list entry.
- + * @addr: address in the FLE
- + * @len: length in the FLE
- + * @bpid: buffer pool ID
- + * @format_offset: format, offset, and short-length fields
- + * @frc: frame context
- + * @ctrl: control bits...including pta, pvt1, pvt2, err, etc
- + * @flc: flow context address
- + */
- +struct dpaa2_fl_entry {
- + __le64 addr;
- + __le32 len;
- + __le16 bpid;
- + __le16 format_offset;
- + __le32 frc;
- + __le32 ctrl;
- + __le64 flc;
- +};
- +
- +enum dpaa2_fl_format {
- + dpaa2_fl_single = 0,
- + dpaa2_fl_res,
- + dpaa2_fl_sg
- +};
- +
- +/**
- + * dpaa2_fl_get_addr() - get the addr field of FLE
- + * @fle: the given frame list entry
- + *
- + * Return the address in the frame list entry.
- + */
- +static inline dma_addr_t dpaa2_fl_get_addr(const struct dpaa2_fl_entry *fle)
- +{
- + return (dma_addr_t)le64_to_cpu(fle->addr);
- +}
- +
- +/**
- + * dpaa2_fl_set_addr() - Set the addr field of FLE
- + * @fle: the given frame list entry
- + * @addr: the address needs to be set in frame list entry
- + */
- +static inline void dpaa2_fl_set_addr(struct dpaa2_fl_entry *fle,
- + dma_addr_t addr)
- +{
- + fle->addr = cpu_to_le64(addr);
- +}
- +
- +/**
- + * dpaa2_fl_get_frc() - Get the frame context in the FLE
- + * @fle: the given frame list entry
- + *
- + * Return the frame context field in the frame lsit entry.
- + */
- +static inline u32 dpaa2_fl_get_frc(const struct dpaa2_fl_entry *fle)
- +{
- + return le32_to_cpu(fle->frc);
- +}
- +
- +/**
- + * dpaa2_fl_set_frc() - Set the frame context in the FLE
- + * @fle: the given frame list entry
- + * @frc: the frame context needs to be set in frame list entry
- + */
- +static inline void dpaa2_fl_set_frc(struct dpaa2_fl_entry *fle, u32 frc)
- +{
- + fle->frc = cpu_to_le32(frc);
- +}
- +
- +/**
- + * dpaa2_fl_get_ctrl() - Get the control bits in the FLE
- + * @fle: the given frame list entry
- + *
- + * Return the control bits field in the frame list entry.
- + */
- +static inline u32 dpaa2_fl_get_ctrl(const struct dpaa2_fl_entry *fle)
- +{
- + return le32_to_cpu(fle->ctrl);
- +}
- +
- +/**
- + * dpaa2_fl_set_ctrl() - Set the control bits in the FLE
- + * @fle: the given frame list entry
- + * @ctrl: the control bits to be set in the frame list entry
- + */
- +static inline void dpaa2_fl_set_ctrl(struct dpaa2_fl_entry *fle, u32 ctrl)
- +{
- + fle->ctrl = cpu_to_le32(ctrl);
- +}
- +
- +/**
- + * dpaa2_fl_get_flc() - Get the flow context in the FLE
- + * @fle: the given frame list entry
- + *
- + * Return the flow context in the frame list entry.
- + */
- +static inline dma_addr_t dpaa2_fl_get_flc(const struct dpaa2_fl_entry *fle)
- +{
- + return (dma_addr_t)le64_to_cpu(fle->flc);
- +}
- +
- +/**
- + * dpaa2_fl_set_flc() - Set the flow context field of FLE
- + * @fle: the given frame list entry
- + * @flc_addr: the flow context needs to be set in frame list entry
- + */
- +static inline void dpaa2_fl_set_flc(struct dpaa2_fl_entry *fle,
- + dma_addr_t flc_addr)
- +{
- + fle->flc = cpu_to_le64(flc_addr);
- +}
- +
- +static inline bool dpaa2_fl_short_len(const struct dpaa2_fl_entry *fle)
- +{
- + return !!((le16_to_cpu(fle->format_offset) >>
- + FL_SHORT_LEN_FLAG_SHIFT) & FL_SHORT_LEN_FLAG_MASK);
- +}
- +
- +/**
- + * dpaa2_fl_get_len() - Get the length in the FLE
- + * @fle: the given frame list entry
- + *
- + * Return the length field in the frame list entry.
- + */
- +static inline u32 dpaa2_fl_get_len(const struct dpaa2_fl_entry *fle)
- +{
- + if (dpaa2_fl_short_len(fle))
- + return le32_to_cpu(fle->len) & FL_SHORT_LEN_MASK;
- +
- + return le32_to_cpu(fle->len);
- +}
- +
- +/**
- + * dpaa2_fl_set_len() - Set the length field of FLE
- + * @fle: the given frame list entry
- + * @len: the length needs to be set in frame list entry
- + */
- +static inline void dpaa2_fl_set_len(struct dpaa2_fl_entry *fle, u32 len)
- +{
- + fle->len = cpu_to_le32(len);
- +}
- +
- +/**
- + * dpaa2_fl_get_offset() - Get the offset field in the frame list entry
- + * @fle: the given frame list entry
- + *
- + * Return the offset.
- + */
- +static inline u16 dpaa2_fl_get_offset(const struct dpaa2_fl_entry *fle)
- +{
- + return le16_to_cpu(fle->format_offset) & FL_OFFSET_MASK;
- +}
- +
- +/**
- + * dpaa2_fl_set_offset() - Set the offset field of FLE
- + * @fle: the given frame list entry
- + * @offset: the offset needs to be set in frame list entry
- + */
- +static inline void dpaa2_fl_set_offset(struct dpaa2_fl_entry *fle, u16 offset)
- +{
- + fle->format_offset &= cpu_to_le16(~FL_OFFSET_MASK);
- + fle->format_offset |= cpu_to_le16(offset);
- +}
- +
- +/**
- + * dpaa2_fl_get_format() - Get the format field in the FLE
- + * @fle: the given frame list entry
- + *
- + * Return the format.
- + */
- +static inline enum dpaa2_fl_format dpaa2_fl_get_format(
- + const struct dpaa2_fl_entry *fle)
- +{
- + return (enum dpaa2_fl_format)((le16_to_cpu(fle->format_offset) >>
- + FL_FORMAT_SHIFT) & FL_FORMAT_MASK);
- +}
- +
- +/**
- + * dpaa2_fl_set_format() - Set the format field of FLE
- + * @fle: the given frame list entry
- + * @format: the format needs to be set in frame list entry
- + */
- +static inline void dpaa2_fl_set_format(struct dpaa2_fl_entry *fle,
- + enum dpaa2_fl_format format)
- +{
- + fle->format_offset &= cpu_to_le16(~(FL_FORMAT_MASK << FL_FORMAT_SHIFT));
- + fle->format_offset |= cpu_to_le16(format << FL_FORMAT_SHIFT);
- +}
- +
- +/**
- + * dpaa2_fl_get_bpid() - Get the bpid field in the FLE
- + * @fle: the given frame list entry
- + *
- + * Return the buffer pool id.
- + */
- +static inline u16 dpaa2_fl_get_bpid(const struct dpaa2_fl_entry *fle)
- +{
- + return le16_to_cpu(fle->bpid) & FL_BPID_MASK;
- +}
- +
- +/**
- + * dpaa2_fl_set_bpid() - Set the bpid field of FLE
- + * @fle: the given frame list entry
- + * @bpid: buffer pool id to be set
- + */
- +static inline void dpaa2_fl_set_bpid(struct dpaa2_fl_entry *fle, u16 bpid)
- +{
- + fle->bpid &= cpu_to_le16(~(FL_BPID_MASK));
- + fle->bpid |= cpu_to_le16(bpid);
- +}
- +
- +/**
- + * dpaa2_fl_is_final() - Check final bit in FLE
- + * @fle: the given frame list entry
- + *
- + * Return bool.
- + */
- +static inline bool dpaa2_fl_is_final(const struct dpaa2_fl_entry *fle)
- +{
- + return !!(le16_to_cpu(fle->format_offset) >> FL_FINAL_FLAG_SHIFT);
- +}
- +
- +/**
- + * dpaa2_fl_set_final() - Set the final bit in FLE
- + * @fle: the given frame list entry
- + * @final: the final boolean to be set
- + */
- +static inline void dpaa2_fl_set_final(struct dpaa2_fl_entry *fle, bool final)
- +{
- + fle->format_offset &= cpu_to_le16(~(FL_FINAL_FLAG_MASK <<
- + FL_FINAL_FLAG_SHIFT));
- + fle->format_offset |= cpu_to_le16(final << FL_FINAL_FLAG_SHIFT);
- +}
- +
- +#endif /* __FSL_DPAA2_FD_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/include/dpaa2-global.h
- @@ -0,0 +1,202 @@
- +/*
- + * Copyright 2014-2016 Freescale Semiconductor Inc.
- + * Copyright 2016 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef __FSL_DPAA2_GLOBAL_H
- +#define __FSL_DPAA2_GLOBAL_H
- +
- +#include <linux/types.h>
- +#include <linux/cpumask.h>
- +#include "dpaa2-fd.h"
- +
- +struct dpaa2_dq {
- + union {
- + struct common {
- + u8 verb;
- + u8 reserved[63];
- + } common;
- + struct dq {
- + u8 verb;
- + u8 stat;
- + __le16 seqnum;
- + __le16 oprid;
- + u8 reserved;
- + u8 tok;
- + __le32 fqid;
- + u32 reserved2;
- + __le32 fq_byte_cnt;
- + __le32 fq_frm_cnt;
- + __le64 fqd_ctx;
- + u8 fd[32];
- + } dq;
- + struct scn {
- + u8 verb;
- + u8 stat;
- + u8 state;
- + u8 reserved;
- + __le32 rid_tok;
- + __le64 ctx;
- + } scn;
- + };
- +};
- +
- +/* Parsing frame dequeue results */
- +/* FQ empty */
- +#define DPAA2_DQ_STAT_FQEMPTY 0x80
- +/* FQ held active */
- +#define DPAA2_DQ_STAT_HELDACTIVE 0x40
- +/* FQ force eligible */
- +#define DPAA2_DQ_STAT_FORCEELIGIBLE 0x20
- +/* valid frame */
- +#define DPAA2_DQ_STAT_VALIDFRAME 0x10
- +/* FQ ODP enable */
- +#define DPAA2_DQ_STAT_ODPVALID 0x04
- +/* volatile dequeue */
- +#define DPAA2_DQ_STAT_VOLATILE 0x02
- +/* volatile dequeue command is expired */
- +#define DPAA2_DQ_STAT_EXPIRED 0x01
- +
- +#define DQ_FQID_MASK 0x00FFFFFF
- +#define DQ_FRAME_COUNT_MASK 0x00FFFFFF
- +
- +/**
- + * dpaa2_dq_flags() - Get the stat field of dequeue response
- + * @dq: the dequeue result.
- + */
- +static inline u32 dpaa2_dq_flags(const struct dpaa2_dq *dq)
- +{
- + return dq->dq.stat;
- +}
- +
- +/**
- + * dpaa2_dq_is_pull() - Check whether the dq response is from a pull
- + * command.
- + * @dq: the dequeue result
- + *
- + * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
- + */
- +static inline int dpaa2_dq_is_pull(const struct dpaa2_dq *dq)
- +{
- + return (int)(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_VOLATILE);
- +}
- +
- +/**
- + * dpaa2_dq_is_pull_complete() - Check whether the pull command is completed.
- + * @dq: the dequeue result
- + *
- + * Return boolean.
- + */
- +static inline bool dpaa2_dq_is_pull_complete(const struct dpaa2_dq *dq)
- +{
- + return !!(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_EXPIRED);
- +}
- +
- +/**
- + * dpaa2_dq_seqnum() - Get the seqnum field in dequeue response
- + * @dq: the dequeue result
- + *
- + * seqnum is valid only if VALIDFRAME flag is TRUE
- + *
- + * Return seqnum.
- + */
- +static inline u16 dpaa2_dq_seqnum(const struct dpaa2_dq *dq)
- +{
- + return le16_to_cpu(dq->dq.seqnum);
- +}
- +
- +/**
- + * dpaa2_dq_odpid() - Get the odpid field in dequeue response
- + * @dq: the dequeue result
- + *
- + * odpid is valid only if ODPVALID flag is TRUE.
- + *
- + * Return odpid.
- + */
- +static inline u16 dpaa2_dq_odpid(const struct dpaa2_dq *dq)
- +{
- + return le16_to_cpu(dq->dq.oprid);
- +}
- +
- +/**
- + * dpaa2_dq_fqid() - Get the fqid in dequeue response
- + * @dq: the dequeue result
- + *
- + * Return fqid.
- + */
- +static inline u32 dpaa2_dq_fqid(const struct dpaa2_dq *dq)
- +{
- + return le32_to_cpu(dq->dq.fqid) & DQ_FQID_MASK;
- +}
- +
- +/**
- + * dpaa2_dq_byte_count() - Get the byte count in dequeue response
- + * @dq: the dequeue result
- + *
- + * Return the byte count remaining in the FQ.
- + */
- +static inline u32 dpaa2_dq_byte_count(const struct dpaa2_dq *dq)
- +{
- + return le32_to_cpu(dq->dq.fq_byte_cnt);
- +}
- +
- +/**
- + * dpaa2_dq_frame_count() - Get the frame count in dequeue response
- + * @dq: the dequeue result
- + *
- + * Return the frame count remaining in the FQ.
- + */
- +static inline u32 dpaa2_dq_frame_count(const struct dpaa2_dq *dq)
- +{
- + return le32_to_cpu(dq->dq.fq_frm_cnt) & DQ_FRAME_COUNT_MASK;
- +}
- +
- +/**
- + * dpaa2_dq_fd_ctx() - Get the frame queue context in dequeue response
- + * @dq: the dequeue result
- + *
- + * Return the frame queue context.
- + */
- +static inline u64 dpaa2_dq_fqd_ctx(const struct dpaa2_dq *dq)
- +{
- + return le64_to_cpu(dq->dq.fqd_ctx);
- +}
- +
- +/**
- + * dpaa2_dq_fd() - Get the frame descriptor in dequeue response
- + * @dq: the dequeue result
- + *
- + * Return the frame descriptor.
- + */
- +static inline const struct dpaa2_fd *dpaa2_dq_fd(const struct dpaa2_dq *dq)
- +{
- + return (const struct dpaa2_fd *)&dq->dq.fd[0];
- +}
- +
- +#endif /* __FSL_DPAA2_GLOBAL_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/include/dpaa2-io.h
- @@ -0,0 +1,190 @@
- +/*
- + * Copyright 2014-2016 Freescale Semiconductor Inc.
- + * Copyright 2017 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of Freescale Semiconductor nor the
- + * names of its contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef __FSL_DPAA2_IO_H
- +#define __FSL_DPAA2_IO_H
- +
- +#include <linux/types.h>
- +#include <linux/cpumask.h>
- +
- +#include "dpaa2-fd.h"
- +#include "dpaa2-global.h"
- +
- +struct dpaa2_io;
- +struct dpaa2_io_store;
- +struct device;
- +
- +/**
- + * DOC: DPIO Service
- + *
- + * The DPIO service provides APIs for users to interact with the datapath
- + * by enqueueing and dequeing frame descriptors.
- + *
- + * The following set of APIs can be used to enqueue and dequeue frames
- + * as well as producing notification callbacks when data is available
- + * for dequeue.
- + */
- +
- +/**
- + * struct dpaa2_io_desc - The DPIO descriptor
- + * @receives_notifications: Use notificaton mode. Non-zero if the DPIO
- + * has a channel.
- + * @has_8prio: Set to non-zero for channel with 8 priority WQs. Ignored
- + * unless receives_notification is TRUE.
- + * @cpu: The cpu index that at least interrupt handlers will
- + * execute on.
- + * @stash_affinity: The stash affinity for this portal favour 'cpu'
- + * @regs_cena: The cache enabled regs.
- + * @regs_cinh: The cache inhibited regs
- + * @dpio_id: The dpio index
- + * @qman_version: The qman version
- + *
- + * Describes the attributes and features of the DPIO object.
- + */
- +struct dpaa2_io_desc {
- + int receives_notifications;
- + int has_8prio;
- + int cpu;
- + void *regs_cena;
- + void *regs_cinh;
- + int dpio_id;
- + u32 qman_version;
- +};
- +
- +struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc);
- +
- +void dpaa2_io_down(struct dpaa2_io *d);
- +
- +irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj);
- +
- +/**
- + * struct dpaa2_io_notification_ctx - The DPIO notification context structure
- + * @cb: The callback to be invoked when the notification arrives
- + * @is_cdan: Zero for FQDAN, non-zero for CDAN
- + * @id: FQID or channel ID, needed for rearm
- + * @desired_cpu: The cpu on which the notifications will show up. -1 means
- + * any CPU.
- + * @dpio_id: The dpio index
- + * @qman64: The 64-bit context value shows up in the FQDAN/CDAN.
- + * @node: The list node
- + * @dpio_private: The dpio object internal to dpio_service
- + *
- + * Used when a FQDAN/CDAN registration is made by drivers.
- + */
- +struct dpaa2_io_notification_ctx {
- + void (*cb)(struct dpaa2_io_notification_ctx *);
- + int is_cdan;
- + u32 id;
- + int desired_cpu;
- + int dpio_id;
- + u64 qman64;
- + struct list_head node;
- + void *dpio_private;
- +};
- +
- +int dpaa2_io_service_register(struct dpaa2_io *service,
- + struct dpaa2_io_notification_ctx *ctx);
- +void dpaa2_io_service_deregister(struct dpaa2_io *service,
- + struct dpaa2_io_notification_ctx *ctx);
- +int dpaa2_io_service_rearm(struct dpaa2_io *service,
- + struct dpaa2_io_notification_ctx *ctx);
- +
- +int dpaa2_io_service_pull_fq(struct dpaa2_io *d, u32 fqid,
- + struct dpaa2_io_store *s);
- +int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid,
- + struct dpaa2_io_store *s);
- +
- +int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid,
- + const struct dpaa2_fd *fd);
- +int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
- + u16 qdbin, const struct dpaa2_fd *fd);
- +int dpaa2_io_service_release(struct dpaa2_io *d, u32 bpid,
- + const u64 *buffers, unsigned int num_buffers);
- +int dpaa2_io_service_acquire(struct dpaa2_io *d, u32 bpid,
- + u64 *buffers, unsigned int num_buffers);
- +
- +struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
- + struct device *dev);
- +void dpaa2_io_store_destroy(struct dpaa2_io_store *s);
- +struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last);
- +
- +#ifdef CONFIG_FSL_QBMAN_DEBUG
- +int dpaa2_io_query_fq_count(struct dpaa2_io *d, uint32_t fqid,
- + uint32_t *fcnt, uint32_t *bcnt);
- +int dpaa2_io_query_bp_count(struct dpaa2_io *d, uint32_t bpid,
- + uint32_t *num);
- +#endif
- +
- +
- +/***************/
- +/* CSCN */
- +/***************/
- +
- +/**
- + * struct dpaa2_cscn - The CSCN message format
- + * @verb: identifies the type of message (should be 0x27).
- + * @stat: status bits related to dequeuing response (not used)
- + * @state: bit 0 = 0/1 if CG is no/is congested
- + * @reserved: reserved byte
- + * @cgid: congest grp ID - the first 16 bits
- + * @ctx: context data
- + *
- + * Congestion management can be implemented in software through
- + * the use of Congestion State Change Notifications (CSCN). These
- + * are messages written by DPAA2 hardware to memory whenever the
- + * instantaneous count (I_CNT field in the CG) exceeds the
- + * Congestion State (CS) entrance threshold, signifying congestion
- + * entrance, or when the instantaneous count returns below exit
- + * threshold, signifying congestion exit. The format of the message
- + * is given by the dpaa2_cscn structure. Bit 0 of the state field
- + * represents congestion state written by the hardware.
- + */
- +struct dpaa2_cscn {
- + u8 verb;
- + u8 stat;
- + u8 state;
- + u8 reserved;
- + __le32 cgid;
- + __le64 ctx;
- +};
- +
- +#define DPAA2_CSCN_SIZE 64
- +#define DPAA2_CSCN_ALIGN 16
- +
- +#define DPAA2_CSCN_STATE_MASK 0x1
- +#define DPAA2_CSCN_CONGESTED 1
- +
- +static inline bool dpaa2_cscn_state_congested(struct dpaa2_cscn *cscn)
- +{
- + return ((cscn->state & DPAA2_CSCN_STATE_MASK) == DPAA2_CSCN_CONGESTED);
- +}
- +
- +#endif /* __FSL_DPAA2_IO_H */
- --- a/drivers/staging/fsl-mc/include/dpbp-cmd.h
- +++ /dev/null
- @@ -1,185 +0,0 @@
- -/* Copyright 2013-2016 Freescale Semiconductor Inc.
- - *
- - * Redistribution and use in source and binary forms, with or without
- - * modification, are permitted provided that the following conditions are met:
- - * * Redistributions of source code must retain the above copyright
- - * notice, this list of conditions and the following disclaimer.
- - * * Redistributions in binary form must reproduce the above copyright
- - * notice, this list of conditions and the following disclaimer in the
- - * documentation and/or other materials provided with the distribution.
- - * * Neither the name of the above-listed copyright holders nor the
- - * names of any contributors may be used to endorse or promote products
- - * derived from this software without specific prior written permission.
- - *
- - *
- - * ALTERNATIVELY, this software may be distributed under the terms of the
- - * GNU General Public License ("GPL") as published by the Free Software
- - * Foundation, either version 2 of that License or (at your option) any
- - * later version.
- - *
- - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- - * POSSIBILITY OF SUCH DAMAGE.
- - */
- -#ifndef _FSL_DPBP_CMD_H
- -#define _FSL_DPBP_CMD_H
- -
- -/* DPBP Version */
- -#define DPBP_VER_MAJOR 2
- -#define DPBP_VER_MINOR 2
- -
- -/* Command IDs */
- -#define DPBP_CMDID_CLOSE 0x800
- -#define DPBP_CMDID_OPEN 0x804
- -#define DPBP_CMDID_CREATE 0x904
- -#define DPBP_CMDID_DESTROY 0x900
- -
- -#define DPBP_CMDID_ENABLE 0x002
- -#define DPBP_CMDID_DISABLE 0x003
- -#define DPBP_CMDID_GET_ATTR 0x004
- -#define DPBP_CMDID_RESET 0x005
- -#define DPBP_CMDID_IS_ENABLED 0x006
- -
- -#define DPBP_CMDID_SET_IRQ 0x010
- -#define DPBP_CMDID_GET_IRQ 0x011
- -#define DPBP_CMDID_SET_IRQ_ENABLE 0x012
- -#define DPBP_CMDID_GET_IRQ_ENABLE 0x013
- -#define DPBP_CMDID_SET_IRQ_MASK 0x014
- -#define DPBP_CMDID_GET_IRQ_MASK 0x015
- -#define DPBP_CMDID_GET_IRQ_STATUS 0x016
- -#define DPBP_CMDID_CLEAR_IRQ_STATUS 0x017
- -
- -#define DPBP_CMDID_SET_NOTIFICATIONS 0x01b0
- -#define DPBP_CMDID_GET_NOTIFICATIONS 0x01b1
- -
- -struct dpbp_cmd_open {
- - __le32 dpbp_id;
- -};
- -
- -#define DPBP_ENABLE 0x1
- -
- -struct dpbp_rsp_is_enabled {
- - u8 enabled;
- -};
- -
- -struct dpbp_cmd_set_irq {
- - /* cmd word 0 */
- - u8 irq_index;
- - u8 pad[3];
- - __le32 irq_val;
- - /* cmd word 1 */
- - __le64 irq_addr;
- - /* cmd word 2 */
- - __le32 irq_num;
- -};
- -
- -struct dpbp_cmd_get_irq {
- - __le32 pad;
- - u8 irq_index;
- -};
- -
- -struct dpbp_rsp_get_irq {
- - /* response word 0 */
- - __le32 irq_val;
- - __le32 pad;
- - /* response word 1 */
- - __le64 irq_addr;
- - /* response word 2 */
- - __le32 irq_num;
- - __le32 type;
- -};
- -
- -struct dpbp_cmd_set_irq_enable {
- - u8 enable;
- - u8 pad[3];
- - u8 irq_index;
- -};
- -
- -struct dpbp_cmd_get_irq_enable {
- - __le32 pad;
- - u8 irq_index;
- -};
- -
- -struct dpbp_rsp_get_irq_enable {
- - u8 enabled;
- -};
- -
- -struct dpbp_cmd_set_irq_mask {
- - __le32 mask;
- - u8 irq_index;
- -};
- -
- -struct dpbp_cmd_get_irq_mask {
- - __le32 pad;
- - u8 irq_index;
- -};
- -
- -struct dpbp_rsp_get_irq_mask {
- - __le32 mask;
- -};
- -
- -struct dpbp_cmd_get_irq_status {
- - __le32 status;
- - u8 irq_index;
- -};
- -
- -struct dpbp_rsp_get_irq_status {
- - __le32 status;
- -};
- -
- -struct dpbp_cmd_clear_irq_status {
- - __le32 status;
- - u8 irq_index;
- -};
- -
- -struct dpbp_rsp_get_attributes {
- - /* response word 0 */
- - __le16 pad;
- - __le16 bpid;
- - __le32 id;
- - /* response word 1 */
- - __le16 version_major;
- - __le16 version_minor;
- -};
- -
- -struct dpbp_cmd_set_notifications {
- - /* cmd word 0 */
- - __le32 depletion_entry;
- - __le32 depletion_exit;
- - /* cmd word 1 */
- - __le32 surplus_entry;
- - __le32 surplus_exit;
- - /* cmd word 2 */
- - __le16 options;
- - __le16 pad[3];
- - /* cmd word 3 */
- - __le64 message_ctx;
- - /* cmd word 4 */
- - __le64 message_iova;
- -};
- -
- -struct dpbp_rsp_get_notifications {
- - /* response word 0 */
- - __le32 depletion_entry;
- - __le32 depletion_exit;
- - /* response word 1 */
- - __le32 surplus_entry;
- - __le32 surplus_exit;
- - /* response word 2 */
- - __le16 options;
- - __le16 pad[3];
- - /* response word 3 */
- - __le64 message_ctx;
- - /* response word 4 */
- - __le64 message_iova;
- -};
- -
- -#endif /* _FSL_DPBP_CMD_H */
- --- a/drivers/staging/fsl-mc/include/dpbp.h
- +++ b/drivers/staging/fsl-mc/include/dpbp.h
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2015 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -32,7 +33,8 @@
- #ifndef __FSL_DPBP_H
- #define __FSL_DPBP_H
-
- -/* Data Path Buffer Pool API
- +/*
- + * Data Path Buffer Pool API
- * Contains initialization APIs and runtime control APIs for DPBP
- */
-
- @@ -44,25 +46,8 @@ int dpbp_open(struct fsl_mc_io *mc_io,
- u16 *token);
-
- int dpbp_close(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token);
- -
- -/**
- - * struct dpbp_cfg - Structure representing DPBP configuration
- - * @options: place holder
- - */
- -struct dpbp_cfg {
- - u32 options;
- -};
- -
- -int dpbp_create(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - const struct dpbp_cfg *cfg,
- - u16 *token);
- -
- -int dpbp_destroy(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token);
- + u32 cmd_flags,
- + u16 token);
-
- int dpbp_enable(struct fsl_mc_io *mc_io,
- u32 cmd_flags,
- @@ -82,139 +67,24 @@ int dpbp_reset(struct fsl_mc_io *mc_io,
- u16 token);
-
- /**
- - * struct dpbp_irq_cfg - IRQ configuration
- - * @addr: Address that must be written to signal a message-based interrupt
- - * @val: Value to write into irq_addr address
- - * @irq_num: A user defined number associated with this IRQ
- - */
- -struct dpbp_irq_cfg {
- - u64 addr;
- - u32 val;
- - int irq_num;
- -};
- -
- -int dpbp_set_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - struct dpbp_irq_cfg *irq_cfg);
- -
- -int dpbp_get_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - int *type,
- - struct dpbp_irq_cfg *irq_cfg);
- -
- -int dpbp_set_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 en);
- -
- -int dpbp_get_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 *en);
- -
- -int dpbp_set_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 mask);
- -
- -int dpbp_get_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *mask);
- -
- -int dpbp_get_irq_status(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *status);
- -
- -int dpbp_clear_irq_status(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 status);
- -
- -/**
- * struct dpbp_attr - Structure representing DPBP attributes
- * @id: DPBP object ID
- - * @version: DPBP version
- * @bpid: Hardware buffer pool ID; should be used as an argument in
- * acquire/release operations on buffers
- */
- struct dpbp_attr {
- int id;
- - /**
- - * struct version - Structure representing DPBP version
- - * @major: DPBP major version
- - * @minor: DPBP minor version
- - */
- - struct {
- - u16 major;
- - u16 minor;
- - } version;
- u16 bpid;
- };
-
- -int dpbp_get_attributes(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dpbp_attr *attr);
- -
- -/**
- - * DPBP notifications options
- - */
- -
- -/**
- - * BPSCN write will attempt to allocate into a cache (coherent write)
- - */
- -#define DPBP_NOTIF_OPT_COHERENT_WRITE 0x00000001
- -
- -/**
- - * struct dpbp_notification_cfg - Structure representing DPBP notifications
- - * towards software
- - * @depletion_entry: below this threshold the pool is "depleted";
- - * set it to '0' to disable it
- - * @depletion_exit: greater than or equal to this threshold the pool exit its
- - * "depleted" state
- - * @surplus_entry: above this threshold the pool is in "surplus" state;
- - * set it to '0' to disable it
- - * @surplus_exit: less than or equal to this threshold the pool exit its
- - * "surplus" state
- - * @message_iova: MUST be given if either 'depletion_entry' or 'surplus_entry'
- - * is not '0' (enable); I/O virtual address (must be in DMA-able memory),
- - * must be 16B aligned.
- - * @message_ctx: The context that will be part of the BPSCN message and will
- - * be written to 'message_iova'
- - * @options: Mask of available options; use 'DPBP_NOTIF_OPT_<X>' values
- - */
- -struct dpbp_notification_cfg {
- - u32 depletion_entry;
- - u32 depletion_exit;
- - u32 surplus_entry;
- - u32 surplus_exit;
- - u64 message_iova;
- - u64 message_ctx;
- - u16 options;
- -};
- -
- -int dpbp_set_notifications(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dpbp_notification_cfg *cfg);
- -
- -int dpbp_get_notifications(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dpbp_notification_cfg *cfg);
- -
- -/** @} */
- +int dpbp_get_attributes(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dpbp_attr *attr);
- +
- +int dpbp_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver);
-
- #endif /* __FSL_DPBP_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/include/dpcon.h
- @@ -0,0 +1,115 @@
- +/* Copyright 2013-2016 Freescale Semiconductor Inc.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef __FSL_DPCON_H
- +#define __FSL_DPCON_H
- +
- +/* Data Path Concentrator API
- + * Contains initialization APIs and runtime control APIs for DPCON
- + */
- +
- +struct fsl_mc_io;
- +
- +/** General DPCON macros */
- +
- +/**
- + * Use it to disable notifications; see dpcon_set_notification()
- + */
- +#define DPCON_INVALID_DPIO_ID (int)(-1)
- +
- +int dpcon_open(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + int dpcon_id,
- + u16 *token);
- +
- +int dpcon_close(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token);
- +
- +int dpcon_enable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token);
- +
- +int dpcon_disable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token);
- +
- +int dpcon_is_enabled(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + int *en);
- +
- +int dpcon_reset(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token);
- +
- +/**
- + * struct dpcon_attr - Structure representing DPCON attributes
- + * @id: DPCON object ID
- + * @qbman_ch_id: Channel ID to be used by dequeue operation
- + * @num_priorities: Number of priorities for the DPCON channel (1-8)
- + */
- +struct dpcon_attr {
- + int id;
- + u16 qbman_ch_id;
- + u8 num_priorities;
- +};
- +
- +int dpcon_get_attributes(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dpcon_attr *attr);
- +
- +/**
- + * struct dpcon_notification_cfg - Structure representing notification params
- + * @dpio_id: DPIO object ID; must be configured with a notification channel;
- + * to disable notifications set it to 'DPCON_INVALID_DPIO_ID';
- + * @priority: Priority selection within the DPIO channel; valid values
- + * are 0-7, depending on the number of priorities in that channel
- + * @user_ctx: User context value provided with each CDAN message
- + */
- +struct dpcon_notification_cfg {
- + int dpio_id;
- + u8 priority;
- + u64 user_ctx;
- +};
- +
- +int dpcon_set_notification(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dpcon_notification_cfg *cfg);
- +
- +int dpcon_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver);
- +
- +#endif /* __FSL_DPCON_H */
- --- a/drivers/staging/fsl-mc/include/dpmng.h
- +++ b/drivers/staging/fsl-mc/include/dpmng.h
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2015 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -32,7 +33,8 @@
- #ifndef __FSL_DPMNG_H
- #define __FSL_DPMNG_H
-
- -/* Management Complex General API
- +/*
- + * Management Complex General API
- * Contains general API for the Management Complex firmware
- */
-
- @@ -58,12 +60,8 @@ struct mc_version {
- u32 revision;
- };
-
- -int mc_get_version(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - struct mc_version *mc_ver_info);
- -
- -int dpmng_get_container_id(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - int *container_id);
- +int mc_get_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + struct mc_version *mc_ver_info);
-
- #endif /* __FSL_DPMNG_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-mc/include/dpopr.h
- @@ -0,0 +1,110 @@
- +/*
- + * Copyright 2017 NXP
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are met:
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * * Neither the name of the above-listed copyright holders nor the
- + * names of any contributors may be used to endorse or promote products
- + * derived from this software without specific prior written permission.
- + *
- + *
- + * ALTERNATIVELY, this software may be distributed under the terms of the
- + * GNU General Public License ("GPL") as published by the Free Software
- + * Foundation, either version 2 of that License or (at your option) any
- + * later version.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- + * POSSIBILITY OF SUCH DAMAGE.
- + */
- +#ifndef __FSL_DPOPR_H_
- +#define __FSL_DPOPR_H_
- +
- +/* Data Path Order Restoration API
- + * Contains initialization APIs and runtime APIs for the Order Restoration
- + */
- +
- +/** Order Restoration properties */
- +
- +/**
- + * Create a new Order Point Record option
- + */
- +#define OPR_OPT_CREATE 0x1
- +/**
- + * Retire an existing Order Point Record option
- + */
- +#define OPR_OPT_RETIRE 0x2
- +
- +/**
- + * struct opr_cfg - Structure representing OPR configuration
- + * @oprrws: Order point record (OPR) restoration window size (0 to 5)
- + * 0 - Window size is 32 frames.
- + * 1 - Window size is 64 frames.
- + * 2 - Window size is 128 frames.
- + * 3 - Window size is 256 frames.
- + * 4 - Window size is 512 frames.
- + * 5 - Window size is 1024 frames.
- + * @oa: OPR auto advance NESN window size (0 disabled, 1 enabled)
- + * @olws: OPR acceptable late arrival window size (0 to 3)
- + * 0 - Disabled. Late arrivals are always rejected.
- + * 1 - Window size is 32 frames.
- + * 2 - Window size is the same as the OPR restoration
- + * window size configured in the OPRRWS field.
- + * 3 - Window size is 8192 frames. Late arrivals are
- + * always accepted.
- + * @oeane: Order restoration list (ORL) resource exhaustion
- + * advance NESN enable (0 disabled, 1 enabled)
- + * @oloe: OPR loose ordering enable (0 disabled, 1 enabled)
- + */
- +struct opr_cfg {
- + u8 oprrws;
- + u8 oa;
- + u8 olws;
- + u8 oeane;
- + u8 oloe;
- +};
- +
- +/**
- + * struct opr_qry - Structure representing OPR configuration
- + * @enable: Enabled state
- + * @rip: Retirement In Progress
- + * @ndsn: Next dispensed sequence number
- + * @nesn: Next expected sequence number
- + * @ea_hseq: Early arrival head sequence number
- + * @hseq_nlis: HSEQ not last in sequence
- + * @ea_tseq: Early arrival tail sequence number
- + * @tseq_nlis: TSEQ not last in sequence
- + * @ea_tptr: Early arrival tail pointer
- + * @ea_hptr: Early arrival head pointer
- + * @opr_id: Order Point Record ID
- + * @opr_vid: Order Point Record Virtual ID
- + */
- +struct opr_qry {
- + char enable;
- + char rip;
- + u16 ndsn;
- + u16 nesn;
- + u16 ea_hseq;
- + char hseq_nlis;
- + u16 ea_tseq;
- + char tseq_nlis;
- + u16 ea_tptr;
- + u16 ea_hptr;
- + u16 opr_id;
- + u16 opr_vid;
- +};
- +
- +#endif /* __FSL_DPOPR_H_ */
- --- a/drivers/staging/fsl-mc/include/dprc.h
- +++ b/drivers/staging/fsl-mc/include/dprc.h
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2015 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -34,26 +35,13 @@
-
- #include "mc-cmd.h"
-
- -/* Data Path Resource Container API
- +/*
- + * Data Path Resource Container API
- * Contains DPRC API for managing and querying DPAA resources
- */
-
- struct fsl_mc_io;
-
- -/**
- - * Set this value as the icid value in dprc_cfg structure when creating a
- - * container, in case the ICID is not selected by the user and should be
- - * allocated by the DPRC from the pool of ICIDs.
- - */
- -#define DPRC_GET_ICID_FROM_POOL (u16)(~(0))
- -
- -/**
- - * Set this value as the portal_id value in dprc_cfg structure when creating a
- - * container, in case the portal ID is not specifically selected by the
- - * user and should be allocated by the DPRC from the pool of portal ids.
- - */
- -#define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0))
- -
- int dprc_open(struct fsl_mc_io *mc_io,
- u32 cmd_flags,
- int container_id,
- @@ -63,75 +51,6 @@ int dprc_close(struct fsl_mc_io *mc_io,
- u32 cmd_flags,
- u16 token);
-
- -/**
- - * Container general options
- - *
- - * These options may be selected at container creation by the container creator
- - * and can be retrieved using dprc_get_attributes()
- - */
- -
- -/* Spawn Policy Option allowed - Indicates that the new container is allowed
- - * to spawn and have its own child containers.
- - */
- -#define DPRC_CFG_OPT_SPAWN_ALLOWED 0x00000001
- -
- -/* General Container allocation policy - Indicates that the new container is
- - * allowed to allocate requested resources from its parent container; if not
- - * set, the container is only allowed to use resources in its own pools; Note
- - * that this is a container's global policy, but the parent container may
- - * override it and set specific quota per resource type.
- - */
- -#define DPRC_CFG_OPT_ALLOC_ALLOWED 0x00000002
- -
- -/* Object initialization allowed - software context associated with this
- - * container is allowed to invoke object initialization operations.
- - */
- -#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004
- -
- -/* Topology change allowed - software context associated with this
- - * container is allowed to invoke topology operations, such as attach/detach
- - * of network objects.
- - */
- -#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008
- -
- -/* AIOP - Indicates that container belongs to AIOP. */
- -#define DPRC_CFG_OPT_AIOP 0x00000020
- -
- -/* IRQ Config - Indicates that the container allowed to configure its IRQs. */
- -#define DPRC_CFG_OPT_IRQ_CFG_ALLOWED 0x00000040
- -
- -/**
- - * struct dprc_cfg - Container configuration options
- - * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free
- - * ICID value is allocated by the DPRC
- - * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free
- - * portal ID is allocated by the DPRC
- - * @options: Combination of 'DPRC_CFG_OPT_<X>' options
- - * @label: Object's label
- - */
- -struct dprc_cfg {
- - u16 icid;
- - int portal_id;
- - u64 options;
- - char label[16];
- -};
- -
- -int dprc_create_container(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dprc_cfg *cfg,
- - int *child_container_id,
- - u64 *child_portal_offset);
- -
- -int dprc_destroy_container(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id);
- -
- -int dprc_reset_container(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id);
-
- /* IRQ */
-
- @@ -139,7 +58,7 @@ int dprc_reset_container(struct fsl_mc_i
- #define DPRC_IRQ_INDEX 0
-
- /* Number of dprc's IRQs */
- -#define DPRC_NUM_OF_IRQS 1
- +#define DPRC_NUM_OF_IRQS 1
-
- /* DPRC IRQ events */
-
- @@ -151,12 +70,14 @@ int dprc_reset_container(struct fsl_mc_i
- #define DPRC_IRQ_EVENT_RES_ADDED 0x00000004
- /* IRQ event - Indicates that resources removed from the container */
- #define DPRC_IRQ_EVENT_RES_REMOVED 0x00000008
- -/* IRQ event - Indicates that one of the descendant containers that opened by
- +/*
- + * IRQ event - Indicates that one of the descendant containers that opened by
- * this container is destroyed
- */
- #define DPRC_IRQ_EVENT_CONTAINER_DESTROYED 0x00000010
-
- -/* IRQ event - Indicates that on one of the container's opened object is
- +/*
- + * IRQ event - Indicates that on one of the container's opened object is
- * destroyed
- */
- #define DPRC_IRQ_EVENT_OBJ_DESTROYED 0x00000020
- @@ -171,59 +92,59 @@ int dprc_reset_container(struct fsl_mc_i
- * @irq_num: A user defined number associated with this IRQ
- */
- struct dprc_irq_cfg {
- - phys_addr_t paddr;
- - u32 val;
- - int irq_num;
- -};
- -
- -int dprc_set_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - struct dprc_irq_cfg *irq_cfg);
- -
- -int dprc_get_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - int *type,
- - struct dprc_irq_cfg *irq_cfg);
- -
- -int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 en);
- -
- -int dprc_get_irq_enable(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u8 *en);
- -
- -int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 mask);
- -
- -int dprc_get_irq_mask(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *mask);
- -
- -int dprc_get_irq_status(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 *status);
- -
- -int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - u8 irq_index,
- - u32 status);
- + phys_addr_t paddr;
- + u32 val;
- + int irq_num;
- +};
- +
- +int dprc_set_irq(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + struct dprc_irq_cfg *irq_cfg);
- +
- +int dprc_get_irq(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + int *type,
- + struct dprc_irq_cfg *irq_cfg);
- +
- +int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + u8 en);
- +
- +int dprc_get_irq_enable(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + u8 *en);
- +
- +int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + u32 mask);
- +
- +int dprc_get_irq_mask(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + u32 *mask);
- +
- +int dprc_get_irq_status(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + u32 *status);
- +
- +int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + u8 irq_index,
- + u32 status);
-
- /**
- * struct dprc_attributes - Container attributes
- @@ -231,114 +152,23 @@ int dprc_clear_irq_status(struct fsl_mc_
- * @icid: Container's ICID
- * @portal_id: Container's portal ID
- * @options: Container's options as set at container's creation
- - * @version: DPRC version
- */
- struct dprc_attributes {
- int container_id;
- u16 icid;
- int portal_id;
- u64 options;
- - /**
- - * struct version - DPRC version
- - * @major: DPRC major version
- - * @minor: DPRC minor version
- - */
- - struct {
- - u16 major;
- - u16 minor;
- - } version;
- };
-
- -int dprc_get_attributes(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - struct dprc_attributes *attributes);
- -
- -int dprc_set_res_quota(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id,
- - char *type,
- - u16 quota);
- -
- -int dprc_get_res_quota(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id,
- - char *type,
- - u16 *quota);
- -
- -/* Resource request options */
- -
- -/* Explicit resource ID request - The requested objects/resources
- - * are explicit and sequential (in case of resources).
- - * The base ID is given at res_req at base_align field
- - */
- -#define DPRC_RES_REQ_OPT_EXPLICIT 0x00000001
- -
- -/* Aligned resources request - Relevant only for resources
- - * request (and not objects). Indicates that resources base ID should be
- - * sequential and aligned to the value given at dprc_res_req base_align field
- - */
- -#define DPRC_RES_REQ_OPT_ALIGNED 0x00000002
- -
- -/* Plugged Flag - Relevant only for object assignment request.
- - * Indicates that after all objects assigned. An interrupt will be invoked at
- - * the relevant GPP. The assigned object will be marked as plugged.
- - * plugged objects can't be assigned from their container
- - */
- -#define DPRC_RES_REQ_OPT_PLUGGED 0x00000004
- -
- -/**
- - * struct dprc_res_req - Resource request descriptor, to be used in assignment
- - * or un-assignment of resources and objects.
- - * @type: Resource/object type: Represent as a NULL terminated string.
- - * This string may received by using dprc_get_pool() to get resource
- - * type and dprc_get_obj() to get object type;
- - * Note: it is not possible to assign/un-assign DPRC objects
- - * @num: Number of resources
- - * @options: Request options: combination of DPRC_RES_REQ_OPT_ options
- - * @id_base_align: In case of explicit assignment (DPRC_RES_REQ_OPT_EXPLICIT
- - * is set at option), this field represents the required base ID
- - * for resource allocation; In case of aligned assignment
- - * (DPRC_RES_REQ_OPT_ALIGNED is set at option), this field
- - * indicates the required alignment for the resource ID(s) -
- - * use 0 if there is no alignment or explicit ID requirements
- - */
- -struct dprc_res_req {
- - char type[16];
- - u32 num;
- - u32 options;
- - int id_base_align;
- -};
- -
- -int dprc_assign(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int container_id,
- - struct dprc_res_req *res_req);
- -
- -int dprc_unassign(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int child_container_id,
- - struct dprc_res_req *res_req);
- -
- -int dprc_get_pool_count(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int *pool_count);
- -
- -int dprc_get_pool(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int pool_index,
- - char *type);
- +int dprc_get_attributes(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + struct dprc_attributes *attributes);
-
- int dprc_get_obj_count(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int *obj_count);
- + u32 cmd_flags,
- + u16 token,
- + int *obj_count);
-
- /* Objects Attributes Flags */
-
- @@ -353,7 +183,7 @@ int dprc_get_obj_count(struct fsl_mc_io
- * masters;
- * user is responsible for proper memory handling through IOMMU configuration.
- */
- -#define DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY 0x0001
- +#define DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY 0x0001
-
- /**
- * struct dprc_obj_desc - Object descriptor, returned from dprc_get_obj()
- @@ -381,41 +211,41 @@ struct dprc_obj_desc {
- u16 flags;
- };
-
- -int dprc_get_obj(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - int obj_index,
- - struct dprc_obj_desc *obj_desc);
- -
- -int dprc_get_obj_desc(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *obj_type,
- - int obj_id,
- - struct dprc_obj_desc *obj_desc);
- -
- -int dprc_set_obj_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *obj_type,
- - int obj_id,
- - u8 irq_index,
- - struct dprc_irq_cfg *irq_cfg);
- -
- -int dprc_get_obj_irq(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *obj_type,
- - int obj_id,
- - u8 irq_index,
- - int *type,
- - struct dprc_irq_cfg *irq_cfg);
- -
- -int dprc_get_res_count(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *type,
- - int *res_count);
- +int dprc_get_obj(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + int obj_index,
- + struct dprc_obj_desc *obj_desc);
- +
- +int dprc_get_obj_desc(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + char *obj_type,
- + int obj_id,
- + struct dprc_obj_desc *obj_desc);
- +
- +int dprc_set_obj_irq(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + char *obj_type,
- + int obj_id,
- + u8 irq_index,
- + struct dprc_irq_cfg *irq_cfg);
- +
- +int dprc_get_obj_irq(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + char *obj_type,
- + int obj_id,
- + u8 irq_index,
- + int *type,
- + struct dprc_irq_cfg *irq_cfg);
- +
- +int dprc_get_res_count(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + char *type,
- + int *res_count);
-
- /**
- * enum dprc_iter_status - Iteration status
- @@ -429,27 +259,6 @@ enum dprc_iter_status {
- DPRC_ITER_STATUS_LAST = 2
- };
-
- -/**
- - * struct dprc_res_ids_range_desc - Resource ID range descriptor
- - * @base_id: Base resource ID of this range
- - * @last_id: Last resource ID of this range
- - * @iter_status: Iteration status - should be set to DPRC_ITER_STATUS_FIRST at
- - * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE,
- - * additional iterations are needed, until the returned marker is
- - * DPRC_ITER_STATUS_LAST
- - */
- -struct dprc_res_ids_range_desc {
- - int base_id;
- - int last_id;
- - enum dprc_iter_status iter_status;
- -};
- -
- -int dprc_get_res_ids(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *type,
- - struct dprc_res_ids_range_desc *range_desc);
- -
- /* Region flags */
- /* Cacheable - Indicates that region should be mapped as cacheable */
- #define DPRC_REGION_CACHEABLE 0x00000001
- @@ -481,64 +290,27 @@ struct dprc_region_desc {
- enum dprc_region_type type;
- };
-
- -int dprc_get_obj_region(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *obj_type,
- - int obj_id,
- - u8 region_index,
- - struct dprc_region_desc *region_desc);
- -
- -int dprc_set_obj_label(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - char *obj_type,
- - int obj_id,
- - char *label);
- +int dprc_get_obj_region(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + char *obj_type,
- + int obj_id,
- + u8 region_index,
- + struct dprc_region_desc *region_desc);
-
- -/**
- - * struct dprc_endpoint - Endpoint description for link connect/disconnect
- - * operations
- - * @type: Endpoint object type: NULL terminated string
- - * @id: Endpoint object ID
- - * @if_id: Interface ID; should be set for endpoints with multiple
- - * interfaces ("dpsw", "dpdmux"); for others, always set to 0
- - */
- -struct dprc_endpoint {
- - char type[16];
- - int id;
- - int if_id;
- -};
- +int dprc_get_api_version(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 *major_ver,
- + u16 *minor_ver);
-
- -/**
- - * struct dprc_connection_cfg - Connection configuration.
- - * Used for virtual connections only
- - * @committed_rate: Committed rate (Mbits/s)
- - * @max_rate: Maximum rate (Mbits/s)
- - */
- -struct dprc_connection_cfg {
- - u32 committed_rate;
- - u32 max_rate;
- -};
- +int dprc_get_container_id(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + int *container_id);
-
- -int dprc_connect(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - const struct dprc_endpoint *endpoint1,
- - const struct dprc_endpoint *endpoint2,
- - const struct dprc_connection_cfg *cfg);
- -
- -int dprc_disconnect(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - const struct dprc_endpoint *endpoint);
- -
- -int dprc_get_connection(struct fsl_mc_io *mc_io,
- - u32 cmd_flags,
- - u16 token,
- - const struct dprc_endpoint *endpoint1,
- - struct dprc_endpoint *endpoint2,
- - int *state);
- +int dprc_reset_container(struct fsl_mc_io *mc_io,
- + u32 cmd_flags,
- + u16 token,
- + int child_container_id);
-
- #endif /* _FSL_DPRC_H */
-
- --- a/drivers/staging/fsl-mc/include/mc-bus.h
- +++ b/drivers/staging/fsl-mc/include/mc-bus.h
- @@ -1,7 +1,7 @@
- /*
- * Freescale Management Complex (MC) bus declarations
- *
- - * Copyright (C) 2014 Freescale Semiconductor, Inc.
- + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Author: German Rivera <[email protected]>
- *
- * This file is licensed under the terms of the GNU General Public
- @@ -42,8 +42,8 @@ struct msi_domain_info;
- */
- struct fsl_mc_resource_pool {
- enum fsl_mc_pool_type type;
- - int16_t max_count;
- - int16_t free_count;
- + int max_count;
- + int free_count;
- struct mutex mutex; /* serializes access to free_list */
- struct list_head free_list;
- struct fsl_mc_bus *mc_bus;
- @@ -73,6 +73,7 @@ struct fsl_mc_bus {
- int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);
-
- int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
- + const char *driver_override,
- unsigned int *total_irq_count);
-
- int __init dprc_driver_init(void);
- --- a/drivers/staging/fsl-mc/include/mc-cmd.h
- +++ b/drivers/staging/fsl-mc/include/mc-cmd.h
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2015 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- @@ -48,6 +49,15 @@ struct mc_command {
- u64 params[MC_CMD_NUM_OF_PARAMS];
- };
-
- +struct mc_rsp_create {
- + __le32 object_id;
- +};
- +
- +struct mc_rsp_api_ver {
- + __le16 major_ver;
- + __le16 minor_ver;
- +};
- +
- enum mc_cmd_status {
- MC_CMD_STATUS_OK = 0x0, /* Completed successfully */
- MC_CMD_STATUS_READY = 0x1, /* Ready to be processed */
- @@ -72,11 +82,6 @@ enum mc_cmd_status {
- /* Command completion flag */
- #define MC_CMD_FLAG_INTR_DIS 0x01
-
- -#define MC_CMD_HDR_CMDID_MASK 0xFFF0
- -#define MC_CMD_HDR_CMDID_SHIFT 4
- -#define MC_CMD_HDR_TOKEN_MASK 0xFFC0
- -#define MC_CMD_HDR_TOKEN_SHIFT 6
- -
- static inline u64 mc_encode_cmd_header(u16 cmd_id,
- u32 cmd_flags,
- u16 token)
- @@ -84,10 +89,8 @@ static inline u64 mc_encode_cmd_header(u
- u64 header = 0;
- struct mc_cmd_header *hdr = (struct mc_cmd_header *)&header;
-
- - hdr->cmd_id = cpu_to_le16((cmd_id << MC_CMD_HDR_CMDID_SHIFT) &
- - MC_CMD_HDR_CMDID_MASK);
- - hdr->token = cpu_to_le16((token << MC_CMD_HDR_TOKEN_SHIFT) &
- - MC_CMD_HDR_TOKEN_MASK);
- + hdr->cmd_id = cpu_to_le16(cmd_id);
- + hdr->token = cpu_to_le16(token);
- hdr->status = MC_CMD_STATUS_READY;
- if (cmd_flags & MC_CMD_FLAG_PRI)
- hdr->flags_hw = MC_CMD_FLAG_PRI;
- @@ -102,7 +105,26 @@ static inline u16 mc_cmd_hdr_read_token(
- struct mc_cmd_header *hdr = (struct mc_cmd_header *)&cmd->header;
- u16 token = le16_to_cpu(hdr->token);
-
- - return (token & MC_CMD_HDR_TOKEN_MASK) >> MC_CMD_HDR_TOKEN_SHIFT;
- + return token;
- +}
- +
- +static inline u32 mc_cmd_read_object_id(struct mc_command *cmd)
- +{
- + struct mc_rsp_create *rsp_params;
- +
- + rsp_params = (struct mc_rsp_create *)cmd->params;
- + return le32_to_cpu(rsp_params->object_id);
- +}
- +
- +static inline void mc_cmd_read_api_version(struct mc_command *cmd,
- + u16 *major_ver,
- + u16 *minor_ver)
- +{
- + struct mc_rsp_api_ver *rsp_params;
- +
- + rsp_params = (struct mc_rsp_api_ver *)cmd->params;
- + *major_ver = le16_to_cpu(rsp_params->major_ver);
- + *minor_ver = le16_to_cpu(rsp_params->minor_ver);
- }
-
- #endif /* __FSL_MC_CMD_H */
- --- a/drivers/staging/fsl-mc/include/mc-sys.h
- +++ b/drivers/staging/fsl-mc/include/mc-sys.h
- @@ -1,4 +1,5 @@
- -/* Copyright 2013-2014 Freescale Semiconductor Inc.
- +/*
- + * Copyright 2013-2016 Freescale Semiconductor Inc.
- *
- * Interface of the I/O services to send MC commands to the MC hardware
- *
- --- a/drivers/staging/fsl-mc/include/mc.h
- +++ b/drivers/staging/fsl-mc/include/mc.h
- @@ -1,7 +1,7 @@
- /*
- * Freescale Management Complex (MC) bus public interface
- *
- - * Copyright (C) 2014 Freescale Semiconductor, Inc.
- + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Author: German Rivera <[email protected]>
- *
- * This file is licensed under the terms of the GNU General Public
- @@ -81,7 +81,7 @@ enum fsl_mc_pool_type {
- */
- struct fsl_mc_resource {
- enum fsl_mc_pool_type type;
- - int32_t id;
- + s32 id;
- void *data;
- struct fsl_mc_resource_pool *parent_pool;
- struct list_head node;
- @@ -122,6 +122,7 @@ struct fsl_mc_device_irq {
- * @regions: pointer to array of MMIO region entries
- * @irqs: pointer to array of pointers to interrupts allocated to this device
- * @resource: generic resource associated with this MC object device, if any.
- + * @driver_override: Driver name to force a match
- *
- * Generic device object for MC object devices that are "attached" to a
- * MC bus.
- @@ -154,6 +155,7 @@ struct fsl_mc_device {
- struct resource *regions;
- struct fsl_mc_device_irq **irqs;
- struct fsl_mc_resource *resource;
- + const char *driver_override;
- };
-
- #define to_fsl_mc_device(_dev) \
- @@ -175,6 +177,8 @@ struct fsl_mc_device {
- #define fsl_mc_driver_register(drv) \
- __fsl_mc_driver_register(drv, THIS_MODULE)
-
- +void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
- +
- int __must_check __fsl_mc_driver_register(struct fsl_mc_driver *fsl_mc_driver,
- struct module *owner);
-
- @@ -198,4 +202,13 @@ int __must_check fsl_mc_allocate_irqs(st
-
- void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev);
-
- +void fsl_mc_dma_configure(struct fsl_mc_device *mc_dev,
- + struct device_node *fsl_mc_platform_node, int coherent);
- +
- +#ifdef CONFIG_FSL_MC_BUS
- +struct iommu_group *fsl_mc_device_group(struct device *dev);
- +#else
- +#define fsl_mc_device_group(__dev) NULL
- +#endif
- +
- #endif /* _FSL_MC_H_ */
|