vsc9953.c 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2014 - 2015 Freescale Semiconductor, Inc.
  4. *
  5. * Driver for the Vitesse VSC9953 L2 Switch
  6. */
  7. #include <asm/io.h>
  8. #include <asm/fsl_serdes.h>
  9. #include <fm_eth.h>
  10. #include <fsl_memac.h>
  11. #include <bitfield.h>
  12. #include <errno.h>
  13. #include <malloc.h>
  14. #include <vsc9953.h>
  15. #include <ethsw.h>
  16. static struct vsc9953_info vsc9953_l2sw = {
  17. .port[0] = VSC9953_PORT_INFO_INITIALIZER(0),
  18. .port[1] = VSC9953_PORT_INFO_INITIALIZER(1),
  19. .port[2] = VSC9953_PORT_INFO_INITIALIZER(2),
  20. .port[3] = VSC9953_PORT_INFO_INITIALIZER(3),
  21. .port[4] = VSC9953_PORT_INFO_INITIALIZER(4),
  22. .port[5] = VSC9953_PORT_INFO_INITIALIZER(5),
  23. .port[6] = VSC9953_PORT_INFO_INITIALIZER(6),
  24. .port[7] = VSC9953_PORT_INFO_INITIALIZER(7),
  25. .port[8] = VSC9953_PORT_INFO_INITIALIZER(8),
  26. .port[9] = VSC9953_PORT_INFO_INITIALIZER(9),
  27. };
  28. void vsc9953_port_info_set_mdio(int port_no, struct mii_dev *bus)
  29. {
  30. if (!VSC9953_PORT_CHECK(port_no))
  31. return;
  32. vsc9953_l2sw.port[port_no].bus = bus;
  33. }
  34. void vsc9953_port_info_set_phy_address(int port_no, int address)
  35. {
  36. if (!VSC9953_PORT_CHECK(port_no))
  37. return;
  38. vsc9953_l2sw.port[port_no].phyaddr = address;
  39. }
  40. void vsc9953_port_info_set_phy_int(int port_no, phy_interface_t phy_int)
  41. {
  42. if (!VSC9953_PORT_CHECK(port_no))
  43. return;
  44. vsc9953_l2sw.port[port_no].enet_if = phy_int;
  45. }
  46. void vsc9953_port_enable(int port_no)
  47. {
  48. if (!VSC9953_PORT_CHECK(port_no))
  49. return;
  50. vsc9953_l2sw.port[port_no].enabled = 1;
  51. }
  52. void vsc9953_port_disable(int port_no)
  53. {
  54. if (!VSC9953_PORT_CHECK(port_no))
  55. return;
  56. vsc9953_l2sw.port[port_no].enabled = 0;
  57. }
  58. static void vsc9953_mdio_write(struct vsc9953_mii_mng *phyregs, int port_addr,
  59. int regnum, int value)
  60. {
  61. int timeout = 50000;
  62. out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) |
  63. ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) |
  64. (0x1 << 1));
  65. asm("sync");
  66. while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout)
  67. udelay(1);
  68. if (timeout == 0)
  69. debug("Timeout waiting for MDIO write\n");
  70. }
  71. static int vsc9953_mdio_read(struct vsc9953_mii_mng *phyregs, int port_addr,
  72. int regnum)
  73. {
  74. int value = 0xFFFF;
  75. int timeout = 50000;
  76. while ((in_le32(&phyregs->miimstatus) & MIIMIND_OPR_PEND) && --timeout)
  77. udelay(1);
  78. if (timeout == 0) {
  79. debug("Timeout waiting for MDIO operation to finish\n");
  80. return value;
  81. }
  82. /* Put the address of the phy, and the register
  83. * number into MIICMD
  84. */
  85. out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) |
  86. ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) |
  87. (0x2 << 1));
  88. timeout = 50000;
  89. /* Wait for the the indication that the read is done */
  90. while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout)
  91. udelay(1);
  92. if (timeout == 0)
  93. debug("Timeout waiting for MDIO read\n");
  94. /* Grab the value read from the PHY */
  95. value = in_le32(&phyregs->miimdata);
  96. if ((value & 0x00030000) == 0)
  97. return value & 0x0000ffff;
  98. return value;
  99. }
  100. static int init_phy(struct eth_device *dev)
  101. {
  102. struct vsc9953_port_info *l2sw_port = dev->priv;
  103. struct phy_device *phydev = NULL;
  104. #ifdef CONFIG_PHYLIB
  105. if (!l2sw_port->bus)
  106. return 0;
  107. phydev = phy_connect(l2sw_port->bus, l2sw_port->phyaddr, dev,
  108. l2sw_port->enet_if);
  109. if (!phydev) {
  110. printf("Failed to connect\n");
  111. return -1;
  112. }
  113. phydev->supported &= SUPPORTED_10baseT_Half |
  114. SUPPORTED_10baseT_Full |
  115. SUPPORTED_100baseT_Half |
  116. SUPPORTED_100baseT_Full |
  117. SUPPORTED_1000baseT_Full;
  118. phydev->advertising = phydev->supported;
  119. l2sw_port->phydev = phydev;
  120. phy_config(phydev);
  121. #endif
  122. return 0;
  123. }
  124. static int vsc9953_port_init(int port_no)
  125. {
  126. struct eth_device *dev;
  127. /* Internal ports never have a PHY */
  128. if (VSC9953_INTERNAL_PORT_CHECK(port_no))
  129. return 0;
  130. /* alloc eth device */
  131. dev = (struct eth_device *)calloc(1, sizeof(struct eth_device));
  132. if (!dev)
  133. return -ENOMEM;
  134. sprintf(dev->name, "SW@PORT%d", port_no);
  135. dev->priv = &vsc9953_l2sw.port[port_no];
  136. dev->init = NULL;
  137. dev->halt = NULL;
  138. dev->send = NULL;
  139. dev->recv = NULL;
  140. if (init_phy(dev)) {
  141. free(dev);
  142. return -ENODEV;
  143. }
  144. return 0;
  145. }
  146. static int vsc9953_vlan_table_poll_idle(void)
  147. {
  148. struct vsc9953_analyzer *l2ana_reg;
  149. int timeout;
  150. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  151. VSC9953_ANA_OFFSET);
  152. timeout = 50000;
  153. while (((in_le32(&l2ana_reg->ana_tables.vlan_access) &
  154. VSC9953_VLAN_CMD_MASK) != VSC9953_VLAN_CMD_IDLE) && --timeout)
  155. udelay(1);
  156. return timeout ? 0 : -EBUSY;
  157. }
  158. #ifdef CONFIG_CMD_ETHSW
  159. /* Add/remove a port to/from a VLAN */
  160. static void vsc9953_vlan_table_membership_set(int vid, u32 port_no, u8 add)
  161. {
  162. u32 val;
  163. struct vsc9953_analyzer *l2ana_reg;
  164. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  165. VSC9953_ANA_OFFSET);
  166. if (vsc9953_vlan_table_poll_idle() < 0) {
  167. debug("VLAN table timeout\n");
  168. return;
  169. }
  170. val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
  171. val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid);
  172. out_le32(&l2ana_reg->ana_tables.vlan_tidx, val);
  173. clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
  174. VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ);
  175. if (vsc9953_vlan_table_poll_idle() < 0) {
  176. debug("VLAN table timeout\n");
  177. return;
  178. }
  179. val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
  180. val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid);
  181. out_le32(&l2ana_reg->ana_tables.vlan_tidx, val);
  182. val = in_le32(&l2ana_reg->ana_tables.vlan_access);
  183. if (!add) {
  184. val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK,
  185. VSC9953_VLAN_CMD_WRITE) &
  186. ~(bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK,
  187. (1 << port_no)));
  188. ;
  189. } else {
  190. val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK,
  191. VSC9953_VLAN_CMD_WRITE) |
  192. bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK,
  193. (1 << port_no));
  194. }
  195. out_le32(&l2ana_reg->ana_tables.vlan_access, val);
  196. /* wait for VLAN table command to flush */
  197. if (vsc9953_vlan_table_poll_idle() < 0) {
  198. debug("VLAN table timeout\n");
  199. return;
  200. }
  201. }
  202. /* show VLAN membership for a port */
  203. static void vsc9953_vlan_membership_show(int port_no)
  204. {
  205. u32 val;
  206. struct vsc9953_analyzer *l2ana_reg;
  207. u32 vid;
  208. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  209. VSC9953_ANA_OFFSET);
  210. printf("Port %d VLAN membership: ", port_no);
  211. for (vid = 0; vid < VSC9953_MAX_VLAN; vid++) {
  212. if (vsc9953_vlan_table_poll_idle() < 0) {
  213. debug("VLAN table timeout\n");
  214. return;
  215. }
  216. val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
  217. val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK,
  218. vid);
  219. out_le32(&l2ana_reg->ana_tables.vlan_tidx, val);
  220. clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
  221. VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ);
  222. if (vsc9953_vlan_table_poll_idle() < 0) {
  223. debug("VLAN table timeout\n");
  224. return;
  225. }
  226. val = in_le32(&l2ana_reg->ana_tables.vlan_access);
  227. if (bitfield_extract_by_mask(val, VSC9953_VLAN_PORT_MASK) &
  228. (1 << port_no))
  229. printf("%d ", vid);
  230. }
  231. printf("\n");
  232. }
  233. #endif
  234. /* vlan table set/clear all membership of vid */
  235. static void vsc9953_vlan_table_membership_all_set(int vid, int set_member)
  236. {
  237. uint val;
  238. struct vsc9953_analyzer *l2ana_reg;
  239. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  240. VSC9953_ANA_OFFSET);
  241. if (vsc9953_vlan_table_poll_idle() < 0) {
  242. debug("VLAN table timeout\n");
  243. return;
  244. }
  245. /* read current vlan configuration */
  246. val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
  247. out_le32(&l2ana_reg->ana_tables.vlan_tidx,
  248. bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid));
  249. clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
  250. VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ);
  251. if (vsc9953_vlan_table_poll_idle() < 0) {
  252. debug("VLAN table timeout\n");
  253. return;
  254. }
  255. val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
  256. out_le32(&l2ana_reg->ana_tables.vlan_tidx,
  257. bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid));
  258. clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
  259. VSC9953_VLAN_PORT_MASK | VSC9953_VLAN_CMD_MASK,
  260. VSC9953_VLAN_CMD_WRITE |
  261. (set_member ? VSC9953_VLAN_PORT_MASK : 0));
  262. }
  263. #ifdef CONFIG_CMD_ETHSW
  264. /* Get PVID of a VSC9953 port */
  265. static int vsc9953_port_vlan_pvid_get(int port_nr, int *pvid)
  266. {
  267. u32 val;
  268. struct vsc9953_analyzer *l2ana_reg;
  269. /* Administrative down */
  270. if (!vsc9953_l2sw.port[port_nr].enabled) {
  271. printf("Port %d is administrative down\n", port_nr);
  272. return -1;
  273. }
  274. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  275. VSC9953_ANA_OFFSET);
  276. /* Get ingress PVID */
  277. val = in_le32(&l2ana_reg->port[port_nr].vlan_cfg);
  278. *pvid = bitfield_extract_by_mask(val, VSC9953_VLAN_CFG_VID_MASK);
  279. return 0;
  280. }
  281. #endif
  282. /* Set PVID for a VSC9953 port */
  283. static void vsc9953_port_vlan_pvid_set(int port_no, int pvid)
  284. {
  285. uint val;
  286. struct vsc9953_analyzer *l2ana_reg;
  287. struct vsc9953_rew_reg *l2rew_reg;
  288. /* Administrative down */
  289. if (!vsc9953_l2sw.port[port_no].enabled) {
  290. printf("Port %d is administrative down\n", port_no);
  291. return;
  292. }
  293. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  294. VSC9953_ANA_OFFSET);
  295. l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
  296. VSC9953_REW_OFFSET);
  297. /* Set PVID on ingress */
  298. val = in_le32(&l2ana_reg->port[port_no].vlan_cfg);
  299. val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_VID_MASK, pvid);
  300. out_le32(&l2ana_reg->port[port_no].vlan_cfg, val);
  301. /* Set PVID on egress */
  302. val = in_le32(&l2rew_reg->port[port_no].port_vlan_cfg);
  303. val = bitfield_replace_by_mask(val, VSC9953_PORT_VLAN_CFG_VID_MASK,
  304. pvid);
  305. out_le32(&l2rew_reg->port[port_no].port_vlan_cfg, val);
  306. }
  307. static void vsc9953_port_all_vlan_pvid_set(int pvid)
  308. {
  309. int i;
  310. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  311. vsc9953_port_vlan_pvid_set(i, pvid);
  312. }
  313. /* Enable/disable vlan aware of a VSC9953 port */
  314. static void vsc9953_port_vlan_aware_set(int port_no, int enabled)
  315. {
  316. struct vsc9953_analyzer *l2ana_reg;
  317. /* Administrative down */
  318. if (!vsc9953_l2sw.port[port_no].enabled) {
  319. printf("Port %d is administrative down\n", port_no);
  320. return;
  321. }
  322. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  323. VSC9953_ANA_OFFSET);
  324. if (enabled)
  325. setbits_le32(&l2ana_reg->port[port_no].vlan_cfg,
  326. VSC9953_VLAN_CFG_AWARE_ENA);
  327. else
  328. clrbits_le32(&l2ana_reg->port[port_no].vlan_cfg,
  329. VSC9953_VLAN_CFG_AWARE_ENA);
  330. }
  331. /* Set all VSC9953 ports' vlan aware */
  332. static void vsc9953_port_all_vlan_aware_set(int enabled)
  333. {
  334. int i;
  335. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  336. vsc9953_port_vlan_aware_set(i, enabled);
  337. }
  338. /* Enable/disable vlan pop count of a VSC9953 port */
  339. static void vsc9953_port_vlan_popcnt_set(int port_no, int popcnt)
  340. {
  341. uint val;
  342. struct vsc9953_analyzer *l2ana_reg;
  343. /* Administrative down */
  344. if (!vsc9953_l2sw.port[port_no].enabled) {
  345. printf("Port %d is administrative down\n", port_no);
  346. return;
  347. }
  348. if (popcnt > 3 || popcnt < 0) {
  349. printf("Invalid pop count value: %d\n", port_no);
  350. return;
  351. }
  352. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  353. VSC9953_ANA_OFFSET);
  354. val = in_le32(&l2ana_reg->port[port_no].vlan_cfg);
  355. val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_POP_CNT_MASK,
  356. popcnt);
  357. out_le32(&l2ana_reg->port[port_no].vlan_cfg, val);
  358. }
  359. /* Set all VSC9953 ports' pop count */
  360. static void vsc9953_port_all_vlan_poncnt_set(int popcnt)
  361. {
  362. int i;
  363. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  364. vsc9953_port_vlan_popcnt_set(i, popcnt);
  365. }
  366. /* Enable/disable learning for frames dropped due to ingress filtering */
  367. static void vsc9953_vlan_ingr_fltr_learn_drop(int enable)
  368. {
  369. struct vsc9953_analyzer *l2ana_reg;
  370. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  371. VSC9953_ANA_OFFSET);
  372. if (enable)
  373. setbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK);
  374. else
  375. clrbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK);
  376. }
  377. enum aggr_code_mode {
  378. AGGR_CODE_RAND = 0,
  379. AGGR_CODE_ALL, /* S/D MAC, IPv4 S/D IP, IPv6 Flow Label, S/D PORT */
  380. };
  381. /* Set aggregation code generation mode */
  382. static int vsc9953_aggr_code_set(enum aggr_code_mode ac)
  383. {
  384. int rc;
  385. struct vsc9953_analyzer *l2ana_reg;
  386. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  387. VSC9953_ANA_OFFSET);
  388. switch (ac) {
  389. case AGGR_CODE_RAND:
  390. clrsetbits_le32(&l2ana_reg->common.aggr_cfg,
  391. VSC9953_AC_DMAC_ENA | VSC9953_AC_SMAC_ENA |
  392. VSC9953_AC_IP6_LBL_ENA |
  393. VSC9953_AC_IP6_TCPUDP_ENA |
  394. VSC9953_AC_IP4_SIPDIP_ENA |
  395. VSC9953_AC_IP4_TCPUDP_ENA, VSC9953_AC_RND_ENA);
  396. rc = 0;
  397. break;
  398. case AGGR_CODE_ALL:
  399. clrsetbits_le32(&l2ana_reg->common.aggr_cfg, VSC9953_AC_RND_ENA,
  400. VSC9953_AC_DMAC_ENA | VSC9953_AC_SMAC_ENA |
  401. VSC9953_AC_IP6_LBL_ENA |
  402. VSC9953_AC_IP6_TCPUDP_ENA |
  403. VSC9953_AC_IP4_SIPDIP_ENA |
  404. VSC9953_AC_IP4_TCPUDP_ENA);
  405. rc = 0;
  406. break;
  407. default:
  408. /* unknown mode for aggregation code */
  409. rc = -EINVAL;
  410. }
  411. return rc;
  412. }
  413. /* Egress untag modes of a VSC9953 port */
  414. enum egress_untag_mode {
  415. EGRESS_UNTAG_ALL = 0,
  416. EGRESS_UNTAG_PVID_AND_ZERO,
  417. EGRESS_UNTAG_ZERO,
  418. EGRESS_UNTAG_NONE,
  419. };
  420. #ifdef CONFIG_CMD_ETHSW
  421. /* Get egress tagging configuration for a VSC9953 port */
  422. static int vsc9953_port_vlan_egr_untag_get(int port_no,
  423. enum egress_untag_mode *mode)
  424. {
  425. u32 val;
  426. struct vsc9953_rew_reg *l2rew_reg;
  427. /* Administrative down */
  428. if (!vsc9953_l2sw.port[port_no].enabled) {
  429. printf("Port %d is administrative down\n", port_no);
  430. return -1;
  431. }
  432. l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
  433. VSC9953_REW_OFFSET);
  434. val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg);
  435. switch (val & VSC9953_TAG_CFG_MASK) {
  436. case VSC9953_TAG_CFG_NONE:
  437. *mode = EGRESS_UNTAG_ALL;
  438. return 0;
  439. case VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO:
  440. *mode = EGRESS_UNTAG_PVID_AND_ZERO;
  441. return 0;
  442. case VSC9953_TAG_CFG_ALL_BUT_ZERO:
  443. *mode = EGRESS_UNTAG_ZERO;
  444. return 0;
  445. case VSC9953_TAG_CFG_ALL:
  446. *mode = EGRESS_UNTAG_NONE;
  447. return 0;
  448. default:
  449. printf("Unknown egress tagging configuration for port %d\n",
  450. port_no);
  451. return -1;
  452. }
  453. }
  454. /* Show egress tagging configuration for a VSC9953 port */
  455. static void vsc9953_port_vlan_egr_untag_show(int port_no)
  456. {
  457. enum egress_untag_mode mode;
  458. if (vsc9953_port_vlan_egr_untag_get(port_no, &mode)) {
  459. printf("%7d\t%17s\n", port_no, "-");
  460. return;
  461. }
  462. printf("%7d\t", port_no);
  463. switch (mode) {
  464. case EGRESS_UNTAG_ALL:
  465. printf("%17s\n", "all");
  466. break;
  467. case EGRESS_UNTAG_NONE:
  468. printf("%17s\n", "none");
  469. break;
  470. case EGRESS_UNTAG_PVID_AND_ZERO:
  471. printf("%17s\n", "PVID and 0");
  472. break;
  473. case EGRESS_UNTAG_ZERO:
  474. printf("%17s\n", "0");
  475. break;
  476. default:
  477. printf("%17s\n", "-");
  478. }
  479. }
  480. #endif
  481. static void vsc9953_port_vlan_egr_untag_set(int port_no,
  482. enum egress_untag_mode mode)
  483. {
  484. struct vsc9953_rew_reg *l2rew_reg;
  485. /* Administrative down */
  486. if (!vsc9953_l2sw.port[port_no].enabled) {
  487. printf("Port %d is administrative down\n", port_no);
  488. return;
  489. }
  490. l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
  491. VSC9953_REW_OFFSET);
  492. switch (mode) {
  493. case EGRESS_UNTAG_ALL:
  494. clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
  495. VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_NONE);
  496. break;
  497. case EGRESS_UNTAG_PVID_AND_ZERO:
  498. clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
  499. VSC9953_TAG_CFG_MASK,
  500. VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO);
  501. break;
  502. case EGRESS_UNTAG_ZERO:
  503. clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
  504. VSC9953_TAG_CFG_MASK,
  505. VSC9953_TAG_CFG_ALL_BUT_ZERO);
  506. break;
  507. case EGRESS_UNTAG_NONE:
  508. clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
  509. VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_ALL);
  510. break;
  511. default:
  512. printf("Unknown untag mode for port %d\n", port_no);
  513. }
  514. }
  515. static void vsc9953_port_all_vlan_egress_untagged_set(
  516. enum egress_untag_mode mode)
  517. {
  518. int i;
  519. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  520. vsc9953_port_vlan_egr_untag_set(i, mode);
  521. }
  522. static int vsc9953_autoage_time_set(int age_period)
  523. {
  524. u32 autoage;
  525. struct vsc9953_analyzer *l2ana_reg;
  526. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  527. VSC9953_ANA_OFFSET);
  528. if (age_period < 0 || age_period > VSC9953_AUTOAGE_PERIOD_MASK)
  529. return -EINVAL;
  530. autoage = bitfield_replace_by_mask(in_le32(&l2ana_reg->ana.auto_age),
  531. VSC9953_AUTOAGE_PERIOD_MASK,
  532. age_period);
  533. out_le32(&l2ana_reg->ana.auto_age, autoage);
  534. return 0;
  535. }
  536. #ifdef CONFIG_CMD_ETHSW
  537. /* Enable/disable status of a VSC9953 port */
  538. static void vsc9953_port_status_set(int port_no, u8 enabled)
  539. {
  540. struct vsc9953_qsys_reg *l2qsys_reg;
  541. /* Administrative down */
  542. if (!vsc9953_l2sw.port[port_no].enabled)
  543. return;
  544. l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET +
  545. VSC9953_QSYS_OFFSET);
  546. if (enabled)
  547. setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no],
  548. VSC9953_PORT_ENA);
  549. else
  550. clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no],
  551. VSC9953_PORT_ENA);
  552. }
  553. /* Start autonegotiation for a VSC9953 PHY */
  554. static void vsc9953_phy_autoneg(int port_no)
  555. {
  556. if (!vsc9953_l2sw.port[port_no].phydev)
  557. return;
  558. if (vsc9953_l2sw.port[port_no].phydev->drv->startup(
  559. vsc9953_l2sw.port[port_no].phydev))
  560. printf("Failed to start PHY for port %d\n", port_no);
  561. }
  562. /* Print a VSC9953 port's configuration */
  563. static void vsc9953_port_config_show(int port_no)
  564. {
  565. int speed;
  566. int duplex;
  567. int link;
  568. u8 enabled;
  569. u32 val;
  570. struct vsc9953_qsys_reg *l2qsys_reg;
  571. l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET +
  572. VSC9953_QSYS_OFFSET);
  573. val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]);
  574. enabled = vsc9953_l2sw.port[port_no].enabled &&
  575. (val & VSC9953_PORT_ENA);
  576. /* internal ports (8 and 9) are fixed */
  577. if (VSC9953_INTERNAL_PORT_CHECK(port_no)) {
  578. link = 1;
  579. speed = SPEED_2500;
  580. duplex = DUPLEX_FULL;
  581. } else {
  582. if (vsc9953_l2sw.port[port_no].phydev) {
  583. link = vsc9953_l2sw.port[port_no].phydev->link;
  584. speed = vsc9953_l2sw.port[port_no].phydev->speed;
  585. duplex = vsc9953_l2sw.port[port_no].phydev->duplex;
  586. } else {
  587. link = -1;
  588. speed = -1;
  589. duplex = -1;
  590. }
  591. }
  592. printf("%8d ", port_no);
  593. printf("%8s ", enabled == 1 ? "enabled" : "disabled");
  594. printf("%8s ", link == 1 ? "up" : "down");
  595. switch (speed) {
  596. case SPEED_10:
  597. printf("%8d ", 10);
  598. break;
  599. case SPEED_100:
  600. printf("%8d ", 100);
  601. break;
  602. case SPEED_1000:
  603. printf("%8d ", 1000);
  604. break;
  605. case SPEED_2500:
  606. printf("%8d ", 2500);
  607. break;
  608. case SPEED_10000:
  609. printf("%8d ", 10000);
  610. break;
  611. default:
  612. printf("%8s ", "-");
  613. }
  614. printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half");
  615. }
  616. /* Show VSC9953 ports' statistics */
  617. static void vsc9953_port_statistics_show(int port_no)
  618. {
  619. u32 rx_val;
  620. u32 tx_val;
  621. struct vsc9953_system_reg *l2sys_reg;
  622. /* Administrative down */
  623. if (!vsc9953_l2sw.port[port_no].enabled) {
  624. printf("Port %d is administrative down\n", port_no);
  625. return;
  626. }
  627. l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET +
  628. VSC9953_SYS_OFFSET);
  629. printf("Statistics for L2 Switch port %d:\n", port_no);
  630. /* Set counter view for our port */
  631. out_le32(&l2sys_reg->sys.stat_cfg, port_no);
  632. #define VSC9953_STATS_PRINTF "%-15s %10u"
  633. /* Get number of Rx and Tx frames */
  634. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short) +
  635. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag) +
  636. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber) +
  637. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long) +
  638. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64) +
  639. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127) +
  640. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255) +
  641. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511) +
  642. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023) +
  643. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526) +
  644. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo);
  645. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) +
  646. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) +
  647. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) +
  648. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) +
  649. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) +
  650. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) +
  651. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo);
  652. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  653. "Rx frames:", rx_val, "Tx frames:", tx_val);
  654. /* Get number of Rx and Tx bytes */
  655. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_oct);
  656. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_oct);
  657. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  658. "Rx bytes:", rx_val, "Tx bytes:", tx_val);
  659. /* Get number of Rx frames received ok and Tx frames sent ok */
  660. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_0) +
  661. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_1) +
  662. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_2) +
  663. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_3) +
  664. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_4) +
  665. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_5) +
  666. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_6) +
  667. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_7) +
  668. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_0) +
  669. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_1) +
  670. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_2) +
  671. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_3) +
  672. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_4) +
  673. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_5) +
  674. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_6) +
  675. in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_7);
  676. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) +
  677. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) +
  678. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) +
  679. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) +
  680. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) +
  681. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) +
  682. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo);
  683. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  684. "Rx frames ok:", rx_val, "Tx frames ok:", tx_val);
  685. /* Get number of Rx and Tx unicast frames */
  686. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_uc);
  687. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_uc);
  688. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  689. "Rx unicast:", rx_val, "Tx unicast:", tx_val);
  690. /* Get number of Rx and Tx broadcast frames */
  691. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_bc);
  692. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_bc);
  693. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  694. "Rx broadcast:", rx_val, "Tx broadcast:", tx_val);
  695. /* Get number of Rx and Tx frames of 64B */
  696. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64);
  697. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64);
  698. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  699. "Rx 64B:", rx_val, "Tx 64B:", tx_val);
  700. /* Get number of Rx and Tx frames with sizes between 65B and 127B */
  701. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127);
  702. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127);
  703. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  704. "Rx 65B-127B:", rx_val, "Tx 65B-127B:", tx_val);
  705. /* Get number of Rx and Tx frames with sizes between 128B and 255B */
  706. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255);
  707. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255);
  708. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  709. "Rx 128B-255B:", rx_val, "Tx 128B-255B:", tx_val);
  710. /* Get number of Rx and Tx frames with sizes between 256B and 511B */
  711. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511);
  712. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511);
  713. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  714. "Rx 256B-511B:", rx_val, "Tx 256B-511B:", tx_val);
  715. /* Get number of Rx and Tx frames with sizes between 512B and 1023B */
  716. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023);
  717. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023);
  718. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  719. "Rx 512B-1023B:", rx_val, "Tx 512B-1023B:", tx_val);
  720. /* Get number of Rx and Tx frames with sizes between 1024B and 1526B */
  721. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526);
  722. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526);
  723. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  724. "Rx 1024B-1526B:", rx_val, "Tx 1024B-1526B:", tx_val);
  725. /* Get number of Rx and Tx jumbo frames */
  726. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo);
  727. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo);
  728. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  729. "Rx jumbo:", rx_val, "Tx jumbo:", tx_val);
  730. /* Get number of Rx and Tx dropped frames */
  731. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) +
  732. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_tail) +
  733. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_0) +
  734. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_1) +
  735. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_2) +
  736. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_3) +
  737. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_4) +
  738. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_5) +
  739. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_6) +
  740. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_7) +
  741. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_0) +
  742. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_1) +
  743. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_2) +
  744. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_3) +
  745. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_4) +
  746. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_5) +
  747. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_6) +
  748. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_7);
  749. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_drop) +
  750. in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged);
  751. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  752. "Rx drops:", rx_val, "Tx drops:", tx_val);
  753. /*
  754. * Get number of Rx frames with CRC or alignment errors
  755. * and number of detected Tx collisions
  756. */
  757. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_crc);
  758. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_col);
  759. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  760. "Rx CRC&align:", rx_val, "Tx coll:", tx_val);
  761. /*
  762. * Get number of Rx undersized frames and
  763. * number of Tx aged frames
  764. */
  765. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short);
  766. tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged);
  767. printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
  768. "Rx undersize:", rx_val, "Tx aged:", tx_val);
  769. /* Get number of Rx oversized frames */
  770. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long);
  771. printf(VSC9953_STATS_PRINTF"\n", "Rx oversized:", rx_val);
  772. /* Get number of Rx fragmented frames */
  773. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag);
  774. printf(VSC9953_STATS_PRINTF"\n", "Rx fragments:", rx_val);
  775. /* Get number of Rx jabber errors */
  776. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber);
  777. printf(VSC9953_STATS_PRINTF"\n", "Rx jabbers:", rx_val);
  778. /*
  779. * Get number of Rx frames filtered due to classification rules or
  780. * no destination ports
  781. */
  782. rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) +
  783. in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_local);
  784. printf(VSC9953_STATS_PRINTF"\n", "Rx filtered:", rx_val);
  785. printf("\n");
  786. }
  787. /* Clear statistics for a VSC9953 port */
  788. static void vsc9953_port_statistics_clear(int port_no)
  789. {
  790. struct vsc9953_system_reg *l2sys_reg;
  791. /* Administrative down */
  792. if (!vsc9953_l2sw.port[port_no].enabled) {
  793. printf("Port %d is administrative down\n", port_no);
  794. return;
  795. }
  796. l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET +
  797. VSC9953_SYS_OFFSET);
  798. /* Clear all counter groups for our ports */
  799. out_le32(&l2sys_reg->sys.stat_cfg, port_no |
  800. VSC9953_STAT_CLEAR_RX | VSC9953_STAT_CLEAR_TX |
  801. VSC9953_STAT_CLEAR_DR);
  802. }
  803. enum port_learn_mode {
  804. PORT_LEARN_NONE,
  805. PORT_LEARN_AUTO
  806. };
  807. /* Set learning configuration for a VSC9953 port */
  808. static void vsc9953_port_learn_mode_set(int port_no, enum port_learn_mode mode)
  809. {
  810. struct vsc9953_analyzer *l2ana_reg;
  811. /* Administrative down */
  812. if (!vsc9953_l2sw.port[port_no].enabled) {
  813. printf("Port %d is administrative down\n", port_no);
  814. return;
  815. }
  816. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  817. VSC9953_ANA_OFFSET);
  818. switch (mode) {
  819. case PORT_LEARN_NONE:
  820. clrbits_le32(&l2ana_reg->port[port_no].port_cfg,
  821. VSC9953_PORT_CFG_LEARN_DROP |
  822. VSC9953_PORT_CFG_LEARN_CPU |
  823. VSC9953_PORT_CFG_LEARN_AUTO |
  824. VSC9953_PORT_CFG_LEARN_ENA);
  825. break;
  826. case PORT_LEARN_AUTO:
  827. clrsetbits_le32(&l2ana_reg->port[port_no].port_cfg,
  828. VSC9953_PORT_CFG_LEARN_DROP |
  829. VSC9953_PORT_CFG_LEARN_CPU,
  830. VSC9953_PORT_CFG_LEARN_ENA |
  831. VSC9953_PORT_CFG_LEARN_AUTO);
  832. break;
  833. default:
  834. printf("Unknown learn mode for port %d\n", port_no);
  835. }
  836. }
  837. /* Get learning configuration for a VSC9953 port */
  838. static int vsc9953_port_learn_mode_get(int port_no, enum port_learn_mode *mode)
  839. {
  840. u32 val;
  841. struct vsc9953_analyzer *l2ana_reg;
  842. /* Administrative down */
  843. if (!vsc9953_l2sw.port[port_no].enabled) {
  844. printf("Port %d is administrative down\n", port_no);
  845. return -1;
  846. }
  847. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  848. VSC9953_ANA_OFFSET);
  849. /* For now we only support HW learning (auto) and no learning */
  850. val = in_le32(&l2ana_reg->port[port_no].port_cfg);
  851. if ((val & (VSC9953_PORT_CFG_LEARN_ENA |
  852. VSC9953_PORT_CFG_LEARN_AUTO)) ==
  853. (VSC9953_PORT_CFG_LEARN_ENA | VSC9953_PORT_CFG_LEARN_AUTO))
  854. *mode = PORT_LEARN_AUTO;
  855. else
  856. *mode = PORT_LEARN_NONE;
  857. return 0;
  858. }
  859. /* wait for FDB to become available */
  860. static int vsc9953_mac_table_poll_idle(void)
  861. {
  862. struct vsc9953_analyzer *l2ana_reg;
  863. u32 timeout;
  864. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  865. VSC9953_ANA_OFFSET);
  866. timeout = 50000;
  867. while (((in_le32(&l2ana_reg->ana_tables.mac_access) &
  868. VSC9953_MAC_CMD_MASK) !=
  869. VSC9953_MAC_CMD_IDLE) && --timeout)
  870. udelay(1);
  871. return timeout ? 0 : -EBUSY;
  872. }
  873. /* enum describing available commands for the MAC table */
  874. enum mac_table_cmd {
  875. MAC_TABLE_READ,
  876. MAC_TABLE_LOOKUP,
  877. MAC_TABLE_WRITE,
  878. MAC_TABLE_LEARN,
  879. MAC_TABLE_FORGET,
  880. MAC_TABLE_GET_NEXT,
  881. MAC_TABLE_AGE,
  882. };
  883. /* Issues a command to the FDB table */
  884. static int vsc9953_mac_table_cmd(enum mac_table_cmd cmd)
  885. {
  886. struct vsc9953_analyzer *l2ana_reg;
  887. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  888. VSC9953_ANA_OFFSET);
  889. switch (cmd) {
  890. case MAC_TABLE_READ:
  891. clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
  892. VSC9953_MAC_CMD_MASK | VSC9953_MAC_CMD_VALID,
  893. VSC9953_MAC_CMD_READ);
  894. break;
  895. case MAC_TABLE_LOOKUP:
  896. clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
  897. VSC9953_MAC_CMD_MASK, VSC9953_MAC_CMD_READ |
  898. VSC9953_MAC_CMD_VALID);
  899. break;
  900. case MAC_TABLE_WRITE:
  901. clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
  902. VSC9953_MAC_CMD_MASK |
  903. VSC9953_MAC_ENTRYTYPE_MASK,
  904. VSC9953_MAC_CMD_WRITE |
  905. VSC9953_MAC_ENTRYTYPE_LOCKED);
  906. break;
  907. case MAC_TABLE_LEARN:
  908. clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
  909. VSC9953_MAC_CMD_MASK |
  910. VSC9953_MAC_ENTRYTYPE_MASK,
  911. VSC9953_MAC_CMD_LEARN |
  912. VSC9953_MAC_ENTRYTYPE_LOCKED |
  913. VSC9953_MAC_CMD_VALID);
  914. break;
  915. case MAC_TABLE_FORGET:
  916. clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
  917. VSC9953_MAC_CMD_MASK |
  918. VSC9953_MAC_ENTRYTYPE_MASK,
  919. VSC9953_MAC_CMD_FORGET);
  920. break;
  921. case MAC_TABLE_GET_NEXT:
  922. clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
  923. VSC9953_MAC_CMD_MASK |
  924. VSC9953_MAC_ENTRYTYPE_MASK,
  925. VSC9953_MAC_CMD_NEXT);
  926. break;
  927. case MAC_TABLE_AGE:
  928. clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
  929. VSC9953_MAC_CMD_MASK |
  930. VSC9953_MAC_ENTRYTYPE_MASK,
  931. VSC9953_MAC_CMD_AGE);
  932. break;
  933. default:
  934. printf("Unknown MAC table command\n");
  935. }
  936. if (vsc9953_mac_table_poll_idle() < 0) {
  937. debug("MAC table timeout\n");
  938. return -1;
  939. }
  940. return 0;
  941. }
  942. /* show the FDB entries that correspond to a port and a VLAN */
  943. static void vsc9953_mac_table_show(int port_no, int vid)
  944. {
  945. int rc[VSC9953_MAX_PORTS];
  946. enum port_learn_mode mode[VSC9953_MAX_PORTS];
  947. int i;
  948. u32 val;
  949. u32 vlan;
  950. u32 mach;
  951. u32 macl;
  952. u32 dest_indx;
  953. struct vsc9953_analyzer *l2ana_reg;
  954. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  955. VSC9953_ANA_OFFSET);
  956. /* disable auto learning */
  957. if (port_no == ETHSW_CMD_PORT_ALL) {
  958. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  959. rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]);
  960. if (!rc[i] && mode[i] != PORT_LEARN_NONE)
  961. vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE);
  962. }
  963. } else {
  964. rc[port_no] = vsc9953_port_learn_mode_get(port_no,
  965. &mode[port_no]);
  966. if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
  967. vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE);
  968. }
  969. /* write port and vid to get selected FDB entries */
  970. val = in_le32(&l2ana_reg->ana.anag_efil);
  971. if (port_no != ETHSW_CMD_PORT_ALL) {
  972. val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK,
  973. port_no) | VSC9953_AGE_PORT_EN;
  974. }
  975. if (vid != ETHSW_CMD_VLAN_ALL) {
  976. val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK,
  977. vid) | VSC9953_AGE_VID_EN;
  978. }
  979. out_le32(&l2ana_reg->ana.anag_efil, val);
  980. /* set MAC and VLAN to 0 to look from beginning */
  981. clrbits_le32(&l2ana_reg->ana_tables.mach_data,
  982. VSC9953_MAC_VID_MASK | VSC9953_MAC_MACH_MASK);
  983. out_le32(&l2ana_reg->ana_tables.macl_data, 0);
  984. /* get entries */
  985. printf("%10s %17s %5s %4s\n", "EntryType", "MAC", "PORT", "VID");
  986. do {
  987. if (vsc9953_mac_table_cmd(MAC_TABLE_GET_NEXT) < 0) {
  988. debug("GET NEXT MAC table command failed\n");
  989. break;
  990. }
  991. val = in_le32(&l2ana_reg->ana_tables.mac_access);
  992. /* get out when an invalid entry is found */
  993. if (!(val & VSC9953_MAC_CMD_VALID))
  994. break;
  995. switch (val & VSC9953_MAC_ENTRYTYPE_MASK) {
  996. case VSC9953_MAC_ENTRYTYPE_NORMAL:
  997. printf("%10s ", "Dynamic");
  998. break;
  999. case VSC9953_MAC_ENTRYTYPE_LOCKED:
  1000. printf("%10s ", "Static");
  1001. break;
  1002. case VSC9953_MAC_ENTRYTYPE_IPV4MCAST:
  1003. printf("%10s ", "IPv4 Mcast");
  1004. break;
  1005. case VSC9953_MAC_ENTRYTYPE_IPV6MCAST:
  1006. printf("%10s ", "IPv6 Mcast");
  1007. break;
  1008. default:
  1009. printf("%10s ", "Unknown");
  1010. }
  1011. dest_indx = bitfield_extract_by_mask(val,
  1012. VSC9953_MAC_DESTIDX_MASK);
  1013. val = in_le32(&l2ana_reg->ana_tables.mach_data);
  1014. vlan = bitfield_extract_by_mask(val, VSC9953_MAC_VID_MASK);
  1015. mach = bitfield_extract_by_mask(val, VSC9953_MAC_MACH_MASK);
  1016. macl = in_le32(&l2ana_reg->ana_tables.macl_data);
  1017. printf("%02x:%02x:%02x:%02x:%02x:%02x ", (mach >> 8) & 0xff,
  1018. mach & 0xff, (macl >> 24) & 0xff, (macl >> 16) & 0xff,
  1019. (macl >> 8) & 0xff, macl & 0xff);
  1020. printf("%5d ", dest_indx);
  1021. printf("%4d\n", vlan);
  1022. } while (1);
  1023. /* set learning mode to previous value */
  1024. if (port_no == ETHSW_CMD_PORT_ALL) {
  1025. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1026. if (!rc[i] && mode[i] != PORT_LEARN_NONE)
  1027. vsc9953_port_learn_mode_set(i, mode[i]);
  1028. }
  1029. } else {
  1030. /* If administrative down, skip */
  1031. if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
  1032. vsc9953_port_learn_mode_set(port_no, mode[port_no]);
  1033. }
  1034. /* reset FDB port and VLAN FDB selection */
  1035. clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN |
  1036. VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN |
  1037. VSC9953_AGE_VID_MASK);
  1038. }
  1039. /* Add a static FDB entry */
  1040. static int vsc9953_mac_table_add(u8 port_no, uchar mac[6], int vid)
  1041. {
  1042. u32 val;
  1043. struct vsc9953_analyzer *l2ana_reg;
  1044. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1045. VSC9953_ANA_OFFSET);
  1046. val = in_le32(&l2ana_reg->ana_tables.mach_data);
  1047. val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
  1048. (mac[0] << 8) | (mac[1] << 0);
  1049. out_le32(&l2ana_reg->ana_tables.mach_data, val);
  1050. out_le32(&l2ana_reg->ana_tables.macl_data,
  1051. (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) |
  1052. (mac[5] << 0));
  1053. /* set on which port is the MAC address added */
  1054. val = in_le32(&l2ana_reg->ana_tables.mac_access);
  1055. val = bitfield_replace_by_mask(val, VSC9953_MAC_DESTIDX_MASK, port_no);
  1056. out_le32(&l2ana_reg->ana_tables.mac_access, val);
  1057. if (vsc9953_mac_table_cmd(MAC_TABLE_LEARN) < 0)
  1058. return -1;
  1059. /* check if the MAC address was indeed added */
  1060. val = in_le32(&l2ana_reg->ana_tables.mach_data);
  1061. val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
  1062. (mac[0] << 8) | (mac[1] << 0);
  1063. out_le32(&l2ana_reg->ana_tables.mach_data, val);
  1064. out_le32(&l2ana_reg->ana_tables.macl_data,
  1065. (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) |
  1066. (mac[5] << 0));
  1067. if (vsc9953_mac_table_cmd(MAC_TABLE_READ) < 0)
  1068. return -1;
  1069. val = in_le32(&l2ana_reg->ana_tables.mac_access);
  1070. if ((port_no != bitfield_extract_by_mask(val,
  1071. VSC9953_MAC_DESTIDX_MASK))) {
  1072. printf("Failed to add MAC address\n");
  1073. return -1;
  1074. }
  1075. return 0;
  1076. }
  1077. /* Delete a FDB entry */
  1078. static int vsc9953_mac_table_del(uchar mac[6], u16 vid)
  1079. {
  1080. u32 val;
  1081. struct vsc9953_analyzer *l2ana_reg;
  1082. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1083. VSC9953_ANA_OFFSET);
  1084. /* check first if MAC entry is present */
  1085. val = in_le32(&l2ana_reg->ana_tables.mach_data);
  1086. val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
  1087. (mac[0] << 8) | (mac[1] << 0);
  1088. out_le32(&l2ana_reg->ana_tables.mach_data, val);
  1089. out_le32(&l2ana_reg->ana_tables.macl_data,
  1090. (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) |
  1091. (mac[5] << 0));
  1092. if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) {
  1093. debug("Lookup in the MAC table failed\n");
  1094. return -1;
  1095. }
  1096. if (!(in_le32(&l2ana_reg->ana_tables.mac_access) &
  1097. VSC9953_MAC_CMD_VALID)) {
  1098. printf("The MAC address: %02x:%02x:%02x:%02x:%02x:%02x ",
  1099. mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  1100. printf("VLAN: %d does not exist.\n", vid);
  1101. return -1;
  1102. }
  1103. /* FDB entry found, proceed to delete */
  1104. val = in_le32(&l2ana_reg->ana_tables.mach_data);
  1105. val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
  1106. (mac[0] << 8) | (mac[1] << 0);
  1107. out_le32(&l2ana_reg->ana_tables.mach_data, val);
  1108. out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) |
  1109. (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0));
  1110. if (vsc9953_mac_table_cmd(MAC_TABLE_FORGET) < 0)
  1111. return -1;
  1112. /* check if the MAC entry is still in FDB */
  1113. val = in_le32(&l2ana_reg->ana_tables.mach_data);
  1114. val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
  1115. (mac[0] << 8) | (mac[1] << 0);
  1116. out_le32(&l2ana_reg->ana_tables.mach_data, val);
  1117. out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) |
  1118. (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0));
  1119. if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) {
  1120. debug("Lookup in the MAC table failed\n");
  1121. return -1;
  1122. }
  1123. if (in_le32(&l2ana_reg->ana_tables.mac_access) &
  1124. VSC9953_MAC_CMD_VALID) {
  1125. printf("Failed to delete MAC address\n");
  1126. return -1;
  1127. }
  1128. return 0;
  1129. }
  1130. /* age the unlocked entries in FDB */
  1131. static void vsc9953_mac_table_age(int port_no, int vid)
  1132. {
  1133. int rc[VSC9953_MAX_PORTS];
  1134. enum port_learn_mode mode[VSC9953_MAX_PORTS];
  1135. u32 val;
  1136. int i;
  1137. struct vsc9953_analyzer *l2ana_reg;
  1138. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1139. VSC9953_ANA_OFFSET);
  1140. /* set port and VID for selective aging */
  1141. val = in_le32(&l2ana_reg->ana.anag_efil);
  1142. if (port_no != ETHSW_CMD_PORT_ALL) {
  1143. /* disable auto learning */
  1144. rc[port_no] = vsc9953_port_learn_mode_get(port_no,
  1145. &mode[port_no]);
  1146. if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
  1147. vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE);
  1148. val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK,
  1149. port_no) | VSC9953_AGE_PORT_EN;
  1150. } else {
  1151. /* disable auto learning on all ports */
  1152. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1153. rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]);
  1154. if (!rc[i] && mode[i] != PORT_LEARN_NONE)
  1155. vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE);
  1156. }
  1157. }
  1158. if (vid != ETHSW_CMD_VLAN_ALL) {
  1159. val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK, vid) |
  1160. VSC9953_AGE_VID_EN;
  1161. }
  1162. out_le32(&l2ana_reg->ana.anag_efil, val);
  1163. /* age the dynamic FDB entries */
  1164. vsc9953_mac_table_cmd(MAC_TABLE_AGE);
  1165. /* clear previously set port and VID */
  1166. clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN |
  1167. VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN |
  1168. VSC9953_AGE_VID_MASK);
  1169. if (port_no != ETHSW_CMD_PORT_ALL) {
  1170. if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
  1171. vsc9953_port_learn_mode_set(port_no, mode[port_no]);
  1172. } else {
  1173. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1174. if (!rc[i] && mode[i] != PORT_LEARN_NONE)
  1175. vsc9953_port_learn_mode_set(i, mode[i]);
  1176. }
  1177. }
  1178. }
  1179. /* Delete all the dynamic FDB entries */
  1180. static void vsc9953_mac_table_flush(int port, int vid)
  1181. {
  1182. vsc9953_mac_table_age(port, vid);
  1183. vsc9953_mac_table_age(port, vid);
  1184. }
  1185. enum egress_vlan_tag {
  1186. EGR_TAG_CLASS = 0,
  1187. EGR_TAG_PVID,
  1188. };
  1189. /* Set egress tag mode for a VSC9953 port */
  1190. static void vsc9953_port_vlan_egress_tag_set(int port_no,
  1191. enum egress_vlan_tag mode)
  1192. {
  1193. struct vsc9953_rew_reg *l2rew_reg;
  1194. l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
  1195. VSC9953_REW_OFFSET);
  1196. switch (mode) {
  1197. case EGR_TAG_CLASS:
  1198. clrbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
  1199. VSC9953_TAG_VID_PVID);
  1200. break;
  1201. case EGR_TAG_PVID:
  1202. setbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
  1203. VSC9953_TAG_VID_PVID);
  1204. break;
  1205. default:
  1206. printf("Unknown egress VLAN tag mode for port %d\n", port_no);
  1207. }
  1208. }
  1209. /* Get egress tag mode for a VSC9953 port */
  1210. static void vsc9953_port_vlan_egress_tag_get(int port_no,
  1211. enum egress_vlan_tag *mode)
  1212. {
  1213. u32 val;
  1214. struct vsc9953_rew_reg *l2rew_reg;
  1215. l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
  1216. VSC9953_REW_OFFSET);
  1217. val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg);
  1218. if (val & VSC9953_TAG_VID_PVID)
  1219. *mode = EGR_TAG_PVID;
  1220. else
  1221. *mode = EGR_TAG_CLASS;
  1222. }
  1223. /* VSC9953 VLAN learning modes */
  1224. enum vlan_learning_mode {
  1225. SHARED_VLAN_LEARNING,
  1226. PRIVATE_VLAN_LEARNING,
  1227. };
  1228. /* Set VLAN learning mode for VSC9953 */
  1229. static void vsc9953_vlan_learning_set(enum vlan_learning_mode lrn_mode)
  1230. {
  1231. struct vsc9953_analyzer *l2ana_reg;
  1232. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1233. VSC9953_ANA_OFFSET);
  1234. switch (lrn_mode) {
  1235. case SHARED_VLAN_LEARNING:
  1236. setbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL);
  1237. break;
  1238. case PRIVATE_VLAN_LEARNING:
  1239. clrbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL);
  1240. break;
  1241. default:
  1242. printf("Unknown VLAN learn mode\n");
  1243. }
  1244. }
  1245. /* Get VLAN learning mode for VSC9953 */
  1246. static int vsc9953_vlan_learning_get(enum vlan_learning_mode *lrn_mode)
  1247. {
  1248. u32 val;
  1249. struct vsc9953_analyzer *l2ana_reg;
  1250. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1251. VSC9953_ANA_OFFSET);
  1252. val = in_le32(&l2ana_reg->ana.agen_ctrl);
  1253. if (!(val & VSC9953_FID_MASK_ALL)) {
  1254. *lrn_mode = PRIVATE_VLAN_LEARNING;
  1255. } else if ((val & VSC9953_FID_MASK_ALL) == VSC9953_FID_MASK_ALL) {
  1256. *lrn_mode = SHARED_VLAN_LEARNING;
  1257. } else {
  1258. printf("Unknown VLAN learning mode\n");
  1259. return -EINVAL;
  1260. }
  1261. return 0;
  1262. }
  1263. /* Enable/disable VLAN ingress filtering on a VSC9953 port */
  1264. static void vsc9953_port_ingress_filtering_set(int port_no, int enabled)
  1265. {
  1266. struct vsc9953_analyzer *l2ana_reg;
  1267. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1268. VSC9953_ANA_OFFSET);
  1269. if (enabled)
  1270. setbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no);
  1271. else
  1272. clrbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no);
  1273. }
  1274. /* Return VLAN ingress filtering on a VSC9953 port */
  1275. static int vsc9953_port_ingress_filtering_get(int port_no)
  1276. {
  1277. u32 val;
  1278. struct vsc9953_analyzer *l2ana_reg;
  1279. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1280. VSC9953_ANA_OFFSET);
  1281. val = in_le32(&l2ana_reg->ana.vlan_mask);
  1282. return !!(val & (1 << port_no));
  1283. }
  1284. /* Get the aggregation group of a port */
  1285. static int vsc9953_port_aggr_grp_get(int port_no, int *aggr_grp)
  1286. {
  1287. u32 val;
  1288. struct vsc9953_analyzer *l2ana_reg;
  1289. if (!VSC9953_PORT_CHECK(port_no))
  1290. return -EINVAL;
  1291. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1292. VSC9953_ANA_OFFSET);
  1293. val = in_le32(&l2ana_reg->port[port_no].port_cfg);
  1294. *aggr_grp = bitfield_extract_by_mask(val,
  1295. VSC9953_PORT_CFG_PORTID_MASK);
  1296. return 0;
  1297. }
  1298. static void vsc9953_aggr_grp_members_get(int aggr_grp,
  1299. u8 aggr_membr[VSC9953_MAX_PORTS])
  1300. {
  1301. int port_no;
  1302. int aggr_membr_grp;
  1303. for (port_no = 0; port_no < VSC9953_MAX_PORTS; port_no++) {
  1304. aggr_membr[port_no] = 0;
  1305. if (vsc9953_port_aggr_grp_get(port_no, &aggr_membr_grp))
  1306. continue;
  1307. if (aggr_grp == aggr_membr_grp)
  1308. aggr_membr[port_no] = 1;
  1309. }
  1310. }
  1311. static void vsc9953_update_dest_members_masks(int port_no, u32 membr_bitfld_old,
  1312. u32 membr_bitfld_new)
  1313. {
  1314. int i;
  1315. u32 pgid;
  1316. struct vsc9953_analyzer *l2ana_reg;
  1317. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1318. VSC9953_ANA_OFFSET);
  1319. /*
  1320. * NOTE: Only the unicast destination masks are updated, since
  1321. * we do not support for now Layer-2 multicast entries
  1322. */
  1323. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1324. if (i == port_no) {
  1325. clrsetbits_le32(&l2ana_reg->port_id_tbl.port_grp_id[i],
  1326. VSC9953_PGID_PORT_MASK,
  1327. membr_bitfld_new);
  1328. continue;
  1329. }
  1330. pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[i]);
  1331. if ((u32)(1 << i) & membr_bitfld_old & VSC9953_PGID_PORT_MASK)
  1332. pgid &= ~((u32)(1 << port_no));
  1333. if ((u32)(1 << i) & membr_bitfld_new & VSC9953_PGID_PORT_MASK)
  1334. pgid |= ((u32)(1 << port_no));
  1335. out_le32(&l2ana_reg->port_id_tbl.port_grp_id[i], pgid);
  1336. }
  1337. }
  1338. static void vsc9953_update_source_members_masks(int port_no,
  1339. u32 membr_bitfld_old,
  1340. u32 membr_bitfld_new)
  1341. {
  1342. int i;
  1343. int index;
  1344. u32 pgid;
  1345. struct vsc9953_analyzer *l2ana_reg;
  1346. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1347. VSC9953_ANA_OFFSET);
  1348. for (i = 0; i < VSC9953_MAX_PORTS + 1; i++) {
  1349. index = PGID_SRC_START + i;
  1350. pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[index]);
  1351. if (i == port_no) {
  1352. pgid = (pgid | VSC9953_PGID_PORT_MASK) &
  1353. ~membr_bitfld_new;
  1354. out_le32(&l2ana_reg->port_id_tbl.port_grp_id[index],
  1355. pgid);
  1356. continue;
  1357. }
  1358. if ((u32)(1 << i) & membr_bitfld_old & VSC9953_PGID_PORT_MASK)
  1359. pgid |= (u32)(1 << port_no);
  1360. if ((u32)(1 << i) & membr_bitfld_new & VSC9953_PGID_PORT_MASK)
  1361. pgid &= ~(u32)(1 << port_no);
  1362. out_le32(&l2ana_reg->port_id_tbl.port_grp_id[index], pgid);
  1363. }
  1364. }
  1365. static u32 vsc9953_aggr_mask_get_next(u32 aggr_mask, u32 member_bitfield)
  1366. {
  1367. if (!member_bitfield)
  1368. return 0;
  1369. if (!(aggr_mask & VSC9953_PGID_PORT_MASK))
  1370. aggr_mask = 1;
  1371. else
  1372. aggr_mask <<= 1;
  1373. while (!(aggr_mask & member_bitfield)) {
  1374. aggr_mask <<= 1;
  1375. if (!(aggr_mask & VSC9953_PGID_PORT_MASK))
  1376. aggr_mask = 1;
  1377. }
  1378. return aggr_mask;
  1379. }
  1380. static void vsc9953_update_aggr_members_masks(int port_no, u32 membr_bitfld_old,
  1381. u32 membr_bitfld_new)
  1382. {
  1383. int i;
  1384. u32 pgid;
  1385. u32 aggr_mask_old = 0;
  1386. u32 aggr_mask_new = 0;
  1387. struct vsc9953_analyzer *l2ana_reg;
  1388. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1389. VSC9953_ANA_OFFSET);
  1390. /* Update all the PGID aggregation masks */
  1391. for (i = PGID_AGGR_START; i < PGID_SRC_START; i++) {
  1392. pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[i]);
  1393. aggr_mask_old = vsc9953_aggr_mask_get_next(aggr_mask_old,
  1394. membr_bitfld_old);
  1395. pgid = (pgid & ~membr_bitfld_old) | aggr_mask_old;
  1396. aggr_mask_new = vsc9953_aggr_mask_get_next(aggr_mask_new,
  1397. membr_bitfld_new);
  1398. pgid = (pgid & ~membr_bitfld_new) | aggr_mask_new;
  1399. out_le32(&l2ana_reg->port_id_tbl.port_grp_id[i], pgid);
  1400. }
  1401. }
  1402. static u32 vsc9953_aggr_membr_bitfield_get(u8 member[VSC9953_MAX_PORTS])
  1403. {
  1404. int i;
  1405. u32 member_bitfield = 0;
  1406. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1407. if (member[i])
  1408. member_bitfield |= 1 << i;
  1409. }
  1410. member_bitfield &= VSC9953_PGID_PORT_MASK;
  1411. return member_bitfield;
  1412. }
  1413. static void vsc9953_update_members_masks(int port_no,
  1414. u8 member_old[VSC9953_MAX_PORTS],
  1415. u8 member_new[VSC9953_MAX_PORTS])
  1416. {
  1417. u32 membr_bitfld_old = vsc9953_aggr_membr_bitfield_get(member_old);
  1418. u32 membr_bitfld_new = vsc9953_aggr_membr_bitfield_get(member_new);
  1419. vsc9953_update_dest_members_masks(port_no, membr_bitfld_old,
  1420. membr_bitfld_new);
  1421. vsc9953_update_source_members_masks(port_no, membr_bitfld_old,
  1422. membr_bitfld_new);
  1423. vsc9953_update_aggr_members_masks(port_no, membr_bitfld_old,
  1424. membr_bitfld_new);
  1425. }
  1426. /* Set the aggregation group of a port */
  1427. static int vsc9953_port_aggr_grp_set(int port_no, int aggr_grp)
  1428. {
  1429. u8 aggr_membr_old[VSC9953_MAX_PORTS];
  1430. u8 aggr_membr_new[VSC9953_MAX_PORTS];
  1431. int rc;
  1432. int aggr_grp_old;
  1433. u32 val;
  1434. struct vsc9953_analyzer *l2ana_reg;
  1435. if (!VSC9953_PORT_CHECK(port_no) || !VSC9953_PORT_CHECK(aggr_grp))
  1436. return -EINVAL;
  1437. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  1438. VSC9953_ANA_OFFSET);
  1439. rc = vsc9953_port_aggr_grp_get(port_no, &aggr_grp_old);
  1440. if (rc)
  1441. return rc;
  1442. /* get all the members of the old aggregation group */
  1443. vsc9953_aggr_grp_members_get(aggr_grp_old, aggr_membr_old);
  1444. /* get all the members of the same aggregation group */
  1445. vsc9953_aggr_grp_members_get(aggr_grp, aggr_membr_new);
  1446. /* add current port as member to the new aggregation group */
  1447. aggr_membr_old[port_no] = 0;
  1448. aggr_membr_new[port_no] = 1;
  1449. /* update masks */
  1450. vsc9953_update_members_masks(port_no, aggr_membr_old, aggr_membr_new);
  1451. /* Change logical port number */
  1452. val = in_le32(&l2ana_reg->port[port_no].port_cfg);
  1453. val = bitfield_replace_by_mask(val,
  1454. VSC9953_PORT_CFG_PORTID_MASK, aggr_grp);
  1455. out_le32(&l2ana_reg->port[port_no].port_cfg, val);
  1456. return 0;
  1457. }
  1458. static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd)
  1459. {
  1460. int i;
  1461. u8 enabled;
  1462. /* Last keyword should tell us if we should enable/disable the port */
  1463. if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1464. ethsw_id_enable)
  1465. enabled = 1;
  1466. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1467. ethsw_id_disable)
  1468. enabled = 0;
  1469. else
  1470. return CMD_RET_USAGE;
  1471. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1472. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1473. printf("Invalid port number: %d\n", parsed_cmd->port);
  1474. return CMD_RET_FAILURE;
  1475. }
  1476. vsc9953_port_status_set(parsed_cmd->port, enabled);
  1477. } else {
  1478. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1479. vsc9953_port_status_set(i, enabled);
  1480. }
  1481. return CMD_RET_SUCCESS;
  1482. }
  1483. static int vsc9953_port_config_key_func(struct ethsw_command_def *parsed_cmd)
  1484. {
  1485. int i;
  1486. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1487. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1488. printf("Invalid port number: %d\n", parsed_cmd->port);
  1489. return CMD_RET_FAILURE;
  1490. }
  1491. vsc9953_phy_autoneg(parsed_cmd->port);
  1492. printf("%8s %8s %8s %8s %8s\n",
  1493. "Port", "Status", "Link", "Speed",
  1494. "Duplex");
  1495. vsc9953_port_config_show(parsed_cmd->port);
  1496. } else {
  1497. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1498. vsc9953_phy_autoneg(i);
  1499. printf("%8s %8s %8s %8s %8s\n",
  1500. "Port", "Status", "Link", "Speed", "Duplex");
  1501. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1502. vsc9953_port_config_show(i);
  1503. }
  1504. return CMD_RET_SUCCESS;
  1505. }
  1506. static int vsc9953_port_stats_key_func(struct ethsw_command_def *parsed_cmd)
  1507. {
  1508. int i;
  1509. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1510. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1511. printf("Invalid port number: %d\n", parsed_cmd->port);
  1512. return CMD_RET_FAILURE;
  1513. }
  1514. vsc9953_port_statistics_show(parsed_cmd->port);
  1515. } else {
  1516. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1517. vsc9953_port_statistics_show(i);
  1518. }
  1519. return CMD_RET_SUCCESS;
  1520. }
  1521. static int vsc9953_port_stats_clear_key_func(struct ethsw_command_def
  1522. *parsed_cmd)
  1523. {
  1524. int i;
  1525. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1526. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1527. printf("Invalid port number: %d\n", parsed_cmd->port);
  1528. return CMD_RET_FAILURE;
  1529. }
  1530. vsc9953_port_statistics_clear(parsed_cmd->port);
  1531. } else {
  1532. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1533. vsc9953_port_statistics_clear(i);
  1534. }
  1535. return CMD_RET_SUCCESS;
  1536. }
  1537. static int vsc9953_learn_show_key_func(struct ethsw_command_def *parsed_cmd)
  1538. {
  1539. int i;
  1540. enum port_learn_mode mode;
  1541. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1542. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1543. printf("Invalid port number: %d\n", parsed_cmd->port);
  1544. return CMD_RET_FAILURE;
  1545. }
  1546. if (vsc9953_port_learn_mode_get(parsed_cmd->port, &mode))
  1547. return CMD_RET_FAILURE;
  1548. printf("%7s %11s\n", "Port", "Learn mode");
  1549. switch (mode) {
  1550. case PORT_LEARN_NONE:
  1551. printf("%7d %11s\n", parsed_cmd->port, "disable");
  1552. break;
  1553. case PORT_LEARN_AUTO:
  1554. printf("%7d %11s\n", parsed_cmd->port, "auto");
  1555. break;
  1556. default:
  1557. printf("%7d %11s\n", parsed_cmd->port, "-");
  1558. }
  1559. } else {
  1560. printf("%7s %11s\n", "Port", "Learn mode");
  1561. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1562. if (vsc9953_port_learn_mode_get(i, &mode))
  1563. continue;
  1564. switch (mode) {
  1565. case PORT_LEARN_NONE:
  1566. printf("%7d %11s\n", i, "disable");
  1567. break;
  1568. case PORT_LEARN_AUTO:
  1569. printf("%7d %11s\n", i, "auto");
  1570. break;
  1571. default:
  1572. printf("%7d %11s\n", i, "-");
  1573. }
  1574. }
  1575. }
  1576. return CMD_RET_SUCCESS;
  1577. }
  1578. static int vsc9953_learn_set_key_func(struct ethsw_command_def *parsed_cmd)
  1579. {
  1580. int i;
  1581. enum port_learn_mode mode;
  1582. /* Last keyword should tell us the learn mode */
  1583. if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1584. ethsw_id_auto)
  1585. mode = PORT_LEARN_AUTO;
  1586. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1587. ethsw_id_disable)
  1588. mode = PORT_LEARN_NONE;
  1589. else
  1590. return CMD_RET_USAGE;
  1591. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1592. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1593. printf("Invalid port number: %d\n", parsed_cmd->port);
  1594. return CMD_RET_FAILURE;
  1595. }
  1596. vsc9953_port_learn_mode_set(parsed_cmd->port, mode);
  1597. } else {
  1598. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1599. vsc9953_port_learn_mode_set(i, mode);
  1600. }
  1601. return CMD_RET_SUCCESS;
  1602. }
  1603. static int vsc9953_fdb_show_key_func(struct ethsw_command_def *parsed_cmd)
  1604. {
  1605. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL &&
  1606. !VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1607. printf("Invalid port number: %d\n", parsed_cmd->port);
  1608. return CMD_RET_FAILURE;
  1609. }
  1610. if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL &&
  1611. !VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
  1612. printf("Invalid VID number: %d\n", parsed_cmd->vid);
  1613. return CMD_RET_FAILURE;
  1614. }
  1615. vsc9953_mac_table_show(parsed_cmd->port, parsed_cmd->vid);
  1616. return CMD_RET_SUCCESS;
  1617. }
  1618. static int vsc9953_fdb_flush_key_func(struct ethsw_command_def *parsed_cmd)
  1619. {
  1620. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL &&
  1621. !VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1622. printf("Invalid port number: %d\n", parsed_cmd->port);
  1623. return CMD_RET_FAILURE;
  1624. }
  1625. if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL &&
  1626. !VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
  1627. printf("Invalid VID number: %d\n", parsed_cmd->vid);
  1628. return CMD_RET_FAILURE;
  1629. }
  1630. vsc9953_mac_table_flush(parsed_cmd->port, parsed_cmd->vid);
  1631. return CMD_RET_SUCCESS;
  1632. }
  1633. static int vsc9953_fdb_entry_add_key_func(struct ethsw_command_def *parsed_cmd)
  1634. {
  1635. int vid;
  1636. /* a port number must be present */
  1637. if (parsed_cmd->port == ETHSW_CMD_PORT_ALL) {
  1638. printf("Please specify a port\n");
  1639. return CMD_RET_FAILURE;
  1640. }
  1641. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1642. printf("Invalid port number: %d\n", parsed_cmd->port);
  1643. return CMD_RET_FAILURE;
  1644. }
  1645. /* Use VLAN 1 if VID is not set */
  1646. vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid);
  1647. if (!VSC9953_VLAN_CHECK(vid)) {
  1648. printf("Invalid VID number: %d\n", vid);
  1649. return CMD_RET_FAILURE;
  1650. }
  1651. if (vsc9953_mac_table_add(parsed_cmd->port, parsed_cmd->ethaddr, vid))
  1652. return CMD_RET_FAILURE;
  1653. return CMD_RET_SUCCESS;
  1654. }
  1655. static int vsc9953_fdb_entry_del_key_func(struct ethsw_command_def *parsed_cmd)
  1656. {
  1657. int vid;
  1658. /* Use VLAN 1 if VID is not set */
  1659. vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid);
  1660. if (!VSC9953_VLAN_CHECK(vid)) {
  1661. printf("Invalid VID number: %d\n", vid);
  1662. return CMD_RET_FAILURE;
  1663. }
  1664. if (vsc9953_mac_table_del(parsed_cmd->ethaddr, vid))
  1665. return CMD_RET_FAILURE;
  1666. return CMD_RET_SUCCESS;
  1667. }
  1668. static int vsc9953_pvid_show_key_func(struct ethsw_command_def *parsed_cmd)
  1669. {
  1670. int i;
  1671. int pvid;
  1672. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1673. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1674. printf("Invalid port number: %d\n", parsed_cmd->port);
  1675. return CMD_RET_FAILURE;
  1676. }
  1677. if (vsc9953_port_vlan_pvid_get(parsed_cmd->port, &pvid))
  1678. return CMD_RET_FAILURE;
  1679. printf("%7s %7s\n", "Port", "PVID");
  1680. printf("%7d %7d\n", parsed_cmd->port, pvid);
  1681. } else {
  1682. printf("%7s %7s\n", "Port", "PVID");
  1683. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1684. if (vsc9953_port_vlan_pvid_get(i, &pvid))
  1685. continue;
  1686. printf("%7d %7d\n", i, pvid);
  1687. }
  1688. }
  1689. return CMD_RET_SUCCESS;
  1690. }
  1691. static int vsc9953_pvid_set_key_func(struct ethsw_command_def *parsed_cmd)
  1692. {
  1693. /* PVID number should be set in parsed_cmd->vid */
  1694. if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) {
  1695. printf("Please set a pvid value\n");
  1696. return CMD_RET_FAILURE;
  1697. }
  1698. if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
  1699. printf("Invalid VID number: %d\n", parsed_cmd->vid);
  1700. return CMD_RET_FAILURE;
  1701. }
  1702. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1703. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1704. printf("Invalid port number: %d\n", parsed_cmd->port);
  1705. return CMD_RET_FAILURE;
  1706. }
  1707. vsc9953_port_vlan_pvid_set(parsed_cmd->port, parsed_cmd->vid);
  1708. } else {
  1709. vsc9953_port_all_vlan_pvid_set(parsed_cmd->vid);
  1710. }
  1711. return CMD_RET_SUCCESS;
  1712. }
  1713. static int vsc9953_vlan_show_key_func(struct ethsw_command_def *parsed_cmd)
  1714. {
  1715. int i;
  1716. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1717. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1718. printf("Invalid port number: %d\n", parsed_cmd->port);
  1719. return CMD_RET_FAILURE;
  1720. }
  1721. vsc9953_vlan_membership_show(parsed_cmd->port);
  1722. } else {
  1723. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1724. vsc9953_vlan_membership_show(i);
  1725. }
  1726. return CMD_RET_SUCCESS;
  1727. }
  1728. static int vsc9953_vlan_set_key_func(struct ethsw_command_def *parsed_cmd)
  1729. {
  1730. int i;
  1731. int add;
  1732. /* VLAN should be set in parsed_cmd->vid */
  1733. if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) {
  1734. printf("Please set a vlan value\n");
  1735. return CMD_RET_FAILURE;
  1736. }
  1737. if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
  1738. printf("Invalid VID number: %d\n", parsed_cmd->vid);
  1739. return CMD_RET_FAILURE;
  1740. }
  1741. /* keywords add/delete should be the last but one in array */
  1742. if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] ==
  1743. ethsw_id_add)
  1744. add = 1;
  1745. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] ==
  1746. ethsw_id_del)
  1747. add = 0;
  1748. else
  1749. return CMD_RET_USAGE;
  1750. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1751. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1752. printf("Invalid port number: %d\n", parsed_cmd->port);
  1753. return CMD_RET_FAILURE;
  1754. }
  1755. vsc9953_vlan_table_membership_set(parsed_cmd->vid,
  1756. parsed_cmd->port, add);
  1757. } else {
  1758. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1759. vsc9953_vlan_table_membership_set(parsed_cmd->vid, i,
  1760. add);
  1761. }
  1762. return CMD_RET_SUCCESS;
  1763. }
  1764. static int vsc9953_port_untag_show_key_func(
  1765. struct ethsw_command_def *parsed_cmd)
  1766. {
  1767. int i;
  1768. printf("%7s\t%17s\n", "Port", "Untag");
  1769. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1770. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1771. printf("Invalid port number: %d\n", parsed_cmd->port);
  1772. return CMD_RET_FAILURE;
  1773. }
  1774. vsc9953_port_vlan_egr_untag_show(parsed_cmd->port);
  1775. } else {
  1776. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1777. vsc9953_port_vlan_egr_untag_show(i);
  1778. }
  1779. return CMD_RET_SUCCESS;
  1780. }
  1781. static int vsc9953_port_untag_set_key_func(struct ethsw_command_def *parsed_cmd)
  1782. {
  1783. int i;
  1784. enum egress_untag_mode mode;
  1785. /* keywords for the untagged mode are the last in the array */
  1786. if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1787. ethsw_id_all)
  1788. mode = EGRESS_UNTAG_ALL;
  1789. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1790. ethsw_id_none)
  1791. mode = EGRESS_UNTAG_NONE;
  1792. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1793. ethsw_id_pvid)
  1794. mode = EGRESS_UNTAG_PVID_AND_ZERO;
  1795. else
  1796. return CMD_RET_USAGE;
  1797. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1798. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1799. printf("Invalid port number: %d\n", parsed_cmd->port);
  1800. return CMD_RET_FAILURE;
  1801. }
  1802. vsc9953_port_vlan_egr_untag_set(parsed_cmd->port, mode);
  1803. } else {
  1804. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1805. vsc9953_port_vlan_egr_untag_set(i, mode);
  1806. }
  1807. return CMD_RET_SUCCESS;
  1808. }
  1809. static int vsc9953_egr_vlan_tag_show_key_func(
  1810. struct ethsw_command_def *parsed_cmd)
  1811. {
  1812. int i;
  1813. enum egress_vlan_tag mode;
  1814. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1815. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1816. printf("Invalid port number: %d\n", parsed_cmd->port);
  1817. return CMD_RET_FAILURE;
  1818. }
  1819. vsc9953_port_vlan_egress_tag_get(parsed_cmd->port, &mode);
  1820. printf("%7s\t%12s\n", "Port", "Egress VID");
  1821. printf("%7d\t", parsed_cmd->port);
  1822. switch (mode) {
  1823. case EGR_TAG_CLASS:
  1824. printf("%12s\n", "classified");
  1825. break;
  1826. case EGR_TAG_PVID:
  1827. printf("%12s\n", "pvid");
  1828. break;
  1829. default:
  1830. printf("%12s\n", "-");
  1831. }
  1832. } else {
  1833. printf("%7s\t%12s\n", "Port", "Egress VID");
  1834. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1835. vsc9953_port_vlan_egress_tag_get(i, &mode);
  1836. switch (mode) {
  1837. case EGR_TAG_CLASS:
  1838. printf("%7d\t%12s\n", i, "classified");
  1839. break;
  1840. case EGR_TAG_PVID:
  1841. printf("%7d\t%12s\n", i, "pvid");
  1842. break;
  1843. default:
  1844. printf("%7d\t%12s\n", i, "-");
  1845. }
  1846. }
  1847. }
  1848. return CMD_RET_SUCCESS;
  1849. }
  1850. static int vsc9953_egr_vlan_tag_set_key_func(
  1851. struct ethsw_command_def *parsed_cmd)
  1852. {
  1853. int i;
  1854. enum egress_vlan_tag mode;
  1855. /* keywords for the egress vlan tag mode are the last in the array */
  1856. if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1857. ethsw_id_pvid)
  1858. mode = EGR_TAG_PVID;
  1859. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1860. ethsw_id_classified)
  1861. mode = EGR_TAG_CLASS;
  1862. else
  1863. return CMD_RET_USAGE;
  1864. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1865. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1866. printf("Invalid port number: %d\n", parsed_cmd->port);
  1867. return CMD_RET_FAILURE;
  1868. }
  1869. vsc9953_port_vlan_egress_tag_set(parsed_cmd->port, mode);
  1870. } else {
  1871. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1872. vsc9953_port_vlan_egress_tag_set(i, mode);
  1873. }
  1874. return CMD_RET_SUCCESS;
  1875. }
  1876. static int vsc9953_vlan_learn_show_key_func(
  1877. struct ethsw_command_def *parsed_cmd)
  1878. {
  1879. int rc;
  1880. enum vlan_learning_mode mode;
  1881. rc = vsc9953_vlan_learning_get(&mode);
  1882. if (rc)
  1883. return CMD_RET_FAILURE;
  1884. switch (mode) {
  1885. case SHARED_VLAN_LEARNING:
  1886. printf("VLAN learning mode: shared\n");
  1887. break;
  1888. case PRIVATE_VLAN_LEARNING:
  1889. printf("VLAN learning mode: private\n");
  1890. break;
  1891. default:
  1892. printf("Unknown VLAN learning mode\n");
  1893. rc = CMD_RET_FAILURE;
  1894. }
  1895. return CMD_RET_SUCCESS;
  1896. }
  1897. static int vsc9953_vlan_learn_set_key_func(struct ethsw_command_def *parsed_cmd)
  1898. {
  1899. enum vlan_learning_mode mode;
  1900. /* keywords for shared/private are the last in the array */
  1901. if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1902. ethsw_id_shared)
  1903. mode = SHARED_VLAN_LEARNING;
  1904. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1905. ethsw_id_private)
  1906. mode = PRIVATE_VLAN_LEARNING;
  1907. else
  1908. return CMD_RET_USAGE;
  1909. vsc9953_vlan_learning_set(mode);
  1910. return CMD_RET_SUCCESS;
  1911. }
  1912. static int vsc9953_ingr_fltr_show_key_func(struct ethsw_command_def *parsed_cmd)
  1913. {
  1914. int i;
  1915. int enabled;
  1916. printf("%7s\t%18s\n", "Port", "Ingress filtering");
  1917. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1918. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1919. printf("Invalid port number: %d\n", parsed_cmd->port);
  1920. return CMD_RET_FAILURE;
  1921. }
  1922. enabled = vsc9953_port_ingress_filtering_get(parsed_cmd->port);
  1923. printf("%7d\t%18s\n", parsed_cmd->port, enabled ? "enable" :
  1924. "disable");
  1925. } else {
  1926. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1927. enabled = vsc9953_port_ingress_filtering_get(i);
  1928. printf("%7d\t%18s\n", parsed_cmd->port, enabled ?
  1929. "enable" :
  1930. "disable");
  1931. }
  1932. }
  1933. return CMD_RET_SUCCESS;
  1934. }
  1935. static int vsc9953_ingr_fltr_set_key_func(struct ethsw_command_def *parsed_cmd)
  1936. {
  1937. int i;
  1938. int enable;
  1939. /* keywords for enabling/disabling ingress filtering
  1940. * are the last in the array
  1941. */
  1942. if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1943. ethsw_id_enable)
  1944. enable = 1;
  1945. else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
  1946. ethsw_id_disable)
  1947. enable = 0;
  1948. else
  1949. return CMD_RET_USAGE;
  1950. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1951. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1952. printf("Invalid port number: %d\n", parsed_cmd->port);
  1953. return CMD_RET_FAILURE;
  1954. }
  1955. vsc9953_port_ingress_filtering_set(parsed_cmd->port, enable);
  1956. } else {
  1957. for (i = 0; i < VSC9953_MAX_PORTS; i++)
  1958. vsc9953_port_ingress_filtering_set(i, enable);
  1959. }
  1960. return CMD_RET_SUCCESS;
  1961. }
  1962. static int vsc9953_port_aggr_show_key_func(struct ethsw_command_def *parsed_cmd)
  1963. {
  1964. int i;
  1965. int aggr_grp;
  1966. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1967. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  1968. printf("Invalid port number: %d\n", parsed_cmd->port);
  1969. return CMD_RET_FAILURE;
  1970. }
  1971. if (vsc9953_port_aggr_grp_get(parsed_cmd->port, &aggr_grp))
  1972. return CMD_RET_FAILURE;
  1973. printf("%7s %10s\n", "Port", "Aggr grp");
  1974. printf("%7d %10d\n", parsed_cmd->port, aggr_grp);
  1975. } else {
  1976. printf("%7s %10s\n", "Port", "Aggr grp");
  1977. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  1978. if (vsc9953_port_aggr_grp_get(i, &aggr_grp))
  1979. continue;
  1980. printf("%7d %10d\n", i, aggr_grp);
  1981. }
  1982. }
  1983. return CMD_RET_SUCCESS;
  1984. }
  1985. static int vsc9953_port_aggr_set_key_func(struct ethsw_command_def *parsed_cmd)
  1986. {
  1987. int i;
  1988. /* Aggregation group number should be set in parsed_cmd->aggr_grp */
  1989. if (parsed_cmd->aggr_grp == ETHSW_CMD_AGGR_GRP_NONE) {
  1990. printf("Please set an aggregation group value\n");
  1991. return CMD_RET_FAILURE;
  1992. }
  1993. if (!VSC9953_PORT_CHECK(parsed_cmd->aggr_grp)) {
  1994. printf("Invalid aggregation group number: %d\n",
  1995. parsed_cmd->aggr_grp);
  1996. return CMD_RET_FAILURE;
  1997. }
  1998. if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
  1999. if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
  2000. printf("Invalid port number: %d\n", parsed_cmd->port);
  2001. return CMD_RET_FAILURE;
  2002. }
  2003. if (vsc9953_port_aggr_grp_set(parsed_cmd->port,
  2004. parsed_cmd->aggr_grp)) {
  2005. printf("Port %d: failed to set aggr group %d\n",
  2006. parsed_cmd->port, parsed_cmd->aggr_grp);
  2007. }
  2008. } else {
  2009. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  2010. if (vsc9953_port_aggr_grp_set(i,
  2011. parsed_cmd->aggr_grp)) {
  2012. printf("Port %d: failed to set aggr group %d\n",
  2013. i, parsed_cmd->aggr_grp);
  2014. }
  2015. }
  2016. }
  2017. return CMD_RET_SUCCESS;
  2018. }
  2019. static struct ethsw_command_func vsc9953_cmd_func = {
  2020. .ethsw_name = "L2 Switch VSC9953",
  2021. .port_enable = &vsc9953_port_status_key_func,
  2022. .port_disable = &vsc9953_port_status_key_func,
  2023. .port_show = &vsc9953_port_config_key_func,
  2024. .port_stats = &vsc9953_port_stats_key_func,
  2025. .port_stats_clear = &vsc9953_port_stats_clear_key_func,
  2026. .port_learn = &vsc9953_learn_set_key_func,
  2027. .port_learn_show = &vsc9953_learn_show_key_func,
  2028. .fdb_show = &vsc9953_fdb_show_key_func,
  2029. .fdb_flush = &vsc9953_fdb_flush_key_func,
  2030. .fdb_entry_add = &vsc9953_fdb_entry_add_key_func,
  2031. .fdb_entry_del = &vsc9953_fdb_entry_del_key_func,
  2032. .pvid_show = &vsc9953_pvid_show_key_func,
  2033. .pvid_set = &vsc9953_pvid_set_key_func,
  2034. .vlan_show = &vsc9953_vlan_show_key_func,
  2035. .vlan_set = &vsc9953_vlan_set_key_func,
  2036. .port_untag_show = &vsc9953_port_untag_show_key_func,
  2037. .port_untag_set = &vsc9953_port_untag_set_key_func,
  2038. .port_egr_vlan_show = &vsc9953_egr_vlan_tag_show_key_func,
  2039. .port_egr_vlan_set = &vsc9953_egr_vlan_tag_set_key_func,
  2040. .vlan_learn_show = &vsc9953_vlan_learn_show_key_func,
  2041. .vlan_learn_set = &vsc9953_vlan_learn_set_key_func,
  2042. .port_ingr_filt_show = &vsc9953_ingr_fltr_show_key_func,
  2043. .port_ingr_filt_set = &vsc9953_ingr_fltr_set_key_func,
  2044. .port_aggr_show = &vsc9953_port_aggr_show_key_func,
  2045. .port_aggr_set = &vsc9953_port_aggr_set_key_func,
  2046. };
  2047. #endif /* CONFIG_CMD_ETHSW */
  2048. /*****************************************************************************
  2049. At startup, the default configuration would be:
  2050. - HW learning enabled on all ports; (HW default)
  2051. - All ports are in VLAN 1;
  2052. - All ports are VLAN aware;
  2053. - All ports have POP_COUNT 1;
  2054. - All ports have PVID 1;
  2055. - All ports have TPID 0x8100; (HW default)
  2056. - All ports tag frames classified to all VLANs that are not PVID;
  2057. *****************************************************************************/
  2058. void vsc9953_default_configuration(void)
  2059. {
  2060. int i;
  2061. if (vsc9953_autoage_time_set(VSC9953_DEFAULT_AGE_TIME))
  2062. debug("VSC9953: failed to set AGE time to %d\n",
  2063. VSC9953_DEFAULT_AGE_TIME);
  2064. for (i = 0; i < VSC9953_MAX_VLAN; i++)
  2065. vsc9953_vlan_table_membership_all_set(i, 0);
  2066. vsc9953_port_all_vlan_aware_set(1);
  2067. vsc9953_port_all_vlan_pvid_set(1);
  2068. vsc9953_port_all_vlan_poncnt_set(1);
  2069. vsc9953_vlan_table_membership_all_set(1, 1);
  2070. vsc9953_vlan_ingr_fltr_learn_drop(1);
  2071. vsc9953_port_all_vlan_egress_untagged_set(EGRESS_UNTAG_PVID_AND_ZERO);
  2072. if (vsc9953_aggr_code_set(AGGR_CODE_ALL))
  2073. debug("VSC9953: failed to set default aggregation code mode\n");
  2074. }
  2075. void vsc9953_init(bd_t *bis)
  2076. {
  2077. u32 i;
  2078. u32 hdx_cfg = 0;
  2079. u32 phy_addr = 0;
  2080. int timeout;
  2081. struct vsc9953_system_reg *l2sys_reg;
  2082. struct vsc9953_qsys_reg *l2qsys_reg;
  2083. struct vsc9953_dev_gmii *l2dev_gmii_reg;
  2084. struct vsc9953_analyzer *l2ana_reg;
  2085. struct vsc9953_devcpu_gcb *l2dev_gcb;
  2086. l2dev_gmii_reg = (struct vsc9953_dev_gmii *)(VSC9953_OFFSET +
  2087. VSC9953_DEV_GMII_OFFSET);
  2088. l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
  2089. VSC9953_ANA_OFFSET);
  2090. l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET +
  2091. VSC9953_SYS_OFFSET);
  2092. l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET +
  2093. VSC9953_QSYS_OFFSET);
  2094. l2dev_gcb = (struct vsc9953_devcpu_gcb *)(VSC9953_OFFSET +
  2095. VSC9953_DEVCPU_GCB);
  2096. out_le32(&l2dev_gcb->chip_regs.soft_rst,
  2097. VSC9953_SOFT_SWC_RST_ENA);
  2098. timeout = 50000;
  2099. while ((in_le32(&l2dev_gcb->chip_regs.soft_rst) &
  2100. VSC9953_SOFT_SWC_RST_ENA) && --timeout)
  2101. udelay(1); /* busy wait for vsc9953 soft reset */
  2102. if (timeout == 0)
  2103. debug("Timeout waiting for VSC9953 to reset\n");
  2104. out_le32(&l2sys_reg->sys.reset_cfg, VSC9953_MEM_ENABLE |
  2105. VSC9953_MEM_INIT);
  2106. timeout = 50000;
  2107. while ((in_le32(&l2sys_reg->sys.reset_cfg) &
  2108. VSC9953_MEM_INIT) && --timeout)
  2109. udelay(1); /* busy wait for vsc9953 memory init */
  2110. if (timeout == 0)
  2111. debug("Timeout waiting for VSC9953 memory to initialize\n");
  2112. out_le32(&l2sys_reg->sys.reset_cfg, (in_le32(&l2sys_reg->sys.reset_cfg)
  2113. | VSC9953_CORE_ENABLE));
  2114. /* VSC9953 Setting to be done once only */
  2115. out_le32(&l2qsys_reg->sys.ext_cpu_cfg, 0x00000b00);
  2116. for (i = 0; i < VSC9953_MAX_PORTS; i++) {
  2117. if (vsc9953_port_init(i))
  2118. printf("Failed to initialize l2switch port %d\n", i);
  2119. if (!vsc9953_l2sw.port[i].enabled)
  2120. continue;
  2121. /* Enable VSC9953 GMII Ports Port ID 0 - 7 */
  2122. if (VSC9953_INTERNAL_PORT_CHECK(i)) {
  2123. out_le32(&l2ana_reg->pfc[i].pfc_cfg,
  2124. VSC9953_PFC_FC_QSGMII);
  2125. out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i],
  2126. VSC9953_MAC_FC_CFG_QSGMII);
  2127. } else {
  2128. out_le32(&l2ana_reg->pfc[i].pfc_cfg,
  2129. VSC9953_PFC_FC);
  2130. out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i],
  2131. VSC9953_MAC_FC_CFG);
  2132. }
  2133. l2dev_gmii_reg = (struct vsc9953_dev_gmii *)
  2134. (VSC9953_OFFSET + VSC9953_DEV_GMII_OFFSET +
  2135. T1040_SWITCH_GMII_DEV_OFFSET * i);
  2136. out_le32(&l2dev_gmii_reg->port_mode.clock_cfg,
  2137. VSC9953_CLOCK_CFG);
  2138. out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ena_cfg,
  2139. VSC9953_MAC_ENA_CFG);
  2140. out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_mode_cfg,
  2141. VSC9953_MAC_MODE_CFG);
  2142. out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ifg_cfg,
  2143. VSC9953_MAC_IFG_CFG);
  2144. /* mac_hdx_cfg varies with port id*/
  2145. hdx_cfg = VSC9953_MAC_HDX_CFG | (i << 16);
  2146. out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_hdx_cfg, hdx_cfg);
  2147. out_le32(&l2sys_reg->sys.front_port_mode[i],
  2148. VSC9953_FRONT_PORT_MODE);
  2149. setbits_le32(&l2qsys_reg->sys.switch_port_mode[i],
  2150. VSC9953_PORT_ENA);
  2151. out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_maxlen_cfg,
  2152. VSC9953_MAC_MAX_LEN);
  2153. out_le32(&l2sys_reg->pause_cfg.pause_cfg[i],
  2154. VSC9953_PAUSE_CFG);
  2155. /* WAIT FOR 2 us*/
  2156. udelay(2);
  2157. /* Initialize Lynx PHY Wrappers */
  2158. phy_addr = 0;
  2159. if (vsc9953_l2sw.port[i].enet_if ==
  2160. PHY_INTERFACE_MODE_QSGMII)
  2161. phy_addr = (i + 0x4) & 0x1F;
  2162. else if (vsc9953_l2sw.port[i].enet_if ==
  2163. PHY_INTERFACE_MODE_SGMII)
  2164. phy_addr = (i + 1) & 0x1F;
  2165. if (phy_addr) {
  2166. /* SGMII IF mode + AN enable */
  2167. vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
  2168. 0x14, PHY_SGMII_IF_MODE_AN |
  2169. PHY_SGMII_IF_MODE_SGMII);
  2170. /* Dev ability according to SGMII specification */
  2171. vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
  2172. 0x4, PHY_SGMII_DEV_ABILITY_SGMII);
  2173. /* Adjust link timer for SGMII
  2174. * 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40
  2175. */
  2176. vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
  2177. 0x13, 0x0003);
  2178. vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
  2179. 0x12, 0x0d40);
  2180. /* Restart AN */
  2181. vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
  2182. 0x0, PHY_SGMII_CR_DEF_VAL |
  2183. PHY_SGMII_CR_RESET_AN);
  2184. timeout = 50000;
  2185. while ((vsc9953_mdio_read(&l2dev_gcb->mii_mng[0],
  2186. phy_addr, 0x01) & 0x0020) && --timeout)
  2187. udelay(1); /* wait for AN to complete */
  2188. if (timeout == 0)
  2189. debug("Timeout waiting for AN to complete\n");
  2190. }
  2191. }
  2192. vsc9953_default_configuration();
  2193. #ifdef CONFIG_CMD_ETHSW
  2194. if (ethsw_define_functions(&vsc9953_cmd_func) < 0)
  2195. debug("Unable to use \"ethsw\" commands\n");
  2196. #endif
  2197. printf("VSC9953 L2 switch initialized\n");
  2198. return;
  2199. }