global2.c 26 KB

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