port.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  1. /*
  2. * Marvell 88E6xxx Switch Port Registers support
  3. *
  4. * Copyright (c) 2008 Marvell Semiconductor
  5. *
  6. * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
  7. * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. */
  14. #include <linux/bitfield.h>
  15. #include <linux/if_bridge.h>
  16. #include <linux/phy.h>
  17. #include <linux/phylink.h>
  18. #include "chip.h"
  19. #include "port.h"
  20. #include "serdes.h"
  21. int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
  22. u16 *val)
  23. {
  24. int addr = chip->info->port_base_addr + port;
  25. return mv88e6xxx_read(chip, addr, reg, val);
  26. }
  27. int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
  28. u16 val)
  29. {
  30. int addr = chip->info->port_base_addr + port;
  31. return mv88e6xxx_write(chip, addr, reg, val);
  32. }
  33. /* Offset 0x00: MAC (or PCS or Physical) Status Register
  34. *
  35. * For most devices, this is read only. However the 6185 has the MyPause
  36. * bit read/write.
  37. */
  38. int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
  39. int pause)
  40. {
  41. u16 reg;
  42. int err;
  43. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
  44. if (err)
  45. return err;
  46. if (pause)
  47. reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
  48. else
  49. reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
  50. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
  51. }
  52. /* Offset 0x01: MAC (or PCS or Physical) Control Register
  53. *
  54. * Link, Duplex and Flow Control have one force bit, one value bit.
  55. *
  56. * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
  57. * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
  58. * Newer chips need a ForcedSpd bit 13 set to consider the value.
  59. */
  60. static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
  61. phy_interface_t mode)
  62. {
  63. u16 reg;
  64. int err;
  65. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
  66. if (err)
  67. return err;
  68. reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
  69. MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
  70. switch (mode) {
  71. case PHY_INTERFACE_MODE_RGMII_RXID:
  72. reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
  73. break;
  74. case PHY_INTERFACE_MODE_RGMII_TXID:
  75. reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
  76. break;
  77. case PHY_INTERFACE_MODE_RGMII_ID:
  78. reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
  79. MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
  80. break;
  81. case PHY_INTERFACE_MODE_RGMII:
  82. break;
  83. default:
  84. return 0;
  85. }
  86. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
  87. if (err)
  88. return err;
  89. dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
  90. reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
  91. reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
  92. return 0;
  93. }
  94. int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
  95. phy_interface_t mode)
  96. {
  97. if (port < 5)
  98. return -EOPNOTSUPP;
  99. return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
  100. }
  101. int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
  102. phy_interface_t mode)
  103. {
  104. if (port != 0)
  105. return -EOPNOTSUPP;
  106. return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
  107. }
  108. int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
  109. {
  110. u16 reg;
  111. int err;
  112. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
  113. if (err)
  114. return err;
  115. reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
  116. MV88E6XXX_PORT_MAC_CTL_LINK_UP);
  117. switch (link) {
  118. case LINK_FORCED_DOWN:
  119. reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
  120. break;
  121. case LINK_FORCED_UP:
  122. reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
  123. MV88E6XXX_PORT_MAC_CTL_LINK_UP;
  124. break;
  125. case LINK_UNFORCED:
  126. /* normal link detection */
  127. break;
  128. default:
  129. return -EINVAL;
  130. }
  131. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
  132. if (err)
  133. return err;
  134. dev_dbg(chip->dev, "p%d: %s link %s\n", port,
  135. reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
  136. reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
  137. return 0;
  138. }
  139. int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
  140. {
  141. u16 reg;
  142. int err;
  143. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
  144. if (err)
  145. return err;
  146. reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
  147. MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
  148. switch (dup) {
  149. case DUPLEX_HALF:
  150. reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
  151. break;
  152. case DUPLEX_FULL:
  153. reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
  154. MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
  155. break;
  156. case DUPLEX_UNFORCED:
  157. /* normal duplex detection */
  158. break;
  159. default:
  160. return -EOPNOTSUPP;
  161. }
  162. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
  163. if (err)
  164. return err;
  165. dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
  166. reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
  167. reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
  168. return 0;
  169. }
  170. static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
  171. int speed, bool alt_bit, bool force_bit)
  172. {
  173. u16 reg, ctrl;
  174. int err;
  175. switch (speed) {
  176. case 10:
  177. ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
  178. break;
  179. case 100:
  180. ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
  181. break;
  182. case 200:
  183. if (alt_bit)
  184. ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
  185. MV88E6390_PORT_MAC_CTL_ALTSPEED;
  186. else
  187. ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
  188. break;
  189. case 1000:
  190. ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
  191. break;
  192. case 2500:
  193. if (alt_bit)
  194. ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
  195. MV88E6390_PORT_MAC_CTL_ALTSPEED;
  196. else
  197. ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
  198. break;
  199. case 10000:
  200. /* all bits set, fall through... */
  201. case SPEED_UNFORCED:
  202. ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
  203. break;
  204. default:
  205. return -EOPNOTSUPP;
  206. }
  207. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
  208. if (err)
  209. return err;
  210. reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK;
  211. if (alt_bit)
  212. reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
  213. if (force_bit) {
  214. reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
  215. if (speed != SPEED_UNFORCED)
  216. ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
  217. }
  218. reg |= ctrl;
  219. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
  220. if (err)
  221. return err;
  222. if (speed)
  223. dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
  224. else
  225. dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
  226. return 0;
  227. }
  228. /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
  229. int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
  230. {
  231. if (speed == SPEED_MAX)
  232. speed = 200;
  233. if (speed > 200)
  234. return -EOPNOTSUPP;
  235. /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
  236. return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
  237. }
  238. /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
  239. int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
  240. {
  241. if (speed == SPEED_MAX)
  242. speed = 1000;
  243. if (speed == 200 || speed > 1000)
  244. return -EOPNOTSUPP;
  245. return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
  246. }
  247. /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
  248. int mv88e6341_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
  249. {
  250. if (speed == SPEED_MAX)
  251. speed = port < 5 ? 1000 : 2500;
  252. if (speed > 2500)
  253. return -EOPNOTSUPP;
  254. if (speed == 200 && port != 0)
  255. return -EOPNOTSUPP;
  256. if (speed == 2500 && port < 5)
  257. return -EOPNOTSUPP;
  258. return mv88e6xxx_port_set_speed(chip, port, speed, !port, true);
  259. }
  260. /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
  261. int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
  262. {
  263. if (speed == SPEED_MAX)
  264. speed = 1000;
  265. if (speed > 1000)
  266. return -EOPNOTSUPP;
  267. if (speed == 200 && port < 5)
  268. return -EOPNOTSUPP;
  269. return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
  270. }
  271. /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
  272. int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
  273. {
  274. if (speed == SPEED_MAX)
  275. speed = port < 9 ? 1000 : 2500;
  276. if (speed > 2500)
  277. return -EOPNOTSUPP;
  278. if (speed == 200 && port != 0)
  279. return -EOPNOTSUPP;
  280. if (speed == 2500 && port < 9)
  281. return -EOPNOTSUPP;
  282. return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
  283. }
  284. /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
  285. int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
  286. {
  287. if (speed == SPEED_MAX)
  288. speed = port < 9 ? 1000 : 10000;
  289. if (speed == 200 && port != 0)
  290. return -EOPNOTSUPP;
  291. if (speed >= 2500 && port < 9)
  292. return -EOPNOTSUPP;
  293. return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
  294. }
  295. int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
  296. phy_interface_t mode)
  297. {
  298. int lane;
  299. u16 cmode;
  300. u16 reg;
  301. int err;
  302. if (mode == PHY_INTERFACE_MODE_NA)
  303. return 0;
  304. if (port != 9 && port != 10)
  305. return -EOPNOTSUPP;
  306. switch (mode) {
  307. case PHY_INTERFACE_MODE_1000BASEX:
  308. cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
  309. break;
  310. case PHY_INTERFACE_MODE_SGMII:
  311. cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
  312. break;
  313. case PHY_INTERFACE_MODE_2500BASEX:
  314. cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
  315. break;
  316. case PHY_INTERFACE_MODE_XGMII:
  317. case PHY_INTERFACE_MODE_XAUI:
  318. cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
  319. break;
  320. case PHY_INTERFACE_MODE_RXAUI:
  321. cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
  322. break;
  323. default:
  324. cmode = 0;
  325. }
  326. /* cmode doesn't change, nothing to do for us */
  327. if (cmode == chip->ports[port].cmode)
  328. return 0;
  329. lane = mv88e6390x_serdes_get_lane(chip, port);
  330. if (lane < 0 && lane != -ENODEV)
  331. return lane;
  332. if (lane >= 0) {
  333. if (chip->ports[port].serdes_irq) {
  334. err = mv88e6390_serdes_irq_disable(chip, port, lane);
  335. if (err)
  336. return err;
  337. }
  338. err = mv88e6390x_serdes_power(chip, port, false);
  339. if (err)
  340. return err;
  341. }
  342. chip->ports[port].cmode = 0;
  343. if (cmode) {
  344. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
  345. if (err)
  346. return err;
  347. reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
  348. reg |= cmode;
  349. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
  350. if (err)
  351. return err;
  352. chip->ports[port].cmode = cmode;
  353. lane = mv88e6390x_serdes_get_lane(chip, port);
  354. if (lane < 0)
  355. return lane;
  356. err = mv88e6390x_serdes_power(chip, port, true);
  357. if (err)
  358. return err;
  359. if (chip->ports[port].serdes_irq) {
  360. err = mv88e6390_serdes_irq_enable(chip, port, lane);
  361. if (err)
  362. return err;
  363. }
  364. }
  365. return 0;
  366. }
  367. int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
  368. {
  369. int err;
  370. u16 reg;
  371. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
  372. if (err)
  373. return err;
  374. *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
  375. return 0;
  376. }
  377. int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
  378. {
  379. int err;
  380. u16 reg;
  381. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
  382. if (err)
  383. return err;
  384. *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
  385. return 0;
  386. }
  387. int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
  388. struct phylink_link_state *state)
  389. {
  390. int err;
  391. u16 reg;
  392. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
  393. if (err)
  394. return err;
  395. switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
  396. case MV88E6XXX_PORT_STS_SPEED_10:
  397. state->speed = SPEED_10;
  398. break;
  399. case MV88E6XXX_PORT_STS_SPEED_100:
  400. state->speed = SPEED_100;
  401. break;
  402. case MV88E6XXX_PORT_STS_SPEED_1000:
  403. state->speed = SPEED_1000;
  404. break;
  405. case MV88E6XXX_PORT_STS_SPEED_10000:
  406. if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
  407. MV88E6XXX_PORT_STS_CMODE_2500BASEX)
  408. state->speed = SPEED_2500;
  409. else
  410. state->speed = SPEED_10000;
  411. break;
  412. }
  413. state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
  414. DUPLEX_FULL : DUPLEX_HALF;
  415. state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
  416. state->an_enabled = 1;
  417. state->an_complete = state->link;
  418. return 0;
  419. }
  420. int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
  421. struct phylink_link_state *state)
  422. {
  423. if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
  424. u8 cmode = chip->ports[port].cmode;
  425. /* When a port is in "Cross-chip serdes" mode, it uses
  426. * 1000Base-X full duplex mode, but there is no automatic
  427. * link detection. Use the sync OK status for link (as it
  428. * would do for 1000Base-X mode.)
  429. */
  430. if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
  431. u16 mac;
  432. int err;
  433. err = mv88e6xxx_port_read(chip, port,
  434. MV88E6XXX_PORT_MAC_CTL, &mac);
  435. if (err)
  436. return err;
  437. state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
  438. state->an_enabled = 1;
  439. state->an_complete =
  440. !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
  441. state->duplex =
  442. state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
  443. state->speed =
  444. state->link ? SPEED_1000 : SPEED_UNKNOWN;
  445. return 0;
  446. }
  447. }
  448. return mv88e6352_port_link_state(chip, port, state);
  449. }
  450. /* Offset 0x02: Jamming Control
  451. *
  452. * Do not limit the period of time that this port can be paused for by
  453. * the remote end or the period of time that this port can pause the
  454. * remote end.
  455. */
  456. int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
  457. u8 out)
  458. {
  459. return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
  460. out << 8 | in);
  461. }
  462. int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
  463. u8 out)
  464. {
  465. int err;
  466. err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
  467. MV88E6390_PORT_FLOW_CTL_UPDATE |
  468. MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
  469. if (err)
  470. return err;
  471. return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
  472. MV88E6390_PORT_FLOW_CTL_UPDATE |
  473. MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
  474. }
  475. /* Offset 0x04: Port Control Register */
  476. static const char * const mv88e6xxx_port_state_names[] = {
  477. [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
  478. [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
  479. [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
  480. [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
  481. };
  482. int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
  483. {
  484. u16 reg;
  485. int err;
  486. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
  487. if (err)
  488. return err;
  489. reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
  490. switch (state) {
  491. case BR_STATE_DISABLED:
  492. state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
  493. break;
  494. case BR_STATE_BLOCKING:
  495. case BR_STATE_LISTENING:
  496. state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
  497. break;
  498. case BR_STATE_LEARNING:
  499. state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
  500. break;
  501. case BR_STATE_FORWARDING:
  502. state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
  503. break;
  504. default:
  505. return -EINVAL;
  506. }
  507. reg |= state;
  508. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
  509. if (err)
  510. return err;
  511. dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
  512. mv88e6xxx_port_state_names[state]);
  513. return 0;
  514. }
  515. int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
  516. enum mv88e6xxx_egress_mode mode)
  517. {
  518. int err;
  519. u16 reg;
  520. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
  521. if (err)
  522. return err;
  523. reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
  524. switch (mode) {
  525. case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
  526. reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
  527. break;
  528. case MV88E6XXX_EGRESS_MODE_UNTAGGED:
  529. reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
  530. break;
  531. case MV88E6XXX_EGRESS_MODE_TAGGED:
  532. reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
  533. break;
  534. case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
  535. reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
  536. break;
  537. default:
  538. return -EINVAL;
  539. }
  540. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
  541. }
  542. int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
  543. enum mv88e6xxx_frame_mode mode)
  544. {
  545. int err;
  546. u16 reg;
  547. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
  548. if (err)
  549. return err;
  550. reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
  551. switch (mode) {
  552. case MV88E6XXX_FRAME_MODE_NORMAL:
  553. reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
  554. break;
  555. case MV88E6XXX_FRAME_MODE_DSA:
  556. reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
  557. break;
  558. default:
  559. return -EINVAL;
  560. }
  561. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
  562. }
  563. int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
  564. enum mv88e6xxx_frame_mode mode)
  565. {
  566. int err;
  567. u16 reg;
  568. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
  569. if (err)
  570. return err;
  571. reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
  572. switch (mode) {
  573. case MV88E6XXX_FRAME_MODE_NORMAL:
  574. reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
  575. break;
  576. case MV88E6XXX_FRAME_MODE_DSA:
  577. reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
  578. break;
  579. case MV88E6XXX_FRAME_MODE_PROVIDER:
  580. reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
  581. break;
  582. case MV88E6XXX_FRAME_MODE_ETHERTYPE:
  583. reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
  584. break;
  585. default:
  586. return -EINVAL;
  587. }
  588. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
  589. }
  590. static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
  591. int port, bool unicast)
  592. {
  593. int err;
  594. u16 reg;
  595. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
  596. if (err)
  597. return err;
  598. if (unicast)
  599. reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
  600. else
  601. reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
  602. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
  603. }
  604. int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
  605. bool unicast, bool multicast)
  606. {
  607. int err;
  608. u16 reg;
  609. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
  610. if (err)
  611. return err;
  612. reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
  613. if (unicast && multicast)
  614. reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
  615. else if (unicast)
  616. reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
  617. else if (multicast)
  618. reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
  619. else
  620. reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
  621. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
  622. }
  623. /* Offset 0x05: Port Control 1 */
  624. int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
  625. bool message_port)
  626. {
  627. u16 val;
  628. int err;
  629. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
  630. if (err)
  631. return err;
  632. if (message_port)
  633. val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
  634. else
  635. val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
  636. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
  637. }
  638. /* Offset 0x06: Port Based VLAN Map */
  639. int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
  640. {
  641. const u16 mask = mv88e6xxx_port_mask(chip);
  642. u16 reg;
  643. int err;
  644. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
  645. if (err)
  646. return err;
  647. reg &= ~mask;
  648. reg |= map & mask;
  649. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
  650. if (err)
  651. return err;
  652. dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
  653. return 0;
  654. }
  655. int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
  656. {
  657. const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
  658. u16 reg;
  659. int err;
  660. /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
  661. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
  662. if (err)
  663. return err;
  664. *fid = (reg & 0xf000) >> 12;
  665. /* Port's default FID upper bits are located in reg 0x05, offset 0 */
  666. if (upper_mask) {
  667. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
  668. &reg);
  669. if (err)
  670. return err;
  671. *fid |= (reg & upper_mask) << 4;
  672. }
  673. return 0;
  674. }
  675. int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
  676. {
  677. const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
  678. u16 reg;
  679. int err;
  680. if (fid >= mv88e6xxx_num_databases(chip))
  681. return -EINVAL;
  682. /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
  683. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
  684. if (err)
  685. return err;
  686. reg &= 0x0fff;
  687. reg |= (fid & 0x000f) << 12;
  688. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
  689. if (err)
  690. return err;
  691. /* Port's default FID upper bits are located in reg 0x05, offset 0 */
  692. if (upper_mask) {
  693. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
  694. &reg);
  695. if (err)
  696. return err;
  697. reg &= ~upper_mask;
  698. reg |= (fid >> 4) & upper_mask;
  699. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
  700. reg);
  701. if (err)
  702. return err;
  703. }
  704. dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
  705. return 0;
  706. }
  707. /* Offset 0x07: Default Port VLAN ID & Priority */
  708. int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
  709. {
  710. u16 reg;
  711. int err;
  712. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
  713. &reg);
  714. if (err)
  715. return err;
  716. *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
  717. return 0;
  718. }
  719. int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
  720. {
  721. u16 reg;
  722. int err;
  723. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
  724. &reg);
  725. if (err)
  726. return err;
  727. reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
  728. reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
  729. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
  730. reg);
  731. if (err)
  732. return err;
  733. dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
  734. return 0;
  735. }
  736. /* Offset 0x08: Port Control 2 Register */
  737. static const char * const mv88e6xxx_port_8021q_mode_names[] = {
  738. [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
  739. [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
  740. [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
  741. [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
  742. };
  743. static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
  744. int port, bool multicast)
  745. {
  746. int err;
  747. u16 reg;
  748. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
  749. if (err)
  750. return err;
  751. if (multicast)
  752. reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
  753. else
  754. reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
  755. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
  756. }
  757. int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
  758. bool unicast, bool multicast)
  759. {
  760. int err;
  761. err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
  762. if (err)
  763. return err;
  764. return mv88e6185_port_set_default_forward(chip, port, multicast);
  765. }
  766. int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
  767. int upstream_port)
  768. {
  769. int err;
  770. u16 reg;
  771. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
  772. if (err)
  773. return err;
  774. reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
  775. reg |= upstream_port;
  776. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
  777. }
  778. int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
  779. u16 mode)
  780. {
  781. u16 reg;
  782. int err;
  783. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
  784. if (err)
  785. return err;
  786. reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
  787. reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
  788. err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
  789. if (err)
  790. return err;
  791. dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
  792. mv88e6xxx_port_8021q_mode_names[mode]);
  793. return 0;
  794. }
  795. int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
  796. {
  797. u16 reg;
  798. int err;
  799. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
  800. if (err)
  801. return err;
  802. reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
  803. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
  804. }
  805. int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
  806. size_t size)
  807. {
  808. u16 reg;
  809. int err;
  810. err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
  811. if (err)
  812. return err;
  813. reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
  814. if (size <= 1522)
  815. reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
  816. else if (size <= 2048)
  817. reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
  818. else if (size <= 10240)
  819. reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
  820. else
  821. return -ERANGE;
  822. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
  823. }
  824. /* Offset 0x09: Port Rate Control */
  825. int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
  826. {
  827. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
  828. 0x0000);
  829. }
  830. int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
  831. {
  832. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
  833. 0x0001);
  834. }
  835. /* Offset 0x0C: Port ATU Control */
  836. int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
  837. {
  838. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
  839. }
  840. /* Offset 0x0D: (Priority) Override Register */
  841. int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
  842. {
  843. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
  844. }
  845. /* Offset 0x0f: Port Ether type */
  846. int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
  847. u16 etype)
  848. {
  849. return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
  850. }
  851. /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
  852. * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
  853. */
  854. int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
  855. {
  856. int err;
  857. /* Use a direct priority mapping for all IEEE tagged frames */
  858. err = mv88e6xxx_port_write(chip, port,
  859. MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
  860. 0x3210);
  861. if (err)
  862. return err;
  863. return mv88e6xxx_port_write(chip, port,
  864. MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
  865. 0x7654);
  866. }
  867. static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
  868. int port, u16 table, u8 ptr, u16 data)
  869. {
  870. u16 reg;
  871. reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
  872. (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
  873. (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
  874. return mv88e6xxx_port_write(chip, port,
  875. MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
  876. }
  877. int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
  878. {
  879. int err, i;
  880. u16 table;
  881. for (i = 0; i <= 7; i++) {
  882. table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
  883. err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
  884. (i | i << 4));
  885. if (err)
  886. return err;
  887. table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
  888. err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
  889. if (err)
  890. return err;
  891. table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
  892. err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
  893. if (err)
  894. return err;
  895. table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
  896. err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
  897. if (err)
  898. return err;
  899. }
  900. return 0;
  901. }