qca8k-ipq4019.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2009 Felix Fietkau <[email protected]>
  4. * Copyright (C) 2011-2012, 2020-2021 Gabor Juhos <[email protected]>
  5. * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
  6. * Copyright (c) 2016 John Crispin <[email protected]>
  7. * Copyright (c) 2021 Robert Marko <[email protected]>
  8. */
  9. #include <linux/bitfield.h>
  10. #include <linux/version.h>
  11. #include <linux/etherdevice.h>
  12. #include <linux/if_bridge.h>
  13. #include <linux/mdio.h>
  14. #include <linux/mfd/syscon.h>
  15. #include <linux/module.h>
  16. #include <linux/netdevice.h>
  17. #include <linux/of_mdio.h>
  18. #include <linux/of_net.h>
  19. #include <linux/of_platform.h>
  20. #include <linux/phy.h>
  21. #include <linux/phylink.h>
  22. #include <linux/reset.h>
  23. #include <net/dsa.h>
  24. #include "qca8k-ipq4019.h"
  25. #define MIB_DESC(_s, _o, _n) \
  26. { \
  27. .size = (_s), \
  28. .offset = (_o), \
  29. .name = (_n), \
  30. }
  31. static const struct qca8k_mib_desc ar8327_mib[] = {
  32. MIB_DESC(1, 0x00, "RxBroad"),
  33. MIB_DESC(1, 0x04, "RxPause"),
  34. MIB_DESC(1, 0x08, "RxMulti"),
  35. MIB_DESC(1, 0x0c, "RxFcsErr"),
  36. MIB_DESC(1, 0x10, "RxAlignErr"),
  37. MIB_DESC(1, 0x14, "RxRunt"),
  38. MIB_DESC(1, 0x18, "RxFragment"),
  39. MIB_DESC(1, 0x1c, "Rx64Byte"),
  40. MIB_DESC(1, 0x20, "Rx128Byte"),
  41. MIB_DESC(1, 0x24, "Rx256Byte"),
  42. MIB_DESC(1, 0x28, "Rx512Byte"),
  43. MIB_DESC(1, 0x2c, "Rx1024Byte"),
  44. MIB_DESC(1, 0x30, "Rx1518Byte"),
  45. MIB_DESC(1, 0x34, "RxMaxByte"),
  46. MIB_DESC(1, 0x38, "RxTooLong"),
  47. MIB_DESC(2, 0x3c, "RxGoodByte"),
  48. MIB_DESC(2, 0x44, "RxBadByte"),
  49. MIB_DESC(1, 0x4c, "RxOverFlow"),
  50. MIB_DESC(1, 0x50, "Filtered"),
  51. MIB_DESC(1, 0x54, "TxBroad"),
  52. MIB_DESC(1, 0x58, "TxPause"),
  53. MIB_DESC(1, 0x5c, "TxMulti"),
  54. MIB_DESC(1, 0x60, "TxUnderRun"),
  55. MIB_DESC(1, 0x64, "Tx64Byte"),
  56. MIB_DESC(1, 0x68, "Tx128Byte"),
  57. MIB_DESC(1, 0x6c, "Tx256Byte"),
  58. MIB_DESC(1, 0x70, "Tx512Byte"),
  59. MIB_DESC(1, 0x74, "Tx1024Byte"),
  60. MIB_DESC(1, 0x78, "Tx1518Byte"),
  61. MIB_DESC(1, 0x7c, "TxMaxByte"),
  62. MIB_DESC(1, 0x80, "TxOverSize"),
  63. MIB_DESC(2, 0x84, "TxByte"),
  64. MIB_DESC(1, 0x8c, "TxCollision"),
  65. MIB_DESC(1, 0x90, "TxAbortCol"),
  66. MIB_DESC(1, 0x94, "TxMultiCol"),
  67. MIB_DESC(1, 0x98, "TxSingleCol"),
  68. MIB_DESC(1, 0x9c, "TxExcDefer"),
  69. MIB_DESC(1, 0xa0, "TxDefer"),
  70. MIB_DESC(1, 0xa4, "TxLateCol"),
  71. MIB_DESC(1, 0xa8, "RXUnicast"),
  72. MIB_DESC(1, 0xac, "TXunicast"),
  73. };
  74. static int
  75. qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
  76. {
  77. return regmap_read(priv->regmap, reg, val);
  78. }
  79. static int
  80. qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
  81. {
  82. return regmap_write(priv->regmap, reg, val);
  83. }
  84. static int
  85. qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
  86. {
  87. return regmap_update_bits(priv->regmap, reg, mask, write_val);
  88. }
  89. static int
  90. qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val)
  91. {
  92. return regmap_set_bits(priv->regmap, reg, val);
  93. }
  94. static int
  95. qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val)
  96. {
  97. return regmap_clear_bits(priv->regmap, reg, val);
  98. }
  99. static const struct regmap_range qca8k_readable_ranges[] = {
  100. regmap_reg_range(0x0000, 0x00e4), /* Global control */
  101. regmap_reg_range(0x0100, 0x0168), /* EEE control */
  102. regmap_reg_range(0x0200, 0x0270), /* Parser control */
  103. regmap_reg_range(0x0400, 0x0454), /* ACL */
  104. regmap_reg_range(0x0600, 0x0718), /* Lookup */
  105. regmap_reg_range(0x0800, 0x0b70), /* QM */
  106. regmap_reg_range(0x0c00, 0x0c80), /* PKT */
  107. regmap_reg_range(0x0e00, 0x0e98), /* L3 */
  108. regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
  109. regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
  110. regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
  111. regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
  112. regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
  113. regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
  114. regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
  115. };
  116. static const struct regmap_access_table qca8k_readable_table = {
  117. .yes_ranges = qca8k_readable_ranges,
  118. .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
  119. };
  120. static struct regmap_config qca8k_ipq4019_regmap_config = {
  121. .reg_bits = 32,
  122. .val_bits = 32,
  123. .reg_stride = 4,
  124. .max_register = 0x16ac, /* end MIB - Port6 range */
  125. .rd_table = &qca8k_readable_table,
  126. };
  127. static struct regmap_config qca8k_ipq4019_psgmii_phy_regmap_config = {
  128. .name = "psgmii-phy",
  129. .reg_bits = 32,
  130. .val_bits = 32,
  131. .reg_stride = 4,
  132. .max_register = 0x7fc,
  133. };
  134. static int
  135. qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
  136. {
  137. u32 val;
  138. return regmap_read_poll_timeout(priv->regmap, reg, val,
  139. !(val & mask),
  140. 0,
  141. QCA8K_BUSY_WAIT_TIMEOUT);
  142. }
  143. static int
  144. qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
  145. {
  146. u32 reg[4], val;
  147. int i, ret;
  148. /* load the ARL table into an array */
  149. for (i = 0; i < 4; i++) {
  150. ret = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4), &val);
  151. if (ret < 0)
  152. return ret;
  153. reg[i] = val;
  154. }
  155. /* vid - 83:72 */
  156. fdb->vid = (reg[2] >> QCA8K_ATU_VID_S) & QCA8K_ATU_VID_M;
  157. /* aging - 67:64 */
  158. fdb->aging = reg[2] & QCA8K_ATU_STATUS_M;
  159. /* portmask - 54:48 */
  160. fdb->port_mask = (reg[1] >> QCA8K_ATU_PORT_S) & QCA8K_ATU_PORT_M;
  161. /* mac - 47:0 */
  162. fdb->mac[0] = (reg[1] >> QCA8K_ATU_ADDR0_S) & 0xff;
  163. fdb->mac[1] = reg[1] & 0xff;
  164. fdb->mac[2] = (reg[0] >> QCA8K_ATU_ADDR2_S) & 0xff;
  165. fdb->mac[3] = (reg[0] >> QCA8K_ATU_ADDR3_S) & 0xff;
  166. fdb->mac[4] = (reg[0] >> QCA8K_ATU_ADDR4_S) & 0xff;
  167. fdb->mac[5] = reg[0] & 0xff;
  168. return 0;
  169. }
  170. static void
  171. qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac,
  172. u8 aging)
  173. {
  174. u32 reg[3] = { 0 };
  175. int i;
  176. /* vid - 83:72 */
  177. reg[2] = (vid & QCA8K_ATU_VID_M) << QCA8K_ATU_VID_S;
  178. /* aging - 67:64 */
  179. reg[2] |= aging & QCA8K_ATU_STATUS_M;
  180. /* portmask - 54:48 */
  181. reg[1] = (port_mask & QCA8K_ATU_PORT_M) << QCA8K_ATU_PORT_S;
  182. /* mac - 47:0 */
  183. reg[1] |= mac[0] << QCA8K_ATU_ADDR0_S;
  184. reg[1] |= mac[1];
  185. reg[0] |= mac[2] << QCA8K_ATU_ADDR2_S;
  186. reg[0] |= mac[3] << QCA8K_ATU_ADDR3_S;
  187. reg[0] |= mac[4] << QCA8K_ATU_ADDR4_S;
  188. reg[0] |= mac[5];
  189. /* load the array into the ARL table */
  190. for (i = 0; i < 3; i++)
  191. qca8k_write(priv, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]);
  192. }
  193. static int
  194. qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
  195. {
  196. u32 reg;
  197. int ret;
  198. /* Set the command and FDB index */
  199. reg = QCA8K_ATU_FUNC_BUSY;
  200. reg |= cmd;
  201. if (port >= 0) {
  202. reg |= QCA8K_ATU_FUNC_PORT_EN;
  203. reg |= (port & QCA8K_ATU_FUNC_PORT_M) << QCA8K_ATU_FUNC_PORT_S;
  204. }
  205. /* Write the function register triggering the table access */
  206. ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
  207. if (ret)
  208. return ret;
  209. /* wait for completion */
  210. ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
  211. if (ret)
  212. return ret;
  213. /* Check for table full violation when adding an entry */
  214. if (cmd == QCA8K_FDB_LOAD) {
  215. ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
  216. if (ret < 0)
  217. return ret;
  218. if (reg & QCA8K_ATU_FUNC_FULL)
  219. return -1;
  220. }
  221. return 0;
  222. }
  223. static int
  224. qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port)
  225. {
  226. int ret;
  227. qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
  228. ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
  229. if (ret < 0)
  230. return ret;
  231. return qca8k_fdb_read(priv, fdb);
  232. }
  233. static int
  234. qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask,
  235. u16 vid, u8 aging)
  236. {
  237. int ret;
  238. mutex_lock(&priv->reg_mutex);
  239. qca8k_fdb_write(priv, vid, port_mask, mac, aging);
  240. ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
  241. mutex_unlock(&priv->reg_mutex);
  242. return ret;
  243. }
  244. static int
  245. qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid)
  246. {
  247. int ret;
  248. mutex_lock(&priv->reg_mutex);
  249. qca8k_fdb_write(priv, vid, port_mask, mac, 0);
  250. ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
  251. mutex_unlock(&priv->reg_mutex);
  252. return ret;
  253. }
  254. static void
  255. qca8k_fdb_flush(struct qca8k_priv *priv)
  256. {
  257. mutex_lock(&priv->reg_mutex);
  258. qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
  259. mutex_unlock(&priv->reg_mutex);
  260. }
  261. static int
  262. qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
  263. {
  264. u32 reg;
  265. int ret;
  266. /* Set the command and VLAN index */
  267. reg = QCA8K_VTU_FUNC1_BUSY;
  268. reg |= cmd;
  269. reg |= vid << QCA8K_VTU_FUNC1_VID_S;
  270. /* Write the function register triggering the table access */
  271. ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
  272. if (ret)
  273. return ret;
  274. /* wait for completion */
  275. ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
  276. if (ret)
  277. return ret;
  278. /* Check for table full violation when adding an entry */
  279. if (cmd == QCA8K_VLAN_LOAD) {
  280. ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
  281. if (ret < 0)
  282. return ret;
  283. if (reg & QCA8K_VTU_FUNC1_FULL)
  284. return -ENOMEM;
  285. }
  286. return 0;
  287. }
  288. static int
  289. qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
  290. {
  291. u32 reg;
  292. int ret;
  293. /*
  294. We do the right thing with VLAN 0 and treat it as untagged while
  295. preserving the tag on egress.
  296. */
  297. if (vid == 0)
  298. return 0;
  299. mutex_lock(&priv->reg_mutex);
  300. ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
  301. if (ret < 0)
  302. goto out;
  303. ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
  304. if (ret < 0)
  305. goto out;
  306. reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
  307. reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
  308. if (untagged)
  309. reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
  310. QCA8K_VTU_FUNC0_EG_MODE_S(port);
  311. else
  312. reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
  313. QCA8K_VTU_FUNC0_EG_MODE_S(port);
  314. ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
  315. if (ret)
  316. goto out;
  317. ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
  318. out:
  319. mutex_unlock(&priv->reg_mutex);
  320. return ret;
  321. }
  322. static int
  323. qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
  324. {
  325. u32 reg, mask;
  326. int ret, i;
  327. bool del;
  328. mutex_lock(&priv->reg_mutex);
  329. ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
  330. if (ret < 0)
  331. goto out;
  332. ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
  333. if (ret < 0)
  334. goto out;
  335. reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
  336. reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
  337. QCA8K_VTU_FUNC0_EG_MODE_S(port);
  338. /* Check if we're the last member to be removed */
  339. del = true;
  340. for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  341. mask = QCA8K_VTU_FUNC0_EG_MODE_NOT;
  342. mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i);
  343. if ((reg & mask) != mask) {
  344. del = false;
  345. break;
  346. }
  347. }
  348. if (del) {
  349. ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
  350. } else {
  351. ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
  352. if (ret)
  353. goto out;
  354. ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
  355. }
  356. out:
  357. mutex_unlock(&priv->reg_mutex);
  358. return ret;
  359. }
  360. static int
  361. qca8k_mib_init(struct qca8k_priv *priv)
  362. {
  363. int ret;
  364. mutex_lock(&priv->reg_mutex);
  365. ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
  366. if (ret)
  367. goto exit;
  368. ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
  369. if (ret)
  370. goto exit;
  371. ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
  372. if (ret)
  373. goto exit;
  374. ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
  375. exit:
  376. mutex_unlock(&priv->reg_mutex);
  377. return ret;
  378. }
  379. static void
  380. qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
  381. {
  382. u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
  383. /* Port 0 is internally connected to the CPU
  384. * TODO: Probably check for RGMII as well if it doesnt work
  385. * in RGMII mode.
  386. */
  387. if (port > QCA8K_CPU_PORT)
  388. mask |= QCA8K_PORT_STATUS_LINK_AUTO;
  389. if (enable)
  390. qca8k_reg_set(priv, QCA8K_REG_PORT_STATUS(port), mask);
  391. else
  392. qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask);
  393. }
  394. static int
  395. qca8k_setup_port(struct dsa_switch *ds, int port)
  396. {
  397. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  398. int ret;
  399. /* CPU port gets connected to all user ports of the switch */
  400. if (dsa_is_cpu_port(ds, port)) {
  401. ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
  402. QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
  403. if (ret)
  404. return ret;
  405. /* Disable CPU ARP Auto-learning by default */
  406. ret = qca8k_reg_clear(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
  407. QCA8K_PORT_LOOKUP_LEARN);
  408. if (ret)
  409. return ret;
  410. }
  411. /* Individual user ports get connected to CPU port only */
  412. if (dsa_is_user_port(ds, port)) {
  413. int shift = 16 * (port % 2);
  414. ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  415. QCA8K_PORT_LOOKUP_MEMBER,
  416. BIT(QCA8K_CPU_PORT));
  417. if (ret)
  418. return ret;
  419. /* Enable ARP Auto-learning by default */
  420. ret = qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  421. QCA8K_PORT_LOOKUP_LEARN);
  422. if (ret)
  423. return ret;
  424. /* For port based vlans to work we need to set the
  425. * default egress vid
  426. */
  427. ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
  428. 0xfff << shift,
  429. QCA8K_PORT_VID_DEF << shift);
  430. if (ret)
  431. return ret;
  432. ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
  433. QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
  434. QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
  435. if (ret)
  436. return ret;
  437. }
  438. return 0;
  439. }
  440. static int
  441. qca8k_setup(struct dsa_switch *ds)
  442. {
  443. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  444. int ret, i;
  445. /* Make sure that port 0 is the cpu port */
  446. if (!dsa_is_cpu_port(ds, 0)) {
  447. dev_err(priv->dev, "port 0 is not the CPU port");
  448. return -EINVAL;
  449. }
  450. /* Enable CPU Port */
  451. ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
  452. QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
  453. if (ret) {
  454. dev_err(priv->dev, "failed enabling CPU port");
  455. return ret;
  456. }
  457. /* Enable MIB counters */
  458. ret = qca8k_mib_init(priv);
  459. if (ret)
  460. dev_warn(priv->dev, "MIB init failed");
  461. /* Enable QCA header mode on the cpu port */
  462. ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
  463. QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
  464. QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
  465. if (ret) {
  466. dev_err(priv->dev, "failed enabling QCA header mode");
  467. return ret;
  468. }
  469. /* Disable forwarding by default on all ports */
  470. for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  471. ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
  472. QCA8K_PORT_LOOKUP_MEMBER, 0);
  473. if (ret)
  474. return ret;
  475. }
  476. /* Disable MAC by default on all ports */
  477. for (i = 1; i < QCA8K_NUM_PORTS; i++)
  478. qca8k_port_set_status(priv, i, 0);
  479. /* Forward all unknown frames to CPU port for Linux processing */
  480. ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
  481. BIT(QCA8K_CPU_PORT) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
  482. BIT(QCA8K_CPU_PORT) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
  483. BIT(QCA8K_CPU_PORT) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
  484. BIT(QCA8K_CPU_PORT) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
  485. if (ret)
  486. return ret;
  487. /* Setup connection between CPU port & user ports */
  488. for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  489. ret = qca8k_setup_port(ds, i);
  490. if (ret)
  491. return ret;
  492. }
  493. /* Setup our port MTUs to match power on defaults */
  494. for (i = 0; i < QCA8K_NUM_PORTS; i++)
  495. /* Set per port MTU to 1500 as the MTU change function
  496. * will add the overhead and if its set to 1518 then it
  497. * will apply the overhead again and we will end up with
  498. * MTU of 1536 instead of 1518
  499. */
  500. priv->port_mtu[i] = ETH_DATA_LEN;
  501. ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
  502. if (ret)
  503. dev_warn(priv->dev, "failed setting MTU settings");
  504. /* Flush the FDB table */
  505. qca8k_fdb_flush(priv);
  506. /* We don't have interrupts for link changes, so we need to poll */
  507. ds->pcs_poll = true;
  508. /* CPU port HW learning doesnt work correctly, so let DSA handle it */
  509. ds->assisted_learning_on_cpu_port = true;
  510. return 0;
  511. }
  512. static int psgmii_vco_calibrate(struct qca8k_priv *priv)
  513. {
  514. int val, ret;
  515. if (!priv->psgmii_ethphy) {
  516. dev_err(priv->dev, "PSGMII eth PHY missing, calibration failed!\n");
  517. return -ENODEV;
  518. }
  519. /* Fix PSGMII RX 20bit */
  520. ret = phy_write(priv->psgmii_ethphy, MII_BMCR, 0x5b);
  521. /* Reset PHY PSGMII */
  522. ret = phy_write(priv->psgmii_ethphy, MII_BMCR, 0x1b);
  523. /* Release PHY PSGMII reset */
  524. ret = phy_write(priv->psgmii_ethphy, MII_BMCR, 0x5b);
  525. /* Poll for VCO PLL calibration finish - Malibu(QCA8075) */
  526. ret = phy_read_mmd_poll_timeout(priv->psgmii_ethphy,
  527. MDIO_MMD_PMAPMD,
  528. 0x28, val,
  529. (val & BIT(0)),
  530. 10000, 1000000,
  531. false);
  532. if (ret) {
  533. dev_err(priv->dev, "QCA807x PSGMII VCO calibration PLL not ready\n");
  534. return ret;
  535. }
  536. mdelay(50);
  537. /* Freeze PSGMII RX CDR */
  538. ret = phy_write(priv->psgmii_ethphy, MII_RESV2, 0x2230);
  539. /* Start PSGMIIPHY VCO PLL calibration */
  540. ret = regmap_set_bits(priv->psgmii,
  541. PSGMIIPHY_VCO_CALIBRATION_CONTROL_REGISTER_1,
  542. PSGMIIPHY_REG_PLL_VCO_CALIB_RESTART);
  543. /* Poll for PSGMIIPHY PLL calibration finish - Dakota(IPQ40xx) */
  544. ret = regmap_read_poll_timeout(priv->psgmii,
  545. PSGMIIPHY_VCO_CALIBRATION_CONTROL_REGISTER_2,
  546. val, val & PSGMIIPHY_REG_PLL_VCO_CALIB_READY,
  547. 10000, 1000000);
  548. if (ret) {
  549. dev_err(priv->dev, "IPQ PSGMIIPHY VCO calibration PLL not ready\n");
  550. return ret;
  551. }
  552. mdelay(50);
  553. /* Release PSGMII RX CDR */
  554. ret = phy_write(priv->psgmii_ethphy, MII_RESV2, 0x3230);
  555. /* Release PSGMII RX 20bit */
  556. ret = phy_write(priv->psgmii_ethphy, MII_BMCR, 0x5f);
  557. mdelay(200);
  558. return ret;
  559. }
  560. static void
  561. qca8k_switch_port_loopback_on_off(struct qca8k_priv *priv, int port, int on)
  562. {
  563. u32 val = QCA8K_PORT_LOOKUP_LOOPBACK;
  564. if (on == 0)
  565. val = 0;
  566. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  567. QCA8K_PORT_LOOKUP_LOOPBACK, val);
  568. }
  569. static int
  570. qca8k_wait_for_phy_link_state(struct phy_device *phy, int need_status)
  571. {
  572. int a;
  573. u16 status;
  574. for (a = 0; a < 100; a++) {
  575. status = phy_read(phy, MII_QCA8075_SSTATUS);
  576. status &= QCA8075_PHY_SPEC_STATUS_LINK;
  577. status = !!status;
  578. if (status == need_status)
  579. return 0;
  580. mdelay(8);
  581. }
  582. return -1;
  583. }
  584. static void
  585. qca8k_phy_loopback_on_off(struct qca8k_priv *priv, struct phy_device *phy,
  586. int sw_port, int on)
  587. {
  588. if (on) {
  589. phy_write(phy, MII_BMCR, BMCR_ANENABLE | BMCR_RESET);
  590. phy_modify(phy, MII_BMCR, BMCR_PDOWN, BMCR_PDOWN);
  591. qca8k_wait_for_phy_link_state(phy, 0);
  592. qca8k_write(priv, QCA8K_REG_PORT_STATUS(sw_port), 0);
  593. phy_write(phy, MII_BMCR,
  594. BMCR_SPEED1000 |
  595. BMCR_FULLDPLX |
  596. BMCR_LOOPBACK);
  597. qca8k_wait_for_phy_link_state(phy, 1);
  598. qca8k_write(priv, QCA8K_REG_PORT_STATUS(sw_port),
  599. QCA8K_PORT_STATUS_SPEED_1000 |
  600. QCA8K_PORT_STATUS_TXMAC |
  601. QCA8K_PORT_STATUS_RXMAC |
  602. QCA8K_PORT_STATUS_DUPLEX);
  603. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(sw_port),
  604. QCA8K_PORT_LOOKUP_STATE_FORWARD,
  605. QCA8K_PORT_LOOKUP_STATE_FORWARD);
  606. } else { /* off */
  607. qca8k_write(priv, QCA8K_REG_PORT_STATUS(sw_port), 0);
  608. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(sw_port),
  609. QCA8K_PORT_LOOKUP_STATE_DISABLED,
  610. QCA8K_PORT_LOOKUP_STATE_DISABLED);
  611. phy_write(phy, MII_BMCR, BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_RESET);
  612. /* turn off the power of the phys - so that unused
  613. ports do not raise links */
  614. phy_modify(phy, MII_BMCR, BMCR_PDOWN, BMCR_PDOWN);
  615. }
  616. }
  617. static void
  618. qca8k_phy_pkt_gen_prep(struct qca8k_priv *priv, struct phy_device *phy,
  619. int pkts_num, int on)
  620. {
  621. if (on) {
  622. /* enable CRC checker and packets counters */
  623. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_CRC_AND_PKTS_COUNT, 0);
  624. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_CRC_AND_PKTS_COUNT,
  625. QCA8075_MMD7_CNT_FRAME_CHK_EN | QCA8075_MMD7_CNT_SELFCLR);
  626. qca8k_wait_for_phy_link_state(phy, 1);
  627. /* packet number */
  628. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_PKT_GEN_PKT_NUMB, pkts_num);
  629. /* pkt size - 1504 bytes + 20 bytes */
  630. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_PKT_GEN_PKT_SIZE, 1504);
  631. } else { /* off */
  632. /* packet number */
  633. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_PKT_GEN_PKT_NUMB, 0);
  634. /* disable CRC checker and packet counter */
  635. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_CRC_AND_PKTS_COUNT, 0);
  636. /* disable traffic gen */
  637. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_PKT_GEN_CTRL, 0);
  638. }
  639. }
  640. static void
  641. qca8k_wait_for_phy_pkt_gen_fin(struct qca8k_priv *priv, struct phy_device *phy)
  642. {
  643. int val;
  644. /* wait for all traffic end: 4096(pkt num)*1524(size)*8ns(125MHz)=49938us */
  645. phy_read_mmd_poll_timeout(phy, MDIO_MMD_AN, QCA8075_MMD7_PKT_GEN_CTRL,
  646. val, !(val & QCA8075_MMD7_PKT_GEN_INPROGR),
  647. 50000, 1000000, true);
  648. }
  649. static void
  650. qca8k_start_phy_pkt_gen(struct phy_device *phy)
  651. {
  652. /* start traffic gen */
  653. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_PKT_GEN_CTRL,
  654. QCA8075_MMD7_PKT_GEN_START | QCA8075_MMD7_PKT_GEN_INPROGR);
  655. }
  656. static int
  657. qca8k_start_all_phys_pkt_gens(struct qca8k_priv *priv)
  658. {
  659. struct phy_device *phy;
  660. phy = phy_device_create(priv->bus, QCA8075_MDIO_BRDCST_PHY_ADDR,
  661. 0, 0, NULL);
  662. if (!phy) {
  663. dev_err(priv->dev, "unable to create mdio broadcast PHY(0x%x)\n",
  664. QCA8075_MDIO_BRDCST_PHY_ADDR);
  665. return -ENODEV;
  666. }
  667. qca8k_start_phy_pkt_gen(phy);
  668. phy_device_free(phy);
  669. return 0;
  670. }
  671. static int
  672. qca8k_get_phy_pkt_gen_test_result(struct phy_device *phy, int pkts_num)
  673. {
  674. u32 tx_ok, tx_error;
  675. u32 rx_ok, rx_error;
  676. u32 tx_ok_high16;
  677. u32 rx_ok_high16;
  678. u32 tx_all_ok, rx_all_ok;
  679. /* check counters */
  680. tx_ok = phy_read_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_EG_FRAME_RECV_CNT_LO);
  681. tx_ok_high16 = phy_read_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_EG_FRAME_RECV_CNT_HI);
  682. tx_error = phy_read_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_EG_FRAME_ERR_CNT);
  683. rx_ok = phy_read_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_IG_FRAME_RECV_CNT_LO);
  684. rx_ok_high16 = phy_read_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_IG_FRAME_RECV_CNT_HI);
  685. rx_error = phy_read_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_IG_FRAME_ERR_CNT);
  686. tx_all_ok = tx_ok + (tx_ok_high16 << 16);
  687. rx_all_ok = rx_ok + (rx_ok_high16 << 16);
  688. if (tx_all_ok < pkts_num)
  689. return -1;
  690. if(rx_all_ok < pkts_num)
  691. return -2;
  692. if(tx_error)
  693. return -3;
  694. if(rx_error)
  695. return -4;
  696. return 0; /* test is ok */
  697. }
  698. static
  699. void qca8k_phy_broadcast_write_on_off(struct qca8k_priv *priv,
  700. struct phy_device *phy, int on)
  701. {
  702. u32 val;
  703. val = phy_read_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_MDIO_BRDCST_WRITE);
  704. if (on == 0)
  705. val &= ~QCA8075_MMD7_MDIO_BRDCST_WRITE_EN;
  706. else
  707. val |= QCA8075_MMD7_MDIO_BRDCST_WRITE_EN;
  708. phy_write_mmd(phy, MDIO_MMD_AN, QCA8075_MMD7_MDIO_BRDCST_WRITE, val);
  709. }
  710. static int
  711. qca8k_test_dsa_port_for_errors(struct qca8k_priv *priv, struct phy_device *phy,
  712. int port, int test_phase)
  713. {
  714. int res = 0;
  715. const int test_pkts_num = QCA8075_PKT_GEN_PKTS_COUNT;
  716. if (test_phase == 1) { /* start test preps */
  717. qca8k_phy_loopback_on_off(priv, phy, port, 1);
  718. qca8k_switch_port_loopback_on_off(priv, port, 1);
  719. qca8k_phy_broadcast_write_on_off(priv, phy, 1);
  720. qca8k_phy_pkt_gen_prep(priv, phy, test_pkts_num, 1);
  721. } else if (test_phase == 2) {
  722. /* wait for test results, collect it and cleanup */
  723. qca8k_wait_for_phy_pkt_gen_fin(priv, phy);
  724. res = qca8k_get_phy_pkt_gen_test_result(phy, test_pkts_num);
  725. qca8k_phy_pkt_gen_prep(priv, phy, test_pkts_num, 0);
  726. qca8k_phy_broadcast_write_on_off(priv, phy, 0);
  727. qca8k_switch_port_loopback_on_off(priv, port, 0);
  728. qca8k_phy_loopback_on_off(priv, phy, port, 0);
  729. }
  730. return res;
  731. }
  732. static int
  733. qca8k_do_dsa_sw_ports_self_test(struct qca8k_priv *priv, int parallel_test)
  734. {
  735. struct device_node *dn = priv->dev->of_node;
  736. struct device_node *ports, *port;
  737. struct device_node *phy_dn;
  738. struct phy_device *phy;
  739. int reg, err = 0, test_phase;
  740. u32 tests_result = 0;
  741. ports = of_get_child_by_name(dn, "ports");
  742. if (!ports) {
  743. dev_err(priv->dev, "no ports child node found\n");
  744. return -EINVAL;
  745. }
  746. for (test_phase = 1; test_phase <= 2; test_phase++) {
  747. if (parallel_test && test_phase == 2) {
  748. err = qca8k_start_all_phys_pkt_gens(priv);
  749. if (err)
  750. goto error;
  751. }
  752. for_each_available_child_of_node(ports, port) {
  753. err = of_property_read_u32(port, "reg", &reg);
  754. if (err)
  755. goto error;
  756. if (reg >= QCA8K_NUM_PORTS) {
  757. err = -EINVAL;
  758. goto error;
  759. }
  760. phy_dn = of_parse_phandle(port, "phy-handle", 0);
  761. if (phy_dn) {
  762. phy = of_phy_find_device(phy_dn);
  763. of_node_put(phy_dn);
  764. if (phy) {
  765. int result;
  766. result = qca8k_test_dsa_port_for_errors(priv,
  767. phy, reg, test_phase);
  768. if (!parallel_test && test_phase == 1)
  769. qca8k_start_phy_pkt_gen(phy);
  770. put_device(&phy->mdio.dev);
  771. if (test_phase == 2) {
  772. tests_result <<= 1;
  773. if (result)
  774. tests_result |= 1;
  775. }
  776. }
  777. }
  778. }
  779. }
  780. end:
  781. of_node_put(ports);
  782. qca8k_fdb_flush(priv);
  783. return tests_result;
  784. error:
  785. tests_result |= 0xf000;
  786. goto end;
  787. }
  788. static int
  789. psgmii_vco_calibrate_and_test(struct dsa_switch *ds)
  790. {
  791. int ret, a, test_result;
  792. struct qca8k_priv *priv = ds->priv;
  793. for (a = 0; a <= QCA8K_PSGMII_CALB_NUM; a++) {
  794. ret = psgmii_vco_calibrate(priv);
  795. if (ret)
  796. return ret;
  797. /* first we run serial test */
  798. test_result = qca8k_do_dsa_sw_ports_self_test(priv, 0);
  799. /* and if it is ok then we run the test in parallel */
  800. if (!test_result)
  801. test_result = qca8k_do_dsa_sw_ports_self_test(priv, 1);
  802. if (!test_result) {
  803. if (a > 0) {
  804. dev_warn(priv->dev, "PSGMII work was stabilized after %d "
  805. "calibration retries !\n", a);
  806. }
  807. return 0;
  808. } else {
  809. schedule();
  810. if (a > 0 && a % 10 == 0) {
  811. dev_err(priv->dev, "PSGMII work is unstable !!! "
  812. "Let's try to wait a bit ... %d\n", a);
  813. set_current_state(TASK_INTERRUPTIBLE);
  814. schedule_timeout(msecs_to_jiffies(a * 100));
  815. }
  816. }
  817. }
  818. panic("PSGMII work is unstable !!! "
  819. "Repeated recalibration attempts did not help(0x%x) !\n",
  820. test_result);
  821. return -EFAULT;
  822. }
  823. static int
  824. ipq4019_psgmii_configure(struct dsa_switch *ds)
  825. {
  826. struct qca8k_priv *priv = ds->priv;
  827. int ret;
  828. if (!priv->psgmii_calibrated) {
  829. ret = psgmii_vco_calibrate_and_test(ds);
  830. ret = regmap_clear_bits(priv->psgmii, PSGMIIPHY_MODE_CONTROL,
  831. PSGMIIPHY_MODE_ATHR_CSCO_MODE_25M);
  832. ret = regmap_write(priv->psgmii, PSGMIIPHY_TX_CONTROL,
  833. PSGMIIPHY_TX_CONTROL_MAGIC_VALUE);
  834. priv->psgmii_calibrated = true;
  835. return ret;
  836. }
  837. return 0;
  838. }
  839. static void
  840. qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
  841. const struct phylink_link_state *state)
  842. {
  843. struct qca8k_priv *priv = ds->priv;
  844. switch (port) {
  845. case 0:
  846. /* CPU port, no configuration needed */
  847. return;
  848. case 1:
  849. case 2:
  850. case 3:
  851. if (state->interface == PHY_INTERFACE_MODE_PSGMII)
  852. if (ipq4019_psgmii_configure(ds))
  853. dev_err(ds->dev, "PSGMII configuration failed!\n");
  854. return;
  855. case 4:
  856. case 5:
  857. if (state->interface == PHY_INTERFACE_MODE_RGMII ||
  858. state->interface == PHY_INTERFACE_MODE_RGMII_ID ||
  859. state->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
  860. state->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
  861. qca8k_reg_set(priv, QCA8K_REG_RGMII_CTRL, QCA8K_RGMII_CTRL_CLK);
  862. }
  863. if (state->interface == PHY_INTERFACE_MODE_PSGMII)
  864. if (ipq4019_psgmii_configure(ds))
  865. dev_err(ds->dev, "PSGMII configuration failed!\n");
  866. return;
  867. default:
  868. dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
  869. return;
  870. }
  871. }
  872. static void
  873. qca8k_phylink_validate(struct dsa_switch *ds, int port,
  874. unsigned long *supported,
  875. struct phylink_link_state *state)
  876. {
  877. __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
  878. switch (port) {
  879. case 0: /* CPU port */
  880. if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
  881. goto unsupported;
  882. break;
  883. case 1:
  884. case 2:
  885. case 3:
  886. /* Only PSGMII mode is supported */
  887. if (state->interface != PHY_INTERFACE_MODE_PSGMII)
  888. goto unsupported;
  889. break;
  890. case 4:
  891. case 5:
  892. /* PSGMII and RGMII modes are supported */
  893. if (state->interface != PHY_INTERFACE_MODE_PSGMII &&
  894. state->interface != PHY_INTERFACE_MODE_RGMII &&
  895. state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
  896. state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
  897. state->interface != PHY_INTERFACE_MODE_RGMII_TXID)
  898. goto unsupported;
  899. break;
  900. default:
  901. unsupported:
  902. dev_warn(ds->dev, "interface '%s' (%d) on port %d is not supported\n",
  903. phy_modes(state->interface), state->interface, port);
  904. linkmode_zero(supported);
  905. return;
  906. }
  907. if (port == 0) {
  908. phylink_set_port_modes(mask);
  909. phylink_set(mask, 1000baseT_Full);
  910. phylink_set(mask, Pause);
  911. phylink_set(mask, Asym_Pause);
  912. linkmode_and(supported, supported, mask);
  913. linkmode_and(state->advertising, state->advertising, mask);
  914. } else {
  915. /* Simply copy what PHYs tell us */
  916. linkmode_copy(state->advertising, supported);
  917. }
  918. }
  919. static int
  920. qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port,
  921. struct phylink_link_state *state)
  922. {
  923. struct qca8k_priv *priv = ds->priv;
  924. u32 reg;
  925. int ret;
  926. ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
  927. if (ret < 0)
  928. return ret;
  929. state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
  930. state->an_complete = state->link;
  931. state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
  932. state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
  933. DUPLEX_HALF;
  934. switch (reg & QCA8K_PORT_STATUS_SPEED) {
  935. case QCA8K_PORT_STATUS_SPEED_10:
  936. state->speed = SPEED_10;
  937. break;
  938. case QCA8K_PORT_STATUS_SPEED_100:
  939. state->speed = SPEED_100;
  940. break;
  941. case QCA8K_PORT_STATUS_SPEED_1000:
  942. state->speed = SPEED_1000;
  943. break;
  944. default:
  945. state->speed = SPEED_UNKNOWN;
  946. break;
  947. }
  948. state->pause = MLO_PAUSE_NONE;
  949. if (reg & QCA8K_PORT_STATUS_RXFLOW)
  950. state->pause |= MLO_PAUSE_RX;
  951. if (reg & QCA8K_PORT_STATUS_TXFLOW)
  952. state->pause |= MLO_PAUSE_TX;
  953. return 1;
  954. }
  955. static void
  956. qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
  957. phy_interface_t interface)
  958. {
  959. struct qca8k_priv *priv = ds->priv;
  960. qca8k_port_set_status(priv, port, 0);
  961. }
  962. static void
  963. qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
  964. phy_interface_t interface, struct phy_device *phydev,
  965. int speed, int duplex, bool tx_pause, bool rx_pause)
  966. {
  967. struct qca8k_priv *priv = ds->priv;
  968. u32 reg;
  969. if (phylink_autoneg_inband(mode)) {
  970. reg = QCA8K_PORT_STATUS_LINK_AUTO;
  971. } else {
  972. switch (speed) {
  973. case SPEED_10:
  974. reg = QCA8K_PORT_STATUS_SPEED_10;
  975. break;
  976. case SPEED_100:
  977. reg = QCA8K_PORT_STATUS_SPEED_100;
  978. break;
  979. case SPEED_1000:
  980. reg = QCA8K_PORT_STATUS_SPEED_1000;
  981. break;
  982. default:
  983. reg = QCA8K_PORT_STATUS_LINK_AUTO;
  984. break;
  985. }
  986. if (duplex == DUPLEX_FULL)
  987. reg |= QCA8K_PORT_STATUS_DUPLEX;
  988. if (rx_pause || dsa_is_cpu_port(ds, port))
  989. reg |= QCA8K_PORT_STATUS_RXFLOW;
  990. if (tx_pause || dsa_is_cpu_port(ds, port))
  991. reg |= QCA8K_PORT_STATUS_TXFLOW;
  992. }
  993. reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
  994. qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
  995. }
  996. static void
  997. qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
  998. {
  999. int i;
  1000. if (stringset != ETH_SS_STATS)
  1001. return;
  1002. for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++)
  1003. strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
  1004. ETH_GSTRING_LEN);
  1005. }
  1006. static void
  1007. qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
  1008. uint64_t *data)
  1009. {
  1010. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1011. const struct qca8k_mib_desc *mib;
  1012. u32 reg, i, val;
  1013. u32 hi = 0;
  1014. int ret;
  1015. for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
  1016. mib = &ar8327_mib[i];
  1017. reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
  1018. ret = qca8k_read(priv, reg, &val);
  1019. if (ret < 0)
  1020. continue;
  1021. if (mib->size == 2) {
  1022. ret = qca8k_read(priv, reg + 4, &hi);
  1023. if (ret < 0)
  1024. continue;
  1025. }
  1026. data[i] = val;
  1027. if (mib->size == 2)
  1028. data[i] |= (u64)hi << 32;
  1029. }
  1030. }
  1031. static int
  1032. qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
  1033. {
  1034. if (sset != ETH_SS_STATS)
  1035. return 0;
  1036. return ARRAY_SIZE(ar8327_mib);
  1037. }
  1038. static int
  1039. qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
  1040. {
  1041. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1042. u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
  1043. u32 reg;
  1044. int ret;
  1045. mutex_lock(&priv->reg_mutex);
  1046. ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
  1047. if (ret < 0)
  1048. goto exit;
  1049. if (eee->eee_enabled)
  1050. reg |= lpi_en;
  1051. else
  1052. reg &= ~lpi_en;
  1053. ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
  1054. exit:
  1055. mutex_unlock(&priv->reg_mutex);
  1056. return ret;
  1057. }
  1058. static int
  1059. qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
  1060. {
  1061. /* Nothing to do on the port's MAC */
  1062. return 0;
  1063. }
  1064. static void
  1065. qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
  1066. {
  1067. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1068. u32 stp_state;
  1069. switch (state) {
  1070. case BR_STATE_DISABLED:
  1071. stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
  1072. break;
  1073. case BR_STATE_BLOCKING:
  1074. stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
  1075. break;
  1076. case BR_STATE_LISTENING:
  1077. stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
  1078. break;
  1079. case BR_STATE_LEARNING:
  1080. stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
  1081. break;
  1082. case BR_STATE_FORWARDING:
  1083. default:
  1084. stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
  1085. break;
  1086. }
  1087. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  1088. QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
  1089. }
  1090. static int
  1091. qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
  1092. {
  1093. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1094. int port_mask, cpu_port;
  1095. int i, ret;
  1096. cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
  1097. port_mask = BIT(cpu_port);
  1098. for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  1099. if (dsa_is_cpu_port(ds, i))
  1100. continue;
  1101. if (dsa_to_port(ds, i)->bridge_dev != br)
  1102. continue;
  1103. /* Add this port to the portvlan mask of the other ports
  1104. * in the bridge
  1105. */
  1106. ret = qca8k_reg_set(priv,
  1107. QCA8K_PORT_LOOKUP_CTRL(i),
  1108. BIT(port));
  1109. if (ret)
  1110. return ret;
  1111. if (i != port)
  1112. port_mask |= BIT(i);
  1113. }
  1114. /* Add all other ports to this ports portvlan mask */
  1115. ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  1116. QCA8K_PORT_LOOKUP_MEMBER, port_mask);
  1117. return ret;
  1118. }
  1119. static void
  1120. qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
  1121. {
  1122. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1123. int cpu_port, i;
  1124. cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
  1125. for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  1126. if (dsa_is_cpu_port(ds, i))
  1127. continue;
  1128. if (dsa_to_port(ds, i)->bridge_dev != br)
  1129. continue;
  1130. /* Remove this port to the portvlan mask of the other ports
  1131. * in the bridge
  1132. */
  1133. qca8k_reg_clear(priv,
  1134. QCA8K_PORT_LOOKUP_CTRL(i),
  1135. BIT(port));
  1136. }
  1137. /* Set the cpu port to be the only one in the portvlan mask of
  1138. * this port
  1139. */
  1140. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  1141. QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
  1142. }
  1143. void qca8k_port_fast_age(struct dsa_switch *ds, int port)
  1144. {
  1145. struct qca8k_priv *priv = ds->priv;
  1146. mutex_lock(&priv->reg_mutex);
  1147. qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
  1148. mutex_unlock(&priv->reg_mutex);
  1149. }
  1150. int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
  1151. {
  1152. struct qca8k_priv *priv = ds->priv;
  1153. unsigned int secs = msecs / 1000;
  1154. u32 val;
  1155. /* AGE_TIME reg is set in 7s step */
  1156. val = secs / 7;
  1157. /* Handle case with 0 as val to NOT disable
  1158. * learning
  1159. */
  1160. if (!val)
  1161. val = 1;
  1162. return qca8k_rmw(priv, QCA8K_REG_ATU_CTRL,
  1163. QCA8K_ATU_AGE_TIME_MASK,
  1164. QCA8K_ATU_AGE_TIME(val));
  1165. }
  1166. static int
  1167. qca8k_port_enable(struct dsa_switch *ds, int port,
  1168. struct phy_device *phy)
  1169. {
  1170. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1171. qca8k_port_set_status(priv, port, 1);
  1172. priv->port_sts[port].enabled = 1;
  1173. if (dsa_is_user_port(ds, port))
  1174. phy_support_asym_pause(phy);
  1175. return 0;
  1176. }
  1177. static void
  1178. qca8k_port_disable(struct dsa_switch *ds, int port)
  1179. {
  1180. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1181. qca8k_port_set_status(priv, port, 0);
  1182. priv->port_sts[port].enabled = 0;
  1183. }
  1184. static int
  1185. qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
  1186. {
  1187. struct qca8k_priv *priv = ds->priv;
  1188. int i, mtu = 0;
  1189. priv->port_mtu[port] = new_mtu;
  1190. for (i = 0; i < QCA8K_NUM_PORTS; i++)
  1191. if (priv->port_mtu[i] > mtu)
  1192. mtu = priv->port_mtu[i];
  1193. /* Include L2 header / FCS length */
  1194. return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
  1195. }
  1196. static int
  1197. qca8k_port_max_mtu(struct dsa_switch *ds, int port)
  1198. {
  1199. return QCA8K_MAX_MTU;
  1200. }
  1201. static int
  1202. qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
  1203. u16 port_mask, u16 vid)
  1204. {
  1205. /* Set the vid to the port vlan id if no vid is set */
  1206. if (!vid)
  1207. vid = QCA8K_PORT_VID_DEF;
  1208. return qca8k_fdb_add(priv, addr, port_mask, vid,
  1209. QCA8K_ATU_STATUS_STATIC);
  1210. }
  1211. static int
  1212. qca8k_port_fdb_add(struct dsa_switch *ds, int port,
  1213. const unsigned char *addr, u16 vid)
  1214. {
  1215. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1216. u16 port_mask = BIT(port);
  1217. return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
  1218. }
  1219. static int
  1220. qca8k_port_fdb_del(struct dsa_switch *ds, int port,
  1221. const unsigned char *addr, u16 vid)
  1222. {
  1223. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1224. u16 port_mask = BIT(port);
  1225. if (!vid)
  1226. vid = QCA8K_PORT_VID_DEF;
  1227. return qca8k_fdb_del(priv, addr, port_mask, vid);
  1228. }
  1229. static int
  1230. qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
  1231. dsa_fdb_dump_cb_t *cb, void *data)
  1232. {
  1233. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  1234. struct qca8k_fdb _fdb = { 0 };
  1235. int cnt = QCA8K_NUM_FDB_RECORDS;
  1236. bool is_static;
  1237. int ret = 0;
  1238. mutex_lock(&priv->reg_mutex);
  1239. while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
  1240. if (!_fdb.aging)
  1241. break;
  1242. is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
  1243. ret = cb(_fdb.mac, _fdb.vid, is_static, data);
  1244. if (ret)
  1245. break;
  1246. }
  1247. mutex_unlock(&priv->reg_mutex);
  1248. return 0;
  1249. }
  1250. static int
  1251. qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
  1252. struct netlink_ext_ack *extack)
  1253. {
  1254. struct qca8k_priv *priv = ds->priv;
  1255. if (vlan_filtering) {
  1256. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  1257. QCA8K_PORT_LOOKUP_VLAN_MODE,
  1258. QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
  1259. } else {
  1260. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  1261. QCA8K_PORT_LOOKUP_VLAN_MODE,
  1262. QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
  1263. }
  1264. return 0;
  1265. }
  1266. static int
  1267. qca8k_port_vlan_add(struct dsa_switch *ds, int port,
  1268. const struct switchdev_obj_port_vlan *vlan,
  1269. struct netlink_ext_ack *extack)
  1270. {
  1271. bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
  1272. bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
  1273. struct qca8k_priv *priv = ds->priv;
  1274. int ret = 0;
  1275. ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
  1276. if (ret) {
  1277. dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
  1278. return ret;
  1279. }
  1280. if (pvid) {
  1281. int shift = 16 * (port % 2);
  1282. qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
  1283. 0xfff << shift, vlan->vid << shift);
  1284. qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
  1285. QCA8K_PORT_VLAN_CVID(vlan->vid) |
  1286. QCA8K_PORT_VLAN_SVID(vlan->vid));
  1287. }
  1288. return 0;
  1289. }
  1290. static int
  1291. qca8k_port_vlan_del(struct dsa_switch *ds, int port,
  1292. const struct switchdev_obj_port_vlan *vlan)
  1293. {
  1294. struct qca8k_priv *priv = ds->priv;
  1295. int ret = 0;
  1296. ret = qca8k_vlan_del(priv, port, vlan->vid);
  1297. if (ret)
  1298. dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
  1299. return ret;
  1300. }
  1301. static enum dsa_tag_protocol
  1302. qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
  1303. enum dsa_tag_protocol mp)
  1304. {
  1305. return DSA_TAG_PROTO_IPQ4019;
  1306. }
  1307. static const struct dsa_switch_ops qca8k_switch_ops = {
  1308. .get_tag_protocol = qca8k_get_tag_protocol,
  1309. .setup = qca8k_setup,
  1310. .get_strings = qca8k_get_strings,
  1311. .get_ethtool_stats = qca8k_get_ethtool_stats,
  1312. .get_sset_count = qca8k_get_sset_count,
  1313. .set_ageing_time = qca8k_set_ageing_time,
  1314. .get_mac_eee = qca8k_get_mac_eee,
  1315. .set_mac_eee = qca8k_set_mac_eee,
  1316. .port_enable = qca8k_port_enable,
  1317. .port_disable = qca8k_port_disable,
  1318. .port_change_mtu = qca8k_port_change_mtu,
  1319. .port_max_mtu = qca8k_port_max_mtu,
  1320. .port_stp_state_set = qca8k_port_stp_state_set,
  1321. .port_bridge_join = qca8k_port_bridge_join,
  1322. .port_bridge_leave = qca8k_port_bridge_leave,
  1323. .port_fast_age = qca8k_port_fast_age,
  1324. .port_fdb_add = qca8k_port_fdb_add,
  1325. .port_fdb_del = qca8k_port_fdb_del,
  1326. .port_fdb_dump = qca8k_port_fdb_dump,
  1327. .port_vlan_filtering = qca8k_port_vlan_filtering,
  1328. .port_vlan_add = qca8k_port_vlan_add,
  1329. .port_vlan_del = qca8k_port_vlan_del,
  1330. .phylink_validate = qca8k_phylink_validate,
  1331. .phylink_mac_link_state = qca8k_phylink_mac_link_state,
  1332. .phylink_mac_config = qca8k_phylink_mac_config,
  1333. .phylink_mac_link_down = qca8k_phylink_mac_link_down,
  1334. .phylink_mac_link_up = qca8k_phylink_mac_link_up,
  1335. };
  1336. static int
  1337. qca8k_ipq4019_probe(struct platform_device *pdev)
  1338. {
  1339. struct qca8k_priv *priv;
  1340. void __iomem *base, *psgmii;
  1341. struct device_node *np = pdev->dev.of_node, *mdio_np, *psgmii_ethphy_np;
  1342. int ret;
  1343. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  1344. if (!priv)
  1345. return -ENOMEM;
  1346. priv->dev = &pdev->dev;
  1347. base = devm_platform_ioremap_resource_byname(pdev, "base");
  1348. if (IS_ERR(base))
  1349. return PTR_ERR(base);
  1350. priv->regmap = devm_regmap_init_mmio(priv->dev, base,
  1351. &qca8k_ipq4019_regmap_config);
  1352. if (IS_ERR(priv->regmap)) {
  1353. ret = PTR_ERR(priv->regmap);
  1354. dev_err(priv->dev, "base regmap initialization failed, %d\n", ret);
  1355. return ret;
  1356. }
  1357. psgmii = devm_platform_ioremap_resource_byname(pdev, "psgmii_phy");
  1358. if (IS_ERR(psgmii))
  1359. return PTR_ERR(psgmii);
  1360. priv->psgmii = devm_regmap_init_mmio(priv->dev, psgmii,
  1361. &qca8k_ipq4019_psgmii_phy_regmap_config);
  1362. if (IS_ERR(priv->psgmii)) {
  1363. ret = PTR_ERR(priv->psgmii);
  1364. dev_err(priv->dev, "PSGMII regmap initialization failed, %d\n", ret);
  1365. return ret;
  1366. }
  1367. mdio_np = of_parse_phandle(np, "mdio", 0);
  1368. if (!mdio_np) {
  1369. dev_err(&pdev->dev, "unable to get MDIO bus phandle\n");
  1370. of_node_put(mdio_np);
  1371. return -EINVAL;
  1372. }
  1373. priv->bus = of_mdio_find_bus(mdio_np);
  1374. of_node_put(mdio_np);
  1375. if (!priv->bus) {
  1376. dev_err(&pdev->dev, "unable to find MDIO bus\n");
  1377. return -EPROBE_DEFER;
  1378. }
  1379. psgmii_ethphy_np = of_parse_phandle(np, "psgmii-ethphy", 0);
  1380. if (!psgmii_ethphy_np) {
  1381. dev_dbg(&pdev->dev, "unable to get PSGMII eth PHY phandle\n");
  1382. of_node_put(psgmii_ethphy_np);
  1383. }
  1384. if (psgmii_ethphy_np) {
  1385. priv->psgmii_ethphy = of_phy_find_device(psgmii_ethphy_np);
  1386. of_node_put(psgmii_ethphy_np);
  1387. if (!priv->psgmii_ethphy) {
  1388. dev_err(&pdev->dev, "unable to get PSGMII eth PHY\n");
  1389. return -ENODEV;
  1390. }
  1391. }
  1392. priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
  1393. if (!priv->ds)
  1394. return -ENOMEM;
  1395. priv->ds->dev = priv->dev;
  1396. priv->ds->num_ports = QCA8K_NUM_PORTS;
  1397. priv->ds->priv = priv;
  1398. priv->ops = qca8k_switch_ops;
  1399. priv->ds->ops = &priv->ops;
  1400. mutex_init(&priv->reg_mutex);
  1401. platform_set_drvdata(pdev, priv);
  1402. return dsa_register_switch(priv->ds);
  1403. }
  1404. static int
  1405. qca8k_ipq4019_remove(struct platform_device *pdev)
  1406. {
  1407. struct qca8k_priv *priv = dev_get_drvdata(&pdev->dev);
  1408. int i;
  1409. if (!priv)
  1410. return 0;
  1411. for (i = 0; i < QCA8K_NUM_PORTS; i++)
  1412. qca8k_port_set_status(priv, i, 0);
  1413. dsa_unregister_switch(priv->ds);
  1414. dev_set_drvdata(&pdev->dev, NULL);
  1415. return 0;
  1416. }
  1417. static const struct of_device_id qca8k_ipq4019_of_match[] = {
  1418. { .compatible = "qca,ipq4019-qca8337n" },
  1419. { /* sentinel */ },
  1420. };
  1421. static struct platform_driver qca8k_ipq4019_driver = {
  1422. .probe = qca8k_ipq4019_probe,
  1423. .remove = qca8k_ipq4019_remove,
  1424. .driver = {
  1425. .name = "qca8k-ipq4019",
  1426. .of_match_table = qca8k_ipq4019_of_match,
  1427. },
  1428. };
  1429. module_platform_driver(qca8k_ipq4019_driver);
  1430. MODULE_AUTHOR("Mathieu Olivari, John Crispin <[email protected]>");
  1431. MODULE_AUTHOR("Gabor Juhos <[email protected]>, Robert Marko <[email protected]>");
  1432. MODULE_DESCRIPTION("Qualcomm IPQ4019 built-in switch driver");
  1433. MODULE_LICENSE("GPL v2");