spectrum_fid.c 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
  3. #include <linux/kernel.h>
  4. #include <linux/bitops.h>
  5. #include <linux/if_vlan.h>
  6. #include <linux/if_bridge.h>
  7. #include <linux/netdevice.h>
  8. #include <linux/rhashtable.h>
  9. #include <linux/rtnetlink.h>
  10. #include <linux/refcount.h>
  11. #include "spectrum.h"
  12. #include "spectrum_router.h"
  13. #include "reg.h"
  14. struct mlxsw_sp_fid_family;
  15. struct mlxsw_sp_fid_core {
  16. struct rhashtable fid_ht;
  17. struct rhashtable vni_ht;
  18. struct mlxsw_sp_fid_family *fid_family_arr[MLXSW_SP_FID_TYPE_MAX];
  19. unsigned int *port_fid_mappings;
  20. };
  21. struct mlxsw_sp_fid_port_vid {
  22. struct list_head list;
  23. u16 local_port;
  24. u16 vid;
  25. };
  26. struct mlxsw_sp_fid {
  27. struct list_head list;
  28. struct mlxsw_sp_rif *rif;
  29. refcount_t ref_count;
  30. u16 fid_index;
  31. u16 fid_offset;
  32. struct mlxsw_sp_fid_family *fid_family;
  33. struct rhash_head ht_node;
  34. struct rhash_head vni_ht_node;
  35. enum mlxsw_sp_nve_type nve_type;
  36. __be32 vni;
  37. u32 nve_flood_index;
  38. int nve_ifindex;
  39. u8 vni_valid:1,
  40. nve_flood_index_valid:1;
  41. struct list_head port_vid_list; /* Ordered by local port. */
  42. };
  43. struct mlxsw_sp_fid_8021q {
  44. struct mlxsw_sp_fid common;
  45. u16 vid;
  46. };
  47. struct mlxsw_sp_fid_8021d {
  48. struct mlxsw_sp_fid common;
  49. int br_ifindex;
  50. };
  51. static const struct rhashtable_params mlxsw_sp_fid_ht_params = {
  52. .key_len = sizeof_field(struct mlxsw_sp_fid, fid_index),
  53. .key_offset = offsetof(struct mlxsw_sp_fid, fid_index),
  54. .head_offset = offsetof(struct mlxsw_sp_fid, ht_node),
  55. };
  56. static const struct rhashtable_params mlxsw_sp_fid_vni_ht_params = {
  57. .key_len = sizeof_field(struct mlxsw_sp_fid, vni),
  58. .key_offset = offsetof(struct mlxsw_sp_fid, vni),
  59. .head_offset = offsetof(struct mlxsw_sp_fid, vni_ht_node),
  60. };
  61. struct mlxsw_sp_flood_table {
  62. enum mlxsw_sp_flood_type packet_type;
  63. enum mlxsw_flood_table_type table_type; /* For flood_mode!=CFF. */
  64. int table_index;
  65. };
  66. struct mlxsw_sp_fid_ops {
  67. int (*setup)(struct mlxsw_sp_fid *fid, const void *arg);
  68. int (*configure)(struct mlxsw_sp_fid *fid);
  69. void (*deconfigure)(struct mlxsw_sp_fid *fid);
  70. int (*index_alloc)(struct mlxsw_sp_fid *fid, const void *arg,
  71. u16 *p_fid_index);
  72. bool (*compare)(const struct mlxsw_sp_fid *fid,
  73. const void *arg);
  74. int (*port_vid_map)(struct mlxsw_sp_fid *fid,
  75. struct mlxsw_sp_port *port, u16 vid);
  76. void (*port_vid_unmap)(struct mlxsw_sp_fid *fid,
  77. struct mlxsw_sp_port *port, u16 vid);
  78. int (*vni_set)(struct mlxsw_sp_fid *fid);
  79. void (*vni_clear)(struct mlxsw_sp_fid *fid);
  80. int (*nve_flood_index_set)(struct mlxsw_sp_fid *fid);
  81. void (*nve_flood_index_clear)(struct mlxsw_sp_fid *fid);
  82. void (*fdb_clear_offload)(const struct mlxsw_sp_fid *fid,
  83. const struct net_device *nve_dev);
  84. int (*vid_to_fid_rif_update)(const struct mlxsw_sp_fid *fid,
  85. const struct mlxsw_sp_rif *rif);
  86. int (*flood_table_init)(struct mlxsw_sp_fid_family *fid_family,
  87. const struct mlxsw_sp_flood_table *flood_table);
  88. int (*pgt_size)(const struct mlxsw_sp_fid_family *fid_family,
  89. u16 *p_pgt_size);
  90. u16 (*fid_mid)(const struct mlxsw_sp_fid *fid,
  91. const struct mlxsw_sp_flood_table *flood_table);
  92. void (*fid_pack)(char *sfmr_pl, const struct mlxsw_sp_fid *fid,
  93. enum mlxsw_reg_sfmr_op op);
  94. /* These are specific to RFID families and we assume are only
  95. * implemented by RFID families, if at all.
  96. */
  97. int (*fid_port_init)(const struct mlxsw_sp_fid_family *fid_family,
  98. const struct mlxsw_sp_port *mlxsw_sp_port);
  99. void (*fid_port_fini)(const struct mlxsw_sp_fid_family *fid_family,
  100. const struct mlxsw_sp_port *mlxsw_sp_port);
  101. };
  102. enum mlxsw_sp_fid_flood_profile_id {
  103. MLXSW_SP_FID_FLOOD_PROFILE_ID_BRIDGE = 1,
  104. MLXSW_SP_FID_FLOOD_PROFILE_ID_RSP,
  105. MLXSW_SP_FID_FLOOD_PROFILE_ID_NVE,
  106. };
  107. struct mlxsw_sp_fid_flood_profile {
  108. const struct mlxsw_sp_flood_table *flood_tables;
  109. int nr_flood_tables;
  110. const enum mlxsw_sp_fid_flood_profile_id profile_id; /* For CFF mode. */
  111. };
  112. struct mlxsw_sp_fid_family {
  113. enum mlxsw_sp_fid_type type;
  114. size_t fid_size;
  115. u16 start_index;
  116. u16 end_index;
  117. struct list_head fids_list;
  118. unsigned long *fids_bitmap;
  119. const struct mlxsw_sp_fid_flood_profile *flood_profile;
  120. enum mlxsw_sp_rif_type rif_type;
  121. const struct mlxsw_sp_fid_ops *ops;
  122. struct mlxsw_sp *mlxsw_sp;
  123. bool flood_rsp; /* For flood_mode!=CFF. */
  124. enum mlxsw_reg_bridge_type bridge_type;
  125. u16 pgt_base;
  126. bool smpe_index_valid;
  127. };
  128. static const int mlxsw_sp_sfgc_uc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
  129. [MLXSW_REG_SFGC_TYPE_UNKNOWN_UNICAST] = 1,
  130. };
  131. static const int mlxsw_sp_sfgc_bc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
  132. [MLXSW_REG_SFGC_TYPE_BROADCAST] = 1,
  133. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_NON_IP] = 1,
  134. [MLXSW_REG_SFGC_TYPE_IPV4_LINK_LOCAL] = 1,
  135. [MLXSW_REG_SFGC_TYPE_IPV6_ALL_HOST] = 1,
  136. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6] = 1,
  137. };
  138. static const int mlxsw_sp_sfgc_mc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
  139. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV4] = 1,
  140. };
  141. static const int mlxsw_sp_sfgc_not_uc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
  142. [MLXSW_REG_SFGC_TYPE_BROADCAST] = 1,
  143. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_NON_IP] = 1,
  144. [MLXSW_REG_SFGC_TYPE_IPV4_LINK_LOCAL] = 1,
  145. [MLXSW_REG_SFGC_TYPE_IPV6_ALL_HOST] = 1,
  146. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6] = 1,
  147. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV4] = 1,
  148. };
  149. static const int mlxsw_sp_sfgc_any_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
  150. [MLXSW_REG_SFGC_TYPE_UNKNOWN_UNICAST] = 1,
  151. [MLXSW_REG_SFGC_TYPE_BROADCAST] = 1,
  152. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_NON_IP] = 1,
  153. [MLXSW_REG_SFGC_TYPE_IPV4_LINK_LOCAL] = 1,
  154. [MLXSW_REG_SFGC_TYPE_IPV6_ALL_HOST] = 1,
  155. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6] = 1,
  156. [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV4] = 1,
  157. };
  158. static const int *mlxsw_sp_packet_type_sfgc_types[] = {
  159. [MLXSW_SP_FLOOD_TYPE_UC] = mlxsw_sp_sfgc_uc_packet_types,
  160. [MLXSW_SP_FLOOD_TYPE_BC] = mlxsw_sp_sfgc_bc_packet_types,
  161. [MLXSW_SP_FLOOD_TYPE_MC] = mlxsw_sp_sfgc_mc_packet_types,
  162. [MLXSW_SP_FLOOD_TYPE_NOT_UC] = mlxsw_sp_sfgc_not_uc_packet_types,
  163. [MLXSW_SP_FLOOD_TYPE_ANY] = mlxsw_sp_sfgc_any_packet_types,
  164. };
  165. struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_index(struct mlxsw_sp *mlxsw_sp,
  166. u16 fid_index)
  167. {
  168. struct mlxsw_sp_fid *fid;
  169. fid = rhashtable_lookup_fast(&mlxsw_sp->fid_core->fid_ht, &fid_index,
  170. mlxsw_sp_fid_ht_params);
  171. if (fid)
  172. refcount_inc(&fid->ref_count);
  173. return fid;
  174. }
  175. int mlxsw_sp_fid_nve_ifindex(const struct mlxsw_sp_fid *fid, int *nve_ifindex)
  176. {
  177. if (!fid->vni_valid)
  178. return -EINVAL;
  179. *nve_ifindex = fid->nve_ifindex;
  180. return 0;
  181. }
  182. int mlxsw_sp_fid_nve_type(const struct mlxsw_sp_fid *fid,
  183. enum mlxsw_sp_nve_type *p_type)
  184. {
  185. if (!fid->vni_valid)
  186. return -EINVAL;
  187. *p_type = fid->nve_type;
  188. return 0;
  189. }
  190. struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_vni(struct mlxsw_sp *mlxsw_sp,
  191. __be32 vni)
  192. {
  193. struct mlxsw_sp_fid *fid;
  194. fid = rhashtable_lookup_fast(&mlxsw_sp->fid_core->vni_ht, &vni,
  195. mlxsw_sp_fid_vni_ht_params);
  196. if (fid)
  197. refcount_inc(&fid->ref_count);
  198. return fid;
  199. }
  200. int mlxsw_sp_fid_vni(const struct mlxsw_sp_fid *fid, __be32 *vni)
  201. {
  202. if (!fid->vni_valid)
  203. return -EINVAL;
  204. *vni = fid->vni;
  205. return 0;
  206. }
  207. int mlxsw_sp_fid_nve_flood_index_set(struct mlxsw_sp_fid *fid,
  208. u32 nve_flood_index)
  209. {
  210. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  211. const struct mlxsw_sp_fid_ops *ops = fid_family->ops;
  212. int err;
  213. if (WARN_ON(fid->nve_flood_index_valid))
  214. return -EINVAL;
  215. fid->nve_flood_index = nve_flood_index;
  216. fid->nve_flood_index_valid = true;
  217. err = ops->nve_flood_index_set(fid);
  218. if (err)
  219. goto err_nve_flood_index_set;
  220. return 0;
  221. err_nve_flood_index_set:
  222. fid->nve_flood_index_valid = false;
  223. return err;
  224. }
  225. void mlxsw_sp_fid_nve_flood_index_clear(struct mlxsw_sp_fid *fid)
  226. {
  227. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  228. const struct mlxsw_sp_fid_ops *ops = fid_family->ops;
  229. if (WARN_ON(!fid->nve_flood_index_valid))
  230. return;
  231. fid->nve_flood_index_valid = false;
  232. ops->nve_flood_index_clear(fid);
  233. }
  234. bool mlxsw_sp_fid_nve_flood_index_is_set(const struct mlxsw_sp_fid *fid)
  235. {
  236. return fid->nve_flood_index_valid;
  237. }
  238. int mlxsw_sp_fid_vni_set(struct mlxsw_sp_fid *fid, enum mlxsw_sp_nve_type type,
  239. __be32 vni, int nve_ifindex)
  240. {
  241. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  242. const struct mlxsw_sp_fid_ops *ops = fid_family->ops;
  243. struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;
  244. int err;
  245. if (WARN_ON(fid->vni_valid))
  246. return -EINVAL;
  247. fid->nve_type = type;
  248. fid->nve_ifindex = nve_ifindex;
  249. fid->vni = vni;
  250. err = rhashtable_lookup_insert_fast(&mlxsw_sp->fid_core->vni_ht,
  251. &fid->vni_ht_node,
  252. mlxsw_sp_fid_vni_ht_params);
  253. if (err)
  254. return err;
  255. fid->vni_valid = true;
  256. err = ops->vni_set(fid);
  257. if (err)
  258. goto err_vni_set;
  259. return 0;
  260. err_vni_set:
  261. fid->vni_valid = false;
  262. rhashtable_remove_fast(&mlxsw_sp->fid_core->vni_ht, &fid->vni_ht_node,
  263. mlxsw_sp_fid_vni_ht_params);
  264. return err;
  265. }
  266. void mlxsw_sp_fid_vni_clear(struct mlxsw_sp_fid *fid)
  267. {
  268. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  269. const struct mlxsw_sp_fid_ops *ops = fid_family->ops;
  270. struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;
  271. if (WARN_ON(!fid->vni_valid))
  272. return;
  273. fid->vni_valid = false;
  274. ops->vni_clear(fid);
  275. rhashtable_remove_fast(&mlxsw_sp->fid_core->vni_ht, &fid->vni_ht_node,
  276. mlxsw_sp_fid_vni_ht_params);
  277. }
  278. bool mlxsw_sp_fid_vni_is_set(const struct mlxsw_sp_fid *fid)
  279. {
  280. return fid->vni_valid;
  281. }
  282. void mlxsw_sp_fid_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
  283. const struct net_device *nve_dev)
  284. {
  285. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  286. const struct mlxsw_sp_fid_ops *ops = fid_family->ops;
  287. if (ops->fdb_clear_offload)
  288. ops->fdb_clear_offload(fid, nve_dev);
  289. }
  290. static const struct mlxsw_sp_flood_table *
  291. mlxsw_sp_fid_flood_table_lookup(const struct mlxsw_sp_fid *fid,
  292. enum mlxsw_sp_flood_type packet_type)
  293. {
  294. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  295. int i;
  296. for (i = 0; i < fid_family->flood_profile->nr_flood_tables; i++) {
  297. const struct mlxsw_sp_flood_table *flood_table;
  298. flood_table = &fid_family->flood_profile->flood_tables[i];
  299. if (flood_table->packet_type != packet_type)
  300. continue;
  301. return flood_table;
  302. }
  303. return NULL;
  304. }
  305. static u16
  306. mlxsw_sp_fid_family_num_fids(const struct mlxsw_sp_fid_family *fid_family)
  307. {
  308. return fid_family->end_index - fid_family->start_index + 1;
  309. }
  310. static int
  311. mlxsw_sp_fid_8021d_pgt_size(const struct mlxsw_sp_fid_family *fid_family,
  312. u16 *p_pgt_size)
  313. {
  314. u16 num_fids = mlxsw_sp_fid_family_num_fids(fid_family);
  315. *p_pgt_size = num_fids * fid_family->flood_profile->nr_flood_tables;
  316. return 0;
  317. }
  318. static unsigned int mlxsw_sp_fid_rfid_port_offset_cff(unsigned int local_port)
  319. {
  320. /* Port 0 is the CPU port. Since we never create RIFs based off that
  321. * port, we don't need to count it.
  322. */
  323. return WARN_ON_ONCE(!local_port) ? 0 : local_port - 1;
  324. }
  325. static int
  326. mlxsw_sp_fid_rfid_pgt_size_cff(const struct mlxsw_sp_fid_family *fid_family,
  327. u16 *p_pgt_size)
  328. {
  329. struct mlxsw_core *core = fid_family->mlxsw_sp->core;
  330. unsigned int max_ports;
  331. u16 pgt_size;
  332. u16 max_lags;
  333. int err;
  334. max_ports = mlxsw_core_max_ports(core);
  335. err = mlxsw_core_max_lag(core, &max_lags);
  336. if (err)
  337. return err;
  338. pgt_size = (mlxsw_sp_fid_rfid_port_offset_cff(max_ports) + max_lags) *
  339. fid_family->flood_profile->nr_flood_tables;
  340. *p_pgt_size = pgt_size;
  341. return 0;
  342. }
  343. static u16
  344. mlxsw_sp_fid_pgt_base_ctl(const struct mlxsw_sp_fid_family *fid_family,
  345. const struct mlxsw_sp_flood_table *flood_table)
  346. {
  347. u16 num_fids;
  348. num_fids = mlxsw_sp_fid_family_num_fids(fid_family);
  349. return fid_family->pgt_base + num_fids * flood_table->table_index;
  350. }
  351. static u16
  352. mlxsw_sp_fid_fid_mid_ctl(const struct mlxsw_sp_fid *fid,
  353. const struct mlxsw_sp_flood_table *flood_table)
  354. {
  355. return mlxsw_sp_fid_pgt_base_ctl(fid->fid_family, flood_table) +
  356. fid->fid_offset;
  357. }
  358. int mlxsw_sp_fid_flood_set(struct mlxsw_sp_fid *fid,
  359. enum mlxsw_sp_flood_type packet_type, u16 local_port,
  360. bool member)
  361. {
  362. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  363. const struct mlxsw_sp_flood_table *flood_table;
  364. u16 mid_index;
  365. if (WARN_ON(!fid_family->flood_profile))
  366. return -EINVAL;
  367. flood_table = mlxsw_sp_fid_flood_table_lookup(fid, packet_type);
  368. if (!flood_table)
  369. return -ESRCH;
  370. mid_index = fid_family->ops->fid_mid(fid, flood_table);
  371. return mlxsw_sp_pgt_entry_port_set(fid_family->mlxsw_sp, mid_index,
  372. fid->fid_index, local_port, member);
  373. }
  374. int mlxsw_sp_fid_port_vid_map(struct mlxsw_sp_fid *fid,
  375. struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
  376. {
  377. if (WARN_ON(!fid->fid_family->ops->port_vid_map))
  378. return -EINVAL;
  379. return fid->fid_family->ops->port_vid_map(fid, mlxsw_sp_port, vid);
  380. }
  381. void mlxsw_sp_fid_port_vid_unmap(struct mlxsw_sp_fid *fid,
  382. struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
  383. {
  384. fid->fid_family->ops->port_vid_unmap(fid, mlxsw_sp_port, vid);
  385. }
  386. u16 mlxsw_sp_fid_index(const struct mlxsw_sp_fid *fid)
  387. {
  388. return fid->fid_index;
  389. }
  390. enum mlxsw_sp_fid_type mlxsw_sp_fid_type(const struct mlxsw_sp_fid *fid)
  391. {
  392. return fid->fid_family->type;
  393. }
  394. struct mlxsw_sp_rif *mlxsw_sp_fid_rif(const struct mlxsw_sp_fid *fid)
  395. {
  396. return fid->rif;
  397. }
  398. enum mlxsw_sp_rif_type
  399. mlxsw_sp_fid_type_rif_type(const struct mlxsw_sp *mlxsw_sp,
  400. enum mlxsw_sp_fid_type type)
  401. {
  402. struct mlxsw_sp_fid_core *fid_core = mlxsw_sp->fid_core;
  403. return fid_core->fid_family_arr[type]->rif_type;
  404. }
  405. static struct mlxsw_sp_fid_8021q *
  406. mlxsw_sp_fid_8021q_fid(const struct mlxsw_sp_fid *fid)
  407. {
  408. return container_of(fid, struct mlxsw_sp_fid_8021q, common);
  409. }
  410. u16 mlxsw_sp_fid_8021q_vid(const struct mlxsw_sp_fid *fid)
  411. {
  412. return mlxsw_sp_fid_8021q_fid(fid)->vid;
  413. }
  414. static int mlxsw_sp_fid_8021q_setup(struct mlxsw_sp_fid *fid, const void *arg)
  415. {
  416. u16 vid = *(u16 *) arg;
  417. mlxsw_sp_fid_8021q_fid(fid)->vid = vid;
  418. fid->fid_offset = fid->fid_index - fid->fid_family->start_index;
  419. return 0;
  420. }
  421. static enum mlxsw_reg_sfmr_op mlxsw_sp_sfmr_op(bool valid)
  422. {
  423. return valid ? MLXSW_REG_SFMR_OP_CREATE_FID :
  424. MLXSW_REG_SFMR_OP_DESTROY_FID;
  425. }
  426. static void mlxsw_sp_fid_pack(char *sfmr_pl,
  427. const struct mlxsw_sp_fid *fid,
  428. enum mlxsw_reg_sfmr_op op)
  429. {
  430. u16 smpe;
  431. smpe = fid->fid_family->smpe_index_valid ? fid->fid_index : 0;
  432. mlxsw_reg_sfmr_pack(sfmr_pl, op, fid->fid_index,
  433. fid->fid_family->smpe_index_valid, smpe);
  434. }
  435. static void mlxsw_sp_fid_pack_ctl(char *sfmr_pl,
  436. const struct mlxsw_sp_fid *fid,
  437. enum mlxsw_reg_sfmr_op op)
  438. {
  439. mlxsw_sp_fid_pack(sfmr_pl, fid, op);
  440. mlxsw_reg_sfmr_fid_offset_set(sfmr_pl, fid->fid_offset);
  441. mlxsw_reg_sfmr_flood_rsp_set(sfmr_pl, fid->fid_family->flood_rsp);
  442. mlxsw_reg_sfmr_flood_bridge_type_set(sfmr_pl,
  443. fid->fid_family->bridge_type);
  444. }
  445. static u16
  446. mlxsw_sp_fid_off_pgt_base_cff(const struct mlxsw_sp_fid_family *fid_family,
  447. u16 fid_offset)
  448. {
  449. return fid_family->pgt_base +
  450. fid_offset * fid_family->flood_profile->nr_flood_tables;
  451. }
  452. static u16 mlxsw_sp_fid_pgt_base_cff(const struct mlxsw_sp_fid *fid)
  453. {
  454. return mlxsw_sp_fid_off_pgt_base_cff(fid->fid_family, fid->fid_offset);
  455. }
  456. static void mlxsw_sp_fid_fid_pack_cff(char *sfmr_pl,
  457. const struct mlxsw_sp_fid *fid,
  458. enum mlxsw_reg_sfmr_op op)
  459. {
  460. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  461. u16 pgt_base = mlxsw_sp_fid_pgt_base_cff(fid);
  462. mlxsw_sp_fid_pack(sfmr_pl, fid, op);
  463. mlxsw_reg_sfmr_cff_mid_base_set(sfmr_pl, pgt_base);
  464. mlxsw_reg_sfmr_cff_prf_id_set(sfmr_pl,
  465. fid_family->flood_profile->profile_id);
  466. mlxsw_reg_sfmr_nve_flood_prf_id_set(sfmr_pl,
  467. MLXSW_SP_FID_FLOOD_PROFILE_ID_NVE);
  468. }
  469. static u16 mlxsw_sp_fid_rfid_fid_offset_cff(struct mlxsw_sp *mlxsw_sp,
  470. u16 port_lag_id, bool is_lag)
  471. {
  472. u16 max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
  473. if (is_lag)
  474. return mlxsw_sp_fid_rfid_port_offset_cff(max_ports) +
  475. port_lag_id;
  476. else
  477. return mlxsw_sp_fid_rfid_port_offset_cff(port_lag_id);
  478. }
  479. static int mlxsw_sp_fid_op(const struct mlxsw_sp_fid *fid, bool valid)
  480. {
  481. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  482. char sfmr_pl[MLXSW_REG_SFMR_LEN];
  483. fid->fid_family->ops->fid_pack(sfmr_pl, fid,
  484. mlxsw_sp_sfmr_op(valid));
  485. return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
  486. }
  487. static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid,
  488. const struct mlxsw_sp_rif *rif)
  489. {
  490. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  491. char sfmr_pl[MLXSW_REG_SFMR_LEN];
  492. fid->fid_family->ops->fid_pack(sfmr_pl, fid,
  493. MLXSW_REG_SFMR_OP_CREATE_FID);
  494. mlxsw_reg_sfmr_vv_set(sfmr_pl, fid->vni_valid);
  495. mlxsw_reg_sfmr_vni_set(sfmr_pl, be32_to_cpu(fid->vni));
  496. mlxsw_reg_sfmr_vtfp_set(sfmr_pl, fid->nve_flood_index_valid);
  497. mlxsw_reg_sfmr_nve_tunnel_flood_ptr_set(sfmr_pl, fid->nve_flood_index);
  498. if (rif) {
  499. mlxsw_reg_sfmr_irif_v_set(sfmr_pl, true);
  500. mlxsw_reg_sfmr_irif_set(sfmr_pl, mlxsw_sp_rif_index(rif));
  501. }
  502. return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
  503. }
  504. static int mlxsw_sp_fid_vni_to_fid_map(const struct mlxsw_sp_fid *fid,
  505. const struct mlxsw_sp_rif *rif,
  506. bool valid)
  507. {
  508. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  509. char svfa_pl[MLXSW_REG_SVFA_LEN];
  510. bool irif_valid;
  511. u16 irif_index;
  512. irif_valid = !!rif;
  513. irif_index = rif ? mlxsw_sp_rif_index(rif) : 0;
  514. mlxsw_reg_svfa_vni_pack(svfa_pl, valid, fid->fid_index,
  515. be32_to_cpu(fid->vni), irif_valid, irif_index);
  516. return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
  517. }
  518. static int mlxsw_sp_fid_to_fid_rif_update(const struct mlxsw_sp_fid *fid,
  519. const struct mlxsw_sp_rif *rif)
  520. {
  521. return mlxsw_sp_fid_edit_op(fid, rif);
  522. }
  523. static int mlxsw_sp_fid_vni_to_fid_rif_update(const struct mlxsw_sp_fid *fid,
  524. const struct mlxsw_sp_rif *rif)
  525. {
  526. if (!fid->vni_valid)
  527. return 0;
  528. return mlxsw_sp_fid_vni_to_fid_map(fid, rif, fid->vni_valid);
  529. }
  530. static int
  531. mlxsw_sp_fid_vid_to_fid_map(const struct mlxsw_sp_fid *fid, u16 vid, bool valid,
  532. const struct mlxsw_sp_rif *rif)
  533. {
  534. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  535. char svfa_pl[MLXSW_REG_SVFA_LEN];
  536. bool irif_valid;
  537. u16 irif_index;
  538. irif_valid = !!rif;
  539. irif_index = rif ? mlxsw_sp_rif_index(rif) : 0;
  540. mlxsw_reg_svfa_vid_pack(svfa_pl, valid, fid->fid_index, vid, irif_valid,
  541. irif_index);
  542. return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
  543. }
  544. static int
  545. mlxsw_sp_fid_8021q_vid_to_fid_rif_update(const struct mlxsw_sp_fid *fid,
  546. const struct mlxsw_sp_rif *rif)
  547. {
  548. struct mlxsw_sp_fid_8021q *fid_8021q = mlxsw_sp_fid_8021q_fid(fid);
  549. /* Update the global VID => FID mapping we created when the FID was
  550. * configured.
  551. */
  552. return mlxsw_sp_fid_vid_to_fid_map(fid, fid_8021q->vid, true, rif);
  553. }
  554. static int
  555. mlxsw_sp_fid_port_vid_to_fid_rif_update_one(const struct mlxsw_sp_fid *fid,
  556. struct mlxsw_sp_fid_port_vid *pv,
  557. bool irif_valid, u16 irif_index)
  558. {
  559. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  560. char svfa_pl[MLXSW_REG_SVFA_LEN];
  561. mlxsw_reg_svfa_port_vid_pack(svfa_pl, pv->local_port, true,
  562. fid->fid_index, pv->vid, irif_valid,
  563. irif_index);
  564. return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
  565. }
  566. static int mlxsw_sp_fid_vid_to_fid_rif_set(const struct mlxsw_sp_fid *fid,
  567. const struct mlxsw_sp_rif *rif)
  568. {
  569. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  570. struct mlxsw_sp_fid_port_vid *pv;
  571. u16 irif_index;
  572. int err;
  573. err = fid->fid_family->ops->vid_to_fid_rif_update(fid, rif);
  574. if (err)
  575. return err;
  576. irif_index = mlxsw_sp_rif_index(rif);
  577. list_for_each_entry(pv, &fid->port_vid_list, list) {
  578. /* If port is not in virtual mode, then it does not have any
  579. * {Port, VID}->FID mappings that need to be updated with the
  580. * ingress RIF.
  581. */
  582. if (!mlxsw_sp->fid_core->port_fid_mappings[pv->local_port])
  583. continue;
  584. err = mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv,
  585. true,
  586. irif_index);
  587. if (err)
  588. goto err_port_vid_to_fid_rif_update_one;
  589. }
  590. return 0;
  591. err_port_vid_to_fid_rif_update_one:
  592. list_for_each_entry_continue_reverse(pv, &fid->port_vid_list, list) {
  593. if (!mlxsw_sp->fid_core->port_fid_mappings[pv->local_port])
  594. continue;
  595. mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv, false, 0);
  596. }
  597. fid->fid_family->ops->vid_to_fid_rif_update(fid, NULL);
  598. return err;
  599. }
  600. static void mlxsw_sp_fid_vid_to_fid_rif_unset(const struct mlxsw_sp_fid *fid)
  601. {
  602. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  603. struct mlxsw_sp_fid_port_vid *pv;
  604. list_for_each_entry(pv, &fid->port_vid_list, list) {
  605. /* If port is not in virtual mode, then it does not have any
  606. * {Port, VID}->FID mappings that need to be updated.
  607. */
  608. if (!mlxsw_sp->fid_core->port_fid_mappings[pv->local_port])
  609. continue;
  610. mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv, false, 0);
  611. }
  612. fid->fid_family->ops->vid_to_fid_rif_update(fid, NULL);
  613. }
  614. static int mlxsw_sp_fid_reiv_handle(struct mlxsw_sp_fid *fid, u16 rif_index,
  615. bool valid, u8 port_page)
  616. {
  617. u16 local_port_end = (port_page + 1) * MLXSW_REG_REIV_REC_MAX_COUNT - 1;
  618. u16 local_port_start = port_page * MLXSW_REG_REIV_REC_MAX_COUNT;
  619. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  620. struct mlxsw_sp_fid_port_vid *port_vid;
  621. u8 rec_num, entries_num = 0;
  622. char *reiv_pl;
  623. int err;
  624. reiv_pl = kmalloc(MLXSW_REG_REIV_LEN, GFP_KERNEL);
  625. if (!reiv_pl)
  626. return -ENOMEM;
  627. mlxsw_reg_reiv_pack(reiv_pl, port_page, rif_index);
  628. list_for_each_entry(port_vid, &fid->port_vid_list, list) {
  629. /* port_vid_list is sorted by local_port. */
  630. if (port_vid->local_port < local_port_start)
  631. continue;
  632. if (port_vid->local_port > local_port_end)
  633. break;
  634. rec_num = port_vid->local_port % MLXSW_REG_REIV_REC_MAX_COUNT;
  635. mlxsw_reg_reiv_rec_update_set(reiv_pl, rec_num, true);
  636. mlxsw_reg_reiv_rec_evid_set(reiv_pl, rec_num,
  637. valid ? port_vid->vid : 0);
  638. entries_num++;
  639. }
  640. if (!entries_num) {
  641. kfree(reiv_pl);
  642. return 0;
  643. }
  644. err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(reiv), reiv_pl);
  645. if (err)
  646. goto err_reg_write;
  647. kfree(reiv_pl);
  648. return 0;
  649. err_reg_write:
  650. kfree(reiv_pl);
  651. return err;
  652. }
  653. static int mlxsw_sp_fid_erif_eport_to_vid_map(struct mlxsw_sp_fid *fid,
  654. u16 rif_index, bool valid)
  655. {
  656. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  657. u8 num_port_pages;
  658. int err, i;
  659. num_port_pages = mlxsw_core_max_ports(mlxsw_sp->core) /
  660. MLXSW_REG_REIV_REC_MAX_COUNT + 1;
  661. for (i = 0; i < num_port_pages; i++) {
  662. err = mlxsw_sp_fid_reiv_handle(fid, rif_index, valid, i);
  663. if (err)
  664. goto err_reiv_handle;
  665. }
  666. return 0;
  667. err_reiv_handle:
  668. for (; i >= 0; i--)
  669. mlxsw_sp_fid_reiv_handle(fid, rif_index, !valid, i);
  670. return err;
  671. }
  672. int mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif)
  673. {
  674. u16 rif_index = mlxsw_sp_rif_index(rif);
  675. int err;
  676. err = mlxsw_sp_fid_to_fid_rif_update(fid, rif);
  677. if (err)
  678. return err;
  679. err = mlxsw_sp_fid_vni_to_fid_rif_update(fid, rif);
  680. if (err)
  681. goto err_vni_to_fid_rif_update;
  682. err = mlxsw_sp_fid_vid_to_fid_rif_set(fid, rif);
  683. if (err)
  684. goto err_vid_to_fid_rif_set;
  685. err = mlxsw_sp_fid_erif_eport_to_vid_map(fid, rif_index, true);
  686. if (err)
  687. goto err_erif_eport_to_vid_map;
  688. fid->rif = rif;
  689. return 0;
  690. err_erif_eport_to_vid_map:
  691. mlxsw_sp_fid_vid_to_fid_rif_unset(fid);
  692. err_vid_to_fid_rif_set:
  693. mlxsw_sp_fid_vni_to_fid_rif_update(fid, NULL);
  694. err_vni_to_fid_rif_update:
  695. mlxsw_sp_fid_to_fid_rif_update(fid, NULL);
  696. return err;
  697. }
  698. void mlxsw_sp_fid_rif_unset(struct mlxsw_sp_fid *fid)
  699. {
  700. u16 rif_index;
  701. if (!fid->rif)
  702. return;
  703. rif_index = mlxsw_sp_rif_index(fid->rif);
  704. fid->rif = NULL;
  705. mlxsw_sp_fid_erif_eport_to_vid_map(fid, rif_index, false);
  706. mlxsw_sp_fid_vid_to_fid_rif_unset(fid);
  707. mlxsw_sp_fid_vni_to_fid_rif_update(fid, NULL);
  708. mlxsw_sp_fid_to_fid_rif_update(fid, NULL);
  709. }
  710. static int mlxsw_sp_fid_vni_op(const struct mlxsw_sp_fid *fid)
  711. {
  712. int err;
  713. err = mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, fid->vni_valid);
  714. if (err)
  715. return err;
  716. err = mlxsw_sp_fid_edit_op(fid, fid->rif);
  717. if (err)
  718. goto err_fid_edit_op;
  719. return 0;
  720. err_fid_edit_op:
  721. mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, !fid->vni_valid);
  722. return err;
  723. }
  724. static int __mlxsw_sp_fid_port_vid_map(const struct mlxsw_sp_fid *fid,
  725. u16 local_port, u16 vid, bool valid)
  726. {
  727. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  728. char svfa_pl[MLXSW_REG_SVFA_LEN];
  729. bool irif_valid = false;
  730. u16 irif_index = 0;
  731. if (fid->rif) {
  732. irif_valid = true;
  733. irif_index = mlxsw_sp_rif_index(fid->rif);
  734. }
  735. mlxsw_reg_svfa_port_vid_pack(svfa_pl, local_port, valid, fid->fid_index,
  736. vid, irif_valid, irif_index);
  737. return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
  738. }
  739. static struct mlxsw_sp_fid_8021d *
  740. mlxsw_sp_fid_8021d_fid(const struct mlxsw_sp_fid *fid)
  741. {
  742. return container_of(fid, struct mlxsw_sp_fid_8021d, common);
  743. }
  744. static int mlxsw_sp_fid_8021d_setup(struct mlxsw_sp_fid *fid, const void *arg)
  745. {
  746. int br_ifindex = *(int *) arg;
  747. mlxsw_sp_fid_8021d_fid(fid)->br_ifindex = br_ifindex;
  748. fid->fid_offset = fid->fid_index - fid->fid_family->start_index;
  749. return 0;
  750. }
  751. static int mlxsw_sp_fid_8021d_configure(struct mlxsw_sp_fid *fid)
  752. {
  753. return mlxsw_sp_fid_op(fid, true);
  754. }
  755. static void mlxsw_sp_fid_8021d_deconfigure(struct mlxsw_sp_fid *fid)
  756. {
  757. if (fid->vni_valid)
  758. mlxsw_sp_nve_fid_disable(fid->fid_family->mlxsw_sp, fid);
  759. mlxsw_sp_fid_op(fid, false);
  760. }
  761. static int mlxsw_sp_fid_8021d_index_alloc(struct mlxsw_sp_fid *fid,
  762. const void *arg, u16 *p_fid_index)
  763. {
  764. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  765. u16 nr_fids, fid_index;
  766. nr_fids = fid_family->end_index - fid_family->start_index + 1;
  767. fid_index = find_first_zero_bit(fid_family->fids_bitmap, nr_fids);
  768. if (fid_index == nr_fids)
  769. return -ENOBUFS;
  770. *p_fid_index = fid_family->start_index + fid_index;
  771. return 0;
  772. }
  773. static bool
  774. mlxsw_sp_fid_8021d_compare(const struct mlxsw_sp_fid *fid, const void *arg)
  775. {
  776. int br_ifindex = *(int *) arg;
  777. return mlxsw_sp_fid_8021d_fid(fid)->br_ifindex == br_ifindex;
  778. }
  779. static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
  780. {
  781. struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
  782. int err;
  783. list_for_each_entry(mlxsw_sp_port_vlan, &mlxsw_sp_port->vlans_list,
  784. list) {
  785. struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
  786. u16 vid = mlxsw_sp_port_vlan->vid;
  787. if (!fid)
  788. continue;
  789. err = __mlxsw_sp_fid_port_vid_map(fid,
  790. mlxsw_sp_port->local_port,
  791. vid, true);
  792. if (err)
  793. goto err_fid_port_vid_map;
  794. }
  795. err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true);
  796. if (err)
  797. goto err_port_vp_mode_set;
  798. return 0;
  799. err_port_vp_mode_set:
  800. err_fid_port_vid_map:
  801. list_for_each_entry_continue_reverse(mlxsw_sp_port_vlan,
  802. &mlxsw_sp_port->vlans_list, list) {
  803. struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
  804. u16 vid = mlxsw_sp_port_vlan->vid;
  805. if (!fid)
  806. continue;
  807. __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid,
  808. false);
  809. }
  810. return err;
  811. }
  812. static void mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
  813. {
  814. struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
  815. mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
  816. list_for_each_entry_reverse(mlxsw_sp_port_vlan,
  817. &mlxsw_sp_port->vlans_list, list) {
  818. struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
  819. u16 vid = mlxsw_sp_port_vlan->vid;
  820. if (!fid)
  821. continue;
  822. __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid,
  823. false);
  824. }
  825. }
  826. static int
  827. mlxsw_sp_fid_port_vid_list_add(struct mlxsw_sp_fid *fid, u16 local_port,
  828. u16 vid)
  829. {
  830. struct mlxsw_sp_fid_port_vid *port_vid, *tmp_port_vid;
  831. port_vid = kzalloc(sizeof(*port_vid), GFP_KERNEL);
  832. if (!port_vid)
  833. return -ENOMEM;
  834. port_vid->local_port = local_port;
  835. port_vid->vid = vid;
  836. list_for_each_entry(tmp_port_vid, &fid->port_vid_list, list) {
  837. if (tmp_port_vid->local_port > local_port)
  838. break;
  839. }
  840. list_add_tail(&port_vid->list, &tmp_port_vid->list);
  841. return 0;
  842. }
  843. static void
  844. mlxsw_sp_fid_port_vid_list_del(struct mlxsw_sp_fid *fid, u16 local_port,
  845. u16 vid)
  846. {
  847. struct mlxsw_sp_fid_port_vid *port_vid, *tmp;
  848. list_for_each_entry_safe(port_vid, tmp, &fid->port_vid_list, list) {
  849. if (port_vid->local_port != local_port || port_vid->vid != vid)
  850. continue;
  851. list_del(&port_vid->list);
  852. kfree(port_vid);
  853. return;
  854. }
  855. }
  856. static int
  857. mlxsw_sp_fid_mpe_table_map(const struct mlxsw_sp_fid *fid, u16 local_port,
  858. u16 vid, bool valid)
  859. {
  860. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  861. char smpe_pl[MLXSW_REG_SMPE_LEN];
  862. mlxsw_reg_smpe_pack(smpe_pl, local_port, fid->fid_index,
  863. valid ? vid : 0);
  864. return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smpe), smpe_pl);
  865. }
  866. static int
  867. mlxsw_sp_fid_erif_eport_to_vid_map_one(const struct mlxsw_sp_fid *fid,
  868. u16 local_port, u16 vid, bool valid)
  869. {
  870. u8 port_page = local_port / MLXSW_REG_REIV_REC_MAX_COUNT;
  871. u8 rec_num = local_port % MLXSW_REG_REIV_REC_MAX_COUNT;
  872. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  873. u16 rif_index = mlxsw_sp_rif_index(fid->rif);
  874. char *reiv_pl;
  875. int err;
  876. reiv_pl = kmalloc(MLXSW_REG_REIV_LEN, GFP_KERNEL);
  877. if (!reiv_pl)
  878. return -ENOMEM;
  879. mlxsw_reg_reiv_pack(reiv_pl, port_page, rif_index);
  880. mlxsw_reg_reiv_rec_update_set(reiv_pl, rec_num, true);
  881. mlxsw_reg_reiv_rec_evid_set(reiv_pl, rec_num, valid ? vid : 0);
  882. err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(reiv), reiv_pl);
  883. kfree(reiv_pl);
  884. return err;
  885. }
  886. static int mlxsw_sp_fid_evid_map(const struct mlxsw_sp_fid *fid, u16 local_port,
  887. u16 vid, bool valid)
  888. {
  889. int err;
  890. err = mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, valid);
  891. if (err)
  892. return err;
  893. if (!fid->rif)
  894. return 0;
  895. err = mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, vid,
  896. valid);
  897. if (err)
  898. goto err_erif_eport_to_vid_map_one;
  899. return 0;
  900. err_erif_eport_to_vid_map_one:
  901. mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, !valid);
  902. return err;
  903. }
  904. static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid,
  905. struct mlxsw_sp_port *mlxsw_sp_port,
  906. u16 vid)
  907. {
  908. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  909. u16 local_port = mlxsw_sp_port->local_port;
  910. int err;
  911. err = __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid,
  912. true);
  913. if (err)
  914. return err;
  915. err = mlxsw_sp_fid_evid_map(fid, local_port, vid, true);
  916. if (err)
  917. goto err_fid_evid_map;
  918. err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port,
  919. vid);
  920. if (err)
  921. goto err_port_vid_list_add;
  922. if (mlxsw_sp->fid_core->port_fid_mappings[local_port]++ == 0) {
  923. err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
  924. if (err)
  925. goto err_port_vp_mode_trans;
  926. }
  927. return 0;
  928. err_port_vp_mode_trans:
  929. mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
  930. mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
  931. err_port_vid_list_add:
  932. mlxsw_sp_fid_evid_map(fid, local_port, vid, false);
  933. err_fid_evid_map:
  934. __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
  935. return err;
  936. }
  937. static void
  938. mlxsw_sp_fid_8021d_port_vid_unmap(struct mlxsw_sp_fid *fid,
  939. struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
  940. {
  941. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  942. u16 local_port = mlxsw_sp_port->local_port;
  943. if (mlxsw_sp->fid_core->port_fid_mappings[local_port] == 1)
  944. mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
  945. mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
  946. mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
  947. mlxsw_sp_fid_evid_map(fid, local_port, vid, false);
  948. __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
  949. }
  950. static int mlxsw_sp_fid_8021d_vni_set(struct mlxsw_sp_fid *fid)
  951. {
  952. return mlxsw_sp_fid_vni_op(fid);
  953. }
  954. static void mlxsw_sp_fid_8021d_vni_clear(struct mlxsw_sp_fid *fid)
  955. {
  956. mlxsw_sp_fid_vni_op(fid);
  957. }
  958. static int mlxsw_sp_fid_8021d_nve_flood_index_set(struct mlxsw_sp_fid *fid)
  959. {
  960. return mlxsw_sp_fid_edit_op(fid, fid->rif);
  961. }
  962. static void mlxsw_sp_fid_8021d_nve_flood_index_clear(struct mlxsw_sp_fid *fid)
  963. {
  964. mlxsw_sp_fid_edit_op(fid, fid->rif);
  965. }
  966. static void
  967. mlxsw_sp_fid_8021d_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
  968. const struct net_device *nve_dev)
  969. {
  970. br_fdb_clear_offload(nve_dev, 0);
  971. }
  972. static int
  973. mlxsw_sp_fid_8021d_vid_to_fid_rif_update(const struct mlxsw_sp_fid *fid,
  974. const struct mlxsw_sp_rif *rif)
  975. {
  976. return 0;
  977. }
  978. static int
  979. mlxsw_sp_fid_flood_table_init_ctl(struct mlxsw_sp_fid_family *fid_family,
  980. const struct mlxsw_sp_flood_table *flood_table)
  981. {
  982. enum mlxsw_sp_flood_type packet_type = flood_table->packet_type;
  983. struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;
  984. const int *sfgc_packet_types;
  985. u16 mid_base;
  986. int err, i;
  987. mid_base = mlxsw_sp_fid_pgt_base_ctl(fid_family, flood_table);
  988. sfgc_packet_types = mlxsw_sp_packet_type_sfgc_types[packet_type];
  989. for (i = 0; i < MLXSW_REG_SFGC_TYPE_MAX; i++) {
  990. char sfgc_pl[MLXSW_REG_SFGC_LEN];
  991. if (!sfgc_packet_types[i])
  992. continue;
  993. mlxsw_reg_sfgc_pack(sfgc_pl, i, fid_family->bridge_type,
  994. flood_table->table_type, 0, mid_base);
  995. err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfgc), sfgc_pl);
  996. if (err)
  997. return err;
  998. }
  999. return 0;
  1000. }
  1001. static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops_ctl = {
  1002. .setup = mlxsw_sp_fid_8021d_setup,
  1003. .configure = mlxsw_sp_fid_8021d_configure,
  1004. .deconfigure = mlxsw_sp_fid_8021d_deconfigure,
  1005. .index_alloc = mlxsw_sp_fid_8021d_index_alloc,
  1006. .compare = mlxsw_sp_fid_8021d_compare,
  1007. .port_vid_map = mlxsw_sp_fid_8021d_port_vid_map,
  1008. .port_vid_unmap = mlxsw_sp_fid_8021d_port_vid_unmap,
  1009. .vni_set = mlxsw_sp_fid_8021d_vni_set,
  1010. .vni_clear = mlxsw_sp_fid_8021d_vni_clear,
  1011. .nve_flood_index_set = mlxsw_sp_fid_8021d_nve_flood_index_set,
  1012. .nve_flood_index_clear = mlxsw_sp_fid_8021d_nve_flood_index_clear,
  1013. .fdb_clear_offload = mlxsw_sp_fid_8021d_fdb_clear_offload,
  1014. .vid_to_fid_rif_update = mlxsw_sp_fid_8021d_vid_to_fid_rif_update,
  1015. .flood_table_init = mlxsw_sp_fid_flood_table_init_ctl,
  1016. .pgt_size = mlxsw_sp_fid_8021d_pgt_size,
  1017. .fid_mid = mlxsw_sp_fid_fid_mid_ctl,
  1018. .fid_pack = mlxsw_sp_fid_pack_ctl,
  1019. };
  1020. static u16
  1021. mlxsw_sp_fid_fid_mid_cff(const struct mlxsw_sp_fid *fid,
  1022. const struct mlxsw_sp_flood_table *flood_table)
  1023. {
  1024. return mlxsw_sp_fid_pgt_base_cff(fid) + flood_table->table_index;
  1025. }
  1026. static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops_cff = {
  1027. .setup = mlxsw_sp_fid_8021d_setup,
  1028. .configure = mlxsw_sp_fid_8021d_configure,
  1029. .deconfigure = mlxsw_sp_fid_8021d_deconfigure,
  1030. .index_alloc = mlxsw_sp_fid_8021d_index_alloc,
  1031. .compare = mlxsw_sp_fid_8021d_compare,
  1032. .port_vid_map = mlxsw_sp_fid_8021d_port_vid_map,
  1033. .port_vid_unmap = mlxsw_sp_fid_8021d_port_vid_unmap,
  1034. .vni_set = mlxsw_sp_fid_8021d_vni_set,
  1035. .vni_clear = mlxsw_sp_fid_8021d_vni_clear,
  1036. .nve_flood_index_set = mlxsw_sp_fid_8021d_nve_flood_index_set,
  1037. .nve_flood_index_clear = mlxsw_sp_fid_8021d_nve_flood_index_clear,
  1038. .fdb_clear_offload = mlxsw_sp_fid_8021d_fdb_clear_offload,
  1039. .vid_to_fid_rif_update = mlxsw_sp_fid_8021d_vid_to_fid_rif_update,
  1040. .pgt_size = mlxsw_sp_fid_8021d_pgt_size,
  1041. .fid_mid = mlxsw_sp_fid_fid_mid_cff,
  1042. .fid_pack = mlxsw_sp_fid_fid_pack_cff,
  1043. };
  1044. #define MLXSW_SP_FID_8021Q_MAX (VLAN_N_VID - 2)
  1045. #define MLXSW_SP_FID_RFID_MAX (11 * 1024)
  1046. static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_flood_tables[] = {
  1047. {
  1048. .packet_type = MLXSW_SP_FLOOD_TYPE_UC,
  1049. .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET,
  1050. .table_index = 0,
  1051. },
  1052. {
  1053. .packet_type = MLXSW_SP_FLOOD_TYPE_MC,
  1054. .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET,
  1055. .table_index = 1,
  1056. },
  1057. {
  1058. .packet_type = MLXSW_SP_FLOOD_TYPE_BC,
  1059. .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET,
  1060. .table_index = 2,
  1061. },
  1062. };
  1063. static const
  1064. struct mlxsw_sp_fid_flood_profile mlxsw_sp_fid_8021d_flood_profile = {
  1065. .flood_tables = mlxsw_sp_fid_8021d_flood_tables,
  1066. .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_flood_tables),
  1067. .profile_id = MLXSW_SP_FID_FLOOD_PROFILE_ID_BRIDGE,
  1068. };
  1069. static const struct mlxsw_sp_flood_table mlxsw_sp_fid_rsp_flood_tables_cff[] = {
  1070. {
  1071. .packet_type = MLXSW_SP_FLOOD_TYPE_UC,
  1072. .table_index = 0,
  1073. },
  1074. {
  1075. .packet_type = MLXSW_SP_FLOOD_TYPE_NOT_UC,
  1076. .table_index = 1,
  1077. },
  1078. };
  1079. static const
  1080. struct mlxsw_sp_fid_flood_profile mlxsw_sp_fid_rsp_flood_profile_cff = {
  1081. .flood_tables = mlxsw_sp_fid_rsp_flood_tables_cff,
  1082. .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_rsp_flood_tables_cff),
  1083. .profile_id = MLXSW_SP_FID_FLOOD_PROFILE_ID_RSP,
  1084. };
  1085. static const struct mlxsw_sp_flood_table mlxsw_sp_fid_nve_flood_tables_cff[] = {
  1086. {
  1087. .packet_type = MLXSW_SP_FLOOD_TYPE_ANY,
  1088. .table_index = 0,
  1089. },
  1090. };
  1091. static const
  1092. struct mlxsw_sp_fid_flood_profile mlxsw_sp_fid_nve_flood_profile_cff = {
  1093. .flood_tables = mlxsw_sp_fid_nve_flood_tables_cff,
  1094. .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_nve_flood_tables_cff),
  1095. .profile_id = MLXSW_SP_FID_FLOOD_PROFILE_ID_NVE,
  1096. };
  1097. static bool
  1098. mlxsw_sp_fid_8021q_compare(const struct mlxsw_sp_fid *fid, const void *arg)
  1099. {
  1100. u16 vid = *(u16 *) arg;
  1101. return mlxsw_sp_fid_8021q_fid(fid)->vid == vid;
  1102. }
  1103. static void
  1104. mlxsw_sp_fid_8021q_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
  1105. const struct net_device *nve_dev)
  1106. {
  1107. br_fdb_clear_offload(nve_dev, mlxsw_sp_fid_8021q_vid(fid));
  1108. }
  1109. static int mlxsw_sp_fid_rfid_setup_ctl(struct mlxsw_sp_fid *fid,
  1110. const void *arg)
  1111. {
  1112. /* In controlled mode, the FW takes care of FID placement. */
  1113. fid->fid_offset = 0;
  1114. return 0;
  1115. }
  1116. static int mlxsw_sp_fid_rfid_setup_cff(struct mlxsw_sp_fid *fid,
  1117. const void *arg)
  1118. {
  1119. struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
  1120. u16 rif_index = *(const u16 *)arg;
  1121. struct mlxsw_sp_rif *rif;
  1122. bool is_lag;
  1123. u16 port;
  1124. int err;
  1125. rif = mlxsw_sp_rif_by_index(mlxsw_sp, rif_index);
  1126. if (!rif)
  1127. return -ENOENT;
  1128. err = mlxsw_sp_rif_subport_port(rif, &port, &is_lag);
  1129. if (err)
  1130. return err;
  1131. fid->fid_offset = mlxsw_sp_fid_rfid_fid_offset_cff(mlxsw_sp, port,
  1132. is_lag);
  1133. return 0;
  1134. }
  1135. static int mlxsw_sp_fid_rfid_configure(struct mlxsw_sp_fid *fid)
  1136. {
  1137. return mlxsw_sp_fid_op(fid, true);
  1138. }
  1139. static void mlxsw_sp_fid_rfid_deconfigure(struct mlxsw_sp_fid *fid)
  1140. {
  1141. mlxsw_sp_fid_op(fid, false);
  1142. }
  1143. static int mlxsw_sp_fid_rfid_index_alloc(struct mlxsw_sp_fid *fid,
  1144. const void *arg, u16 *p_fid_index)
  1145. {
  1146. u16 rif_index = *(u16 *) arg;
  1147. *p_fid_index = fid->fid_family->start_index + rif_index;
  1148. return 0;
  1149. }
  1150. static bool mlxsw_sp_fid_rfid_compare(const struct mlxsw_sp_fid *fid,
  1151. const void *arg)
  1152. {
  1153. u16 rif_index = *(u16 *) arg;
  1154. return fid->fid_index == rif_index + fid->fid_family->start_index;
  1155. }
  1156. static int mlxsw_sp_fid_rfid_port_vid_map(struct mlxsw_sp_fid *fid,
  1157. struct mlxsw_sp_port *mlxsw_sp_port,
  1158. u16 vid)
  1159. {
  1160. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1161. u16 local_port = mlxsw_sp_port->local_port;
  1162. int err;
  1163. err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port,
  1164. vid);
  1165. if (err)
  1166. return err;
  1167. /* Using legacy bridge model, we only need to transition the port to
  1168. * virtual mode since {Port, VID} => FID is done by the firmware upon
  1169. * RIF creation. Using unified bridge model, we need to map
  1170. * {Port, VID} => FID and map egress VID.
  1171. */
  1172. err = __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid,
  1173. true);
  1174. if (err)
  1175. goto err_port_vid_map;
  1176. if (fid->rif) {
  1177. err = mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port,
  1178. vid, true);
  1179. if (err)
  1180. goto err_erif_eport_to_vid_map_one;
  1181. }
  1182. if (mlxsw_sp->fid_core->port_fid_mappings[local_port]++ == 0) {
  1183. err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
  1184. if (err)
  1185. goto err_port_vp_mode_trans;
  1186. }
  1187. return 0;
  1188. err_port_vp_mode_trans:
  1189. mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
  1190. if (fid->rif)
  1191. mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, vid,
  1192. false);
  1193. err_erif_eport_to_vid_map_one:
  1194. __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
  1195. err_port_vid_map:
  1196. mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
  1197. return err;
  1198. }
  1199. static void
  1200. mlxsw_sp_fid_rfid_port_vid_unmap(struct mlxsw_sp_fid *fid,
  1201. struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
  1202. {
  1203. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1204. u16 local_port = mlxsw_sp_port->local_port;
  1205. if (mlxsw_sp->fid_core->port_fid_mappings[local_port] == 1)
  1206. mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
  1207. mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
  1208. if (fid->rif)
  1209. mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, vid,
  1210. false);
  1211. __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
  1212. mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
  1213. }
  1214. static int mlxsw_sp_fid_rfid_vni_set(struct mlxsw_sp_fid *fid)
  1215. {
  1216. return -EOPNOTSUPP;
  1217. }
  1218. static void mlxsw_sp_fid_rfid_vni_clear(struct mlxsw_sp_fid *fid)
  1219. {
  1220. WARN_ON_ONCE(1);
  1221. }
  1222. static int mlxsw_sp_fid_rfid_nve_flood_index_set(struct mlxsw_sp_fid *fid)
  1223. {
  1224. return -EOPNOTSUPP;
  1225. }
  1226. static void mlxsw_sp_fid_rfid_nve_flood_index_clear(struct mlxsw_sp_fid *fid)
  1227. {
  1228. WARN_ON_ONCE(1);
  1229. }
  1230. static int
  1231. mlxsw_sp_fid_rfid_vid_to_fid_rif_update(const struct mlxsw_sp_fid *fid,
  1232. const struct mlxsw_sp_rif *rif)
  1233. {
  1234. return 0;
  1235. }
  1236. static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops_ctl = {
  1237. .setup = mlxsw_sp_fid_rfid_setup_ctl,
  1238. .configure = mlxsw_sp_fid_rfid_configure,
  1239. .deconfigure = mlxsw_sp_fid_rfid_deconfigure,
  1240. .index_alloc = mlxsw_sp_fid_rfid_index_alloc,
  1241. .compare = mlxsw_sp_fid_rfid_compare,
  1242. .port_vid_map = mlxsw_sp_fid_rfid_port_vid_map,
  1243. .port_vid_unmap = mlxsw_sp_fid_rfid_port_vid_unmap,
  1244. .vni_set = mlxsw_sp_fid_rfid_vni_set,
  1245. .vni_clear = mlxsw_sp_fid_rfid_vni_clear,
  1246. .nve_flood_index_set = mlxsw_sp_fid_rfid_nve_flood_index_set,
  1247. .nve_flood_index_clear = mlxsw_sp_fid_rfid_nve_flood_index_clear,
  1248. .vid_to_fid_rif_update = mlxsw_sp_fid_rfid_vid_to_fid_rif_update,
  1249. .fid_pack = mlxsw_sp_fid_pack_ctl,
  1250. };
  1251. static int
  1252. mlxsw_sp_fid_rfid_port_add_cff(struct mlxsw_sp *mlxsw_sp,
  1253. const struct mlxsw_sp_flood_table *flood_table,
  1254. u16 pgt_addr, u16 smpe, unsigned int local_port)
  1255. {
  1256. int err;
  1257. err = mlxsw_sp_pgt_entry_port_set(mlxsw_sp, pgt_addr, smpe,
  1258. local_port, true);
  1259. if (err)
  1260. return err;
  1261. if (flood_table->packet_type == MLXSW_SP_FLOOD_TYPE_NOT_UC) {
  1262. u16 router_port = mlxsw_sp_router_port(mlxsw_sp);
  1263. err = mlxsw_sp_pgt_entry_port_set(mlxsw_sp, pgt_addr, smpe,
  1264. router_port, true);
  1265. if (err)
  1266. goto err_entry_port_set;
  1267. }
  1268. return 0;
  1269. err_entry_port_set:
  1270. mlxsw_sp_pgt_entry_port_set(mlxsw_sp, pgt_addr, smpe, local_port,
  1271. false);
  1272. return err;
  1273. }
  1274. static void
  1275. mlxsw_sp_fid_rfid_port_del_cff(struct mlxsw_sp *mlxsw_sp,
  1276. const struct mlxsw_sp_flood_table *flood_table,
  1277. u16 pgt_addr, u16 smpe, u16 local_port)
  1278. {
  1279. if (flood_table->packet_type == MLXSW_SP_FLOOD_TYPE_NOT_UC) {
  1280. u16 router_port = mlxsw_sp_router_port(mlxsw_sp);
  1281. mlxsw_sp_pgt_entry_port_set(mlxsw_sp, pgt_addr, smpe,
  1282. router_port, false);
  1283. }
  1284. mlxsw_sp_pgt_entry_port_set(mlxsw_sp, pgt_addr, smpe, local_port,
  1285. false);
  1286. }
  1287. static int
  1288. mlxsw_sp_fid_rfid_port_memb_ft_cff(const struct mlxsw_sp_fid_family *fid_family,
  1289. const struct mlxsw_sp_flood_table *flood_table,
  1290. const struct mlxsw_sp_port *mlxsw_sp_port,
  1291. bool member)
  1292. {
  1293. struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;
  1294. u16 local_port = mlxsw_sp_port->local_port;
  1295. u16 fid_pgt_base;
  1296. u16 fid_offset;
  1297. u16 pgt_addr;
  1298. u16 smpe;
  1299. u16 port;
  1300. /* In-PGT SMPE is only valid on Spectrum-1, CFF only on Spectrum>1. */
  1301. smpe = 0;
  1302. port = mlxsw_sp_port->lagged ? mlxsw_sp_port->lag_id : local_port;
  1303. fid_offset = mlxsw_sp_fid_rfid_fid_offset_cff(mlxsw_sp, port,
  1304. mlxsw_sp_port->lagged);
  1305. fid_pgt_base = mlxsw_sp_fid_off_pgt_base_cff(fid_family, fid_offset);
  1306. pgt_addr = fid_pgt_base + flood_table->table_index;
  1307. if (member)
  1308. return mlxsw_sp_fid_rfid_port_add_cff(mlxsw_sp, flood_table,
  1309. pgt_addr, smpe,
  1310. local_port);
  1311. mlxsw_sp_fid_rfid_port_del_cff(mlxsw_sp, flood_table, pgt_addr, smpe,
  1312. local_port);
  1313. return 0;
  1314. }
  1315. static int
  1316. mlxsw_sp_fid_rfid_port_memb_cff(const struct mlxsw_sp_fid_family *fid_family,
  1317. const struct mlxsw_sp_port *mlxsw_sp_port,
  1318. bool member)
  1319. {
  1320. int i;
  1321. for (i = 0; i < fid_family->flood_profile->nr_flood_tables; i++) {
  1322. const struct mlxsw_sp_flood_table *flood_table =
  1323. &fid_family->flood_profile->flood_tables[i];
  1324. int err;
  1325. err = mlxsw_sp_fid_rfid_port_memb_ft_cff(fid_family,
  1326. flood_table,
  1327. mlxsw_sp_port, member);
  1328. if (err)
  1329. return err;
  1330. }
  1331. return 0;
  1332. }
  1333. static int
  1334. mlxsw_sp_fid_rfid_port_init_cff(const struct mlxsw_sp_fid_family *fid_family,
  1335. const struct mlxsw_sp_port *mlxsw_sp_port)
  1336. {
  1337. return mlxsw_sp_fid_rfid_port_memb_cff(fid_family, mlxsw_sp_port, true);
  1338. }
  1339. static void
  1340. mlxsw_sp_fid_rfid_port_fini_cff(const struct mlxsw_sp_fid_family *fid_family,
  1341. const struct mlxsw_sp_port *mlxsw_sp_port)
  1342. {
  1343. mlxsw_sp_fid_rfid_port_memb_cff(fid_family, mlxsw_sp_port, false);
  1344. }
  1345. static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops_cff = {
  1346. .setup = mlxsw_sp_fid_rfid_setup_cff,
  1347. .configure = mlxsw_sp_fid_rfid_configure,
  1348. .deconfigure = mlxsw_sp_fid_rfid_deconfigure,
  1349. .index_alloc = mlxsw_sp_fid_rfid_index_alloc,
  1350. .compare = mlxsw_sp_fid_rfid_compare,
  1351. .port_vid_map = mlxsw_sp_fid_rfid_port_vid_map,
  1352. .port_vid_unmap = mlxsw_sp_fid_rfid_port_vid_unmap,
  1353. .vni_set = mlxsw_sp_fid_rfid_vni_set,
  1354. .vni_clear = mlxsw_sp_fid_rfid_vni_clear,
  1355. .nve_flood_index_set = mlxsw_sp_fid_rfid_nve_flood_index_set,
  1356. .nve_flood_index_clear = mlxsw_sp_fid_rfid_nve_flood_index_clear,
  1357. .vid_to_fid_rif_update = mlxsw_sp_fid_rfid_vid_to_fid_rif_update,
  1358. .pgt_size = mlxsw_sp_fid_rfid_pgt_size_cff,
  1359. .fid_port_init = mlxsw_sp_fid_rfid_port_init_cff,
  1360. .fid_port_fini = mlxsw_sp_fid_rfid_port_fini_cff,
  1361. .fid_mid = mlxsw_sp_fid_fid_mid_cff,
  1362. .fid_pack = mlxsw_sp_fid_fid_pack_cff,
  1363. };
  1364. static int mlxsw_sp_fid_dummy_setup(struct mlxsw_sp_fid *fid, const void *arg)
  1365. {
  1366. fid->fid_offset = 0;
  1367. return 0;
  1368. }
  1369. static int mlxsw_sp_fid_dummy_configure(struct mlxsw_sp_fid *fid)
  1370. {
  1371. return mlxsw_sp_fid_op(fid, true);
  1372. }
  1373. static void mlxsw_sp_fid_dummy_deconfigure(struct mlxsw_sp_fid *fid)
  1374. {
  1375. mlxsw_sp_fid_op(fid, false);
  1376. }
  1377. static int mlxsw_sp_fid_dummy_index_alloc(struct mlxsw_sp_fid *fid,
  1378. const void *arg, u16 *p_fid_index)
  1379. {
  1380. *p_fid_index = fid->fid_family->start_index;
  1381. return 0;
  1382. }
  1383. static bool mlxsw_sp_fid_dummy_compare(const struct mlxsw_sp_fid *fid,
  1384. const void *arg)
  1385. {
  1386. return true;
  1387. }
  1388. static int mlxsw_sp_fid_dummy_vni_set(struct mlxsw_sp_fid *fid)
  1389. {
  1390. return -EOPNOTSUPP;
  1391. }
  1392. static void mlxsw_sp_fid_dummy_vni_clear(struct mlxsw_sp_fid *fid)
  1393. {
  1394. WARN_ON_ONCE(1);
  1395. }
  1396. static int mlxsw_sp_fid_dummy_nve_flood_index_set(struct mlxsw_sp_fid *fid)
  1397. {
  1398. return -EOPNOTSUPP;
  1399. }
  1400. static void mlxsw_sp_fid_dummy_nve_flood_index_clear(struct mlxsw_sp_fid *fid)
  1401. {
  1402. WARN_ON_ONCE(1);
  1403. }
  1404. static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_dummy_ops = {
  1405. .setup = mlxsw_sp_fid_dummy_setup,
  1406. .configure = mlxsw_sp_fid_dummy_configure,
  1407. .deconfigure = mlxsw_sp_fid_dummy_deconfigure,
  1408. .index_alloc = mlxsw_sp_fid_dummy_index_alloc,
  1409. .compare = mlxsw_sp_fid_dummy_compare,
  1410. .vni_set = mlxsw_sp_fid_dummy_vni_set,
  1411. .vni_clear = mlxsw_sp_fid_dummy_vni_clear,
  1412. .nve_flood_index_set = mlxsw_sp_fid_dummy_nve_flood_index_set,
  1413. .nve_flood_index_clear = mlxsw_sp_fid_dummy_nve_flood_index_clear,
  1414. .fid_pack = mlxsw_sp_fid_pack,
  1415. };
  1416. static int mlxsw_sp_fid_8021q_configure(struct mlxsw_sp_fid *fid)
  1417. {
  1418. struct mlxsw_sp_fid_8021q *fid_8021q = mlxsw_sp_fid_8021q_fid(fid);
  1419. int err;
  1420. err = mlxsw_sp_fid_op(fid, true);
  1421. if (err)
  1422. return err;
  1423. err = mlxsw_sp_fid_vid_to_fid_map(fid, fid_8021q->vid, true, fid->rif);
  1424. if (err)
  1425. goto err_vid_to_fid_map;
  1426. return 0;
  1427. err_vid_to_fid_map:
  1428. mlxsw_sp_fid_op(fid, false);
  1429. return err;
  1430. }
  1431. static void mlxsw_sp_fid_8021q_deconfigure(struct mlxsw_sp_fid *fid)
  1432. {
  1433. struct mlxsw_sp_fid_8021q *fid_8021q = mlxsw_sp_fid_8021q_fid(fid);
  1434. if (fid->vni_valid)
  1435. mlxsw_sp_nve_fid_disable(fid->fid_family->mlxsw_sp, fid);
  1436. mlxsw_sp_fid_vid_to_fid_map(fid, fid_8021q->vid, false, NULL);
  1437. mlxsw_sp_fid_op(fid, false);
  1438. }
  1439. static int mlxsw_sp_fid_8021q_port_vid_map(struct mlxsw_sp_fid *fid,
  1440. struct mlxsw_sp_port *mlxsw_sp_port,
  1441. u16 vid)
  1442. {
  1443. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1444. u16 local_port = mlxsw_sp_port->local_port;
  1445. int err;
  1446. /* In case there are no {Port, VID} => FID mappings on the port,
  1447. * we can use the global VID => FID mapping we created when the
  1448. * FID was configured, otherwise, configure new mapping.
  1449. */
  1450. if (mlxsw_sp->fid_core->port_fid_mappings[local_port]) {
  1451. err = __mlxsw_sp_fid_port_vid_map(fid, local_port, vid, true);
  1452. if (err)
  1453. return err;
  1454. }
  1455. err = mlxsw_sp_fid_evid_map(fid, local_port, vid, true);
  1456. if (err)
  1457. goto err_fid_evid_map;
  1458. err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port,
  1459. vid);
  1460. if (err)
  1461. goto err_port_vid_list_add;
  1462. return 0;
  1463. err_port_vid_list_add:
  1464. mlxsw_sp_fid_evid_map(fid, local_port, vid, false);
  1465. err_fid_evid_map:
  1466. if (mlxsw_sp->fid_core->port_fid_mappings[local_port])
  1467. __mlxsw_sp_fid_port_vid_map(fid, local_port, vid, false);
  1468. return err;
  1469. }
  1470. static void
  1471. mlxsw_sp_fid_8021q_port_vid_unmap(struct mlxsw_sp_fid *fid,
  1472. struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
  1473. {
  1474. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1475. u16 local_port = mlxsw_sp_port->local_port;
  1476. mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
  1477. mlxsw_sp_fid_evid_map(fid, local_port, vid, false);
  1478. if (mlxsw_sp->fid_core->port_fid_mappings[local_port])
  1479. __mlxsw_sp_fid_port_vid_map(fid, local_port, vid, false);
  1480. }
  1481. static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_ops_ctl = {
  1482. .setup = mlxsw_sp_fid_8021q_setup,
  1483. .configure = mlxsw_sp_fid_8021q_configure,
  1484. .deconfigure = mlxsw_sp_fid_8021q_deconfigure,
  1485. .index_alloc = mlxsw_sp_fid_8021d_index_alloc,
  1486. .compare = mlxsw_sp_fid_8021q_compare,
  1487. .port_vid_map = mlxsw_sp_fid_8021q_port_vid_map,
  1488. .port_vid_unmap = mlxsw_sp_fid_8021q_port_vid_unmap,
  1489. .vni_set = mlxsw_sp_fid_8021d_vni_set,
  1490. .vni_clear = mlxsw_sp_fid_8021d_vni_clear,
  1491. .nve_flood_index_set = mlxsw_sp_fid_8021d_nve_flood_index_set,
  1492. .nve_flood_index_clear = mlxsw_sp_fid_8021d_nve_flood_index_clear,
  1493. .fdb_clear_offload = mlxsw_sp_fid_8021q_fdb_clear_offload,
  1494. .vid_to_fid_rif_update = mlxsw_sp_fid_8021q_vid_to_fid_rif_update,
  1495. .flood_table_init = mlxsw_sp_fid_flood_table_init_ctl,
  1496. .pgt_size = mlxsw_sp_fid_8021d_pgt_size,
  1497. .fid_mid = mlxsw_sp_fid_fid_mid_ctl,
  1498. .fid_pack = mlxsw_sp_fid_pack_ctl,
  1499. };
  1500. static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_ops_cff = {
  1501. .setup = mlxsw_sp_fid_8021q_setup,
  1502. .configure = mlxsw_sp_fid_8021q_configure,
  1503. .deconfigure = mlxsw_sp_fid_8021q_deconfigure,
  1504. .index_alloc = mlxsw_sp_fid_8021d_index_alloc,
  1505. .compare = mlxsw_sp_fid_8021q_compare,
  1506. .port_vid_map = mlxsw_sp_fid_8021q_port_vid_map,
  1507. .port_vid_unmap = mlxsw_sp_fid_8021q_port_vid_unmap,
  1508. .vni_set = mlxsw_sp_fid_8021d_vni_set,
  1509. .vni_clear = mlxsw_sp_fid_8021d_vni_clear,
  1510. .nve_flood_index_set = mlxsw_sp_fid_8021d_nve_flood_index_set,
  1511. .nve_flood_index_clear = mlxsw_sp_fid_8021d_nve_flood_index_clear,
  1512. .fdb_clear_offload = mlxsw_sp_fid_8021q_fdb_clear_offload,
  1513. .vid_to_fid_rif_update = mlxsw_sp_fid_8021q_vid_to_fid_rif_update,
  1514. .pgt_size = mlxsw_sp_fid_8021d_pgt_size,
  1515. .fid_mid = mlxsw_sp_fid_fid_mid_cff,
  1516. .fid_pack = mlxsw_sp_fid_fid_pack_cff,
  1517. };
  1518. /* There are 4K-2 802.1Q FIDs */
  1519. #define MLXSW_SP_FID_8021Q_START 1 /* FID 0 is reserved. */
  1520. #define MLXSW_SP_FID_8021Q_END (MLXSW_SP_FID_8021Q_START + \
  1521. MLXSW_SP_FID_8021Q_MAX - 1)
  1522. /* There are 1K 802.1D FIDs */
  1523. #define MLXSW_SP_FID_8021D_START (MLXSW_SP_FID_8021Q_END + 1)
  1524. #define MLXSW_SP_FID_8021D_END (MLXSW_SP_FID_8021D_START + \
  1525. MLXSW_SP_FID_8021D_MAX - 1)
  1526. /* There is one dummy FID */
  1527. #define MLXSW_SP_FID_DUMMY (MLXSW_SP_FID_8021D_END + 1)
  1528. /* There are 11K rFIDs */
  1529. #define MLXSW_SP_RFID_START (MLXSW_SP_FID_DUMMY + 1)
  1530. #define MLXSW_SP_RFID_END (MLXSW_SP_RFID_START + \
  1531. MLXSW_SP_FID_RFID_MAX - 1)
  1532. static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021q_family = {
  1533. .type = MLXSW_SP_FID_TYPE_8021Q,
  1534. .fid_size = sizeof(struct mlxsw_sp_fid_8021q),
  1535. .start_index = MLXSW_SP_FID_8021Q_START,
  1536. .end_index = MLXSW_SP_FID_8021Q_END,
  1537. .flood_profile = &mlxsw_sp_fid_8021d_flood_profile,
  1538. .rif_type = MLXSW_SP_RIF_TYPE_VLAN,
  1539. .ops = &mlxsw_sp_fid_8021q_ops_ctl,
  1540. .flood_rsp = false,
  1541. .bridge_type = MLXSW_REG_BRIDGE_TYPE_0,
  1542. .smpe_index_valid = false,
  1543. };
  1544. static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_family = {
  1545. .type = MLXSW_SP_FID_TYPE_8021D,
  1546. .fid_size = sizeof(struct mlxsw_sp_fid_8021d),
  1547. .start_index = MLXSW_SP_FID_8021D_START,
  1548. .end_index = MLXSW_SP_FID_8021D_END,
  1549. .flood_profile = &mlxsw_sp_fid_8021d_flood_profile,
  1550. .rif_type = MLXSW_SP_RIF_TYPE_FID,
  1551. .ops = &mlxsw_sp_fid_8021d_ops_ctl,
  1552. .bridge_type = MLXSW_REG_BRIDGE_TYPE_1,
  1553. .smpe_index_valid = false,
  1554. };
  1555. static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_dummy_family = {
  1556. .type = MLXSW_SP_FID_TYPE_DUMMY,
  1557. .fid_size = sizeof(struct mlxsw_sp_fid),
  1558. .start_index = MLXSW_SP_FID_DUMMY,
  1559. .end_index = MLXSW_SP_FID_DUMMY,
  1560. .ops = &mlxsw_sp_fid_dummy_ops,
  1561. .smpe_index_valid = false,
  1562. };
  1563. static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_family_ctl = {
  1564. .type = MLXSW_SP_FID_TYPE_RFID,
  1565. .fid_size = sizeof(struct mlxsw_sp_fid),
  1566. .start_index = MLXSW_SP_RFID_START,
  1567. .end_index = MLXSW_SP_RFID_END,
  1568. .rif_type = MLXSW_SP_RIF_TYPE_SUBPORT,
  1569. .ops = &mlxsw_sp_fid_rfid_ops_ctl,
  1570. .flood_rsp = true,
  1571. .smpe_index_valid = false,
  1572. };
  1573. static const struct mlxsw_sp_fid_family *mlxsw_sp1_fid_family_arr[] = {
  1574. [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp1_fid_8021q_family,
  1575. [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp1_fid_8021d_family,
  1576. [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp1_fid_dummy_family,
  1577. [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family_ctl,
  1578. };
  1579. static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_family_ctl = {
  1580. .type = MLXSW_SP_FID_TYPE_8021Q,
  1581. .fid_size = sizeof(struct mlxsw_sp_fid_8021q),
  1582. .start_index = MLXSW_SP_FID_8021Q_START,
  1583. .end_index = MLXSW_SP_FID_8021Q_END,
  1584. .flood_profile = &mlxsw_sp_fid_8021d_flood_profile,
  1585. .rif_type = MLXSW_SP_RIF_TYPE_VLAN,
  1586. .ops = &mlxsw_sp_fid_8021q_ops_ctl,
  1587. .flood_rsp = false,
  1588. .bridge_type = MLXSW_REG_BRIDGE_TYPE_0,
  1589. .smpe_index_valid = true,
  1590. };
  1591. static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_family_ctl = {
  1592. .type = MLXSW_SP_FID_TYPE_8021D,
  1593. .fid_size = sizeof(struct mlxsw_sp_fid_8021d),
  1594. .start_index = MLXSW_SP_FID_8021D_START,
  1595. .end_index = MLXSW_SP_FID_8021D_END,
  1596. .flood_profile = &mlxsw_sp_fid_8021d_flood_profile,
  1597. .rif_type = MLXSW_SP_RIF_TYPE_FID,
  1598. .ops = &mlxsw_sp_fid_8021d_ops_ctl,
  1599. .bridge_type = MLXSW_REG_BRIDGE_TYPE_1,
  1600. .smpe_index_valid = true,
  1601. };
  1602. static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_dummy_family = {
  1603. .type = MLXSW_SP_FID_TYPE_DUMMY,
  1604. .fid_size = sizeof(struct mlxsw_sp_fid),
  1605. .start_index = MLXSW_SP_FID_DUMMY,
  1606. .end_index = MLXSW_SP_FID_DUMMY,
  1607. .ops = &mlxsw_sp_fid_dummy_ops,
  1608. .smpe_index_valid = false,
  1609. };
  1610. static const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr_ctl[] = {
  1611. [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp2_fid_8021q_family_ctl,
  1612. [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp2_fid_8021d_family_ctl,
  1613. [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp2_fid_dummy_family,
  1614. [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family_ctl,
  1615. };
  1616. static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_family_cff = {
  1617. .type = MLXSW_SP_FID_TYPE_8021Q,
  1618. .fid_size = sizeof(struct mlxsw_sp_fid_8021q),
  1619. .start_index = MLXSW_SP_FID_8021Q_START,
  1620. .end_index = MLXSW_SP_FID_8021Q_END,
  1621. .flood_profile = &mlxsw_sp_fid_8021d_flood_profile,
  1622. .rif_type = MLXSW_SP_RIF_TYPE_VLAN,
  1623. .ops = &mlxsw_sp_fid_8021q_ops_cff,
  1624. .smpe_index_valid = true,
  1625. };
  1626. static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_family_cff = {
  1627. .type = MLXSW_SP_FID_TYPE_8021D,
  1628. .fid_size = sizeof(struct mlxsw_sp_fid_8021d),
  1629. .start_index = MLXSW_SP_FID_8021D_START,
  1630. .end_index = MLXSW_SP_FID_8021D_END,
  1631. .flood_profile = &mlxsw_sp_fid_8021d_flood_profile,
  1632. .rif_type = MLXSW_SP_RIF_TYPE_FID,
  1633. .ops = &mlxsw_sp_fid_8021d_ops_cff,
  1634. .smpe_index_valid = true,
  1635. };
  1636. static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_family_cff = {
  1637. .type = MLXSW_SP_FID_TYPE_RFID,
  1638. .fid_size = sizeof(struct mlxsw_sp_fid),
  1639. .start_index = MLXSW_SP_RFID_START,
  1640. .end_index = MLXSW_SP_RFID_END,
  1641. .flood_profile = &mlxsw_sp_fid_rsp_flood_profile_cff,
  1642. .rif_type = MLXSW_SP_RIF_TYPE_SUBPORT,
  1643. .ops = &mlxsw_sp_fid_rfid_ops_cff,
  1644. .smpe_index_valid = false,
  1645. };
  1646. static const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr_cff[] = {
  1647. [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp2_fid_8021q_family_cff,
  1648. [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp2_fid_8021d_family_cff,
  1649. [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp2_fid_dummy_family,
  1650. [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family_cff,
  1651. };
  1652. static struct mlxsw_sp_fid *mlxsw_sp_fid_lookup(struct mlxsw_sp *mlxsw_sp,
  1653. enum mlxsw_sp_fid_type type,
  1654. const void *arg)
  1655. {
  1656. struct mlxsw_sp_fid_family *fid_family;
  1657. struct mlxsw_sp_fid *fid;
  1658. fid_family = mlxsw_sp->fid_core->fid_family_arr[type];
  1659. list_for_each_entry(fid, &fid_family->fids_list, list) {
  1660. if (!fid->fid_family->ops->compare(fid, arg))
  1661. continue;
  1662. refcount_inc(&fid->ref_count);
  1663. return fid;
  1664. }
  1665. return NULL;
  1666. }
  1667. static struct mlxsw_sp_fid *mlxsw_sp_fid_get(struct mlxsw_sp *mlxsw_sp,
  1668. enum mlxsw_sp_fid_type type,
  1669. const void *arg)
  1670. {
  1671. struct mlxsw_sp_fid_family *fid_family;
  1672. struct mlxsw_sp_fid *fid;
  1673. u16 fid_index;
  1674. int err;
  1675. fid = mlxsw_sp_fid_lookup(mlxsw_sp, type, arg);
  1676. if (fid)
  1677. return fid;
  1678. fid_family = mlxsw_sp->fid_core->fid_family_arr[type];
  1679. fid = kzalloc(fid_family->fid_size, GFP_KERNEL);
  1680. if (!fid)
  1681. return ERR_PTR(-ENOMEM);
  1682. INIT_LIST_HEAD(&fid->port_vid_list);
  1683. fid->fid_family = fid_family;
  1684. err = fid->fid_family->ops->index_alloc(fid, arg, &fid_index);
  1685. if (err)
  1686. goto err_index_alloc;
  1687. fid->fid_index = fid_index;
  1688. __set_bit(fid_index - fid_family->start_index, fid_family->fids_bitmap);
  1689. err = fid->fid_family->ops->setup(fid, arg);
  1690. if (err)
  1691. goto err_setup;
  1692. err = fid->fid_family->ops->configure(fid);
  1693. if (err)
  1694. goto err_configure;
  1695. err = rhashtable_insert_fast(&mlxsw_sp->fid_core->fid_ht, &fid->ht_node,
  1696. mlxsw_sp_fid_ht_params);
  1697. if (err)
  1698. goto err_rhashtable_insert;
  1699. list_add(&fid->list, &fid_family->fids_list);
  1700. refcount_set(&fid->ref_count, 1);
  1701. return fid;
  1702. err_rhashtable_insert:
  1703. fid->fid_family->ops->deconfigure(fid);
  1704. err_configure:
  1705. err_setup:
  1706. __clear_bit(fid_index - fid_family->start_index,
  1707. fid_family->fids_bitmap);
  1708. err_index_alloc:
  1709. kfree(fid);
  1710. return ERR_PTR(err);
  1711. }
  1712. void mlxsw_sp_fid_put(struct mlxsw_sp_fid *fid)
  1713. {
  1714. struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
  1715. struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;
  1716. if (!refcount_dec_and_test(&fid->ref_count))
  1717. return;
  1718. list_del(&fid->list);
  1719. rhashtable_remove_fast(&mlxsw_sp->fid_core->fid_ht,
  1720. &fid->ht_node, mlxsw_sp_fid_ht_params);
  1721. fid->fid_family->ops->deconfigure(fid);
  1722. __clear_bit(fid->fid_index - fid_family->start_index,
  1723. fid_family->fids_bitmap);
  1724. WARN_ON_ONCE(!list_empty(&fid->port_vid_list));
  1725. kfree(fid);
  1726. }
  1727. struct mlxsw_sp_fid *mlxsw_sp_fid_8021q_get(struct mlxsw_sp *mlxsw_sp, u16 vid)
  1728. {
  1729. return mlxsw_sp_fid_get(mlxsw_sp, MLXSW_SP_FID_TYPE_8021Q, &vid);
  1730. }
  1731. struct mlxsw_sp_fid *mlxsw_sp_fid_8021d_get(struct mlxsw_sp *mlxsw_sp,
  1732. int br_ifindex)
  1733. {
  1734. return mlxsw_sp_fid_get(mlxsw_sp, MLXSW_SP_FID_TYPE_8021D, &br_ifindex);
  1735. }
  1736. struct mlxsw_sp_fid *mlxsw_sp_fid_8021q_lookup(struct mlxsw_sp *mlxsw_sp,
  1737. u16 vid)
  1738. {
  1739. return mlxsw_sp_fid_lookup(mlxsw_sp, MLXSW_SP_FID_TYPE_8021Q, &vid);
  1740. }
  1741. struct mlxsw_sp_fid *mlxsw_sp_fid_8021d_lookup(struct mlxsw_sp *mlxsw_sp,
  1742. int br_ifindex)
  1743. {
  1744. return mlxsw_sp_fid_lookup(mlxsw_sp, MLXSW_SP_FID_TYPE_8021D,
  1745. &br_ifindex);
  1746. }
  1747. struct mlxsw_sp_fid *mlxsw_sp_fid_rfid_get(struct mlxsw_sp *mlxsw_sp,
  1748. u16 rif_index)
  1749. {
  1750. return mlxsw_sp_fid_get(mlxsw_sp, MLXSW_SP_FID_TYPE_RFID, &rif_index);
  1751. }
  1752. struct mlxsw_sp_fid *mlxsw_sp_fid_dummy_get(struct mlxsw_sp *mlxsw_sp)
  1753. {
  1754. return mlxsw_sp_fid_get(mlxsw_sp, MLXSW_SP_FID_TYPE_DUMMY, NULL);
  1755. }
  1756. static int
  1757. mlxsw_sp_fid_flood_tables_init(struct mlxsw_sp_fid_family *fid_family)
  1758. {
  1759. struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;
  1760. u16 pgt_size;
  1761. int err;
  1762. int i;
  1763. err = fid_family->ops->pgt_size(fid_family, &pgt_size);
  1764. if (err)
  1765. return err;
  1766. err = mlxsw_sp_pgt_mid_alloc_range(mlxsw_sp, &fid_family->pgt_base,
  1767. pgt_size);
  1768. if (err)
  1769. return err;
  1770. if (!fid_family->flood_profile)
  1771. return 0;
  1772. for (i = 0; i < fid_family->flood_profile->nr_flood_tables; i++) {
  1773. const struct mlxsw_sp_flood_table *flood_table;
  1774. flood_table = &fid_family->flood_profile->flood_tables[i];
  1775. if (fid_family->ops->flood_table_init) {
  1776. err = fid_family->ops->flood_table_init(fid_family,
  1777. flood_table);
  1778. if (err)
  1779. goto err_flood_table_init;
  1780. }
  1781. }
  1782. return 0;
  1783. err_flood_table_init:
  1784. mlxsw_sp_pgt_mid_free_range(mlxsw_sp, fid_family->pgt_base, pgt_size);
  1785. return err;
  1786. }
  1787. static void
  1788. mlxsw_sp_fid_flood_tables_fini(struct mlxsw_sp_fid_family *fid_family)
  1789. {
  1790. struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;
  1791. u16 pgt_size;
  1792. int err;
  1793. err = fid_family->ops->pgt_size(fid_family, &pgt_size);
  1794. if (WARN_ON_ONCE(err))
  1795. return;
  1796. mlxsw_sp_pgt_mid_free_range(mlxsw_sp, fid_family->pgt_base, pgt_size);
  1797. }
  1798. static int mlxsw_sp_fid_family_register(struct mlxsw_sp *mlxsw_sp,
  1799. const struct mlxsw_sp_fid_family *tmpl)
  1800. {
  1801. u16 nr_fids = tmpl->end_index - tmpl->start_index + 1;
  1802. struct mlxsw_sp_fid_family *fid_family;
  1803. int err;
  1804. fid_family = kmemdup(tmpl, sizeof(*fid_family), GFP_KERNEL);
  1805. if (!fid_family)
  1806. return -ENOMEM;
  1807. fid_family->mlxsw_sp = mlxsw_sp;
  1808. INIT_LIST_HEAD(&fid_family->fids_list);
  1809. fid_family->fids_bitmap = bitmap_zalloc(nr_fids, GFP_KERNEL);
  1810. if (!fid_family->fids_bitmap) {
  1811. err = -ENOMEM;
  1812. goto err_alloc_fids_bitmap;
  1813. }
  1814. if (fid_family->flood_profile) {
  1815. err = mlxsw_sp_fid_flood_tables_init(fid_family);
  1816. if (err)
  1817. goto err_fid_flood_tables_init;
  1818. }
  1819. mlxsw_sp->fid_core->fid_family_arr[tmpl->type] = fid_family;
  1820. return 0;
  1821. err_fid_flood_tables_init:
  1822. bitmap_free(fid_family->fids_bitmap);
  1823. err_alloc_fids_bitmap:
  1824. kfree(fid_family);
  1825. return err;
  1826. }
  1827. static void
  1828. mlxsw_sp_fid_family_unregister(struct mlxsw_sp *mlxsw_sp,
  1829. struct mlxsw_sp_fid_family *fid_family)
  1830. {
  1831. mlxsw_sp->fid_core->fid_family_arr[fid_family->type] = NULL;
  1832. if (fid_family->flood_profile)
  1833. mlxsw_sp_fid_flood_tables_fini(fid_family);
  1834. bitmap_free(fid_family->fids_bitmap);
  1835. WARN_ON_ONCE(!list_empty(&fid_family->fids_list));
  1836. kfree(fid_family);
  1837. }
  1838. static int mlxsw_sp_fid_port_init(const struct mlxsw_sp_port *mlxsw_sp_port)
  1839. {
  1840. const enum mlxsw_sp_fid_type type_rfid = MLXSW_SP_FID_TYPE_RFID;
  1841. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1842. struct mlxsw_sp_fid_family *rfid_family;
  1843. rfid_family = mlxsw_sp->fid_core->fid_family_arr[type_rfid];
  1844. if (rfid_family->ops->fid_port_init)
  1845. return rfid_family->ops->fid_port_init(rfid_family,
  1846. mlxsw_sp_port);
  1847. return 0;
  1848. }
  1849. static void mlxsw_sp_fid_port_fini(const struct mlxsw_sp_port *mlxsw_sp_port)
  1850. {
  1851. const enum mlxsw_sp_fid_type type_rfid = MLXSW_SP_FID_TYPE_RFID;
  1852. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1853. struct mlxsw_sp_fid_family *rfid_family;
  1854. rfid_family = mlxsw_sp->fid_core->fid_family_arr[type_rfid];
  1855. if (rfid_family->ops->fid_port_fini)
  1856. rfid_family->ops->fid_port_fini(rfid_family, mlxsw_sp_port);
  1857. }
  1858. int mlxsw_sp_port_fids_init(struct mlxsw_sp_port *mlxsw_sp_port)
  1859. {
  1860. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1861. int err;
  1862. /* Track number of FIDs configured on the port with mapping type
  1863. * PORT_VID_TO_FID, so that we know when to transition the port
  1864. * back to non-virtual (VLAN) mode.
  1865. */
  1866. mlxsw_sp->fid_core->port_fid_mappings[mlxsw_sp_port->local_port] = 0;
  1867. err = mlxsw_sp_fid_port_init(mlxsw_sp_port);
  1868. if (err)
  1869. return err;
  1870. err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
  1871. if (err)
  1872. goto err_vp_mode_set;
  1873. return 0;
  1874. err_vp_mode_set:
  1875. mlxsw_sp_fid_port_fini(mlxsw_sp_port);
  1876. return err;
  1877. }
  1878. void mlxsw_sp_port_fids_fini(struct mlxsw_sp_port *mlxsw_sp_port)
  1879. {
  1880. struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
  1881. mlxsw_sp_fid_port_fini(mlxsw_sp_port);
  1882. mlxsw_sp->fid_core->port_fid_mappings[mlxsw_sp_port->local_port] = 0;
  1883. }
  1884. int mlxsw_sp_fid_port_join_lag(const struct mlxsw_sp_port *mlxsw_sp_port)
  1885. {
  1886. return mlxsw_sp_fid_port_init(mlxsw_sp_port);
  1887. }
  1888. void mlxsw_sp_fid_port_leave_lag(const struct mlxsw_sp_port *mlxsw_sp_port)
  1889. {
  1890. mlxsw_sp_fid_port_fini(mlxsw_sp_port);
  1891. }
  1892. static int
  1893. mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp,
  1894. const struct mlxsw_sp_fid_family *fid_family_arr[])
  1895. {
  1896. unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
  1897. struct mlxsw_sp_fid_core *fid_core;
  1898. int err, i;
  1899. fid_core = kzalloc(sizeof(*mlxsw_sp->fid_core), GFP_KERNEL);
  1900. if (!fid_core)
  1901. return -ENOMEM;
  1902. mlxsw_sp->fid_core = fid_core;
  1903. err = rhashtable_init(&fid_core->fid_ht, &mlxsw_sp_fid_ht_params);
  1904. if (err)
  1905. goto err_rhashtable_fid_init;
  1906. err = rhashtable_init(&fid_core->vni_ht, &mlxsw_sp_fid_vni_ht_params);
  1907. if (err)
  1908. goto err_rhashtable_vni_init;
  1909. fid_core->port_fid_mappings = kcalloc(max_ports, sizeof(unsigned int),
  1910. GFP_KERNEL);
  1911. if (!fid_core->port_fid_mappings) {
  1912. err = -ENOMEM;
  1913. goto err_alloc_port_fid_mappings;
  1914. }
  1915. for (i = 0; i < MLXSW_SP_FID_TYPE_MAX; i++) {
  1916. err = mlxsw_sp_fid_family_register(mlxsw_sp, fid_family_arr[i]);
  1917. if (err)
  1918. goto err_fid_ops_register;
  1919. }
  1920. return 0;
  1921. err_fid_ops_register:
  1922. for (i--; i >= 0; i--) {
  1923. struct mlxsw_sp_fid_family *fid_family;
  1924. fid_family = fid_core->fid_family_arr[i];
  1925. mlxsw_sp_fid_family_unregister(mlxsw_sp, fid_family);
  1926. }
  1927. kfree(fid_core->port_fid_mappings);
  1928. err_alloc_port_fid_mappings:
  1929. rhashtable_destroy(&fid_core->vni_ht);
  1930. err_rhashtable_vni_init:
  1931. rhashtable_destroy(&fid_core->fid_ht);
  1932. err_rhashtable_fid_init:
  1933. kfree(fid_core);
  1934. return err;
  1935. }
  1936. static void mlxsw_sp_fids_fini(struct mlxsw_sp *mlxsw_sp)
  1937. {
  1938. struct mlxsw_sp_fid_core *fid_core = mlxsw_sp->fid_core;
  1939. int i;
  1940. for (i = 0; i < MLXSW_SP_FID_TYPE_MAX; i++)
  1941. mlxsw_sp_fid_family_unregister(mlxsw_sp,
  1942. fid_core->fid_family_arr[i]);
  1943. kfree(fid_core->port_fid_mappings);
  1944. rhashtable_destroy(&fid_core->vni_ht);
  1945. rhashtable_destroy(&fid_core->fid_ht);
  1946. kfree(fid_core);
  1947. }
  1948. static int mlxsw_sp1_fids_init(struct mlxsw_sp *mlxsw_sp)
  1949. {
  1950. return mlxsw_sp_fids_init(mlxsw_sp, mlxsw_sp1_fid_family_arr);
  1951. }
  1952. const struct mlxsw_sp_fid_core_ops mlxsw_sp1_fid_core_ops = {
  1953. .init = mlxsw_sp1_fids_init,
  1954. .fini = mlxsw_sp_fids_fini,
  1955. };
  1956. static int mlxsw_sp_fid_check_flood_profile_id(struct mlxsw_sp *mlxsw_sp,
  1957. int profile_id)
  1958. {
  1959. u32 max_profiles;
  1960. if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_NVE_FLOOD_PRF))
  1961. return -EIO;
  1962. max_profiles = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_NVE_FLOOD_PRF);
  1963. if (WARN_ON_ONCE(!profile_id) ||
  1964. WARN_ON_ONCE(profile_id >= max_profiles))
  1965. return -EINVAL;
  1966. return 0;
  1967. }
  1968. static int
  1969. mlxsw_sp2_fids_init_flood_table(struct mlxsw_sp *mlxsw_sp,
  1970. enum mlxsw_sp_fid_flood_profile_id profile_id,
  1971. const struct mlxsw_sp_flood_table *flood_table)
  1972. {
  1973. enum mlxsw_sp_flood_type packet_type = flood_table->packet_type;
  1974. const int *sfgc_packet_types;
  1975. int err;
  1976. int i;
  1977. sfgc_packet_types = mlxsw_sp_packet_type_sfgc_types[packet_type];
  1978. for (i = 0; i < MLXSW_REG_SFGC_TYPE_MAX; i++) {
  1979. char sffp_pl[MLXSW_REG_SFFP_LEN];
  1980. if (!sfgc_packet_types[i])
  1981. continue;
  1982. mlxsw_reg_sffp_pack(sffp_pl, profile_id, i,
  1983. flood_table->table_index);
  1984. err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sffp), sffp_pl);
  1985. if (err)
  1986. return err;
  1987. }
  1988. return 0;
  1989. }
  1990. static int
  1991. mlxsw_sp2_fids_init_flood_profile(struct mlxsw_sp *mlxsw_sp,
  1992. const struct mlxsw_sp_fid_flood_profile *
  1993. flood_profile)
  1994. {
  1995. int err;
  1996. int i;
  1997. err = mlxsw_sp_fid_check_flood_profile_id(mlxsw_sp,
  1998. flood_profile->profile_id);
  1999. if (err)
  2000. return err;
  2001. for (i = 0; i < flood_profile->nr_flood_tables; i++) {
  2002. const struct mlxsw_sp_flood_table *flood_table;
  2003. flood_table = &flood_profile->flood_tables[i];
  2004. err = mlxsw_sp2_fids_init_flood_table(mlxsw_sp,
  2005. flood_profile->profile_id,
  2006. flood_table);
  2007. if (err)
  2008. return err;
  2009. }
  2010. return 0;
  2011. }
  2012. static const
  2013. struct mlxsw_sp_fid_flood_profile *mlxsw_sp_fid_flood_profiles[] = {
  2014. &mlxsw_sp_fid_8021d_flood_profile,
  2015. &mlxsw_sp_fid_rsp_flood_profile_cff,
  2016. &mlxsw_sp_fid_nve_flood_profile_cff,
  2017. };
  2018. static int
  2019. mlxsw_sp2_fids_init_flood_profiles(struct mlxsw_sp *mlxsw_sp)
  2020. {
  2021. int err;
  2022. int i;
  2023. for (i = 0; i < ARRAY_SIZE(mlxsw_sp_fid_flood_profiles); i++) {
  2024. const struct mlxsw_sp_fid_flood_profile *flood_profile;
  2025. flood_profile = mlxsw_sp_fid_flood_profiles[i];
  2026. err = mlxsw_sp2_fids_init_flood_profile(mlxsw_sp,
  2027. flood_profile);
  2028. if (err)
  2029. return err;
  2030. }
  2031. return 0;
  2032. }
  2033. static int mlxsw_sp2_fids_init_ctl(struct mlxsw_sp *mlxsw_sp)
  2034. {
  2035. return mlxsw_sp_fids_init(mlxsw_sp, mlxsw_sp2_fid_family_arr_ctl);
  2036. }
  2037. static int mlxsw_sp2_fids_init_cff(struct mlxsw_sp *mlxsw_sp)
  2038. {
  2039. int err;
  2040. err = mlxsw_sp2_fids_init_flood_profiles(mlxsw_sp);
  2041. if (err)
  2042. return err;
  2043. return mlxsw_sp_fids_init(mlxsw_sp, mlxsw_sp2_fid_family_arr_cff);
  2044. }
  2045. static int mlxsw_sp2_fids_init(struct mlxsw_sp *mlxsw_sp)
  2046. {
  2047. switch (mlxsw_core_flood_mode(mlxsw_sp->core)) {
  2048. case MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CONTROLLED:
  2049. return mlxsw_sp2_fids_init_ctl(mlxsw_sp);
  2050. case MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CFF:
  2051. return mlxsw_sp2_fids_init_cff(mlxsw_sp);
  2052. default:
  2053. WARN_ON_ONCE(1);
  2054. return -EINVAL;
  2055. }
  2056. }
  2057. const struct mlxsw_sp_fid_core_ops mlxsw_sp2_fid_core_ops = {
  2058. .init = mlxsw_sp2_fids_init,
  2059. .fini = mlxsw_sp_fids_fini,
  2060. };