global1.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Marvell 88E6xxx Switch Global (1) Registers support
  4. *
  5. * Copyright (c) 2008 Marvell Semiconductor
  6. *
  7. * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
  8. * Vivien Didelot <[email protected]>
  9. */
  10. #include <linux/bitfield.h>
  11. #include "chip.h"
  12. #include "global1.h"
  13. int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
  14. {
  15. int addr = chip->info->global1_addr;
  16. return mv88e6xxx_read(chip, addr, reg, val);
  17. }
  18. int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
  19. {
  20. int addr = chip->info->global1_addr;
  21. return mv88e6xxx_write(chip, addr, reg, val);
  22. }
  23. int mv88e6xxx_g1_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
  24. bit, int val)
  25. {
  26. return mv88e6xxx_wait_bit(chip, chip->info->global1_addr, reg,
  27. bit, val);
  28. }
  29. int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
  30. u16 mask, u16 val)
  31. {
  32. return mv88e6xxx_wait_mask(chip, chip->info->global1_addr, reg,
  33. mask, val);
  34. }
  35. /* Offset 0x00: Switch Global Status Register */
  36. static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip)
  37. {
  38. return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
  39. MV88E6185_G1_STS_PPU_STATE_MASK,
  40. MV88E6185_G1_STS_PPU_STATE_DISABLED);
  41. }
  42. static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
  43. {
  44. return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
  45. MV88E6185_G1_STS_PPU_STATE_MASK,
  46. MV88E6185_G1_STS_PPU_STATE_POLLING);
  47. }
  48. static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
  49. {
  50. int bit = __bf_shf(MV88E6352_G1_STS_PPU_STATE);
  51. return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
  52. }
  53. static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip)
  54. {
  55. int bit = __bf_shf(MV88E6XXX_G1_STS_INIT_READY);
  56. /* Wait up to 1 second for the switch to be ready. The InitReady bit 11
  57. * is set to a one when all units inside the device (ATU, VTU, etc.)
  58. * have finished their initialization and are ready to accept frames.
  59. */
  60. return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
  61. }
  62. /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
  63. * Offset 0x02: Switch MAC Address Register Bytes 2 & 3
  64. * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
  65. */
  66. int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
  67. {
  68. u16 reg;
  69. int err;
  70. reg = (addr[0] << 8) | addr[1];
  71. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_01, reg);
  72. if (err)
  73. return err;
  74. reg = (addr[2] << 8) | addr[3];
  75. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_23, reg);
  76. if (err)
  77. return err;
  78. reg = (addr[4] << 8) | addr[5];
  79. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_45, reg);
  80. if (err)
  81. return err;
  82. return 0;
  83. }
  84. /* Offset 0x04: Switch Global Control Register */
  85. int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip)
  86. {
  87. u16 val;
  88. int err;
  89. /* Set the SWReset bit 15 along with the PPUEn bit 14, to also restart
  90. * the PPU, including re-doing PHY detection and initialization
  91. */
  92. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
  93. if (err)
  94. return err;
  95. val |= MV88E6XXX_G1_CTL1_SW_RESET;
  96. val |= MV88E6XXX_G1_CTL1_PPU_ENABLE;
  97. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
  98. if (err)
  99. return err;
  100. err = mv88e6xxx_g1_wait_init_ready(chip);
  101. if (err)
  102. return err;
  103. return mv88e6185_g1_wait_ppu_polling(chip);
  104. }
  105. int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip)
  106. {
  107. u16 val;
  108. int err;
  109. /* Set the SWReset bit 15 */
  110. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
  111. if (err)
  112. return err;
  113. val |= MV88E6XXX_G1_CTL1_SW_RESET;
  114. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
  115. if (err)
  116. return err;
  117. return mv88e6xxx_g1_wait_init_ready(chip);
  118. }
  119. int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip)
  120. {
  121. int err;
  122. err = mv88e6250_g1_reset(chip);
  123. if (err)
  124. return err;
  125. return mv88e6352_g1_wait_ppu_polling(chip);
  126. }
  127. int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip)
  128. {
  129. u16 val;
  130. int err;
  131. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
  132. if (err)
  133. return err;
  134. val |= MV88E6XXX_G1_CTL1_PPU_ENABLE;
  135. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
  136. if (err)
  137. return err;
  138. return mv88e6185_g1_wait_ppu_polling(chip);
  139. }
  140. int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip)
  141. {
  142. u16 val;
  143. int err;
  144. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
  145. if (err)
  146. return err;
  147. val &= ~MV88E6XXX_G1_CTL1_PPU_ENABLE;
  148. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
  149. if (err)
  150. return err;
  151. return mv88e6185_g1_wait_ppu_disabled(chip);
  152. }
  153. int mv88e6185_g1_set_max_frame_size(struct mv88e6xxx_chip *chip, int mtu)
  154. {
  155. u16 val;
  156. int err;
  157. mtu += ETH_HLEN + ETH_FCS_LEN;
  158. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
  159. if (err)
  160. return err;
  161. val &= ~MV88E6185_G1_CTL1_MAX_FRAME_1632;
  162. if (mtu > 1518)
  163. val |= MV88E6185_G1_CTL1_MAX_FRAME_1632;
  164. return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
  165. }
  166. /* Offset 0x10: IP-PRI Mapping Register 0
  167. * Offset 0x11: IP-PRI Mapping Register 1
  168. * Offset 0x12: IP-PRI Mapping Register 2
  169. * Offset 0x13: IP-PRI Mapping Register 3
  170. * Offset 0x14: IP-PRI Mapping Register 4
  171. * Offset 0x15: IP-PRI Mapping Register 5
  172. * Offset 0x16: IP-PRI Mapping Register 6
  173. * Offset 0x17: IP-PRI Mapping Register 7
  174. */
  175. int mv88e6085_g1_ip_pri_map(struct mv88e6xxx_chip *chip)
  176. {
  177. int err;
  178. /* Reset the IP TOS/DiffServ/Traffic priorities to defaults */
  179. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_0, 0x0000);
  180. if (err)
  181. return err;
  182. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_1, 0x0000);
  183. if (err)
  184. return err;
  185. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_2, 0x5555);
  186. if (err)
  187. return err;
  188. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_3, 0x5555);
  189. if (err)
  190. return err;
  191. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_4, 0xaaaa);
  192. if (err)
  193. return err;
  194. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_5, 0xaaaa);
  195. if (err)
  196. return err;
  197. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_6, 0xffff);
  198. if (err)
  199. return err;
  200. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_7, 0xffff);
  201. if (err)
  202. return err;
  203. return 0;
  204. }
  205. /* Offset 0x18: IEEE-PRI Register */
  206. int mv88e6085_g1_ieee_pri_map(struct mv88e6xxx_chip *chip)
  207. {
  208. /* Reset the IEEE Tag priorities to defaults */
  209. return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa41);
  210. }
  211. int mv88e6250_g1_ieee_pri_map(struct mv88e6xxx_chip *chip)
  212. {
  213. /* Reset the IEEE Tag priorities to defaults */
  214. return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa50);
  215. }
  216. /* Offset 0x1a: Monitor Control */
  217. /* Offset 0x1a: Monitor & MGMT Control on some devices */
  218. int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip,
  219. enum mv88e6xxx_egress_direction direction,
  220. int port)
  221. {
  222. u16 reg;
  223. int err;
  224. err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, &reg);
  225. if (err)
  226. return err;
  227. switch (direction) {
  228. case MV88E6XXX_EGRESS_DIR_INGRESS:
  229. reg &= ~MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK;
  230. reg |= port <<
  231. __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK);
  232. break;
  233. case MV88E6XXX_EGRESS_DIR_EGRESS:
  234. reg &= ~MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK;
  235. reg |= port <<
  236. __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
  237. break;
  238. default:
  239. return -EINVAL;
  240. }
  241. return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
  242. }
  243. /* Older generations also call this the ARP destination. It has been
  244. * generalized in more modern devices such that more than ARP can
  245. * egress it
  246. */
  247. int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
  248. {
  249. u16 reg;
  250. int err;
  251. err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, &reg);
  252. if (err)
  253. return err;
  254. reg &= ~MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK;
  255. reg |= port << __bf_shf(MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK);
  256. return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
  257. }
  258. static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip *chip,
  259. u16 pointer, u8 data)
  260. {
  261. u16 reg;
  262. reg = MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE | pointer | data;
  263. return mv88e6xxx_g1_write(chip, MV88E6390_G1_MONITOR_MGMT_CTL, reg);
  264. }
  265. int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip,
  266. enum mv88e6xxx_egress_direction direction,
  267. int port)
  268. {
  269. u16 ptr;
  270. switch (direction) {
  271. case MV88E6XXX_EGRESS_DIR_INGRESS:
  272. ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST;
  273. break;
  274. case MV88E6XXX_EGRESS_DIR_EGRESS:
  275. ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST;
  276. break;
  277. default:
  278. return -EINVAL;
  279. }
  280. return mv88e6390_g1_monitor_write(chip, ptr, port);
  281. }
  282. int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
  283. {
  284. u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST;
  285. /* Use the default high priority for management frames sent to
  286. * the CPU.
  287. */
  288. port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI;
  289. return mv88e6390_g1_monitor_write(chip, ptr, port);
  290. }
  291. int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
  292. {
  293. u16 ptr;
  294. int err;
  295. /* 01:80:c2:00:00:00-01:80:c2:00:00:07 are Management */
  296. ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XLO;
  297. err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
  298. if (err)
  299. return err;
  300. /* 01:80:c2:00:00:08-01:80:c2:00:00:0f are Management */
  301. ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XHI;
  302. err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
  303. if (err)
  304. return err;
  305. /* 01:80:c2:00:00:20-01:80:c2:00:00:27 are Management */
  306. ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XLO;
  307. err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
  308. if (err)
  309. return err;
  310. /* 01:80:c2:00:00:28-01:80:c2:00:00:2f are Management */
  311. ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XHI;
  312. err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
  313. if (err)
  314. return err;
  315. return 0;
  316. }
  317. /* Offset 0x1c: Global Control 2 */
  318. static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip *chip, u16 mask,
  319. u16 val)
  320. {
  321. u16 reg;
  322. int err;
  323. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL2, &reg);
  324. if (err)
  325. return err;
  326. reg &= ~mask;
  327. reg |= val & mask;
  328. return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2, reg);
  329. }
  330. int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port)
  331. {
  332. const u16 mask = MV88E6185_G1_CTL2_CASCADE_PORT_MASK;
  333. return mv88e6xxx_g1_ctl2_mask(chip, mask, port << __bf_shf(mask));
  334. }
  335. int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip *chip)
  336. {
  337. return mv88e6xxx_g1_ctl2_mask(chip, MV88E6085_G1_CTL2_P10RM |
  338. MV88E6085_G1_CTL2_RM_ENABLE, 0);
  339. }
  340. int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip *chip)
  341. {
  342. return mv88e6xxx_g1_ctl2_mask(chip, MV88E6352_G1_CTL2_RMU_MODE_MASK,
  343. MV88E6352_G1_CTL2_RMU_MODE_DISABLED);
  344. }
  345. int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip *chip)
  346. {
  347. return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_RMU_MODE_MASK,
  348. MV88E6390_G1_CTL2_RMU_MODE_DISABLED);
  349. }
  350. int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
  351. {
  352. return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_HIST_MODE_MASK,
  353. MV88E6390_G1_CTL2_HIST_MODE_RX |
  354. MV88E6390_G1_CTL2_HIST_MODE_TX);
  355. }
  356. int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index)
  357. {
  358. return mv88e6xxx_g1_ctl2_mask(chip,
  359. MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK,
  360. index);
  361. }
  362. /* Offset 0x1d: Statistics Operation 2 */
  363. static int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip)
  364. {
  365. int bit = __bf_shf(MV88E6XXX_G1_STATS_OP_BUSY);
  366. return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STATS_OP, bit, 0);
  367. }
  368. int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
  369. {
  370. u16 val;
  371. int err;
  372. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val);
  373. if (err)
  374. return err;
  375. val |= MV88E6XXX_G1_STATS_OP_HIST_RX_TX;
  376. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val);
  377. return err;
  378. }
  379. int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
  380. {
  381. int err;
  382. /* Snapshot the hardware statistics counters for this port. */
  383. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP,
  384. MV88E6XXX_G1_STATS_OP_BUSY |
  385. MV88E6XXX_G1_STATS_OP_CAPTURE_PORT |
  386. MV88E6XXX_G1_STATS_OP_HIST_RX_TX | port);
  387. if (err)
  388. return err;
  389. /* Wait for the snapshotting to complete. */
  390. return mv88e6xxx_g1_stats_wait(chip);
  391. }
  392. int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
  393. {
  394. port = (port + 1) << 5;
  395. return mv88e6xxx_g1_stats_snapshot(chip, port);
  396. }
  397. int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
  398. {
  399. int err;
  400. port = (port + 1) << 5;
  401. /* Snapshot the hardware statistics counters for this port. */
  402. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP,
  403. MV88E6XXX_G1_STATS_OP_BUSY |
  404. MV88E6XXX_G1_STATS_OP_CAPTURE_PORT | port);
  405. if (err)
  406. return err;
  407. /* Wait for the snapshotting to complete. */
  408. return mv88e6xxx_g1_stats_wait(chip);
  409. }
  410. void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val)
  411. {
  412. u32 value;
  413. u16 reg;
  414. int err;
  415. *val = 0;
  416. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP,
  417. MV88E6XXX_G1_STATS_OP_BUSY |
  418. MV88E6XXX_G1_STATS_OP_READ_CAPTURED | stat);
  419. if (err)
  420. return;
  421. err = mv88e6xxx_g1_stats_wait(chip);
  422. if (err)
  423. return;
  424. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_32, &reg);
  425. if (err)
  426. return;
  427. value = reg << 16;
  428. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_01, &reg);
  429. if (err)
  430. return;
  431. *val = value | reg;
  432. }
  433. int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip)
  434. {
  435. int err;
  436. u16 val;
  437. err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val);
  438. if (err)
  439. return err;
  440. /* Keep the histogram mode bits */
  441. val &= MV88E6XXX_G1_STATS_OP_HIST_RX_TX;
  442. val |= MV88E6XXX_G1_STATS_OP_BUSY | MV88E6XXX_G1_STATS_OP_FLUSH_ALL;
  443. err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val);
  444. if (err)
  445. return err;
  446. /* Wait for the flush to complete. */
  447. return mv88e6xxx_g1_stats_wait(chip);
  448. }