global2.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  1. /*
  2. * Marvell 88E6xxx Switch Global 2 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/interrupt.h>
  16. #include <linux/irqdomain.h>
  17. #include "chip.h"
  18. #include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
  19. #include "global2.h"
  20. int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
  21. {
  22. return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
  23. }
  24. int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
  25. {
  26. return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
  27. }
  28. int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
  29. {
  30. return mv88e6xxx_update(chip, chip->info->global2_addr, reg, update);
  31. }
  32. int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
  33. {
  34. return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
  35. }
  36. /* Offset 0x00: Interrupt Source Register */
  37. static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip *chip, u16 *src)
  38. {
  39. /* Read (and clear most of) the Interrupt Source bits */
  40. return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SRC, src);
  41. }
  42. /* Offset 0x01: Interrupt Mask Register */
  43. static int mv88e6xxx_g2_int_mask(struct mv88e6xxx_chip *chip, u16 mask)
  44. {
  45. return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, mask);
  46. }
  47. /* Offset 0x02: Management Enable 2x */
  48. static int mv88e6xxx_g2_mgmt_enable_2x(struct mv88e6xxx_chip *chip, u16 en2x)
  49. {
  50. return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, en2x);
  51. }
  52. /* Offset 0x03: Management Enable 0x */
  53. static int mv88e6xxx_g2_mgmt_enable_0x(struct mv88e6xxx_chip *chip, u16 en0x)
  54. {
  55. return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X, en0x);
  56. }
  57. /* Offset 0x05: Switch Management Register */
  58. static int mv88e6xxx_g2_switch_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip,
  59. bool enable)
  60. {
  61. u16 val;
  62. int err;
  63. err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SWITCH_MGMT, &val);
  64. if (err)
  65. return err;
  66. if (enable)
  67. val |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
  68. else
  69. val &= ~MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
  70. return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, val);
  71. }
  72. int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
  73. {
  74. int err;
  75. /* Consider the frames with reserved multicast destination
  76. * addresses matching 01:80:c2:00:00:0x as MGMT.
  77. */
  78. err = mv88e6xxx_g2_mgmt_enable_0x(chip, 0xffff);
  79. if (err)
  80. return err;
  81. return mv88e6xxx_g2_switch_mgmt_rsvd2cpu(chip, true);
  82. }
  83. int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
  84. {
  85. int err;
  86. /* Consider the frames with reserved multicast destination
  87. * addresses matching 01:80:c2:00:00:2x as MGMT.
  88. */
  89. err = mv88e6xxx_g2_mgmt_enable_2x(chip, 0xffff);
  90. if (err)
  91. return err;
  92. return mv88e6185_g2_mgmt_rsvd2cpu(chip);
  93. }
  94. /* Offset 0x06: Device Mapping Table register */
  95. static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip,
  96. int target, int port)
  97. {
  98. u16 val = (target << 8) | (port & 0xf);
  99. return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_DEVICE_MAPPING, val);
  100. }
  101. static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip)
  102. {
  103. int target, port;
  104. int err;
  105. /* Initialize the routing port to the 32 possible target devices */
  106. for (target = 0; target < 32; ++target) {
  107. port = 0xf;
  108. if (target < DSA_MAX_SWITCHES) {
  109. port = chip->ds->rtable[target];
  110. if (port == DSA_RTABLE_NONE)
  111. port = 0xf;
  112. }
  113. err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
  114. if (err)
  115. break;
  116. }
  117. return err;
  118. }
  119. /* Offset 0x07: Trunk Mask Table register */
  120. static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
  121. bool hash, u16 mask)
  122. {
  123. u16 val = (num << 12) | (mask & mv88e6xxx_port_mask(chip));
  124. if (hash)
  125. val |= MV88E6XXX_G2_TRUNK_MASK_HASH;
  126. return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MASK, val);
  127. }
  128. /* Offset 0x08: Trunk Mapping Table register */
  129. static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
  130. u16 map)
  131. {
  132. const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
  133. u16 val = (id << 11) | (map & port_mask);
  134. return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MAPPING, val);
  135. }
  136. static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip)
  137. {
  138. const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
  139. int i, err;
  140. /* Clear all eight possible Trunk Mask vectors */
  141. for (i = 0; i < 8; ++i) {
  142. err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask);
  143. if (err)
  144. return err;
  145. }
  146. /* Clear all sixteen possible Trunk ID routing vectors */
  147. for (i = 0; i < 16; ++i) {
  148. err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0);
  149. if (err)
  150. return err;
  151. }
  152. return 0;
  153. }
  154. /* Offset 0x09: Ingress Rate Command register
  155. * Offset 0x0A: Ingress Rate Data register
  156. */
  157. static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
  158. {
  159. return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_IRL_CMD,
  160. MV88E6XXX_G2_IRL_CMD_BUSY);
  161. }
  162. static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
  163. int res, int reg)
  164. {
  165. int err;
  166. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_IRL_CMD,
  167. MV88E6XXX_G2_IRL_CMD_BUSY | op | (port << 8) |
  168. (res << 5) | reg);
  169. if (err)
  170. return err;
  171. return mv88e6xxx_g2_irl_wait(chip);
  172. }
  173. int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
  174. {
  175. return mv88e6xxx_g2_irl_op(chip, MV88E6352_G2_IRL_CMD_OP_INIT_ALL, port,
  176. 0, 0);
  177. }
  178. int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
  179. {
  180. return mv88e6xxx_g2_irl_op(chip, MV88E6390_G2_IRL_CMD_OP_INIT_ALL, port,
  181. 0, 0);
  182. }
  183. /* Offset 0x0B: Cross-chip Port VLAN (Addr) Register
  184. * Offset 0x0C: Cross-chip Port VLAN Data Register
  185. */
  186. static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
  187. {
  188. return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_PVT_ADDR,
  189. MV88E6XXX_G2_PVT_ADDR_BUSY);
  190. }
  191. static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
  192. int src_port, u16 op)
  193. {
  194. int err;
  195. /* 9-bit Cross-chip PVT pointer: with MV88E6XXX_G2_MISC_5_BIT_PORT
  196. * cleared, source device is 5-bit, source port is 4-bit.
  197. */
  198. op |= MV88E6XXX_G2_PVT_ADDR_BUSY;
  199. op |= (src_dev & 0x1f) << 4;
  200. op |= (src_port & 0xf);
  201. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_ADDR, op);
  202. if (err)
  203. return err;
  204. return mv88e6xxx_g2_pvt_op_wait(chip);
  205. }
  206. int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
  207. int src_port, u16 data)
  208. {
  209. int err;
  210. err = mv88e6xxx_g2_pvt_op_wait(chip);
  211. if (err)
  212. return err;
  213. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_DATA, data);
  214. if (err)
  215. return err;
  216. return mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
  217. MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN);
  218. }
  219. /* Offset 0x0D: Switch MAC/WoL/WoF register */
  220. static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
  221. unsigned int pointer, u8 data)
  222. {
  223. u16 val = (pointer << 8) | data;
  224. return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_SWITCH_MAC, val);
  225. }
  226. int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
  227. {
  228. int i, err;
  229. for (i = 0; i < 6; i++) {
  230. err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]);
  231. if (err)
  232. break;
  233. }
  234. return err;
  235. }
  236. /* Offset 0x0F: Priority Override Table */
  237. static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
  238. u8 data)
  239. {
  240. u16 val = (pointer << 8) | (data & 0x7);
  241. return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_PRIO_OVERRIDE, val);
  242. }
  243. int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
  244. {
  245. int i, err;
  246. /* Clear all sixteen possible Priority Override entries */
  247. for (i = 0; i < 16; i++) {
  248. err = mv88e6xxx_g2_pot_write(chip, i, 0);
  249. if (err)
  250. break;
  251. }
  252. return err;
  253. }
  254. /* Offset 0x14: EEPROM Command
  255. * Offset 0x15: EEPROM Data (for 16-bit data access)
  256. * Offset 0x15: EEPROM Addr (for 8-bit data access)
  257. */
  258. static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
  259. {
  260. return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_EEPROM_CMD,
  261. MV88E6XXX_G2_EEPROM_CMD_BUSY |
  262. MV88E6XXX_G2_EEPROM_CMD_RUNNING);
  263. }
  264. static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
  265. {
  266. int err;
  267. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
  268. MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
  269. if (err)
  270. return err;
  271. return mv88e6xxx_g2_eeprom_wait(chip);
  272. }
  273. static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
  274. u16 addr, u8 *data)
  275. {
  276. u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
  277. int err;
  278. err = mv88e6xxx_g2_eeprom_wait(chip);
  279. if (err)
  280. return err;
  281. err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
  282. if (err)
  283. return err;
  284. err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
  285. if (err)
  286. return err;
  287. err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
  288. if (err)
  289. return err;
  290. *data = cmd & 0xff;
  291. return 0;
  292. }
  293. static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
  294. u16 addr, u8 data)
  295. {
  296. u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
  297. MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
  298. int err;
  299. err = mv88e6xxx_g2_eeprom_wait(chip);
  300. if (err)
  301. return err;
  302. err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
  303. if (err)
  304. return err;
  305. return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
  306. }
  307. static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
  308. u8 addr, u16 *data)
  309. {
  310. u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
  311. int err;
  312. err = mv88e6xxx_g2_eeprom_wait(chip);
  313. if (err)
  314. return err;
  315. err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
  316. if (err)
  317. return err;
  318. return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
  319. }
  320. static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
  321. u8 addr, u16 data)
  322. {
  323. u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
  324. int err;
  325. err = mv88e6xxx_g2_eeprom_wait(chip);
  326. if (err)
  327. return err;
  328. err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
  329. if (err)
  330. return err;
  331. return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
  332. }
  333. int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
  334. struct ethtool_eeprom *eeprom, u8 *data)
  335. {
  336. unsigned int offset = eeprom->offset;
  337. unsigned int len = eeprom->len;
  338. int err;
  339. eeprom->len = 0;
  340. while (len) {
  341. err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
  342. if (err)
  343. return err;
  344. eeprom->len++;
  345. offset++;
  346. data++;
  347. len--;
  348. }
  349. return 0;
  350. }
  351. int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
  352. struct ethtool_eeprom *eeprom, u8 *data)
  353. {
  354. unsigned int offset = eeprom->offset;
  355. unsigned int len = eeprom->len;
  356. int err;
  357. eeprom->len = 0;
  358. while (len) {
  359. err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
  360. if (err)
  361. return err;
  362. eeprom->len++;
  363. offset++;
  364. data++;
  365. len--;
  366. }
  367. return 0;
  368. }
  369. int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
  370. struct ethtool_eeprom *eeprom, u8 *data)
  371. {
  372. unsigned int offset = eeprom->offset;
  373. unsigned int len = eeprom->len;
  374. u16 val;
  375. int err;
  376. eeprom->len = 0;
  377. if (offset & 1) {
  378. err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
  379. if (err)
  380. return err;
  381. *data++ = (val >> 8) & 0xff;
  382. offset++;
  383. len--;
  384. eeprom->len++;
  385. }
  386. while (len >= 2) {
  387. err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
  388. if (err)
  389. return err;
  390. *data++ = val & 0xff;
  391. *data++ = (val >> 8) & 0xff;
  392. offset += 2;
  393. len -= 2;
  394. eeprom->len += 2;
  395. }
  396. if (len) {
  397. err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
  398. if (err)
  399. return err;
  400. *data++ = val & 0xff;
  401. offset++;
  402. len--;
  403. eeprom->len++;
  404. }
  405. return 0;
  406. }
  407. int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
  408. struct ethtool_eeprom *eeprom, u8 *data)
  409. {
  410. unsigned int offset = eeprom->offset;
  411. unsigned int len = eeprom->len;
  412. u16 val;
  413. int err;
  414. /* Ensure the RO WriteEn bit is set */
  415. err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
  416. if (err)
  417. return err;
  418. if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
  419. return -EROFS;
  420. eeprom->len = 0;
  421. if (offset & 1) {
  422. err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
  423. if (err)
  424. return err;
  425. val = (*data++ << 8) | (val & 0xff);
  426. err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
  427. if (err)
  428. return err;
  429. offset++;
  430. len--;
  431. eeprom->len++;
  432. }
  433. while (len >= 2) {
  434. val = *data++;
  435. val |= *data++ << 8;
  436. err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
  437. if (err)
  438. return err;
  439. offset += 2;
  440. len -= 2;
  441. eeprom->len += 2;
  442. }
  443. if (len) {
  444. err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
  445. if (err)
  446. return err;
  447. val = (val & 0xff00) | *data++;
  448. err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
  449. if (err)
  450. return err;
  451. offset++;
  452. len--;
  453. eeprom->len++;
  454. }
  455. return 0;
  456. }
  457. /* Offset 0x18: SMI PHY Command Register
  458. * Offset 0x19: SMI PHY Data Register
  459. */
  460. static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
  461. {
  462. return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_SMI_PHY_CMD,
  463. MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
  464. }
  465. static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
  466. {
  467. int err;
  468. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
  469. MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
  470. if (err)
  471. return err;
  472. return mv88e6xxx_g2_smi_phy_wait(chip);
  473. }
  474. static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
  475. bool external, bool c45, u16 op, int dev,
  476. int reg)
  477. {
  478. u16 cmd = op;
  479. if (external)
  480. cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
  481. else
  482. cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL; /* empty mask */
  483. if (c45)
  484. cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45; /* empty mask */
  485. else
  486. cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;
  487. dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
  488. cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
  489. cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;
  490. return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
  491. }
  492. static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
  493. bool external, u16 op, int dev,
  494. int reg)
  495. {
  496. return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
  497. }
  498. /* IEEE 802.3 Clause 22 Read Data Register */
  499. static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
  500. bool external, int dev, int reg,
  501. u16 *data)
  502. {
  503. u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
  504. int err;
  505. err = mv88e6xxx_g2_smi_phy_wait(chip);
  506. if (err)
  507. return err;
  508. err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
  509. if (err)
  510. return err;
  511. return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
  512. }
  513. /* IEEE 802.3 Clause 22 Write Data Register */
  514. static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
  515. bool external, int dev, int reg,
  516. u16 data)
  517. {
  518. u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
  519. int err;
  520. err = mv88e6xxx_g2_smi_phy_wait(chip);
  521. if (err)
  522. return err;
  523. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
  524. if (err)
  525. return err;
  526. return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
  527. }
  528. static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip *chip,
  529. bool external, u16 op, int port,
  530. int dev)
  531. {
  532. return mv88e6xxx_g2_smi_phy_access(chip, external, true, op, port, dev);
  533. }
  534. /* IEEE 802.3 Clause 45 Write Address Register */
  535. static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip *chip,
  536. bool external, int port, int dev,
  537. int addr)
  538. {
  539. u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR;
  540. int err;
  541. err = mv88e6xxx_g2_smi_phy_wait(chip);
  542. if (err)
  543. return err;
  544. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, addr);
  545. if (err)
  546. return err;
  547. return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
  548. }
  549. /* IEEE 802.3 Clause 45 Read Data Register */
  550. static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip *chip,
  551. bool external, int port, int dev,
  552. u16 *data)
  553. {
  554. u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA;
  555. int err;
  556. err = mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
  557. if (err)
  558. return err;
  559. return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
  560. }
  561. static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
  562. bool external, int port, int reg,
  563. u16 *data)
  564. {
  565. int dev = (reg >> 16) & 0x1f;
  566. int addr = reg & 0xffff;
  567. int err;
  568. err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
  569. addr);
  570. if (err)
  571. return err;
  572. return mv88e6xxx_g2_smi_phy_read_data_c45(chip, external, port, dev,
  573. data);
  574. }
  575. /* IEEE 802.3 Clause 45 Write Data Register */
  576. static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip *chip,
  577. bool external, int port, int dev,
  578. u16 data)
  579. {
  580. u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA;
  581. int err;
  582. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
  583. if (err)
  584. return err;
  585. return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
  586. }
  587. static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
  588. bool external, int port, int reg,
  589. u16 data)
  590. {
  591. int dev = (reg >> 16) & 0x1f;
  592. int addr = reg & 0xffff;
  593. int err;
  594. err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
  595. addr);
  596. if (err)
  597. return err;
  598. return mv88e6xxx_g2_smi_phy_write_data_c45(chip, external, port, dev,
  599. data);
  600. }
  601. int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
  602. int addr, int reg, u16 *val)
  603. {
  604. struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
  605. bool external = mdio_bus->external;
  606. if (reg & MII_ADDR_C45)
  607. return mv88e6xxx_g2_smi_phy_read_c45(chip, external, addr, reg,
  608. val);
  609. return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
  610. val);
  611. }
  612. int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
  613. int addr, int reg, u16 val)
  614. {
  615. struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
  616. bool external = mdio_bus->external;
  617. if (reg & MII_ADDR_C45)
  618. return mv88e6xxx_g2_smi_phy_write_c45(chip, external, addr, reg,
  619. val);
  620. return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
  621. val);
  622. }
  623. /* Offset 0x1B: Watchdog Control */
  624. static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
  625. {
  626. u16 reg;
  627. mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
  628. dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
  629. return IRQ_HANDLED;
  630. }
  631. static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
  632. {
  633. u16 reg;
  634. mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
  635. reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
  636. MV88E6352_G2_WDOG_CTL_QC_ENABLE);
  637. mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
  638. }
  639. static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
  640. {
  641. return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
  642. MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
  643. MV88E6352_G2_WDOG_CTL_QC_ENABLE |
  644. MV88E6352_G2_WDOG_CTL_SWRESET);
  645. }
  646. const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
  647. .irq_action = mv88e6097_watchdog_action,
  648. .irq_setup = mv88e6097_watchdog_setup,
  649. .irq_free = mv88e6097_watchdog_free,
  650. };
  651. static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
  652. {
  653. return mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
  654. MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
  655. MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
  656. MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
  657. MV88E6390_G2_WDOG_CTL_EGRESS |
  658. MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
  659. }
  660. static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
  661. {
  662. int err;
  663. u16 reg;
  664. mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
  665. MV88E6390_G2_WDOG_CTL_PTR_EVENT);
  666. err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
  667. dev_info(chip->dev, "Watchdog event: 0x%04x",
  668. reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
  669. mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
  670. MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
  671. err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
  672. dev_info(chip->dev, "Watchdog history: 0x%04x",
  673. reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
  674. /* Trigger a software reset to try to recover the switch */
  675. if (chip->info->ops->reset)
  676. chip->info->ops->reset(chip);
  677. mv88e6390_watchdog_setup(chip);
  678. return IRQ_HANDLED;
  679. }
  680. static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
  681. {
  682. mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
  683. MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
  684. }
  685. const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
  686. .irq_action = mv88e6390_watchdog_action,
  687. .irq_setup = mv88e6390_watchdog_setup,
  688. .irq_free = mv88e6390_watchdog_free,
  689. };
  690. static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
  691. {
  692. struct mv88e6xxx_chip *chip = dev_id;
  693. irqreturn_t ret = IRQ_NONE;
  694. mutex_lock(&chip->reg_lock);
  695. if (chip->info->ops->watchdog_ops->irq_action)
  696. ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
  697. mutex_unlock(&chip->reg_lock);
  698. return ret;
  699. }
  700. static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
  701. {
  702. mutex_lock(&chip->reg_lock);
  703. if (chip->info->ops->watchdog_ops->irq_free)
  704. chip->info->ops->watchdog_ops->irq_free(chip);
  705. mutex_unlock(&chip->reg_lock);
  706. free_irq(chip->watchdog_irq, chip);
  707. irq_dispose_mapping(chip->watchdog_irq);
  708. }
  709. static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
  710. {
  711. int err;
  712. chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
  713. MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
  714. if (chip->watchdog_irq < 0)
  715. return chip->watchdog_irq;
  716. err = request_threaded_irq(chip->watchdog_irq, NULL,
  717. mv88e6xxx_g2_watchdog_thread_fn,
  718. IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
  719. "mv88e6xxx-watchdog", chip);
  720. if (err)
  721. return err;
  722. mutex_lock(&chip->reg_lock);
  723. if (chip->info->ops->watchdog_ops->irq_setup)
  724. err = chip->info->ops->watchdog_ops->irq_setup(chip);
  725. mutex_unlock(&chip->reg_lock);
  726. return err;
  727. }
  728. /* Offset 0x1D: Misc Register */
  729. static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
  730. bool port_5_bit)
  731. {
  732. u16 val;
  733. int err;
  734. err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
  735. if (err)
  736. return err;
  737. if (port_5_bit)
  738. val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
  739. else
  740. val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;
  741. return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
  742. }
  743. int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
  744. {
  745. return mv88e6xxx_g2_misc_5_bit_port(chip, false);
  746. }
  747. static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
  748. {
  749. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  750. unsigned int n = d->hwirq;
  751. chip->g2_irq.masked |= (1 << n);
  752. }
  753. static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
  754. {
  755. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  756. unsigned int n = d->hwirq;
  757. chip->g2_irq.masked &= ~(1 << n);
  758. }
  759. static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
  760. {
  761. struct mv88e6xxx_chip *chip = dev_id;
  762. unsigned int nhandled = 0;
  763. unsigned int sub_irq;
  764. unsigned int n;
  765. int err;
  766. u16 reg;
  767. mutex_lock(&chip->reg_lock);
  768. err = mv88e6xxx_g2_int_source(chip, &reg);
  769. mutex_unlock(&chip->reg_lock);
  770. if (err)
  771. goto out;
  772. for (n = 0; n < 16; ++n) {
  773. if (reg & (1 << n)) {
  774. sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
  775. handle_nested_irq(sub_irq);
  776. ++nhandled;
  777. }
  778. }
  779. out:
  780. return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
  781. }
  782. static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
  783. {
  784. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  785. mutex_lock(&chip->reg_lock);
  786. }
  787. static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
  788. {
  789. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  790. int err;
  791. err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
  792. if (err)
  793. dev_err(chip->dev, "failed to mask interrupts\n");
  794. mutex_unlock(&chip->reg_lock);
  795. }
  796. static const struct irq_chip mv88e6xxx_g2_irq_chip = {
  797. .name = "mv88e6xxx-g2",
  798. .irq_mask = mv88e6xxx_g2_irq_mask,
  799. .irq_unmask = mv88e6xxx_g2_irq_unmask,
  800. .irq_bus_lock = mv88e6xxx_g2_irq_bus_lock,
  801. .irq_bus_sync_unlock = mv88e6xxx_g2_irq_bus_sync_unlock,
  802. };
  803. static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
  804. unsigned int irq,
  805. irq_hw_number_t hwirq)
  806. {
  807. struct mv88e6xxx_chip *chip = d->host_data;
  808. irq_set_chip_data(irq, d->host_data);
  809. irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
  810. irq_set_noprobe(irq);
  811. return 0;
  812. }
  813. static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
  814. .map = mv88e6xxx_g2_irq_domain_map,
  815. .xlate = irq_domain_xlate_twocell,
  816. };
  817. void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
  818. {
  819. int irq, virq;
  820. mv88e6xxx_g2_watchdog_free(chip);
  821. free_irq(chip->device_irq, chip);
  822. irq_dispose_mapping(chip->device_irq);
  823. for (irq = 0; irq < 16; irq++) {
  824. virq = irq_find_mapping(chip->g2_irq.domain, irq);
  825. irq_dispose_mapping(virq);
  826. }
  827. irq_domain_remove(chip->g2_irq.domain);
  828. }
  829. int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
  830. {
  831. int err, irq, virq;
  832. if (!chip->dev->of_node)
  833. return -EINVAL;
  834. chip->g2_irq.domain = irq_domain_add_simple(
  835. chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
  836. if (!chip->g2_irq.domain)
  837. return -ENOMEM;
  838. for (irq = 0; irq < 16; irq++)
  839. irq_create_mapping(chip->g2_irq.domain, irq);
  840. chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
  841. chip->g2_irq.masked = ~0;
  842. chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
  843. MV88E6XXX_G1_STS_IRQ_DEVICE);
  844. if (chip->device_irq < 0) {
  845. err = chip->device_irq;
  846. goto out;
  847. }
  848. err = request_threaded_irq(chip->device_irq, NULL,
  849. mv88e6xxx_g2_irq_thread_fn,
  850. IRQF_ONESHOT, "mv88e6xxx-g2", chip);
  851. if (err)
  852. goto out;
  853. return mv88e6xxx_g2_watchdog_setup(chip);
  854. out:
  855. for (irq = 0; irq < 16; irq++) {
  856. virq = irq_find_mapping(chip->g2_irq.domain, irq);
  857. irq_dispose_mapping(virq);
  858. }
  859. irq_domain_remove(chip->g2_irq.domain);
  860. return err;
  861. }
  862. int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
  863. struct mii_bus *bus)
  864. {
  865. int phy, irq, err, err_phy;
  866. for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
  867. irq = irq_find_mapping(chip->g2_irq.domain, phy);
  868. if (irq < 0) {
  869. err = irq;
  870. goto out;
  871. }
  872. bus->irq[chip->info->port_base_addr + phy] = irq;
  873. }
  874. return 0;
  875. out:
  876. err_phy = phy;
  877. for (phy = 0; phy < err_phy; phy++)
  878. irq_dispose_mapping(bus->irq[phy]);
  879. return err;
  880. }
  881. void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
  882. struct mii_bus *bus)
  883. {
  884. int phy;
  885. for (phy = 0; phy < chip->info->num_internal_phys; phy++)
  886. irq_dispose_mapping(bus->irq[phy]);
  887. }
  888. int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
  889. {
  890. u16 reg;
  891. int err;
  892. /* Ignore removed tag data on doubly tagged packets, disable
  893. * flow control messages, force flow control priority to the
  894. * highest, and send all special multicast frames to the CPU
  895. * port at the highest priority.
  896. */
  897. reg = MV88E6XXX_G2_SWITCH_MGMT_FORCE_FLOW_CTL_PRI | (0x7 << 4);
  898. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, reg);
  899. if (err)
  900. return err;
  901. /* Program the DSA routing table. */
  902. err = mv88e6xxx_g2_set_device_mapping(chip);
  903. if (err)
  904. return err;
  905. /* Clear all trunk masks and mapping. */
  906. err = mv88e6xxx_g2_clear_trunk(chip);
  907. if (err)
  908. return err;
  909. return 0;
  910. }