mvsw61xx.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. /*
  2. * Marvell 88E61xx switch driver
  3. *
  4. * Copyright (c) 2014 Claudio Leite <leitec@staticky.com>
  5. * Copyright (c) 2014 Nikita Nazarenko <nnazarenko@radiofid.com>
  6. *
  7. * Based on code (c) 2008 Felix Fietkau <nbd@nbd.name>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License v2 as published by the
  11. * Free Software Foundation
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/init.h>
  16. #include <linux/list.h>
  17. #include <linux/mii.h>
  18. #include <linux/phy.h>
  19. #include <linux/of.h>
  20. #include <linux/of_mdio.h>
  21. #include <linux/delay.h>
  22. #include <linux/switch.h>
  23. #include <linux/device.h>
  24. #include <linux/platform_device.h>
  25. #include "mvsw61xx.h"
  26. MODULE_DESCRIPTION("Marvell 88E61xx Switch driver");
  27. MODULE_AUTHOR("Claudio Leite <leitec@staticky.com>");
  28. MODULE_AUTHOR("Nikita Nazarenko <nnazarenko@radiofid.com>");
  29. MODULE_LICENSE("GPL v2");
  30. MODULE_ALIAS("platform:mvsw61xx");
  31. /*
  32. * Register access is done through direct or indirect addressing,
  33. * depending on how the switch is physically connected.
  34. *
  35. * Direct addressing: all port and global registers directly
  36. * accessible via an address/register pair
  37. *
  38. * Indirect addressing: switch is mapped at a single address,
  39. * port and global registers accessible via a single command/data
  40. * register pair
  41. */
  42. static int
  43. mvsw61xx_wait_mask_raw(struct mii_bus *bus, int addr,
  44. int reg, u16 mask, u16 val)
  45. {
  46. int i = 100;
  47. u16 r;
  48. do {
  49. r = bus->read(bus, addr, reg);
  50. if ((r & mask) == val)
  51. return 0;
  52. } while (--i > 0);
  53. return -ETIMEDOUT;
  54. }
  55. static u16
  56. r16(struct mii_bus *bus, bool indirect, int base_addr, int addr, int reg)
  57. {
  58. u16 ind_addr;
  59. if (!indirect)
  60. return bus->read(bus, addr, reg);
  61. /* Indirect read: First, make sure switch is free */
  62. mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
  63. MV_INDIRECT_INPROGRESS, 0);
  64. /* Load address and request read */
  65. ind_addr = MV_INDIRECT_READ | (addr << MV_INDIRECT_ADDR_S) | reg;
  66. bus->write(bus, base_addr, MV_INDIRECT_REG_CMD,
  67. ind_addr);
  68. /* Wait until it's ready */
  69. mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
  70. MV_INDIRECT_INPROGRESS, 0);
  71. /* Read the requested data */
  72. return bus->read(bus, base_addr, MV_INDIRECT_REG_DATA);
  73. }
  74. static void
  75. w16(struct mii_bus *bus, bool indirect, int base_addr, int addr,
  76. int reg, u16 val)
  77. {
  78. u16 ind_addr;
  79. if (!indirect) {
  80. bus->write(bus, addr, reg, val);
  81. return;
  82. }
  83. /* Indirect write: First, make sure switch is free */
  84. mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
  85. MV_INDIRECT_INPROGRESS, 0);
  86. /* Load the data to be written */
  87. bus->write(bus, base_addr, MV_INDIRECT_REG_DATA, val);
  88. /* Wait again for switch to be free */
  89. mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
  90. MV_INDIRECT_INPROGRESS, 0);
  91. /* Load address, and issue write command */
  92. ind_addr = MV_INDIRECT_WRITE | (addr << MV_INDIRECT_ADDR_S) | reg;
  93. bus->write(bus, base_addr, MV_INDIRECT_REG_CMD,
  94. ind_addr);
  95. }
  96. /* swconfig support */
  97. static inline u16
  98. sr16(struct switch_dev *dev, int addr, int reg)
  99. {
  100. struct mvsw61xx_state *state = get_state(dev);
  101. return r16(state->bus, state->is_indirect, state->base_addr, addr, reg);
  102. }
  103. static inline void
  104. sw16(struct switch_dev *dev, int addr, int reg, u16 val)
  105. {
  106. struct mvsw61xx_state *state = get_state(dev);
  107. w16(state->bus, state->is_indirect, state->base_addr, addr, reg, val);
  108. }
  109. static int
  110. mvsw61xx_wait_mask_s(struct switch_dev *dev, int addr,
  111. int reg, u16 mask, u16 val)
  112. {
  113. int i = 100;
  114. u16 r;
  115. do {
  116. r = sr16(dev, addr, reg) & mask;
  117. if (r == val)
  118. return 0;
  119. } while (--i > 0);
  120. return -ETIMEDOUT;
  121. }
  122. static int
  123. mvsw61xx_mdio_read(struct switch_dev *dev, int addr, int reg)
  124. {
  125. sw16(dev, MV_GLOBAL2REG(SMI_OP),
  126. MV_INDIRECT_READ | (addr << MV_INDIRECT_ADDR_S) | reg);
  127. if (mvsw61xx_wait_mask_s(dev, MV_GLOBAL2REG(SMI_OP),
  128. MV_INDIRECT_INPROGRESS, 0) < 0)
  129. return -ETIMEDOUT;
  130. return sr16(dev, MV_GLOBAL2REG(SMI_DATA));
  131. }
  132. static int
  133. mvsw61xx_mdio_write(struct switch_dev *dev, int addr, int reg, u16 val)
  134. {
  135. sw16(dev, MV_GLOBAL2REG(SMI_DATA), val);
  136. sw16(dev, MV_GLOBAL2REG(SMI_OP),
  137. MV_INDIRECT_WRITE | (addr << MV_INDIRECT_ADDR_S) | reg);
  138. return mvsw61xx_wait_mask_s(dev, MV_GLOBAL2REG(SMI_OP),
  139. MV_INDIRECT_INPROGRESS, 0) < 0;
  140. }
  141. static int
  142. mvsw61xx_mdio_page_read(struct switch_dev *dev, int port, int page, int reg)
  143. {
  144. int ret;
  145. mvsw61xx_mdio_write(dev, port, MII_MV_PAGE, page);
  146. ret = mvsw61xx_mdio_read(dev, port, reg);
  147. mvsw61xx_mdio_write(dev, port, MII_MV_PAGE, 0);
  148. return ret;
  149. }
  150. static void
  151. mvsw61xx_mdio_page_write(struct switch_dev *dev, int port, int page, int reg,
  152. u16 val)
  153. {
  154. mvsw61xx_mdio_write(dev, port, MII_MV_PAGE, page);
  155. mvsw61xx_mdio_write(dev, port, reg, val);
  156. mvsw61xx_mdio_write(dev, port, MII_MV_PAGE, 0);
  157. }
  158. static int
  159. mvsw61xx_get_port_mask(struct switch_dev *dev,
  160. const struct switch_attr *attr, struct switch_val *val)
  161. {
  162. struct mvsw61xx_state *state = get_state(dev);
  163. char *buf = state->buf;
  164. int port, len, i;
  165. u16 reg;
  166. port = val->port_vlan;
  167. reg = sr16(dev, MV_PORTREG(VLANMAP, port)) & MV_PORTS_MASK;
  168. len = sprintf(buf, "0x%04x: ", reg);
  169. for (i = 0; i < MV_PORTS; i++) {
  170. if (reg & (1 << i))
  171. len += sprintf(buf + len, "%d ", i);
  172. else if (i == port)
  173. len += sprintf(buf + len, "(%d) ", i);
  174. }
  175. val->value.s = buf;
  176. return 0;
  177. }
  178. static int
  179. mvsw61xx_get_port_qmode(struct switch_dev *dev,
  180. const struct switch_attr *attr, struct switch_val *val)
  181. {
  182. struct mvsw61xx_state *state = get_state(dev);
  183. val->value.i = state->ports[val->port_vlan].qmode;
  184. return 0;
  185. }
  186. static int
  187. mvsw61xx_set_port_qmode(struct switch_dev *dev,
  188. const struct switch_attr *attr, struct switch_val *val)
  189. {
  190. struct mvsw61xx_state *state = get_state(dev);
  191. state->ports[val->port_vlan].qmode = val->value.i;
  192. return 0;
  193. }
  194. static int
  195. mvsw61xx_get_port_pvid(struct switch_dev *dev, int port, int *val)
  196. {
  197. struct mvsw61xx_state *state = get_state(dev);
  198. *val = state->ports[port].pvid;
  199. return 0;
  200. }
  201. static int
  202. mvsw61xx_set_port_pvid(struct switch_dev *dev, int port, int val)
  203. {
  204. struct mvsw61xx_state *state = get_state(dev);
  205. if (val < 0 || val >= MV_VLANS)
  206. return -EINVAL;
  207. state->ports[port].pvid = (u16)val;
  208. return 0;
  209. }
  210. static int
  211. mvsw61xx_get_port_link(struct switch_dev *dev, int port,
  212. struct switch_port_link *link)
  213. {
  214. u16 status, speed;
  215. status = sr16(dev, MV_PORTREG(STATUS, port));
  216. link->link = status & MV_PORT_STATUS_LINK;
  217. if (!link->link)
  218. return 0;
  219. link->duplex = status & MV_PORT_STATUS_FDX;
  220. speed = (status & MV_PORT_STATUS_SPEED_MASK) >>
  221. MV_PORT_STATUS_SPEED_SHIFT;
  222. switch (speed) {
  223. case MV_PORT_STATUS_SPEED_10:
  224. link->speed = SWITCH_PORT_SPEED_10;
  225. break;
  226. case MV_PORT_STATUS_SPEED_100:
  227. link->speed = SWITCH_PORT_SPEED_100;
  228. break;
  229. case MV_PORT_STATUS_SPEED_1000:
  230. link->speed = SWITCH_PORT_SPEED_1000;
  231. break;
  232. }
  233. return 0;
  234. }
  235. static int mvsw61xx_get_vlan_ports(struct switch_dev *dev,
  236. struct switch_val *val)
  237. {
  238. struct mvsw61xx_state *state = get_state(dev);
  239. int i, j, mode, vno;
  240. vno = val->port_vlan;
  241. if (vno <= 0 || vno >= dev->vlans)
  242. return -EINVAL;
  243. for (i = 0, j = 0; i < dev->ports; i++) {
  244. if (state->vlans[vno].mask & (1 << i)) {
  245. val->value.ports[j].id = i;
  246. mode = (state->vlans[vno].port_mode >> (i * 4)) & 0xf;
  247. if (mode == MV_VTUCTL_EGRESS_TAGGED)
  248. val->value.ports[j].flags =
  249. (1 << SWITCH_PORT_FLAG_TAGGED);
  250. else
  251. val->value.ports[j].flags = 0;
  252. j++;
  253. }
  254. }
  255. val->len = j;
  256. return 0;
  257. }
  258. static int mvsw61xx_set_vlan_ports(struct switch_dev *dev,
  259. struct switch_val *val)
  260. {
  261. struct mvsw61xx_state *state = get_state(dev);
  262. int i, mode, pno, vno;
  263. vno = val->port_vlan;
  264. if (vno <= 0 || vno >= dev->vlans)
  265. return -EINVAL;
  266. state->vlans[vno].mask = 0;
  267. state->vlans[vno].port_mode = 0;
  268. state->vlans[vno].port_sstate = 0;
  269. if(state->vlans[vno].vid == 0)
  270. state->vlans[vno].vid = vno;
  271. for (i = 0; i < val->len; i++) {
  272. pno = val->value.ports[i].id;
  273. state->vlans[vno].mask |= (1 << pno);
  274. if (val->value.ports[i].flags &
  275. (1 << SWITCH_PORT_FLAG_TAGGED))
  276. mode = MV_VTUCTL_EGRESS_TAGGED;
  277. else
  278. mode = MV_VTUCTL_EGRESS_UNTAGGED;
  279. state->vlans[vno].port_mode |= mode << (pno * 4);
  280. state->vlans[vno].port_sstate |=
  281. MV_STUCTL_STATE_FORWARDING << (pno * 4 + 2);
  282. }
  283. /*
  284. * DISCARD is nonzero, so it must be explicitly
  285. * set on ports not in the VLAN.
  286. */
  287. for (i = 0; i < dev->ports; i++)
  288. if (!(state->vlans[vno].mask & (1 << i)))
  289. state->vlans[vno].port_mode |=
  290. MV_VTUCTL_DISCARD << (i * 4);
  291. return 0;
  292. }
  293. static int mvsw61xx_get_vlan_port_based(struct switch_dev *dev,
  294. const struct switch_attr *attr, struct switch_val *val)
  295. {
  296. struct mvsw61xx_state *state = get_state(dev);
  297. int vno = val->port_vlan;
  298. if (vno <= 0 || vno >= dev->vlans)
  299. return -EINVAL;
  300. if (state->vlans[vno].port_based)
  301. val->value.i = 1;
  302. else
  303. val->value.i = 0;
  304. return 0;
  305. }
  306. static int mvsw61xx_set_vlan_port_based(struct switch_dev *dev,
  307. const struct switch_attr *attr, struct switch_val *val)
  308. {
  309. struct mvsw61xx_state *state = get_state(dev);
  310. int vno = val->port_vlan;
  311. if (vno <= 0 || vno >= dev->vlans)
  312. return -EINVAL;
  313. if (val->value.i == 1)
  314. state->vlans[vno].port_based = true;
  315. else
  316. state->vlans[vno].port_based = false;
  317. return 0;
  318. }
  319. static int mvsw61xx_get_vid(struct switch_dev *dev,
  320. const struct switch_attr *attr, struct switch_val *val)
  321. {
  322. struct mvsw61xx_state *state = get_state(dev);
  323. int vno = val->port_vlan;
  324. if (vno <= 0 || vno >= dev->vlans)
  325. return -EINVAL;
  326. val->value.i = state->vlans[vno].vid;
  327. return 0;
  328. }
  329. static int mvsw61xx_set_vid(struct switch_dev *dev,
  330. const struct switch_attr *attr, struct switch_val *val)
  331. {
  332. struct mvsw61xx_state *state = get_state(dev);
  333. int vno = val->port_vlan;
  334. if (vno <= 0 || vno >= dev->vlans)
  335. return -EINVAL;
  336. state->vlans[vno].vid = val->value.i;
  337. return 0;
  338. }
  339. static int mvsw61xx_get_enable_vlan(struct switch_dev *dev,
  340. const struct switch_attr *attr, struct switch_val *val)
  341. {
  342. struct mvsw61xx_state *state = get_state(dev);
  343. val->value.i = state->vlan_enabled;
  344. return 0;
  345. }
  346. static int mvsw61xx_set_enable_vlan(struct switch_dev *dev,
  347. const struct switch_attr *attr, struct switch_val *val)
  348. {
  349. struct mvsw61xx_state *state = get_state(dev);
  350. state->vlan_enabled = val->value.i;
  351. return 0;
  352. }
  353. static int mvsw61xx_vtu_program(struct switch_dev *dev)
  354. {
  355. struct mvsw61xx_state *state = get_state(dev);
  356. u16 v1, v2, s1, s2;
  357. int i;
  358. /* Flush */
  359. mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(VTU_OP),
  360. MV_VTUOP_INPROGRESS, 0);
  361. sw16(dev, MV_GLOBALREG(VTU_OP),
  362. MV_VTUOP_INPROGRESS | MV_VTUOP_PURGE);
  363. /* Write VLAN table */
  364. for (i = 1; i < dev->vlans; i++) {
  365. if (state->vlans[i].mask == 0 ||
  366. state->vlans[i].vid == 0 ||
  367. state->vlans[i].port_based == true)
  368. continue;
  369. mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(VTU_OP),
  370. MV_VTUOP_INPROGRESS, 0);
  371. /* Write per-VLAN port state into STU */
  372. s1 = (u16) (state->vlans[i].port_sstate & 0xffff);
  373. s2 = (u16) ((state->vlans[i].port_sstate >> 16) & 0xffff);
  374. sw16(dev, MV_GLOBALREG(VTU_VID), MV_VTU_VID_VALID);
  375. sw16(dev, MV_GLOBALREG(VTU_SID), i);
  376. sw16(dev, MV_GLOBALREG(VTU_DATA1), s1);
  377. sw16(dev, MV_GLOBALREG(VTU_DATA2), s2);
  378. sw16(dev, MV_GLOBALREG(VTU_DATA3), 0);
  379. sw16(dev, MV_GLOBALREG(VTU_OP),
  380. MV_VTUOP_INPROGRESS | MV_VTUOP_STULOAD);
  381. mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(VTU_OP),
  382. MV_VTUOP_INPROGRESS, 0);
  383. /* Write VLAN information into VTU */
  384. v1 = (u16) (state->vlans[i].port_mode & 0xffff);
  385. v2 = (u16) ((state->vlans[i].port_mode >> 16) & 0xffff);
  386. sw16(dev, MV_GLOBALREG(VTU_VID),
  387. MV_VTU_VID_VALID | state->vlans[i].vid);
  388. sw16(dev, MV_GLOBALREG(VTU_SID), i);
  389. sw16(dev, MV_GLOBALREG(VTU_FID), i);
  390. sw16(dev, MV_GLOBALREG(VTU_DATA1), v1);
  391. sw16(dev, MV_GLOBALREG(VTU_DATA2), v2);
  392. sw16(dev, MV_GLOBALREG(VTU_DATA3), 0);
  393. sw16(dev, MV_GLOBALREG(VTU_OP),
  394. MV_VTUOP_INPROGRESS | MV_VTUOP_LOAD);
  395. mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(VTU_OP),
  396. MV_VTUOP_INPROGRESS, 0);
  397. }
  398. return 0;
  399. }
  400. static void mvsw61xx_vlan_port_config(struct switch_dev *dev, int vno)
  401. {
  402. struct mvsw61xx_state *state = get_state(dev);
  403. int i, mode;
  404. for (i = 0; i < dev->ports; i++) {
  405. if (!(state->vlans[vno].mask & (1 << i)))
  406. continue;
  407. mode = (state->vlans[vno].port_mode >> (i * 4)) & 0xf;
  408. if(mode != MV_VTUCTL_EGRESS_TAGGED)
  409. state->ports[i].pvid = state->vlans[vno].vid;
  410. if (state->vlans[vno].port_based) {
  411. state->ports[i].mask |= state->vlans[vno].mask;
  412. state->ports[i].fdb = vno;
  413. }
  414. else
  415. state->ports[i].qmode = MV_8021Q_MODE_SECURE;
  416. }
  417. }
  418. static int mvsw61xx_update_state(struct switch_dev *dev)
  419. {
  420. struct mvsw61xx_state *state = get_state(dev);
  421. int i;
  422. u16 reg;
  423. if (!state->registered)
  424. return -EINVAL;
  425. /*
  426. * Set 802.1q-only mode if vlan_enabled is true.
  427. *
  428. * Without this, even if 802.1q is enabled for
  429. * a port/VLAN, it still depends on the port-based
  430. * VLAN mask being set.
  431. *
  432. * With this setting, port-based VLANs are still
  433. * functional, provided the VID is not in the VTU.
  434. */
  435. reg = sr16(dev, MV_GLOBAL2REG(SDET_POLARITY));
  436. if (state->vlan_enabled)
  437. reg |= MV_8021Q_VLAN_ONLY;
  438. else
  439. reg &= ~MV_8021Q_VLAN_ONLY;
  440. sw16(dev, MV_GLOBAL2REG(SDET_POLARITY), reg);
  441. /*
  442. * Set port-based VLAN masks on each port
  443. * based only on VLAN definitions known to
  444. * the driver (i.e. in state).
  445. *
  446. * This means any pre-existing port mapping is
  447. * wiped out once our driver is initialized.
  448. */
  449. for (i = 0; i < dev->ports; i++) {
  450. state->ports[i].mask = 0;
  451. state->ports[i].qmode = MV_8021Q_MODE_DISABLE;
  452. }
  453. for (i = 0; i < dev->vlans; i++)
  454. mvsw61xx_vlan_port_config(dev, i);
  455. for (i = 0; i < dev->ports; i++) {
  456. reg = sr16(dev, MV_PORTREG(VLANID, i)) & ~MV_PVID_MASK;
  457. reg |= state->ports[i].pvid;
  458. sw16(dev, MV_PORTREG(VLANID, i), reg);
  459. state->ports[i].mask &= ~(1 << i);
  460. /* set default forwarding DB number and port mask */
  461. reg = sr16(dev, MV_PORTREG(CONTROL1, i)) & ~MV_FDB_HI_MASK;
  462. reg |= (state->ports[i].fdb >> MV_FDB_HI_SHIFT) &
  463. MV_FDB_HI_MASK;
  464. sw16(dev, MV_PORTREG(CONTROL1, i), reg);
  465. reg = ((state->ports[i].fdb & 0xf) << MV_FDB_LO_SHIFT) |
  466. state->ports[i].mask;
  467. sw16(dev, MV_PORTREG(VLANMAP, i), reg);
  468. reg = sr16(dev, MV_PORTREG(CONTROL2, i)) &
  469. ~MV_8021Q_MODE_MASK;
  470. reg |= state->ports[i].qmode << MV_8021Q_MODE_SHIFT;
  471. sw16(dev, MV_PORTREG(CONTROL2, i), reg);
  472. }
  473. mvsw61xx_vtu_program(dev);
  474. return 0;
  475. }
  476. static int mvsw61xx_apply(struct switch_dev *dev)
  477. {
  478. return mvsw61xx_update_state(dev);
  479. }
  480. static void mvsw61xx_enable_serdes(struct switch_dev *dev)
  481. {
  482. int bmcr = mvsw61xx_mdio_page_read(dev, MV_REG_FIBER_SERDES,
  483. MV_PAGE_FIBER_SERDES, MII_BMCR);
  484. if (bmcr < 0)
  485. return;
  486. if (bmcr & BMCR_PDOWN)
  487. mvsw61xx_mdio_page_write(dev, MV_REG_FIBER_SERDES,
  488. MV_PAGE_FIBER_SERDES, MII_BMCR,
  489. bmcr & ~BMCR_PDOWN);
  490. }
  491. static int _mvsw61xx_reset(struct switch_dev *dev, bool full)
  492. {
  493. struct mvsw61xx_state *state = get_state(dev);
  494. int i;
  495. u16 reg;
  496. /* Disable all ports before reset */
  497. for (i = 0; i < dev->ports; i++) {
  498. reg = sr16(dev, MV_PORTREG(CONTROL, i)) &
  499. ~MV_PORTCTRL_FORWARDING;
  500. sw16(dev, MV_PORTREG(CONTROL, i), reg);
  501. }
  502. reg = sr16(dev, MV_GLOBALREG(CONTROL)) | MV_CONTROL_RESET;
  503. sw16(dev, MV_GLOBALREG(CONTROL), reg);
  504. if (mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(CONTROL),
  505. MV_CONTROL_RESET, 0) < 0)
  506. return -ETIMEDOUT;
  507. for (i = 0; i < dev->ports; i++) {
  508. state->ports[i].fdb = 0;
  509. state->ports[i].qmode = 0;
  510. state->ports[i].mask = 0;
  511. state->ports[i].pvid = 0;
  512. /* Force flow control off */
  513. reg = sr16(dev, MV_PORTREG(PHYCTL, i)) & ~MV_PHYCTL_FC_MASK;
  514. reg |= MV_PHYCTL_FC_DISABLE;
  515. sw16(dev, MV_PORTREG(PHYCTL, i), reg);
  516. /* Set port association vector */
  517. sw16(dev, MV_PORTREG(ASSOC, i), (1 << i));
  518. /* power up phys */
  519. if (full && i < 5) {
  520. mvsw61xx_mdio_write(dev, i, MII_MV_SPEC_CTRL,
  521. MV_SPEC_MDI_CROSS_AUTO |
  522. MV_SPEC_ENERGY_DETECT |
  523. MV_SPEC_DOWNSHIFT_COUNTER);
  524. mvsw61xx_mdio_write(dev, i, MII_BMCR, BMCR_RESET |
  525. BMCR_ANENABLE | BMCR_FULLDPLX |
  526. BMCR_SPEED1000);
  527. }
  528. /* enable SerDes if necessary */
  529. if (full && i >= 5 && state->model == MV_IDENT_VALUE_6176) {
  530. u16 sts = sr16(dev, MV_PORTREG(STATUS, i));
  531. u16 mode = sts & MV_PORT_STATUS_CMODE_MASK;
  532. if (mode == MV_PORT_STATUS_CMODE_100BASE_X ||
  533. mode == MV_PORT_STATUS_CMODE_1000BASE_X ||
  534. mode == MV_PORT_STATUS_CMODE_SGMII) {
  535. mvsw61xx_enable_serdes(dev);
  536. }
  537. }
  538. }
  539. for (i = 0; i < dev->vlans; i++) {
  540. state->vlans[i].port_based = false;
  541. state->vlans[i].mask = 0;
  542. state->vlans[i].vid = 0;
  543. state->vlans[i].port_mode = 0;
  544. state->vlans[i].port_sstate = 0;
  545. }
  546. state->vlan_enabled = 0;
  547. mvsw61xx_update_state(dev);
  548. /* Re-enable ports */
  549. for (i = 0; i < dev->ports; i++) {
  550. reg = sr16(dev, MV_PORTREG(CONTROL, i)) |
  551. MV_PORTCTRL_FORWARDING;
  552. sw16(dev, MV_PORTREG(CONTROL, i), reg);
  553. }
  554. return 0;
  555. }
  556. static int mvsw61xx_reset(struct switch_dev *dev)
  557. {
  558. return _mvsw61xx_reset(dev, false);
  559. }
  560. enum {
  561. MVSW61XX_ENABLE_VLAN,
  562. };
  563. enum {
  564. MVSW61XX_VLAN_PORT_BASED,
  565. MVSW61XX_VLAN_ID,
  566. };
  567. enum {
  568. MVSW61XX_PORT_MASK,
  569. MVSW61XX_PORT_QMODE,
  570. };
  571. static const struct switch_attr mvsw61xx_global[] = {
  572. [MVSW61XX_ENABLE_VLAN] = {
  573. .id = MVSW61XX_ENABLE_VLAN,
  574. .type = SWITCH_TYPE_INT,
  575. .name = "enable_vlan",
  576. .description = "Enable 802.1q VLAN support",
  577. .get = mvsw61xx_get_enable_vlan,
  578. .set = mvsw61xx_set_enable_vlan,
  579. },
  580. };
  581. static const struct switch_attr mvsw61xx_vlan[] = {
  582. [MVSW61XX_VLAN_PORT_BASED] = {
  583. .id = MVSW61XX_VLAN_PORT_BASED,
  584. .type = SWITCH_TYPE_INT,
  585. .name = "port_based",
  586. .description = "Use port-based (non-802.1q) VLAN only",
  587. .get = mvsw61xx_get_vlan_port_based,
  588. .set = mvsw61xx_set_vlan_port_based,
  589. },
  590. [MVSW61XX_VLAN_ID] = {
  591. .id = MVSW61XX_VLAN_ID,
  592. .type = SWITCH_TYPE_INT,
  593. .name = "vid",
  594. .description = "Get/set VLAN ID",
  595. .get = mvsw61xx_get_vid,
  596. .set = mvsw61xx_set_vid,
  597. },
  598. };
  599. static const struct switch_attr mvsw61xx_port[] = {
  600. [MVSW61XX_PORT_MASK] = {
  601. .id = MVSW61XX_PORT_MASK,
  602. .type = SWITCH_TYPE_STRING,
  603. .description = "Port-based VLAN mask",
  604. .name = "mask",
  605. .get = mvsw61xx_get_port_mask,
  606. .set = NULL,
  607. },
  608. [MVSW61XX_PORT_QMODE] = {
  609. .id = MVSW61XX_PORT_QMODE,
  610. .type = SWITCH_TYPE_INT,
  611. .description = "802.1q mode: 0=off/1=fallback/2=check/3=secure",
  612. .name = "qmode",
  613. .get = mvsw61xx_get_port_qmode,
  614. .set = mvsw61xx_set_port_qmode,
  615. },
  616. };
  617. static const struct switch_dev_ops mvsw61xx_ops = {
  618. .attr_global = {
  619. .attr = mvsw61xx_global,
  620. .n_attr = ARRAY_SIZE(mvsw61xx_global),
  621. },
  622. .attr_vlan = {
  623. .attr = mvsw61xx_vlan,
  624. .n_attr = ARRAY_SIZE(mvsw61xx_vlan),
  625. },
  626. .attr_port = {
  627. .attr = mvsw61xx_port,
  628. .n_attr = ARRAY_SIZE(mvsw61xx_port),
  629. },
  630. .get_port_link = mvsw61xx_get_port_link,
  631. .get_port_pvid = mvsw61xx_get_port_pvid,
  632. .set_port_pvid = mvsw61xx_set_port_pvid,
  633. .get_vlan_ports = mvsw61xx_get_vlan_ports,
  634. .set_vlan_ports = mvsw61xx_set_vlan_ports,
  635. .apply_config = mvsw61xx_apply,
  636. .reset_switch = mvsw61xx_reset,
  637. };
  638. /* end swconfig stuff */
  639. static int mvsw61xx_probe(struct platform_device *pdev)
  640. {
  641. struct mvsw61xx_state *state;
  642. struct device_node *np = pdev->dev.of_node;
  643. struct device_node *mdio;
  644. char *model_str;
  645. u32 val;
  646. int err;
  647. state = kzalloc(sizeof(*state), GFP_KERNEL);
  648. if (!state)
  649. return -ENOMEM;
  650. mdio = of_parse_phandle(np, "mii-bus", 0);
  651. if (!mdio) {
  652. dev_err(&pdev->dev, "Couldn't get MII bus handle\n");
  653. err = -ENODEV;
  654. goto out_err;
  655. }
  656. state->bus = of_mdio_find_bus(mdio);
  657. if (!state->bus) {
  658. dev_err(&pdev->dev, "Couldn't find MII bus from handle\n");
  659. err = -ENODEV;
  660. goto out_err;
  661. }
  662. state->is_indirect = of_property_read_bool(np, "is-indirect");
  663. if (state->is_indirect) {
  664. if (of_property_read_u32(np, "reg", &val)) {
  665. dev_err(&pdev->dev, "Switch address not specified\n");
  666. err = -ENODEV;
  667. goto out_err;
  668. }
  669. state->base_addr = val;
  670. } else {
  671. state->base_addr = MV_BASE;
  672. }
  673. state->model = r16(state->bus, state->is_indirect, state->base_addr,
  674. MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
  675. switch(state->model) {
  676. case MV_IDENT_VALUE_6171:
  677. model_str = MV_IDENT_STR_6171;
  678. break;
  679. case MV_IDENT_VALUE_6172:
  680. model_str = MV_IDENT_STR_6172;
  681. break;
  682. case MV_IDENT_VALUE_6176:
  683. model_str = MV_IDENT_STR_6176;
  684. break;
  685. case MV_IDENT_VALUE_6352:
  686. model_str = MV_IDENT_STR_6352;
  687. break;
  688. default:
  689. dev_err(&pdev->dev, "No compatible switch found at 0x%02x\n",
  690. state->base_addr);
  691. err = -ENODEV;
  692. goto out_err;
  693. }
  694. platform_set_drvdata(pdev, state);
  695. dev_info(&pdev->dev, "Found %s at %s:%02x\n", model_str,
  696. state->bus->id, state->base_addr);
  697. dev_info(&pdev->dev, "Using %sdirect addressing\n",
  698. (state->is_indirect ? "in" : ""));
  699. if (of_property_read_u32(np, "cpu-port-0", &val)) {
  700. dev_err(&pdev->dev, "CPU port not set\n");
  701. err = -ENODEV;
  702. goto out_err;
  703. }
  704. state->cpu_port0 = val;
  705. if (!of_property_read_u32(np, "cpu-port-1", &val))
  706. state->cpu_port1 = val;
  707. else
  708. state->cpu_port1 = -1;
  709. state->dev.vlans = MV_VLANS;
  710. state->dev.cpu_port = state->cpu_port0;
  711. state->dev.ports = MV_PORTS;
  712. state->dev.name = model_str;
  713. state->dev.ops = &mvsw61xx_ops;
  714. state->dev.alias = dev_name(&pdev->dev);
  715. _mvsw61xx_reset(&state->dev, true);
  716. err = register_switch(&state->dev, NULL);
  717. if (err < 0)
  718. goto out_err;
  719. state->registered = true;
  720. return 0;
  721. out_err:
  722. kfree(state);
  723. return err;
  724. }
  725. static int
  726. mvsw61xx_remove(struct platform_device *pdev)
  727. {
  728. struct mvsw61xx_state *state = platform_get_drvdata(pdev);
  729. if (state->registered)
  730. unregister_switch(&state->dev);
  731. kfree(state);
  732. return 0;
  733. }
  734. static const struct of_device_id mvsw61xx_match[] = {
  735. { .compatible = "marvell,88e6171" },
  736. { .compatible = "marvell,88e6172" },
  737. { .compatible = "marvell,88e6176" },
  738. { .compatible = "marvell,88e6352" },
  739. { }
  740. };
  741. MODULE_DEVICE_TABLE(of, mvsw61xx_match);
  742. static struct platform_driver mvsw61xx_driver = {
  743. .probe = mvsw61xx_probe,
  744. .remove = mvsw61xx_remove,
  745. .driver = {
  746. .name = "mvsw61xx",
  747. .of_match_table = of_match_ptr(mvsw61xx_match),
  748. .owner = THIS_MODULE,
  749. },
  750. };
  751. static int __init mvsw61xx_module_init(void)
  752. {
  753. return platform_driver_register(&mvsw61xx_driver);
  754. }
  755. late_initcall(mvsw61xx_module_init);
  756. static void __exit mvsw61xx_module_exit(void)
  757. {
  758. platform_driver_unregister(&mvsw61xx_driver);
  759. }
  760. module_exit(mvsw61xx_module_exit);