ice_switch.c 185 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2018, Intel Corporation. */
  3. #include "ice_lib.h"
  4. #include "ice_switch.h"
  5. #include "ice_trace.h"
  6. #define ICE_ETH_DA_OFFSET 0
  7. #define ICE_ETH_ETHTYPE_OFFSET 12
  8. #define ICE_ETH_VLAN_TCI_OFFSET 14
  9. #define ICE_MAX_VLAN_ID 0xFFF
  10. #define ICE_IPV6_ETHER_ID 0x86DD
  11. /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
  12. * struct to configure any switch filter rules.
  13. * {DA (6 bytes), SA(6 bytes),
  14. * Ether type (2 bytes for header without VLAN tag) OR
  15. * VLAN tag (4 bytes for header with VLAN tag) }
  16. *
  17. * Word on Hardcoded values
  18. * byte 0 = 0x2: to identify it as locally administered DA MAC
  19. * byte 6 = 0x2: to identify it as locally administered SA MAC
  20. * byte 12 = 0x81 & byte 13 = 0x00:
  21. * In case of VLAN filter first two bytes defines ether type (0x8100)
  22. * and remaining two bytes are placeholder for programming a given VLAN ID
  23. * In case of Ether type filter it is treated as header without VLAN tag
  24. * and byte 12 and 13 is used to program a given Ether type instead
  25. */
  26. static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
  27. 0x2, 0, 0, 0, 0, 0,
  28. 0x81, 0, 0, 0};
  29. enum {
  30. ICE_PKT_OUTER_IPV6 = BIT(0),
  31. ICE_PKT_TUN_GTPC = BIT(1),
  32. ICE_PKT_TUN_GTPU = BIT(2),
  33. ICE_PKT_TUN_NVGRE = BIT(3),
  34. ICE_PKT_TUN_UDP = BIT(4),
  35. ICE_PKT_INNER_IPV6 = BIT(5),
  36. ICE_PKT_INNER_TCP = BIT(6),
  37. ICE_PKT_INNER_UDP = BIT(7),
  38. ICE_PKT_GTP_NOPAY = BIT(8),
  39. ICE_PKT_KMALLOC = BIT(9),
  40. ICE_PKT_PPPOE = BIT(10),
  41. ICE_PKT_L2TPV3 = BIT(11),
  42. ICE_PKT_PFCP = BIT(12),
  43. };
  44. struct ice_dummy_pkt_offsets {
  45. enum ice_protocol_type type;
  46. u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
  47. };
  48. struct ice_dummy_pkt_profile {
  49. const struct ice_dummy_pkt_offsets *offsets;
  50. const u8 *pkt;
  51. u32 match;
  52. u16 pkt_len;
  53. u16 offsets_len;
  54. };
  55. #define ICE_DECLARE_PKT_OFFSETS(type) \
  56. static const struct ice_dummy_pkt_offsets \
  57. ice_dummy_##type##_packet_offsets[]
  58. #define ICE_DECLARE_PKT_TEMPLATE(type) \
  59. static const u8 ice_dummy_##type##_packet[]
  60. #define ICE_PKT_PROFILE(type, m) { \
  61. .match = (m), \
  62. .pkt = ice_dummy_##type##_packet, \
  63. .pkt_len = sizeof(ice_dummy_##type##_packet), \
  64. .offsets = ice_dummy_##type##_packet_offsets, \
  65. .offsets_len = sizeof(ice_dummy_##type##_packet_offsets), \
  66. }
  67. ICE_DECLARE_PKT_OFFSETS(vlan) = {
  68. { ICE_VLAN_OFOS, 12 },
  69. };
  70. ICE_DECLARE_PKT_TEMPLATE(vlan) = {
  71. 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
  72. };
  73. ICE_DECLARE_PKT_OFFSETS(qinq) = {
  74. { ICE_VLAN_EX, 12 },
  75. { ICE_VLAN_IN, 16 },
  76. };
  77. ICE_DECLARE_PKT_TEMPLATE(qinq) = {
  78. 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
  79. 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
  80. };
  81. ICE_DECLARE_PKT_OFFSETS(gre_tcp) = {
  82. { ICE_MAC_OFOS, 0 },
  83. { ICE_ETYPE_OL, 12 },
  84. { ICE_IPV4_OFOS, 14 },
  85. { ICE_NVGRE, 34 },
  86. { ICE_MAC_IL, 42 },
  87. { ICE_ETYPE_IL, 54 },
  88. { ICE_IPV4_IL, 56 },
  89. { ICE_TCP_IL, 76 },
  90. { ICE_PROTOCOL_LAST, 0 },
  91. };
  92. ICE_DECLARE_PKT_TEMPLATE(gre_tcp) = {
  93. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  94. 0x00, 0x00, 0x00, 0x00,
  95. 0x00, 0x00, 0x00, 0x00,
  96. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  97. 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
  98. 0x00, 0x00, 0x00, 0x00,
  99. 0x00, 0x2F, 0x00, 0x00,
  100. 0x00, 0x00, 0x00, 0x00,
  101. 0x00, 0x00, 0x00, 0x00,
  102. 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
  103. 0x00, 0x00, 0x00, 0x00,
  104. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
  105. 0x00, 0x00, 0x00, 0x00,
  106. 0x00, 0x00, 0x00, 0x00,
  107. 0x08, 0x00, /* ICE_ETYPE_IL 54 */
  108. 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
  109. 0x00, 0x00, 0x00, 0x00,
  110. 0x00, 0x06, 0x00, 0x00,
  111. 0x00, 0x00, 0x00, 0x00,
  112. 0x00, 0x00, 0x00, 0x00,
  113. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */
  114. 0x00, 0x00, 0x00, 0x00,
  115. 0x00, 0x00, 0x00, 0x00,
  116. 0x50, 0x02, 0x20, 0x00,
  117. 0x00, 0x00, 0x00, 0x00
  118. };
  119. ICE_DECLARE_PKT_OFFSETS(gre_udp) = {
  120. { ICE_MAC_OFOS, 0 },
  121. { ICE_ETYPE_OL, 12 },
  122. { ICE_IPV4_OFOS, 14 },
  123. { ICE_NVGRE, 34 },
  124. { ICE_MAC_IL, 42 },
  125. { ICE_ETYPE_IL, 54 },
  126. { ICE_IPV4_IL, 56 },
  127. { ICE_UDP_ILOS, 76 },
  128. { ICE_PROTOCOL_LAST, 0 },
  129. };
  130. ICE_DECLARE_PKT_TEMPLATE(gre_udp) = {
  131. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  132. 0x00, 0x00, 0x00, 0x00,
  133. 0x00, 0x00, 0x00, 0x00,
  134. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  135. 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
  136. 0x00, 0x00, 0x00, 0x00,
  137. 0x00, 0x2F, 0x00, 0x00,
  138. 0x00, 0x00, 0x00, 0x00,
  139. 0x00, 0x00, 0x00, 0x00,
  140. 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
  141. 0x00, 0x00, 0x00, 0x00,
  142. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
  143. 0x00, 0x00, 0x00, 0x00,
  144. 0x00, 0x00, 0x00, 0x00,
  145. 0x08, 0x00, /* ICE_ETYPE_IL 54 */
  146. 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
  147. 0x00, 0x00, 0x00, 0x00,
  148. 0x00, 0x11, 0x00, 0x00,
  149. 0x00, 0x00, 0x00, 0x00,
  150. 0x00, 0x00, 0x00, 0x00,
  151. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */
  152. 0x00, 0x08, 0x00, 0x00,
  153. };
  154. ICE_DECLARE_PKT_OFFSETS(udp_tun_tcp) = {
  155. { ICE_MAC_OFOS, 0 },
  156. { ICE_ETYPE_OL, 12 },
  157. { ICE_IPV4_OFOS, 14 },
  158. { ICE_UDP_OF, 34 },
  159. { ICE_VXLAN, 42 },
  160. { ICE_GENEVE, 42 },
  161. { ICE_VXLAN_GPE, 42 },
  162. { ICE_MAC_IL, 50 },
  163. { ICE_ETYPE_IL, 62 },
  164. { ICE_IPV4_IL, 64 },
  165. { ICE_TCP_IL, 84 },
  166. { ICE_PROTOCOL_LAST, 0 },
  167. };
  168. ICE_DECLARE_PKT_TEMPLATE(udp_tun_tcp) = {
  169. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  170. 0x00, 0x00, 0x00, 0x00,
  171. 0x00, 0x00, 0x00, 0x00,
  172. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  173. 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
  174. 0x00, 0x01, 0x00, 0x00,
  175. 0x40, 0x11, 0x00, 0x00,
  176. 0x00, 0x00, 0x00, 0x00,
  177. 0x00, 0x00, 0x00, 0x00,
  178. 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
  179. 0x00, 0x46, 0x00, 0x00,
  180. 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
  181. 0x00, 0x00, 0x00, 0x00,
  182. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
  183. 0x00, 0x00, 0x00, 0x00,
  184. 0x00, 0x00, 0x00, 0x00,
  185. 0x08, 0x00, /* ICE_ETYPE_IL 62 */
  186. 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
  187. 0x00, 0x01, 0x00, 0x00,
  188. 0x40, 0x06, 0x00, 0x00,
  189. 0x00, 0x00, 0x00, 0x00,
  190. 0x00, 0x00, 0x00, 0x00,
  191. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
  192. 0x00, 0x00, 0x00, 0x00,
  193. 0x00, 0x00, 0x00, 0x00,
  194. 0x50, 0x02, 0x20, 0x00,
  195. 0x00, 0x00, 0x00, 0x00
  196. };
  197. ICE_DECLARE_PKT_OFFSETS(udp_tun_udp) = {
  198. { ICE_MAC_OFOS, 0 },
  199. { ICE_ETYPE_OL, 12 },
  200. { ICE_IPV4_OFOS, 14 },
  201. { ICE_UDP_OF, 34 },
  202. { ICE_VXLAN, 42 },
  203. { ICE_GENEVE, 42 },
  204. { ICE_VXLAN_GPE, 42 },
  205. { ICE_MAC_IL, 50 },
  206. { ICE_ETYPE_IL, 62 },
  207. { ICE_IPV4_IL, 64 },
  208. { ICE_UDP_ILOS, 84 },
  209. { ICE_PROTOCOL_LAST, 0 },
  210. };
  211. ICE_DECLARE_PKT_TEMPLATE(udp_tun_udp) = {
  212. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  213. 0x00, 0x00, 0x00, 0x00,
  214. 0x00, 0x00, 0x00, 0x00,
  215. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  216. 0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
  217. 0x00, 0x01, 0x00, 0x00,
  218. 0x00, 0x11, 0x00, 0x00,
  219. 0x00, 0x00, 0x00, 0x00,
  220. 0x00, 0x00, 0x00, 0x00,
  221. 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
  222. 0x00, 0x3a, 0x00, 0x00,
  223. 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
  224. 0x00, 0x00, 0x00, 0x00,
  225. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
  226. 0x00, 0x00, 0x00, 0x00,
  227. 0x00, 0x00, 0x00, 0x00,
  228. 0x08, 0x00, /* ICE_ETYPE_IL 62 */
  229. 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
  230. 0x00, 0x01, 0x00, 0x00,
  231. 0x00, 0x11, 0x00, 0x00,
  232. 0x00, 0x00, 0x00, 0x00,
  233. 0x00, 0x00, 0x00, 0x00,
  234. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
  235. 0x00, 0x08, 0x00, 0x00,
  236. };
  237. ICE_DECLARE_PKT_OFFSETS(gre_ipv6_tcp) = {
  238. { ICE_MAC_OFOS, 0 },
  239. { ICE_ETYPE_OL, 12 },
  240. { ICE_IPV4_OFOS, 14 },
  241. { ICE_NVGRE, 34 },
  242. { ICE_MAC_IL, 42 },
  243. { ICE_ETYPE_IL, 54 },
  244. { ICE_IPV6_IL, 56 },
  245. { ICE_TCP_IL, 96 },
  246. { ICE_PROTOCOL_LAST, 0 },
  247. };
  248. ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_tcp) = {
  249. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  250. 0x00, 0x00, 0x00, 0x00,
  251. 0x00, 0x00, 0x00, 0x00,
  252. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  253. 0x45, 0x00, 0x00, 0x66, /* ICE_IPV4_OFOS 14 */
  254. 0x00, 0x00, 0x00, 0x00,
  255. 0x00, 0x2F, 0x00, 0x00,
  256. 0x00, 0x00, 0x00, 0x00,
  257. 0x00, 0x00, 0x00, 0x00,
  258. 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
  259. 0x00, 0x00, 0x00, 0x00,
  260. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
  261. 0x00, 0x00, 0x00, 0x00,
  262. 0x00, 0x00, 0x00, 0x00,
  263. 0x86, 0xdd, /* ICE_ETYPE_IL 54 */
  264. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
  265. 0x00, 0x08, 0x06, 0x40,
  266. 0x00, 0x00, 0x00, 0x00,
  267. 0x00, 0x00, 0x00, 0x00,
  268. 0x00, 0x00, 0x00, 0x00,
  269. 0x00, 0x00, 0x00, 0x00,
  270. 0x00, 0x00, 0x00, 0x00,
  271. 0x00, 0x00, 0x00, 0x00,
  272. 0x00, 0x00, 0x00, 0x00,
  273. 0x00, 0x00, 0x00, 0x00,
  274. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 96 */
  275. 0x00, 0x00, 0x00, 0x00,
  276. 0x00, 0x00, 0x00, 0x00,
  277. 0x50, 0x02, 0x20, 0x00,
  278. 0x00, 0x00, 0x00, 0x00
  279. };
  280. ICE_DECLARE_PKT_OFFSETS(gre_ipv6_udp) = {
  281. { ICE_MAC_OFOS, 0 },
  282. { ICE_ETYPE_OL, 12 },
  283. { ICE_IPV4_OFOS, 14 },
  284. { ICE_NVGRE, 34 },
  285. { ICE_MAC_IL, 42 },
  286. { ICE_ETYPE_IL, 54 },
  287. { ICE_IPV6_IL, 56 },
  288. { ICE_UDP_ILOS, 96 },
  289. { ICE_PROTOCOL_LAST, 0 },
  290. };
  291. ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_udp) = {
  292. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  293. 0x00, 0x00, 0x00, 0x00,
  294. 0x00, 0x00, 0x00, 0x00,
  295. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  296. 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
  297. 0x00, 0x00, 0x00, 0x00,
  298. 0x00, 0x2F, 0x00, 0x00,
  299. 0x00, 0x00, 0x00, 0x00,
  300. 0x00, 0x00, 0x00, 0x00,
  301. 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
  302. 0x00, 0x00, 0x00, 0x00,
  303. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
  304. 0x00, 0x00, 0x00, 0x00,
  305. 0x00, 0x00, 0x00, 0x00,
  306. 0x86, 0xdd, /* ICE_ETYPE_IL 54 */
  307. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
  308. 0x00, 0x08, 0x11, 0x40,
  309. 0x00, 0x00, 0x00, 0x00,
  310. 0x00, 0x00, 0x00, 0x00,
  311. 0x00, 0x00, 0x00, 0x00,
  312. 0x00, 0x00, 0x00, 0x00,
  313. 0x00, 0x00, 0x00, 0x00,
  314. 0x00, 0x00, 0x00, 0x00,
  315. 0x00, 0x00, 0x00, 0x00,
  316. 0x00, 0x00, 0x00, 0x00,
  317. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 96 */
  318. 0x00, 0x08, 0x00, 0x00,
  319. };
  320. ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_tcp) = {
  321. { ICE_MAC_OFOS, 0 },
  322. { ICE_ETYPE_OL, 12 },
  323. { ICE_IPV4_OFOS, 14 },
  324. { ICE_UDP_OF, 34 },
  325. { ICE_VXLAN, 42 },
  326. { ICE_GENEVE, 42 },
  327. { ICE_VXLAN_GPE, 42 },
  328. { ICE_MAC_IL, 50 },
  329. { ICE_ETYPE_IL, 62 },
  330. { ICE_IPV6_IL, 64 },
  331. { ICE_TCP_IL, 104 },
  332. { ICE_PROTOCOL_LAST, 0 },
  333. };
  334. ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_tcp) = {
  335. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  336. 0x00, 0x00, 0x00, 0x00,
  337. 0x00, 0x00, 0x00, 0x00,
  338. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  339. 0x45, 0x00, 0x00, 0x6e, /* ICE_IPV4_OFOS 14 */
  340. 0x00, 0x01, 0x00, 0x00,
  341. 0x40, 0x11, 0x00, 0x00,
  342. 0x00, 0x00, 0x00, 0x00,
  343. 0x00, 0x00, 0x00, 0x00,
  344. 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
  345. 0x00, 0x5a, 0x00, 0x00,
  346. 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
  347. 0x00, 0x00, 0x00, 0x00,
  348. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
  349. 0x00, 0x00, 0x00, 0x00,
  350. 0x00, 0x00, 0x00, 0x00,
  351. 0x86, 0xdd, /* ICE_ETYPE_IL 62 */
  352. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
  353. 0x00, 0x08, 0x06, 0x40,
  354. 0x00, 0x00, 0x00, 0x00,
  355. 0x00, 0x00, 0x00, 0x00,
  356. 0x00, 0x00, 0x00, 0x00,
  357. 0x00, 0x00, 0x00, 0x00,
  358. 0x00, 0x00, 0x00, 0x00,
  359. 0x00, 0x00, 0x00, 0x00,
  360. 0x00, 0x00, 0x00, 0x00,
  361. 0x00, 0x00, 0x00, 0x00,
  362. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 104 */
  363. 0x00, 0x00, 0x00, 0x00,
  364. 0x00, 0x00, 0x00, 0x00,
  365. 0x50, 0x02, 0x20, 0x00,
  366. 0x00, 0x00, 0x00, 0x00
  367. };
  368. ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_udp) = {
  369. { ICE_MAC_OFOS, 0 },
  370. { ICE_ETYPE_OL, 12 },
  371. { ICE_IPV4_OFOS, 14 },
  372. { ICE_UDP_OF, 34 },
  373. { ICE_VXLAN, 42 },
  374. { ICE_GENEVE, 42 },
  375. { ICE_VXLAN_GPE, 42 },
  376. { ICE_MAC_IL, 50 },
  377. { ICE_ETYPE_IL, 62 },
  378. { ICE_IPV6_IL, 64 },
  379. { ICE_UDP_ILOS, 104 },
  380. { ICE_PROTOCOL_LAST, 0 },
  381. };
  382. ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_udp) = {
  383. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  384. 0x00, 0x00, 0x00, 0x00,
  385. 0x00, 0x00, 0x00, 0x00,
  386. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  387. 0x45, 0x00, 0x00, 0x62, /* ICE_IPV4_OFOS 14 */
  388. 0x00, 0x01, 0x00, 0x00,
  389. 0x00, 0x11, 0x00, 0x00,
  390. 0x00, 0x00, 0x00, 0x00,
  391. 0x00, 0x00, 0x00, 0x00,
  392. 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
  393. 0x00, 0x4e, 0x00, 0x00,
  394. 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
  395. 0x00, 0x00, 0x00, 0x00,
  396. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
  397. 0x00, 0x00, 0x00, 0x00,
  398. 0x00, 0x00, 0x00, 0x00,
  399. 0x86, 0xdd, /* ICE_ETYPE_IL 62 */
  400. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
  401. 0x00, 0x08, 0x11, 0x40,
  402. 0x00, 0x00, 0x00, 0x00,
  403. 0x00, 0x00, 0x00, 0x00,
  404. 0x00, 0x00, 0x00, 0x00,
  405. 0x00, 0x00, 0x00, 0x00,
  406. 0x00, 0x00, 0x00, 0x00,
  407. 0x00, 0x00, 0x00, 0x00,
  408. 0x00, 0x00, 0x00, 0x00,
  409. 0x00, 0x00, 0x00, 0x00,
  410. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 104 */
  411. 0x00, 0x08, 0x00, 0x00,
  412. };
  413. /* offset info for MAC + IPv4 + UDP dummy packet */
  414. ICE_DECLARE_PKT_OFFSETS(udp) = {
  415. { ICE_MAC_OFOS, 0 },
  416. { ICE_ETYPE_OL, 12 },
  417. { ICE_IPV4_OFOS, 14 },
  418. { ICE_UDP_ILOS, 34 },
  419. { ICE_PROTOCOL_LAST, 0 },
  420. };
  421. /* Dummy packet for MAC + IPv4 + UDP */
  422. ICE_DECLARE_PKT_TEMPLATE(udp) = {
  423. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  424. 0x00, 0x00, 0x00, 0x00,
  425. 0x00, 0x00, 0x00, 0x00,
  426. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  427. 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
  428. 0x00, 0x01, 0x00, 0x00,
  429. 0x00, 0x11, 0x00, 0x00,
  430. 0x00, 0x00, 0x00, 0x00,
  431. 0x00, 0x00, 0x00, 0x00,
  432. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
  433. 0x00, 0x08, 0x00, 0x00,
  434. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  435. };
  436. /* offset info for MAC + IPv4 + TCP dummy packet */
  437. ICE_DECLARE_PKT_OFFSETS(tcp) = {
  438. { ICE_MAC_OFOS, 0 },
  439. { ICE_ETYPE_OL, 12 },
  440. { ICE_IPV4_OFOS, 14 },
  441. { ICE_TCP_IL, 34 },
  442. { ICE_PROTOCOL_LAST, 0 },
  443. };
  444. /* Dummy packet for MAC + IPv4 + TCP */
  445. ICE_DECLARE_PKT_TEMPLATE(tcp) = {
  446. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  447. 0x00, 0x00, 0x00, 0x00,
  448. 0x00, 0x00, 0x00, 0x00,
  449. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  450. 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
  451. 0x00, 0x01, 0x00, 0x00,
  452. 0x00, 0x06, 0x00, 0x00,
  453. 0x00, 0x00, 0x00, 0x00,
  454. 0x00, 0x00, 0x00, 0x00,
  455. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
  456. 0x00, 0x00, 0x00, 0x00,
  457. 0x00, 0x00, 0x00, 0x00,
  458. 0x50, 0x00, 0x00, 0x00,
  459. 0x00, 0x00, 0x00, 0x00,
  460. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  461. };
  462. ICE_DECLARE_PKT_OFFSETS(tcp_ipv6) = {
  463. { ICE_MAC_OFOS, 0 },
  464. { ICE_ETYPE_OL, 12 },
  465. { ICE_IPV6_OFOS, 14 },
  466. { ICE_TCP_IL, 54 },
  467. { ICE_PROTOCOL_LAST, 0 },
  468. };
  469. ICE_DECLARE_PKT_TEMPLATE(tcp_ipv6) = {
  470. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  471. 0x00, 0x00, 0x00, 0x00,
  472. 0x00, 0x00, 0x00, 0x00,
  473. 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
  474. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
  475. 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
  476. 0x00, 0x00, 0x00, 0x00,
  477. 0x00, 0x00, 0x00, 0x00,
  478. 0x00, 0x00, 0x00, 0x00,
  479. 0x00, 0x00, 0x00, 0x00,
  480. 0x00, 0x00, 0x00, 0x00,
  481. 0x00, 0x00, 0x00, 0x00,
  482. 0x00, 0x00, 0x00, 0x00,
  483. 0x00, 0x00, 0x00, 0x00,
  484. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
  485. 0x00, 0x00, 0x00, 0x00,
  486. 0x00, 0x00, 0x00, 0x00,
  487. 0x50, 0x00, 0x00, 0x00,
  488. 0x00, 0x00, 0x00, 0x00,
  489. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  490. };
  491. /* IPv6 + UDP */
  492. ICE_DECLARE_PKT_OFFSETS(udp_ipv6) = {
  493. { ICE_MAC_OFOS, 0 },
  494. { ICE_ETYPE_OL, 12 },
  495. { ICE_IPV6_OFOS, 14 },
  496. { ICE_UDP_ILOS, 54 },
  497. { ICE_PROTOCOL_LAST, 0 },
  498. };
  499. /* IPv6 + UDP dummy packet */
  500. ICE_DECLARE_PKT_TEMPLATE(udp_ipv6) = {
  501. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  502. 0x00, 0x00, 0x00, 0x00,
  503. 0x00, 0x00, 0x00, 0x00,
  504. 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
  505. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
  506. 0x00, 0x10, 0x11, 0x00, /* Next header UDP */
  507. 0x00, 0x00, 0x00, 0x00,
  508. 0x00, 0x00, 0x00, 0x00,
  509. 0x00, 0x00, 0x00, 0x00,
  510. 0x00, 0x00, 0x00, 0x00,
  511. 0x00, 0x00, 0x00, 0x00,
  512. 0x00, 0x00, 0x00, 0x00,
  513. 0x00, 0x00, 0x00, 0x00,
  514. 0x00, 0x00, 0x00, 0x00,
  515. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
  516. 0x00, 0x10, 0x00, 0x00,
  517. 0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
  518. 0x00, 0x00, 0x00, 0x00,
  519. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  520. };
  521. /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
  522. ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_tcp) = {
  523. { ICE_MAC_OFOS, 0 },
  524. { ICE_IPV4_OFOS, 14 },
  525. { ICE_UDP_OF, 34 },
  526. { ICE_GTP, 42 },
  527. { ICE_IPV4_IL, 62 },
  528. { ICE_TCP_IL, 82 },
  529. { ICE_PROTOCOL_LAST, 0 },
  530. };
  531. ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_tcp) = {
  532. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  533. 0x00, 0x00, 0x00, 0x00,
  534. 0x00, 0x00, 0x00, 0x00,
  535. 0x08, 0x00,
  536. 0x45, 0x00, 0x00, 0x58, /* IP 14 */
  537. 0x00, 0x00, 0x00, 0x00,
  538. 0x00, 0x11, 0x00, 0x00,
  539. 0x00, 0x00, 0x00, 0x00,
  540. 0x00, 0x00, 0x00, 0x00,
  541. 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
  542. 0x00, 0x44, 0x00, 0x00,
  543. 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 42 */
  544. 0x00, 0x00, 0x00, 0x00,
  545. 0x00, 0x00, 0x00, 0x85,
  546. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
  547. 0x00, 0x00, 0x00, 0x00,
  548. 0x45, 0x00, 0x00, 0x28, /* IP 62 */
  549. 0x00, 0x00, 0x00, 0x00,
  550. 0x00, 0x06, 0x00, 0x00,
  551. 0x00, 0x00, 0x00, 0x00,
  552. 0x00, 0x00, 0x00, 0x00,
  553. 0x00, 0x00, 0x00, 0x00, /* TCP 82 */
  554. 0x00, 0x00, 0x00, 0x00,
  555. 0x00, 0x00, 0x00, 0x00,
  556. 0x50, 0x00, 0x00, 0x00,
  557. 0x00, 0x00, 0x00, 0x00,
  558. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  559. };
  560. /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
  561. ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_udp) = {
  562. { ICE_MAC_OFOS, 0 },
  563. { ICE_IPV4_OFOS, 14 },
  564. { ICE_UDP_OF, 34 },
  565. { ICE_GTP, 42 },
  566. { ICE_IPV4_IL, 62 },
  567. { ICE_UDP_ILOS, 82 },
  568. { ICE_PROTOCOL_LAST, 0 },
  569. };
  570. ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_udp) = {
  571. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  572. 0x00, 0x00, 0x00, 0x00,
  573. 0x00, 0x00, 0x00, 0x00,
  574. 0x08, 0x00,
  575. 0x45, 0x00, 0x00, 0x4c, /* IP 14 */
  576. 0x00, 0x00, 0x00, 0x00,
  577. 0x00, 0x11, 0x00, 0x00,
  578. 0x00, 0x00, 0x00, 0x00,
  579. 0x00, 0x00, 0x00, 0x00,
  580. 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
  581. 0x00, 0x38, 0x00, 0x00,
  582. 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 42 */
  583. 0x00, 0x00, 0x00, 0x00,
  584. 0x00, 0x00, 0x00, 0x85,
  585. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
  586. 0x00, 0x00, 0x00, 0x00,
  587. 0x45, 0x00, 0x00, 0x1c, /* IP 62 */
  588. 0x00, 0x00, 0x00, 0x00,
  589. 0x00, 0x11, 0x00, 0x00,
  590. 0x00, 0x00, 0x00, 0x00,
  591. 0x00, 0x00, 0x00, 0x00,
  592. 0x00, 0x00, 0x00, 0x00, /* UDP 82 */
  593. 0x00, 0x08, 0x00, 0x00,
  594. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  595. };
  596. /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
  597. ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_tcp) = {
  598. { ICE_MAC_OFOS, 0 },
  599. { ICE_IPV4_OFOS, 14 },
  600. { ICE_UDP_OF, 34 },
  601. { ICE_GTP, 42 },
  602. { ICE_IPV6_IL, 62 },
  603. { ICE_TCP_IL, 102 },
  604. { ICE_PROTOCOL_LAST, 0 },
  605. };
  606. ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_tcp) = {
  607. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  608. 0x00, 0x00, 0x00, 0x00,
  609. 0x00, 0x00, 0x00, 0x00,
  610. 0x08, 0x00,
  611. 0x45, 0x00, 0x00, 0x6c, /* IP 14 */
  612. 0x00, 0x00, 0x00, 0x00,
  613. 0x00, 0x11, 0x00, 0x00,
  614. 0x00, 0x00, 0x00, 0x00,
  615. 0x00, 0x00, 0x00, 0x00,
  616. 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
  617. 0x00, 0x58, 0x00, 0x00,
  618. 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 42 */
  619. 0x00, 0x00, 0x00, 0x00,
  620. 0x00, 0x00, 0x00, 0x85,
  621. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
  622. 0x00, 0x00, 0x00, 0x00,
  623. 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
  624. 0x00, 0x14, 0x06, 0x00,
  625. 0x00, 0x00, 0x00, 0x00,
  626. 0x00, 0x00, 0x00, 0x00,
  627. 0x00, 0x00, 0x00, 0x00,
  628. 0x00, 0x00, 0x00, 0x00,
  629. 0x00, 0x00, 0x00, 0x00,
  630. 0x00, 0x00, 0x00, 0x00,
  631. 0x00, 0x00, 0x00, 0x00,
  632. 0x00, 0x00, 0x00, 0x00,
  633. 0x00, 0x00, 0x00, 0x00, /* TCP 102 */
  634. 0x00, 0x00, 0x00, 0x00,
  635. 0x00, 0x00, 0x00, 0x00,
  636. 0x50, 0x00, 0x00, 0x00,
  637. 0x00, 0x00, 0x00, 0x00,
  638. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  639. };
  640. ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_udp) = {
  641. { ICE_MAC_OFOS, 0 },
  642. { ICE_IPV4_OFOS, 14 },
  643. { ICE_UDP_OF, 34 },
  644. { ICE_GTP, 42 },
  645. { ICE_IPV6_IL, 62 },
  646. { ICE_UDP_ILOS, 102 },
  647. { ICE_PROTOCOL_LAST, 0 },
  648. };
  649. ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_udp) = {
  650. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  651. 0x00, 0x00, 0x00, 0x00,
  652. 0x00, 0x00, 0x00, 0x00,
  653. 0x08, 0x00,
  654. 0x45, 0x00, 0x00, 0x60, /* IP 14 */
  655. 0x00, 0x00, 0x00, 0x00,
  656. 0x00, 0x11, 0x00, 0x00,
  657. 0x00, 0x00, 0x00, 0x00,
  658. 0x00, 0x00, 0x00, 0x00,
  659. 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
  660. 0x00, 0x4c, 0x00, 0x00,
  661. 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 42 */
  662. 0x00, 0x00, 0x00, 0x00,
  663. 0x00, 0x00, 0x00, 0x85,
  664. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
  665. 0x00, 0x00, 0x00, 0x00,
  666. 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
  667. 0x00, 0x08, 0x11, 0x00,
  668. 0x00, 0x00, 0x00, 0x00,
  669. 0x00, 0x00, 0x00, 0x00,
  670. 0x00, 0x00, 0x00, 0x00,
  671. 0x00, 0x00, 0x00, 0x00,
  672. 0x00, 0x00, 0x00, 0x00,
  673. 0x00, 0x00, 0x00, 0x00,
  674. 0x00, 0x00, 0x00, 0x00,
  675. 0x00, 0x00, 0x00, 0x00,
  676. 0x00, 0x00, 0x00, 0x00, /* UDP 102 */
  677. 0x00, 0x08, 0x00, 0x00,
  678. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  679. };
  680. ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_tcp) = {
  681. { ICE_MAC_OFOS, 0 },
  682. { ICE_IPV6_OFOS, 14 },
  683. { ICE_UDP_OF, 54 },
  684. { ICE_GTP, 62 },
  685. { ICE_IPV4_IL, 82 },
  686. { ICE_TCP_IL, 102 },
  687. { ICE_PROTOCOL_LAST, 0 },
  688. };
  689. ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_tcp) = {
  690. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  691. 0x00, 0x00, 0x00, 0x00,
  692. 0x00, 0x00, 0x00, 0x00,
  693. 0x86, 0xdd,
  694. 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
  695. 0x00, 0x44, 0x11, 0x00,
  696. 0x00, 0x00, 0x00, 0x00,
  697. 0x00, 0x00, 0x00, 0x00,
  698. 0x00, 0x00, 0x00, 0x00,
  699. 0x00, 0x00, 0x00, 0x00,
  700. 0x00, 0x00, 0x00, 0x00,
  701. 0x00, 0x00, 0x00, 0x00,
  702. 0x00, 0x00, 0x00, 0x00,
  703. 0x00, 0x00, 0x00, 0x00,
  704. 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
  705. 0x00, 0x44, 0x00, 0x00,
  706. 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 62 */
  707. 0x00, 0x00, 0x00, 0x00,
  708. 0x00, 0x00, 0x00, 0x85,
  709. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
  710. 0x00, 0x00, 0x00, 0x00,
  711. 0x45, 0x00, 0x00, 0x28, /* IP 82 */
  712. 0x00, 0x00, 0x00, 0x00,
  713. 0x00, 0x06, 0x00, 0x00,
  714. 0x00, 0x00, 0x00, 0x00,
  715. 0x00, 0x00, 0x00, 0x00,
  716. 0x00, 0x00, 0x00, 0x00, /* TCP 102 */
  717. 0x00, 0x00, 0x00, 0x00,
  718. 0x00, 0x00, 0x00, 0x00,
  719. 0x50, 0x00, 0x00, 0x00,
  720. 0x00, 0x00, 0x00, 0x00,
  721. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  722. };
  723. ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_udp) = {
  724. { ICE_MAC_OFOS, 0 },
  725. { ICE_IPV6_OFOS, 14 },
  726. { ICE_UDP_OF, 54 },
  727. { ICE_GTP, 62 },
  728. { ICE_IPV4_IL, 82 },
  729. { ICE_UDP_ILOS, 102 },
  730. { ICE_PROTOCOL_LAST, 0 },
  731. };
  732. ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_udp) = {
  733. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  734. 0x00, 0x00, 0x00, 0x00,
  735. 0x00, 0x00, 0x00, 0x00,
  736. 0x86, 0xdd,
  737. 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
  738. 0x00, 0x38, 0x11, 0x00,
  739. 0x00, 0x00, 0x00, 0x00,
  740. 0x00, 0x00, 0x00, 0x00,
  741. 0x00, 0x00, 0x00, 0x00,
  742. 0x00, 0x00, 0x00, 0x00,
  743. 0x00, 0x00, 0x00, 0x00,
  744. 0x00, 0x00, 0x00, 0x00,
  745. 0x00, 0x00, 0x00, 0x00,
  746. 0x00, 0x00, 0x00, 0x00,
  747. 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
  748. 0x00, 0x38, 0x00, 0x00,
  749. 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 62 */
  750. 0x00, 0x00, 0x00, 0x00,
  751. 0x00, 0x00, 0x00, 0x85,
  752. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
  753. 0x00, 0x00, 0x00, 0x00,
  754. 0x45, 0x00, 0x00, 0x1c, /* IP 82 */
  755. 0x00, 0x00, 0x00, 0x00,
  756. 0x00, 0x11, 0x00, 0x00,
  757. 0x00, 0x00, 0x00, 0x00,
  758. 0x00, 0x00, 0x00, 0x00,
  759. 0x00, 0x00, 0x00, 0x00, /* UDP 102 */
  760. 0x00, 0x08, 0x00, 0x00,
  761. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  762. };
  763. ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_tcp) = {
  764. { ICE_MAC_OFOS, 0 },
  765. { ICE_IPV6_OFOS, 14 },
  766. { ICE_UDP_OF, 54 },
  767. { ICE_GTP, 62 },
  768. { ICE_IPV6_IL, 82 },
  769. { ICE_TCP_IL, 122 },
  770. { ICE_PROTOCOL_LAST, 0 },
  771. };
  772. ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_tcp) = {
  773. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  774. 0x00, 0x00, 0x00, 0x00,
  775. 0x00, 0x00, 0x00, 0x00,
  776. 0x86, 0xdd,
  777. 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
  778. 0x00, 0x58, 0x11, 0x00,
  779. 0x00, 0x00, 0x00, 0x00,
  780. 0x00, 0x00, 0x00, 0x00,
  781. 0x00, 0x00, 0x00, 0x00,
  782. 0x00, 0x00, 0x00, 0x00,
  783. 0x00, 0x00, 0x00, 0x00,
  784. 0x00, 0x00, 0x00, 0x00,
  785. 0x00, 0x00, 0x00, 0x00,
  786. 0x00, 0x00, 0x00, 0x00,
  787. 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
  788. 0x00, 0x58, 0x00, 0x00,
  789. 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 62 */
  790. 0x00, 0x00, 0x00, 0x00,
  791. 0x00, 0x00, 0x00, 0x85,
  792. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
  793. 0x00, 0x00, 0x00, 0x00,
  794. 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
  795. 0x00, 0x14, 0x06, 0x00,
  796. 0x00, 0x00, 0x00, 0x00,
  797. 0x00, 0x00, 0x00, 0x00,
  798. 0x00, 0x00, 0x00, 0x00,
  799. 0x00, 0x00, 0x00, 0x00,
  800. 0x00, 0x00, 0x00, 0x00,
  801. 0x00, 0x00, 0x00, 0x00,
  802. 0x00, 0x00, 0x00, 0x00,
  803. 0x00, 0x00, 0x00, 0x00,
  804. 0x00, 0x00, 0x00, 0x00, /* TCP 122 */
  805. 0x00, 0x00, 0x00, 0x00,
  806. 0x00, 0x00, 0x00, 0x00,
  807. 0x50, 0x00, 0x00, 0x00,
  808. 0x00, 0x00, 0x00, 0x00,
  809. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  810. };
  811. ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_udp) = {
  812. { ICE_MAC_OFOS, 0 },
  813. { ICE_IPV6_OFOS, 14 },
  814. { ICE_UDP_OF, 54 },
  815. { ICE_GTP, 62 },
  816. { ICE_IPV6_IL, 82 },
  817. { ICE_UDP_ILOS, 122 },
  818. { ICE_PROTOCOL_LAST, 0 },
  819. };
  820. ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_udp) = {
  821. 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
  822. 0x00, 0x00, 0x00, 0x00,
  823. 0x00, 0x00, 0x00, 0x00,
  824. 0x86, 0xdd,
  825. 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
  826. 0x00, 0x4c, 0x11, 0x00,
  827. 0x00, 0x00, 0x00, 0x00,
  828. 0x00, 0x00, 0x00, 0x00,
  829. 0x00, 0x00, 0x00, 0x00,
  830. 0x00, 0x00, 0x00, 0x00,
  831. 0x00, 0x00, 0x00, 0x00,
  832. 0x00, 0x00, 0x00, 0x00,
  833. 0x00, 0x00, 0x00, 0x00,
  834. 0x00, 0x00, 0x00, 0x00,
  835. 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
  836. 0x00, 0x4c, 0x00, 0x00,
  837. 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 62 */
  838. 0x00, 0x00, 0x00, 0x00,
  839. 0x00, 0x00, 0x00, 0x85,
  840. 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
  841. 0x00, 0x00, 0x00, 0x00,
  842. 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
  843. 0x00, 0x08, 0x11, 0x00,
  844. 0x00, 0x00, 0x00, 0x00,
  845. 0x00, 0x00, 0x00, 0x00,
  846. 0x00, 0x00, 0x00, 0x00,
  847. 0x00, 0x00, 0x00, 0x00,
  848. 0x00, 0x00, 0x00, 0x00,
  849. 0x00, 0x00, 0x00, 0x00,
  850. 0x00, 0x00, 0x00, 0x00,
  851. 0x00, 0x00, 0x00, 0x00,
  852. 0x00, 0x00, 0x00, 0x00, /* UDP 122 */
  853. 0x00, 0x08, 0x00, 0x00,
  854. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  855. };
  856. ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4) = {
  857. { ICE_MAC_OFOS, 0 },
  858. { ICE_IPV4_OFOS, 14 },
  859. { ICE_UDP_OF, 34 },
  860. { ICE_GTP_NO_PAY, 42 },
  861. { ICE_PROTOCOL_LAST, 0 },
  862. };
  863. ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4) = {
  864. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  865. 0x00, 0x00, 0x00, 0x00,
  866. 0x00, 0x00, 0x00, 0x00,
  867. 0x08, 0x00,
  868. 0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */
  869. 0x00, 0x00, 0x40, 0x00,
  870. 0x40, 0x11, 0x00, 0x00,
  871. 0x00, 0x00, 0x00, 0x00,
  872. 0x00, 0x00, 0x00, 0x00,
  873. 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
  874. 0x00, 0x00, 0x00, 0x00,
  875. 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */
  876. 0x00, 0x00, 0x00, 0x00,
  877. 0x00, 0x00, 0x00, 0x85,
  878. 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
  879. 0x00, 0x00, 0x00, 0x00,
  880. 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */
  881. 0x00, 0x00, 0x40, 0x00,
  882. 0x40, 0x00, 0x00, 0x00,
  883. 0x00, 0x00, 0x00, 0x00,
  884. 0x00, 0x00, 0x00, 0x00,
  885. 0x00, 0x00,
  886. };
  887. ICE_DECLARE_PKT_OFFSETS(ipv6_gtp) = {
  888. { ICE_MAC_OFOS, 0 },
  889. { ICE_IPV6_OFOS, 14 },
  890. { ICE_UDP_OF, 54 },
  891. { ICE_GTP_NO_PAY, 62 },
  892. { ICE_PROTOCOL_LAST, 0 },
  893. };
  894. ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = {
  895. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  896. 0x00, 0x00, 0x00, 0x00,
  897. 0x00, 0x00, 0x00, 0x00,
  898. 0x86, 0xdd,
  899. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
  900. 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
  901. 0x00, 0x00, 0x00, 0x00,
  902. 0x00, 0x00, 0x00, 0x00,
  903. 0x00, 0x00, 0x00, 0x00,
  904. 0x00, 0x00, 0x00, 0x00,
  905. 0x00, 0x00, 0x00, 0x00,
  906. 0x00, 0x00, 0x00, 0x00,
  907. 0x00, 0x00, 0x00, 0x00,
  908. 0x00, 0x00, 0x00, 0x00,
  909. 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
  910. 0x00, 0x00, 0x00, 0x00,
  911. 0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */
  912. 0x00, 0x00, 0x00, 0x00,
  913. 0x00, 0x00,
  914. };
  915. ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv4) = {
  916. { ICE_MAC_OFOS, 0 },
  917. { ICE_ETYPE_OL, 12 },
  918. { ICE_IPV4_OFOS, 14 },
  919. { ICE_UDP_ILOS, 34 },
  920. { ICE_PFCP, 42 },
  921. { ICE_PROTOCOL_LAST, 0 },
  922. };
  923. ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv4) = {
  924. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  925. 0x00, 0x00, 0x00, 0x00,
  926. 0x00, 0x00, 0x00, 0x00,
  927. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  928. 0x45, 0x00, 0x00, 0x2c, /* ICE_IPV4_OFOS 14 */
  929. 0x00, 0x01, 0x00, 0x00,
  930. 0x00, 0x11, 0x00, 0x00,
  931. 0x00, 0x00, 0x00, 0x00,
  932. 0x00, 0x00, 0x00, 0x00,
  933. 0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 34 */
  934. 0x00, 0x18, 0x00, 0x00,
  935. 0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 42 */
  936. 0x00, 0x00, 0x00, 0x00,
  937. 0x00, 0x00, 0x00, 0x00,
  938. 0x00, 0x00, 0x00, 0x00,
  939. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  940. };
  941. ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv6) = {
  942. { ICE_MAC_OFOS, 0 },
  943. { ICE_ETYPE_OL, 12 },
  944. { ICE_IPV6_OFOS, 14 },
  945. { ICE_UDP_ILOS, 54 },
  946. { ICE_PFCP, 62 },
  947. { ICE_PROTOCOL_LAST, 0 },
  948. };
  949. ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv6) = {
  950. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  951. 0x00, 0x00, 0x00, 0x00,
  952. 0x00, 0x00, 0x00, 0x00,
  953. 0x86, 0xdd, /* ICE_ETYPE_OL 12 */
  954. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
  955. 0x00, 0x10, 0x11, 0x00, /* Next header UDP */
  956. 0x00, 0x00, 0x00, 0x00,
  957. 0x00, 0x00, 0x00, 0x00,
  958. 0x00, 0x00, 0x00, 0x00,
  959. 0x00, 0x00, 0x00, 0x00,
  960. 0x00, 0x00, 0x00, 0x00,
  961. 0x00, 0x00, 0x00, 0x00,
  962. 0x00, 0x00, 0x00, 0x00,
  963. 0x00, 0x00, 0x00, 0x00,
  964. 0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 54 */
  965. 0x00, 0x18, 0x00, 0x00,
  966. 0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 62 */
  967. 0x00, 0x00, 0x00, 0x00,
  968. 0x00, 0x00, 0x00, 0x00,
  969. 0x00, 0x00, 0x00, 0x00,
  970. 0x00, 0x00, /* 2 bytes for 4 byte alignment */
  971. };
  972. ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = {
  973. { ICE_MAC_OFOS, 0 },
  974. { ICE_ETYPE_OL, 12 },
  975. { ICE_PPPOE, 14 },
  976. { ICE_IPV4_OFOS, 22 },
  977. { ICE_TCP_IL, 42 },
  978. { ICE_PROTOCOL_LAST, 0 },
  979. };
  980. ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = {
  981. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  982. 0x00, 0x00, 0x00, 0x00,
  983. 0x00, 0x00, 0x00, 0x00,
  984. 0x88, 0x64, /* ICE_ETYPE_OL 12 */
  985. 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
  986. 0x00, 0x16,
  987. 0x00, 0x21, /* PPP Link Layer 20 */
  988. 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */
  989. 0x00, 0x01, 0x00, 0x00,
  990. 0x00, 0x06, 0x00, 0x00,
  991. 0x00, 0x00, 0x00, 0x00,
  992. 0x00, 0x00, 0x00, 0x00,
  993. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */
  994. 0x00, 0x00, 0x00, 0x00,
  995. 0x00, 0x00, 0x00, 0x00,
  996. 0x50, 0x00, 0x00, 0x00,
  997. 0x00, 0x00, 0x00, 0x00,
  998. 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
  999. };
  1000. ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = {
  1001. { ICE_MAC_OFOS, 0 },
  1002. { ICE_ETYPE_OL, 12 },
  1003. { ICE_PPPOE, 14 },
  1004. { ICE_IPV4_OFOS, 22 },
  1005. { ICE_UDP_ILOS, 42 },
  1006. { ICE_PROTOCOL_LAST, 0 },
  1007. };
  1008. ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = {
  1009. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  1010. 0x00, 0x00, 0x00, 0x00,
  1011. 0x00, 0x00, 0x00, 0x00,
  1012. 0x88, 0x64, /* ICE_ETYPE_OL 12 */
  1013. 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
  1014. 0x00, 0x16,
  1015. 0x00, 0x21, /* PPP Link Layer 20 */
  1016. 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
  1017. 0x00, 0x01, 0x00, 0x00,
  1018. 0x00, 0x11, 0x00, 0x00,
  1019. 0x00, 0x00, 0x00, 0x00,
  1020. 0x00, 0x00, 0x00, 0x00,
  1021. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
  1022. 0x00, 0x08, 0x00, 0x00,
  1023. 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
  1024. };
  1025. ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = {
  1026. { ICE_MAC_OFOS, 0 },
  1027. { ICE_ETYPE_OL, 12 },
  1028. { ICE_PPPOE, 14 },
  1029. { ICE_IPV6_OFOS, 22 },
  1030. { ICE_TCP_IL, 62 },
  1031. { ICE_PROTOCOL_LAST, 0 },
  1032. };
  1033. ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = {
  1034. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  1035. 0x00, 0x00, 0x00, 0x00,
  1036. 0x00, 0x00, 0x00, 0x00,
  1037. 0x88, 0x64, /* ICE_ETYPE_OL 12 */
  1038. 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
  1039. 0x00, 0x2a,
  1040. 0x00, 0x57, /* PPP Link Layer 20 */
  1041. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
  1042. 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
  1043. 0x00, 0x00, 0x00, 0x00,
  1044. 0x00, 0x00, 0x00, 0x00,
  1045. 0x00, 0x00, 0x00, 0x00,
  1046. 0x00, 0x00, 0x00, 0x00,
  1047. 0x00, 0x00, 0x00, 0x00,
  1048. 0x00, 0x00, 0x00, 0x00,
  1049. 0x00, 0x00, 0x00, 0x00,
  1050. 0x00, 0x00, 0x00, 0x00,
  1051. 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */
  1052. 0x00, 0x00, 0x00, 0x00,
  1053. 0x00, 0x00, 0x00, 0x00,
  1054. 0x50, 0x00, 0x00, 0x00,
  1055. 0x00, 0x00, 0x00, 0x00,
  1056. 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
  1057. };
  1058. ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = {
  1059. { ICE_MAC_OFOS, 0 },
  1060. { ICE_ETYPE_OL, 12 },
  1061. { ICE_PPPOE, 14 },
  1062. { ICE_IPV6_OFOS, 22 },
  1063. { ICE_UDP_ILOS, 62 },
  1064. { ICE_PROTOCOL_LAST, 0 },
  1065. };
  1066. ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = {
  1067. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  1068. 0x00, 0x00, 0x00, 0x00,
  1069. 0x00, 0x00, 0x00, 0x00,
  1070. 0x88, 0x64, /* ICE_ETYPE_OL 12 */
  1071. 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
  1072. 0x00, 0x2a,
  1073. 0x00, 0x57, /* PPP Link Layer 20 */
  1074. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
  1075. 0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
  1076. 0x00, 0x00, 0x00, 0x00,
  1077. 0x00, 0x00, 0x00, 0x00,
  1078. 0x00, 0x00, 0x00, 0x00,
  1079. 0x00, 0x00, 0x00, 0x00,
  1080. 0x00, 0x00, 0x00, 0x00,
  1081. 0x00, 0x00, 0x00, 0x00,
  1082. 0x00, 0x00, 0x00, 0x00,
  1083. 0x00, 0x00, 0x00, 0x00,
  1084. 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */
  1085. 0x00, 0x08, 0x00, 0x00,
  1086. 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
  1087. };
  1088. ICE_DECLARE_PKT_OFFSETS(ipv4_l2tpv3) = {
  1089. { ICE_MAC_OFOS, 0 },
  1090. { ICE_ETYPE_OL, 12 },
  1091. { ICE_IPV4_OFOS, 14 },
  1092. { ICE_L2TPV3, 34 },
  1093. { ICE_PROTOCOL_LAST, 0 },
  1094. };
  1095. ICE_DECLARE_PKT_TEMPLATE(ipv4_l2tpv3) = {
  1096. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  1097. 0x00, 0x00, 0x00, 0x00,
  1098. 0x00, 0x00, 0x00, 0x00,
  1099. 0x08, 0x00, /* ICE_ETYPE_OL 12 */
  1100. 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
  1101. 0x00, 0x00, 0x40, 0x00,
  1102. 0x40, 0x73, 0x00, 0x00,
  1103. 0x00, 0x00, 0x00, 0x00,
  1104. 0x00, 0x00, 0x00, 0x00,
  1105. 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
  1106. 0x00, 0x00, 0x00, 0x00,
  1107. 0x00, 0x00, 0x00, 0x00,
  1108. 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
  1109. };
  1110. ICE_DECLARE_PKT_OFFSETS(ipv6_l2tpv3) = {
  1111. { ICE_MAC_OFOS, 0 },
  1112. { ICE_ETYPE_OL, 12 },
  1113. { ICE_IPV6_OFOS, 14 },
  1114. { ICE_L2TPV3, 54 },
  1115. { ICE_PROTOCOL_LAST, 0 },
  1116. };
  1117. ICE_DECLARE_PKT_TEMPLATE(ipv6_l2tpv3) = {
  1118. 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
  1119. 0x00, 0x00, 0x00, 0x00,
  1120. 0x00, 0x00, 0x00, 0x00,
  1121. 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
  1122. 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
  1123. 0x00, 0x0c, 0x73, 0x40,
  1124. 0x00, 0x00, 0x00, 0x00,
  1125. 0x00, 0x00, 0x00, 0x00,
  1126. 0x00, 0x00, 0x00, 0x00,
  1127. 0x00, 0x00, 0x00, 0x00,
  1128. 0x00, 0x00, 0x00, 0x00,
  1129. 0x00, 0x00, 0x00, 0x00,
  1130. 0x00, 0x00, 0x00, 0x00,
  1131. 0x00, 0x00, 0x00, 0x00,
  1132. 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
  1133. 0x00, 0x00, 0x00, 0x00,
  1134. 0x00, 0x00, 0x00, 0x00,
  1135. 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
  1136. };
  1137. static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
  1138. ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 |
  1139. ICE_PKT_GTP_NOPAY),
  1140. ICE_PKT_PROFILE(ipv6_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
  1141. ICE_PKT_OUTER_IPV6 |
  1142. ICE_PKT_INNER_IPV6 |
  1143. ICE_PKT_INNER_UDP),
  1144. ICE_PKT_PROFILE(ipv6_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
  1145. ICE_PKT_OUTER_IPV6 |
  1146. ICE_PKT_INNER_IPV6),
  1147. ICE_PKT_PROFILE(ipv6_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
  1148. ICE_PKT_OUTER_IPV6 |
  1149. ICE_PKT_INNER_UDP),
  1150. ICE_PKT_PROFILE(ipv6_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU |
  1151. ICE_PKT_OUTER_IPV6),
  1152. ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPU | ICE_PKT_GTP_NOPAY),
  1153. ICE_PKT_PROFILE(ipv4_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
  1154. ICE_PKT_INNER_IPV6 |
  1155. ICE_PKT_INNER_UDP),
  1156. ICE_PKT_PROFILE(ipv4_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
  1157. ICE_PKT_INNER_IPV6),
  1158. ICE_PKT_PROFILE(ipv4_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
  1159. ICE_PKT_INNER_UDP),
  1160. ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
  1161. ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
  1162. ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC),
  1163. ICE_PKT_PROFILE(pfcp_session_ipv6, ICE_PKT_PFCP | ICE_PKT_OUTER_IPV6),
  1164. ICE_PKT_PROFILE(pfcp_session_ipv4, ICE_PKT_PFCP),
  1165. ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 |
  1166. ICE_PKT_INNER_UDP),
  1167. ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6),
  1168. ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP),
  1169. ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE),
  1170. ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 |
  1171. ICE_PKT_INNER_TCP),
  1172. ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP),
  1173. ICE_PKT_PROFILE(gre_ipv6_udp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6),
  1174. ICE_PKT_PROFILE(gre_udp, ICE_PKT_TUN_NVGRE),
  1175. ICE_PKT_PROFILE(udp_tun_ipv6_tcp, ICE_PKT_TUN_UDP |
  1176. ICE_PKT_INNER_IPV6 |
  1177. ICE_PKT_INNER_TCP),
  1178. ICE_PKT_PROFILE(ipv6_l2tpv3, ICE_PKT_L2TPV3 | ICE_PKT_OUTER_IPV6),
  1179. ICE_PKT_PROFILE(ipv4_l2tpv3, ICE_PKT_L2TPV3),
  1180. ICE_PKT_PROFILE(udp_tun_tcp, ICE_PKT_TUN_UDP | ICE_PKT_INNER_TCP),
  1181. ICE_PKT_PROFILE(udp_tun_ipv6_udp, ICE_PKT_TUN_UDP |
  1182. ICE_PKT_INNER_IPV6),
  1183. ICE_PKT_PROFILE(udp_tun_udp, ICE_PKT_TUN_UDP),
  1184. ICE_PKT_PROFILE(udp_ipv6, ICE_PKT_OUTER_IPV6 | ICE_PKT_INNER_UDP),
  1185. ICE_PKT_PROFILE(udp, ICE_PKT_INNER_UDP),
  1186. ICE_PKT_PROFILE(tcp_ipv6, ICE_PKT_OUTER_IPV6),
  1187. ICE_PKT_PROFILE(tcp, 0),
  1188. };
  1189. /* this is a recipe to profile association bitmap */
  1190. static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES],
  1191. ICE_MAX_NUM_PROFILES);
  1192. /* this is a profile to recipe association bitmap */
  1193. static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES],
  1194. ICE_MAX_NUM_RECIPES);
  1195. /**
  1196. * ice_init_def_sw_recp - initialize the recipe book keeping tables
  1197. * @hw: pointer to the HW struct
  1198. *
  1199. * Allocate memory for the entire recipe table and initialize the structures/
  1200. * entries corresponding to basic recipes.
  1201. */
  1202. int ice_init_def_sw_recp(struct ice_hw *hw)
  1203. {
  1204. struct ice_sw_recipe *recps;
  1205. u8 i;
  1206. recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
  1207. sizeof(*recps), GFP_KERNEL);
  1208. if (!recps)
  1209. return -ENOMEM;
  1210. for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
  1211. recps[i].root_rid = i;
  1212. INIT_LIST_HEAD(&recps[i].filt_rules);
  1213. INIT_LIST_HEAD(&recps[i].filt_replay_rules);
  1214. mutex_init(&recps[i].filt_rule_lock);
  1215. }
  1216. hw->switch_info->recp_list = recps;
  1217. return 0;
  1218. }
  1219. /**
  1220. * ice_aq_get_sw_cfg - get switch configuration
  1221. * @hw: pointer to the hardware structure
  1222. * @buf: pointer to the result buffer
  1223. * @buf_size: length of the buffer available for response
  1224. * @req_desc: pointer to requested descriptor
  1225. * @num_elems: pointer to number of elements
  1226. * @cd: pointer to command details structure or NULL
  1227. *
  1228. * Get switch configuration (0x0200) to be placed in buf.
  1229. * This admin command returns information such as initial VSI/port number
  1230. * and switch ID it belongs to.
  1231. *
  1232. * NOTE: *req_desc is both an input/output parameter.
  1233. * The caller of this function first calls this function with *request_desc set
  1234. * to 0. If the response from f/w has *req_desc set to 0, all the switch
  1235. * configuration information has been returned; if non-zero (meaning not all
  1236. * the information was returned), the caller should call this function again
  1237. * with *req_desc set to the previous value returned by f/w to get the
  1238. * next block of switch configuration information.
  1239. *
  1240. * *num_elems is output only parameter. This reflects the number of elements
  1241. * in response buffer. The caller of this function to use *num_elems while
  1242. * parsing the response buffer.
  1243. */
  1244. static int
  1245. ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
  1246. u16 buf_size, u16 *req_desc, u16 *num_elems,
  1247. struct ice_sq_cd *cd)
  1248. {
  1249. struct ice_aqc_get_sw_cfg *cmd;
  1250. struct ice_aq_desc desc;
  1251. int status;
  1252. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
  1253. cmd = &desc.params.get_sw_conf;
  1254. cmd->element = cpu_to_le16(*req_desc);
  1255. status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
  1256. if (!status) {
  1257. *req_desc = le16_to_cpu(cmd->element);
  1258. *num_elems = le16_to_cpu(cmd->num_elems);
  1259. }
  1260. return status;
  1261. }
  1262. /**
  1263. * ice_aq_add_vsi
  1264. * @hw: pointer to the HW struct
  1265. * @vsi_ctx: pointer to a VSI context struct
  1266. * @cd: pointer to command details structure or NULL
  1267. *
  1268. * Add a VSI context to the hardware (0x0210)
  1269. */
  1270. static int
  1271. ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
  1272. struct ice_sq_cd *cd)
  1273. {
  1274. struct ice_aqc_add_update_free_vsi_resp *res;
  1275. struct ice_aqc_add_get_update_free_vsi *cmd;
  1276. struct ice_aq_desc desc;
  1277. int status;
  1278. cmd = &desc.params.vsi_cmd;
  1279. res = &desc.params.add_update_free_vsi_res;
  1280. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
  1281. if (!vsi_ctx->alloc_from_pool)
  1282. cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num |
  1283. ICE_AQ_VSI_IS_VALID);
  1284. cmd->vf_id = vsi_ctx->vf_num;
  1285. cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
  1286. desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
  1287. status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
  1288. sizeof(vsi_ctx->info), cd);
  1289. if (!status) {
  1290. vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M;
  1291. vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used);
  1292. vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free);
  1293. }
  1294. return status;
  1295. }
  1296. /**
  1297. * ice_aq_free_vsi
  1298. * @hw: pointer to the HW struct
  1299. * @vsi_ctx: pointer to a VSI context struct
  1300. * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
  1301. * @cd: pointer to command details structure or NULL
  1302. *
  1303. * Free VSI context info from hardware (0x0213)
  1304. */
  1305. static int
  1306. ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
  1307. bool keep_vsi_alloc, struct ice_sq_cd *cd)
  1308. {
  1309. struct ice_aqc_add_update_free_vsi_resp *resp;
  1310. struct ice_aqc_add_get_update_free_vsi *cmd;
  1311. struct ice_aq_desc desc;
  1312. int status;
  1313. cmd = &desc.params.vsi_cmd;
  1314. resp = &desc.params.add_update_free_vsi_res;
  1315. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
  1316. cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
  1317. if (keep_vsi_alloc)
  1318. cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);
  1319. status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
  1320. if (!status) {
  1321. vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
  1322. vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
  1323. }
  1324. return status;
  1325. }
  1326. /**
  1327. * ice_aq_update_vsi
  1328. * @hw: pointer to the HW struct
  1329. * @vsi_ctx: pointer to a VSI context struct
  1330. * @cd: pointer to command details structure or NULL
  1331. *
  1332. * Update VSI context in the hardware (0x0211)
  1333. */
  1334. static int
  1335. ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
  1336. struct ice_sq_cd *cd)
  1337. {
  1338. struct ice_aqc_add_update_free_vsi_resp *resp;
  1339. struct ice_aqc_add_get_update_free_vsi *cmd;
  1340. struct ice_aq_desc desc;
  1341. int status;
  1342. cmd = &desc.params.vsi_cmd;
  1343. resp = &desc.params.add_update_free_vsi_res;
  1344. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
  1345. cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
  1346. desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
  1347. status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
  1348. sizeof(vsi_ctx->info), cd);
  1349. if (!status) {
  1350. vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
  1351. vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
  1352. }
  1353. return status;
  1354. }
  1355. /**
  1356. * ice_is_vsi_valid - check whether the VSI is valid or not
  1357. * @hw: pointer to the HW struct
  1358. * @vsi_handle: VSI handle
  1359. *
  1360. * check whether the VSI is valid or not
  1361. */
  1362. bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
  1363. {
  1364. return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
  1365. }
  1366. /**
  1367. * ice_get_hw_vsi_num - return the HW VSI number
  1368. * @hw: pointer to the HW struct
  1369. * @vsi_handle: VSI handle
  1370. *
  1371. * return the HW VSI number
  1372. * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
  1373. */
  1374. u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
  1375. {
  1376. return hw->vsi_ctx[vsi_handle]->vsi_num;
  1377. }
  1378. /**
  1379. * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
  1380. * @hw: pointer to the HW struct
  1381. * @vsi_handle: VSI handle
  1382. *
  1383. * return the VSI context entry for a given VSI handle
  1384. */
  1385. struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
  1386. {
  1387. return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
  1388. }
  1389. /**
  1390. * ice_save_vsi_ctx - save the VSI context for a given VSI handle
  1391. * @hw: pointer to the HW struct
  1392. * @vsi_handle: VSI handle
  1393. * @vsi: VSI context pointer
  1394. *
  1395. * save the VSI context entry for a given VSI handle
  1396. */
  1397. static void
  1398. ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
  1399. {
  1400. hw->vsi_ctx[vsi_handle] = vsi;
  1401. }
  1402. /**
  1403. * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
  1404. * @hw: pointer to the HW struct
  1405. * @vsi_handle: VSI handle
  1406. */
  1407. static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
  1408. {
  1409. struct ice_vsi_ctx *vsi = ice_get_vsi_ctx(hw, vsi_handle);
  1410. u8 i;
  1411. if (!vsi)
  1412. return;
  1413. ice_for_each_traffic_class(i) {
  1414. devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]);
  1415. vsi->lan_q_ctx[i] = NULL;
  1416. devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]);
  1417. vsi->rdma_q_ctx[i] = NULL;
  1418. }
  1419. }
  1420. /**
  1421. * ice_clear_vsi_ctx - clear the VSI context entry
  1422. * @hw: pointer to the HW struct
  1423. * @vsi_handle: VSI handle
  1424. *
  1425. * clear the VSI context entry
  1426. */
  1427. static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
  1428. {
  1429. struct ice_vsi_ctx *vsi;
  1430. vsi = ice_get_vsi_ctx(hw, vsi_handle);
  1431. if (vsi) {
  1432. ice_clear_vsi_q_ctx(hw, vsi_handle);
  1433. devm_kfree(ice_hw_to_dev(hw), vsi);
  1434. hw->vsi_ctx[vsi_handle] = NULL;
  1435. }
  1436. }
  1437. /**
  1438. * ice_clear_all_vsi_ctx - clear all the VSI context entries
  1439. * @hw: pointer to the HW struct
  1440. */
  1441. void ice_clear_all_vsi_ctx(struct ice_hw *hw)
  1442. {
  1443. u16 i;
  1444. for (i = 0; i < ICE_MAX_VSI; i++)
  1445. ice_clear_vsi_ctx(hw, i);
  1446. }
  1447. /**
  1448. * ice_add_vsi - add VSI context to the hardware and VSI handle list
  1449. * @hw: pointer to the HW struct
  1450. * @vsi_handle: unique VSI handle provided by drivers
  1451. * @vsi_ctx: pointer to a VSI context struct
  1452. * @cd: pointer to command details structure or NULL
  1453. *
  1454. * Add a VSI context to the hardware also add it into the VSI handle list.
  1455. * If this function gets called after reset for existing VSIs then update
  1456. * with the new HW VSI number in the corresponding VSI handle list entry.
  1457. */
  1458. int
  1459. ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
  1460. struct ice_sq_cd *cd)
  1461. {
  1462. struct ice_vsi_ctx *tmp_vsi_ctx;
  1463. int status;
  1464. if (vsi_handle >= ICE_MAX_VSI)
  1465. return -EINVAL;
  1466. status = ice_aq_add_vsi(hw, vsi_ctx, cd);
  1467. if (status)
  1468. return status;
  1469. tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
  1470. if (!tmp_vsi_ctx) {
  1471. /* Create a new VSI context */
  1472. tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
  1473. sizeof(*tmp_vsi_ctx), GFP_KERNEL);
  1474. if (!tmp_vsi_ctx) {
  1475. ice_aq_free_vsi(hw, vsi_ctx, false, cd);
  1476. return -ENOMEM;
  1477. }
  1478. *tmp_vsi_ctx = *vsi_ctx;
  1479. ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
  1480. } else {
  1481. /* update with new HW VSI num */
  1482. tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
  1483. }
  1484. return 0;
  1485. }
  1486. /**
  1487. * ice_free_vsi- free VSI context from hardware and VSI handle list
  1488. * @hw: pointer to the HW struct
  1489. * @vsi_handle: unique VSI handle
  1490. * @vsi_ctx: pointer to a VSI context struct
  1491. * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
  1492. * @cd: pointer to command details structure or NULL
  1493. *
  1494. * Free VSI context info from hardware as well as from VSI handle list
  1495. */
  1496. int
  1497. ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
  1498. bool keep_vsi_alloc, struct ice_sq_cd *cd)
  1499. {
  1500. int status;
  1501. if (!ice_is_vsi_valid(hw, vsi_handle))
  1502. return -EINVAL;
  1503. vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
  1504. status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
  1505. if (!status)
  1506. ice_clear_vsi_ctx(hw, vsi_handle);
  1507. return status;
  1508. }
  1509. /**
  1510. * ice_update_vsi
  1511. * @hw: pointer to the HW struct
  1512. * @vsi_handle: unique VSI handle
  1513. * @vsi_ctx: pointer to a VSI context struct
  1514. * @cd: pointer to command details structure or NULL
  1515. *
  1516. * Update VSI context in the hardware
  1517. */
  1518. int
  1519. ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
  1520. struct ice_sq_cd *cd)
  1521. {
  1522. if (!ice_is_vsi_valid(hw, vsi_handle))
  1523. return -EINVAL;
  1524. vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
  1525. return ice_aq_update_vsi(hw, vsi_ctx, cd);
  1526. }
  1527. /**
  1528. * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI
  1529. * @hw: pointer to HW struct
  1530. * @vsi_handle: VSI SW index
  1531. * @enable: boolean for enable/disable
  1532. */
  1533. int
  1534. ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
  1535. {
  1536. struct ice_vsi_ctx *ctx, *cached_ctx;
  1537. int status;
  1538. cached_ctx = ice_get_vsi_ctx(hw, vsi_handle);
  1539. if (!cached_ctx)
  1540. return -ENOENT;
  1541. ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
  1542. if (!ctx)
  1543. return -ENOMEM;
  1544. ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss;
  1545. ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc;
  1546. ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags;
  1547. ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
  1548. if (enable)
  1549. ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
  1550. else
  1551. ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
  1552. status = ice_update_vsi(hw, vsi_handle, ctx, NULL);
  1553. if (!status) {
  1554. cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags;
  1555. cached_ctx->info.valid_sections |= ctx->info.valid_sections;
  1556. }
  1557. kfree(ctx);
  1558. return status;
  1559. }
  1560. /**
  1561. * ice_aq_alloc_free_vsi_list
  1562. * @hw: pointer to the HW struct
  1563. * @vsi_list_id: VSI list ID returned or used for lookup
  1564. * @lkup_type: switch rule filter lookup type
  1565. * @opc: switch rules population command type - pass in the command opcode
  1566. *
  1567. * allocates or free a VSI list resource
  1568. */
  1569. static int
  1570. ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
  1571. enum ice_sw_lkup_type lkup_type,
  1572. enum ice_adminq_opc opc)
  1573. {
  1574. DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
  1575. u16 buf_len = __struct_size(sw_buf);
  1576. struct ice_aqc_res_elem *vsi_ele;
  1577. int status;
  1578. sw_buf->num_elems = cpu_to_le16(1);
  1579. if (lkup_type == ICE_SW_LKUP_MAC ||
  1580. lkup_type == ICE_SW_LKUP_MAC_VLAN ||
  1581. lkup_type == ICE_SW_LKUP_ETHERTYPE ||
  1582. lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
  1583. lkup_type == ICE_SW_LKUP_PROMISC ||
  1584. lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
  1585. lkup_type == ICE_SW_LKUP_DFLT ||
  1586. lkup_type == ICE_SW_LKUP_LAST) {
  1587. sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
  1588. } else if (lkup_type == ICE_SW_LKUP_VLAN) {
  1589. if (opc == ice_aqc_opc_alloc_res)
  1590. sw_buf->res_type =
  1591. cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE |
  1592. ICE_AQC_RES_TYPE_FLAG_SHARED);
  1593. else
  1594. sw_buf->res_type =
  1595. cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
  1596. } else {
  1597. return -EINVAL;
  1598. }
  1599. if (opc == ice_aqc_opc_free_res)
  1600. sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);
  1601. status = ice_aq_alloc_free_res(hw, sw_buf, buf_len, opc);
  1602. if (status)
  1603. return status;
  1604. if (opc == ice_aqc_opc_alloc_res) {
  1605. vsi_ele = &sw_buf->elem[0];
  1606. *vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp);
  1607. }
  1608. return 0;
  1609. }
  1610. /**
  1611. * ice_aq_sw_rules - add/update/remove switch rules
  1612. * @hw: pointer to the HW struct
  1613. * @rule_list: pointer to switch rule population list
  1614. * @rule_list_sz: total size of the rule list in bytes
  1615. * @num_rules: number of switch rules in the rule_list
  1616. * @opc: switch rules population command type - pass in the command opcode
  1617. * @cd: pointer to command details structure or NULL
  1618. *
  1619. * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
  1620. */
  1621. int
  1622. ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
  1623. u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
  1624. {
  1625. struct ice_aq_desc desc;
  1626. int status;
  1627. if (opc != ice_aqc_opc_add_sw_rules &&
  1628. opc != ice_aqc_opc_update_sw_rules &&
  1629. opc != ice_aqc_opc_remove_sw_rules)
  1630. return -EINVAL;
  1631. ice_fill_dflt_direct_cmd_desc(&desc, opc);
  1632. desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
  1633. desc.params.sw_rules.num_rules_fltr_entry_index =
  1634. cpu_to_le16(num_rules);
  1635. status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
  1636. if (opc != ice_aqc_opc_add_sw_rules &&
  1637. hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
  1638. status = -ENOENT;
  1639. if (!status) {
  1640. if (opc == ice_aqc_opc_add_sw_rules)
  1641. hw->switch_info->rule_cnt += num_rules;
  1642. else if (opc == ice_aqc_opc_remove_sw_rules)
  1643. hw->switch_info->rule_cnt -= num_rules;
  1644. }
  1645. trace_ice_aq_sw_rules(hw->switch_info);
  1646. return status;
  1647. }
  1648. /**
  1649. * ice_aq_add_recipe - add switch recipe
  1650. * @hw: pointer to the HW struct
  1651. * @s_recipe_list: pointer to switch rule population list
  1652. * @num_recipes: number of switch recipes in the list
  1653. * @cd: pointer to command details structure or NULL
  1654. *
  1655. * Add(0x0290)
  1656. */
  1657. int
  1658. ice_aq_add_recipe(struct ice_hw *hw,
  1659. struct ice_aqc_recipe_data_elem *s_recipe_list,
  1660. u16 num_recipes, struct ice_sq_cd *cd)
  1661. {
  1662. struct ice_aqc_add_get_recipe *cmd;
  1663. struct ice_aq_desc desc;
  1664. u16 buf_size;
  1665. cmd = &desc.params.add_get_recipe;
  1666. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
  1667. cmd->num_sub_recipes = cpu_to_le16(num_recipes);
  1668. desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
  1669. buf_size = num_recipes * sizeof(*s_recipe_list);
  1670. return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
  1671. }
  1672. /**
  1673. * ice_aq_get_recipe - get switch recipe
  1674. * @hw: pointer to the HW struct
  1675. * @s_recipe_list: pointer to switch rule population list
  1676. * @num_recipes: pointer to the number of recipes (input and output)
  1677. * @recipe_root: root recipe number of recipe(s) to retrieve
  1678. * @cd: pointer to command details structure or NULL
  1679. *
  1680. * Get(0x0292)
  1681. *
  1682. * On input, *num_recipes should equal the number of entries in s_recipe_list.
  1683. * On output, *num_recipes will equal the number of entries returned in
  1684. * s_recipe_list.
  1685. *
  1686. * The caller must supply enough space in s_recipe_list to hold all possible
  1687. * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
  1688. */
  1689. int
  1690. ice_aq_get_recipe(struct ice_hw *hw,
  1691. struct ice_aqc_recipe_data_elem *s_recipe_list,
  1692. u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
  1693. {
  1694. struct ice_aqc_add_get_recipe *cmd;
  1695. struct ice_aq_desc desc;
  1696. u16 buf_size;
  1697. int status;
  1698. if (*num_recipes != ICE_MAX_NUM_RECIPES)
  1699. return -EINVAL;
  1700. cmd = &desc.params.add_get_recipe;
  1701. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
  1702. cmd->return_index = cpu_to_le16(recipe_root);
  1703. cmd->num_sub_recipes = 0;
  1704. buf_size = *num_recipes * sizeof(*s_recipe_list);
  1705. status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
  1706. *num_recipes = le16_to_cpu(cmd->num_sub_recipes);
  1707. return status;
  1708. }
  1709. /**
  1710. * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
  1711. * @hw: pointer to the HW struct
  1712. * @params: parameters used to update the default recipe
  1713. *
  1714. * This function only supports updating default recipes and it only supports
  1715. * updating a single recipe based on the lkup_idx at a time.
  1716. *
  1717. * This is done as a read-modify-write operation. First, get the current recipe
  1718. * contents based on the recipe's ID. Then modify the field vector index and
  1719. * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
  1720. * the pre-existing recipe with the modifications.
  1721. */
  1722. int
  1723. ice_update_recipe_lkup_idx(struct ice_hw *hw,
  1724. struct ice_update_recipe_lkup_idx_params *params)
  1725. {
  1726. struct ice_aqc_recipe_data_elem *rcp_list;
  1727. u16 num_recps = ICE_MAX_NUM_RECIPES;
  1728. int status;
  1729. rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL);
  1730. if (!rcp_list)
  1731. return -ENOMEM;
  1732. /* read current recipe list from firmware */
  1733. rcp_list->recipe_indx = params->rid;
  1734. status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
  1735. if (status) {
  1736. ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
  1737. params->rid, status);
  1738. goto error_out;
  1739. }
  1740. /* only modify existing recipe's lkup_idx and mask if valid, while
  1741. * leaving all other fields the same, then update the recipe firmware
  1742. */
  1743. rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
  1744. if (params->mask_valid)
  1745. rcp_list->content.mask[params->lkup_idx] =
  1746. cpu_to_le16(params->mask);
  1747. if (params->ignore_valid)
  1748. rcp_list->content.lkup_indx[params->lkup_idx] |=
  1749. ICE_AQ_RECIPE_LKUP_IGNORE;
  1750. status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
  1751. if (status)
  1752. ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n",
  1753. params->rid, params->lkup_idx, params->fv_idx,
  1754. params->mask, params->mask_valid ? "true" : "false",
  1755. status);
  1756. error_out:
  1757. kfree(rcp_list);
  1758. return status;
  1759. }
  1760. /**
  1761. * ice_aq_map_recipe_to_profile - Map recipe to packet profile
  1762. * @hw: pointer to the HW struct
  1763. * @profile_id: package profile ID to associate the recipe with
  1764. * @r_assoc: Recipe bitmap filled in and need to be returned as response
  1765. * @cd: pointer to command details structure or NULL
  1766. * Recipe to profile association (0x0291)
  1767. */
  1768. int
  1769. ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 r_assoc,
  1770. struct ice_sq_cd *cd)
  1771. {
  1772. struct ice_aqc_recipe_to_profile *cmd;
  1773. struct ice_aq_desc desc;
  1774. cmd = &desc.params.recipe_to_profile;
  1775. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
  1776. cmd->profile_id = cpu_to_le16(profile_id);
  1777. /* Set the recipe ID bit in the bitmask to let the device know which
  1778. * profile we are associating the recipe to
  1779. */
  1780. cmd->recipe_assoc = cpu_to_le64(r_assoc);
  1781. return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
  1782. }
  1783. /**
  1784. * ice_aq_get_recipe_to_profile - Map recipe to packet profile
  1785. * @hw: pointer to the HW struct
  1786. * @profile_id: package profile ID to associate the recipe with
  1787. * @r_assoc: Recipe bitmap filled in and need to be returned as response
  1788. * @cd: pointer to command details structure or NULL
  1789. * Associate profile ID with given recipe (0x0293)
  1790. */
  1791. int
  1792. ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 *r_assoc,
  1793. struct ice_sq_cd *cd)
  1794. {
  1795. struct ice_aqc_recipe_to_profile *cmd;
  1796. struct ice_aq_desc desc;
  1797. int status;
  1798. cmd = &desc.params.recipe_to_profile;
  1799. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
  1800. cmd->profile_id = cpu_to_le16(profile_id);
  1801. status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
  1802. if (!status)
  1803. *r_assoc = le64_to_cpu(cmd->recipe_assoc);
  1804. return status;
  1805. }
  1806. /**
  1807. * ice_init_chk_recipe_reuse_support - check if recipe reuse is supported
  1808. * @hw: pointer to the hardware structure
  1809. */
  1810. void ice_init_chk_recipe_reuse_support(struct ice_hw *hw)
  1811. {
  1812. struct ice_nvm_info *nvm = &hw->flash.nvm;
  1813. hw->recp_reuse = (nvm->major == 0x4 && nvm->minor >= 0x30) ||
  1814. nvm->major > 0x4;
  1815. }
  1816. /**
  1817. * ice_alloc_recipe - add recipe resource
  1818. * @hw: pointer to the hardware structure
  1819. * @rid: recipe ID returned as response to AQ call
  1820. */
  1821. int ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
  1822. {
  1823. DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
  1824. u16 buf_len = __struct_size(sw_buf);
  1825. u16 res_type;
  1826. int status;
  1827. sw_buf->num_elems = cpu_to_le16(1);
  1828. res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, ICE_AQC_RES_TYPE_RECIPE);
  1829. if (hw->recp_reuse)
  1830. res_type |= ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_SHARED;
  1831. else
  1832. res_type |= ICE_AQC_RES_TYPE_FLAG_SHARED;
  1833. sw_buf->res_type = cpu_to_le16(res_type);
  1834. status = ice_aq_alloc_free_res(hw, sw_buf, buf_len,
  1835. ice_aqc_opc_alloc_res);
  1836. if (!status) {
  1837. *rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp);
  1838. hw->switch_info->recp_cnt++;
  1839. }
  1840. return status;
  1841. }
  1842. /**
  1843. * ice_free_recipe_res - free recipe resource
  1844. * @hw: pointer to the hardware structure
  1845. * @rid: recipe ID to free
  1846. *
  1847. * Return: 0 on success, and others on error
  1848. */
  1849. static int ice_free_recipe_res(struct ice_hw *hw, u16 rid)
  1850. {
  1851. int status;
  1852. status = ice_free_hw_res(hw, ICE_AQC_RES_TYPE_RECIPE, 1, &rid);
  1853. if (!status)
  1854. hw->switch_info->recp_cnt--;
  1855. return status;
  1856. }
  1857. /**
  1858. * ice_release_recipe_res - disassociate and free recipe resource
  1859. * @hw: pointer to the hardware structure
  1860. * @recp: the recipe struct resource to unassociate and free
  1861. *
  1862. * Return: 0 on success, and others on error
  1863. */
  1864. static int ice_release_recipe_res(struct ice_hw *hw,
  1865. struct ice_sw_recipe *recp)
  1866. {
  1867. DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
  1868. struct ice_switch_info *sw = hw->switch_info;
  1869. u64 recp_assoc;
  1870. u32 rid, prof;
  1871. int status;
  1872. for_each_set_bit(rid, recp->r_bitmap, ICE_MAX_NUM_RECIPES) {
  1873. for_each_set_bit(prof, recipe_to_profile[rid],
  1874. ICE_MAX_NUM_PROFILES) {
  1875. status = ice_aq_get_recipe_to_profile(hw, prof,
  1876. &recp_assoc,
  1877. NULL);
  1878. if (status)
  1879. return status;
  1880. bitmap_from_arr64(r_bitmap, &recp_assoc,
  1881. ICE_MAX_NUM_RECIPES);
  1882. bitmap_andnot(r_bitmap, r_bitmap, recp->r_bitmap,
  1883. ICE_MAX_NUM_RECIPES);
  1884. bitmap_to_arr64(&recp_assoc, r_bitmap,
  1885. ICE_MAX_NUM_RECIPES);
  1886. ice_aq_map_recipe_to_profile(hw, prof,
  1887. recp_assoc, NULL);
  1888. clear_bit(rid, profile_to_recipe[prof]);
  1889. clear_bit(prof, recipe_to_profile[rid]);
  1890. }
  1891. status = ice_free_recipe_res(hw, rid);
  1892. if (status)
  1893. return status;
  1894. sw->recp_list[rid].recp_created = false;
  1895. sw->recp_list[rid].adv_rule = false;
  1896. memset(&sw->recp_list[rid].lkup_exts, 0,
  1897. sizeof(sw->recp_list[rid].lkup_exts));
  1898. clear_bit(rid, recp->r_bitmap);
  1899. }
  1900. return 0;
  1901. }
  1902. /**
  1903. * ice_get_recp_to_prof_map - updates recipe to profile mapping
  1904. * @hw: pointer to hardware structure
  1905. *
  1906. * This function is used to populate recipe_to_profile matrix where index to
  1907. * this array is the recipe ID and the element is the mapping of which profiles
  1908. * is this recipe mapped to.
  1909. */
  1910. static void ice_get_recp_to_prof_map(struct ice_hw *hw)
  1911. {
  1912. DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
  1913. u64 recp_assoc;
  1914. u16 i;
  1915. for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
  1916. u16 j;
  1917. bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
  1918. bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES);
  1919. if (ice_aq_get_recipe_to_profile(hw, i, &recp_assoc, NULL))
  1920. continue;
  1921. bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
  1922. bitmap_copy(profile_to_recipe[i], r_bitmap,
  1923. ICE_MAX_NUM_RECIPES);
  1924. for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
  1925. set_bit(i, recipe_to_profile[j]);
  1926. }
  1927. }
  1928. /**
  1929. * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
  1930. * @hw: pointer to hardware structure
  1931. * @recps: struct that we need to populate
  1932. * @rid: recipe ID that we are populating
  1933. * @refresh_required: true if we should get recipe to profile mapping from FW
  1934. * @is_add: flag of adding recipe
  1935. *
  1936. * This function is used to populate all the necessary entries into our
  1937. * bookkeeping so that we have a current list of all the recipes that are
  1938. * programmed in the firmware.
  1939. */
  1940. static int
  1941. ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
  1942. bool *refresh_required, bool is_add)
  1943. {
  1944. DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS);
  1945. struct ice_aqc_recipe_data_elem *tmp;
  1946. u16 num_recps = ICE_MAX_NUM_RECIPES;
  1947. struct ice_prot_lkup_ext *lkup_exts;
  1948. u8 fv_word_idx = 0;
  1949. u16 sub_recps;
  1950. int status;
  1951. bitmap_zero(result_bm, ICE_MAX_FV_WORDS);
  1952. /* we need a buffer big enough to accommodate all the recipes */
  1953. tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
  1954. if (!tmp)
  1955. return -ENOMEM;
  1956. tmp[0].recipe_indx = rid;
  1957. status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
  1958. /* non-zero status meaning recipe doesn't exist */
  1959. if (status)
  1960. goto err_unroll;
  1961. /* Get recipe to profile map so that we can get the fv from lkups that
  1962. * we read for a recipe from FW. Since we want to minimize the number of
  1963. * times we make this FW call, just make one call and cache the copy
  1964. * until a new recipe is added. This operation is only required the
  1965. * first time to get the changes from FW. Then to search existing
  1966. * entries we don't need to update the cache again until another recipe
  1967. * gets added.
  1968. */
  1969. if (*refresh_required) {
  1970. ice_get_recp_to_prof_map(hw);
  1971. *refresh_required = false;
  1972. }
  1973. /* Start populating all the entries for recps[rid] based on lkups from
  1974. * firmware. Note that we are only creating the root recipe in our
  1975. * database.
  1976. */
  1977. lkup_exts = &recps[rid].lkup_exts;
  1978. for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
  1979. struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
  1980. u8 i, prof, idx, prot = 0;
  1981. bool is_root;
  1982. u16 off = 0;
  1983. idx = root_bufs.recipe_indx;
  1984. is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
  1985. /* Mark all result indices in this chain */
  1986. if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
  1987. set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
  1988. result_bm);
  1989. /* get the first profile that is associated with rid */
  1990. prof = find_first_bit(recipe_to_profile[idx],
  1991. ICE_MAX_NUM_PROFILES);
  1992. for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
  1993. u8 lkup_indx = root_bufs.content.lkup_indx[i];
  1994. u16 lkup_mask = le16_to_cpu(root_bufs.content.mask[i]);
  1995. /* If the recipe is a chained recipe then all its
  1996. * child recipe's result will have a result index.
  1997. * To fill fv_words we should not use those result
  1998. * index, we only need the protocol ids and offsets.
  1999. * We will skip all the fv_idx which stores result
  2000. * index in them. We also need to skip any fv_idx which
  2001. * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
  2002. * valid offset value.
  2003. */
  2004. if (!lkup_indx ||
  2005. (lkup_indx & ICE_AQ_RECIPE_LKUP_IGNORE) ||
  2006. test_bit(lkup_indx,
  2007. hw->switch_info->prof_res_bm[prof]))
  2008. continue;
  2009. ice_find_prot_off(hw, ICE_BLK_SW, prof, lkup_indx,
  2010. &prot, &off);
  2011. lkup_exts->fv_words[fv_word_idx].prot_id = prot;
  2012. lkup_exts->fv_words[fv_word_idx].off = off;
  2013. lkup_exts->field_mask[fv_word_idx] = lkup_mask;
  2014. fv_word_idx++;
  2015. }
  2016. /* Propagate some data to the recipe database */
  2017. recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
  2018. recps[idx].need_pass_l2 = !!(root_bufs.content.act_ctrl &
  2019. ICE_AQ_RECIPE_ACT_NEED_PASS_L2);
  2020. recps[idx].allow_pass_l2 = !!(root_bufs.content.act_ctrl &
  2021. ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2);
  2022. bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
  2023. if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
  2024. set_bit(root_bufs.content.result_indx &
  2025. ~ICE_AQ_RECIPE_RESULT_EN, recps[idx].res_idxs);
  2026. }
  2027. if (!is_root) {
  2028. if (hw->recp_reuse && is_add)
  2029. recps[idx].recp_created = true;
  2030. continue;
  2031. }
  2032. /* Only do the following for root recipes entries */
  2033. memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
  2034. sizeof(recps[idx].r_bitmap));
  2035. recps[idx].root_rid = root_bufs.content.rid &
  2036. ~ICE_AQ_RECIPE_ID_IS_ROOT;
  2037. recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
  2038. }
  2039. /* Complete initialization of the root recipe entry */
  2040. lkup_exts->n_val_words = fv_word_idx;
  2041. /* Copy result indexes */
  2042. bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
  2043. if (is_add)
  2044. recps[rid].recp_created = true;
  2045. err_unroll:
  2046. kfree(tmp);
  2047. return status;
  2048. }
  2049. /* ice_init_port_info - Initialize port_info with switch configuration data
  2050. * @pi: pointer to port_info
  2051. * @vsi_port_num: VSI number or port number
  2052. * @type: Type of switch element (port or VSI)
  2053. * @swid: switch ID of the switch the element is attached to
  2054. * @pf_vf_num: PF or VF number
  2055. * @is_vf: true if the element is a VF, false otherwise
  2056. */
  2057. static void
  2058. ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
  2059. u16 swid, u16 pf_vf_num, bool is_vf)
  2060. {
  2061. switch (type) {
  2062. case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
  2063. pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
  2064. pi->sw_id = swid;
  2065. pi->pf_vf_num = pf_vf_num;
  2066. pi->is_vf = is_vf;
  2067. break;
  2068. default:
  2069. ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
  2070. break;
  2071. }
  2072. }
  2073. /* ice_get_initial_sw_cfg - Get initial port and default VSI data
  2074. * @hw: pointer to the hardware structure
  2075. */
  2076. int ice_get_initial_sw_cfg(struct ice_hw *hw)
  2077. {
  2078. struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
  2079. u16 req_desc = 0;
  2080. u16 num_elems;
  2081. int status;
  2082. u16 i;
  2083. rbuf = kzalloc(ICE_SW_CFG_MAX_BUF_LEN, GFP_KERNEL);
  2084. if (!rbuf)
  2085. return -ENOMEM;
  2086. /* Multiple calls to ice_aq_get_sw_cfg may be required
  2087. * to get all the switch configuration information. The need
  2088. * for additional calls is indicated by ice_aq_get_sw_cfg
  2089. * writing a non-zero value in req_desc
  2090. */
  2091. do {
  2092. struct ice_aqc_get_sw_cfg_resp_elem *ele;
  2093. status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
  2094. &req_desc, &num_elems, NULL);
  2095. if (status)
  2096. break;
  2097. for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
  2098. u16 pf_vf_num, swid, vsi_port_num;
  2099. bool is_vf = false;
  2100. u8 res_type;
  2101. vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
  2102. ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
  2103. pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
  2104. ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
  2105. swid = le16_to_cpu(ele->swid);
  2106. if (le16_to_cpu(ele->pf_vf_num) &
  2107. ICE_AQC_GET_SW_CONF_RESP_IS_VF)
  2108. is_vf = true;
  2109. res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
  2110. ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
  2111. if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
  2112. /* FW VSI is not needed. Just continue. */
  2113. continue;
  2114. }
  2115. ice_init_port_info(hw->port_info, vsi_port_num,
  2116. res_type, swid, pf_vf_num, is_vf);
  2117. }
  2118. } while (req_desc && !status);
  2119. kfree(rbuf);
  2120. return status;
  2121. }
  2122. /**
  2123. * ice_fill_sw_info - Helper function to populate lb_en and lan_en
  2124. * @hw: pointer to the hardware structure
  2125. * @fi: filter info structure to fill/update
  2126. *
  2127. * This helper function populates the lb_en and lan_en elements of the provided
  2128. * ice_fltr_info struct using the switch's type and characteristics of the
  2129. * switch rule being configured.
  2130. */
  2131. static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
  2132. {
  2133. fi->lb_en = false;
  2134. fi->lan_en = false;
  2135. if ((fi->flag & ICE_FLTR_TX) &&
  2136. (fi->fltr_act == ICE_FWD_TO_VSI ||
  2137. fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
  2138. fi->fltr_act == ICE_FWD_TO_Q ||
  2139. fi->fltr_act == ICE_FWD_TO_QGRP)) {
  2140. /* Setting LB for prune actions will result in replicated
  2141. * packets to the internal switch that will be dropped.
  2142. */
  2143. if (fi->lkup_type != ICE_SW_LKUP_VLAN)
  2144. fi->lb_en = true;
  2145. /* Set lan_en to TRUE if
  2146. * 1. The switch is a VEB AND
  2147. * 2
  2148. * 2.1 The lookup is a directional lookup like ethertype,
  2149. * promiscuous, ethertype-MAC, promiscuous-VLAN
  2150. * and default-port OR
  2151. * 2.2 The lookup is VLAN, OR
  2152. * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
  2153. * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
  2154. *
  2155. * OR
  2156. *
  2157. * The switch is a VEPA.
  2158. *
  2159. * In all other cases, the LAN enable has to be set to false.
  2160. */
  2161. if (hw->evb_veb) {
  2162. if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
  2163. fi->lkup_type == ICE_SW_LKUP_PROMISC ||
  2164. fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
  2165. fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
  2166. fi->lkup_type == ICE_SW_LKUP_DFLT ||
  2167. fi->lkup_type == ICE_SW_LKUP_VLAN ||
  2168. (fi->lkup_type == ICE_SW_LKUP_MAC &&
  2169. !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) ||
  2170. (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
  2171. !is_unicast_ether_addr(fi->l_data.mac.mac_addr)))
  2172. fi->lan_en = true;
  2173. } else {
  2174. fi->lan_en = true;
  2175. }
  2176. }
  2177. if (fi->flag & ICE_FLTR_TX_ONLY)
  2178. fi->lan_en = false;
  2179. }
  2180. /**
  2181. * ice_fill_eth_hdr - helper to copy dummy_eth_hdr into supplied buffer
  2182. * @eth_hdr: pointer to buffer to populate
  2183. */
  2184. void ice_fill_eth_hdr(u8 *eth_hdr)
  2185. {
  2186. memcpy(eth_hdr, dummy_eth_header, DUMMY_ETH_HDR_LEN);
  2187. }
  2188. /**
  2189. * ice_fill_sw_rule - Helper function to fill switch rule structure
  2190. * @hw: pointer to the hardware structure
  2191. * @f_info: entry containing packet forwarding information
  2192. * @s_rule: switch rule structure to be filled in based on mac_entry
  2193. * @opc: switch rules population command type - pass in the command opcode
  2194. */
  2195. static void
  2196. ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
  2197. struct ice_sw_rule_lkup_rx_tx *s_rule,
  2198. enum ice_adminq_opc opc)
  2199. {
  2200. u16 vlan_id = ICE_MAX_VLAN_ID + 1;
  2201. u16 vlan_tpid = ETH_P_8021Q;
  2202. void *daddr = NULL;
  2203. u16 eth_hdr_sz;
  2204. u8 *eth_hdr;
  2205. u32 act = 0;
  2206. __be16 *off;
  2207. u8 q_rgn;
  2208. if (opc == ice_aqc_opc_remove_sw_rules) {
  2209. s_rule->act = 0;
  2210. s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
  2211. s_rule->hdr_len = 0;
  2212. return;
  2213. }
  2214. eth_hdr_sz = sizeof(dummy_eth_header);
  2215. eth_hdr = s_rule->hdr_data;
  2216. /* initialize the ether header with a dummy header */
  2217. memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
  2218. ice_fill_sw_info(hw, f_info);
  2219. switch (f_info->fltr_act) {
  2220. case ICE_FWD_TO_VSI:
  2221. act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
  2222. f_info->fwd_id.hw_vsi_id);
  2223. if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
  2224. act |= ICE_SINGLE_ACT_VSI_FORWARDING |
  2225. ICE_SINGLE_ACT_VALID_BIT;
  2226. break;
  2227. case ICE_FWD_TO_VSI_LIST:
  2228. act |= ICE_SINGLE_ACT_VSI_LIST;
  2229. act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_LIST_ID_M,
  2230. f_info->fwd_id.vsi_list_id);
  2231. if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
  2232. act |= ICE_SINGLE_ACT_VSI_FORWARDING |
  2233. ICE_SINGLE_ACT_VALID_BIT;
  2234. break;
  2235. case ICE_FWD_TO_Q:
  2236. act |= ICE_SINGLE_ACT_TO_Q;
  2237. act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
  2238. f_info->fwd_id.q_id);
  2239. break;
  2240. case ICE_DROP_PACKET:
  2241. act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
  2242. ICE_SINGLE_ACT_VALID_BIT;
  2243. break;
  2244. case ICE_FWD_TO_QGRP:
  2245. q_rgn = f_info->qgrp_size > 0 ?
  2246. (u8)ilog2(f_info->qgrp_size) : 0;
  2247. act |= ICE_SINGLE_ACT_TO_Q;
  2248. act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
  2249. f_info->fwd_id.q_id);
  2250. act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
  2251. break;
  2252. default:
  2253. return;
  2254. }
  2255. if (f_info->lb_en)
  2256. act |= ICE_SINGLE_ACT_LB_ENABLE;
  2257. if (f_info->lan_en)
  2258. act |= ICE_SINGLE_ACT_LAN_ENABLE;
  2259. switch (f_info->lkup_type) {
  2260. case ICE_SW_LKUP_MAC:
  2261. daddr = f_info->l_data.mac.mac_addr;
  2262. break;
  2263. case ICE_SW_LKUP_VLAN:
  2264. vlan_id = f_info->l_data.vlan.vlan_id;
  2265. if (f_info->l_data.vlan.tpid_valid)
  2266. vlan_tpid = f_info->l_data.vlan.tpid;
  2267. if (f_info->fltr_act == ICE_FWD_TO_VSI ||
  2268. f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
  2269. act |= ICE_SINGLE_ACT_PRUNE;
  2270. act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
  2271. }
  2272. break;
  2273. case ICE_SW_LKUP_ETHERTYPE_MAC:
  2274. daddr = f_info->l_data.ethertype_mac.mac_addr;
  2275. fallthrough;
  2276. case ICE_SW_LKUP_ETHERTYPE:
  2277. off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
  2278. *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
  2279. break;
  2280. case ICE_SW_LKUP_MAC_VLAN:
  2281. daddr = f_info->l_data.mac_vlan.mac_addr;
  2282. vlan_id = f_info->l_data.mac_vlan.vlan_id;
  2283. break;
  2284. case ICE_SW_LKUP_PROMISC_VLAN:
  2285. vlan_id = f_info->l_data.mac_vlan.vlan_id;
  2286. fallthrough;
  2287. case ICE_SW_LKUP_PROMISC:
  2288. daddr = f_info->l_data.mac_vlan.mac_addr;
  2289. break;
  2290. default:
  2291. break;
  2292. }
  2293. s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ?
  2294. cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
  2295. cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
  2296. /* Recipe set depending on lookup type */
  2297. s_rule->recipe_id = cpu_to_le16(f_info->lkup_type);
  2298. s_rule->src = cpu_to_le16(f_info->src);
  2299. s_rule->act = cpu_to_le32(act);
  2300. if (daddr)
  2301. ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
  2302. if (!(vlan_id > ICE_MAX_VLAN_ID)) {
  2303. off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
  2304. *off = cpu_to_be16(vlan_id);
  2305. off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
  2306. *off = cpu_to_be16(vlan_tpid);
  2307. }
  2308. /* Create the switch rule with the final dummy Ethernet header */
  2309. if (opc != ice_aqc_opc_update_sw_rules)
  2310. s_rule->hdr_len = cpu_to_le16(eth_hdr_sz);
  2311. }
  2312. /**
  2313. * ice_add_marker_act
  2314. * @hw: pointer to the hardware structure
  2315. * @m_ent: the management entry for which sw marker needs to be added
  2316. * @sw_marker: sw marker to tag the Rx descriptor with
  2317. * @l_id: large action resource ID
  2318. *
  2319. * Create a large action to hold software marker and update the switch rule
  2320. * entry pointed by m_ent with newly created large action
  2321. */
  2322. static int
  2323. ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
  2324. u16 sw_marker, u16 l_id)
  2325. {
  2326. struct ice_sw_rule_lkup_rx_tx *rx_tx;
  2327. struct ice_sw_rule_lg_act *lg_act;
  2328. /* For software marker we need 3 large actions
  2329. * 1. FWD action: FWD TO VSI or VSI LIST
  2330. * 2. GENERIC VALUE action to hold the profile ID
  2331. * 3. GENERIC VALUE action to hold the software marker ID
  2332. */
  2333. const u16 num_lg_acts = 3;
  2334. u16 lg_act_size;
  2335. u16 rules_size;
  2336. int status;
  2337. u32 act;
  2338. u16 id;
  2339. if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
  2340. return -EINVAL;
  2341. /* Create two back-to-back switch rules and submit them to the HW using
  2342. * one memory buffer:
  2343. * 1. Large Action
  2344. * 2. Look up Tx Rx
  2345. */
  2346. lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(lg_act, num_lg_acts);
  2347. rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(rx_tx);
  2348. lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
  2349. if (!lg_act)
  2350. return -ENOMEM;
  2351. rx_tx = (typeof(rx_tx))((u8 *)lg_act + lg_act_size);
  2352. /* Fill in the first switch rule i.e. large action */
  2353. lg_act->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
  2354. lg_act->index = cpu_to_le16(l_id);
  2355. lg_act->size = cpu_to_le16(num_lg_acts);
  2356. /* First action VSI forwarding or VSI list forwarding depending on how
  2357. * many VSIs
  2358. */
  2359. id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
  2360. m_ent->fltr_info.fwd_id.hw_vsi_id;
  2361. act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
  2362. act |= FIELD_PREP(ICE_LG_ACT_VSI_LIST_ID_M, id);
  2363. if (m_ent->vsi_count > 1)
  2364. act |= ICE_LG_ACT_VSI_LIST;
  2365. lg_act->act[0] = cpu_to_le32(act);
  2366. /* Second action descriptor type */
  2367. act = ICE_LG_ACT_GENERIC;
  2368. act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, 1);
  2369. lg_act->act[1] = cpu_to_le32(act);
  2370. act = FIELD_PREP(ICE_LG_ACT_GENERIC_OFFSET_M,
  2371. ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX);
  2372. /* Third action Marker value */
  2373. act |= ICE_LG_ACT_GENERIC;
  2374. act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, sw_marker);
  2375. lg_act->act[2] = cpu_to_le32(act);
  2376. /* call the fill switch rule to fill the lookup Tx Rx structure */
  2377. ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
  2378. ice_aqc_opc_update_sw_rules);
  2379. /* Update the action to point to the large action ID */
  2380. act = ICE_SINGLE_ACT_PTR;
  2381. act |= FIELD_PREP(ICE_SINGLE_ACT_PTR_VAL_M, l_id);
  2382. rx_tx->act = cpu_to_le32(act);
  2383. /* Use the filter rule ID of the previously created rule with single
  2384. * act. Once the update happens, hardware will treat this as large
  2385. * action
  2386. */
  2387. rx_tx->index = cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
  2388. status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
  2389. ice_aqc_opc_update_sw_rules, NULL);
  2390. if (!status) {
  2391. m_ent->lg_act_idx = l_id;
  2392. m_ent->sw_marker_id = sw_marker;
  2393. }
  2394. devm_kfree(ice_hw_to_dev(hw), lg_act);
  2395. return status;
  2396. }
  2397. /**
  2398. * ice_create_vsi_list_map
  2399. * @hw: pointer to the hardware structure
  2400. * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
  2401. * @num_vsi: number of VSI handles in the array
  2402. * @vsi_list_id: VSI list ID generated as part of allocate resource
  2403. *
  2404. * Helper function to create a new entry of VSI list ID to VSI mapping
  2405. * using the given VSI list ID
  2406. */
  2407. static struct ice_vsi_list_map_info *
  2408. ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
  2409. u16 vsi_list_id)
  2410. {
  2411. struct ice_switch_info *sw = hw->switch_info;
  2412. struct ice_vsi_list_map_info *v_map;
  2413. int i;
  2414. v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
  2415. if (!v_map)
  2416. return NULL;
  2417. v_map->vsi_list_id = vsi_list_id;
  2418. v_map->ref_cnt = 1;
  2419. for (i = 0; i < num_vsi; i++)
  2420. set_bit(vsi_handle_arr[i], v_map->vsi_map);
  2421. list_add(&v_map->list_entry, &sw->vsi_list_map_head);
  2422. return v_map;
  2423. }
  2424. /**
  2425. * ice_update_vsi_list_rule
  2426. * @hw: pointer to the hardware structure
  2427. * @vsi_handle_arr: array of VSI handles to form a VSI list
  2428. * @num_vsi: number of VSI handles in the array
  2429. * @vsi_list_id: VSI list ID generated as part of allocate resource
  2430. * @remove: Boolean value to indicate if this is a remove action
  2431. * @opc: switch rules population command type - pass in the command opcode
  2432. * @lkup_type: lookup type of the filter
  2433. *
  2434. * Call AQ command to add a new switch rule or update existing switch rule
  2435. * using the given VSI list ID
  2436. */
  2437. static int
  2438. ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
  2439. u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
  2440. enum ice_sw_lkup_type lkup_type)
  2441. {
  2442. struct ice_sw_rule_vsi_list *s_rule;
  2443. u16 s_rule_size;
  2444. u16 rule_type;
  2445. int status;
  2446. int i;
  2447. if (!num_vsi)
  2448. return -EINVAL;
  2449. if (lkup_type == ICE_SW_LKUP_MAC ||
  2450. lkup_type == ICE_SW_LKUP_MAC_VLAN ||
  2451. lkup_type == ICE_SW_LKUP_ETHERTYPE ||
  2452. lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
  2453. lkup_type == ICE_SW_LKUP_PROMISC ||
  2454. lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
  2455. lkup_type == ICE_SW_LKUP_DFLT ||
  2456. lkup_type == ICE_SW_LKUP_LAST)
  2457. rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
  2458. ICE_AQC_SW_RULES_T_VSI_LIST_SET;
  2459. else if (lkup_type == ICE_SW_LKUP_VLAN)
  2460. rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
  2461. ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
  2462. else
  2463. return -EINVAL;
  2464. s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);
  2465. s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
  2466. if (!s_rule)
  2467. return -ENOMEM;
  2468. for (i = 0; i < num_vsi; i++) {
  2469. if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
  2470. status = -EINVAL;
  2471. goto exit;
  2472. }
  2473. /* AQ call requires hw_vsi_id(s) */
  2474. s_rule->vsi[i] =
  2475. cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
  2476. }
  2477. s_rule->hdr.type = cpu_to_le16(rule_type);
  2478. s_rule->number_vsi = cpu_to_le16(num_vsi);
  2479. s_rule->index = cpu_to_le16(vsi_list_id);
  2480. status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
  2481. exit:
  2482. devm_kfree(ice_hw_to_dev(hw), s_rule);
  2483. return status;
  2484. }
  2485. /**
  2486. * ice_create_vsi_list_rule - Creates and populates a VSI list rule
  2487. * @hw: pointer to the HW struct
  2488. * @vsi_handle_arr: array of VSI handles to form a VSI list
  2489. * @num_vsi: number of VSI handles in the array
  2490. * @vsi_list_id: stores the ID of the VSI list to be created
  2491. * @lkup_type: switch rule filter's lookup type
  2492. */
  2493. static int
  2494. ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
  2495. u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
  2496. {
  2497. int status;
  2498. status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
  2499. ice_aqc_opc_alloc_res);
  2500. if (status)
  2501. return status;
  2502. /* Update the newly created VSI list to include the specified VSIs */
  2503. return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
  2504. *vsi_list_id, false,
  2505. ice_aqc_opc_add_sw_rules, lkup_type);
  2506. }
  2507. /**
  2508. * ice_create_pkt_fwd_rule
  2509. * @hw: pointer to the hardware structure
  2510. * @f_entry: entry containing packet forwarding information
  2511. *
  2512. * Create switch rule with given filter information and add an entry
  2513. * to the corresponding filter management list to track this switch rule
  2514. * and VSI mapping
  2515. */
  2516. static int
  2517. ice_create_pkt_fwd_rule(struct ice_hw *hw,
  2518. struct ice_fltr_list_entry *f_entry)
  2519. {
  2520. struct ice_fltr_mgmt_list_entry *fm_entry;
  2521. struct ice_sw_rule_lkup_rx_tx *s_rule;
  2522. enum ice_sw_lkup_type l_type;
  2523. struct ice_sw_recipe *recp;
  2524. int status;
  2525. s_rule = devm_kzalloc(ice_hw_to_dev(hw),
  2526. ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
  2527. GFP_KERNEL);
  2528. if (!s_rule)
  2529. return -ENOMEM;
  2530. fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
  2531. GFP_KERNEL);
  2532. if (!fm_entry) {
  2533. status = -ENOMEM;
  2534. goto ice_create_pkt_fwd_rule_exit;
  2535. }
  2536. fm_entry->fltr_info = f_entry->fltr_info;
  2537. /* Initialize all the fields for the management entry */
  2538. fm_entry->vsi_count = 1;
  2539. fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
  2540. fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
  2541. fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
  2542. ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
  2543. ice_aqc_opc_add_sw_rules);
  2544. status = ice_aq_sw_rules(hw, s_rule,
  2545. ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
  2546. ice_aqc_opc_add_sw_rules, NULL);
  2547. if (status) {
  2548. devm_kfree(ice_hw_to_dev(hw), fm_entry);
  2549. goto ice_create_pkt_fwd_rule_exit;
  2550. }
  2551. f_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
  2552. fm_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
  2553. /* The book keeping entries will get removed when base driver
  2554. * calls remove filter AQ command
  2555. */
  2556. l_type = fm_entry->fltr_info.lkup_type;
  2557. recp = &hw->switch_info->recp_list[l_type];
  2558. list_add(&fm_entry->list_entry, &recp->filt_rules);
  2559. ice_create_pkt_fwd_rule_exit:
  2560. devm_kfree(ice_hw_to_dev(hw), s_rule);
  2561. return status;
  2562. }
  2563. /**
  2564. * ice_update_pkt_fwd_rule
  2565. * @hw: pointer to the hardware structure
  2566. * @f_info: filter information for switch rule
  2567. *
  2568. * Call AQ command to update a previously created switch rule with a
  2569. * VSI list ID
  2570. */
  2571. static int
  2572. ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
  2573. {
  2574. struct ice_sw_rule_lkup_rx_tx *s_rule;
  2575. int status;
  2576. s_rule = devm_kzalloc(ice_hw_to_dev(hw),
  2577. ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
  2578. GFP_KERNEL);
  2579. if (!s_rule)
  2580. return -ENOMEM;
  2581. ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
  2582. s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
  2583. /* Update switch rule with new rule set to forward VSI list */
  2584. status = ice_aq_sw_rules(hw, s_rule,
  2585. ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
  2586. ice_aqc_opc_update_sw_rules, NULL);
  2587. devm_kfree(ice_hw_to_dev(hw), s_rule);
  2588. return status;
  2589. }
  2590. /**
  2591. * ice_update_sw_rule_bridge_mode
  2592. * @hw: pointer to the HW struct
  2593. *
  2594. * Updates unicast switch filter rules based on VEB/VEPA mode
  2595. */
  2596. int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
  2597. {
  2598. struct ice_switch_info *sw = hw->switch_info;
  2599. struct ice_fltr_mgmt_list_entry *fm_entry;
  2600. struct list_head *rule_head;
  2601. struct mutex *rule_lock; /* Lock to protect filter rule list */
  2602. int status = 0;
  2603. rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
  2604. rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
  2605. mutex_lock(rule_lock);
  2606. list_for_each_entry(fm_entry, rule_head, list_entry) {
  2607. struct ice_fltr_info *fi = &fm_entry->fltr_info;
  2608. u8 *addr = fi->l_data.mac.mac_addr;
  2609. /* Update unicast Tx rules to reflect the selected
  2610. * VEB/VEPA mode
  2611. */
  2612. if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
  2613. (fi->fltr_act == ICE_FWD_TO_VSI ||
  2614. fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
  2615. fi->fltr_act == ICE_FWD_TO_Q ||
  2616. fi->fltr_act == ICE_FWD_TO_QGRP)) {
  2617. status = ice_update_pkt_fwd_rule(hw, fi);
  2618. if (status)
  2619. break;
  2620. }
  2621. }
  2622. mutex_unlock(rule_lock);
  2623. return status;
  2624. }
  2625. /**
  2626. * ice_add_update_vsi_list
  2627. * @hw: pointer to the hardware structure
  2628. * @m_entry: pointer to current filter management list entry
  2629. * @cur_fltr: filter information from the book keeping entry
  2630. * @new_fltr: filter information with the new VSI to be added
  2631. *
  2632. * Call AQ command to add or update previously created VSI list with new VSI.
  2633. *
  2634. * Helper function to do book keeping associated with adding filter information
  2635. * The algorithm to do the book keeping is described below :
  2636. * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
  2637. * if only one VSI has been added till now
  2638. * Allocate a new VSI list and add two VSIs
  2639. * to this list using switch rule command
  2640. * Update the previously created switch rule with the
  2641. * newly created VSI list ID
  2642. * if a VSI list was previously created
  2643. * Add the new VSI to the previously created VSI list set
  2644. * using the update switch rule command
  2645. */
  2646. static int
  2647. ice_add_update_vsi_list(struct ice_hw *hw,
  2648. struct ice_fltr_mgmt_list_entry *m_entry,
  2649. struct ice_fltr_info *cur_fltr,
  2650. struct ice_fltr_info *new_fltr)
  2651. {
  2652. u16 vsi_list_id = 0;
  2653. int status = 0;
  2654. if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
  2655. cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
  2656. return -EOPNOTSUPP;
  2657. if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
  2658. new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
  2659. (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
  2660. cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
  2661. return -EOPNOTSUPP;
  2662. if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
  2663. /* Only one entry existed in the mapping and it was not already
  2664. * a part of a VSI list. So, create a VSI list with the old and
  2665. * new VSIs.
  2666. */
  2667. struct ice_fltr_info tmp_fltr;
  2668. u16 vsi_handle_arr[2];
  2669. /* A rule already exists with the new VSI being added */
  2670. if (cur_fltr->vsi_handle == new_fltr->vsi_handle)
  2671. return -EEXIST;
  2672. vsi_handle_arr[0] = cur_fltr->vsi_handle;
  2673. vsi_handle_arr[1] = new_fltr->vsi_handle;
  2674. status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
  2675. &vsi_list_id,
  2676. new_fltr->lkup_type);
  2677. if (status)
  2678. return status;
  2679. tmp_fltr = *new_fltr;
  2680. tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
  2681. tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
  2682. tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
  2683. /* Update the previous switch rule of "MAC forward to VSI" to
  2684. * "MAC fwd to VSI list"
  2685. */
  2686. status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
  2687. if (status)
  2688. return status;
  2689. cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
  2690. cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
  2691. m_entry->vsi_list_info =
  2692. ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
  2693. vsi_list_id);
  2694. if (!m_entry->vsi_list_info)
  2695. return -ENOMEM;
  2696. /* If this entry was large action then the large action needs
  2697. * to be updated to point to FWD to VSI list
  2698. */
  2699. if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
  2700. status =
  2701. ice_add_marker_act(hw, m_entry,
  2702. m_entry->sw_marker_id,
  2703. m_entry->lg_act_idx);
  2704. } else {
  2705. u16 vsi_handle = new_fltr->vsi_handle;
  2706. enum ice_adminq_opc opcode;
  2707. if (!m_entry->vsi_list_info)
  2708. return -EIO;
  2709. /* A rule already exists with the new VSI being added */
  2710. if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
  2711. return -EEXIST;
  2712. /* Update the previously created VSI list set with
  2713. * the new VSI ID passed in
  2714. */
  2715. vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
  2716. opcode = ice_aqc_opc_update_sw_rules;
  2717. status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
  2718. vsi_list_id, false, opcode,
  2719. new_fltr->lkup_type);
  2720. /* update VSI list mapping info with new VSI ID */
  2721. if (!status)
  2722. set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
  2723. }
  2724. if (!status)
  2725. m_entry->vsi_count++;
  2726. return status;
  2727. }
  2728. /**
  2729. * ice_find_rule_entry - Search a rule entry
  2730. * @hw: pointer to the hardware structure
  2731. * @recp_id: lookup type for which the specified rule needs to be searched
  2732. * @f_info: rule information
  2733. *
  2734. * Helper function to search for a given rule entry
  2735. * Returns pointer to entry storing the rule if found
  2736. */
  2737. static struct ice_fltr_mgmt_list_entry *
  2738. ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
  2739. {
  2740. struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
  2741. struct ice_switch_info *sw = hw->switch_info;
  2742. struct list_head *list_head;
  2743. list_head = &sw->recp_list[recp_id].filt_rules;
  2744. list_for_each_entry(list_itr, list_head, list_entry) {
  2745. if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
  2746. sizeof(f_info->l_data)) &&
  2747. f_info->flag == list_itr->fltr_info.flag) {
  2748. ret = list_itr;
  2749. break;
  2750. }
  2751. }
  2752. return ret;
  2753. }
  2754. /**
  2755. * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
  2756. * @hw: pointer to the hardware structure
  2757. * @recp_id: lookup type for which VSI lists needs to be searched
  2758. * @vsi_handle: VSI handle to be found in VSI list
  2759. * @vsi_list_id: VSI list ID found containing vsi_handle
  2760. *
  2761. * Helper function to search a VSI list with single entry containing given VSI
  2762. * handle element. This can be extended further to search VSI list with more
  2763. * than 1 vsi_count. Returns pointer to VSI list entry if found.
  2764. */
  2765. struct ice_vsi_list_map_info *
  2766. ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
  2767. u16 *vsi_list_id)
  2768. {
  2769. struct ice_vsi_list_map_info *map_info = NULL;
  2770. struct ice_switch_info *sw = hw->switch_info;
  2771. struct ice_fltr_mgmt_list_entry *list_itr;
  2772. struct list_head *list_head;
  2773. list_head = &sw->recp_list[recp_id].filt_rules;
  2774. list_for_each_entry(list_itr, list_head, list_entry) {
  2775. if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) {
  2776. map_info = list_itr->vsi_list_info;
  2777. if (test_bit(vsi_handle, map_info->vsi_map)) {
  2778. *vsi_list_id = map_info->vsi_list_id;
  2779. return map_info;
  2780. }
  2781. }
  2782. }
  2783. return NULL;
  2784. }
  2785. /**
  2786. * ice_add_rule_internal - add rule for a given lookup type
  2787. * @hw: pointer to the hardware structure
  2788. * @recp_id: lookup type (recipe ID) for which rule has to be added
  2789. * @f_entry: structure containing MAC forwarding information
  2790. *
  2791. * Adds or updates the rule lists for a given recipe
  2792. */
  2793. static int
  2794. ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
  2795. struct ice_fltr_list_entry *f_entry)
  2796. {
  2797. struct ice_switch_info *sw = hw->switch_info;
  2798. struct ice_fltr_info *new_fltr, *cur_fltr;
  2799. struct ice_fltr_mgmt_list_entry *m_entry;
  2800. struct mutex *rule_lock; /* Lock to protect filter rule list */
  2801. int status = 0;
  2802. if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
  2803. return -EINVAL;
  2804. f_entry->fltr_info.fwd_id.hw_vsi_id =
  2805. ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
  2806. rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
  2807. mutex_lock(rule_lock);
  2808. new_fltr = &f_entry->fltr_info;
  2809. if (new_fltr->flag & ICE_FLTR_RX)
  2810. new_fltr->src = hw->port_info->lport;
  2811. else if (new_fltr->flag & ICE_FLTR_TX)
  2812. new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;
  2813. m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
  2814. if (!m_entry) {
  2815. mutex_unlock(rule_lock);
  2816. return ice_create_pkt_fwd_rule(hw, f_entry);
  2817. }
  2818. cur_fltr = &m_entry->fltr_info;
  2819. status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
  2820. mutex_unlock(rule_lock);
  2821. return status;
  2822. }
  2823. /**
  2824. * ice_remove_vsi_list_rule
  2825. * @hw: pointer to the hardware structure
  2826. * @vsi_list_id: VSI list ID generated as part of allocate resource
  2827. * @lkup_type: switch rule filter lookup type
  2828. *
  2829. * The VSI list should be emptied before this function is called to remove the
  2830. * VSI list.
  2831. */
  2832. static int
  2833. ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
  2834. enum ice_sw_lkup_type lkup_type)
  2835. {
  2836. struct ice_sw_rule_vsi_list *s_rule;
  2837. u16 s_rule_size;
  2838. int status;
  2839. s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, 0);
  2840. s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
  2841. if (!s_rule)
  2842. return -ENOMEM;
  2843. s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
  2844. s_rule->index = cpu_to_le16(vsi_list_id);
  2845. /* Free the vsi_list resource that we allocated. It is assumed that the
  2846. * list is empty at this point.
  2847. */
  2848. status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
  2849. ice_aqc_opc_free_res);
  2850. devm_kfree(ice_hw_to_dev(hw), s_rule);
  2851. return status;
  2852. }
  2853. /**
  2854. * ice_rem_update_vsi_list
  2855. * @hw: pointer to the hardware structure
  2856. * @vsi_handle: VSI handle of the VSI to remove
  2857. * @fm_list: filter management entry for which the VSI list management needs to
  2858. * be done
  2859. */
  2860. static int
  2861. ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
  2862. struct ice_fltr_mgmt_list_entry *fm_list)
  2863. {
  2864. enum ice_sw_lkup_type lkup_type;
  2865. u16 vsi_list_id;
  2866. int status = 0;
  2867. if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
  2868. fm_list->vsi_count == 0)
  2869. return -EINVAL;
  2870. /* A rule with the VSI being removed does not exist */
  2871. if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
  2872. return -ENOENT;
  2873. lkup_type = fm_list->fltr_info.lkup_type;
  2874. vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
  2875. status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
  2876. ice_aqc_opc_update_sw_rules,
  2877. lkup_type);
  2878. if (status)
  2879. return status;
  2880. fm_list->vsi_count--;
  2881. clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
  2882. if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
  2883. struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
  2884. struct ice_vsi_list_map_info *vsi_list_info =
  2885. fm_list->vsi_list_info;
  2886. u16 rem_vsi_handle;
  2887. rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
  2888. ICE_MAX_VSI);
  2889. if (!ice_is_vsi_valid(hw, rem_vsi_handle))
  2890. return -EIO;
  2891. /* Make sure VSI list is empty before removing it below */
  2892. status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
  2893. vsi_list_id, true,
  2894. ice_aqc_opc_update_sw_rules,
  2895. lkup_type);
  2896. if (status)
  2897. return status;
  2898. tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
  2899. tmp_fltr_info.fwd_id.hw_vsi_id =
  2900. ice_get_hw_vsi_num(hw, rem_vsi_handle);
  2901. tmp_fltr_info.vsi_handle = rem_vsi_handle;
  2902. status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
  2903. if (status) {
  2904. ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
  2905. tmp_fltr_info.fwd_id.hw_vsi_id, status);
  2906. return status;
  2907. }
  2908. fm_list->fltr_info = tmp_fltr_info;
  2909. }
  2910. if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
  2911. (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
  2912. struct ice_vsi_list_map_info *vsi_list_info =
  2913. fm_list->vsi_list_info;
  2914. /* Remove the VSI list since it is no longer used */
  2915. status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
  2916. if (status) {
  2917. ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
  2918. vsi_list_id, status);
  2919. return status;
  2920. }
  2921. list_del(&vsi_list_info->list_entry);
  2922. devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
  2923. fm_list->vsi_list_info = NULL;
  2924. }
  2925. return status;
  2926. }
  2927. /**
  2928. * ice_remove_rule_internal - Remove a filter rule of a given type
  2929. * @hw: pointer to the hardware structure
  2930. * @recp_id: recipe ID for which the rule needs to removed
  2931. * @f_entry: rule entry containing filter information
  2932. */
  2933. static int
  2934. ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
  2935. struct ice_fltr_list_entry *f_entry)
  2936. {
  2937. struct ice_switch_info *sw = hw->switch_info;
  2938. struct ice_fltr_mgmt_list_entry *list_elem;
  2939. struct mutex *rule_lock; /* Lock to protect filter rule list */
  2940. bool remove_rule = false;
  2941. u16 vsi_handle;
  2942. int status = 0;
  2943. if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
  2944. return -EINVAL;
  2945. f_entry->fltr_info.fwd_id.hw_vsi_id =
  2946. ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
  2947. rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
  2948. mutex_lock(rule_lock);
  2949. list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
  2950. if (!list_elem) {
  2951. status = -ENOENT;
  2952. goto exit;
  2953. }
  2954. if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
  2955. remove_rule = true;
  2956. } else if (!list_elem->vsi_list_info) {
  2957. status = -ENOENT;
  2958. goto exit;
  2959. } else if (list_elem->vsi_list_info->ref_cnt > 1) {
  2960. /* a ref_cnt > 1 indicates that the vsi_list is being
  2961. * shared by multiple rules. Decrement the ref_cnt and
  2962. * remove this rule, but do not modify the list, as it
  2963. * is in-use by other rules.
  2964. */
  2965. list_elem->vsi_list_info->ref_cnt--;
  2966. remove_rule = true;
  2967. } else {
  2968. /* a ref_cnt of 1 indicates the vsi_list is only used
  2969. * by one rule. However, the original removal request is only
  2970. * for a single VSI. Update the vsi_list first, and only
  2971. * remove the rule if there are no further VSIs in this list.
  2972. */
  2973. vsi_handle = f_entry->fltr_info.vsi_handle;
  2974. status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
  2975. if (status)
  2976. goto exit;
  2977. /* if VSI count goes to zero after updating the VSI list */
  2978. if (list_elem->vsi_count == 0)
  2979. remove_rule = true;
  2980. }
  2981. if (remove_rule) {
  2982. /* Remove the lookup rule */
  2983. struct ice_sw_rule_lkup_rx_tx *s_rule;
  2984. s_rule = devm_kzalloc(ice_hw_to_dev(hw),
  2985. ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
  2986. GFP_KERNEL);
  2987. if (!s_rule) {
  2988. status = -ENOMEM;
  2989. goto exit;
  2990. }
  2991. ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
  2992. ice_aqc_opc_remove_sw_rules);
  2993. status = ice_aq_sw_rules(hw, s_rule,
  2994. ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
  2995. 1, ice_aqc_opc_remove_sw_rules, NULL);
  2996. /* Remove a book keeping from the list */
  2997. devm_kfree(ice_hw_to_dev(hw), s_rule);
  2998. if (status)
  2999. goto exit;
  3000. list_del(&list_elem->list_entry);
  3001. devm_kfree(ice_hw_to_dev(hw), list_elem);
  3002. }
  3003. exit:
  3004. mutex_unlock(rule_lock);
  3005. return status;
  3006. }
  3007. /**
  3008. * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI
  3009. * @hw: pointer to the hardware structure
  3010. * @vlan_id: VLAN ID
  3011. * @vsi_handle: check MAC filter for this VSI
  3012. */
  3013. bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
  3014. {
  3015. struct ice_fltr_mgmt_list_entry *entry;
  3016. struct list_head *rule_head;
  3017. struct ice_switch_info *sw;
  3018. struct mutex *rule_lock; /* Lock to protect filter rule list */
  3019. u16 hw_vsi_id;
  3020. if (vlan_id > ICE_MAX_VLAN_ID)
  3021. return false;
  3022. if (!ice_is_vsi_valid(hw, vsi_handle))
  3023. return false;
  3024. hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
  3025. sw = hw->switch_info;
  3026. rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
  3027. if (!rule_head)
  3028. return false;
  3029. rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
  3030. mutex_lock(rule_lock);
  3031. list_for_each_entry(entry, rule_head, list_entry) {
  3032. struct ice_fltr_info *f_info = &entry->fltr_info;
  3033. u16 entry_vlan_id = f_info->l_data.vlan.vlan_id;
  3034. struct ice_vsi_list_map_info *map_info;
  3035. if (entry_vlan_id > ICE_MAX_VLAN_ID)
  3036. continue;
  3037. if (f_info->flag != ICE_FLTR_TX ||
  3038. f_info->src_id != ICE_SRC_ID_VSI ||
  3039. f_info->lkup_type != ICE_SW_LKUP_VLAN)
  3040. continue;
  3041. /* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */
  3042. if (f_info->fltr_act != ICE_FWD_TO_VSI &&
  3043. f_info->fltr_act != ICE_FWD_TO_VSI_LIST)
  3044. continue;
  3045. if (f_info->fltr_act == ICE_FWD_TO_VSI) {
  3046. if (hw_vsi_id != f_info->fwd_id.hw_vsi_id)
  3047. continue;
  3048. } else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
  3049. /* If filter_action is FWD_TO_VSI_LIST, make sure
  3050. * that VSI being checked is part of VSI list
  3051. */
  3052. if (entry->vsi_count == 1 &&
  3053. entry->vsi_list_info) {
  3054. map_info = entry->vsi_list_info;
  3055. if (!test_bit(vsi_handle, map_info->vsi_map))
  3056. continue;
  3057. }
  3058. }
  3059. if (vlan_id == entry_vlan_id) {
  3060. mutex_unlock(rule_lock);
  3061. return true;
  3062. }
  3063. }
  3064. mutex_unlock(rule_lock);
  3065. return false;
  3066. }
  3067. /**
  3068. * ice_add_mac - Add a MAC address based filter rule
  3069. * @hw: pointer to the hardware structure
  3070. * @m_list: list of MAC addresses and forwarding information
  3071. */
  3072. int ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
  3073. {
  3074. struct ice_fltr_list_entry *m_list_itr;
  3075. int status = 0;
  3076. if (!m_list || !hw)
  3077. return -EINVAL;
  3078. list_for_each_entry(m_list_itr, m_list, list_entry) {
  3079. u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
  3080. u16 vsi_handle;
  3081. u16 hw_vsi_id;
  3082. m_list_itr->fltr_info.flag = ICE_FLTR_TX;
  3083. vsi_handle = m_list_itr->fltr_info.vsi_handle;
  3084. if (!ice_is_vsi_valid(hw, vsi_handle))
  3085. return -EINVAL;
  3086. hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
  3087. m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
  3088. /* update the src in case it is VSI num */
  3089. if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
  3090. return -EINVAL;
  3091. m_list_itr->fltr_info.src = hw_vsi_id;
  3092. if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
  3093. is_zero_ether_addr(add))
  3094. return -EINVAL;
  3095. m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
  3096. m_list_itr);
  3097. if (m_list_itr->status)
  3098. return m_list_itr->status;
  3099. }
  3100. return status;
  3101. }
  3102. /**
  3103. * ice_add_vlan_internal - Add one VLAN based filter rule
  3104. * @hw: pointer to the hardware structure
  3105. * @f_entry: filter entry containing one VLAN information
  3106. */
  3107. static int
  3108. ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
  3109. {
  3110. struct ice_switch_info *sw = hw->switch_info;
  3111. struct ice_fltr_mgmt_list_entry *v_list_itr;
  3112. struct ice_fltr_info *new_fltr, *cur_fltr;
  3113. enum ice_sw_lkup_type lkup_type;
  3114. u16 vsi_list_id = 0, vsi_handle;
  3115. struct mutex *rule_lock; /* Lock to protect filter rule list */
  3116. int status = 0;
  3117. if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
  3118. return -EINVAL;
  3119. f_entry->fltr_info.fwd_id.hw_vsi_id =
  3120. ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
  3121. new_fltr = &f_entry->fltr_info;
  3122. /* VLAN ID should only be 12 bits */
  3123. if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
  3124. return -EINVAL;
  3125. if (new_fltr->src_id != ICE_SRC_ID_VSI)
  3126. return -EINVAL;
  3127. new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
  3128. lkup_type = new_fltr->lkup_type;
  3129. vsi_handle = new_fltr->vsi_handle;
  3130. rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
  3131. mutex_lock(rule_lock);
  3132. v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
  3133. if (!v_list_itr) {
  3134. struct ice_vsi_list_map_info *map_info = NULL;
  3135. if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
  3136. /* All VLAN pruning rules use a VSI list. Check if
  3137. * there is already a VSI list containing VSI that we
  3138. * want to add. If found, use the same vsi_list_id for
  3139. * this new VLAN rule or else create a new list.
  3140. */
  3141. map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
  3142. vsi_handle,
  3143. &vsi_list_id);
  3144. if (!map_info) {
  3145. status = ice_create_vsi_list_rule(hw,
  3146. &vsi_handle,
  3147. 1,
  3148. &vsi_list_id,
  3149. lkup_type);
  3150. if (status)
  3151. goto exit;
  3152. }
  3153. /* Convert the action to forwarding to a VSI list. */
  3154. new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
  3155. new_fltr->fwd_id.vsi_list_id = vsi_list_id;
  3156. }
  3157. status = ice_create_pkt_fwd_rule(hw, f_entry);
  3158. if (!status) {
  3159. v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
  3160. new_fltr);
  3161. if (!v_list_itr) {
  3162. status = -ENOENT;
  3163. goto exit;
  3164. }
  3165. /* reuse VSI list for new rule and increment ref_cnt */
  3166. if (map_info) {
  3167. v_list_itr->vsi_list_info = map_info;
  3168. map_info->ref_cnt++;
  3169. } else {
  3170. v_list_itr->vsi_list_info =
  3171. ice_create_vsi_list_map(hw, &vsi_handle,
  3172. 1, vsi_list_id);
  3173. }
  3174. }
  3175. } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
  3176. /* Update existing VSI list to add new VSI ID only if it used
  3177. * by one VLAN rule.
  3178. */
  3179. cur_fltr = &v_list_itr->fltr_info;
  3180. status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
  3181. new_fltr);
  3182. } else {
  3183. /* If VLAN rule exists and VSI list being used by this rule is
  3184. * referenced by more than 1 VLAN rule. Then create a new VSI
  3185. * list appending previous VSI with new VSI and update existing
  3186. * VLAN rule to point to new VSI list ID
  3187. */
  3188. struct ice_fltr_info tmp_fltr;
  3189. u16 vsi_handle_arr[2];
  3190. u16 cur_handle;
  3191. /* Current implementation only supports reusing VSI list with
  3192. * one VSI count. We should never hit below condition
  3193. */
  3194. if (v_list_itr->vsi_count > 1 &&
  3195. v_list_itr->vsi_list_info->ref_cnt > 1) {
  3196. ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
  3197. status = -EIO;
  3198. goto exit;
  3199. }
  3200. cur_handle =
  3201. find_first_bit(v_list_itr->vsi_list_info->vsi_map,
  3202. ICE_MAX_VSI);
  3203. /* A rule already exists with the new VSI being added */
  3204. if (cur_handle == vsi_handle) {
  3205. status = -EEXIST;
  3206. goto exit;
  3207. }
  3208. vsi_handle_arr[0] = cur_handle;
  3209. vsi_handle_arr[1] = vsi_handle;
  3210. status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
  3211. &vsi_list_id, lkup_type);
  3212. if (status)
  3213. goto exit;
  3214. tmp_fltr = v_list_itr->fltr_info;
  3215. tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
  3216. tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
  3217. tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
  3218. /* Update the previous switch rule to a new VSI list which
  3219. * includes current VSI that is requested
  3220. */
  3221. status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
  3222. if (status)
  3223. goto exit;
  3224. /* before overriding VSI list map info. decrement ref_cnt of
  3225. * previous VSI list
  3226. */
  3227. v_list_itr->vsi_list_info->ref_cnt--;
  3228. /* now update to newly created list */
  3229. v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
  3230. v_list_itr->vsi_list_info =
  3231. ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
  3232. vsi_list_id);
  3233. v_list_itr->vsi_count++;
  3234. }
  3235. exit:
  3236. mutex_unlock(rule_lock);
  3237. return status;
  3238. }
  3239. /**
  3240. * ice_add_vlan - Add VLAN based filter rule
  3241. * @hw: pointer to the hardware structure
  3242. * @v_list: list of VLAN entries and forwarding information
  3243. */
  3244. int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
  3245. {
  3246. struct ice_fltr_list_entry *v_list_itr;
  3247. if (!v_list || !hw)
  3248. return -EINVAL;
  3249. list_for_each_entry(v_list_itr, v_list, list_entry) {
  3250. if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
  3251. return -EINVAL;
  3252. v_list_itr->fltr_info.flag = ICE_FLTR_TX;
  3253. v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
  3254. if (v_list_itr->status)
  3255. return v_list_itr->status;
  3256. }
  3257. return 0;
  3258. }
  3259. /**
  3260. * ice_add_eth_mac - Add ethertype and MAC based filter rule
  3261. * @hw: pointer to the hardware structure
  3262. * @em_list: list of ether type MAC filter, MAC is optional
  3263. *
  3264. * This function requires the caller to populate the entries in
  3265. * the filter list with the necessary fields (including flags to
  3266. * indicate Tx or Rx rules).
  3267. */
  3268. int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
  3269. {
  3270. struct ice_fltr_list_entry *em_list_itr;
  3271. if (!em_list || !hw)
  3272. return -EINVAL;
  3273. list_for_each_entry(em_list_itr, em_list, list_entry) {
  3274. enum ice_sw_lkup_type l_type =
  3275. em_list_itr->fltr_info.lkup_type;
  3276. if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
  3277. l_type != ICE_SW_LKUP_ETHERTYPE)
  3278. return -EINVAL;
  3279. em_list_itr->status = ice_add_rule_internal(hw, l_type,
  3280. em_list_itr);
  3281. if (em_list_itr->status)
  3282. return em_list_itr->status;
  3283. }
  3284. return 0;
  3285. }
  3286. /**
  3287. * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule
  3288. * @hw: pointer to the hardware structure
  3289. * @em_list: list of ethertype or ethertype MAC entries
  3290. */
  3291. int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
  3292. {
  3293. struct ice_fltr_list_entry *em_list_itr, *tmp;
  3294. if (!em_list || !hw)
  3295. return -EINVAL;
  3296. list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) {
  3297. enum ice_sw_lkup_type l_type =
  3298. em_list_itr->fltr_info.lkup_type;
  3299. if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
  3300. l_type != ICE_SW_LKUP_ETHERTYPE)
  3301. return -EINVAL;
  3302. em_list_itr->status = ice_remove_rule_internal(hw, l_type,
  3303. em_list_itr);
  3304. if (em_list_itr->status)
  3305. return em_list_itr->status;
  3306. }
  3307. return 0;
  3308. }
  3309. /**
  3310. * ice_rem_sw_rule_info
  3311. * @hw: pointer to the hardware structure
  3312. * @rule_head: pointer to the switch list structure that we want to delete
  3313. */
  3314. static void
  3315. ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
  3316. {
  3317. if (!list_empty(rule_head)) {
  3318. struct ice_fltr_mgmt_list_entry *entry;
  3319. struct ice_fltr_mgmt_list_entry *tmp;
  3320. list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
  3321. list_del(&entry->list_entry);
  3322. devm_kfree(ice_hw_to_dev(hw), entry);
  3323. }
  3324. }
  3325. }
  3326. /**
  3327. * ice_rem_adv_rule_info
  3328. * @hw: pointer to the hardware structure
  3329. * @rule_head: pointer to the switch list structure that we want to delete
  3330. */
  3331. static void
  3332. ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head)
  3333. {
  3334. struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
  3335. struct ice_adv_fltr_mgmt_list_entry *lst_itr;
  3336. if (list_empty(rule_head))
  3337. return;
  3338. list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) {
  3339. list_del(&lst_itr->list_entry);
  3340. devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups);
  3341. devm_kfree(ice_hw_to_dev(hw), lst_itr);
  3342. }
  3343. }
  3344. /**
  3345. * ice_cfg_dflt_vsi - change state of VSI to set/clear default
  3346. * @pi: pointer to the port_info structure
  3347. * @vsi_handle: VSI handle to set as default
  3348. * @set: true to add the above mentioned switch rule, false to remove it
  3349. * @direction: ICE_FLTR_RX or ICE_FLTR_TX
  3350. *
  3351. * add filter rule to set/unset given VSI as default VSI for the switch
  3352. * (represented by swid)
  3353. */
  3354. int
  3355. ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
  3356. u8 direction)
  3357. {
  3358. struct ice_fltr_list_entry f_list_entry;
  3359. struct ice_fltr_info f_info;
  3360. struct ice_hw *hw = pi->hw;
  3361. u16 hw_vsi_id;
  3362. int status;
  3363. if (!ice_is_vsi_valid(hw, vsi_handle))
  3364. return -EINVAL;
  3365. hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
  3366. memset(&f_info, 0, sizeof(f_info));
  3367. f_info.lkup_type = ICE_SW_LKUP_DFLT;
  3368. f_info.flag = direction;
  3369. f_info.fltr_act = ICE_FWD_TO_VSI;
  3370. f_info.fwd_id.hw_vsi_id = hw_vsi_id;
  3371. f_info.vsi_handle = vsi_handle;
  3372. if (f_info.flag & ICE_FLTR_RX) {
  3373. f_info.src = hw->port_info->lport;
  3374. f_info.src_id = ICE_SRC_ID_LPORT;
  3375. } else if (f_info.flag & ICE_FLTR_TX) {
  3376. f_info.src_id = ICE_SRC_ID_VSI;
  3377. f_info.src = hw_vsi_id;
  3378. f_info.flag |= ICE_FLTR_TX_ONLY;
  3379. }
  3380. f_list_entry.fltr_info = f_info;
  3381. if (set)
  3382. status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT,
  3383. &f_list_entry);
  3384. else
  3385. status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT,
  3386. &f_list_entry);
  3387. return status;
  3388. }
  3389. /**
  3390. * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
  3391. * @fm_entry: filter entry to inspect
  3392. * @vsi_handle: VSI handle to compare with filter info
  3393. */
  3394. static bool
  3395. ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
  3396. {
  3397. return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
  3398. fm_entry->fltr_info.vsi_handle == vsi_handle) ||
  3399. (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
  3400. fm_entry->vsi_list_info &&
  3401. (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
  3402. }
  3403. /**
  3404. * ice_check_if_dflt_vsi - check if VSI is default VSI
  3405. * @pi: pointer to the port_info structure
  3406. * @vsi_handle: vsi handle to check for in filter list
  3407. * @rule_exists: indicates if there are any VSI's in the rule list
  3408. *
  3409. * checks if the VSI is in a default VSI list, and also indicates
  3410. * if the default VSI list is empty
  3411. */
  3412. bool
  3413. ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle,
  3414. bool *rule_exists)
  3415. {
  3416. struct ice_fltr_mgmt_list_entry *fm_entry;
  3417. struct ice_sw_recipe *recp_list;
  3418. struct list_head *rule_head;
  3419. struct mutex *rule_lock; /* Lock to protect filter rule list */
  3420. bool ret = false;
  3421. recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
  3422. rule_lock = &recp_list->filt_rule_lock;
  3423. rule_head = &recp_list->filt_rules;
  3424. mutex_lock(rule_lock);
  3425. if (rule_exists && !list_empty(rule_head))
  3426. *rule_exists = true;
  3427. list_for_each_entry(fm_entry, rule_head, list_entry) {
  3428. if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) {
  3429. ret = true;
  3430. break;
  3431. }
  3432. }
  3433. mutex_unlock(rule_lock);
  3434. return ret;
  3435. }
  3436. /**
  3437. * ice_remove_mac - remove a MAC address based filter rule
  3438. * @hw: pointer to the hardware structure
  3439. * @m_list: list of MAC addresses and forwarding information
  3440. *
  3441. * This function removes either a MAC filter rule or a specific VSI from a
  3442. * VSI list for a multicast MAC address.
  3443. *
  3444. * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should
  3445. * be aware that this call will only work if all the entries passed into m_list
  3446. * were added previously. It will not attempt to do a partial remove of entries
  3447. * that were found.
  3448. */
  3449. int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
  3450. {
  3451. struct ice_fltr_list_entry *list_itr, *tmp;
  3452. if (!m_list)
  3453. return -EINVAL;
  3454. list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
  3455. enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
  3456. u16 vsi_handle;
  3457. if (l_type != ICE_SW_LKUP_MAC)
  3458. return -EINVAL;
  3459. vsi_handle = list_itr->fltr_info.vsi_handle;
  3460. if (!ice_is_vsi_valid(hw, vsi_handle))
  3461. return -EINVAL;
  3462. list_itr->fltr_info.fwd_id.hw_vsi_id =
  3463. ice_get_hw_vsi_num(hw, vsi_handle);
  3464. list_itr->status = ice_remove_rule_internal(hw,
  3465. ICE_SW_LKUP_MAC,
  3466. list_itr);
  3467. if (list_itr->status)
  3468. return list_itr->status;
  3469. }
  3470. return 0;
  3471. }
  3472. /**
  3473. * ice_remove_vlan - Remove VLAN based filter rule
  3474. * @hw: pointer to the hardware structure
  3475. * @v_list: list of VLAN entries and forwarding information
  3476. */
  3477. int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
  3478. {
  3479. struct ice_fltr_list_entry *v_list_itr, *tmp;
  3480. if (!v_list || !hw)
  3481. return -EINVAL;
  3482. list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
  3483. enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
  3484. if (l_type != ICE_SW_LKUP_VLAN)
  3485. return -EINVAL;
  3486. v_list_itr->status = ice_remove_rule_internal(hw,
  3487. ICE_SW_LKUP_VLAN,
  3488. v_list_itr);
  3489. if (v_list_itr->status)
  3490. return v_list_itr->status;
  3491. }
  3492. return 0;
  3493. }
  3494. /**
  3495. * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
  3496. * @hw: pointer to the hardware structure
  3497. * @vsi_handle: VSI handle to remove filters from
  3498. * @vsi_list_head: pointer to the list to add entry to
  3499. * @fi: pointer to fltr_info of filter entry to copy & add
  3500. *
  3501. * Helper function, used when creating a list of filters to remove from
  3502. * a specific VSI. The entry added to vsi_list_head is a COPY of the
  3503. * original filter entry, with the exception of fltr_info.fltr_act and
  3504. * fltr_info.fwd_id fields. These are set such that later logic can
  3505. * extract which VSI to remove the fltr from, and pass on that information.
  3506. */
  3507. static int
  3508. ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
  3509. struct list_head *vsi_list_head,
  3510. struct ice_fltr_info *fi)
  3511. {
  3512. struct ice_fltr_list_entry *tmp;
  3513. /* this memory is freed up in the caller function
  3514. * once filters for this VSI are removed
  3515. */
  3516. tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
  3517. if (!tmp)
  3518. return -ENOMEM;
  3519. tmp->fltr_info = *fi;
  3520. /* Overwrite these fields to indicate which VSI to remove filter from,
  3521. * so find and remove logic can extract the information from the
  3522. * list entries. Note that original entries will still have proper
  3523. * values.
  3524. */
  3525. tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
  3526. tmp->fltr_info.vsi_handle = vsi_handle;
  3527. tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
  3528. list_add(&tmp->list_entry, vsi_list_head);
  3529. return 0;
  3530. }
  3531. /**
  3532. * ice_add_to_vsi_fltr_list - Add VSI filters to the list
  3533. * @hw: pointer to the hardware structure
  3534. * @vsi_handle: VSI handle to remove filters from
  3535. * @lkup_list_head: pointer to the list that has certain lookup type filters
  3536. * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
  3537. *
  3538. * Locates all filters in lkup_list_head that are used by the given VSI,
  3539. * and adds COPIES of those entries to vsi_list_head (intended to be used
  3540. * to remove the listed filters).
  3541. * Note that this means all entries in vsi_list_head must be explicitly
  3542. * deallocated by the caller when done with list.
  3543. */
  3544. static int
  3545. ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
  3546. struct list_head *lkup_list_head,
  3547. struct list_head *vsi_list_head)
  3548. {
  3549. struct ice_fltr_mgmt_list_entry *fm_entry;
  3550. int status = 0;
  3551. /* check to make sure VSI ID is valid and within boundary */
  3552. if (!ice_is_vsi_valid(hw, vsi_handle))
  3553. return -EINVAL;
  3554. list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
  3555. if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
  3556. continue;
  3557. status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
  3558. vsi_list_head,
  3559. &fm_entry->fltr_info);
  3560. if (status)
  3561. return status;
  3562. }
  3563. return status;
  3564. }
  3565. /**
  3566. * ice_determine_promisc_mask
  3567. * @fi: filter info to parse
  3568. *
  3569. * Helper function to determine which ICE_PROMISC_ mask corresponds
  3570. * to given filter into.
  3571. */
  3572. static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
  3573. {
  3574. u16 vid = fi->l_data.mac_vlan.vlan_id;
  3575. u8 *macaddr = fi->l_data.mac.mac_addr;
  3576. bool is_tx_fltr = false;
  3577. u8 promisc_mask = 0;
  3578. if (fi->flag == ICE_FLTR_TX)
  3579. is_tx_fltr = true;
  3580. if (is_broadcast_ether_addr(macaddr))
  3581. promisc_mask |= is_tx_fltr ?
  3582. ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
  3583. else if (is_multicast_ether_addr(macaddr))
  3584. promisc_mask |= is_tx_fltr ?
  3585. ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
  3586. else if (is_unicast_ether_addr(macaddr))
  3587. promisc_mask |= is_tx_fltr ?
  3588. ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
  3589. if (vid)
  3590. promisc_mask |= is_tx_fltr ?
  3591. ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
  3592. return promisc_mask;
  3593. }
  3594. /**
  3595. * ice_remove_promisc - Remove promisc based filter rules
  3596. * @hw: pointer to the hardware structure
  3597. * @recp_id: recipe ID for which the rule needs to removed
  3598. * @v_list: list of promisc entries
  3599. */
  3600. static int
  3601. ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list)
  3602. {
  3603. struct ice_fltr_list_entry *v_list_itr, *tmp;
  3604. list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
  3605. v_list_itr->status =
  3606. ice_remove_rule_internal(hw, recp_id, v_list_itr);
  3607. if (v_list_itr->status)
  3608. return v_list_itr->status;
  3609. }
  3610. return 0;
  3611. }
  3612. /**
  3613. * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
  3614. * @hw: pointer to the hardware structure
  3615. * @vsi_handle: VSI handle to clear mode
  3616. * @promisc_mask: mask of promiscuous config bits to clear
  3617. * @vid: VLAN ID to clear VLAN promiscuous
  3618. */
  3619. int
  3620. ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
  3621. u16 vid)
  3622. {
  3623. struct ice_switch_info *sw = hw->switch_info;
  3624. struct ice_fltr_list_entry *fm_entry, *tmp;
  3625. struct list_head remove_list_head;
  3626. struct ice_fltr_mgmt_list_entry *itr;
  3627. struct list_head *rule_head;
  3628. struct mutex *rule_lock; /* Lock to protect filter rule list */
  3629. int status = 0;
  3630. u8 recipe_id;
  3631. if (!ice_is_vsi_valid(hw, vsi_handle))
  3632. return -EINVAL;
  3633. if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
  3634. recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
  3635. else
  3636. recipe_id = ICE_SW_LKUP_PROMISC;
  3637. rule_head = &sw->recp_list[recipe_id].filt_rules;
  3638. rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
  3639. INIT_LIST_HEAD(&remove_list_head);
  3640. mutex_lock(rule_lock);
  3641. list_for_each_entry(itr, rule_head, list_entry) {
  3642. struct ice_fltr_info *fltr_info;
  3643. u8 fltr_promisc_mask = 0;
  3644. if (!ice_vsi_uses_fltr(itr, vsi_handle))
  3645. continue;
  3646. fltr_info = &itr->fltr_info;
  3647. if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
  3648. vid != fltr_info->l_data.mac_vlan.vlan_id)
  3649. continue;
  3650. fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
  3651. /* Skip if filter is not completely specified by given mask */
  3652. if (fltr_promisc_mask & ~promisc_mask)
  3653. continue;
  3654. status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
  3655. &remove_list_head,
  3656. fltr_info);
  3657. if (status) {
  3658. mutex_unlock(rule_lock);
  3659. goto free_fltr_list;
  3660. }
  3661. }
  3662. mutex_unlock(rule_lock);
  3663. status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
  3664. free_fltr_list:
  3665. list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
  3666. list_del(&fm_entry->list_entry);
  3667. devm_kfree(ice_hw_to_dev(hw), fm_entry);
  3668. }
  3669. return status;
  3670. }
  3671. /**
  3672. * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
  3673. * @hw: pointer to the hardware structure
  3674. * @vsi_handle: VSI handle to configure
  3675. * @promisc_mask: mask of promiscuous config bits
  3676. * @vid: VLAN ID to set VLAN promiscuous
  3677. */
  3678. int
  3679. ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
  3680. {
  3681. enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
  3682. struct ice_fltr_list_entry f_list_entry;
  3683. struct ice_fltr_info new_fltr;
  3684. bool is_tx_fltr;
  3685. int status = 0;
  3686. u16 hw_vsi_id;
  3687. int pkt_type;
  3688. u8 recipe_id;
  3689. if (!ice_is_vsi_valid(hw, vsi_handle))
  3690. return -EINVAL;
  3691. hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
  3692. memset(&new_fltr, 0, sizeof(new_fltr));
  3693. if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
  3694. new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
  3695. new_fltr.l_data.mac_vlan.vlan_id = vid;
  3696. recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
  3697. } else {
  3698. new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
  3699. recipe_id = ICE_SW_LKUP_PROMISC;
  3700. }
  3701. /* Separate filters must be set for each direction/packet type
  3702. * combination, so we will loop over the mask value, store the
  3703. * individual type, and clear it out in the input mask as it
  3704. * is found.
  3705. */
  3706. while (promisc_mask) {
  3707. u8 *mac_addr;
  3708. pkt_type = 0;
  3709. is_tx_fltr = false;
  3710. if (promisc_mask & ICE_PROMISC_UCAST_RX) {
  3711. promisc_mask &= ~ICE_PROMISC_UCAST_RX;
  3712. pkt_type = UCAST_FLTR;
  3713. } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
  3714. promisc_mask &= ~ICE_PROMISC_UCAST_TX;
  3715. pkt_type = UCAST_FLTR;
  3716. is_tx_fltr = true;
  3717. } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
  3718. promisc_mask &= ~ICE_PROMISC_MCAST_RX;
  3719. pkt_type = MCAST_FLTR;
  3720. } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
  3721. promisc_mask &= ~ICE_PROMISC_MCAST_TX;
  3722. pkt_type = MCAST_FLTR;
  3723. is_tx_fltr = true;
  3724. } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
  3725. promisc_mask &= ~ICE_PROMISC_BCAST_RX;
  3726. pkt_type = BCAST_FLTR;
  3727. } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
  3728. promisc_mask &= ~ICE_PROMISC_BCAST_TX;
  3729. pkt_type = BCAST_FLTR;
  3730. is_tx_fltr = true;
  3731. }
  3732. /* Check for VLAN promiscuous flag */
  3733. if (promisc_mask & ICE_PROMISC_VLAN_RX) {
  3734. promisc_mask &= ~ICE_PROMISC_VLAN_RX;
  3735. } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
  3736. promisc_mask &= ~ICE_PROMISC_VLAN_TX;
  3737. is_tx_fltr = true;
  3738. }
  3739. /* Set filter DA based on packet type */
  3740. mac_addr = new_fltr.l_data.mac.mac_addr;
  3741. if (pkt_type == BCAST_FLTR) {
  3742. eth_broadcast_addr(mac_addr);
  3743. } else if (pkt_type == MCAST_FLTR ||
  3744. pkt_type == UCAST_FLTR) {
  3745. /* Use the dummy ether header DA */
  3746. ether_addr_copy(mac_addr, dummy_eth_header);
  3747. if (pkt_type == MCAST_FLTR)
  3748. mac_addr[0] |= 0x1; /* Set multicast bit */
  3749. }
  3750. /* Need to reset this to zero for all iterations */
  3751. new_fltr.flag = 0;
  3752. if (is_tx_fltr) {
  3753. new_fltr.flag |= ICE_FLTR_TX;
  3754. new_fltr.src = hw_vsi_id;
  3755. } else {
  3756. new_fltr.flag |= ICE_FLTR_RX;
  3757. new_fltr.src = hw->port_info->lport;
  3758. }
  3759. new_fltr.fltr_act = ICE_FWD_TO_VSI;
  3760. new_fltr.vsi_handle = vsi_handle;
  3761. new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
  3762. f_list_entry.fltr_info = new_fltr;
  3763. status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
  3764. if (status)
  3765. goto set_promisc_exit;
  3766. }
  3767. set_promisc_exit:
  3768. return status;
  3769. }
  3770. /**
  3771. * ice_set_vlan_vsi_promisc
  3772. * @hw: pointer to the hardware structure
  3773. * @vsi_handle: VSI handle to configure
  3774. * @promisc_mask: mask of promiscuous config bits
  3775. * @rm_vlan_promisc: Clear VLANs VSI promisc mode
  3776. *
  3777. * Configure VSI with all associated VLANs to given promiscuous mode(s)
  3778. */
  3779. int
  3780. ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
  3781. bool rm_vlan_promisc)
  3782. {
  3783. struct ice_switch_info *sw = hw->switch_info;
  3784. struct ice_fltr_list_entry *list_itr, *tmp;
  3785. struct list_head vsi_list_head;
  3786. struct list_head *vlan_head;
  3787. struct mutex *vlan_lock; /* Lock to protect filter rule list */
  3788. u16 vlan_id;
  3789. int status;
  3790. INIT_LIST_HEAD(&vsi_list_head);
  3791. vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
  3792. vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
  3793. mutex_lock(vlan_lock);
  3794. status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
  3795. &vsi_list_head);
  3796. mutex_unlock(vlan_lock);
  3797. if (status)
  3798. goto free_fltr_list;
  3799. list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
  3800. /* Avoid enabling or disabling VLAN zero twice when in double
  3801. * VLAN mode
  3802. */
  3803. if (ice_is_dvm_ena(hw) &&
  3804. list_itr->fltr_info.l_data.vlan.tpid == 0)
  3805. continue;
  3806. vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
  3807. if (rm_vlan_promisc)
  3808. status = ice_clear_vsi_promisc(hw, vsi_handle,
  3809. promisc_mask, vlan_id);
  3810. else
  3811. status = ice_set_vsi_promisc(hw, vsi_handle,
  3812. promisc_mask, vlan_id);
  3813. if (status && status != -EEXIST)
  3814. break;
  3815. }
  3816. free_fltr_list:
  3817. list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
  3818. list_del(&list_itr->list_entry);
  3819. devm_kfree(ice_hw_to_dev(hw), list_itr);
  3820. }
  3821. return status;
  3822. }
  3823. /**
  3824. * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
  3825. * @hw: pointer to the hardware structure
  3826. * @vsi_handle: VSI handle to remove filters from
  3827. * @lkup: switch rule filter lookup type
  3828. */
  3829. static void
  3830. ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
  3831. enum ice_sw_lkup_type lkup)
  3832. {
  3833. struct ice_switch_info *sw = hw->switch_info;
  3834. struct ice_fltr_list_entry *fm_entry;
  3835. struct list_head remove_list_head;
  3836. struct list_head *rule_head;
  3837. struct ice_fltr_list_entry *tmp;
  3838. struct mutex *rule_lock; /* Lock to protect filter rule list */
  3839. int status;
  3840. INIT_LIST_HEAD(&remove_list_head);
  3841. rule_lock = &sw->recp_list[lkup].filt_rule_lock;
  3842. rule_head = &sw->recp_list[lkup].filt_rules;
  3843. mutex_lock(rule_lock);
  3844. status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
  3845. &remove_list_head);
  3846. mutex_unlock(rule_lock);
  3847. if (status)
  3848. goto free_fltr_list;
  3849. switch (lkup) {
  3850. case ICE_SW_LKUP_MAC:
  3851. ice_remove_mac(hw, &remove_list_head);
  3852. break;
  3853. case ICE_SW_LKUP_VLAN:
  3854. ice_remove_vlan(hw, &remove_list_head);
  3855. break;
  3856. case ICE_SW_LKUP_PROMISC:
  3857. case ICE_SW_LKUP_PROMISC_VLAN:
  3858. ice_remove_promisc(hw, lkup, &remove_list_head);
  3859. break;
  3860. case ICE_SW_LKUP_MAC_VLAN:
  3861. case ICE_SW_LKUP_ETHERTYPE:
  3862. case ICE_SW_LKUP_ETHERTYPE_MAC:
  3863. case ICE_SW_LKUP_DFLT:
  3864. case ICE_SW_LKUP_LAST:
  3865. default:
  3866. ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
  3867. break;
  3868. }
  3869. free_fltr_list:
  3870. list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
  3871. list_del(&fm_entry->list_entry);
  3872. devm_kfree(ice_hw_to_dev(hw), fm_entry);
  3873. }
  3874. }
  3875. /**
  3876. * ice_remove_vsi_fltr - Remove all filters for a VSI
  3877. * @hw: pointer to the hardware structure
  3878. * @vsi_handle: VSI handle to remove filters from
  3879. */
  3880. void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
  3881. {
  3882. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
  3883. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
  3884. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
  3885. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
  3886. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
  3887. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
  3888. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
  3889. ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
  3890. }
  3891. /**
  3892. * ice_alloc_res_cntr - allocating resource counter
  3893. * @hw: pointer to the hardware structure
  3894. * @type: type of resource
  3895. * @alloc_shared: if set it is shared else dedicated
  3896. * @num_items: number of entries requested for FD resource type
  3897. * @counter_id: counter index returned by AQ call
  3898. */
  3899. int
  3900. ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
  3901. u16 *counter_id)
  3902. {
  3903. DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
  3904. u16 buf_len = __struct_size(buf);
  3905. int status;
  3906. buf->num_elems = cpu_to_le16(num_items);
  3907. buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
  3908. alloc_shared);
  3909. status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_alloc_res);
  3910. if (status)
  3911. return status;
  3912. *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
  3913. return status;
  3914. }
  3915. /**
  3916. * ice_free_res_cntr - free resource counter
  3917. * @hw: pointer to the hardware structure
  3918. * @type: type of resource
  3919. * @alloc_shared: if set it is shared else dedicated
  3920. * @num_items: number of entries to be freed for FD resource type
  3921. * @counter_id: counter ID resource which needs to be freed
  3922. */
  3923. int
  3924. ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
  3925. u16 counter_id)
  3926. {
  3927. DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
  3928. u16 buf_len = __struct_size(buf);
  3929. int status;
  3930. buf->num_elems = cpu_to_le16(num_items);
  3931. buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
  3932. alloc_shared);
  3933. buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);
  3934. status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_free_res);
  3935. if (status)
  3936. ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
  3937. return status;
  3938. }
  3939. #define ICE_PROTOCOL_ENTRY(id, ...) { \
  3940. .prot_type = id, \
  3941. .offs = {__VA_ARGS__}, \
  3942. }
  3943. /**
  3944. * ice_share_res - set a resource as shared or dedicated
  3945. * @hw: hw struct of original owner of resource
  3946. * @type: resource type
  3947. * @shared: is the resource being set to shared
  3948. * @res_id: resource id (descriptor)
  3949. */
  3950. int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id)
  3951. {
  3952. DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
  3953. u16 buf_len = __struct_size(buf);
  3954. u16 res_type;
  3955. int status;
  3956. buf->num_elems = cpu_to_le16(1);
  3957. res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, type);
  3958. if (shared)
  3959. res_type |= ICE_AQC_RES_TYPE_FLAG_SHARED;
  3960. buf->res_type = cpu_to_le16(res_type);
  3961. buf->elem[0].e.sw_resp = cpu_to_le16(res_id);
  3962. status = ice_aq_alloc_free_res(hw, buf, buf_len,
  3963. ice_aqc_opc_share_res);
  3964. if (status)
  3965. ice_debug(hw, ICE_DBG_SW, "Could not set resource type %u id %u to %s\n",
  3966. type, res_id, shared ? "SHARED" : "DEDICATED");
  3967. return status;
  3968. }
  3969. /* This is mapping table entry that maps every word within a given protocol
  3970. * structure to the real byte offset as per the specification of that
  3971. * protocol header.
  3972. * for example dst address is 3 words in ethertype header and corresponding
  3973. * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
  3974. * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
  3975. * matching entry describing its field. This needs to be updated if new
  3976. * structure is added to that union.
  3977. */
  3978. static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
  3979. ICE_PROTOCOL_ENTRY(ICE_MAC_OFOS, 0, 2, 4, 6, 8, 10, 12),
  3980. ICE_PROTOCOL_ENTRY(ICE_MAC_IL, 0, 2, 4, 6, 8, 10, 12),
  3981. ICE_PROTOCOL_ENTRY(ICE_ETYPE_OL, 0),
  3982. ICE_PROTOCOL_ENTRY(ICE_ETYPE_IL, 0),
  3983. ICE_PROTOCOL_ENTRY(ICE_VLAN_OFOS, 2, 0),
  3984. ICE_PROTOCOL_ENTRY(ICE_IPV4_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
  3985. ICE_PROTOCOL_ENTRY(ICE_IPV4_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
  3986. ICE_PROTOCOL_ENTRY(ICE_IPV6_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
  3987. 20, 22, 24, 26, 28, 30, 32, 34, 36, 38),
  3988. ICE_PROTOCOL_ENTRY(ICE_IPV6_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
  3989. 22, 24, 26, 28, 30, 32, 34, 36, 38),
  3990. ICE_PROTOCOL_ENTRY(ICE_TCP_IL, 0, 2),
  3991. ICE_PROTOCOL_ENTRY(ICE_UDP_OF, 0, 2),
  3992. ICE_PROTOCOL_ENTRY(ICE_UDP_ILOS, 0, 2),
  3993. ICE_PROTOCOL_ENTRY(ICE_VXLAN, 8, 10, 12, 14),
  3994. ICE_PROTOCOL_ENTRY(ICE_GENEVE, 8, 10, 12, 14),
  3995. ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6),
  3996. ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22),
  3997. ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14),
  3998. ICE_PROTOCOL_ENTRY(ICE_PFCP, 8, 10, 12, 14, 16, 18, 20, 22),
  3999. ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6),
  4000. ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10),
  4001. ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0),
  4002. ICE_PROTOCOL_ENTRY(ICE_VLAN_IN, 2, 0),
  4003. ICE_PROTOCOL_ENTRY(ICE_HW_METADATA,
  4004. ICE_SOURCE_PORT_MDID_OFFSET,
  4005. ICE_PTYPE_MDID_OFFSET,
  4006. ICE_PACKET_LENGTH_MDID_OFFSET,
  4007. ICE_SOURCE_VSI_MDID_OFFSET,
  4008. ICE_PKT_VLAN_MDID_OFFSET,
  4009. ICE_PKT_TUNNEL_MDID_OFFSET,
  4010. ICE_PKT_TCP_MDID_OFFSET,
  4011. ICE_PKT_ERROR_MDID_OFFSET),
  4012. };
  4013. static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
  4014. { ICE_MAC_OFOS, ICE_MAC_OFOS_HW },
  4015. { ICE_MAC_IL, ICE_MAC_IL_HW },
  4016. { ICE_ETYPE_OL, ICE_ETYPE_OL_HW },
  4017. { ICE_ETYPE_IL, ICE_ETYPE_IL_HW },
  4018. { ICE_VLAN_OFOS, ICE_VLAN_OL_HW },
  4019. { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW },
  4020. { ICE_IPV4_IL, ICE_IPV4_IL_HW },
  4021. { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW },
  4022. { ICE_IPV6_IL, ICE_IPV6_IL_HW },
  4023. { ICE_TCP_IL, ICE_TCP_IL_HW },
  4024. { ICE_UDP_OF, ICE_UDP_OF_HW },
  4025. { ICE_UDP_ILOS, ICE_UDP_ILOS_HW },
  4026. { ICE_VXLAN, ICE_UDP_OF_HW },
  4027. { ICE_GENEVE, ICE_UDP_OF_HW },
  4028. { ICE_NVGRE, ICE_GRE_OF_HW },
  4029. { ICE_GTP, ICE_UDP_OF_HW },
  4030. { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
  4031. { ICE_PFCP, ICE_UDP_ILOS_HW },
  4032. { ICE_PPPOE, ICE_PPPOE_HW },
  4033. { ICE_L2TPV3, ICE_L2TPV3_HW },
  4034. { ICE_VLAN_EX, ICE_VLAN_OF_HW },
  4035. { ICE_VLAN_IN, ICE_VLAN_OL_HW },
  4036. { ICE_HW_METADATA, ICE_META_DATA_ID_HW },
  4037. };
  4038. /**
  4039. * ice_find_recp - find a recipe
  4040. * @hw: pointer to the hardware structure
  4041. * @lkup_exts: extension sequence to match
  4042. * @rinfo: information regarding the rule e.g. priority and action info
  4043. * @is_add: flag of adding recipe
  4044. *
  4045. * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
  4046. */
  4047. static u16
  4048. ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
  4049. const struct ice_adv_rule_info *rinfo, bool is_add)
  4050. {
  4051. bool refresh_required = true;
  4052. struct ice_sw_recipe *recp;
  4053. u8 i;
  4054. /* Walk through existing recipes to find a match */
  4055. recp = hw->switch_info->recp_list;
  4056. for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
  4057. /* If recipe was not created for this ID, in SW bookkeeping,
  4058. * check if FW has an entry for this recipe. If the FW has an
  4059. * entry update it in our SW bookkeeping and continue with the
  4060. * matching.
  4061. */
  4062. if (hw->recp_reuse) {
  4063. if (ice_get_recp_frm_fw(hw,
  4064. hw->switch_info->recp_list, i,
  4065. &refresh_required, is_add))
  4066. continue;
  4067. }
  4068. /* if number of words we are looking for match */
  4069. if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
  4070. struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
  4071. struct ice_fv_word *be = lkup_exts->fv_words;
  4072. u16 *cr = recp[i].lkup_exts.field_mask;
  4073. u16 *de = lkup_exts->field_mask;
  4074. bool found = true;
  4075. u8 pe, qr;
  4076. /* ar, cr, and qr are related to the recipe words, while
  4077. * be, de, and pe are related to the lookup words
  4078. */
  4079. for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
  4080. for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
  4081. qr++) {
  4082. if (ar[qr].off == be[pe].off &&
  4083. ar[qr].prot_id == be[pe].prot_id &&
  4084. cr[qr] == de[pe])
  4085. /* Found the "pe"th word in the
  4086. * given recipe
  4087. */
  4088. break;
  4089. }
  4090. /* After walking through all the words in the
  4091. * "i"th recipe if "p"th word was not found then
  4092. * this recipe is not what we are looking for.
  4093. * So break out from this loop and try the next
  4094. * recipe
  4095. */
  4096. if (qr >= recp[i].lkup_exts.n_val_words) {
  4097. found = false;
  4098. break;
  4099. }
  4100. }
  4101. /* If for "i"th recipe the found was never set to false
  4102. * then it means we found our match
  4103. * Also tun type and *_pass_l2 of recipe needs to be
  4104. * checked
  4105. */
  4106. if (found && recp[i].tun_type == rinfo->tun_type &&
  4107. recp[i].need_pass_l2 == rinfo->need_pass_l2 &&
  4108. recp[i].allow_pass_l2 == rinfo->allow_pass_l2)
  4109. return i; /* Return the recipe ID */
  4110. }
  4111. }
  4112. return ICE_MAX_NUM_RECIPES;
  4113. }
  4114. /**
  4115. * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
  4116. *
  4117. * As protocol id for outer vlan is different in dvm and svm, if dvm is
  4118. * supported protocol array record for outer vlan has to be modified to
  4119. * reflect the value proper for DVM.
  4120. */
  4121. void ice_change_proto_id_to_dvm(void)
  4122. {
  4123. u8 i;
  4124. for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
  4125. if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
  4126. ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
  4127. ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
  4128. }
  4129. /**
  4130. * ice_prot_type_to_id - get protocol ID from protocol type
  4131. * @type: protocol type
  4132. * @id: pointer to variable that will receive the ID
  4133. *
  4134. * Returns true if found, false otherwise
  4135. */
  4136. static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
  4137. {
  4138. u8 i;
  4139. for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
  4140. if (ice_prot_id_tbl[i].type == type) {
  4141. *id = ice_prot_id_tbl[i].protocol_id;
  4142. return true;
  4143. }
  4144. return false;
  4145. }
  4146. /**
  4147. * ice_fill_valid_words - count valid words
  4148. * @rule: advanced rule with lookup information
  4149. * @lkup_exts: byte offset extractions of the words that are valid
  4150. *
  4151. * calculate valid words in a lookup rule using mask value
  4152. */
  4153. static u8
  4154. ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
  4155. struct ice_prot_lkup_ext *lkup_exts)
  4156. {
  4157. u8 j, word, prot_id, ret_val;
  4158. if (!ice_prot_type_to_id(rule->type, &prot_id))
  4159. return 0;
  4160. word = lkup_exts->n_val_words;
  4161. for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
  4162. if (((u16 *)&rule->m_u)[j] &&
  4163. rule->type < ARRAY_SIZE(ice_prot_ext)) {
  4164. /* No more space to accommodate */
  4165. if (word >= ICE_MAX_CHAIN_WORDS)
  4166. return 0;
  4167. lkup_exts->fv_words[word].off =
  4168. ice_prot_ext[rule->type].offs[j];
  4169. lkup_exts->fv_words[word].prot_id =
  4170. ice_prot_id_tbl[rule->type].protocol_id;
  4171. lkup_exts->field_mask[word] =
  4172. be16_to_cpu(((__force __be16 *)&rule->m_u)[j]);
  4173. word++;
  4174. }
  4175. ret_val = word - lkup_exts->n_val_words;
  4176. lkup_exts->n_val_words = word;
  4177. return ret_val;
  4178. }
  4179. /**
  4180. * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
  4181. * @hw: pointer to the hardware structure
  4182. * @rm: recipe management list entry
  4183. *
  4184. * Helper function to fill in the field vector indices for protocol-offset
  4185. * pairs. These indexes are then ultimately programmed into a recipe.
  4186. */
  4187. static int
  4188. ice_fill_fv_word_index(struct ice_hw *hw, struct ice_sw_recipe *rm)
  4189. {
  4190. struct ice_sw_fv_list_entry *fv;
  4191. struct ice_fv_word *fv_ext;
  4192. u8 i;
  4193. if (list_empty(&rm->fv_list))
  4194. return -EINVAL;
  4195. fv = list_first_entry(&rm->fv_list, struct ice_sw_fv_list_entry,
  4196. list_entry);
  4197. fv_ext = fv->fv_ptr->ew;
  4198. /* Add switch id as the first word. */
  4199. rm->fv_idx[0] = ICE_AQ_SW_ID_LKUP_IDX;
  4200. rm->fv_mask[0] = ICE_AQ_SW_ID_LKUP_MASK;
  4201. rm->n_ext_words++;
  4202. for (i = 1; i < rm->n_ext_words; i++) {
  4203. struct ice_fv_word *fv_word = &rm->ext_words[i - 1];
  4204. u16 fv_mask = rm->word_masks[i - 1];
  4205. bool found = false;
  4206. u8 j;
  4207. for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) {
  4208. if (fv_ext[j].prot_id == fv_word->prot_id &&
  4209. fv_ext[j].off == fv_word->off) {
  4210. found = true;
  4211. /* Store index of field vector */
  4212. rm->fv_idx[i] = j;
  4213. rm->fv_mask[i] = fv_mask;
  4214. break;
  4215. }
  4216. }
  4217. /* Protocol/offset could not be found, caller gave an invalid
  4218. * pair.
  4219. */
  4220. if (!found)
  4221. return -EINVAL;
  4222. }
  4223. return 0;
  4224. }
  4225. /**
  4226. * ice_find_free_recp_res_idx - find free result indexes for recipe
  4227. * @hw: pointer to hardware structure
  4228. * @profiles: bitmap of profiles that will be associated with the new recipe
  4229. * @free_idx: pointer to variable to receive the free index bitmap
  4230. *
  4231. * The algorithm used here is:
  4232. * 1. When creating a new recipe, create a set P which contains all
  4233. * Profiles that will be associated with our new recipe
  4234. *
  4235. * 2. For each Profile p in set P:
  4236. * a. Add all recipes associated with Profile p into set R
  4237. * b. Optional : PossibleIndexes &= profile[p].possibleIndexes
  4238. * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
  4239. * i. Or just assume they all have the same possible indexes:
  4240. * 44, 45, 46, 47
  4241. * i.e., PossibleIndexes = 0x0000F00000000000
  4242. *
  4243. * 3. For each Recipe r in set R:
  4244. * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
  4245. * b. FreeIndexes = UsedIndexes ^ PossibleIndexes
  4246. *
  4247. * FreeIndexes will contain the bits indicating the indexes free for use,
  4248. * then the code needs to update the recipe[r].used_result_idx_bits to
  4249. * indicate which indexes were selected for use by this recipe.
  4250. */
  4251. static u16
  4252. ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
  4253. unsigned long *free_idx)
  4254. {
  4255. DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
  4256. DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES);
  4257. DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS);
  4258. u16 bit;
  4259. bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
  4260. bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
  4261. bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
  4262. /* For each profile we are going to associate the recipe with, add the
  4263. * recipes that are associated with that profile. This will give us
  4264. * the set of recipes that our recipe may collide with. Also, determine
  4265. * what possible result indexes are usable given this set of profiles.
  4266. */
  4267. for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
  4268. bitmap_or(recipes, recipes, profile_to_recipe[bit],
  4269. ICE_MAX_NUM_RECIPES);
  4270. bitmap_and(possible_idx, possible_idx,
  4271. hw->switch_info->prof_res_bm[bit],
  4272. ICE_MAX_FV_WORDS);
  4273. }
  4274. /* For each recipe that our new recipe may collide with, determine
  4275. * which indexes have been used.
  4276. */
  4277. for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
  4278. bitmap_or(used_idx, used_idx,
  4279. hw->switch_info->recp_list[bit].res_idxs,
  4280. ICE_MAX_FV_WORDS);
  4281. bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
  4282. /* return number of free indexes */
  4283. return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS);
  4284. }
  4285. /**
  4286. * ice_calc_recp_cnt - calculate number of recipes based on word count
  4287. * @word_cnt: number of lookup words
  4288. *
  4289. * Word count should include switch ID word and regular lookup words.
  4290. * Returns: number of recipes required to fit @word_cnt, including extra recipes
  4291. * needed for recipe chaining (if needed).
  4292. */
  4293. static int ice_calc_recp_cnt(u8 word_cnt)
  4294. {
  4295. /* All words fit in a single recipe, no need for chaining. */
  4296. if (word_cnt <= ICE_NUM_WORDS_RECIPE)
  4297. return 1;
  4298. /* Recipe chaining required. Result indexes are fitted right after
  4299. * regular lookup words. In some cases a new recipe must be added in
  4300. * order to fit result indexes.
  4301. *
  4302. * While the word count increases, every 5 words an extra recipe needs
  4303. * to be added. However, by adding a recipe, one word for its result
  4304. * index must also be added, therefore every 4 words recipe count
  4305. * increases by 1. This calculation does not apply to word count == 1,
  4306. * which is handled above.
  4307. */
  4308. return (word_cnt + 2) / (ICE_NUM_WORDS_RECIPE - 1);
  4309. }
  4310. static void fill_recipe_template(struct ice_aqc_recipe_data_elem *recp, u16 rid,
  4311. const struct ice_sw_recipe *rm)
  4312. {
  4313. int i;
  4314. recp->recipe_indx = rid;
  4315. recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_PRUNE_INDX_M;
  4316. for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
  4317. recp->content.lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE;
  4318. recp->content.mask[i] = cpu_to_le16(0);
  4319. }
  4320. set_bit(rid, (unsigned long *)recp->recipe_bitmap);
  4321. recp->content.act_ctrl_fwd_priority = rm->priority;
  4322. if (rm->need_pass_l2)
  4323. recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2;
  4324. if (rm->allow_pass_l2)
  4325. recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2;
  4326. }
  4327. static void bookkeep_recipe(struct ice_sw_recipe *recipe,
  4328. struct ice_aqc_recipe_data_elem *r,
  4329. const struct ice_sw_recipe *rm)
  4330. {
  4331. memcpy(recipe->r_bitmap, r->recipe_bitmap, sizeof(recipe->r_bitmap));
  4332. recipe->priority = r->content.act_ctrl_fwd_priority;
  4333. recipe->tun_type = rm->tun_type;
  4334. recipe->need_pass_l2 = rm->need_pass_l2;
  4335. recipe->allow_pass_l2 = rm->allow_pass_l2;
  4336. recipe->recp_created = true;
  4337. }
  4338. /* For memcpy in ice_add_sw_recipe. */
  4339. static_assert(sizeof_field(struct ice_aqc_recipe_data_elem, recipe_bitmap) ==
  4340. sizeof_field(struct ice_sw_recipe, r_bitmap));
  4341. /**
  4342. * ice_add_sw_recipe - function to call AQ calls to create switch recipe
  4343. * @hw: pointer to hardware structure
  4344. * @rm: recipe management list entry
  4345. * @profiles: bitmap of profiles that will be associated.
  4346. */
  4347. static int
  4348. ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
  4349. unsigned long *profiles)
  4350. {
  4351. struct ice_aqc_recipe_data_elem *buf __free(kfree) = NULL;
  4352. DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
  4353. struct ice_aqc_recipe_data_elem *root;
  4354. struct ice_sw_recipe *recipe;
  4355. u16 free_res_idx, rid;
  4356. int lookup = 0;
  4357. int recp_cnt;
  4358. int status;
  4359. int word;
  4360. int i;
  4361. recp_cnt = ice_calc_recp_cnt(rm->n_ext_words);
  4362. bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS);
  4363. bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
  4364. /* Check number of free result indices */
  4365. free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
  4366. ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
  4367. free_res_idx, recp_cnt);
  4368. /* Last recipe doesn't need result index */
  4369. if (recp_cnt - 1 > free_res_idx)
  4370. return -ENOSPC;
  4371. if (recp_cnt > ICE_MAX_CHAIN_RECIPE_RES)
  4372. return -E2BIG;
  4373. buf = kcalloc(recp_cnt, sizeof(*buf), GFP_KERNEL);
  4374. if (!buf)
  4375. return -ENOMEM;
  4376. /* Setup the non-root subrecipes. These do not contain lookups for other
  4377. * subrecipes results. Set associated recipe only to own recipe index.
  4378. * Each non-root subrecipe needs a free result index from FV.
  4379. *
  4380. * Note: only done if there is more than one recipe.
  4381. */
  4382. for (i = 0; i < recp_cnt - 1; i++) {
  4383. struct ice_aqc_recipe_content *content;
  4384. u8 result_idx;
  4385. status = ice_alloc_recipe(hw, &rid);
  4386. if (status)
  4387. return status;
  4388. fill_recipe_template(&buf[i], rid, rm);
  4389. result_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
  4390. /* Check if there really is a valid result index that can be
  4391. * used.
  4392. */
  4393. if (result_idx >= ICE_MAX_FV_WORDS) {
  4394. ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
  4395. return -ENOSPC;
  4396. }
  4397. clear_bit(result_idx, result_idx_bm);
  4398. content = &buf[i].content;
  4399. content->result_indx = ICE_AQ_RECIPE_RESULT_EN |
  4400. FIELD_PREP(ICE_AQ_RECIPE_RESULT_DATA_M,
  4401. result_idx);
  4402. /* Set recipe association to be used for root recipe */
  4403. set_bit(rid, rm->r_bitmap);
  4404. word = 0;
  4405. while (lookup < rm->n_ext_words &&
  4406. word < ICE_NUM_WORDS_RECIPE) {
  4407. content->lkup_indx[word] = rm->fv_idx[lookup];
  4408. content->mask[word] = cpu_to_le16(rm->fv_mask[lookup]);
  4409. lookup++;
  4410. word++;
  4411. }
  4412. recipe = &hw->switch_info->recp_list[rid];
  4413. set_bit(result_idx, recipe->res_idxs);
  4414. bookkeep_recipe(recipe, &buf[i], rm);
  4415. }
  4416. /* Setup the root recipe */
  4417. status = ice_alloc_recipe(hw, &rid);
  4418. if (status)
  4419. return status;
  4420. recipe = &hw->switch_info->recp_list[rid];
  4421. root = &buf[recp_cnt - 1];
  4422. fill_recipe_template(root, rid, rm);
  4423. /* Set recipe association, use previously set bitmap and own rid */
  4424. set_bit(rid, rm->r_bitmap);
  4425. memcpy(root->recipe_bitmap, rm->r_bitmap, sizeof(root->recipe_bitmap));
  4426. /* For non-root recipes rid should be 0, for root it should be correct
  4427. * rid value ored with 0x80 (is root bit).
  4428. */
  4429. root->content.rid = rid | ICE_AQ_RECIPE_ID_IS_ROOT;
  4430. /* Fill remaining lookups in root recipe */
  4431. word = 0;
  4432. while (lookup < rm->n_ext_words &&
  4433. word < ICE_NUM_WORDS_RECIPE /* should always be true */) {
  4434. root->content.lkup_indx[word] = rm->fv_idx[lookup];
  4435. root->content.mask[word] = cpu_to_le16(rm->fv_mask[lookup]);
  4436. lookup++;
  4437. word++;
  4438. }
  4439. /* Fill result indexes as lookups */
  4440. i = 0;
  4441. while (i < recp_cnt - 1 &&
  4442. word < ICE_NUM_WORDS_RECIPE /* should always be true */) {
  4443. root->content.lkup_indx[word] = buf[i].content.result_indx &
  4444. ~ICE_AQ_RECIPE_RESULT_EN;
  4445. root->content.mask[word] = cpu_to_le16(0xffff);
  4446. /* For bookkeeping, it is needed to mark FV index as used for
  4447. * intermediate result.
  4448. */
  4449. set_bit(root->content.lkup_indx[word], recipe->res_idxs);
  4450. i++;
  4451. word++;
  4452. }
  4453. rm->root_rid = rid;
  4454. bookkeep_recipe(&hw->switch_info->recp_list[rid], root, rm);
  4455. /* Program the recipe */
  4456. status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
  4457. if (status)
  4458. return status;
  4459. status = ice_aq_add_recipe(hw, buf, recp_cnt, NULL);
  4460. ice_release_change_lock(hw);
  4461. if (status)
  4462. return status;
  4463. return 0;
  4464. }
  4465. /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
  4466. * @hw: pointer to hardware structure
  4467. * @rinfo: other information regarding the rule e.g. priority and action info
  4468. * @bm: pointer to memory for returning the bitmap of field vectors
  4469. */
  4470. static void
  4471. ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
  4472. unsigned long *bm)
  4473. {
  4474. enum ice_prof_type prof_type;
  4475. bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
  4476. switch (rinfo->tun_type) {
  4477. case ICE_NON_TUN:
  4478. prof_type = ICE_PROF_NON_TUN;
  4479. break;
  4480. case ICE_ALL_TUNNELS:
  4481. prof_type = ICE_PROF_TUN_ALL;
  4482. break;
  4483. case ICE_SW_TUN_GENEVE:
  4484. case ICE_SW_TUN_VXLAN:
  4485. prof_type = ICE_PROF_TUN_UDP;
  4486. break;
  4487. case ICE_SW_TUN_NVGRE:
  4488. prof_type = ICE_PROF_TUN_GRE;
  4489. break;
  4490. case ICE_SW_TUN_GTPU:
  4491. prof_type = ICE_PROF_TUN_GTPU;
  4492. break;
  4493. case ICE_SW_TUN_GTPC:
  4494. prof_type = ICE_PROF_TUN_GTPC;
  4495. break;
  4496. case ICE_SW_TUN_PFCP:
  4497. prof_type = ICE_PROF_TUN_PFCP;
  4498. break;
  4499. case ICE_SW_TUN_AND_NON_TUN:
  4500. default:
  4501. prof_type = ICE_PROF_ALL;
  4502. break;
  4503. }
  4504. ice_get_sw_fv_bitmap(hw, prof_type, bm);
  4505. }
  4506. /**
  4507. * ice_subscribe_recipe - subscribe to an existing recipe
  4508. * @hw: pointer to the hardware structure
  4509. * @rid: recipe ID to subscribe to
  4510. *
  4511. * Return: 0 on success, and others on error
  4512. */
  4513. static int ice_subscribe_recipe(struct ice_hw *hw, u16 rid)
  4514. {
  4515. DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
  4516. u16 buf_len = __struct_size(sw_buf);
  4517. u16 res_type;
  4518. int status;
  4519. /* Prepare buffer to allocate resource */
  4520. sw_buf->num_elems = cpu_to_le16(1);
  4521. res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, ICE_AQC_RES_TYPE_RECIPE) |
  4522. ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_SHARED |
  4523. ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_CTL;
  4524. sw_buf->res_type = cpu_to_le16(res_type);
  4525. sw_buf->elem[0].e.sw_resp = cpu_to_le16(rid);
  4526. status = ice_aq_alloc_free_res(hw, sw_buf, buf_len,
  4527. ice_aqc_opc_alloc_res);
  4528. return status;
  4529. }
  4530. /**
  4531. * ice_subscribable_recp_shared - share an existing subscribable recipe
  4532. * @hw: pointer to the hardware structure
  4533. * @rid: recipe ID to subscribe to
  4534. */
  4535. static void ice_subscribable_recp_shared(struct ice_hw *hw, u16 rid)
  4536. {
  4537. struct ice_sw_recipe *recps = hw->switch_info->recp_list;
  4538. u16 sub_rid;
  4539. for_each_set_bit(sub_rid, recps[rid].r_bitmap, ICE_MAX_NUM_RECIPES)
  4540. ice_subscribe_recipe(hw, sub_rid);
  4541. }
  4542. /**
  4543. * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
  4544. * @hw: pointer to hardware structure
  4545. * @lkups: lookup elements or match criteria for the advanced recipe, one
  4546. * structure per protocol header
  4547. * @lkups_cnt: number of protocols
  4548. * @rinfo: other information regarding the rule e.g. priority and action info
  4549. * @rid: return the recipe ID of the recipe created
  4550. */
  4551. static int
  4552. ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
  4553. u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
  4554. {
  4555. DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES);
  4556. DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES);
  4557. struct ice_prot_lkup_ext *lkup_exts;
  4558. struct ice_sw_fv_list_entry *fvit;
  4559. struct ice_sw_fv_list_entry *tmp;
  4560. struct ice_sw_recipe *rm;
  4561. int status = 0;
  4562. u16 rid_tmp;
  4563. u8 i;
  4564. if (!lkups_cnt)
  4565. return -EINVAL;
  4566. lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL);
  4567. if (!lkup_exts)
  4568. return -ENOMEM;
  4569. /* Determine the number of words to be matched and if it exceeds a
  4570. * recipe's restrictions
  4571. */
  4572. for (i = 0; i < lkups_cnt; i++) {
  4573. u16 count;
  4574. if (lkups[i].type >= ICE_PROTOCOL_LAST) {
  4575. status = -EIO;
  4576. goto err_free_lkup_exts;
  4577. }
  4578. count = ice_fill_valid_words(&lkups[i], lkup_exts);
  4579. if (!count) {
  4580. status = -EIO;
  4581. goto err_free_lkup_exts;
  4582. }
  4583. }
  4584. rm = kzalloc(sizeof(*rm), GFP_KERNEL);
  4585. if (!rm) {
  4586. status = -ENOMEM;
  4587. goto err_free_lkup_exts;
  4588. }
  4589. /* Get field vectors that contain fields extracted from all the protocol
  4590. * headers being programmed.
  4591. */
  4592. INIT_LIST_HEAD(&rm->fv_list);
  4593. /* Get bitmap of field vectors (profiles) that are compatible with the
  4594. * rule request; only these will be searched in the subsequent call to
  4595. * ice_get_sw_fv_list.
  4596. */
  4597. ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
  4598. status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
  4599. if (status)
  4600. goto err_unroll;
  4601. /* Copy FV words and masks from lkup_exts to recipe struct. */
  4602. rm->n_ext_words = lkup_exts->n_val_words;
  4603. memcpy(rm->ext_words, lkup_exts->fv_words, sizeof(rm->ext_words));
  4604. memcpy(rm->word_masks, lkup_exts->field_mask, sizeof(rm->word_masks));
  4605. /* set the recipe priority if specified */
  4606. rm->priority = (u8)rinfo->priority;
  4607. rm->need_pass_l2 = rinfo->need_pass_l2;
  4608. rm->allow_pass_l2 = rinfo->allow_pass_l2;
  4609. /* Find offsets from the field vector. Pick the first one for all the
  4610. * recipes.
  4611. */
  4612. status = ice_fill_fv_word_index(hw, rm);
  4613. if (status)
  4614. goto err_unroll;
  4615. /* get bitmap of all profiles the recipe will be associated with */
  4616. bitmap_zero(profiles, ICE_MAX_NUM_PROFILES);
  4617. list_for_each_entry(fvit, &rm->fv_list, list_entry) {
  4618. ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
  4619. set_bit((u16)fvit->profile_id, profiles);
  4620. }
  4621. /* Look for a recipe which matches our requested fv / mask list */
  4622. *rid = ice_find_recp(hw, lkup_exts, rinfo, true);
  4623. if (*rid < ICE_MAX_NUM_RECIPES) {
  4624. /* Success if found a recipe that match the existing criteria */
  4625. if (hw->recp_reuse)
  4626. ice_subscribable_recp_shared(hw, *rid);
  4627. goto err_unroll;
  4628. }
  4629. rm->tun_type = rinfo->tun_type;
  4630. /* Recipe we need does not exist, add a recipe */
  4631. status = ice_add_sw_recipe(hw, rm, profiles);
  4632. if (status)
  4633. goto err_unroll;
  4634. /* Associate all the recipes created with all the profiles in the
  4635. * common field vector.
  4636. */
  4637. list_for_each_entry(fvit, &rm->fv_list, list_entry) {
  4638. DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
  4639. u64 recp_assoc;
  4640. u16 j;
  4641. status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
  4642. &recp_assoc, NULL);
  4643. if (status)
  4644. goto err_free_recipe;
  4645. bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
  4646. bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
  4647. ICE_MAX_NUM_RECIPES);
  4648. status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
  4649. if (status)
  4650. goto err_free_recipe;
  4651. bitmap_to_arr64(&recp_assoc, r_bitmap, ICE_MAX_NUM_RECIPES);
  4652. status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
  4653. recp_assoc, NULL);
  4654. ice_release_change_lock(hw);
  4655. if (status)
  4656. goto err_free_recipe;
  4657. /* Update profile to recipe bitmap array */
  4658. bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap,
  4659. ICE_MAX_NUM_RECIPES);
  4660. /* Update recipe to profile bitmap array */
  4661. for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
  4662. set_bit((u16)fvit->profile_id, recipe_to_profile[j]);
  4663. }
  4664. *rid = rm->root_rid;
  4665. memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts,
  4666. sizeof(*lkup_exts));
  4667. goto err_unroll;
  4668. err_free_recipe:
  4669. if (hw->recp_reuse) {
  4670. for_each_set_bit(rid_tmp, rm->r_bitmap, ICE_MAX_NUM_RECIPES) {
  4671. if (!ice_free_recipe_res(hw, rid_tmp))
  4672. clear_bit(rid_tmp, rm->r_bitmap);
  4673. }
  4674. }
  4675. err_unroll:
  4676. list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) {
  4677. list_del(&fvit->list_entry);
  4678. devm_kfree(ice_hw_to_dev(hw), fvit);
  4679. }
  4680. kfree(rm);
  4681. err_free_lkup_exts:
  4682. kfree(lkup_exts);
  4683. return status;
  4684. }
  4685. /**
  4686. * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt
  4687. *
  4688. * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added
  4689. * @num_vlan: number of VLAN tags
  4690. */
  4691. static struct ice_dummy_pkt_profile *
  4692. ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt,
  4693. u32 num_vlan)
  4694. {
  4695. struct ice_dummy_pkt_profile *profile;
  4696. struct ice_dummy_pkt_offsets *offsets;
  4697. u32 buf_len, off, etype_off, i;
  4698. u8 *pkt;
  4699. if (num_vlan < 1 || num_vlan > 2)
  4700. return ERR_PTR(-EINVAL);
  4701. off = num_vlan * VLAN_HLEN;
  4702. buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) +
  4703. dummy_pkt->offsets_len;
  4704. offsets = kzalloc(buf_len, GFP_KERNEL);
  4705. if (!offsets)
  4706. return ERR_PTR(-ENOMEM);
  4707. offsets[0] = dummy_pkt->offsets[0];
  4708. if (num_vlan == 2) {
  4709. offsets[1] = ice_dummy_qinq_packet_offsets[0];
  4710. offsets[2] = ice_dummy_qinq_packet_offsets[1];
  4711. } else if (num_vlan == 1) {
  4712. offsets[1] = ice_dummy_vlan_packet_offsets[0];
  4713. }
  4714. for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) {
  4715. offsets[i + num_vlan].type = dummy_pkt->offsets[i].type;
  4716. offsets[i + num_vlan].offset =
  4717. dummy_pkt->offsets[i].offset + off;
  4718. }
  4719. offsets[i + num_vlan] = dummy_pkt->offsets[i];
  4720. etype_off = dummy_pkt->offsets[1].offset;
  4721. buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) +
  4722. dummy_pkt->pkt_len;
  4723. pkt = kzalloc(buf_len, GFP_KERNEL);
  4724. if (!pkt) {
  4725. kfree(offsets);
  4726. return ERR_PTR(-ENOMEM);
  4727. }
  4728. memcpy(pkt, dummy_pkt->pkt, etype_off);
  4729. memcpy(pkt + etype_off,
  4730. num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet,
  4731. off);
  4732. memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off,
  4733. dummy_pkt->pkt_len - etype_off);
  4734. profile = kzalloc(sizeof(*profile), GFP_KERNEL);
  4735. if (!profile) {
  4736. kfree(offsets);
  4737. kfree(pkt);
  4738. return ERR_PTR(-ENOMEM);
  4739. }
  4740. profile->offsets = offsets;
  4741. profile->pkt = pkt;
  4742. profile->pkt_len = buf_len;
  4743. profile->match |= ICE_PKT_KMALLOC;
  4744. return profile;
  4745. }
  4746. /**
  4747. * ice_find_dummy_packet - find dummy packet
  4748. *
  4749. * @lkups: lookup elements or match criteria for the advanced recipe, one
  4750. * structure per protocol header
  4751. * @lkups_cnt: number of protocols
  4752. * @tun_type: tunnel type
  4753. *
  4754. * Returns the &ice_dummy_pkt_profile corresponding to these lookup params.
  4755. */
  4756. static const struct ice_dummy_pkt_profile *
  4757. ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
  4758. enum ice_sw_tunnel_type tun_type)
  4759. {
  4760. const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles;
  4761. u32 match = 0, vlan_count = 0;
  4762. u16 i;
  4763. switch (tun_type) {
  4764. case ICE_SW_TUN_GTPC:
  4765. match |= ICE_PKT_TUN_GTPC;
  4766. break;
  4767. case ICE_SW_TUN_GTPU:
  4768. match |= ICE_PKT_TUN_GTPU;
  4769. break;
  4770. case ICE_SW_TUN_NVGRE:
  4771. match |= ICE_PKT_TUN_NVGRE;
  4772. break;
  4773. case ICE_SW_TUN_GENEVE:
  4774. case ICE_SW_TUN_VXLAN:
  4775. match |= ICE_PKT_TUN_UDP;
  4776. break;
  4777. case ICE_SW_TUN_PFCP:
  4778. match |= ICE_PKT_PFCP;
  4779. break;
  4780. default:
  4781. break;
  4782. }
  4783. for (i = 0; i < lkups_cnt; i++) {
  4784. if (lkups[i].type == ICE_UDP_ILOS)
  4785. match |= ICE_PKT_INNER_UDP;
  4786. else if (lkups[i].type == ICE_TCP_IL)
  4787. match |= ICE_PKT_INNER_TCP;
  4788. else if (lkups[i].type == ICE_IPV6_OFOS)
  4789. match |= ICE_PKT_OUTER_IPV6;
  4790. else if (lkups[i].type == ICE_VLAN_OFOS ||
  4791. lkups[i].type == ICE_VLAN_EX)
  4792. vlan_count++;
  4793. else if (lkups[i].type == ICE_VLAN_IN)
  4794. vlan_count++;
  4795. else if (lkups[i].type == ICE_ETYPE_OL &&
  4796. lkups[i].h_u.ethertype.ethtype_id ==
  4797. cpu_to_be16(ICE_IPV6_ETHER_ID) &&
  4798. lkups[i].m_u.ethertype.ethtype_id ==
  4799. cpu_to_be16(0xFFFF))
  4800. match |= ICE_PKT_OUTER_IPV6;
  4801. else if (lkups[i].type == ICE_ETYPE_IL &&
  4802. lkups[i].h_u.ethertype.ethtype_id ==
  4803. cpu_to_be16(ICE_IPV6_ETHER_ID) &&
  4804. lkups[i].m_u.ethertype.ethtype_id ==
  4805. cpu_to_be16(0xFFFF))
  4806. match |= ICE_PKT_INNER_IPV6;
  4807. else if (lkups[i].type == ICE_IPV6_IL)
  4808. match |= ICE_PKT_INNER_IPV6;
  4809. else if (lkups[i].type == ICE_GTP_NO_PAY)
  4810. match |= ICE_PKT_GTP_NOPAY;
  4811. else if (lkups[i].type == ICE_PPPOE) {
  4812. match |= ICE_PKT_PPPOE;
  4813. if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
  4814. htons(PPP_IPV6))
  4815. match |= ICE_PKT_OUTER_IPV6;
  4816. } else if (lkups[i].type == ICE_L2TPV3)
  4817. match |= ICE_PKT_L2TPV3;
  4818. }
  4819. while (ret->match && (match & ret->match) != ret->match)
  4820. ret++;
  4821. if (vlan_count != 0)
  4822. ret = ice_dummy_packet_add_vlan(ret, vlan_count);
  4823. return ret;
  4824. }
  4825. /**
  4826. * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
  4827. *
  4828. * @lkups: lookup elements or match criteria for the advanced recipe, one
  4829. * structure per protocol header
  4830. * @lkups_cnt: number of protocols
  4831. * @s_rule: stores rule information from the match criteria
  4832. * @profile: dummy packet profile (the template, its size and header offsets)
  4833. */
  4834. static int
  4835. ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
  4836. struct ice_sw_rule_lkup_rx_tx *s_rule,
  4837. const struct ice_dummy_pkt_profile *profile)
  4838. {
  4839. u8 *pkt;
  4840. u16 i;
  4841. /* Start with a packet with a pre-defined/dummy content. Then, fill
  4842. * in the header values to be looked up or matched.
  4843. */
  4844. pkt = s_rule->hdr_data;
  4845. memcpy(pkt, profile->pkt, profile->pkt_len);
  4846. for (i = 0; i < lkups_cnt; i++) {
  4847. const struct ice_dummy_pkt_offsets *offsets = profile->offsets;
  4848. enum ice_protocol_type type;
  4849. u16 offset = 0, len = 0, j;
  4850. bool found = false;
  4851. /* find the start of this layer; it should be found since this
  4852. * was already checked when search for the dummy packet
  4853. */
  4854. type = lkups[i].type;
  4855. /* metadata isn't present in the packet */
  4856. if (type == ICE_HW_METADATA)
  4857. continue;
  4858. for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
  4859. if (type == offsets[j].type) {
  4860. offset = offsets[j].offset;
  4861. found = true;
  4862. break;
  4863. }
  4864. }
  4865. /* this should never happen in a correct calling sequence */
  4866. if (!found)
  4867. return -EINVAL;
  4868. switch (lkups[i].type) {
  4869. case ICE_MAC_OFOS:
  4870. case ICE_MAC_IL:
  4871. len = sizeof(struct ice_ether_hdr);
  4872. break;
  4873. case ICE_ETYPE_OL:
  4874. case ICE_ETYPE_IL:
  4875. len = sizeof(struct ice_ethtype_hdr);
  4876. break;
  4877. case ICE_VLAN_OFOS:
  4878. case ICE_VLAN_EX:
  4879. case ICE_VLAN_IN:
  4880. len = sizeof(struct ice_vlan_hdr);
  4881. break;
  4882. case ICE_IPV4_OFOS:
  4883. case ICE_IPV4_IL:
  4884. len = sizeof(struct ice_ipv4_hdr);
  4885. break;
  4886. case ICE_IPV6_OFOS:
  4887. case ICE_IPV6_IL:
  4888. len = sizeof(struct ice_ipv6_hdr);
  4889. break;
  4890. case ICE_TCP_IL:
  4891. case ICE_UDP_OF:
  4892. case ICE_UDP_ILOS:
  4893. len = sizeof(struct ice_l4_hdr);
  4894. break;
  4895. case ICE_SCTP_IL:
  4896. len = sizeof(struct ice_sctp_hdr);
  4897. break;
  4898. case ICE_NVGRE:
  4899. len = sizeof(struct ice_nvgre_hdr);
  4900. break;
  4901. case ICE_VXLAN:
  4902. case ICE_GENEVE:
  4903. len = sizeof(struct ice_udp_tnl_hdr);
  4904. break;
  4905. case ICE_GTP_NO_PAY:
  4906. case ICE_GTP:
  4907. len = sizeof(struct ice_udp_gtp_hdr);
  4908. break;
  4909. case ICE_PFCP:
  4910. len = sizeof(struct ice_pfcp_hdr);
  4911. break;
  4912. case ICE_PPPOE:
  4913. len = sizeof(struct ice_pppoe_hdr);
  4914. break;
  4915. case ICE_L2TPV3:
  4916. len = sizeof(struct ice_l2tpv3_sess_hdr);
  4917. break;
  4918. default:
  4919. return -EINVAL;
  4920. }
  4921. /* the length should be a word multiple */
  4922. if (len % ICE_BYTES_PER_WORD)
  4923. return -EIO;
  4924. /* We have the offset to the header start, the length, the
  4925. * caller's header values and mask. Use this information to
  4926. * copy the data into the dummy packet appropriately based on
  4927. * the mask. Note that we need to only write the bits as
  4928. * indicated by the mask to make sure we don't improperly write
  4929. * over any significant packet data.
  4930. */
  4931. for (j = 0; j < len / sizeof(u16); j++) {
  4932. u16 *ptr = (u16 *)(pkt + offset);
  4933. u16 mask = lkups[i].m_raw[j];
  4934. if (!mask)
  4935. continue;
  4936. ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask);
  4937. }
  4938. }
  4939. s_rule->hdr_len = cpu_to_le16(profile->pkt_len);
  4940. return 0;
  4941. }
  4942. /**
  4943. * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
  4944. * @hw: pointer to the hardware structure
  4945. * @tun_type: tunnel type
  4946. * @pkt: dummy packet to fill in
  4947. * @offsets: offset info for the dummy packet
  4948. */
  4949. static int
  4950. ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
  4951. u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
  4952. {
  4953. u16 open_port, i;
  4954. switch (tun_type) {
  4955. case ICE_SW_TUN_VXLAN:
  4956. if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
  4957. return -EIO;
  4958. break;
  4959. case ICE_SW_TUN_GENEVE:
  4960. if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
  4961. return -EIO;
  4962. break;
  4963. default:
  4964. /* Nothing needs to be done for this tunnel type */
  4965. return 0;
  4966. }
  4967. /* Find the outer UDP protocol header and insert the port number */
  4968. for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
  4969. if (offsets[i].type == ICE_UDP_OF) {
  4970. struct ice_l4_hdr *hdr;
  4971. u16 offset;
  4972. offset = offsets[i].offset;
  4973. hdr = (struct ice_l4_hdr *)&pkt[offset];
  4974. hdr->dst_port = cpu_to_be16(open_port);
  4975. return 0;
  4976. }
  4977. }
  4978. return -EIO;
  4979. }
  4980. /**
  4981. * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type
  4982. * @hw: pointer to hw structure
  4983. * @vlan_type: VLAN tag type
  4984. * @pkt: dummy packet to fill in
  4985. * @offsets: offset info for the dummy packet
  4986. */
  4987. static int
  4988. ice_fill_adv_packet_vlan(struct ice_hw *hw, u16 vlan_type, u8 *pkt,
  4989. const struct ice_dummy_pkt_offsets *offsets)
  4990. {
  4991. u16 i;
  4992. /* Check if there is something to do */
  4993. if (!vlan_type || !ice_is_dvm_ena(hw))
  4994. return 0;
  4995. /* Find VLAN header and insert VLAN TPID */
  4996. for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
  4997. if (offsets[i].type == ICE_VLAN_OFOS ||
  4998. offsets[i].type == ICE_VLAN_EX) {
  4999. struct ice_vlan_hdr *hdr;
  5000. u16 offset;
  5001. offset = offsets[i].offset;
  5002. hdr = (struct ice_vlan_hdr *)&pkt[offset];
  5003. hdr->type = cpu_to_be16(vlan_type);
  5004. return 0;
  5005. }
  5006. }
  5007. return -EIO;
  5008. }
  5009. static bool ice_rules_equal(const struct ice_adv_rule_info *first,
  5010. const struct ice_adv_rule_info *second)
  5011. {
  5012. return first->sw_act.flag == second->sw_act.flag &&
  5013. first->tun_type == second->tun_type &&
  5014. first->vlan_type == second->vlan_type &&
  5015. first->src_vsi == second->src_vsi &&
  5016. first->need_pass_l2 == second->need_pass_l2 &&
  5017. first->allow_pass_l2 == second->allow_pass_l2;
  5018. }
  5019. /**
  5020. * ice_find_adv_rule_entry - Search a rule entry
  5021. * @hw: pointer to the hardware structure
  5022. * @lkups: lookup elements or match criteria for the advanced recipe, one
  5023. * structure per protocol header
  5024. * @lkups_cnt: number of protocols
  5025. * @recp_id: recipe ID for which we are finding the rule
  5026. * @rinfo: other information regarding the rule e.g. priority and action info
  5027. *
  5028. * Helper function to search for a given advance rule entry
  5029. * Returns pointer to entry storing the rule if found
  5030. */
  5031. static struct ice_adv_fltr_mgmt_list_entry *
  5032. ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
  5033. u16 lkups_cnt, u16 recp_id,
  5034. struct ice_adv_rule_info *rinfo)
  5035. {
  5036. struct ice_adv_fltr_mgmt_list_entry *list_itr;
  5037. struct ice_switch_info *sw = hw->switch_info;
  5038. int i;
  5039. list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules,
  5040. list_entry) {
  5041. bool lkups_matched = true;
  5042. if (lkups_cnt != list_itr->lkups_cnt)
  5043. continue;
  5044. for (i = 0; i < list_itr->lkups_cnt; i++)
  5045. if (memcmp(&list_itr->lkups[i], &lkups[i],
  5046. sizeof(*lkups))) {
  5047. lkups_matched = false;
  5048. break;
  5049. }
  5050. if (ice_rules_equal(rinfo, &list_itr->rule_info) &&
  5051. lkups_matched)
  5052. return list_itr;
  5053. }
  5054. return NULL;
  5055. }
  5056. /**
  5057. * ice_adv_add_update_vsi_list
  5058. * @hw: pointer to the hardware structure
  5059. * @m_entry: pointer to current adv filter management list entry
  5060. * @cur_fltr: filter information from the book keeping entry
  5061. * @new_fltr: filter information with the new VSI to be added
  5062. *
  5063. * Call AQ command to add or update previously created VSI list with new VSI.
  5064. *
  5065. * Helper function to do book keeping associated with adding filter information
  5066. * The algorithm to do the booking keeping is described below :
  5067. * When a VSI needs to subscribe to a given advanced filter
  5068. * if only one VSI has been added till now
  5069. * Allocate a new VSI list and add two VSIs
  5070. * to this list using switch rule command
  5071. * Update the previously created switch rule with the
  5072. * newly created VSI list ID
  5073. * if a VSI list was previously created
  5074. * Add the new VSI to the previously created VSI list set
  5075. * using the update switch rule command
  5076. */
  5077. static int
  5078. ice_adv_add_update_vsi_list(struct ice_hw *hw,
  5079. struct ice_adv_fltr_mgmt_list_entry *m_entry,
  5080. struct ice_adv_rule_info *cur_fltr,
  5081. struct ice_adv_rule_info *new_fltr)
  5082. {
  5083. u16 vsi_list_id = 0;
  5084. int status;
  5085. if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
  5086. cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
  5087. cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
  5088. return -EOPNOTSUPP;
  5089. if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
  5090. new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
  5091. (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
  5092. cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
  5093. return -EOPNOTSUPP;
  5094. if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
  5095. /* Only one entry existed in the mapping and it was not already
  5096. * a part of a VSI list. So, create a VSI list with the old and
  5097. * new VSIs.
  5098. */
  5099. struct ice_fltr_info tmp_fltr;
  5100. u16 vsi_handle_arr[2];
  5101. /* A rule already exists with the new VSI being added */
  5102. if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
  5103. new_fltr->sw_act.fwd_id.hw_vsi_id)
  5104. return -EEXIST;
  5105. vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
  5106. vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
  5107. status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
  5108. &vsi_list_id,
  5109. ICE_SW_LKUP_LAST);
  5110. if (status)
  5111. return status;
  5112. memset(&tmp_fltr, 0, sizeof(tmp_fltr));
  5113. tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
  5114. tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
  5115. tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
  5116. tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
  5117. tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
  5118. /* Update the previous switch rule of "forward to VSI" to
  5119. * "fwd to VSI list"
  5120. */
  5121. status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
  5122. if (status)
  5123. return status;
  5124. cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
  5125. cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
  5126. m_entry->vsi_list_info =
  5127. ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
  5128. vsi_list_id);
  5129. } else {
  5130. u16 vsi_handle = new_fltr->sw_act.vsi_handle;
  5131. if (!m_entry->vsi_list_info)
  5132. return -EIO;
  5133. /* A rule already exists with the new VSI being added */
  5134. if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
  5135. return -EEXIST;
  5136. /* Update the previously created VSI list set with
  5137. * the new VSI ID passed in
  5138. */
  5139. vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
  5140. status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
  5141. vsi_list_id, false,
  5142. ice_aqc_opc_update_sw_rules,
  5143. ICE_SW_LKUP_LAST);
  5144. /* update VSI list mapping info with new VSI ID */
  5145. if (!status)
  5146. set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
  5147. }
  5148. if (!status)
  5149. m_entry->vsi_count++;
  5150. return status;
  5151. }
  5152. void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup)
  5153. {
  5154. lkup->type = ICE_HW_METADATA;
  5155. lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID21] |=
  5156. cpu_to_be16(ICE_PKT_TUNNEL_MASK);
  5157. }
  5158. void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup)
  5159. {
  5160. lkup->type = ICE_HW_METADATA;
  5161. lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
  5162. cpu_to_be16(ICE_PKT_FROM_NETWORK);
  5163. }
  5164. void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
  5165. {
  5166. lkup->type = ICE_HW_METADATA;
  5167. lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
  5168. cpu_to_be16(ICE_PKT_VLAN_MASK);
  5169. }
  5170. void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup)
  5171. {
  5172. lkup->type = ICE_HW_METADATA;
  5173. lkup->m_u.metadata.source_vsi = cpu_to_be16(ICE_MDID_SOURCE_VSI_MASK);
  5174. }
  5175. /**
  5176. * ice_add_adv_rule - helper function to create an advanced switch rule
  5177. * @hw: pointer to the hardware structure
  5178. * @lkups: information on the words that needs to be looked up. All words
  5179. * together makes one recipe
  5180. * @lkups_cnt: num of entries in the lkups array
  5181. * @rinfo: other information related to the rule that needs to be programmed
  5182. * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
  5183. * ignored is case of error.
  5184. *
  5185. * This function can program only 1 rule at a time. The lkups is used to
  5186. * describe the all the words that forms the "lookup" portion of the recipe.
  5187. * These words can span multiple protocols. Callers to this function need to
  5188. * pass in a list of protocol headers with lookup information along and mask
  5189. * that determines which words are valid from the given protocol header.
  5190. * rinfo describes other information related to this rule such as forwarding
  5191. * IDs, priority of this rule, etc.
  5192. */
  5193. int
  5194. ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
  5195. u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
  5196. struct ice_rule_query_data *added_entry)
  5197. {
  5198. struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
  5199. struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
  5200. const struct ice_dummy_pkt_profile *profile;
  5201. u16 rid = 0, i, rule_buf_sz, vsi_handle;
  5202. struct list_head *rule_head;
  5203. struct ice_switch_info *sw;
  5204. u16 word_cnt;
  5205. u32 act = 0;
  5206. int status;
  5207. u8 q_rgn;
  5208. /* Initialize profile to result index bitmap */
  5209. if (!hw->switch_info->prof_res_bm_init) {
  5210. hw->switch_info->prof_res_bm_init = 1;
  5211. ice_init_prof_result_bm(hw);
  5212. }
  5213. if (!lkups_cnt)
  5214. return -EINVAL;
  5215. /* get # of words we need to match */
  5216. word_cnt = 0;
  5217. for (i = 0; i < lkups_cnt; i++) {
  5218. u16 j;
  5219. for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++)
  5220. if (lkups[i].m_raw[j])
  5221. word_cnt++;
  5222. }
  5223. if (!word_cnt)
  5224. return -EINVAL;
  5225. if (word_cnt > ICE_MAX_CHAIN_WORDS)
  5226. return -ENOSPC;
  5227. /* locate a dummy packet */
  5228. profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type);
  5229. if (IS_ERR(profile))
  5230. return PTR_ERR(profile);
  5231. if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
  5232. rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
  5233. rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
  5234. rinfo->sw_act.fltr_act == ICE_DROP_PACKET ||
  5235. rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
  5236. rinfo->sw_act.fltr_act == ICE_NOP)) {
  5237. status = -EIO;
  5238. goto free_pkt_profile;
  5239. }
  5240. vsi_handle = rinfo->sw_act.vsi_handle;
  5241. if (!ice_is_vsi_valid(hw, vsi_handle)) {
  5242. status = -EINVAL;
  5243. goto free_pkt_profile;
  5244. }
  5245. if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
  5246. rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
  5247. rinfo->sw_act.fltr_act == ICE_NOP) {
  5248. rinfo->sw_act.fwd_id.hw_vsi_id =
  5249. ice_get_hw_vsi_num(hw, vsi_handle);
  5250. }
  5251. if (rinfo->src_vsi)
  5252. rinfo->sw_act.src = ice_get_hw_vsi_num(hw, rinfo->src_vsi);
  5253. else
  5254. rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
  5255. status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
  5256. if (status)
  5257. goto free_pkt_profile;
  5258. m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
  5259. if (m_entry) {
  5260. /* we have to add VSI to VSI_LIST and increment vsi_count.
  5261. * Also Update VSI list so that we can change forwarding rule
  5262. * if the rule already exists, we will check if it exists with
  5263. * same vsi_id, if not then add it to the VSI list if it already
  5264. * exists if not then create a VSI list and add the existing VSI
  5265. * ID and the new VSI ID to the list
  5266. * We will add that VSI to the list
  5267. */
  5268. status = ice_adv_add_update_vsi_list(hw, m_entry,
  5269. &m_entry->rule_info,
  5270. rinfo);
  5271. if (added_entry) {
  5272. added_entry->rid = rid;
  5273. added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
  5274. added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
  5275. }
  5276. goto free_pkt_profile;
  5277. }
  5278. rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len);
  5279. s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
  5280. if (!s_rule) {
  5281. status = -ENOMEM;
  5282. goto free_pkt_profile;
  5283. }
  5284. if (rinfo->sw_act.fltr_act != ICE_MIRROR_PACKET) {
  5285. if (!rinfo->flags_info.act_valid) {
  5286. act |= ICE_SINGLE_ACT_LAN_ENABLE;
  5287. act |= ICE_SINGLE_ACT_LB_ENABLE;
  5288. } else {
  5289. act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
  5290. ICE_SINGLE_ACT_LB_ENABLE);
  5291. }
  5292. }
  5293. switch (rinfo->sw_act.fltr_act) {
  5294. case ICE_FWD_TO_VSI:
  5295. act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
  5296. rinfo->sw_act.fwd_id.hw_vsi_id);
  5297. act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
  5298. break;
  5299. case ICE_FWD_TO_Q:
  5300. act |= ICE_SINGLE_ACT_TO_Q;
  5301. act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
  5302. rinfo->sw_act.fwd_id.q_id);
  5303. break;
  5304. case ICE_FWD_TO_QGRP:
  5305. q_rgn = rinfo->sw_act.qgrp_size > 0 ?
  5306. (u8)ilog2(rinfo->sw_act.qgrp_size) : 0;
  5307. act |= ICE_SINGLE_ACT_TO_Q;
  5308. act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
  5309. rinfo->sw_act.fwd_id.q_id);
  5310. act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
  5311. break;
  5312. case ICE_DROP_PACKET:
  5313. act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
  5314. ICE_SINGLE_ACT_VALID_BIT;
  5315. break;
  5316. case ICE_MIRROR_PACKET:
  5317. act |= ICE_SINGLE_ACT_OTHER_ACTS;
  5318. act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
  5319. rinfo->sw_act.fwd_id.hw_vsi_id);
  5320. break;
  5321. case ICE_NOP:
  5322. act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
  5323. rinfo->sw_act.fwd_id.hw_vsi_id);
  5324. act &= ~ICE_SINGLE_ACT_VALID_BIT;
  5325. break;
  5326. default:
  5327. status = -EIO;
  5328. goto err_ice_add_adv_rule;
  5329. }
  5330. /* If there is no matching criteria for direction there
  5331. * is only one difference between Rx and Tx:
  5332. * - get switch id base on VSI number from source field (Tx)
  5333. * - get switch id base on port number (Rx)
  5334. *
  5335. * If matching on direction metadata is chose rule direction is
  5336. * extracted from type value set here.
  5337. */
  5338. if (rinfo->sw_act.flag & ICE_FLTR_TX) {
  5339. s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
  5340. s_rule->src = cpu_to_le16(rinfo->sw_act.src);
  5341. } else {
  5342. s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
  5343. s_rule->src = cpu_to_le16(hw->port_info->lport);
  5344. }
  5345. s_rule->recipe_id = cpu_to_le16(rid);
  5346. s_rule->act = cpu_to_le32(act);
  5347. status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile);
  5348. if (status)
  5349. goto err_ice_add_adv_rule;
  5350. status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, s_rule->hdr_data,
  5351. profile->offsets);
  5352. if (status)
  5353. goto err_ice_add_adv_rule;
  5354. status = ice_fill_adv_packet_vlan(hw, rinfo->vlan_type,
  5355. s_rule->hdr_data,
  5356. profile->offsets);
  5357. if (status)
  5358. goto err_ice_add_adv_rule;
  5359. status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
  5360. rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
  5361. NULL);
  5362. if (status)
  5363. goto err_ice_add_adv_rule;
  5364. adv_fltr = devm_kzalloc(ice_hw_to_dev(hw),
  5365. sizeof(struct ice_adv_fltr_mgmt_list_entry),
  5366. GFP_KERNEL);
  5367. if (!adv_fltr) {
  5368. status = -ENOMEM;
  5369. goto err_ice_add_adv_rule;
  5370. }
  5371. adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups,
  5372. lkups_cnt * sizeof(*lkups), GFP_KERNEL);
  5373. if (!adv_fltr->lkups) {
  5374. status = -ENOMEM;
  5375. goto err_ice_add_adv_rule;
  5376. }
  5377. adv_fltr->lkups_cnt = lkups_cnt;
  5378. adv_fltr->rule_info = *rinfo;
  5379. adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index);
  5380. sw = hw->switch_info;
  5381. sw->recp_list[rid].adv_rule = true;
  5382. rule_head = &sw->recp_list[rid].filt_rules;
  5383. if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
  5384. adv_fltr->vsi_count = 1;
  5385. /* Add rule entry to book keeping list */
  5386. list_add(&adv_fltr->list_entry, rule_head);
  5387. if (added_entry) {
  5388. added_entry->rid = rid;
  5389. added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
  5390. added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
  5391. }
  5392. err_ice_add_adv_rule:
  5393. if (status && adv_fltr) {
  5394. devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups);
  5395. devm_kfree(ice_hw_to_dev(hw), adv_fltr);
  5396. }
  5397. kfree(s_rule);
  5398. free_pkt_profile:
  5399. if (profile->match & ICE_PKT_KMALLOC) {
  5400. kfree(profile->offsets);
  5401. kfree(profile->pkt);
  5402. kfree(profile);
  5403. }
  5404. return status;
  5405. }
  5406. /**
  5407. * ice_replay_vsi_fltr - Replay filters for requested VSI
  5408. * @hw: pointer to the hardware structure
  5409. * @vsi_handle: driver VSI handle
  5410. * @recp_id: Recipe ID for which rules need to be replayed
  5411. * @list_head: list for which filters need to be replayed
  5412. *
  5413. * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
  5414. * It is required to pass valid VSI handle.
  5415. */
  5416. static int
  5417. ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
  5418. struct list_head *list_head)
  5419. {
  5420. struct ice_fltr_mgmt_list_entry *itr;
  5421. int status = 0;
  5422. u16 hw_vsi_id;
  5423. if (list_empty(list_head))
  5424. return status;
  5425. hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
  5426. list_for_each_entry(itr, list_head, list_entry) {
  5427. struct ice_fltr_list_entry f_entry;
  5428. f_entry.fltr_info = itr->fltr_info;
  5429. if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
  5430. itr->fltr_info.vsi_handle == vsi_handle) {
  5431. /* update the src in case it is VSI num */
  5432. if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
  5433. f_entry.fltr_info.src = hw_vsi_id;
  5434. status = ice_add_rule_internal(hw, recp_id, &f_entry);
  5435. if (status)
  5436. goto end;
  5437. continue;
  5438. }
  5439. if (!itr->vsi_list_info ||
  5440. !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
  5441. continue;
  5442. f_entry.fltr_info.vsi_handle = vsi_handle;
  5443. f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
  5444. /* update the src in case it is VSI num */
  5445. if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
  5446. f_entry.fltr_info.src = hw_vsi_id;
  5447. if (recp_id == ICE_SW_LKUP_VLAN)
  5448. status = ice_add_vlan_internal(hw, &f_entry);
  5449. else
  5450. status = ice_add_rule_internal(hw, recp_id, &f_entry);
  5451. if (status)
  5452. goto end;
  5453. }
  5454. end:
  5455. return status;
  5456. }
  5457. /**
  5458. * ice_adv_rem_update_vsi_list
  5459. * @hw: pointer to the hardware structure
  5460. * @vsi_handle: VSI handle of the VSI to remove
  5461. * @fm_list: filter management entry for which the VSI list management needs to
  5462. * be done
  5463. */
  5464. static int
  5465. ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
  5466. struct ice_adv_fltr_mgmt_list_entry *fm_list)
  5467. {
  5468. struct ice_vsi_list_map_info *vsi_list_info;
  5469. enum ice_sw_lkup_type lkup_type;
  5470. u16 vsi_list_id;
  5471. int status;
  5472. if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
  5473. fm_list->vsi_count == 0)
  5474. return -EINVAL;
  5475. /* A rule with the VSI being removed does not exist */
  5476. if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
  5477. return -ENOENT;
  5478. lkup_type = ICE_SW_LKUP_LAST;
  5479. vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
  5480. status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
  5481. ice_aqc_opc_update_sw_rules,
  5482. lkup_type);
  5483. if (status)
  5484. return status;
  5485. fm_list->vsi_count--;
  5486. clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
  5487. vsi_list_info = fm_list->vsi_list_info;
  5488. if (fm_list->vsi_count == 1) {
  5489. struct ice_fltr_info tmp_fltr;
  5490. u16 rem_vsi_handle;
  5491. rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
  5492. ICE_MAX_VSI);
  5493. if (!ice_is_vsi_valid(hw, rem_vsi_handle))
  5494. return -EIO;
  5495. /* Make sure VSI list is empty before removing it below */
  5496. status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
  5497. vsi_list_id, true,
  5498. ice_aqc_opc_update_sw_rules,
  5499. lkup_type);
  5500. if (status)
  5501. return status;
  5502. memset(&tmp_fltr, 0, sizeof(tmp_fltr));
  5503. tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
  5504. tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
  5505. fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
  5506. tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
  5507. tmp_fltr.fwd_id.hw_vsi_id =
  5508. ice_get_hw_vsi_num(hw, rem_vsi_handle);
  5509. fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
  5510. ice_get_hw_vsi_num(hw, rem_vsi_handle);
  5511. fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
  5512. /* Update the previous switch rule of "MAC forward to VSI" to
  5513. * "MAC fwd to VSI list"
  5514. */
  5515. status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
  5516. if (status) {
  5517. ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
  5518. tmp_fltr.fwd_id.hw_vsi_id, status);
  5519. return status;
  5520. }
  5521. fm_list->vsi_list_info->ref_cnt--;
  5522. /* Remove the VSI list since it is no longer used */
  5523. status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
  5524. if (status) {
  5525. ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
  5526. vsi_list_id, status);
  5527. return status;
  5528. }
  5529. list_del(&vsi_list_info->list_entry);
  5530. devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
  5531. fm_list->vsi_list_info = NULL;
  5532. }
  5533. return status;
  5534. }
  5535. /**
  5536. * ice_rem_adv_rule - removes existing advanced switch rule
  5537. * @hw: pointer to the hardware structure
  5538. * @lkups: information on the words that needs to be looked up. All words
  5539. * together makes one recipe
  5540. * @lkups_cnt: num of entries in the lkups array
  5541. * @rinfo: Its the pointer to the rule information for the rule
  5542. *
  5543. * This function can be used to remove 1 rule at a time. The lkups is
  5544. * used to describe all the words that forms the "lookup" portion of the
  5545. * rule. These words can span multiple protocols. Callers to this function
  5546. * need to pass in a list of protocol headers with lookup information along
  5547. * and mask that determines which words are valid from the given protocol
  5548. * header. rinfo describes other information related to this rule such as
  5549. * forwarding IDs, priority of this rule, etc.
  5550. */
  5551. static int
  5552. ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
  5553. u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
  5554. {
  5555. struct ice_adv_fltr_mgmt_list_entry *list_elem;
  5556. struct ice_prot_lkup_ext lkup_exts;
  5557. bool remove_rule = false;
  5558. struct mutex *rule_lock; /* Lock to protect filter rule list */
  5559. u16 i, rid, vsi_handle;
  5560. int status = 0;
  5561. memset(&lkup_exts, 0, sizeof(lkup_exts));
  5562. for (i = 0; i < lkups_cnt; i++) {
  5563. u16 count;
  5564. if (lkups[i].type >= ICE_PROTOCOL_LAST)
  5565. return -EIO;
  5566. count = ice_fill_valid_words(&lkups[i], &lkup_exts);
  5567. if (!count)
  5568. return -EIO;
  5569. }
  5570. rid = ice_find_recp(hw, &lkup_exts, rinfo, false);
  5571. /* If did not find a recipe that match the existing criteria */
  5572. if (rid == ICE_MAX_NUM_RECIPES)
  5573. return -EINVAL;
  5574. rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
  5575. list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
  5576. /* the rule is already removed */
  5577. if (!list_elem)
  5578. return 0;
  5579. mutex_lock(rule_lock);
  5580. if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
  5581. remove_rule = true;
  5582. } else if (list_elem->vsi_count > 1) {
  5583. remove_rule = false;
  5584. vsi_handle = rinfo->sw_act.vsi_handle;
  5585. status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
  5586. } else {
  5587. vsi_handle = rinfo->sw_act.vsi_handle;
  5588. status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
  5589. if (status) {
  5590. mutex_unlock(rule_lock);
  5591. return status;
  5592. }
  5593. if (list_elem->vsi_count == 0)
  5594. remove_rule = true;
  5595. }
  5596. mutex_unlock(rule_lock);
  5597. if (remove_rule) {
  5598. struct ice_sw_rule_lkup_rx_tx *s_rule;
  5599. u16 rule_buf_sz;
  5600. rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule);
  5601. s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
  5602. if (!s_rule)
  5603. return -ENOMEM;
  5604. s_rule->act = 0;
  5605. s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id);
  5606. s_rule->hdr_len = 0;
  5607. status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
  5608. rule_buf_sz, 1,
  5609. ice_aqc_opc_remove_sw_rules, NULL);
  5610. if (!status || status == -ENOENT) {
  5611. struct ice_switch_info *sw = hw->switch_info;
  5612. struct ice_sw_recipe *r_list = sw->recp_list;
  5613. mutex_lock(rule_lock);
  5614. list_del(&list_elem->list_entry);
  5615. devm_kfree(ice_hw_to_dev(hw), list_elem->lkups);
  5616. devm_kfree(ice_hw_to_dev(hw), list_elem);
  5617. mutex_unlock(rule_lock);
  5618. if (list_empty(&r_list[rid].filt_rules)) {
  5619. r_list[rid].adv_rule = false;
  5620. /* All rules for this recipe are now removed */
  5621. if (hw->recp_reuse)
  5622. ice_release_recipe_res(hw,
  5623. &r_list[rid]);
  5624. }
  5625. }
  5626. kfree(s_rule);
  5627. }
  5628. return status;
  5629. }
  5630. /**
  5631. * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
  5632. * @hw: pointer to the hardware structure
  5633. * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
  5634. *
  5635. * This function is used to remove 1 rule at a time. The removal is based on
  5636. * the remove_entry parameter. This function will remove rule for a given
  5637. * vsi_handle with a given rule_id which is passed as parameter in remove_entry
  5638. */
  5639. int
  5640. ice_rem_adv_rule_by_id(struct ice_hw *hw,
  5641. struct ice_rule_query_data *remove_entry)
  5642. {
  5643. struct ice_adv_fltr_mgmt_list_entry *list_itr;
  5644. struct list_head *list_head;
  5645. struct ice_adv_rule_info rinfo;
  5646. struct ice_switch_info *sw;
  5647. sw = hw->switch_info;
  5648. if (!sw->recp_list[remove_entry->rid].recp_created)
  5649. return -EINVAL;
  5650. list_head = &sw->recp_list[remove_entry->rid].filt_rules;
  5651. list_for_each_entry(list_itr, list_head, list_entry) {
  5652. if (list_itr->rule_info.fltr_rule_id ==
  5653. remove_entry->rule_id) {
  5654. rinfo = list_itr->rule_info;
  5655. rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
  5656. return ice_rem_adv_rule(hw, list_itr->lkups,
  5657. list_itr->lkups_cnt, &rinfo);
  5658. }
  5659. }
  5660. /* either list is empty or unable to find rule */
  5661. return -ENOENT;
  5662. }
  5663. /**
  5664. * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
  5665. * @hw: pointer to the hardware structure
  5666. * @vsi_handle: driver VSI handle
  5667. * @list_head: list for which filters need to be replayed
  5668. *
  5669. * Replay the advanced rule for the given VSI.
  5670. */
  5671. static int
  5672. ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
  5673. struct list_head *list_head)
  5674. {
  5675. struct ice_rule_query_data added_entry = { 0 };
  5676. struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
  5677. int status = 0;
  5678. if (list_empty(list_head))
  5679. return status;
  5680. list_for_each_entry(adv_fltr, list_head, list_entry) {
  5681. struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
  5682. u16 lk_cnt = adv_fltr->lkups_cnt;
  5683. if (vsi_handle != rinfo->sw_act.vsi_handle)
  5684. continue;
  5685. status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
  5686. &added_entry);
  5687. if (status)
  5688. break;
  5689. }
  5690. return status;
  5691. }
  5692. /**
  5693. * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
  5694. * @hw: pointer to the hardware structure
  5695. * @vsi_handle: driver VSI handle
  5696. *
  5697. * Replays filters for requested VSI via vsi_handle.
  5698. */
  5699. int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
  5700. {
  5701. struct ice_switch_info *sw = hw->switch_info;
  5702. int status;
  5703. u8 i;
  5704. for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
  5705. struct list_head *head;
  5706. head = &sw->recp_list[i].filt_replay_rules;
  5707. if (!sw->recp_list[i].adv_rule)
  5708. status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
  5709. else
  5710. status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
  5711. if (status)
  5712. return status;
  5713. }
  5714. return status;
  5715. }
  5716. /**
  5717. * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
  5718. * @hw: pointer to the HW struct
  5719. *
  5720. * Deletes the filter replay rules.
  5721. */
  5722. void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
  5723. {
  5724. struct ice_switch_info *sw = hw->switch_info;
  5725. u8 i;
  5726. if (!sw)
  5727. return;
  5728. for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
  5729. if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
  5730. struct list_head *l_head;
  5731. l_head = &sw->recp_list[i].filt_replay_rules;
  5732. if (!sw->recp_list[i].adv_rule)
  5733. ice_rem_sw_rule_info(hw, l_head);
  5734. else
  5735. ice_rem_adv_rule_info(hw, l_head);
  5736. }
  5737. }
  5738. }