vsc9953.c 76 KB

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