global2.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  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. static 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. static 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. static 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. static 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. static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
  624. {
  625. u16 reg;
  626. mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
  627. dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
  628. return IRQ_HANDLED;
  629. }
  630. static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
  631. {
  632. u16 reg;
  633. mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
  634. reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
  635. MV88E6352_G2_WDOG_CTL_QC_ENABLE);
  636. mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
  637. }
  638. static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
  639. {
  640. return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
  641. MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
  642. MV88E6352_G2_WDOG_CTL_QC_ENABLE |
  643. MV88E6352_G2_WDOG_CTL_SWRESET);
  644. }
  645. const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
  646. .irq_action = mv88e6097_watchdog_action,
  647. .irq_setup = mv88e6097_watchdog_setup,
  648. .irq_free = mv88e6097_watchdog_free,
  649. };
  650. static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
  651. {
  652. return mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
  653. MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
  654. MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
  655. MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
  656. MV88E6390_G2_WDOG_CTL_EGRESS |
  657. MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
  658. }
  659. static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
  660. {
  661. int err;
  662. u16 reg;
  663. mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
  664. MV88E6390_G2_WDOG_CTL_PTR_EVENT);
  665. err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
  666. dev_info(chip->dev, "Watchdog event: 0x%04x",
  667. reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
  668. mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
  669. MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
  670. err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
  671. dev_info(chip->dev, "Watchdog history: 0x%04x",
  672. reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
  673. /* Trigger a software reset to try to recover the switch */
  674. if (chip->info->ops->reset)
  675. chip->info->ops->reset(chip);
  676. mv88e6390_watchdog_setup(chip);
  677. return IRQ_HANDLED;
  678. }
  679. static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
  680. {
  681. mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
  682. MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
  683. }
  684. const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
  685. .irq_action = mv88e6390_watchdog_action,
  686. .irq_setup = mv88e6390_watchdog_setup,
  687. .irq_free = mv88e6390_watchdog_free,
  688. };
  689. static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
  690. {
  691. struct mv88e6xxx_chip *chip = dev_id;
  692. irqreturn_t ret = IRQ_NONE;
  693. mutex_lock(&chip->reg_lock);
  694. if (chip->info->ops->watchdog_ops->irq_action)
  695. ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
  696. mutex_unlock(&chip->reg_lock);
  697. return ret;
  698. }
  699. static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
  700. {
  701. mutex_lock(&chip->reg_lock);
  702. if (chip->info->ops->watchdog_ops->irq_free)
  703. chip->info->ops->watchdog_ops->irq_free(chip);
  704. mutex_unlock(&chip->reg_lock);
  705. free_irq(chip->watchdog_irq, chip);
  706. irq_dispose_mapping(chip->watchdog_irq);
  707. }
  708. static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
  709. {
  710. int err;
  711. chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
  712. MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
  713. if (chip->watchdog_irq < 0)
  714. return chip->watchdog_irq;
  715. err = request_threaded_irq(chip->watchdog_irq, NULL,
  716. mv88e6xxx_g2_watchdog_thread_fn,
  717. IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
  718. "mv88e6xxx-watchdog", chip);
  719. if (err)
  720. return err;
  721. mutex_lock(&chip->reg_lock);
  722. if (chip->info->ops->watchdog_ops->irq_setup)
  723. err = chip->info->ops->watchdog_ops->irq_setup(chip);
  724. mutex_unlock(&chip->reg_lock);
  725. return err;
  726. }
  727. /* Offset 0x1D: Misc Register */
  728. static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
  729. bool port_5_bit)
  730. {
  731. u16 val;
  732. int err;
  733. err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
  734. if (err)
  735. return err;
  736. if (port_5_bit)
  737. val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
  738. else
  739. val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;
  740. return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
  741. }
  742. int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
  743. {
  744. return mv88e6xxx_g2_misc_5_bit_port(chip, false);
  745. }
  746. static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
  747. {
  748. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  749. unsigned int n = d->hwirq;
  750. chip->g2_irq.masked |= (1 << n);
  751. }
  752. static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
  753. {
  754. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  755. unsigned int n = d->hwirq;
  756. chip->g2_irq.masked &= ~(1 << n);
  757. }
  758. static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
  759. {
  760. struct mv88e6xxx_chip *chip = dev_id;
  761. unsigned int nhandled = 0;
  762. unsigned int sub_irq;
  763. unsigned int n;
  764. int err;
  765. u16 reg;
  766. mutex_lock(&chip->reg_lock);
  767. err = mv88e6xxx_g2_int_source(chip, &reg);
  768. mutex_unlock(&chip->reg_lock);
  769. if (err)
  770. goto out;
  771. for (n = 0; n < 16; ++n) {
  772. if (reg & (1 << n)) {
  773. sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
  774. handle_nested_irq(sub_irq);
  775. ++nhandled;
  776. }
  777. }
  778. out:
  779. return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
  780. }
  781. static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
  782. {
  783. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  784. mutex_lock(&chip->reg_lock);
  785. }
  786. static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
  787. {
  788. struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
  789. int err;
  790. err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
  791. if (err)
  792. dev_err(chip->dev, "failed to mask interrupts\n");
  793. mutex_unlock(&chip->reg_lock);
  794. }
  795. static const struct irq_chip mv88e6xxx_g2_irq_chip = {
  796. .name = "mv88e6xxx-g2",
  797. .irq_mask = mv88e6xxx_g2_irq_mask,
  798. .irq_unmask = mv88e6xxx_g2_irq_unmask,
  799. .irq_bus_lock = mv88e6xxx_g2_irq_bus_lock,
  800. .irq_bus_sync_unlock = mv88e6xxx_g2_irq_bus_sync_unlock,
  801. };
  802. static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
  803. unsigned int irq,
  804. irq_hw_number_t hwirq)
  805. {
  806. struct mv88e6xxx_chip *chip = d->host_data;
  807. irq_set_chip_data(irq, d->host_data);
  808. irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
  809. irq_set_noprobe(irq);
  810. return 0;
  811. }
  812. static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
  813. .map = mv88e6xxx_g2_irq_domain_map,
  814. .xlate = irq_domain_xlate_twocell,
  815. };
  816. void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
  817. {
  818. int irq, virq;
  819. mv88e6xxx_g2_watchdog_free(chip);
  820. free_irq(chip->device_irq, chip);
  821. irq_dispose_mapping(chip->device_irq);
  822. for (irq = 0; irq < 16; irq++) {
  823. virq = irq_find_mapping(chip->g2_irq.domain, irq);
  824. irq_dispose_mapping(virq);
  825. }
  826. irq_domain_remove(chip->g2_irq.domain);
  827. }
  828. int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
  829. {
  830. int err, irq, virq;
  831. if (!chip->dev->of_node)
  832. return -EINVAL;
  833. chip->g2_irq.domain = irq_domain_add_simple(
  834. chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
  835. if (!chip->g2_irq.domain)
  836. return -ENOMEM;
  837. for (irq = 0; irq < 16; irq++)
  838. irq_create_mapping(chip->g2_irq.domain, irq);
  839. chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
  840. chip->g2_irq.masked = ~0;
  841. chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
  842. MV88E6XXX_G1_STS_IRQ_DEVICE);
  843. if (chip->device_irq < 0) {
  844. err = chip->device_irq;
  845. goto out;
  846. }
  847. err = request_threaded_irq(chip->device_irq, NULL,
  848. mv88e6xxx_g2_irq_thread_fn,
  849. IRQF_ONESHOT, "mv88e6xxx-g1", chip);
  850. if (err)
  851. goto out;
  852. return mv88e6xxx_g2_watchdog_setup(chip);
  853. out:
  854. for (irq = 0; irq < 16; irq++) {
  855. virq = irq_find_mapping(chip->g2_irq.domain, irq);
  856. irq_dispose_mapping(virq);
  857. }
  858. irq_domain_remove(chip->g2_irq.domain);
  859. return err;
  860. }
  861. int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
  862. {
  863. u16 reg;
  864. int err;
  865. /* Ignore removed tag data on doubly tagged packets, disable
  866. * flow control messages, force flow control priority to the
  867. * highest, and send all special multicast frames to the CPU
  868. * port at the highest priority.
  869. */
  870. reg = MV88E6XXX_G2_SWITCH_MGMT_FORCE_FLOW_CTL_PRI | (0x7 << 4);
  871. err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, reg);
  872. if (err)
  873. return err;
  874. /* Program the DSA routing table. */
  875. err = mv88e6xxx_g2_set_device_mapping(chip);
  876. if (err)
  877. return err;
  878. /* Clear all trunk masks and mapping. */
  879. err = mv88e6xxx_g2_clear_trunk(chip);
  880. if (err)
  881. return err;
  882. return 0;
  883. }