12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605 |
- From 8df017d70c54ceafc99b7904785603c678a2e5c1 Mon Sep 17 00:00:00 2001
- From: Razvan Stefanescu <razvan.stefanescu@freescale.com>
- Date: Tue, 22 Sep 2015 11:36:34 +0300
- Subject: [PATCH 220/226] dpaa2-ethsw: Ethernet Switch driver
- This is a commit of the cummulative, squashed dpaa2-l2switch patches.
- All the commit logs are preserved below.
- Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
- ---------------------------------------------------------------------
- dpaa2-ethsw: Ethernet Switch driver
- Initial support for DPAA2 L2 switch. The switch and all ports are
- presented as network interfaces in linux (swX and swXpY). I/O
- functionality is not available on these interfaces, they are exclusively
- for management.
- Configuration is done using bridge tool. Supported commands are:
- - fdb operations with unicast/multicast addresses
- - vlan configuration
- - setting STP state of ports
- - flooding, learning control
- Offers support for retrieving port statistics via ethtool (or similar
- applications).
- This patch contains the following patches squashed together:
- staging: fsl-dpaa2: ethsw: ethernet switch driver
- dpaa2-ethsw: Include by default in configuration
- staging: fsl-dpaa2: ethsw: Rebasing onto kernel 4.0
- staging: fsl-mc: migrated remaining flibs for MC fw 8.0.0
- dpaa2-ethsw: Prefix driver name with dpaa2-
- dpaa2-ethsw: Set carrier state on probe
- dpaa2-ethsw: Add support for link state update
- These patches were initally submitted by:
- Alex Marginean <alexandru.marginean@freescale.com>
- J. German Rivera <German.Rivera@freescale.com>
- Razvan Stefanescu <razvan.stefanescu@freescale.com>
- and reviewed by Stuart Yoder <stuart.yoder@freescale.com>
- Ported to linux-v4.1 by updating iflink usage and ndo_bridge_getlink()
- parameters list update.
- Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
- [Stuart: resolved minor merge conflicts]
- Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
- dpaa2-ethsw: Update dpsw binary interface to 7.0
- This corresponds to MC release 0.8.0.
- Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
- dpaa2-ethsw: Add object version check
- Abort probing if DPSW object version is smaller than required.
- Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
- dpaa2-ethsw: Fix interrupt handling
- Mask only the events handled by the driver - DPSW_IRQ_EVENT_LINK_CHANGED.
- Use clear-on-read mechanism for the interrupt status and avoid calling
- dpsw_clear_irq_status(). Status contains the events handled (only link
- state change for the moment) and masks the first 16-bits, as they are used
- to store the interface ID that generated the event.
- Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
- dpaa2-ethsw: resolve compile issues on uprev to 4.5
- -irq_number field no longer exists in fsl-mc interrupt
- struct
- -netdev_master_upper_dev_link() has 2 new parameters, which
- are set to NULL for now
- Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
- ---
- MAINTAINERS | 6 +
- drivers/staging/fsl-dpaa2/Kconfig | 1 +
- drivers/staging/fsl-dpaa2/Makefile | 1 +
- drivers/staging/fsl-dpaa2/ethsw/Kconfig | 7 +
- drivers/staging/fsl-dpaa2/ethsw/Makefile | 10 +
- drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h | 916 ++++++++++++
- drivers/staging/fsl-dpaa2/ethsw/dpsw.c | 1639 +++++++++++++++++++++
- drivers/staging/fsl-dpaa2/ethsw/dpsw.h | 2164 ++++++++++++++++++++++++++++
- drivers/staging/fsl-dpaa2/ethsw/switch.c | 1711 ++++++++++++++++++++++
- drivers/staging/fsl-mc/include/net.h | 1 -
- 10 files changed, 6455 insertions(+), 1 deletion(-)
- create mode 100644 drivers/staging/fsl-dpaa2/ethsw/Kconfig
- create mode 100644 drivers/staging/fsl-dpaa2/ethsw/Makefile
- create mode 100644 drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h
- create mode 100644 drivers/staging/fsl-dpaa2/ethsw/dpsw.c
- create mode 100644 drivers/staging/fsl-dpaa2/ethsw/dpsw.h
- create mode 100644 drivers/staging/fsl-dpaa2/ethsw/switch.c
- --- a/MAINTAINERS
- +++ b/MAINTAINERS
- @@ -4554,6 +4554,12 @@ S: Maintained
- F: drivers/staging/fsl-mc/bus/mc-ioctl.h
- F: drivers/staging/fsl-mc/bus/mc-restool.c
-
- +FREESCALE DPAA2 ETHERNET SWITCH DRIVER
- +M: Alex Marginean <Alexandru.Marginean@freescale.com>
- +L: linux-kernel@vger.kernel.org
- +S: Maintained
- +F: drivers/staging/fsl-dpaa2/ethsw/
- +
- FREESCALE DPAA2 MAC/PHY INTERFACE DRIVER
- M: Alex Marginean <Alexandru.Marginean@freescale.com>
- L: linux-kernel@vger.kernel.org
- --- a/drivers/staging/fsl-dpaa2/Kconfig
- +++ b/drivers/staging/fsl-dpaa2/Kconfig
- @@ -11,3 +11,4 @@ config FSL_DPAA2
- source "drivers/staging/fsl-dpaa2/ethernet/Kconfig"
- source "drivers/staging/fsl-dpaa2/mac/Kconfig"
- source "drivers/staging/fsl-dpaa2/evb/Kconfig"
- +source "drivers/staging/fsl-dpaa2/ethsw/Kconfig"
- --- a/drivers/staging/fsl-dpaa2/Makefile
- +++ b/drivers/staging/fsl-dpaa2/Makefile
- @@ -5,3 +5,4 @@
- obj-$(CONFIG_FSL_DPAA2_ETH) += ethernet/
- obj-$(CONFIG_FSL_DPAA2_MAC) += mac/
- obj-$(CONFIG_FSL_DPAA2_EVB) += evb/
- +obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/
- --- /dev/null
- +++ b/drivers/staging/fsl-dpaa2/ethsw/Kconfig
- @@ -0,0 +1,7 @@
- +config FSL_DPAA2_ETHSW
- + tristate "DPAA2 Ethernet Switch"
- + depends on FSL_MC_BUS && FSL_DPAA2 && FSL_DPAA2_ETH
- + select FSL_DPAA2_MAC
- + default y
- + ---help---
- + Prototype driver for DPAA2 Ethernet Switch.
- --- /dev/null
- +++ b/drivers/staging/fsl-dpaa2/ethsw/Makefile
- @@ -0,0 +1,10 @@
- +
- +obj-$(CONFIG_FSL_DPAA2_ETHSW) += dpaa2-ethsw.o
- +
- +dpaa2-ethsw-objs := switch.o dpsw.o
- +
- +all:
- + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
- +
- +clean:
- + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
- --- /dev/null
- +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h
- @@ -0,0 +1,916 @@
- +/* 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_DPSW_CMD_H
- +#define __FSL_DPSW_CMD_H
- +
- +/* DPSW Version */
- +#define DPSW_VER_MAJOR 7
- +#define DPSW_VER_MINOR 0
- +
- +/* Command IDs */
- +#define DPSW_CMDID_CLOSE 0x800
- +#define DPSW_CMDID_OPEN 0x802
- +#define DPSW_CMDID_CREATE 0x902
- +#define DPSW_CMDID_DESTROY 0x900
- +
- +#define DPSW_CMDID_ENABLE 0x002
- +#define DPSW_CMDID_DISABLE 0x003
- +#define DPSW_CMDID_GET_ATTR 0x004
- +#define DPSW_CMDID_RESET 0x005
- +#define DPSW_CMDID_IS_ENABLED 0x006
- +
- +#define DPSW_CMDID_SET_IRQ 0x010
- +#define DPSW_CMDID_GET_IRQ 0x011
- +#define DPSW_CMDID_SET_IRQ_ENABLE 0x012
- +#define DPSW_CMDID_GET_IRQ_ENABLE 0x013
- +#define DPSW_CMDID_SET_IRQ_MASK 0x014
- +#define DPSW_CMDID_GET_IRQ_MASK 0x015
- +#define DPSW_CMDID_GET_IRQ_STATUS 0x016
- +#define DPSW_CMDID_CLEAR_IRQ_STATUS 0x017
- +
- +#define DPSW_CMDID_SET_REFLECTION_IF 0x022
- +
- +#define DPSW_CMDID_ADD_CUSTOM_TPID 0x024
- +
- +#define DPSW_CMDID_REMOVE_CUSTOM_TPID 0x026
- +
- +#define DPSW_CMDID_IF_SET_TCI 0x030
- +#define DPSW_CMDID_IF_SET_STP 0x031
- +#define DPSW_CMDID_IF_SET_ACCEPTED_FRAMES 0x032
- +#define DPSW_CMDID_SET_IF_ACCEPT_ALL_VLAN 0x033
- +#define DPSW_CMDID_IF_GET_COUNTER 0x034
- +#define DPSW_CMDID_IF_SET_COUNTER 0x035
- +#define DPSW_CMDID_IF_SET_TX_SELECTION 0x036
- +#define DPSW_CMDID_IF_ADD_REFLECTION 0x037
- +#define DPSW_CMDID_IF_REMOVE_REFLECTION 0x038
- +#define DPSW_CMDID_IF_SET_FLOODING_METERING 0x039
- +#define DPSW_CMDID_IF_SET_METERING 0x03A
- +#define DPSW_CMDID_IF_SET_EARLY_DROP 0x03B
- +
- +#define DPSW_CMDID_IF_ENABLE 0x03D
- +#define DPSW_CMDID_IF_DISABLE 0x03E
- +
- +#define DPSW_CMDID_IF_GET_ATTR 0x042
- +
- +#define DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH 0x044
- +#define DPSW_CMDID_IF_GET_MAX_FRAME_LENGTH 0x045
- +#define DPSW_CMDID_IF_GET_LINK_STATE 0x046
- +#define DPSW_CMDID_IF_SET_FLOODING 0x047
- +#define DPSW_CMDID_IF_SET_BROADCAST 0x048
- +#define DPSW_CMDID_IF_SET_MULTICAST 0x049
- +#define DPSW_CMDID_IF_GET_TCI 0x04A
- +
- +#define DPSW_CMDID_IF_SET_LINK_CFG 0x04C
- +
- +#define DPSW_CMDID_VLAN_ADD 0x060
- +#define DPSW_CMDID_VLAN_ADD_IF 0x061
- +#define DPSW_CMDID_VLAN_ADD_IF_UNTAGGED 0x062
- +#define DPSW_CMDID_VLAN_ADD_IF_FLOODING 0x063
- +#define DPSW_CMDID_VLAN_REMOVE_IF 0x064
- +#define DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED 0x065
- +#define DPSW_CMDID_VLAN_REMOVE_IF_FLOODING 0x066
- +#define DPSW_CMDID_VLAN_REMOVE 0x067
- +#define DPSW_CMDID_VLAN_GET_IF 0x068
- +#define DPSW_CMDID_VLAN_GET_IF_FLOODING 0x069
- +#define DPSW_CMDID_VLAN_GET_IF_UNTAGGED 0x06A
- +#define DPSW_CMDID_VLAN_GET_ATTRIBUTES 0x06B
- +
- +#define DPSW_CMDID_FDB_GET_MULTICAST 0x080
- +#define DPSW_CMDID_FDB_GET_UNICAST 0x081
- +#define DPSW_CMDID_FDB_ADD 0x082
- +#define DPSW_CMDID_FDB_REMOVE 0x083
- +#define DPSW_CMDID_FDB_ADD_UNICAST 0x084
- +#define DPSW_CMDID_FDB_REMOVE_UNICAST 0x085
- +#define DPSW_CMDID_FDB_ADD_MULTICAST 0x086
- +#define DPSW_CMDID_FDB_REMOVE_MULTICAST 0x087
- +#define DPSW_CMDID_FDB_SET_LEARNING_MODE 0x088
- +#define DPSW_CMDID_FDB_GET_ATTR 0x089
- +
- +#define DPSW_CMDID_ACL_ADD 0x090
- +#define DPSW_CMDID_ACL_REMOVE 0x091
- +#define DPSW_CMDID_ACL_ADD_ENTRY 0x092
- +#define DPSW_CMDID_ACL_REMOVE_ENTRY 0x093
- +#define DPSW_CMDID_ACL_ADD_IF 0x094
- +#define DPSW_CMDID_ACL_REMOVE_IF 0x095
- +#define DPSW_CMDID_ACL_GET_ATTR 0x096
- +
- +#define DPSW_CMDID_CTRL_IF_GET_ATTR 0x0A0
- +#define DPSW_CMDID_CTRL_IF_SET_POOLS 0x0A1
- +#define DPSW_CMDID_CTRL_IF_ENABLE 0x0A2
- +#define DPSW_CMDID_CTRL_IF_DISABLE 0x0A3
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_OPEN(cmd, dpsw_id) \
- + MC_CMD_OP(cmd, 0, 0, 32, int, dpsw_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_CREATE(cmd, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->num_ifs);\
- + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->adv.max_fdbs);\
- + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->adv.max_meters_per_if);\
- + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_component_type, \
- + cfg->adv.component_type);\
- + MC_CMD_OP(cmd, 1, 0, 16, uint16_t, cfg->adv.max_vlans);\
- + MC_CMD_OP(cmd, 1, 16, 16, uint16_t, cfg->adv.max_fdb_entries);\
- + MC_CMD_OP(cmd, 1, 32, 16, uint16_t, cfg->adv.fdb_aging_time);\
- + MC_CMD_OP(cmd, 1, 48, 16, uint16_t, cfg->adv.max_fdb_mc_groups);\
- + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->adv.options);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_IS_ENABLED(cmd, en) \
- + MC_RSP_OP(cmd, 0, 0, 1, int, en)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
- + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
- + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
- + MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_GET_IRQ(cmd, irq_index) \
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_GET_IRQ(cmd, type, irq_cfg) \
- +do { \
- + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \
- + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
- + MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
- + MC_RSP_OP(cmd, 2, 32, 32, int, type); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_SET_IRQ_ENABLE(cmd, irq_index, enable_state) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, enable_state); \
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_GET_IRQ_ENABLE(cmd, enable_state) \
- + MC_RSP_OP(cmd, 0, 0, 8, uint8_t, enable_state)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask); \
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_GET_IRQ_MASK(cmd, irq_index) \
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_GET_IRQ_MASK(cmd, mask) \
- + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_GET_IRQ_STATUS(cmd, status) \
- + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_GET_ATTR(cmd, attr) \
- +do { \
- + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, attr->num_ifs);\
- + MC_RSP_OP(cmd, 0, 16, 8, uint8_t, attr->max_fdbs);\
- + MC_RSP_OP(cmd, 0, 24, 8, uint8_t, attr->num_fdbs);\
- + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->max_vlans);\
- + MC_RSP_OP(cmd, 0, 48, 16, uint16_t, attr->num_vlans);\
- + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\
- + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
- + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, attr->max_fdb_entries);\
- + MC_RSP_OP(cmd, 1, 48, 16, uint16_t, attr->fdb_aging_time);\
- + MC_RSP_OP(cmd, 2, 0, 32, int, attr->id);\
- + MC_RSP_OP(cmd, 2, 32, 16, uint16_t, attr->mem_size);\
- + MC_RSP_OP(cmd, 2, 48, 16, uint16_t, attr->max_fdb_mc_groups);\
- + MC_RSP_OP(cmd, 3, 0, 64, uint64_t, attr->options);\
- + MC_RSP_OP(cmd, 4, 0, 8, uint8_t, attr->max_meters_per_if);\
- + MC_RSP_OP(cmd, 4, 8, 4, enum dpsw_component_type, \
- + attr->component_type);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_SET_REFLECTION_IF(cmd, if_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 1, int, en);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_BROADCAST(cmd, if_id, en) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 1, int, en);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_MULTICAST(cmd, if_id, en) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 1, int, en);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_TCI(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 12, uint16_t, cfg->vlan_id);\
- + MC_CMD_OP(cmd, 0, 28, 1, uint8_t, cfg->dei);\
- + MC_CMD_OP(cmd, 0, 29, 3, uint8_t, cfg->pcp);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_GET_TCI(cmd, if_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_IF_GET_TCI(cmd, cfg) \
- +do { \
- + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
- + MC_RSP_OP(cmd, 0, 32, 8, uint8_t, cfg->dei);\
- + MC_RSP_OP(cmd, 0, 40, 8, uint8_t, cfg->pcp);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_STP(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
- + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_stp_state, cfg->state);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_ACCEPTED_FRAMES(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 4, enum dpsw_accepted_frames, cfg->type);\
- + MC_CMD_OP(cmd, 0, 20, 4, enum dpsw_action, cfg->unaccept_act);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_ACCEPT_ALL_VLAN(cmd, if_id, accept_all) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 1, int, accept_all);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_GET_COUNTER(cmd, if_id, type) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 5, enum dpsw_counter, type);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_IF_GET_COUNTER(cmd, counter) \
- + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, counter)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_COUNTER(cmd, if_id, type, counter) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 5, enum dpsw_counter, type);\
- + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, counter);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_TX_SELECTION(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 3, enum dpsw_priority_selector, \
- + cfg->priority_selector);\
- + MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->tc_id[0]);\
- + MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->tc_id[1]);\
- + MC_CMD_OP(cmd, 1, 16, 8, uint8_t, cfg->tc_id[2]);\
- + MC_CMD_OP(cmd, 1, 24, 8, uint8_t, cfg->tc_id[3]);\
- + MC_CMD_OP(cmd, 1, 32, 8, uint8_t, cfg->tc_id[4]);\
- + MC_CMD_OP(cmd, 1, 40, 8, uint8_t, cfg->tc_id[5]);\
- + MC_CMD_OP(cmd, 1, 48, 8, uint8_t, cfg->tc_id[6]);\
- + MC_CMD_OP(cmd, 1, 56, 8, uint8_t, cfg->tc_id[7]);\
- + MC_CMD_OP(cmd, 2, 0, 16, uint16_t, cfg->tc_sched[0].delta_bandwidth);\
- + MC_CMD_OP(cmd, 2, 16, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[0].mode);\
- + MC_CMD_OP(cmd, 2, 32, 16, uint16_t, cfg->tc_sched[1].delta_bandwidth);\
- + MC_CMD_OP(cmd, 2, 48, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[1].mode);\
- + MC_CMD_OP(cmd, 3, 0, 16, uint16_t, cfg->tc_sched[2].delta_bandwidth);\
- + MC_CMD_OP(cmd, 3, 16, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[2].mode);\
- + MC_CMD_OP(cmd, 3, 32, 16, uint16_t, cfg->tc_sched[3].delta_bandwidth);\
- + MC_CMD_OP(cmd, 3, 48, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[3].mode);\
- + MC_CMD_OP(cmd, 4, 0, 16, uint16_t, cfg->tc_sched[4].delta_bandwidth);\
- + MC_CMD_OP(cmd, 4, 16, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[4].mode);\
- + MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->tc_sched[5].delta_bandwidth);\
- + MC_CMD_OP(cmd, 4, 48, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[5].mode);\
- + MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->tc_sched[6].delta_bandwidth);\
- + MC_CMD_OP(cmd, 5, 16, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[6].mode);\
- + MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->tc_sched[7].delta_bandwidth);\
- + MC_CMD_OP(cmd, 5, 48, 4, enum dpsw_schedule_mode, \
- + cfg->tc_sched[7].mode);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_ADD_REFLECTION(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
- + MC_CMD_OP(cmd, 0, 32, 2, enum dpsw_reflection_filter, cfg->filter);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_REMOVE_REFLECTION(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
- + MC_CMD_OP(cmd, 0, 32, 2, enum dpsw_reflection_filter, cfg->filter);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_FLOODING_METERING(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 24, 4, enum dpsw_metering_mode, cfg->mode);\
- + MC_CMD_OP(cmd, 0, 28, 4, enum dpsw_metering_unit, cfg->units);\
- + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, cfg->cir);\
- + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->eir);\
- + MC_CMD_OP(cmd, 1, 32, 32, uint32_t, cfg->cbs);\
- + MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->ebs);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_METERING(cmd, if_id, tc_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id);\
- + MC_CMD_OP(cmd, 0, 24, 4, enum dpsw_metering_mode, cfg->mode);\
- + MC_CMD_OP(cmd, 0, 28, 4, enum dpsw_metering_unit, cfg->units);\
- + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, cfg->cir);\
- + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->eir);\
- + MC_CMD_OP(cmd, 1, 32, 32, uint32_t, cfg->cbs);\
- + MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->ebs);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_PREP_EARLY_DROP(ext, cfg) \
- +do { \
- + MC_PREP_OP(ext, 0, 0, 2, enum dpsw_early_drop_mode, cfg->drop_mode); \
- + MC_PREP_OP(ext, 0, 2, 2, \
- + enum dpsw_early_drop_unit, cfg->units); \
- + MC_PREP_OP(ext, 0, 32, 32, uint32_t, cfg->tail_drop_threshold); \
- + MC_PREP_OP(ext, 1, 0, 8, uint8_t, cfg->green.drop_probability); \
- + MC_PREP_OP(ext, 2, 0, 64, uint64_t, cfg->green.max_threshold); \
- + MC_PREP_OP(ext, 3, 0, 64, uint64_t, cfg->green.min_threshold); \
- + MC_PREP_OP(ext, 5, 0, 8, uint8_t, cfg->yellow.drop_probability);\
- + MC_PREP_OP(ext, 6, 0, 64, uint64_t, cfg->yellow.max_threshold); \
- + MC_PREP_OP(ext, 7, 0, 64, uint64_t, cfg->yellow.min_threshold); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_EXT_EARLY_DROP(ext, cfg) \
- +do { \
- + MC_EXT_OP(ext, 0, 0, 2, enum dpsw_early_drop_mode, cfg->drop_mode); \
- + MC_EXT_OP(ext, 0, 2, 2, \
- + enum dpsw_early_drop_unit, cfg->units); \
- + MC_EXT_OP(ext, 0, 32, 32, uint32_t, cfg->tail_drop_threshold); \
- + MC_EXT_OP(ext, 1, 0, 8, uint8_t, cfg->green.drop_probability); \
- + MC_EXT_OP(ext, 2, 0, 64, uint64_t, cfg->green.max_threshold); \
- + MC_EXT_OP(ext, 3, 0, 64, uint64_t, cfg->green.min_threshold); \
- + MC_EXT_OP(ext, 5, 0, 8, uint8_t, cfg->yellow.drop_probability);\
- + MC_EXT_OP(ext, 6, 0, 64, uint64_t, cfg->yellow.max_threshold); \
- + MC_EXT_OP(ext, 7, 0, 64, uint64_t, cfg->yellow.min_threshold); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_EARLY_DROP(cmd, if_id, tc_id, early_drop_iova) \
- +do { \
- + MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc_id); \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, if_id); \
- + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, early_drop_iova); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ADD_CUSTOM_TPID(cmd, cfg) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->tpid)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_REMOVE_CUSTOM_TPID(cmd, cfg) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->tpid)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_ENABLE(cmd, if_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_DISABLE(cmd, if_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_GET_ATTR(cmd, if_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_IF_GET_ATTR(cmd, attr) \
- +do { \
- + MC_RSP_OP(cmd, 0, 0, 4, enum dpsw_accepted_frames, \
- + attr->admit_untagged);\
- + MC_RSP_OP(cmd, 0, 5, 1, int, attr->enabled);\
- + MC_RSP_OP(cmd, 0, 6, 1, int, attr->accept_all_vlan);\
- + MC_RSP_OP(cmd, 0, 16, 8, uint8_t, attr->num_tcs);\
- + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qdid);\
- + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options);\
- + MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->rate);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_MAX_FRAME_LENGTH(cmd, if_id, frame_length) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, frame_length);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_GET_MAX_FRAME_LENGTH(cmd, if_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_IF_GET_MAX_FRAME_LENGTH(cmd, frame_length) \
- + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, frame_length)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_SET_LINK_CFG(cmd, if_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
- + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->rate);\
- + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_IF_GET_LINK_STATE(cmd, if_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_IF_GET_LINK_STATE(cmd, state) \
- +do { \
- + MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
- + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
- + MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_ADD(cmd, vlan_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_ADD_IF(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_ADD_IF_UNTAGGED(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_ADD_IF_FLOODING(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
- +
- +#define DPSW_CMD_VLAN_REMOVE_IF(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_REMOVE_IF_UNTAGGED(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_REMOVE_IF_FLOODING(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_REMOVE(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_GET_ATTR(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_VLAN_GET_ATTR(cmd, attr) \
- +do { \
- + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->fdb_id); \
- + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->num_ifs); \
- + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, attr->num_untagged_ifs); \
- + MC_RSP_OP(cmd, 1, 48, 16, uint16_t, attr->num_flooding_ifs); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_GET_IF(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_VLAN_GET_IF(cmd, cfg) \
- + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_GET_IF_FLOODING(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_VLAN_GET_IF_FLOODING(cmd, cfg) \
- + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_VLAN_GET_IF_UNTAGGED(cmd, vlan_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_VLAN_GET_IF_UNTAGGED(cmd, cfg) \
- + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs)
- +
- +/* param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_ADD(cmd, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 32, 16, uint16_t, cfg->fdb_aging_time);\
- + MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->num_fdb_entries);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_FDB_ADD(cmd, fdb_id) \
- + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, fdb_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_REMOVE(cmd, fdb_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_ADD_UNICAST(cmd, fdb_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
- + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
- + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
- + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
- + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
- + MC_CMD_OP(cmd, 1, 0, 8, uint16_t, cfg->if_egress);\
- + MC_CMD_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_GET_UNICAST(cmd, fdb_id) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
- + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
- + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
- + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
- + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_FDB_GET_UNICAST(cmd, cfg) \
- +do { \
- + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, cfg->if_egress);\
- + MC_RSP_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_REMOVE_UNICAST(cmd, fdb_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
- + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
- + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
- + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
- + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
- + MC_CMD_OP(cmd, 1, 0, 16, uint16_t, cfg->if_egress);\
- + MC_CMD_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_ADD_MULTICAST(cmd, fdb_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs);\
- + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_fdb_entry_type, cfg->type);\
- + MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->mac_addr[5]);\
- + MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->mac_addr[4]);\
- + MC_CMD_OP(cmd, 1, 16, 8, uint8_t, cfg->mac_addr[3]);\
- + MC_CMD_OP(cmd, 1, 24, 8, uint8_t, cfg->mac_addr[2]);\
- + MC_CMD_OP(cmd, 1, 32, 8, uint8_t, cfg->mac_addr[1]);\
- + MC_CMD_OP(cmd, 1, 40, 8, uint8_t, cfg->mac_addr[0]);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_GET_MULTICAST(cmd, fdb_id) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
- + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
- + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
- + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
- + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
- + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_FDB_GET_MULTICAST(cmd, cfg) \
- +do { \
- + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, cfg->num_ifs);\
- + MC_RSP_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_REMOVE_MULTICAST(cmd, fdb_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs);\
- + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_fdb_entry_type, cfg->type);\
- + MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->mac_addr[5]);\
- + MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->mac_addr[4]);\
- + MC_CMD_OP(cmd, 1, 16, 8, uint8_t, cfg->mac_addr[3]);\
- + MC_CMD_OP(cmd, 1, 24, 8, uint8_t, cfg->mac_addr[2]);\
- + MC_CMD_OP(cmd, 1, 32, 8, uint8_t, cfg->mac_addr[1]);\
- + MC_CMD_OP(cmd, 1, 40, 8, uint8_t, cfg->mac_addr[0]);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_SET_LEARNING_MODE(cmd, fdb_id, mode) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
- + MC_CMD_OP(cmd, 0, 16, 4, enum dpsw_fdb_learning_mode, mode);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_FDB_GET_ATTR(cmd, fdb_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_FDB_GET_ATTR(cmd, attr) \
- +do { \
- + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->max_fdb_entries);\
- + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->fdb_aging_time);\
- + MC_RSP_OP(cmd, 0, 48, 16, uint16_t, attr->num_fdb_mc_groups);\
- + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->max_fdb_mc_groups);\
- + MC_RSP_OP(cmd, 1, 16, 4, enum dpsw_fdb_learning_mode, \
- + attr->learning_mode);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ACL_ADD(cmd, cfg) \
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->max_entries)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_ACL_ADD(cmd, acl_id) \
- + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, acl_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ACL_REMOVE(cmd, acl_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_PREP_ACL_ENTRY(ext, key) \
- +do { \
- + MC_PREP_OP(ext, 0, 0, 8, uint8_t, key->match.l2_dest_mac[5]);\
- + MC_PREP_OP(ext, 0, 8, 8, uint8_t, key->match.l2_dest_mac[4]);\
- + MC_PREP_OP(ext, 0, 16, 8, uint8_t, key->match.l2_dest_mac[3]);\
- + MC_PREP_OP(ext, 0, 24, 8, uint8_t, key->match.l2_dest_mac[2]);\
- + MC_PREP_OP(ext, 0, 32, 8, uint8_t, key->match.l2_dest_mac[1]);\
- + MC_PREP_OP(ext, 0, 40, 8, uint8_t, key->match.l2_dest_mac[0]);\
- + MC_PREP_OP(ext, 0, 48, 16, uint16_t, key->match.l2_tpid);\
- + MC_PREP_OP(ext, 1, 0, 8, uint8_t, key->match.l2_source_mac[5]);\
- + MC_PREP_OP(ext, 1, 8, 8, uint8_t, key->match.l2_source_mac[4]);\
- + MC_PREP_OP(ext, 1, 16, 8, uint8_t, key->match.l2_source_mac[3]);\
- + MC_PREP_OP(ext, 1, 24, 8, uint8_t, key->match.l2_source_mac[2]);\
- + MC_PREP_OP(ext, 1, 32, 8, uint8_t, key->match.l2_source_mac[1]);\
- + MC_PREP_OP(ext, 1, 40, 8, uint8_t, key->match.l2_source_mac[0]);\
- + MC_PREP_OP(ext, 1, 48, 16, uint16_t, key->match.l2_vlan_id);\
- + MC_PREP_OP(ext, 2, 0, 32, uint32_t, key->match.l3_dest_ip);\
- + MC_PREP_OP(ext, 2, 32, 32, uint32_t, key->match.l3_source_ip);\
- + MC_PREP_OP(ext, 3, 0, 16, uint16_t, key->match.l4_dest_port);\
- + MC_PREP_OP(ext, 3, 16, 16, uint16_t, key->match.l4_source_port);\
- + MC_PREP_OP(ext, 3, 32, 16, uint16_t, key->match.l2_ether_type);\
- + MC_PREP_OP(ext, 3, 48, 8, uint8_t, key->match.l2_pcp_dei);\
- + MC_PREP_OP(ext, 3, 56, 8, uint8_t, key->match.l3_dscp);\
- + MC_PREP_OP(ext, 4, 0, 8, uint8_t, key->mask.l2_dest_mac[5]);\
- + MC_PREP_OP(ext, 4, 8, 8, uint8_t, key->mask.l2_dest_mac[4]);\
- + MC_PREP_OP(ext, 4, 16, 8, uint8_t, key->mask.l2_dest_mac[3]);\
- + MC_PREP_OP(ext, 4, 24, 8, uint8_t, key->mask.l2_dest_mac[2]);\
- + MC_PREP_OP(ext, 4, 32, 8, uint8_t, key->mask.l2_dest_mac[1]);\
- + MC_PREP_OP(ext, 4, 40, 8, uint8_t, key->mask.l2_dest_mac[0]);\
- + MC_PREP_OP(ext, 4, 48, 16, uint16_t, key->mask.l2_tpid);\
- + MC_PREP_OP(ext, 5, 0, 8, uint8_t, key->mask.l2_source_mac[5]);\
- + MC_PREP_OP(ext, 5, 8, 8, uint8_t, key->mask.l2_source_mac[4]);\
- + MC_PREP_OP(ext, 5, 16, 8, uint8_t, key->mask.l2_source_mac[3]);\
- + MC_PREP_OP(ext, 5, 24, 8, uint8_t, key->mask.l2_source_mac[2]);\
- + MC_PREP_OP(ext, 5, 32, 8, uint8_t, key->mask.l2_source_mac[1]);\
- + MC_PREP_OP(ext, 5, 40, 8, uint8_t, key->mask.l2_source_mac[0]);\
- + MC_PREP_OP(ext, 5, 48, 16, uint16_t, key->mask.l2_vlan_id);\
- + MC_PREP_OP(ext, 6, 0, 32, uint32_t, key->mask.l3_dest_ip);\
- + MC_PREP_OP(ext, 6, 32, 32, uint32_t, key->mask.l3_source_ip);\
- + MC_PREP_OP(ext, 7, 0, 16, uint16_t, key->mask.l4_dest_port);\
- + MC_PREP_OP(ext, 7, 16, 16, uint16_t, key->mask.l4_source_port);\
- + MC_PREP_OP(ext, 7, 32, 16, uint16_t, key->mask.l2_ether_type);\
- + MC_PREP_OP(ext, 7, 48, 8, uint8_t, key->mask.l2_pcp_dei);\
- + MC_PREP_OP(ext, 7, 56, 8, uint8_t, key->mask.l3_dscp);\
- + MC_PREP_OP(ext, 8, 0, 8, uint8_t, key->match.l3_protocol);\
- + MC_PREP_OP(ext, 8, 8, 8, uint8_t, key->mask.l3_protocol);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_EXT_ACL_ENTRY(ext, key) \
- +do { \
- + MC_EXT_OP(ext, 0, 0, 8, uint8_t, key->match.l2_dest_mac[5]);\
- + MC_EXT_OP(ext, 0, 8, 8, uint8_t, key->match.l2_dest_mac[4]);\
- + MC_EXT_OP(ext, 0, 16, 8, uint8_t, key->match.l2_dest_mac[3]);\
- + MC_EXT_OP(ext, 0, 24, 8, uint8_t, key->match.l2_dest_mac[2]);\
- + MC_EXT_OP(ext, 0, 32, 8, uint8_t, key->match.l2_dest_mac[1]);\
- + MC_EXT_OP(ext, 0, 40, 8, uint8_t, key->match.l2_dest_mac[0]);\
- + MC_EXT_OP(ext, 0, 48, 16, uint16_t, key->match.l2_tpid);\
- + MC_EXT_OP(ext, 1, 0, 8, uint8_t, key->match.l2_source_mac[5]);\
- + MC_EXT_OP(ext, 1, 8, 8, uint8_t, key->match.l2_source_mac[4]);\
- + MC_EXT_OP(ext, 1, 16, 8, uint8_t, key->match.l2_source_mac[3]);\
- + MC_EXT_OP(ext, 1, 24, 8, uint8_t, key->match.l2_source_mac[2]);\
- + MC_EXT_OP(ext, 1, 32, 8, uint8_t, key->match.l2_source_mac[1]);\
- + MC_EXT_OP(ext, 1, 40, 8, uint8_t, key->match.l2_source_mac[0]);\
- + MC_EXT_OP(ext, 1, 48, 16, uint16_t, key->match.l2_vlan_id);\
- + MC_EXT_OP(ext, 2, 0, 32, uint32_t, key->match.l3_dest_ip);\
- + MC_EXT_OP(ext, 2, 32, 32, uint32_t, key->match.l3_source_ip);\
- + MC_EXT_OP(ext, 3, 0, 16, uint16_t, key->match.l4_dest_port);\
- + MC_EXT_OP(ext, 3, 16, 16, uint16_t, key->match.l4_source_port);\
- + MC_EXT_OP(ext, 3, 32, 16, uint16_t, key->match.l2_ether_type);\
- + MC_EXT_OP(ext, 3, 48, 8, uint8_t, key->match.l2_pcp_dei);\
- + MC_EXT_OP(ext, 3, 56, 8, uint8_t, key->match.l3_dscp);\
- + MC_EXT_OP(ext, 4, 0, 8, uint8_t, key->mask.l2_dest_mac[5]);\
- + MC_EXT_OP(ext, 4, 8, 8, uint8_t, key->mask.l2_dest_mac[4]);\
- + MC_EXT_OP(ext, 4, 16, 8, uint8_t, key->mask.l2_dest_mac[3]);\
- + MC_EXT_OP(ext, 4, 24, 8, uint8_t, key->mask.l2_dest_mac[2]);\
- + MC_EXT_OP(ext, 4, 32, 8, uint8_t, key->mask.l2_dest_mac[1]);\
- + MC_EXT_OP(ext, 4, 40, 8, uint8_t, key->mask.l2_dest_mac[0]);\
- + MC_EXT_OP(ext, 4, 48, 16, uint16_t, key->mask.l2_tpid);\
- + MC_EXT_OP(ext, 5, 0, 8, uint8_t, key->mask.l2_source_mac[5]);\
- + MC_EXT_OP(ext, 5, 8, 8, uint8_t, key->mask.l2_source_mac[4]);\
- + MC_EXT_OP(ext, 5, 16, 8, uint8_t, key->mask.l2_source_mac[3]);\
- + MC_EXT_OP(ext, 5, 24, 8, uint8_t, key->mask.l2_source_mac[2]);\
- + MC_EXT_OP(ext, 5, 32, 8, uint8_t, key->mask.l2_source_mac[1]);\
- + MC_EXT_OP(ext, 5, 40, 8, uint8_t, key->mask.l2_source_mac[0]);\
- + MC_EXT_OP(ext, 5, 48, 16, uint16_t, key->mask.l2_vlan_id);\
- + MC_EXT_OP(ext, 6, 0, 32, uint32_t, key->mask.l3_dest_ip);\
- + MC_EXT_OP(ext, 6, 32, 32, uint32_t, key->mask.l3_source_ip);\
- + MC_EXT_OP(ext, 7, 0, 16, uint16_t, key->mask.l4_dest_port);\
- + MC_EXT_OP(ext, 7, 16, 16, uint16_t, key->mask.l4_source_port);\
- + MC_EXT_OP(ext, 7, 32, 16, uint16_t, key->mask.l2_ether_type);\
- + MC_EXT_OP(ext, 7, 48, 8, uint8_t, key->mask.l2_pcp_dei);\
- + MC_EXT_OP(ext, 7, 56, 8, uint8_t, key->mask.l3_dscp);\
- + MC_EXT_OP(ext, 8, 0, 8, uint8_t, key->match.l3_protocol);\
- + MC_EXT_OP(ext, 8, 8, 8, uint8_t, key->mask.l3_protocol);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ACL_ADD_ENTRY(cmd, acl_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->result.if_id);\
- + MC_CMD_OP(cmd, 0, 32, 32, int, cfg->precedence);\
- + MC_CMD_OP(cmd, 1, 0, 4, enum dpsw_acl_action, cfg->result.action);\
- + MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_iova); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ACL_REMOVE_ENTRY(cmd, acl_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->result.if_id);\
- + MC_CMD_OP(cmd, 0, 32, 32, int, cfg->precedence);\
- + MC_CMD_OP(cmd, 1, 0, 4, enum dpsw_acl_action, cfg->result.action);\
- + MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_iova); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ACL_ADD_IF(cmd, acl_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ACL_REMOVE_IF(cmd, acl_id, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
- + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs); \
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_ACL_GET_ATTR(cmd, acl_id) \
- + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_ACL_GET_ATTR(cmd, attr) \
- +do { \
- + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->max_entries);\
- + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->num_entries);\
- + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, attr->num_ifs);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_RSP_CTRL_IF_GET_ATTR(cmd, attr) \
- +do { \
- + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->rx_fqid);\
- + MC_RSP_OP(cmd, 1, 32, 32, uint32_t, attr->rx_err_fqid);\
- + MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->tx_err_conf_fqid);\
- +} while (0)
- +
- +/* cmd, param, offset, width, type, arg_name */
- +#define DPSW_CMD_CTRL_IF_SET_POOLS(cmd, cfg) \
- +do { \
- + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
- + MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
- + MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
- + MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
- + MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
- + MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
- + MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
- + MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
- + MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
- + MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
- + MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
- + MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
- + MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
- + MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
- + MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
- + MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
- + MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
- + MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
- + MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
- + MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
- + MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
- + MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
- + MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
- + MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
- + MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
- +} while (0)
- +
- +#endif /* __FSL_DPSW_CMD_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c
- @@ -0,0 +1,1639 @@
- +/* 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.
- + */
- +#include "../../fsl-mc/include/mc-sys.h"
- +#include "../../fsl-mc/include/mc-cmd.h"
- +#include "dpsw.h"
- +#include "dpsw-cmd.h"
- +
- +/* internal functions */
- +static void build_if_id_bitmap(const uint16_t *if_id,
- + const uint16_t num_ifs,
- + struct mc_command *cmd,
- + int start_param)
- +{
- + int i;
- +
- + for (i = 0; (i < num_ifs) && (i < DPSW_MAX_IF); i++)
- + cmd->params[start_param + (if_id[i] / 64)] |= mc_enc(
- + (if_id[i] % 64), 1, 1);
- +}
- +
- +static int read_if_id_bitmap(uint16_t *if_id,
- + uint16_t *num_ifs,
- + struct mc_command *cmd,
- + int start_param)
- +{
- + int bitmap[DPSW_MAX_IF] = { 0 };
- + int i, j = 0;
- + int count = 0;
- +
- + for (i = 0; i < DPSW_MAX_IF; i++) {
- + bitmap[i] = (int)mc_dec(cmd->params[start_param + i / 64],
- + i % 64, 1);
- + count += bitmap[i];
- + }
- +
- + *num_ifs = (uint16_t)count;
- +
- + for (i = 0; (i < DPSW_MAX_IF) && (j < count); i++) {
- + if (bitmap[i]) {
- + if_id[j] = (uint16_t)i;
- + j++;
- + }
- + }
- +
- + return 0;
- +}
- +
- +/* DPSW APIs */
- +int dpsw_open(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + int dpsw_id,
- + uint16_t *token)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN,
- + cmd_flags,
- + 0);
- + DPSW_CMD_OPEN(cmd, dpsw_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.header);
- +
- + return 0;
- +}
- +
- +int dpsw_close(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_create(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + const struct dpsw_cfg *cfg,
- + uint16_t *token)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CREATE,
- + cmd_flags,
- + 0);
- + DPSW_CMD_CREATE(cmd, cfg);
- +
- + /* 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.header);
- +
- + return 0;
- +}
- +
- +int dpsw_destroy(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_DESTROY,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_disable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_is_enabled(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + int *en)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IS_ENABLED, cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_IS_ENABLED(cmd, *en);
- +
- + return 0;
- +}
- +
- +int dpsw_reset(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_set_irq(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + struct dpsw_irq_cfg *irq_cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ,
- + cmd_flags,
- + token);
- + DPSW_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_get_irq(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + int *type,
- + struct dpsw_irq_cfg *irq_cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ,
- + cmd_flags,
- + token);
- + DPSW_CMD_GET_IRQ(cmd, irq_index);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_GET_IRQ(cmd, *type, irq_cfg);
- +
- + return 0;
- +}
- +
- +int dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint8_t en)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE,
- + cmd_flags,
- + token);
- + DPSW_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_get_irq_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint8_t *en)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_ENABLE,
- + cmd_flags,
- + token);
- + DPSW_CMD_GET_IRQ_ENABLE(cmd, irq_index);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_GET_IRQ_ENABLE(cmd, *en);
- +
- + return 0;
- +}
- +
- +int dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t mask)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK,
- + cmd_flags,
- + token);
- + DPSW_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_get_irq_mask(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t *mask)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_MASK,
- + cmd_flags,
- + token);
- + DPSW_CMD_GET_IRQ_MASK(cmd, irq_index);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_GET_IRQ_MASK(cmd, *mask);
- +
- + return 0;
- +}
- +
- +int dpsw_get_irq_status(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t *status)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS,
- + cmd_flags,
- + token);
- + DPSW_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_GET_IRQ_STATUS(cmd, *status);
- +
- + return 0;
- +}
- +
- +int dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t status)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS,
- + cmd_flags,
- + token);
- + DPSW_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + struct dpsw_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_GET_ATTR(cmd, attr);
- +
- + return 0;
- +}
- +
- +int dpsw_set_reflection_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_REFLECTION_IF,
- + cmd_flags,
- + token);
- + DPSW_CMD_SET_REFLECTION_IF(cmd, if_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_link_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LINK_CFG,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_LINK_CFG(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_link_state *state)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_GET_LINK_STATE(cmd, if_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_IF_GET_LINK_STATE(cmd, state);
- +
- + return 0;
- +}
- +
- +int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int en)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_FLOODING,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int en)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_BROADCAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int en)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MULTICAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_tci_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_TCI(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_get_tci(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_tci_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err = 0;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_TCI,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_GET_TCI(cmd, if_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_IF_GET_TCI(cmd, cfg);
- +
- + return 0;
- +}
- +
- +int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_stp_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_STP(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_accepted_frames(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_accepted_frames_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_ACCEPTED_FRAMES,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_ACCEPTED_FRAMES(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_accept_all_vlan(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int accept_all)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IF_ACCEPT_ALL_VLAN,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_ACCEPT_ALL_VLAN(cmd, if_id, accept_all);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + enum dpsw_counter type,
- + uint64_t *counter)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_GET_COUNTER(cmd, if_id, type);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_IF_GET_COUNTER(cmd, *counter);
- +
- + return 0;
- +}
- +
- +int dpsw_if_set_counter(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + enum dpsw_counter type,
- + uint64_t counter)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_COUNTER,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_COUNTER(cmd, if_id, type, counter);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_tx_selection(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_tx_selection_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TX_SELECTION,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_TX_SELECTION(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_add_reflection(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_reflection_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ADD_REFLECTION,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_ADD_REFLECTION(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_remove_reflection(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_reflection_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_REMOVE_REFLECTION,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_REMOVE_REFLECTION(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_flooding_metering(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_metering_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_FLOODING_METERING,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_FLOODING_METERING(cmd, if_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_set_metering(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint8_t tc_id,
- + const struct dpsw_metering_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_METERING,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_METERING(cmd, if_id, tc_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +void dpsw_prepare_early_drop(const struct dpsw_early_drop_cfg *cfg,
- + uint8_t *early_drop_buf)
- +{
- + uint64_t *ext_params = (uint64_t *)early_drop_buf;
- +
- + DPSW_PREP_EARLY_DROP(ext_params, cfg);
- +}
- +
- +int dpsw_if_set_early_drop(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint8_t tc_id,
- + uint64_t early_drop_iova)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_EARLY_DROP,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_EARLY_DROP(cmd, if_id, tc_id, early_drop_iova);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_add_custom_tpid(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + const struct dpsw_custom_tpid_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ADD_CUSTOM_TPID,
- + cmd_flags,
- + token);
- + DPSW_CMD_ADD_CUSTOM_TPID(cmd, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_remove_custom_tpid(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + const struct dpsw_custom_tpid_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_REMOVE_CUSTOM_TPID,
- + cmd_flags,
- + token);
- + DPSW_CMD_REMOVE_CUSTOM_TPID(cmd, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_ENABLE(cmd, if_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_disable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_DISABLE(cmd, if_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_if_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_ATTR,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_GET_ATTR(cmd, if_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_IF_GET_ATTR(cmd, attr);
- +
- + return 0;
- +}
- +
- +int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint16_t frame_length)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_SET_MAX_FRAME_LENGTH(cmd, if_id, frame_length);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_if_get_max_frame_length(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint16_t *frame_length)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_MAX_FRAME_LENGTH,
- + cmd_flags,
- + token);
- + DPSW_CMD_IF_GET_MAX_FRAME_LENGTH(cmd, if_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + DPSW_RSP_IF_GET_MAX_FRAME_LENGTH(cmd, *frame_length);
- +
- + return 0;
- +}
- +
- +int dpsw_vlan_add(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_ADD(cmd, vlan_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_ADD_IF(cmd, vlan_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_ADD_IF_UNTAGGED(cmd, vlan_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_add_if_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_FLOODING,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_ADD_IF_FLOODING(cmd, vlan_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_REMOVE_IF(cmd, vlan_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_REMOVE_IF_UNTAGGED(cmd, vlan_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_remove_if_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_FLOODING,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_REMOVE_IF_FLOODING(cmd, vlan_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_REMOVE(cmd, vlan_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_vlan_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_ATTRIBUTES,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_GET_ATTR(cmd, vlan_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_VLAN_GET_ATTR(cmd, attr);
- +
- + return 0;
- +}
- +
- +int dpsw_vlan_get_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_IF,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_GET_IF(cmd, vlan_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_VLAN_GET_IF(cmd, cfg);
- + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 1);
- +
- + return 0;
- +}
- +
- +int dpsw_vlan_get_if_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_IF_FLOODING,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_GET_IF_FLOODING(cmd, vlan_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_VLAN_GET_IF_FLOODING(cmd, cfg);
- + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 1);
- +
- + return 0;
- +}
- +
- +int dpsw_vlan_get_if_untagged(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_IF_UNTAGGED,
- + cmd_flags,
- + token);
- + DPSW_CMD_VLAN_GET_IF_UNTAGGED(cmd, vlan_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_VLAN_GET_IF(cmd, cfg);
- + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 1);
- +
- + return 0;
- +}
- +
- +int dpsw_fdb_add(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t *fdb_id,
- + const struct dpsw_fdb_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_ADD(cmd, cfg);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_FDB_ADD(cmd, *fdb_id);
- +
- + return 0;
- +}
- +
- +int dpsw_fdb_remove(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_REMOVE(cmd, fdb_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_unicast_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_ADD_UNICAST(cmd, fdb_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_fdb_get_unicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + struct dpsw_fdb_unicast_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_GET_UNICAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_GET_UNICAST(cmd, fdb_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_FDB_GET_UNICAST(cmd, cfg);
- +
- + return 0;
- +}
- +
- +int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_unicast_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_REMOVE_UNICAST(cmd, fdb_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_multicast_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 2);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_ADD_MULTICAST(cmd, fdb_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_fdb_get_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + struct dpsw_fdb_multicast_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_GET_MULTICAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_GET_MULTICAST(cmd, fdb_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_FDB_GET_MULTICAST(cmd, cfg);
- + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 2);
- +
- + return 0;
- +}
- +
- +int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_multicast_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 2);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_REMOVE_MULTICAST(cmd, fdb_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + enum dpsw_fdb_learning_mode mode)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_SET_LEARNING_MODE,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_SET_LEARNING_MODE(cmd, fdb_id, mode);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_fdb_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + struct dpsw_fdb_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_GET_ATTR,
- + cmd_flags,
- + token);
- + DPSW_CMD_FDB_GET_ATTR(cmd, fdb_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_FDB_GET_ATTR(cmd, attr);
- +
- + return 0;
- +}
- +
- +int dpsw_acl_add(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t *acl_id,
- + const struct dpsw_acl_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD,
- + cmd_flags,
- + token);
- + DPSW_CMD_ACL_ADD(cmd, cfg);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_ACL_ADD(cmd, *acl_id);
- +
- + return 0;
- +}
- +
- +int dpsw_acl_remove(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE,
- + cmd_flags,
- + token);
- + DPSW_CMD_ACL_REMOVE(cmd, acl_id);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key,
- + uint8_t *entry_cfg_buf)
- +{
- + uint64_t *ext_params = (uint64_t *)entry_cfg_buf;
- +
- + DPSW_PREP_ACL_ENTRY(ext_params, key);
- +}
- +
- +int dpsw_acl_add_entry(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_entry_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_ENTRY,
- + cmd_flags,
- + token);
- + DPSW_CMD_ACL_ADD_ENTRY(cmd, acl_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_entry_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_ENTRY,
- + cmd_flags,
- + token);
- + DPSW_CMD_ACL_REMOVE_ENTRY(cmd, acl_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_acl_add_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_IF,
- + cmd_flags,
- + token);
- + DPSW_CMD_ACL_ADD_IF(cmd, acl_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_acl_remove_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_if_cfg *cfg)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_IF,
- + cmd_flags,
- + token);
- + DPSW_CMD_ACL_REMOVE_IF(cmd, acl_id, cfg);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_acl_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + struct dpsw_acl_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_GET_ATTR,
- + cmd_flags,
- + token);
- + DPSW_CMD_ACL_GET_ATTR(cmd, acl_id);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_ACL_GET_ATTR(cmd, attr);
- +
- + return 0;
- +}
- +
- +int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + struct dpsw_ctrl_if_attr *attr)
- +{
- + struct mc_command cmd = { 0 };
- + int err;
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_GET_ATTR,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + err = mc_send_command(mc_io, &cmd);
- + if (err)
- + return err;
- +
- + /* retrieve response parameters */
- + DPSW_RSP_CTRL_IF_GET_ATTR(cmd, attr);
- +
- + return 0;
- +}
- +
- +int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + const struct dpsw_ctrl_if_pools_cfg *pools)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_POOLS,
- + cmd_flags,
- + token);
- + DPSW_CMD_CTRL_IF_SET_POOLS(cmd, pools);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +int dpsw_ctrl_if_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_ENABLE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- +
- +/**
- +* @brief Function disables control interface
- +* @mc_io: Pointer to MC portal's I/O object
- +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- +* @token: Token of DPSW object
- +*
- +* Return: '0' on Success; Error code otherwise.
- +*/
- +int dpsw_ctrl_if_disable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token)
- +{
- + struct mc_command cmd = { 0 };
- +
- + /* prepare command */
- + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_DISABLE,
- + cmd_flags,
- + token);
- +
- + /* send command to mc*/
- + return mc_send_command(mc_io, &cmd);
- +}
- --- /dev/null
- +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
- @@ -0,0 +1,2164 @@
- +/* 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_DPSW_H
- +#define __FSL_DPSW_H
- +
- +#include "../../fsl-mc/include/net.h"
- +
- +/* Data Path L2-Switch API
- + * Contains API for handling DPSW topology and functionality
- + */
- +
- +struct fsl_mc_io;
- +
- +/**
- + * DPSW general definitions
- + */
- +
- +/**
- + * Maximum number of traffic class priorities
- + */
- +#define DPSW_MAX_PRIORITIES 8
- +/**
- + * Maximum number of interfaces
- + */
- +#define DPSW_MAX_IF 64
- +
- +/**
- + * dpsw_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_'
- + * @dpsw_id: DPSW 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 dpsw_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 dpsw_open(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + int dpsw_id,
- + uint16_t *token);
- +
- +/**
- + * dpsw_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 DPSW 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 dpsw_close(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token);
- +
- +/**
- + * DPSW options
- + */
- +
- +/**
- + * Disable flooding
- + */
- +#define DPSW_OPT_FLOODING_DIS 0x0000000000000001ULL
- +/**
- + * Disable Multicast
- + */
- +#define DPSW_OPT_MULTICAST_DIS 0x0000000000000004ULL
- +/**
- + * Support control interface
- + */
- +#define DPSW_OPT_CTRL_IF_DIS 0x0000000000000010ULL
- +/**
- + * Disable flooding metering
- + */
- +#define DPSW_OPT_FLOODING_METERING_DIS 0x0000000000000020ULL
- +/**
- + * Enable metering
- + */
- +#define DPSW_OPT_METERING_EN 0x0000000000000040ULL
- +
- +/**
- + * enum dpsw_component_type - component type of a bridge
- + * @DPSW_COMPONENT_TYPE_C_VLAN: A C-VLAN component of an
- + * enterprise VLAN bridge or of a Provider Bridge used
- + * to process C-tagged frames
- + * @DPSW_COMPONENT_TYPE_S_VLAN: An S-VLAN component of a
- + * Provider Bridge
- + *
- + */
- +enum dpsw_component_type {
- + DPSW_COMPONENT_TYPE_C_VLAN = 0,
- + DPSW_COMPONENT_TYPE_S_VLAN
- +};
- +
- +/**
- + * struct dpsw_cfg - DPSW configuration
- + * @num_ifs: Number of external and internal interfaces
- + * @adv: Advanced parameters; default is all zeros;
- + * use this structure to change default settings
- + */
- +struct dpsw_cfg {
- + uint16_t num_ifs;
- + /**
- + * struct adv - Advanced parameters
- + * @options: Enable/Disable DPSW features (bitmap)
- + * @max_vlans: Maximum Number of VLAN's; 0 - indicates default 16
- + * @max_meters_per_if: Number of meters per interface
- + * @max_fdbs: Maximum Number of FDB's; 0 - indicates default 16
- + * @max_fdb_entries: Number of FDB entries for default FDB table;
- + * 0 - indicates default 1024 entries.
- + * @fdb_aging_time: Default FDB aging time for default FDB table;
- + * 0 - indicates default 300 seconds
- + * @max_fdb_mc_groups: Number of multicast groups in each FDB table;
- + * 0 - indicates default 32
- + * @component_type: Indicates the component type of this bridge
- + */
- + struct {
- + uint64_t options;
- + uint16_t max_vlans;
- + uint8_t max_meters_per_if;
- + uint8_t max_fdbs;
- + uint16_t max_fdb_entries;
- + uint16_t fdb_aging_time;
- + uint16_t max_fdb_mc_groups;
- + enum dpsw_component_type component_type;
- + } adv;
- +};
- +
- +/**
- + * dpsw_create() - Create the DPSW 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 DPSW 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 dpsw_open() function to get an authentication
- + * token first
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_create(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + const struct dpsw_cfg *cfg,
- + uint16_t *token);
- +
- +/**
- + * dpsw_destroy() - Destroy the DPSW 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 DPSW object
- + *
- + * Return: '0' on Success; error code otherwise.
- + */
- +int dpsw_destroy(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token);
- +
- +/**
- + * dpsw_enable() - Enable DPSW functionality
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token);
- +
- +/**
- + * dpsw_disable() - Disable DPSW functionality
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_disable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token);
- +
- +/**
- + * dpsw_is_enabled() - Check if the DPSW 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 DPSW object
- + * @en: Returns '1' if object is enabled; '0' otherwise
- + *
- + * Return: '0' on Success; Error code otherwise
- + */
- +int dpsw_is_enabled(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + int *en);
- +
- +/**
- + * dpsw_reset() - Reset the DPSW, 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 DPSW object
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_reset(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token);
- +
- +/**
- + * DPSW IRQ Index and Events
- + */
- +
- +#define DPSW_IRQ_INDEX_IF 0x0000
- +#define DPSW_IRQ_INDEX_L2SW 0x0001
- +
- +/**
- + * IRQ event - Indicates that the link state changed
- + */
- +#define DPSW_IRQ_EVENT_LINK_CHANGED 0x0001
- +
- +/**
- + * struct dpsw_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 dpsw_irq_cfg {
- + uint64_t addr;
- + uint32_t val;
- + int irq_num;
- +};
- +
- +/**
- + * dpsw_set_irq() - Set IRQ information for the DPSW 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 DPSW object
- + * @irq_index: Identifies the interrupt index to configure
- + * @irq_cfg: IRQ configuration
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_set_irq(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + struct dpsw_irq_cfg *irq_cfg);
- +
- +/**
- + * dpsw_get_irq() - Get IRQ information from the DPSW
- + *
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW 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 dpsw_get_irq(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + int *type,
- + struct dpsw_irq_cfg *irq_cfg);
- +
- +/**
- + * dpsw_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 DPCI 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 dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint8_t en);
- +
- +/**
- + * dpsw_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 DPSW object
- + * @irq_index: The interrupt index to configure
- + * @en: Returned Interrupt state - enable = 1, disable = 0
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_get_irq_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint8_t *en);
- +
- +/**
- + * dpsw_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 DPCI 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 dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t mask);
- +
- +/**
- + * dpsw_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 DPSW 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 dpsw_get_irq_mask(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t *mask);
- +
- +/**
- + * dpsw_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 DPSW 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 dpsw_get_irq_status(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t *status);
- +
- +/**
- + * dpsw_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 DPCI 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 dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint8_t irq_index,
- + uint32_t status);
- +/**
- + * struct dpsw_attr - Structure representing DPSW attributes
- + * @id: DPSW object ID
- + * @version: DPSW version
- + * @options: Enable/Disable DPSW features
- + * @max_vlans: Maximum Number of VLANs
- + * @max_meters_per_if: Number of meters per interface
- + * @max_fdbs: Maximum Number of FDBs
- + * @max_fdb_entries: Number of FDB entries for default FDB table;
- + * 0 - indicates default 1024 entries.
- + * @fdb_aging_time: Default FDB aging time for default FDB table;
- + * 0 - indicates default 300 seconds
- + * @max_fdb_mc_groups: Number of multicast groups in each FDB table;
- + * 0 - indicates default 32
- + * @mem_size: DPSW frame storage memory size
- + * @num_ifs: Number of interfaces
- + * @num_vlans: Current number of VLANs
- + * @num_fdbs: Current number of FDBs
- + * @component_type: Component type of this bridge
- + */
- +struct dpsw_attr {
- + int id;
- + /**
- + * struct version - DPSW version
- + * @major: DPSW major version
- + * @minor: DPSW minor version
- + */
- + struct {
- + uint16_t major;
- + uint16_t minor;
- + } version;
- + uint64_t options;
- + uint16_t max_vlans;
- + uint8_t max_meters_per_if;
- + uint8_t max_fdbs;
- + uint16_t max_fdb_entries;
- + uint16_t fdb_aging_time;
- + uint16_t max_fdb_mc_groups;
- + uint16_t num_ifs;
- + uint16_t mem_size;
- + uint16_t num_vlans;
- + uint8_t num_fdbs;
- + enum dpsw_component_type component_type;
- +};
- +
- +/**
- + * dpsw_get_attributes() - Retrieve DPSW 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 DPSW object
- + * @attr: Returned DPSW attributes
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + struct dpsw_attr *attr);
- +
- +/**
- + * dpsw_set_reflection_if() - Set target interface for reflected interfaces.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Id
- + *
- + * Only one reflection receive interface is allowed per switch
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_set_reflection_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id);
- +
- +/**
- + * enum dpsw_action - Action selection for special/control frames
- + * @DPSW_ACTION_DROP: Drop frame
- + * @DPSW_ACTION_REDIRECT: Redirect frame to control port
- + */
- +enum dpsw_action {
- + DPSW_ACTION_DROP = 0,
- + DPSW_ACTION_REDIRECT = 1
- +};
- +
- +/**
- + * Enable auto-negotiation
- + */
- +#define DPSW_LINK_OPT_AUTONEG 0x0000000000000001ULL
- +/**
- + * Enable half-duplex mode
- + */
- +#define DPSW_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
- +/**
- + * Enable pause frames
- + */
- +#define DPSW_LINK_OPT_PAUSE 0x0000000000000004ULL
- +/**
- + * Enable a-symmetric pause frames
- + */
- +#define DPSW_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
- +
- +/**
- + * struct dpsw_link_cfg - Structure representing DPSW link configuration
- + * @rate: Rate
- + * @options: Mask of available options; use 'DPSW_LINK_OPT_<X>' values
- + */
- +struct dpsw_link_cfg {
- + uint32_t rate;
- + uint64_t options;
- +};
- +
- +/**
- + * dpsw_if_set_link_cfg() - set the link 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 DPSW object
- + * @if_id: interface id
- + * @cfg: Link configuration
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_link_cfg *cfg);
- +/**
- + * struct dpsw_link_state - Structure representing DPSW link state
- + * @rate: Rate
- + * @options: Mask of available options; use 'DPSW_LINK_OPT_<X>' values
- + * @up: 0 - covers two cases: down and disconnected, 1 - up
- + */
- +struct dpsw_link_state {
- + uint32_t rate;
- + uint64_t options;
- + int up;
- +};
- +
- +/**
- + * dpsw_if_get_link_state - Return the link 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 DPSW object
- + * @if_id: interface id
- + * @state: link state 1 - linkup, 0 - link down or disconnected
- + *
- + * @returns '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_link_state *state);
- +
- +/**
- + * dpsw_if_set_flooding() - Enable Disable flooding for particular interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @en: 1 - enable, 0 - disable
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int en);
- +
- +/**
- + * dpsw_if_set_broadcast() - Enable/disable broadcast for particular interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @en: 1 - enable, 0 - disable
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int en);
- +
- +/**
- + * dpsw_if_set_multicast() - Enable/disable multicast for particular interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @en: 1 - enable, 0 - disable
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int en);
- +
- +/**
- + * struct dpsw_tci_cfg - Tag Contorl Information (TCI) configuration
- + * @pcp: Priority Code Point (PCP): a 3-bit field which refers
- + * to the IEEE 802.1p priority
- + * @dei: Drop Eligible Indicator (DEI): a 1-bit field. May be used
- + * separately or in conjunction with PCP to indicate frames
- + * eligible to be dropped in the presence of congestion
- + * @vlan_id: VLAN Identifier (VID): a 12-bit field specifying the VLAN
- + * to which the frame belongs. The hexadecimal values
- + * of 0x000 and 0xFFF are reserved;
- + * all other values may be used as VLAN identifiers,
- + * allowing up to 4,094 VLANs
- + */
- +struct dpsw_tci_cfg {
- + uint8_t pcp;
- + uint8_t dei;
- + uint16_t vlan_id;
- +};
- +
- +/**
- + * dpsw_if_set_tci() - Set default VLAN Tag Control Information (TCI)
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: Tag Control Information Configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_tci_cfg *cfg);
- +
- +/**
- + * dpsw_if_get_tci() - Get default VLAN Tag Control Information (TCI)
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: Tag Control Information Configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_get_tci(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_tci_cfg *cfg);
- +
- +/**
- + * enum dpsw_stp_state - Spanning Tree Protocol (STP) states
- + * @DPSW_STP_STATE_BLOCKING: Blocking state
- + * @DPSW_STP_STATE_LISTENING: Listening state
- + * @DPSW_STP_STATE_LEARNING: Learning state
- + * @DPSW_STP_STATE_FORWARDING: Forwarding state
- + *
- + */
- +enum dpsw_stp_state {
- + DPSW_STP_STATE_BLOCKING = 0,
- + DPSW_STP_STATE_LISTENING = 1,
- + DPSW_STP_STATE_LEARNING = 2,
- + DPSW_STP_STATE_FORWARDING = 3
- +};
- +
- +/**
- + * struct dpsw_stp_cfg - Spanning Tree Protocol (STP) Configuration
- + * @vlan_id: VLAN ID STP state
- + * @state: STP state
- + */
- +struct dpsw_stp_cfg {
- + uint16_t vlan_id;
- + enum dpsw_stp_state state;
- +};
- +
- +/**
- + * dpsw_if_set_stp() - Function sets Spanning Tree Protocol (STP) 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 DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: STP State configuration parameters
- + *
- + * The following STP states are supported -
- + * blocking, listening, learning, forwarding and disabled.
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_stp_cfg *cfg);
- +
- +/**
- + * enum dpsw_accepted_frames - Types of frames to accept
- + * @DPSW_ADMIT_ALL: The device accepts VLAN tagged, untagged and
- + * priority tagged frames
- + * @DPSW_ADMIT_ONLY_VLAN_TAGGED: The device discards untagged frames or
- + * Priority-Tagged frames received on this interface.
- + *
- + */
- +enum dpsw_accepted_frames {
- + DPSW_ADMIT_ALL = 1,
- + DPSW_ADMIT_ONLY_VLAN_TAGGED = 3
- +};
- +
- +/**
- + * struct dpsw_accepted_frames_cfg - Types of frames to accept configuration
- + * @type: Defines ingress accepted frames
- + * @unaccept_act: When a frame is not accepted, it may be discarded or
- + * redirected to control interface depending on this mode
- + */
- +struct dpsw_accepted_frames_cfg {
- + enum dpsw_accepted_frames type;
- + enum dpsw_action unaccept_act;
- +};
- +
- +/**
- + * dpsw_if_set_accepted_frames()
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: Frame types configuration
- + *
- + * When is admit_only_vlan_tagged- the device will discard untagged
- + * frames or Priority-Tagged frames received on this interface.
- + * When admit_only_untagged- untagged frames or Priority-Tagged
- + * frames received on this interface will be accepted and assigned
- + * to a VID based on the PVID and VID Set for this interface.
- + * When admit_all - the device will accept VLAN tagged, untagged
- + * and priority tagged frames.
- + * The default is admit_all
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_accepted_frames(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_accepted_frames_cfg *cfg);
- +
- +/**
- + * dpsw_if_set_accept_all_vlan()
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @accept_all: Accept or drop frames having different VLAN
- + *
- + * When this is accept (FALSE), the device will discard incoming
- + * frames for VLANs that do not include this interface in its
- + * Member set. When accept (TRUE), the interface will accept all incoming frames
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_accept_all_vlan(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + int accept_all);
- +
- +/**
- + * enum dpsw_counter - Counters types
- + * @DPSW_CNT_ING_FRAME: Counts ingress frames
- + * @DPSW_CNT_ING_BYTE: Counts ingress bytes
- + * @DPSW_CNT_ING_FLTR_FRAME: Counts filtered ingress frames
- + * @DPSW_CNT_ING_FRAME_DISCARD: Counts discarded ingress frame
- + * @DPSW_CNT_ING_MCAST_FRAME: Counts ingress multicast frames
- + * @DPSW_CNT_ING_MCAST_BYTE: Counts ingress multicast bytes
- + * @DPSW_CNT_ING_BCAST_FRAME: Counts ingress broadcast frames
- + * @DPSW_CNT_ING_BCAST_BYTES: Counts ingress broadcast bytes
- + * @DPSW_CNT_EGR_FRAME: Counts egress frames
- + * @DPSW_CNT_EGR_BYTE: Counts eEgress bytes
- + * @DPSW_CNT_EGR_FRAME_DISCARD: Counts discarded egress frames
- + * @DPSW_CNT_EGR_STP_FRAME_DISCARD: Counts egress STP discarded frames
- + */
- +enum dpsw_counter {
- + DPSW_CNT_ING_FRAME = 0x0,
- + DPSW_CNT_ING_BYTE = 0x1,
- + DPSW_CNT_ING_FLTR_FRAME = 0x2,
- + DPSW_CNT_ING_FRAME_DISCARD = 0x3,
- + DPSW_CNT_ING_MCAST_FRAME = 0x4,
- + DPSW_CNT_ING_MCAST_BYTE = 0x5,
- + DPSW_CNT_ING_BCAST_FRAME = 0x6,
- + DPSW_CNT_ING_BCAST_BYTES = 0x7,
- + DPSW_CNT_EGR_FRAME = 0x8,
- + DPSW_CNT_EGR_BYTE = 0x9,
- + DPSW_CNT_EGR_FRAME_DISCARD = 0xa,
- + DPSW_CNT_EGR_STP_FRAME_DISCARD = 0xb
- +};
- +
- +/**
- + * dpsw_if_get_counter() - Get specific counter of particular interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @type: Counter type
- + * @counter: return value
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + enum dpsw_counter type,
- + uint64_t *counter);
- +
- +/**
- + * dpsw_if_set_counter() - Set specific counter of particular interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @type: Counter type
- + * @counter: New counter value
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_counter(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + enum dpsw_counter type,
- + uint64_t counter);
- +
- +/**
- + * Maximum number of TC
- + */
- +#define DPSW_MAX_TC 8
- +
- +/**
- + * enum dpsw_priority_selector - User priority
- + * @DPSW_UP_PCP: Priority Code Point (PCP): a 3-bit field which
- + * refers to the IEEE 802.1p priority.
- + * @DPSW_UP_DSCP: Differentiated services Code Point (DSCP): 6 bit
- + * field from IP header
- + *
- + */
- +enum dpsw_priority_selector {
- + DPSW_UP_PCP = 0,
- + DPSW_UP_DSCP = 1
- +};
- +
- +/**
- + * enum dpsw_schedule_mode - Traffic classes scheduling
- + * @DPSW_SCHED_STRICT_PRIORITY: schedule strict priority
- + * @DPSW_SCHED_WEIGHTED: schedule based on token bucket created algorithm
- + */
- +enum dpsw_schedule_mode {
- + DPSW_SCHED_STRICT_PRIORITY,
- + DPSW_SCHED_WEIGHTED
- +};
- +
- +/**
- + * struct dpsw_tx_schedule_cfg - traffic class configuration
- + * @mode: Strict or weight-based scheduling
- + * @delta_bandwidth: weighted Bandwidth in range from 100 to 10000
- + */
- +struct dpsw_tx_schedule_cfg {
- + enum dpsw_schedule_mode mode;
- + uint16_t delta_bandwidth;
- +};
- +
- +/**
- + * struct dpsw_tx_selection_cfg - Mapping user priority into traffic
- + * class configuration
- + * @priority_selector: Source for user priority regeneration
- + * @tc_id: The Regenerated User priority that the incoming
- + * User Priority is mapped to for this interface
- + * @tc_sched: Traffic classes configuration
- + */
- +struct dpsw_tx_selection_cfg {
- + enum dpsw_priority_selector priority_selector;
- + uint8_t tc_id[DPSW_MAX_PRIORITIES];
- + struct dpsw_tx_schedule_cfg tc_sched[DPSW_MAX_TC];
- +};
- +
- +/**
- + * dpsw_if_set_tx_selection() - Function is used for mapping variety
- + * of frame fields
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: Traffic class mapping configuration
- + *
- + * Function is used for mapping variety of frame fields (DSCP, PCP)
- + * to Traffic Class. Traffic class is a number
- + * in the range from 0 to 7
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_tx_selection(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_tx_selection_cfg *cfg);
- +
- +/**
- + * enum dpsw_reflection_filter - Filter type for frames to reflect
- + * @DPSW_REFLECTION_FILTER_INGRESS_ALL: Reflect all frames
- + * @DPSW_REFLECTION_FILTER_INGRESS_VLAN: Reflect only frames belong to
- + * particular VLAN defined by vid parameter
- + *
- + */
- +enum dpsw_reflection_filter {
- + DPSW_REFLECTION_FILTER_INGRESS_ALL = 0,
- + DPSW_REFLECTION_FILTER_INGRESS_VLAN = 1
- +};
- +
- +/**
- + * struct dpsw_reflection_cfg - Structure representing reflection information
- + * @filter: Filter type for frames to reflect
- + * @vlan_id: Vlan Id to reflect; valid only when filter type is
- + * DPSW_INGRESS_VLAN
- + */
- +struct dpsw_reflection_cfg {
- + enum dpsw_reflection_filter filter;
- + uint16_t vlan_id;
- +};
- +
- +/**
- + * dpsw_if_add_reflection() - Identify interface to be reflected or mirrored
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: Reflection configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_add_reflection(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_reflection_cfg *cfg);
- +
- +/**
- + * dpsw_if_remove_reflection() - Remove interface to be reflected or mirrored
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: Reflection configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_remove_reflection(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_reflection_cfg *cfg);
- +
- +/**
- + * enum dpsw_metering_mode - Metering modes
- + * @DPSW_METERING_MODE_NONE: metering disabled
- + * @DPSW_METERING_MODE_RFC2698: RFC 2698
- + * @DPSW_METERING_MODE_RFC4115: RFC 4115
- + */
- +enum dpsw_metering_mode {
- + DPSW_METERING_MODE_NONE = 0,
- + DPSW_METERING_MODE_RFC2698,
- + DPSW_METERING_MODE_RFC4115
- +};
- +
- +/**
- + * enum dpsw_metering_unit - Metering count
- + * @DPSW_METERING_UNIT_BYTES: count bytes
- + * @DPSW_METERING_UNIT_FRAMES: count frames
- + */
- +enum dpsw_metering_unit {
- + DPSW_METERING_UNIT_BYTES = 0,
- + DPSW_METERING_UNIT_FRAMES
- +};
- +
- +/**
- + * struct dpsw_metering_cfg - Metering configuration
- + * @mode: metering modes
- + * @units: Bytes or frame units
- + * @cir: Committed information rate (CIR) in Kbits/s
- + * @eir: Peak information rate (PIR) Kbit/s rfc2698
- + * Excess information rate (EIR) Kbit/s rfc4115
- + * @cbs: Committed burst size (CBS) in bytes
- + * @ebs: Peak burst size (PBS) in bytes for rfc2698
- + * Excess bust size (EBS) in bytes rfc4115
- + *
- + */
- +struct dpsw_metering_cfg {
- + enum dpsw_metering_mode mode;
- + enum dpsw_metering_unit units;
- + uint32_t cir;
- + uint32_t eir;
- + uint32_t cbs;
- + uint32_t ebs;
- +};
- +
- +/**
- + * dpsw_if_set_flooding_metering() - Set flooding metering
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @cfg: Metering parameters
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_flooding_metering(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + const struct dpsw_metering_cfg *cfg);
- +
- +/**
- + * dpsw_if_set_metering() - Set interface metering for flooding
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @tc_id: Traffic class ID
- + * @cfg: Metering parameters
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_metering(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint8_t tc_id,
- + const struct dpsw_metering_cfg *cfg);
- +
- +/**
- + * enum dpsw_early_drop_unit - DPSW early drop unit
- + * @DPSW_EARLY_DROP_UNIT_BYTE: count bytes
- + * @DPSW_EARLY_DROP_UNIT_FRAMES: count frames
- + */
- +enum dpsw_early_drop_unit {
- + DPSW_EARLY_DROP_UNIT_BYTE = 0,
- + DPSW_EARLY_DROP_UNIT_FRAMES
- +};
- +
- +/**
- + * enum dpsw_early_drop_mode - DPSW early drop mode
- + * @DPSW_EARLY_DROP_MODE_NONE: early drop is disabled
- + * @DPSW_EARLY_DROP_MODE_TAIL: early drop in taildrop mode
- + * @DPSW_EARLY_DROP_MODE_WRED: early drop in WRED mode
- + */
- +enum dpsw_early_drop_mode {
- + DPSW_EARLY_DROP_MODE_NONE = 0,
- + DPSW_EARLY_DROP_MODE_TAIL,
- + DPSW_EARLY_DROP_MODE_WRED
- +};
- +
- +/**
- + * struct dpsw_wred_cfg - WRED configuration
- + * @max_threshold: maximum threshold that packets may be discarded. Above this
- + * threshold all packets are discarded; must be less than 2^39;
- + * approximated to be expressed as (x+256)*2^(y-1) due to HW
- + * implementation.
- + * @min_threshold: minimum threshold that packets may be discarded at
- + * @drop_probability: probability that a packet will be discarded (1-100,
- + * associated with the maximum threshold)
- + */
- +struct dpsw_wred_cfg {
- + uint64_t min_threshold;
- + uint64_t max_threshold;
- + uint8_t drop_probability;
- +};
- +
- +/**
- + * struct dpsw_early_drop_cfg - early-drop configuration
- + * @drop_mode: drop mode
- + * @units: count units
- + * @yellow: WRED - 'yellow' configuration
- + * @green: WRED - 'green' configuration
- + * @tail_drop_threshold: tail drop threshold
- + */
- +struct dpsw_early_drop_cfg {
- + enum dpsw_early_drop_mode drop_mode;
- + enum dpsw_early_drop_unit units;
- + struct dpsw_wred_cfg yellow;
- + struct dpsw_wred_cfg green;
- + uint32_t tail_drop_threshold;
- +};
- +
- +/**
- + * dpsw_prepare_early_drop() - Prepare an early drop for setting in to interface
- + * @cfg: Early-drop configuration
- + * @early_drop_buf: Zeroed 256 bytes of memory before mapping it to DMA
- + *
- + * This function has to be called before dpsw_if_tc_set_early_drop
- + *
- + */
- +void dpsw_prepare_early_drop(const struct dpsw_early_drop_cfg *cfg,
- + uint8_t *early_drop_buf);
- +
- +/**
- + * dpsw_if_set_early_drop() - Set interface traffic class early-drop
- + * 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 DPSW object
- + * @if_id: Interface Identifier
- + * @tc_id: Traffic class selection (0-7)
- + * @early_drop_iova: I/O virtual address of 64 bytes;
- + * Must be cacheline-aligned and DMA-able memory
- + *
- + * warning: Before calling this function, call dpsw_prepare_if_tc_early_drop()
- + * to prepare the early_drop_iova parameter
- + *
- + * Return: '0' on Success; error code otherwise.
- + */
- +int dpsw_if_set_early_drop(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint8_t tc_id,
- + uint64_t early_drop_iova);
- +
- +/**
- + * struct dpsw_custom_tpid_cfg - Structure representing tag Protocol identifier
- + * @tpid: An additional tag protocol identifier
- + */
- +struct dpsw_custom_tpid_cfg {
- + uint16_t tpid;
- +};
- +
- +/**
- + * dpsw_add_custom_tpid() - API Configures a distinct Ethernet type value
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @cfg: Tag Protocol identifier
- + *
- + * API Configures a distinct Ethernet type value (or TPID value)
- + * to indicate a VLAN tag in addition to the common
- + * TPID values 0x8100 and 0x88A8.
- + * Two additional TPID's are supported
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_add_custom_tpid(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + const struct dpsw_custom_tpid_cfg *cfg);
- +
- +/**
- + * dpsw_remove_custom_tpid - API removes a distinct Ethernet type value
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @cfg: Tag Protocol identifier
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_remove_custom_tpid(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + const struct dpsw_custom_tpid_cfg *cfg);
- +
- +/**
- + * dpsw_if_enable() - Enable Interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id);
- +
- +/**
- + * dpsw_if_disable() - Disable Interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_disable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id);
- +
- +/**
- + * struct dpsw_if_attr - Structure representing DPSW interface attributes
- + * @num_tcs: Number of traffic classes
- + * @rate: Transmit rate in bits per second
- + * @options: Interface configuration options (bitmap)
- + * @enabled: Indicates if interface is enabled
- + * @accept_all_vlan: The device discards/accepts incoming frames
- + * for VLANs that do not include this interface
- + * @admit_untagged: When set to 'DPSW_ADMIT_ONLY_VLAN_TAGGED', the device
- + * discards untagged frames or priority-tagged frames received on
- + * this interface;
- + * When set to 'DPSW_ADMIT_ALL', untagged frames or priority-
- + * tagged frames received on this interface are accepted
- + * @qdid: control frames transmit qdid
- + */
- +struct dpsw_if_attr {
- + uint8_t num_tcs;
- + uint32_t rate;
- + uint32_t options;
- + int enabled;
- + int accept_all_vlan;
- + enum dpsw_accepted_frames admit_untagged;
- + uint16_t qdid;
- +};
- +
- +/**
- + * dpsw_if_get_attributes() - Function obtains attributes of interface
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @attr: Returned interface attributes
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + struct dpsw_if_attr *attr);
- +
- +/**
- + * dpsw_if_set_max_frame_length() - Set Maximum Receive frame length.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @frame_length: Maximum Frame Length
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint16_t frame_length);
- +
- +/**
- + * dpsw_if_get_max_frame_length() - Get Maximum Receive frame length.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @if_id: Interface Identifier
- + * @frame_length: Returned maximum Frame Length
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_if_get_max_frame_length(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t if_id,
- + uint16_t *frame_length);
- +
- +/**
- + * struct dpsw_vlan_cfg - VLAN Configuration
- + * @fdb_id: Forwarding Data Base
- + */
- +struct dpsw_vlan_cfg {
- + uint16_t fdb_id;
- +};
- +
- +/**
- + * dpsw_vlan_add() - Adding new VLAN to DPSW.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: VLAN configuration
- + *
- + * Only VLAN ID and FDB ID are required parameters here.
- + * 12 bit VLAN ID is defined in IEEE802.1Q.
- + * Adding a duplicate VLAN ID is not allowed.
- + * FDB ID can be shared across multiple VLANs. Shared learning
- + * is obtained by calling dpsw_vlan_add for multiple VLAN IDs
- + * with same fdb_id
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_add(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_cfg *cfg);
- +
- +/**
- + * struct dpsw_vlan_if_cfg - Set of VLAN Interfaces
- + * @num_ifs: The number of interfaces that are assigned to the egress
- + * list for this VLAN
- + * @if_id: The set of interfaces that are
- + * assigned to the egress list for this VLAN
- + */
- +struct dpsw_vlan_if_cfg {
- + uint16_t num_ifs;
- + uint16_t if_id[DPSW_MAX_IF];
- +};
- +
- +/**
- + * dpsw_vlan_add_if() - Adding a set of interfaces to an existing VLAN.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: Set of interfaces to add
- + *
- + * It adds only interfaces not belonging to this VLAN yet,
- + * otherwise an error is generated and an entire command is
- + * ignored. This function can be called numerous times always
- + * providing required interfaces delta.
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_add_if_untagged() - Defining a set of interfaces that should be
- + * transmitted as untagged.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: set of interfaces that should be transmitted as untagged
- + *
- + * These interfaces should already belong to this VLAN.
- + * By default all interfaces are transmitted as tagged.
- + * Providing un-existing interface or untagged interface that is
- + * configured untagged already generates an error and the entire
- + * command is ignored.
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_add_if_flooding() - Define a set of interfaces that should be
- + * included in flooding when frame with unknown destination
- + * unicast MAC arrived.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: Set of interfaces that should be used for flooding
- + *
- + * These interfaces should belong to this VLAN. By default all
- + * interfaces are included into flooding list. Providing
- + * un-existing interface or an interface that already in the
- + * flooding list generates an error and the entire command is
- + * ignored.
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_add_if_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_remove_if() - Remove interfaces from an existing VLAN.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: Set of interfaces that should be removed
- + *
- + * Interfaces must belong to this VLAN, otherwise an error
- + * is returned and an the command is ignored
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_remove_if_untagged() - Define a set of interfaces that should be
- + * converted from transmitted as untagged to transmit as tagged.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: set of interfaces that should be removed
- + *
- + * Interfaces provided by API have to belong to this VLAN and
- + * configured untagged, otherwise an error is returned and the
- + * command is ignored
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_remove_if_flooding() - Define a set of interfaces that should be
- + * removed from the flooding list.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: set of interfaces used for flooding
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_remove_if_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + const struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_remove() - Remove an entire VLAN
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id);
- +
- +/**
- + * struct dpsw_vlan_attr - VLAN attributes
- + * @fdb_id: Associated FDB ID
- + * @num_ifs: Number of interfaces
- + * @num_untagged_ifs: Number of untagged interfaces
- + * @num_flooding_ifs: Number of flooding interfaces
- + */
- +struct dpsw_vlan_attr {
- + uint16_t fdb_id;
- + uint16_t num_ifs;
- + uint16_t num_untagged_ifs;
- + uint16_t num_flooding_ifs;
- +};
- +
- +/**
- + * dpsw_vlan_get_attributes() - Get VLAN 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 DPSW object
- + * @vlan_id: VLAN Identifier
- + * @attr: Returned DPSW attributes
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_attr *attr);
- +
- +/**
- + * dpsw_vlan_get_if() - Get interfaces belong to this VLAN
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: Returned set of interfaces belong to this VLAN
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_get_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_get_if_flooding() - Get interfaces used in flooding for this VLAN
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: Returned set of flooding interfaces
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_get_if_flooding(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * dpsw_vlan_get_if_untagged() - Get interfaces that should be transmitted as
- + * untagged
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @vlan_id: VLAN Identifier
- + * @cfg: Returned set of untagged interfaces
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_vlan_get_if_untagged(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t vlan_id,
- + struct dpsw_vlan_if_cfg *cfg);
- +
- +/**
- + * struct dpsw_fdb_cfg - FDB Configuration
- + * @num_fdb_entries: Number of FDB entries
- + * @fdb_aging_time: Aging time in seconds
- + */
- +struct dpsw_fdb_cfg {
- + uint16_t num_fdb_entries;
- + uint16_t fdb_aging_time;
- +};
- +
- +/**
- + * dpsw_fdb_add() - Add FDB to switch and Returns handle to FDB table for
- + * the reference
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Returned Forwarding Database Identifier
- + * @cfg: FDB Configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_add(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t *fdb_id,
- + const struct dpsw_fdb_cfg *cfg);
- +
- +/**
- + * dpsw_fdb_remove() - Remove FDB from switch
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_remove(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id);
- +
- +/**
- + * enum dpsw_fdb_entry_type - FDB Entry type - Static/Dynamic
- + * @DPSW_FDB_ENTRY_STATIC: Static entry
- + * @DPSW_FDB_ENTRY_DINAMIC: Dynamic entry
- + */
- +enum dpsw_fdb_entry_type {
- + DPSW_FDB_ENTRY_STATIC = 0,
- + DPSW_FDB_ENTRY_DINAMIC = 1
- +};
- +
- +/**
- + * struct dpsw_fdb_unicast_cfg - Unicast entry configuration
- + * @type: Select static or dynamic entry
- + * @mac_addr: MAC address
- + * @if_egress: Egress interface ID
- + */
- +struct dpsw_fdb_unicast_cfg {
- + enum dpsw_fdb_entry_type type;
- + uint8_t mac_addr[6];
- + uint16_t if_egress;
- +};
- +
- +/**
- + * dpsw_fdb_add_unicast() - Function adds an unicast entry into MAC lookup table
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @cfg: Unicast entry configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_unicast_cfg *cfg);
- +
- +/**
- + * dpsw_fdb_get_unicast() - Get unicast entry from MAC lookup table by
- + * unicast Ethernet address
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @cfg: Returned unicast entry configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_get_unicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + struct dpsw_fdb_unicast_cfg *cfg);
- +
- +/**
- + * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @cfg: Unicast entry configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_unicast_cfg *cfg);
- +
- +/**
- + * struct dpsw_fdb_multicast_cfg - Multi-cast entry configuration
- + * @type: Select static or dynamic entry
- + * @mac_addr: MAC address
- + * @num_ifs: Number of external and internal interfaces
- + * @if_id: Egress interface IDs
- + */
- +struct dpsw_fdb_multicast_cfg {
- + enum dpsw_fdb_entry_type type;
- + uint8_t mac_addr[6];
- + uint16_t num_ifs;
- + uint16_t if_id[DPSW_MAX_IF];
- +};
- +
- +/**
- + * dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @cfg: Multicast entry configuration
- + *
- + * If group doesn't exist, it will be created.
- + * It adds only interfaces not belonging to this multicast group
- + * yet, otherwise error will be generated and the command is
- + * ignored.
- + * This function may be called numerous times always providing
- + * required interfaces delta.
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_multicast_cfg *cfg);
- +
- +/**
- + * dpsw_fdb_get_multicast() - Reading multi-cast group by multi-cast Ethernet
- + * address.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @cfg: Returned multicast entry configuration
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_get_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + struct dpsw_fdb_multicast_cfg *cfg);
- +
- +/**
- + * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast
- + * group.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @cfg: Multicast entry configuration
- + *
- + * Interfaces provided by this API have to exist in the group,
- + * otherwise an error will be returned and an entire command
- + * ignored. If there is no interface left in the group,
- + * an entire group is deleted
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + const struct dpsw_fdb_multicast_cfg *cfg);
- +
- +/**
- + * enum dpsw_fdb_learning_mode - Auto-learning modes
- + * @DPSW_FDB_LEARNING_MODE_DIS: Disable Auto-learning
- + * @DPSW_FDB_LEARNING_MODE_HW: Enable HW auto-Learning
- + * @DPSW_FDB_LEARNING_MODE_NON_SECURE: Enable None secure learning by CPU
- + * @DPSW_FDB_LEARNING_MODE_SECURE: Enable secure learning by CPU
- + *
- + * NONE - SECURE LEARNING
- + * SMAC found DMAC found CTLU Action
- + * v v Forward frame to
- + * 1. DMAC destination
- + * - v Forward frame to
- + * 1. DMAC destination
- + * 2. Control interface
- + * v - Forward frame to
- + * 1. Flooding list of interfaces
- + * - - Forward frame to
- + * 1. Flooding list of interfaces
- + * 2. Control interface
- + * SECURE LEARING
- + * SMAC found DMAC found CTLU Action
- + * v v Forward frame to
- + * 1. DMAC destination
- + * - v Forward frame to
- + * 1. Control interface
- + * v - Forward frame to
- + * 1. Flooding list of interfaces
- + * - - Forward frame to
- + * 1. Control interface
- + */
- +enum dpsw_fdb_learning_mode {
- + DPSW_FDB_LEARNING_MODE_DIS = 0,
- + DPSW_FDB_LEARNING_MODE_HW = 1,
- + DPSW_FDB_LEARNING_MODE_NON_SECURE = 2,
- + DPSW_FDB_LEARNING_MODE_SECURE = 3
- +};
- +
- +/**
- + * dpsw_fdb_set_learning_mode() - Define FDB learning mode
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @mode: learning mode
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + enum dpsw_fdb_learning_mode mode);
- +
- +/**
- + * struct dpsw_fdb_attr - FDB Attributes
- + * @max_fdb_entries: Number of FDB entries
- + * @fdb_aging_time: Aging time in seconds
- + * @learning_mode: Learning mode
- + * @num_fdb_mc_groups: Current number of multicast groups
- + * @max_fdb_mc_groups: Maximum number of multicast groups
- + */
- +struct dpsw_fdb_attr {
- + uint16_t max_fdb_entries;
- + uint16_t fdb_aging_time;
- + enum dpsw_fdb_learning_mode learning_mode;
- + uint16_t num_fdb_mc_groups;
- + uint16_t max_fdb_mc_groups;
- +};
- +
- +/**
- + * dpsw_fdb_get_attributes() - Get FDB 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 DPSW object
- + * @fdb_id: Forwarding Database Identifier
- + * @attr: Returned FDB attributes
- + *
- + * Return: Completion status. '0' on Success; Error code otherwise.
- + */
- +int dpsw_fdb_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t fdb_id,
- + struct dpsw_fdb_attr *attr);
- +
- +/**
- + * struct dpsw_acl_cfg - ACL Configuration
- + * @max_entries: Number of FDB entries
- + */
- +struct dpsw_acl_cfg {
- + uint16_t max_entries;
- +};
- +
- +/**
- + * struct dpsw_acl_fields - ACL fields.
- + * @l2_dest_mac: Destination MAC address: BPDU, Multicast, Broadcast, Unicast,
- + * slow protocols, MVRP, STP
- + * @l2_source_mac: Source MAC address
- + * @l2_tpid: Layer 2 (Ethernet) protocol type, used to identify the following
- + * protocols: MPLS, PTP, PFC, ARP, Jumbo frames, LLDP, IEEE802.1ae,
- + * Q-in-Q, IPv4, IPv6, PPPoE
- + * @l2_pcp_dei: indicate which protocol is encapsulated in the payload
- + * @l2_vlan_id: layer 2 VLAN ID
- + * @l2_ether_type: layer 2 Ethernet type
- + * @l3_dscp: Layer 3 differentiated services code point
- + * @l3_protocol: Tells the Network layer at the destination host, to which
- + * Protocol this packet belongs to. The following protocol are
- + * supported: ICMP, IGMP, IPv4 (encapsulation), TCP, IPv6
- + * (encapsulation), GRE, PTP
- + * @l3_source_ip: Source IPv4 IP
- + * @l3_dest_ip: Destination IPv4 IP
- + * @l4_source_port: Source TCP/UDP Port
- + * @l4_dest_port: Destination TCP/UDP Port
- + */
- +struct dpsw_acl_fields {
- + uint8_t l2_dest_mac[6];
- + uint8_t l2_source_mac[6];
- + uint16_t l2_tpid;
- + uint8_t l2_pcp_dei;
- + uint16_t l2_vlan_id;
- + uint16_t l2_ether_type;
- + uint8_t l3_dscp;
- + uint8_t l3_protocol;
- + uint32_t l3_source_ip;
- + uint32_t l3_dest_ip;
- + uint16_t l4_source_port;
- + uint16_t l4_dest_port;
- +};
- +
- +/**
- + * struct dpsw_acl_key - ACL key
- + * @match: Match fields
- + * @mask: Mask: b'1 - valid, b'0 don't care
- + */
- +struct dpsw_acl_key {
- + struct dpsw_acl_fields match;
- + struct dpsw_acl_fields mask;
- +};
- +
- +/**
- + * enum dpsw_acl_action
- + * @DPSW_ACL_ACTION_DROP: Drop frame
- + * @DPSW_ACL_ACTION_REDIRECT: Redirect to certain port
- + * @DPSW_ACL_ACTION_ACCEPT: Accept frame
- + * @DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF: Redirect to control interface
- + */
- +enum dpsw_acl_action {
- + DPSW_ACL_ACTION_DROP,
- + DPSW_ACL_ACTION_REDIRECT,
- + DPSW_ACL_ACTION_ACCEPT,
- + DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF
- +};
- +
- +/**
- + * struct dpsw_acl_result - ACL action
- + * @action: Action should be taken when ACL entry hit
- + * @if_id: Interface IDs to redirect frame. Valid only if redirect selected for
- + * action
- + */
- +struct dpsw_acl_result {
- + enum dpsw_acl_action action;
- + uint16_t if_id;
- +};
- +
- +/**
- + * struct dpsw_acl_entry_cfg - ACL entry
- + * @key_iova: I/O virtual address of DMA-able memory filled with key after call
- + * to dpsw_acl_prepare_entry_cfg()
- + * @result: Required action when entry hit occurs
- + * @precedence: Precedence inside ACL 0 is lowest; This priority can not change
- + * during the lifetime of a Policy. It is user responsibility to
- + * space the priorities according to consequent rule additions.
- + */
- +struct dpsw_acl_entry_cfg {
- + uint64_t key_iova;
- + struct dpsw_acl_result result;
- + int precedence;
- +};
- +
- +/**
- + * dpsw_acl_add() - Adds ACL to L2 switch.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @acl_id: Returned ACL ID, for the future reference
- + * @cfg: ACL configuration
- + *
- + * Create Access Control List. Multiple ACLs can be created and
- + * co-exist in L2 switch
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_acl_add(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t *acl_id,
- + const struct dpsw_acl_cfg *cfg);
- +
- +/**
- + * dpsw_acl_remove() - Removes ACL from L2 switch.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @acl_id: ACL ID
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_acl_remove(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id);
- +
- +/**
- + * dpsw_acl_prepare_entry_cfg() - Set an entry to ACL.
- + * @key: key
- + * @entry_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
- + *
- + * This function has to be called before adding or removing acl_entry
- + *
- + */
- +void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key,
- + uint8_t *entry_cfg_buf);
- +
- +/**
- + * dpsw_acl_add_entry() - Adds an entry to ACL.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @acl_id: ACL ID
- + * @cfg: entry configuration
- + *
- + * warning: This function has to be called after dpsw_acl_set_entry_cfg()
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_acl_add_entry(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_entry_cfg *cfg);
- +
- +/**
- + * dpsw_acl_remove_entry() - Removes an entry from ACL.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @acl_id: ACL ID
- + * @cfg: entry configuration
- + *
- + * warning: This function has to be called after dpsw_acl_set_entry_cfg()
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_entry_cfg *cfg);
- +
- +/**
- + * struct dpsw_acl_if_cfg - List of interfaces to Associate with ACL
- + * @num_ifs: Number of interfaces
- + * @if_id: List of interfaces
- + */
- +struct dpsw_acl_if_cfg {
- + uint16_t num_ifs;
- + uint16_t if_id[DPSW_MAX_IF];
- +};
- +
- +/**
- + * dpsw_acl_add_if() - Associate interface/interfaces with ACL.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @acl_id: ACL ID
- + * @cfg: interfaces list
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_acl_add_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_if_cfg *cfg);
- +
- +/**
- + * dpsw_acl_remove_if() - De-associate interface/interfaces from ACL.
- + * @mc_io: Pointer to MC portal's I/O object
- + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- + * @token: Token of DPSW object
- + * @acl_id: ACL ID
- + * @cfg: interfaces list
- + *
- + * Return: '0' on Success; Error code otherwise.
- + */
- +int dpsw_acl_remove_if(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + const struct dpsw_acl_if_cfg *cfg);
- +
- +/**
- + * struct dpsw_acl_attr - ACL Attributes
- + * @max_entries: Max number of ACL entries
- + * @num_entries: Number of used ACL entries
- + * @num_ifs: Number of interfaces associated with ACL
- + */
- +struct dpsw_acl_attr {
- + uint16_t max_entries;
- + uint16_t num_entries;
- + uint16_t num_ifs;
- +};
- +
- +/**
- +* dpsw_acl_get_attributes() - Get specific counter of particular interface
- +* @mc_io: Pointer to MC portal's I/O object
- +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- +* @token: Token of DPSW object
- +* @acl_id: ACL Identifier
- +* @attr: Returned ACL attributes
- +*
- +* Return: '0' on Success; Error code otherwise.
- +*/
- +int dpsw_acl_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + uint16_t acl_id,
- + struct dpsw_acl_attr *attr);
- +/**
- +* struct dpsw_ctrl_if_attr - Control interface attributes
- +* @rx_fqid: Receive FQID
- +* @rx_err_fqid: Receive error FQID
- +* @tx_err_conf_fqid: Transmit error and confirmation FQID
- +*/
- +struct dpsw_ctrl_if_attr {
- + uint32_t rx_fqid;
- + uint32_t rx_err_fqid;
- + uint32_t tx_err_conf_fqid;
- +};
- +
- +/**
- +* dpsw_ctrl_if_get_attributes() - Obtain control interface 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 DPSW object
- +* @attr: Returned control interface attributes
- +*
- +* Return: '0' on Success; Error code otherwise.
- +*/
- +int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + struct dpsw_ctrl_if_attr *attr);
- +
- +/**
- + * Maximum number of DPBP
- + */
- +#define DPSW_MAX_DPBP 8
- +
- +/**
- + * struct dpsw_ctrl_if_pools_cfg - Control interface buffer pools configuration
- + * @num_dpbp: Number of DPBPs
- + * @pools: Array of buffer pools parameters; The number of valid entries
- + * must match 'num_dpbp' value
- + */
- +struct dpsw_ctrl_if_pools_cfg {
- + uint8_t num_dpbp;
- + /**
- + * struct pools - Buffer pools parameters
- + * @dpbp_id: DPBP object ID
- + * @buffer_size: Buffer size
- + * @backup_pool: Backup pool
- + */
- + struct {
- + int dpbp_id;
- + uint16_t buffer_size;
- + int backup_pool;
- + } pools[DPSW_MAX_DPBP];
- +};
- +
- +/**
- +* dpsw_ctrl_if_set_pools() - Set control interface buffer pools
- +* @mc_io: Pointer to MC portal's I/O object
- +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- +* @token: Token of DPSW object
- +* @cfg: buffer pools configuration
- +*
- +* Return: '0' on Success; Error code otherwise.
- +*/
- +int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token,
- + const struct dpsw_ctrl_if_pools_cfg *cfg);
- +
- +/**
- +* dpsw_ctrl_if_enable() - Enable control interface
- +* @mc_io: Pointer to MC portal's I/O object
- +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- +* @token: Token of DPSW object
- +*
- +* Return: '0' on Success; Error code otherwise.
- +*/
- +int dpsw_ctrl_if_enable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token);
- +
- +/**
- +* dpsw_ctrl_if_disable() - Function disables control interface
- +* @mc_io: Pointer to MC portal's I/O object
- +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- +* @token: Token of DPSW object
- +*
- +* Return: '0' on Success; Error code otherwise.
- +*/
- +int dpsw_ctrl_if_disable(struct fsl_mc_io *mc_io,
- + uint32_t cmd_flags,
- + uint16_t token);
- +
- +#endif /* __FSL_DPSW_H */
- --- /dev/null
- +++ b/drivers/staging/fsl-dpaa2/ethsw/switch.c
- @@ -0,0 +1,1711 @@
- +/* Copyright 2014-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/module.h>
- +
- +#include <linux/netdevice.h>
- +#include <linux/etherdevice.h>
- +#include <linux/rtnetlink.h>
- +#include <linux/if_vlan.h>
- +#include <linux/interrupt.h>
- +#include <linux/msi.h>
- +
- +#include <uapi/linux/if_bridge.h>
- +#include <net/netlink.h>
- +
- +#include "../../fsl-mc/include/mc.h"
- +#include "dpsw.h"
- +#include "dpsw-cmd.h"
- +
- +/* Minimal supported DPSE version */
- +#define DPSW_MIN_VER_MAJOR 7
- +#define DPSW_MIN_VER_MINOR 0
- +
- +/* IRQ index */
- +#define DPSW_MAX_IRQ_NUM 2
- +
- +#define ETHSW_VLAN_MEMBER 1
- +#define ETHSW_VLAN_UNTAGGED 2
- +#define ETHSW_VLAN_PVID 4
- +#define ETHSW_VLAN_GLOBAL 8
- +
- +struct ethsw_port_priv {
- + struct net_device *netdev;
- + struct list_head list;
- + u16 port_index;
- + struct ethsw_dev_priv *ethsw_priv;
- + u8 stp_state;
- +
- + char vlans[VLAN_VID_MASK+1];
- +
- +};
- +
- +struct ethsw_dev_priv {
- + struct net_device *netdev;
- + struct fsl_mc_io *mc_io;
- + uint16_t dpsw_handle;
- + struct dpsw_attr sw_attr;
- + int dev_id;
- + /*TODO: redundant, we can use the slave dev list */
- + struct list_head port_list;
- +
- + bool flood;
- + bool learning;
- +
- + char vlans[VLAN_VID_MASK+1];
- +};
- +
- +static int ethsw_port_stop(struct net_device *netdev);
- +static int ethsw_port_open(struct net_device *netdev);
- +
- +static inline void __get_priv(struct net_device *netdev,
- + struct ethsw_dev_priv **priv,
- + struct ethsw_port_priv **port_priv)
- +{
- + struct ethsw_dev_priv *_priv = NULL;
- + struct ethsw_port_priv *_port_priv = NULL;
- +
- + if (netdev->flags & IFF_MASTER) {
- + _priv = netdev_priv(netdev);
- + } else {
- + _port_priv = netdev_priv(netdev);
- + _priv = _port_priv->ethsw_priv;
- + }
- +
- + if (priv)
- + *priv = _priv;
- + if (port_priv)
- + *port_priv = _port_priv;
- +}
- +
- +/* -------------------------------------------------------------------------- */
- +/* ethsw netdevice ops */
- +
- +static netdev_tx_t ethsw_dropframe(struct sk_buff *skb, struct net_device *dev)
- +{
- + /* we don't support I/O for now, drop the frame */
- + dev_kfree_skb_any(skb);
- + return NETDEV_TX_OK;
- +}
- +
- +static int ethsw_open(struct net_device *netdev)
- +{
- + struct ethsw_dev_priv *priv = netdev_priv(netdev);
- + struct list_head *pos;
- + struct ethsw_port_priv *port_priv = NULL;
- + int err;
- +
- + err = dpsw_enable(priv->mc_io, 0, priv->dpsw_handle);
- + if (err) {
- + netdev_err(netdev, "dpsw_enable err %d\n", err);
- + return err;
- + }
- +
- + list_for_each(pos, &priv->port_list) {
- + port_priv = list_entry(pos, struct ethsw_port_priv, list);
- + err = dev_open(port_priv->netdev);
- + if (err)
- + netdev_err(port_priv->netdev, "dev_open err %d\n", err);
- + }
- +
- + return 0;
- +}
- +
- +static int ethsw_stop(struct net_device *netdev)
- +{
- + struct ethsw_dev_priv *priv = netdev_priv(netdev);
- + struct list_head *pos;
- + struct ethsw_port_priv *port_priv = NULL;
- + int err;
- +
- + err = dpsw_disable(priv->mc_io, 0, priv->dpsw_handle);
- + if (err) {
- + netdev_err(netdev, "dpsw_disable err %d\n", err);
- + return err;
- + }
- +
- + list_for_each(pos, &priv->port_list) {
- + port_priv = list_entry(pos, struct ethsw_port_priv, list);
- + err = dev_close(port_priv->netdev);
- + if (err)
- + netdev_err(port_priv->netdev,
- + "dev_close err %d\n", err);
- + }
- +
- + return 0;
- +}
- +
- +static int ethsw_add_vlan(struct net_device *netdev, u16 vid)
- +{
- + struct ethsw_dev_priv *priv = netdev_priv(netdev);
- + int err;
- +
- + struct dpsw_vlan_cfg vcfg = {
- + /* TODO: add support for VLAN private FDBs */
- + .fdb_id = 0,
- + };
- + if (priv->vlans[vid]) {
- + netdev_err(netdev, "VLAN already configured\n");
- + return -EEXIST;
- + }
- +
- + err = dpsw_vlan_add(priv->mc_io, 0, priv->dpsw_handle, vid, &vcfg);
- + if (err) {
- + netdev_err(netdev, "dpsw_vlan_add err %d\n", err);
- + return err;
- + }
- + priv->vlans[vid] = ETHSW_VLAN_MEMBER;
- +
- + return 0;
- +}
- +
- +static int ethsw_port_add_vlan(struct net_device *netdev, u16 vid, u16 flags)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
- + int err;
- +
- + struct dpsw_vlan_if_cfg vcfg = {
- + .num_ifs = 1,
- + .if_id[0] = port_priv->port_index,
- + };
- +
- + if (port_priv->vlans[vid]) {
- + netdev_err(netdev, "VLAN already configured\n");
- + return -EEXIST;
- + }
- +
- + if (flags & BRIDGE_VLAN_INFO_PVID && netif_oper_up(netdev)) {
- + netdev_err(netdev, "interface must be down to change PVID!\n");
- + return -EBUSY;
- + }
- +
- + err = dpsw_vlan_add_if(priv->mc_io, 0, priv->dpsw_handle, vid, &vcfg);
- + if (err) {
- + netdev_err(netdev, "dpsw_vlan_add_if err %d\n", err);
- + return err;
- + }
- + port_priv->vlans[vid] = ETHSW_VLAN_MEMBER;
- +
- + if (flags & BRIDGE_VLAN_INFO_UNTAGGED) {
- + err = dpsw_vlan_add_if_untagged(priv->mc_io, 0,
- + priv->dpsw_handle, vid, &vcfg);
- + if (err) {
- + netdev_err(netdev, "dpsw_vlan_add_if_untagged err %d\n",
- + err);
- + return err;
- + }
- + port_priv->vlans[vid] |= ETHSW_VLAN_UNTAGGED;
- + }
- +
- + if (flags & BRIDGE_VLAN_INFO_PVID) {
- + struct dpsw_tci_cfg tci_cfg = {
- + /* TODO: at least add better defaults if these cannot
- + * be configured
- + */
- + .pcp = 0,
- + .dei = 0,
- + .vlan_id = vid,
- + };
- +
- + err = dpsw_if_set_tci(priv->mc_io, 0, priv->dpsw_handle,
- + port_priv->port_index, &tci_cfg);
- + if (err) {
- + netdev_err(netdev, "dpsw_if_set_tci err %d\n", err);
- + return err;
- + }
- + port_priv->vlans[vid] |= ETHSW_VLAN_PVID;
- + }
- +
- + return 0;
- +}
- +
- +static const struct nla_policy ifla_br_policy[IFLA_MAX+1] = {
- + [IFLA_BRIDGE_FLAGS] = { .type = NLA_U16 },
- + [IFLA_BRIDGE_MODE] = { .type = NLA_U16 },
- + [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY,
- + .len = sizeof(struct bridge_vlan_info), },
- +};
- +
- +static int ethsw_setlink_af_spec(struct net_device *netdev,
- + struct nlattr **tb)
- +{
- + struct bridge_vlan_info *vinfo;
- + struct ethsw_dev_priv *priv = NULL;
- + struct ethsw_port_priv *port_priv = NULL;
- + int err = 0;
- +
- + if (!tb[IFLA_BRIDGE_VLAN_INFO]) {
- + netdev_err(netdev, "no VLAN INFO in nlmsg\n");
- + return -EOPNOTSUPP;
- + }
- +
- + vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]);
- +
- + if (!vinfo->vid || vinfo->vid > VLAN_VID_MASK)
- + return -EINVAL;
- +
- + __get_priv(netdev, &priv, &port_priv);
- +
- + if (!port_priv || !priv->vlans[vinfo->vid]) {
- + /* command targets switch device or this is a new VLAN */
- + err = ethsw_add_vlan(priv->netdev, vinfo->vid);
- + if (err)
- + return err;
- +
- + /* command targets switch device; mark it*/
- + if (!port_priv)
- + priv->vlans[vinfo->vid] |= ETHSW_VLAN_GLOBAL;
- + }
- +
- + if (port_priv) {
- + /* command targets switch port */
- + err = ethsw_port_add_vlan(netdev, vinfo->vid, vinfo->flags);
- + if (err)
- + return err;
- + }
- +
- + return 0;
- +}
- +
- +static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
- + [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
- + [IFLA_BRPORT_COST] = { .type = NLA_U32 },
- + [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
- + [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
- + [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
- + [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
- + [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
- + [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
- +};
- +
- +static int ethsw_set_learning(struct net_device *netdev, u8 flag)
- +{
- + struct ethsw_dev_priv *priv = netdev_priv(netdev);
- + enum dpsw_fdb_learning_mode learn_mode;
- + int err;
- +
- + if (flag)
- + learn_mode = DPSW_FDB_LEARNING_MODE_HW;
- + else
- + learn_mode = DPSW_FDB_LEARNING_MODE_DIS;
- +
- + err = dpsw_fdb_set_learning_mode(priv->mc_io, 0, priv->dpsw_handle,
- + 0, learn_mode);
- + if (err) {
- + netdev_err(netdev, "dpsw_fdb_set_learning_mode err %d\n", err);
- + return err;
- + }
- + priv->learning = !!flag;
- +
- + return 0;
- +}
- +
- +static int ethsw_port_set_flood(struct net_device *netdev, u8 flag)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
- + int err;
- +
- + err = dpsw_if_set_flooding(priv->mc_io, 0, priv->dpsw_handle,
- + port_priv->port_index, (int)flag);
- + if (err) {
- + netdev_err(netdev, "dpsw_fdb_set_learning_mode err %d\n", err);
- + return err;
- + }
- + priv->flood = !!flag;
- +
- + return 0;
- +}
- +
- +static int ethsw_port_set_state(struct net_device *netdev, u8 state)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
- + u8 old_state = port_priv->stp_state;
- + int err;
- +
- + struct dpsw_stp_cfg stp_cfg = {
- + .vlan_id = 1,
- + .state = state,
- + };
- + /* TODO: check port state, interface may be down */
- +
- + if (state > BR_STATE_BLOCKING)
- + return -EINVAL;
- +
- + if (state == port_priv->stp_state)
- + return 0;
- +
- + if (state == BR_STATE_DISABLED) {
- + port_priv->stp_state = state;
- +
- + err = ethsw_port_stop(netdev);
- + if (err)
- + goto error;
- + } else {
- + err = dpsw_if_set_stp(priv->mc_io, 0, priv->dpsw_handle,
- + port_priv->port_index, &stp_cfg);
- + if (err) {
- + netdev_err(netdev, "dpsw_if_set_stp err %d\n", err);
- + return err;
- + }
- +
- + port_priv->stp_state = state;
- +
- + if (old_state == BR_STATE_DISABLED) {
- + err = ethsw_port_open(netdev);
- + if (err)
- + goto error;
- + }
- + }
- +
- + return 0;
- +error:
- + port_priv->stp_state = old_state;
- + return err;
- +}
- +
- +static int ethsw_setlink_protinfo(struct net_device *netdev,
- + struct nlattr **tb)
- +{
- + struct ethsw_dev_priv *priv;
- + struct ethsw_port_priv *port_priv = NULL;
- + int err = 0;
- +
- + __get_priv(netdev, &priv, &port_priv);
- +
- + if (tb[IFLA_BRPORT_LEARNING]) {
- + u8 flag = nla_get_u8(tb[IFLA_BRPORT_LEARNING]);
- +
- + if (port_priv)
- + netdev_warn(netdev,
- + "learning set on whole switch dev\n");
- +
- + err = ethsw_set_learning(priv->netdev, flag);
- + if (err)
- + return err;
- +
- + } else if (tb[IFLA_BRPORT_UNICAST_FLOOD] && port_priv) {
- + u8 flag = nla_get_u8(tb[IFLA_BRPORT_UNICAST_FLOOD]);
- +
- + err = ethsw_port_set_flood(port_priv->netdev, flag);
- + if (err)
- + return err;
- +
- + } else if (tb[IFLA_BRPORT_STATE] && port_priv) {
- + u8 state = nla_get_u8(tb[IFLA_BRPORT_STATE]);
- +
- + err = ethsw_port_set_state(port_priv->netdev, state);
- + if (err)
- + return err;
- +
- + } else {
- + return -EOPNOTSUPP;
- + }
- +
- + return 0;
- +}
- +
- +static int ethsw_setlink(struct net_device *netdev,
- + struct nlmsghdr *nlh,
- + u16 flags)
- +{
- + struct nlattr *attr;
- + struct nlattr *tb[(IFLA_BRIDGE_MAX > IFLA_BRPORT_MAX) ?
- + IFLA_BRIDGE_MAX : IFLA_BRPORT_MAX+1];
- + int err = 0;
- +
- + attr = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
- + if (attr) {
- + err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, attr,
- + ifla_br_policy);
- + if (err) {
- + netdev_err(netdev,
- + "nla_parse_nested for br_policy err %d\n",
- + err);
- + return err;
- + }
- +
- + err = ethsw_setlink_af_spec(netdev, tb);
- + return err;
- + }
- +
- + attr = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_PROTINFO);
- + if (attr) {
- + err = nla_parse_nested(tb, IFLA_BRPORT_MAX, attr,
- + ifla_brport_policy);
- + if (err) {
- + netdev_err(netdev,
- + "nla_parse_nested for brport_policy err %d\n",
- + err);
- + return err;
- + }
- +
- + err = ethsw_setlink_protinfo(netdev, tb);
- + return err;
- + }
- +
- + netdev_err(netdev, "nlmsg_find_attr found no AF_SPEC/PROTINFO\n");
- + return -EOPNOTSUPP;
- +}
- +
- +static int __nla_put_netdev(struct sk_buff *skb, struct net_device *netdev,
- + struct ethsw_dev_priv *priv)
- +{
- + u8 operstate = netif_running(netdev) ? netdev->operstate : IF_OPER_DOWN;
- + int iflink;
- + int err;
- +
- + err = nla_put_string(skb, IFLA_IFNAME, netdev->name);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u32(skb, IFLA_MASTER, priv->netdev->ifindex);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u32(skb, IFLA_MTU, netdev->mtu);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u8(skb, IFLA_OPERSTATE, operstate);
- + if (err)
- + goto nla_put_err;
- + if (netdev->addr_len) {
- + err = nla_put(skb, IFLA_ADDRESS, netdev->addr_len,
- + netdev->dev_addr);
- + if (err)
- + goto nla_put_err;
- + }
- +
- + iflink = dev_get_iflink(netdev);
- + if (netdev->ifindex != iflink) {
- + err = nla_put_u32(skb, IFLA_LINK, iflink);
- + if (err)
- + goto nla_put_err;
- + }
- +
- + return 0;
- +
- +nla_put_err:
- + netdev_err(netdev, "nla_put_ err %d\n", err);
- + return err;
- +}
- +
- +static int __nla_put_port(struct sk_buff *skb, struct net_device *netdev,
- + struct ethsw_port_priv *port_priv)
- +{
- + struct nlattr *nest;
- + int err;
- +
- + u8 stp_state = port_priv->stp_state;
- +
- + if (port_priv->stp_state == DPSW_STP_STATE_BLOCKING)
- + stp_state = BR_STATE_BLOCKING;
- +
- + nest = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);
- + if (!nest) {
- + netdev_err(netdev, "nla_nest_start failed\n");
- + return -ENOMEM;
- + }
- +
- + err = nla_put_u8(skb, IFLA_BRPORT_STATE, stp_state);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u16(skb, IFLA_BRPORT_PRIORITY, 0);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u32(skb, IFLA_BRPORT_COST, 0);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u8(skb, IFLA_BRPORT_MODE, 0);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u8(skb, IFLA_BRPORT_GUARD, 0);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u8(skb, IFLA_BRPORT_PROTECT, 0);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, 0);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u8(skb, IFLA_BRPORT_LEARNING,
- + port_priv->ethsw_priv->learning);
- + if (err)
- + goto nla_put_err;
- + err = nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD,
- + port_priv->ethsw_priv->flood);
- + if (err)
- + goto nla_put_err;
- + nla_nest_end(skb, nest);
- +
- + return 0;
- +
- +nla_put_err:
- + netdev_err(netdev, "nla_put_ err %d\n", err);
- + nla_nest_cancel(skb, nest);
- + return err;
- +}
- +
- +static int __nla_put_vlan(struct sk_buff *skb, struct net_device *netdev,
- + struct ethsw_dev_priv *priv,
- + struct ethsw_port_priv *port_priv)
- +{
- + struct nlattr *nest;
- + struct bridge_vlan_info vinfo;
- + const char *vlans;
- + u16 i;
- + int err;
- +
- + nest = nla_nest_start(skb, IFLA_AF_SPEC);
- + if (!nest) {
- + netdev_err(netdev, "nla_nest_start failed");
- + return -ENOMEM;
- + }
- +
- + if (port_priv)
- + vlans = port_priv->vlans;
- + else
- + vlans = priv->vlans;
- +
- + for (i = 0; i < VLAN_VID_MASK+1; i++) {
- + vinfo.flags = 0;
- + vinfo.vid = i;
- +
- + if (vlans[i] & ETHSW_VLAN_UNTAGGED)
- + vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
- +
- + if (vlans[i] & ETHSW_VLAN_PVID)
- + vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
- +
- + if (vlans[i] & ETHSW_VLAN_MEMBER) {
- + err = nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
- + sizeof(vinfo), &vinfo);
- + if (err)
- + goto nla_put_err;
- + }
- + }
- +
- + nla_nest_end(skb, nest);
- +
- + return 0;
- +nla_put_err:
- + netdev_err(netdev, "nla_put_ err %d\n", err);
- + nla_nest_cancel(skb, nest);
- + return err;
- +}
- +
- +static int ethsw_getlink(struct sk_buff *skb, u32 pid, u32 seq,
- + struct net_device *netdev, u32 filter_mask,
- + int nlflags)
- +{
- + struct ethsw_dev_priv *priv;
- + struct ethsw_port_priv *port_priv = NULL;
- + struct ifinfomsg *hdr;
- + struct nlmsghdr *nlh;
- + int err;
- +
- + __get_priv(netdev, &priv, &port_priv);
- +
- + nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*hdr), NLM_F_MULTI);
- + if (!nlh)
- + return -EMSGSIZE;
- +
- + hdr = nlmsg_data(nlh);
- + memset(hdr, 0, sizeof(*hdr));
- + hdr->ifi_family = AF_BRIDGE;
- + hdr->ifi_type = netdev->type;
- + hdr->ifi_index = netdev->ifindex;
- + hdr->ifi_flags = dev_get_flags(netdev);
- +
- + err = __nla_put_netdev(skb, netdev, priv);
- + if (err)
- + goto nla_put_err;
- +
- + if (port_priv) {
- + err = __nla_put_port(skb, netdev, port_priv);
- + if (err)
- + goto nla_put_err;
- + }
- +
- + /* Check if the VID information is requested */
- + if (filter_mask & RTEXT_FILTER_BRVLAN) {
- + err = __nla_put_vlan(skb, netdev, priv, port_priv);
- + if (err)
- + goto nla_put_err;
- + }
- +
- + nlmsg_end(skb, nlh);
- + return skb->len;
- +
- +nla_put_err:
- + nlmsg_cancel(skb, nlh);
- + return -EMSGSIZE;
- +}
- +
- +static int ethsw_dellink_switch(struct ethsw_dev_priv *priv, u16 vid)
- +{
- + struct list_head *pos;
- + struct ethsw_port_priv *ppriv_local = NULL;
- + int err = 0;
- +
- + if (!priv->vlans[vid])
- + return -ENOENT;
- +
- + err = dpsw_vlan_remove(priv->mc_io, 0, priv->dpsw_handle, vid);
- + if (err) {
- + netdev_err(priv->netdev, "dpsw_vlan_remove err %d\n", err);
- + return err;
- + }
- + priv->vlans[vid] = 0;
- +
- + list_for_each(pos, &priv->port_list) {
- + ppriv_local = list_entry(pos, struct ethsw_port_priv,
- + list);
- + ppriv_local->vlans[vid] = 0;
- + }
- +
- + return 0;
- +}
- +
- +static int ethsw_dellink_port(struct ethsw_dev_priv *priv,
- + struct ethsw_port_priv *port_priv,
- + u16 vid)
- +{
- + struct list_head *pos;
- + struct ethsw_port_priv *ppriv_local = NULL;
- + struct dpsw_vlan_if_cfg vcfg = {
- + .num_ifs = 1,
- + .if_id[0] = port_priv->port_index,
- + };
- + unsigned int count = 0;
- + int err = 0;
- +
- + if (!port_priv->vlans[vid])
- + return -ENOENT;
- +
- + /* VLAN will be deleted from switch if global flag is not set
- + * and is configured on only one port
- + */
- + if (!(priv->vlans[vid] & ETHSW_VLAN_GLOBAL)) {
- + list_for_each(pos, &priv->port_list) {
- + ppriv_local = list_entry(pos, struct ethsw_port_priv,
- + list);
- + if (ppriv_local->vlans[vid] & ETHSW_VLAN_MEMBER)
- + count++;
- + }
- +
- + if (count == 1)
- + return ethsw_dellink_switch(priv, vid);
- + }
- +
- + err = dpsw_vlan_remove_if(priv->mc_io, 0, priv->dpsw_handle,
- + vid, &vcfg);
- + if (err) {
- + netdev_err(priv->netdev, "dpsw_vlan_remove_if err %d\n", err);
- + return err;
- + }
- + port_priv->vlans[vid] = 0;
- + return 0;
- +}
- +
- +static int ethsw_dellink(struct net_device *netdev,
- + struct nlmsghdr *nlh,
- + u16 flags)
- +{
- + struct nlattr *tb[IFLA_BRIDGE_MAX+1];
- + struct nlattr *spec;
- + struct bridge_vlan_info *vinfo;
- + struct ethsw_dev_priv *priv;
- + struct ethsw_port_priv *port_priv = NULL;
- + int err = 0;
- +
- + spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
- + if (!spec)
- + return 0;
- +
- + err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, spec, ifla_br_policy);
- + if (err)
- + return err;
- +
- + if (!tb[IFLA_BRIDGE_VLAN_INFO])
- + return -EOPNOTSUPP;
- +
- + vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]);
- +
- + if (!vinfo->vid || vinfo->vid > VLAN_VID_MASK)
- + return -EINVAL;
- +
- + __get_priv(netdev, &priv, &port_priv);
- +
- + /* decide if command targets switch device or port */
- + if (!port_priv)
- + err = ethsw_dellink_switch(priv, vinfo->vid);
- + else
- + err = ethsw_dellink_port(priv, port_priv, vinfo->vid);
- +
- + return err;
- +}
- +
- +static const struct net_device_ops ethsw_ops = {
- + .ndo_open = ðsw_open,
- + .ndo_stop = ðsw_stop,
- +
- + .ndo_bridge_setlink = ðsw_setlink,
- + .ndo_bridge_getlink = ðsw_getlink,
- + .ndo_bridge_dellink = ðsw_dellink,
- +
- + .ndo_start_xmit = ðsw_dropframe,
- +};
- +
- +/*--------------------------------------------------------------------------- */
- +/* switch port netdevice ops */
- +
- +static int _ethsw_port_carrier_state_sync(struct net_device *netdev)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct dpsw_link_state state;
- + int err;
- +
- + err = dpsw_if_get_link_state(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index, &state);
- + if (unlikely(err)) {
- + netdev_err(netdev, "dpsw_if_get_link_state() err %d\n", err);
- + return err;
- + }
- +
- + WARN_ONCE(state.up > 1, "Garbage read into link_state");
- +
- + if (state.up)
- + netif_carrier_on(port_priv->netdev);
- + else
- + netif_carrier_off(port_priv->netdev);
- +
- + return 0;
- +}
- +
- +static int ethsw_port_open(struct net_device *netdev)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + int err;
- +
- + if (!netif_oper_up(netdev) ||
- + port_priv->stp_state == BR_STATE_DISABLED)
- + return 0;
- +
- + err = dpsw_if_enable(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index);
- + if (err) {
- + netdev_err(netdev, "dpsw_if_enable err %d\n", err);
- + return err;
- + }
- +
- + return 0;
- +}
- +
- +static int ethsw_port_stop(struct net_device *netdev)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + int err;
- +
- + err = dpsw_if_disable(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index);
- + if (err) {
- + netdev_err(netdev, "dpsw_if_disable err %d\n", err);
- + return err;
- + }
- +
- + return 0;
- +}
- +
- +static int ethsw_port_fdb_add_uc(struct net_device *netdev,
- + const unsigned char *addr)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct dpsw_fdb_unicast_cfg entry = {0};
- + int err;
- +
- + entry.if_egress = port_priv->port_index;
- + entry.type = DPSW_FDB_ENTRY_STATIC;
- + ether_addr_copy(entry.mac_addr, addr);
- +
- + err = dpsw_fdb_add_unicast(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + 0, &entry);
- + if (err)
- + netdev_err(netdev, "dpsw_fdb_add_unicast err %d\n", err);
- + return err;
- +}
- +
- +static int ethsw_port_fdb_del_uc(struct net_device *netdev,
- + const unsigned char *addr)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct dpsw_fdb_unicast_cfg entry = {0};
- + int err;
- +
- + entry.if_egress = port_priv->port_index;
- + entry.type = DPSW_FDB_ENTRY_STATIC;
- + ether_addr_copy(entry.mac_addr, addr);
- +
- + err = dpsw_fdb_remove_unicast(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + 0, &entry);
- + if (err)
- + netdev_err(netdev, "dpsw_fdb_remove_unicast err %d\n", err);
- + return err;
- +}
- +
- +static int ethsw_port_fdb_add_mc(struct net_device *netdev,
- + const unsigned char *addr)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct dpsw_fdb_multicast_cfg entry = {0};
- + int err;
- +
- + ether_addr_copy(entry.mac_addr, addr);
- + entry.type = DPSW_FDB_ENTRY_STATIC;
- + entry.num_ifs = 1;
- + entry.if_id[0] = port_priv->port_index;
- +
- + err = dpsw_fdb_add_multicast(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + 0, &entry);
- + if (err)
- + netdev_err(netdev, "dpsw_fdb_add_multicast err %d\n", err);
- + return err;
- +}
- +
- +static int ethsw_port_fdb_del_mc(struct net_device *netdev,
- + const unsigned char *addr)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct dpsw_fdb_multicast_cfg entry = {0};
- + int err;
- +
- + ether_addr_copy(entry.mac_addr, addr);
- + entry.type = DPSW_FDB_ENTRY_STATIC;
- + entry.num_ifs = 1;
- + entry.if_id[0] = port_priv->port_index;
- +
- + err = dpsw_fdb_remove_multicast(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + 0, &entry);
- + if (err)
- + netdev_err(netdev, "dpsw_fdb_remove_multicast err %d\n", err);
- + return err;
- +}
- +
- +static int _lookup_address(struct net_device *netdev, int is_uc,
- + const unsigned char *addr)
- +{
- + struct netdev_hw_addr *ha;
- + struct netdev_hw_addr_list *list = (is_uc) ? &netdev->uc : &netdev->mc;
- +
- + netif_addr_lock_bh(netdev);
- + list_for_each_entry(ha, &list->list, list) {
- + if (ether_addr_equal(ha->addr, addr)) {
- + netif_addr_unlock_bh(netdev);
- + return 1;
- + }
- + }
- + netif_addr_unlock_bh(netdev);
- + return 0;
- +}
- +
- +static int ethsw_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
- + struct net_device *netdev,
- + const unsigned char *addr, u16 vid,
- + u16 flags)
- +{
- + struct list_head *pos;
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
- + int err;
- +
- + /* TODO: add replace support when added to iproute bridge */
- + if (!(flags & NLM_F_REQUEST)) {
- + netdev_err(netdev,
- + "ethsw_port_fdb_add unexpected flags value %08x\n",
- + flags);
- + return -EINVAL;
- + }
- +
- + if (is_unicast_ether_addr(addr)) {
- + /* if entry cannot be replaced, return error if exists */
- + if (flags & NLM_F_EXCL || flags & NLM_F_APPEND) {
- + list_for_each(pos, &priv->port_list) {
- + port_priv = list_entry(pos,
- + struct ethsw_port_priv,
- + list);
- + if (_lookup_address(port_priv->netdev,
- + 1, addr))
- + return -EEXIST;
- + }
- + }
- +
- + err = ethsw_port_fdb_add_uc(netdev, addr);
- + if (err) {
- + netdev_err(netdev, "ethsw_port_fdb_add_uc err %d\n",
- + err);
- + return err;
- + }
- +
- + /* we might have replaced an existing entry for a different
- + * switch port, make sure the address doesn't linger in any
- + * port address list
- + */
- + list_for_each(pos, &priv->port_list) {
- + port_priv = list_entry(pos, struct ethsw_port_priv,
- + list);
- + dev_uc_del(port_priv->netdev, addr);
- + }
- +
- + err = dev_uc_add(netdev, addr);
- + if (err) {
- + netdev_err(netdev, "dev_uc_add err %d\n", err);
- + return err;
- + }
- + } else {
- + struct dpsw_fdb_multicast_cfg entry = {
- + .type = DPSW_FDB_ENTRY_STATIC,
- + .num_ifs = 0,
- + };
- +
- + /* check if address is already set on this port */
- + if (_lookup_address(netdev, 0, addr))
- + return -EEXIST;
- +
- + /* check if the address exists on other port */
- + ether_addr_copy(entry.mac_addr, addr);
- + err = dpsw_fdb_get_multicast(priv->mc_io, 0, priv->dpsw_handle,
- + 0, &entry);
- + if (!err) {
- + /* entry exists, can we replace it? */
- + if (flags & NLM_F_EXCL)
- + return -EEXIST;
- + } else if (err != -ENAVAIL) {
- + netdev_err(netdev, "dpsw_fdb_get_unicast err %d\n",
- + err);
- + return err;
- + }
- +
- + err = ethsw_port_fdb_add_mc(netdev, addr);
- + if (err) {
- + netdev_err(netdev, "ethsw_port_fdb_add_mc err %d\n",
- + err);
- + return err;
- + }
- +
- + err = dev_mc_add(netdev, addr);
- + if (err) {
- + netdev_err(netdev, "dev_mc_add err %d\n", err);
- + return err;
- + }
- + }
- +
- + return 0;
- +}
- +
- +static int ethsw_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
- + struct net_device *netdev,
- + const unsigned char *addr, u16 vid)
- +{
- + int err;
- +
- + if (is_unicast_ether_addr(addr)) {
- + err = ethsw_port_fdb_del_uc(netdev, addr);
- + if (err) {
- + netdev_err(netdev, "ethsw_port_fdb_del_uc err %d\n",
- + err);
- + return err;
- + }
- +
- + /* also delete if configured on port */
- + err = dev_uc_del(netdev, addr);
- + if (err && err != -ENOENT) {
- + netdev_err(netdev, "dev_uc_del err %d\n", err);
- + return err;
- + }
- + } else {
- + if (!_lookup_address(netdev, 0, addr))
- + return -ENOENT;
- +
- + err = dev_mc_del(netdev, addr);
- + if (err) {
- + netdev_err(netdev, "dev_mc_del err %d\n", err);
- + return err;
- + }
- +
- + err = ethsw_port_fdb_del_mc(netdev, addr);
- + if (err) {
- + netdev_err(netdev, "ethsw_port_fdb_del_mc err %d\n",
- + err);
- + return err;
- + }
- + }
- +
- + return 0;
- +}
- +
- +static struct rtnl_link_stats64 *
- +ethsw_port_get_stats(struct net_device *netdev,
- + struct rtnl_link_stats64 *storage)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + u64 tmp;
- + int err;
- +
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + DPSW_CNT_ING_FRAME, &storage->rx_packets);
- + if (err)
- + goto error;
- +
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + DPSW_CNT_EGR_FRAME, &storage->tx_packets);
- + if (err)
- + goto error;
- +
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + DPSW_CNT_ING_BYTE, &storage->rx_bytes);
- + if (err)
- + goto error;
- +
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + DPSW_CNT_EGR_BYTE, &storage->tx_bytes);
- + if (err)
- + goto error;
- +
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + DPSW_CNT_ING_FRAME_DISCARD,
- + &storage->rx_dropped);
- + if (err)
- + goto error;
- +
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + DPSW_CNT_ING_FLTR_FRAME,
- + &tmp);
- + if (err)
- + goto error;
- + storage->rx_dropped += tmp;
- +
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + DPSW_CNT_EGR_FRAME_DISCARD,
- + &storage->tx_dropped);
- + if (err)
- + goto error;
- +
- + return storage;
- +
- +error:
- + netdev_err(netdev, "dpsw_if_get_counter err %d\n", err);
- + return storage;
- +}
- +
- +static const struct net_device_ops ethsw_port_ops = {
- + .ndo_open = ðsw_port_open,
- + .ndo_stop = ðsw_port_stop,
- +
- + .ndo_fdb_add = ðsw_port_fdb_add,
- + .ndo_fdb_del = ðsw_port_fdb_del,
- + .ndo_fdb_dump = &ndo_dflt_fdb_dump,
- +
- + .ndo_get_stats64 = ðsw_port_get_stats,
- +
- + .ndo_start_xmit = ðsw_dropframe,
- +};
- +
- +static struct {
- + enum dpsw_counter id;
- + char name[ETH_GSTRING_LEN];
- +} ethsw_ethtool_counters[] = {
- + {DPSW_CNT_ING_FRAME, "rx frames"},
- + {DPSW_CNT_ING_BYTE, "rx bytes"},
- + {DPSW_CNT_ING_FLTR_FRAME, "rx filtered frames"},
- + {DPSW_CNT_ING_FRAME_DISCARD, "rx discarded frames"},
- + {DPSW_CNT_ING_BCAST_FRAME, "rx b-cast frames"},
- + {DPSW_CNT_ING_BCAST_BYTES, "rx b-cast bytes"},
- + {DPSW_CNT_ING_MCAST_FRAME, "rx m-cast frames"},
- + {DPSW_CNT_ING_MCAST_BYTE, "rx m-cast bytes"},
- + {DPSW_CNT_EGR_FRAME, "tx frames"},
- + {DPSW_CNT_EGR_BYTE, "tx bytes"},
- + {DPSW_CNT_EGR_FRAME_DISCARD, "tx discarded frames"},
- +
- +};
- +
- +static int ethsw_ethtool_get_sset_count(struct net_device *dev, int sset)
- +{
- + switch (sset) {
- + case ETH_SS_STATS:
- + return ARRAY_SIZE(ethsw_ethtool_counters);
- + default:
- + return -EOPNOTSUPP;
- + }
- +}
- +
- +static void ethsw_ethtool_get_strings(struct net_device *netdev,
- + u32 stringset, u8 *data)
- +{
- + int i;
- +
- + switch (stringset) {
- + case ETH_SS_STATS:
- + for (i = 0; i < ARRAY_SIZE(ethsw_ethtool_counters); i++)
- + memcpy(data + i * ETH_GSTRING_LEN,
- + ethsw_ethtool_counters[i].name, ETH_GSTRING_LEN);
- + break;
- + }
- +}
- +
- +static void ethsw_ethtool_get_stats(struct net_device *netdev,
- + struct ethtool_stats *stats,
- + u64 *data)
- +{
- + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
- + int i;
- + int err;
- +
- + for (i = 0; i < ARRAY_SIZE(ethsw_ethtool_counters); i++) {
- + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
- + port_priv->ethsw_priv->dpsw_handle,
- + port_priv->port_index,
- + ethsw_ethtool_counters[i].id,
- + &data[i]);
- + if (err)
- + netdev_err(netdev, "dpsw_if_get_counter[%s] err %d\n",
- + ethsw_ethtool_counters[i].name, err);
- + }
- +}
- +
- +static const struct ethtool_ops ethsw_port_ethtool_ops = {
- + .get_strings = ðsw_ethtool_get_strings,
- + .get_ethtool_stats = ðsw_ethtool_get_stats,
- + .get_sset_count = ðsw_ethtool_get_sset_count,
- +};
- +
- +/* -------------------------------------------------------------------------- */
- +/* ethsw driver functions */
- +
- +static int ethsw_links_state_update(struct ethsw_dev_priv *priv)
- +{
- + struct list_head *pos;
- + struct ethsw_port_priv *port_priv;
- + int err;
- +
- + list_for_each(pos, &priv->port_list) {
- + port_priv = list_entry(pos, struct ethsw_port_priv,
- + list);
- +
- + err = _ethsw_port_carrier_state_sync(port_priv->netdev);
- + if (err)
- + netdev_err(port_priv->netdev,
- + "_ethsw_port_carrier_state_sync err %d\n",
- + err);
- + }
- +
- + return 0;
- +}
- +
- +static irqreturn_t ethsw_irq0_handler(int irq_num, void *arg)
- +{
- + return IRQ_WAKE_THREAD;
- +}
- +
- +static irqreturn_t _ethsw_irq0_handler_thread(int irq_num, void *arg)
- +{
- + struct device *dev = (struct device *)arg;
- + struct fsl_mc_device *sw_dev = to_fsl_mc_device(dev);
- + struct net_device *netdev = dev_get_drvdata(dev);
- + struct ethsw_dev_priv *priv = netdev_priv(netdev);
- +
- + struct fsl_mc_io *io = priv->mc_io;
- + uint16_t token = priv->dpsw_handle;
- + int irq_index = DPSW_IRQ_INDEX_IF;
- +
- + /* Mask the events and the if_id reserved bits to be cleared on read */
- + uint32_t status = DPSW_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;
- + int err;
- +
- + /* Sanity check */
- + if (WARN_ON(!sw_dev || !sw_dev->irqs || !sw_dev->irqs[irq_index]))
- + goto out;
- + if (WARN_ON(sw_dev->irqs[irq_index]->msi_desc->irq != irq_num))
- + goto out;
- +
- + err = dpsw_get_irq_status(io, 0, token, irq_index, &status);
- + if (unlikely(err)) {
- + netdev_err(netdev, "Can't get irq status (err %d)", err);
- +
- + err = dpsw_clear_irq_status(io, 0, token, irq_index,
- + 0xFFFFFFFF);
- + if (unlikely(err))
- + netdev_err(netdev, "Can't clear irq status (err %d)",
- + err);
- + goto out;
- + }
- +
- + if (status & DPSW_IRQ_EVENT_LINK_CHANGED) {
- + err = ethsw_links_state_update(priv);
- + if (unlikely(err))
- + goto out;
- + }
- +
- +out:
- + return IRQ_HANDLED;
- +}
- +
- +static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev)
- +{
- + struct device *dev = &sw_dev->dev;
- + struct net_device *netdev = dev_get_drvdata(dev);
- + struct ethsw_dev_priv *priv = netdev_priv(netdev);
- + int err = 0;
- + struct fsl_mc_device_irq *irq;
- + const int irq_index = DPSW_IRQ_INDEX_IF;
- + uint32_t mask = DPSW_IRQ_EVENT_LINK_CHANGED;
- +
- + err = fsl_mc_allocate_irqs(sw_dev);
- + if (unlikely(err)) {
- + dev_err(dev, "MC irqs allocation failed\n");
- + return err;
- + }
- +
- + if (WARN_ON(sw_dev->obj_desc.irq_count != DPSW_MAX_IRQ_NUM)) {
- + err = -EINVAL;
- + goto free_irq;
- + }
- +
- + err = dpsw_set_irq_enable(priv->mc_io, 0, priv->dpsw_handle,
- + irq_index, 0);
- + if (unlikely(err)) {
- + dev_err(dev, "dpsw_set_irq_enable err %d\n", err);
- + goto free_irq;
- + }
- +
- + irq = sw_dev->irqs[irq_index];
- +
- + err = devm_request_threaded_irq(dev, irq->msi_desc->irq,
- + ethsw_irq0_handler,
- + _ethsw_irq0_handler_thread,
- + IRQF_NO_SUSPEND | IRQF_ONESHOT,
- + dev_name(dev), dev);
- + if (unlikely(err)) {
- + dev_err(dev, "devm_request_threaded_irq(): %d", err);
- + goto free_irq;
- + }
- +
- + err = dpsw_set_irq_mask(priv->mc_io, 0, priv->dpsw_handle,
- + irq_index, mask);
- + if (unlikely(err)) {
- + dev_err(dev, "dpsw_set_irq_mask(): %d", err);
- + goto free_devm_irq;
- + }
- +
- + err = dpsw_set_irq_enable(priv->mc_io, 0, priv->dpsw_handle,
- + irq_index, 1);
- + if (unlikely(err)) {
- + dev_err(dev, "dpsw_set_irq_enable(): %d", err);
- + goto free_devm_irq;
- + }
- +
- + return 0;
- +
- +free_devm_irq:
- + devm_free_irq(dev, irq->msi_desc->irq, dev);
- +free_irq:
- + fsl_mc_free_irqs(sw_dev);
- + return err;
- +}
- +
- +static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev)
- +{
- + struct device *dev = &sw_dev->dev;
- + struct net_device *netdev = dev_get_drvdata(dev);
- + struct ethsw_dev_priv *priv = netdev_priv(netdev);
- +
- + dpsw_set_irq_enable(priv->mc_io, 0, priv->dpsw_handle,
- + DPSW_IRQ_INDEX_IF, 0);
- + devm_free_irq(dev,
- + sw_dev->irqs[DPSW_IRQ_INDEX_IF]->msi_desc->irq,
- + dev);
- + fsl_mc_free_irqs(sw_dev);
- +}
- +
- +static int __cold
- +ethsw_init(struct fsl_mc_device *sw_dev)
- +{
- + struct device *dev = &sw_dev->dev;
- + struct ethsw_dev_priv *priv;
- + struct net_device *netdev;
- + int err = 0;
- + u16 i;
- + const struct dpsw_stp_cfg stp_cfg = {
- + .vlan_id = 1,
- + .state = DPSW_STP_STATE_FORWARDING,
- + };
- +
- + netdev = dev_get_drvdata(dev);
- + priv = netdev_priv(netdev);
- +
- + priv->dev_id = sw_dev->obj_desc.id;
- +
- + err = dpsw_open(priv->mc_io, 0, priv->dev_id, &priv->dpsw_handle);
- + if (err) {
- + dev_err(dev, "dpsw_open err %d\n", err);
- + goto err_exit;
- + }
- + if (!priv->dpsw_handle) {
- + dev_err(dev, "dpsw_open returned null handle but no error\n");
- + err = -EFAULT;
- + goto err_exit;
- + }
- +
- + err = dpsw_get_attributes(priv->mc_io, 0, priv->dpsw_handle,
- + &priv->sw_attr);
- + if (err) {
- + dev_err(dev, "dpsw_get_attributes err %d\n", err);
- + goto err_close;
- + }
- +
- + /* Minimum supported DPSW version check */
- + if (priv->sw_attr.version.major < DPSW_MIN_VER_MAJOR ||
- + (priv->sw_attr.version.major == DPSW_MIN_VER_MAJOR &&
- + priv->sw_attr.version.minor < DPSW_MIN_VER_MINOR)) {
- + dev_err(dev, "DPSW version %d:%d not supported. Use %d.%d or greater.\n",
- + priv->sw_attr.version.major,
- + priv->sw_attr.version.minor,
- + DPSW_MIN_VER_MAJOR, DPSW_MIN_VER_MINOR);
- + err = -ENOTSUPP;
- + goto err_close;
- + }
- +
- + err = dpsw_reset(priv->mc_io, 0, priv->dpsw_handle);
- + if (err) {
- + dev_err(dev, "dpsw_reset err %d\n", err);
- + goto err_close;
- + }
- +
- + err = dpsw_fdb_set_learning_mode(priv->mc_io, 0, priv->dpsw_handle, 0,
- + DPSW_FDB_LEARNING_MODE_HW);
- + if (err) {
- + dev_err(dev, "dpsw_fdb_set_learning_mode err %d\n", err);
- + goto err_close;
- + }
- +
- + for (i = 0; i < priv->sw_attr.num_ifs; i++) {
- + err = dpsw_if_set_stp(priv->mc_io, 0, priv->dpsw_handle, i,
- + &stp_cfg);
- + if (err) {
- + dev_err(dev, "dpsw_if_set_stp err %d for port %d\n",
- + err, i);
- + goto err_close;
- + }
- +
- + err = dpsw_if_set_broadcast(priv->mc_io, 0,
- + priv->dpsw_handle, i, 1);
- + if (err) {
- + dev_err(dev,
- + "dpsw_if_set_broadcast err %d for port %d\n",
- + err, i);
- + goto err_close;
- + }
- + }
- +
- + return 0;
- +
- +err_close:
- + dpsw_close(priv->mc_io, 0, priv->dpsw_handle);
- +err_exit:
- + return err;
- +}
- +
- +static int __cold
- +ethsw_takedown(struct fsl_mc_device *sw_dev)
- +{
- + struct device *dev = &sw_dev->dev;
- + struct net_device *netdev;
- + struct ethsw_dev_priv *priv;
- + int err;
- +
- + netdev = dev_get_drvdata(dev);
- + priv = netdev_priv(netdev);
- +
- + err = dpsw_close(priv->mc_io, 0, priv->dpsw_handle);
- + if (err)
- + dev_warn(dev, "dpsw_close err %d\n", err);
- +
- + return 0;
- +}
- +
- +static int __cold
- +ethsw_remove(struct fsl_mc_device *sw_dev)
- +{
- + struct device *dev;
- + struct net_device *netdev;
- + struct ethsw_dev_priv *priv;
- + struct ethsw_port_priv *port_priv;
- + struct list_head *pos;
- +
- + dev = &sw_dev->dev;
- + netdev = dev_get_drvdata(dev);
- + priv = netdev_priv(netdev);
- +
- + list_for_each(pos, &priv->port_list) {
- + port_priv = list_entry(pos, struct ethsw_port_priv, list);
- +
- + rtnl_lock();
- + netdev_upper_dev_unlink(port_priv->netdev, netdev);
- + rtnl_unlock();
- +
- + unregister_netdev(port_priv->netdev);
- + free_netdev(port_priv->netdev);
- + }
- +
- + ethsw_teardown_irqs(sw_dev);
- +
- + unregister_netdev(netdev);
- +
- + ethsw_takedown(sw_dev);
- + fsl_mc_portal_free(priv->mc_io);
- +
- + dev_set_drvdata(dev, NULL);
- + free_netdev(netdev);
- +
- + return 0;
- +}
- +
- +static int __cold
- +ethsw_probe(struct fsl_mc_device *sw_dev)
- +{
- + struct device *dev;
- + struct net_device *netdev = NULL;
- + struct ethsw_dev_priv *priv = NULL;
- + int err = 0;
- + u16 i;
- + const char def_mcast[ETH_ALEN] = {
- + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01,
- + };
- + char port_name[IFNAMSIZ];
- +
- + dev = &sw_dev->dev;
- +
- + /* register switch device, it's for management only - no I/O */
- + netdev = alloc_etherdev(sizeof(*priv));
- + if (!netdev) {
- + dev_err(dev, "alloc_etherdev error\n");
- + return -ENOMEM;
- + }
- + netdev->netdev_ops = ðsw_ops;
- +
- + SET_NETDEV_DEV(netdev, dev);
- + dev_set_drvdata(dev, netdev);
- +
- + priv = netdev_priv(netdev);
- + priv->netdev = netdev;
- +
- + err = fsl_mc_portal_allocate(sw_dev, 0, &priv->mc_io);
- + if (err) {
- + dev_err(dev, "fsl_mc_portal_allocate err %d\n", err);
- + goto err_free_netdev;
- + }
- + if (!priv->mc_io) {
- + dev_err(dev, "fsl_mc_portal_allocate returned null handle but no error\n");
- + err = -EFAULT;
- + goto err_free_netdev;
- + }
- +
- + err = ethsw_init(sw_dev);
- + if (err) {
- + dev_err(dev, "switch init err %d\n", err);
- + goto err_free_cmdport;
- + }
- +
- + netdev->flags = netdev->flags | IFF_PROMISC | IFF_MASTER;
- +
- + /* TODO: should we hold rtnl_lock here? We can't register_netdev under
- + * lock
- + */
- + dev_alloc_name(netdev, "sw%d");
- + err = register_netdev(netdev);
- + if (err < 0) {
- + dev_err(dev, "register_netdev error %d\n", err);
- + goto err_takedown;
- + }
- + if (err)
- + dev_info(dev, "register_netdev res %d\n", err);
- +
- + /* VLAN 1 is implicitly configured on the switch */
- + priv->vlans[1] = ETHSW_VLAN_MEMBER;
- + /* Flooding, learning are implicitly enabled */
- + priv->learning = true;
- + priv->flood = true;
- +
- + /* register switch ports */
- + snprintf(port_name, IFNAMSIZ, "%sp%%d", netdev->name);
- +
- + INIT_LIST_HEAD(&priv->port_list);
- + for (i = 0; i < priv->sw_attr.num_ifs; i++) {
- + struct net_device *port_netdev;
- + struct ethsw_port_priv *port_priv;
- +
- + port_netdev = alloc_etherdev(sizeof(struct ethsw_port_priv));
- + if (!port_netdev) {
- + dev_err(dev, "alloc_etherdev error\n");
- + goto err_takedown;
- + }
- +
- + port_priv = netdev_priv(port_netdev);
- + port_priv->netdev = port_netdev;
- + port_priv->ethsw_priv = priv;
- +
- + port_priv->port_index = i;
- + port_priv->stp_state = BR_STATE_FORWARDING;
- + /* VLAN 1 is configured by default on all switch ports */
- + port_priv->vlans[1] = ETHSW_VLAN_MEMBER | ETHSW_VLAN_UNTAGGED |
- + ETHSW_VLAN_PVID;
- +
- + SET_NETDEV_DEV(port_netdev, dev);
- + port_netdev->netdev_ops = ðsw_port_ops;
- + port_netdev->ethtool_ops = ðsw_port_ethtool_ops;
- +
- + port_netdev->flags = port_netdev->flags |
- + IFF_PROMISC | IFF_SLAVE;
- +
- + dev_alloc_name(port_netdev, port_name);
- + err = register_netdev(port_netdev);
- + if (err < 0) {
- + dev_err(dev, "register_netdev error %d\n", err);
- + free_netdev(port_netdev);
- + goto err_takedown;
- + }
- +
- + rtnl_lock();
- +
- + err = netdev_master_upper_dev_link(port_netdev, netdev, NULL, NULL);
- + if (err) {
- + dev_err(dev, "netdev_master_upper_dev_link error %d\n",
- + err);
- + unregister_netdev(port_netdev);
- + free_netdev(port_netdev);
- + rtnl_unlock();
- + goto err_takedown;
- + }
- +
- + rtmsg_ifinfo(RTM_NEWLINK, port_netdev, IFF_SLAVE, GFP_KERNEL);
- +
- + rtnl_unlock();
- +
- + list_add(&port_priv->list, &priv->port_list);
- +
- + /* TODO: implmenet set_rm_mode instead of this */
- + err = ethsw_port_fdb_add_mc(port_netdev, def_mcast);
- + if (err)
- + dev_warn(&netdev->dev,
- + "ethsw_port_fdb_add_mc err %d\n", err);
- +
- +
- + /* sync carrier state */
- + err = _ethsw_port_carrier_state_sync(port_netdev);
- + if (err)
- + netdev_err(netdev,
- + "_ethsw_port_carrier_state_sync err %d\n",
- + err);
- + }
- +
- + /* the switch starts up enabled */
- + rtnl_lock();
- + err = dev_open(netdev);
- + rtnl_unlock();
- + if (err)
- + dev_warn(dev, "dev_open err %d\n", err);
- +
- + /* setup irqs */
- + err = ethsw_setup_irqs(sw_dev);
- + if (unlikely(err)) {
- + dev_warn(dev, "ethsw_setup_irqs err %d\n", err);
- + goto err_takedown;
- + }
- +
- + dev_info(&netdev->dev,
- + "probed %d port switch\n", priv->sw_attr.num_ifs);
- + return 0;
- +
- +err_takedown:
- + ethsw_remove(sw_dev);
- +err_free_cmdport:
- + fsl_mc_portal_free(priv->mc_io);
- +err_free_netdev:
- + dev_set_drvdata(dev, NULL);
- + free_netdev(netdev);
- +
- + return err;
- +}
- +
- +static const struct fsl_mc_device_match_id ethsw_match_id_table[] = {
- + {
- + .vendor = FSL_MC_VENDOR_FREESCALE,
- + .obj_type = "dpsw",
- + .ver_major = DPSW_VER_MAJOR,
- + .ver_minor = DPSW_VER_MINOR,
- + },
- + {}
- +};
- +
- +static struct fsl_mc_driver eth_sw_drv = {
- + .driver = {
- + .name = KBUILD_MODNAME,
- + .owner = THIS_MODULE,
- + },
- + .probe = ethsw_probe,
- + .remove = ethsw_remove,
- + .match_id_table = ethsw_match_id_table,
- +};
- +
- +module_fsl_mc_driver(eth_sw_drv);
- +
- +MODULE_LICENSE("GPL");
- +MODULE_DESCRIPTION("DPAA2 Ethernet Switch Driver (prototype)");
- --- a/drivers/staging/fsl-mc/include/net.h
- +++ b/drivers/staging/fsl-mc/include/net.h
- @@ -367,7 +367,6 @@
- /*************************** GTP fields ************************************/
- #define NH_FLD_GTP_TEID (1)
-
- -
- /* Protocol options */
-
- /* Ethernet options */
|