vsc9953.c 72 KB

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