mscc_main.c 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725
  1. // SPDX-License-Identifier: (GPL-2.0 OR MIT)
  2. /*
  3. * Driver for Microsemi VSC85xx PHYs
  4. *
  5. * Author: Nagaraju Lakkaraju
  6. * License: Dual MIT/GPL
  7. * Copyright (c) 2016 Microsemi Corporation
  8. */
  9. #include <linux/firmware.h>
  10. #include <linux/jiffies.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/mdio.h>
  14. #include <linux/mii.h>
  15. #include <linux/phy.h>
  16. #include <linux/of.h>
  17. #include <linux/netdevice.h>
  18. #include <dt-bindings/net/mscc-phy-vsc8531.h>
  19. #include "mscc_serdes.h"
  20. #include "mscc.h"
  21. static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
  22. {
  23. .string = "phy_receive_errors",
  24. .reg = MSCC_PHY_ERR_RX_CNT,
  25. .page = MSCC_PHY_PAGE_STANDARD,
  26. .mask = ERR_CNT_MASK,
  27. }, {
  28. .string = "phy_false_carrier",
  29. .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
  30. .page = MSCC_PHY_PAGE_STANDARD,
  31. .mask = ERR_CNT_MASK,
  32. }, {
  33. .string = "phy_cu_media_link_disconnect",
  34. .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
  35. .page = MSCC_PHY_PAGE_STANDARD,
  36. .mask = ERR_CNT_MASK,
  37. }, {
  38. .string = "phy_cu_media_crc_good_count",
  39. .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
  40. .page = MSCC_PHY_PAGE_EXTENDED,
  41. .mask = VALID_CRC_CNT_CRC_MASK,
  42. }, {
  43. .string = "phy_cu_media_crc_error_count",
  44. .reg = MSCC_PHY_EXT_PHY_CNTL_4,
  45. .page = MSCC_PHY_PAGE_EXTENDED,
  46. .mask = ERR_CNT_MASK,
  47. },
  48. };
  49. static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
  50. {
  51. .string = "phy_receive_errors",
  52. .reg = MSCC_PHY_ERR_RX_CNT,
  53. .page = MSCC_PHY_PAGE_STANDARD,
  54. .mask = ERR_CNT_MASK,
  55. }, {
  56. .string = "phy_false_carrier",
  57. .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
  58. .page = MSCC_PHY_PAGE_STANDARD,
  59. .mask = ERR_CNT_MASK,
  60. }, {
  61. .string = "phy_cu_media_link_disconnect",
  62. .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
  63. .page = MSCC_PHY_PAGE_STANDARD,
  64. .mask = ERR_CNT_MASK,
  65. }, {
  66. .string = "phy_cu_media_crc_good_count",
  67. .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
  68. .page = MSCC_PHY_PAGE_EXTENDED,
  69. .mask = VALID_CRC_CNT_CRC_MASK,
  70. }, {
  71. .string = "phy_cu_media_crc_error_count",
  72. .reg = MSCC_PHY_EXT_PHY_CNTL_4,
  73. .page = MSCC_PHY_PAGE_EXTENDED,
  74. .mask = ERR_CNT_MASK,
  75. }, {
  76. .string = "phy_serdes_tx_good_pkt_count",
  77. .reg = MSCC_PHY_SERDES_TX_VALID_CNT,
  78. .page = MSCC_PHY_PAGE_EXTENDED_3,
  79. .mask = VALID_CRC_CNT_CRC_MASK,
  80. }, {
  81. .string = "phy_serdes_tx_bad_crc_count",
  82. .reg = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
  83. .page = MSCC_PHY_PAGE_EXTENDED_3,
  84. .mask = ERR_CNT_MASK,
  85. }, {
  86. .string = "phy_serdes_rx_good_pkt_count",
  87. .reg = MSCC_PHY_SERDES_RX_VALID_CNT,
  88. .page = MSCC_PHY_PAGE_EXTENDED_3,
  89. .mask = VALID_CRC_CNT_CRC_MASK,
  90. }, {
  91. .string = "phy_serdes_rx_bad_crc_count",
  92. .reg = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
  93. .page = MSCC_PHY_PAGE_EXTENDED_3,
  94. .mask = ERR_CNT_MASK,
  95. },
  96. };
  97. #if IS_ENABLED(CONFIG_OF_MDIO)
  98. static const struct vsc8531_edge_rate_table edge_table[] = {
  99. {MSCC_VDDMAC_3300, { 0, 2, 4, 7, 10, 17, 29, 53} },
  100. {MSCC_VDDMAC_2500, { 0, 3, 6, 10, 14, 23, 37, 63} },
  101. {MSCC_VDDMAC_1800, { 0, 5, 9, 16, 23, 35, 52, 76} },
  102. {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
  103. };
  104. #endif
  105. static const int vsc85xx_internal_delay[] = {200, 800, 1100, 1700, 2000, 2300,
  106. 2600, 3400};
  107. static int vsc85xx_phy_read_page(struct phy_device *phydev)
  108. {
  109. return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
  110. }
  111. static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
  112. {
  113. return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
  114. }
  115. static int vsc85xx_get_sset_count(struct phy_device *phydev)
  116. {
  117. struct vsc8531_private *priv = phydev->priv;
  118. if (!priv)
  119. return 0;
  120. return priv->nstats;
  121. }
  122. static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
  123. {
  124. struct vsc8531_private *priv = phydev->priv;
  125. int i;
  126. if (!priv)
  127. return;
  128. for (i = 0; i < priv->nstats; i++)
  129. strscpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
  130. ETH_GSTRING_LEN);
  131. }
  132. static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
  133. {
  134. struct vsc8531_private *priv = phydev->priv;
  135. int val;
  136. val = phy_read_paged(phydev, priv->hw_stats[i].page,
  137. priv->hw_stats[i].reg);
  138. if (val < 0)
  139. return U64_MAX;
  140. val = val & priv->hw_stats[i].mask;
  141. priv->stats[i] += val;
  142. return priv->stats[i];
  143. }
  144. static void vsc85xx_get_stats(struct phy_device *phydev,
  145. struct ethtool_stats *stats, u64 *data)
  146. {
  147. struct vsc8531_private *priv = phydev->priv;
  148. int i;
  149. if (!priv)
  150. return;
  151. for (i = 0; i < priv->nstats; i++)
  152. data[i] = vsc85xx_get_stat(phydev, i);
  153. }
  154. static int vsc85xx_led_cntl_set(struct phy_device *phydev,
  155. u8 led_num,
  156. u8 mode)
  157. {
  158. int rc;
  159. u16 reg_val;
  160. mutex_lock(&phydev->lock);
  161. reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
  162. reg_val &= ~LED_MODE_SEL_MASK(led_num);
  163. reg_val |= LED_MODE_SEL(led_num, (u16)mode);
  164. rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
  165. mutex_unlock(&phydev->lock);
  166. return rc;
  167. }
  168. static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
  169. {
  170. u16 reg_val;
  171. reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
  172. if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
  173. *mdix = ETH_TP_MDI_X;
  174. else
  175. *mdix = ETH_TP_MDI;
  176. return 0;
  177. }
  178. static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
  179. {
  180. int rc;
  181. u16 reg_val;
  182. reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
  183. if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
  184. reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
  185. DISABLE_POLARITY_CORR_MASK |
  186. DISABLE_HP_AUTO_MDIX_MASK);
  187. } else {
  188. reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
  189. DISABLE_POLARITY_CORR_MASK |
  190. DISABLE_HP_AUTO_MDIX_MASK);
  191. }
  192. rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
  193. if (rc)
  194. return rc;
  195. reg_val = 0;
  196. if (mdix == ETH_TP_MDI)
  197. reg_val = FORCE_MDI_CROSSOVER_MDI;
  198. else if (mdix == ETH_TP_MDI_X)
  199. reg_val = FORCE_MDI_CROSSOVER_MDIX;
  200. rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
  201. MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
  202. reg_val);
  203. if (rc < 0)
  204. return rc;
  205. return genphy_restart_aneg(phydev);
  206. }
  207. static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
  208. {
  209. int reg_val;
  210. reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
  211. MSCC_PHY_ACTIPHY_CNTL);
  212. if (reg_val < 0)
  213. return reg_val;
  214. reg_val &= DOWNSHIFT_CNTL_MASK;
  215. if (!(reg_val & DOWNSHIFT_EN))
  216. *count = DOWNSHIFT_DEV_DISABLE;
  217. else
  218. *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
  219. return 0;
  220. }
  221. static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
  222. {
  223. if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
  224. /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
  225. count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
  226. } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
  227. phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
  228. return -ERANGE;
  229. } else if (count) {
  230. /* Downshift count is either 2,3,4 or 5 */
  231. count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
  232. }
  233. return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
  234. MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
  235. count);
  236. }
  237. static int vsc85xx_wol_set(struct phy_device *phydev,
  238. struct ethtool_wolinfo *wol)
  239. {
  240. const u8 *mac_addr = phydev->attached_dev->dev_addr;
  241. int rc;
  242. u16 reg_val;
  243. u8 i;
  244. u16 pwd[3] = {0, 0, 0};
  245. struct ethtool_wolinfo *wol_conf = wol;
  246. rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
  247. if (rc < 0)
  248. return phy_restore_page(phydev, rc, rc);
  249. if (wol->wolopts & WAKE_MAGIC) {
  250. /* Store the device address for the magic packet */
  251. for (i = 0; i < ARRAY_SIZE(pwd); i++)
  252. pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
  253. mac_addr[5 - i * 2];
  254. __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
  255. __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
  256. __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
  257. } else {
  258. __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
  259. __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
  260. __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
  261. }
  262. if (wol_conf->wolopts & WAKE_MAGICSECURE) {
  263. for (i = 0; i < ARRAY_SIZE(pwd); i++)
  264. pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
  265. wol_conf->sopass[5 - i * 2];
  266. __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
  267. __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
  268. __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
  269. } else {
  270. __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
  271. __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
  272. __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
  273. }
  274. reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
  275. if (wol_conf->wolopts & WAKE_MAGICSECURE)
  276. reg_val |= SECURE_ON_ENABLE;
  277. else
  278. reg_val &= ~SECURE_ON_ENABLE;
  279. __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
  280. rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
  281. if (rc < 0)
  282. return rc;
  283. if (wol->wolopts & WAKE_MAGIC) {
  284. /* Enable the WOL interrupt */
  285. reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
  286. reg_val |= MII_VSC85XX_INT_MASK_WOL;
  287. rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
  288. if (rc)
  289. return rc;
  290. } else {
  291. /* Disable the WOL interrupt */
  292. reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
  293. reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
  294. rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
  295. if (rc)
  296. return rc;
  297. }
  298. /* Clear WOL iterrupt status */
  299. reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
  300. return 0;
  301. }
  302. static void vsc85xx_wol_get(struct phy_device *phydev,
  303. struct ethtool_wolinfo *wol)
  304. {
  305. int rc;
  306. u16 reg_val;
  307. u8 i;
  308. u16 pwd[3] = {0, 0, 0};
  309. struct ethtool_wolinfo *wol_conf = wol;
  310. rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
  311. if (rc < 0)
  312. goto out_restore_page;
  313. reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
  314. if (reg_val & SECURE_ON_ENABLE)
  315. wol_conf->wolopts |= WAKE_MAGICSECURE;
  316. if (wol_conf->wolopts & WAKE_MAGICSECURE) {
  317. pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
  318. pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
  319. pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
  320. for (i = 0; i < ARRAY_SIZE(pwd); i++) {
  321. wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
  322. wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
  323. >> 8;
  324. }
  325. }
  326. out_restore_page:
  327. phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
  328. }
  329. #if IS_ENABLED(CONFIG_OF_MDIO)
  330. static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
  331. {
  332. u32 vdd, sd;
  333. int i, j;
  334. struct device *dev = &phydev->mdio.dev;
  335. struct device_node *of_node = dev->of_node;
  336. u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
  337. if (!of_node)
  338. return -ENODEV;
  339. if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
  340. vdd = MSCC_VDDMAC_3300;
  341. if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
  342. sd = 0;
  343. for (i = 0; i < ARRAY_SIZE(edge_table); i++)
  344. if (edge_table[i].vddmac == vdd)
  345. for (j = 0; j < sd_array_size; j++)
  346. if (edge_table[i].slowdown[j] == sd)
  347. return (sd_array_size - j - 1);
  348. return -EINVAL;
  349. }
  350. static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
  351. char *led,
  352. u32 default_mode)
  353. {
  354. struct vsc8531_private *priv = phydev->priv;
  355. struct device *dev = &phydev->mdio.dev;
  356. struct device_node *of_node = dev->of_node;
  357. u32 led_mode;
  358. int err;
  359. if (!of_node)
  360. return -ENODEV;
  361. led_mode = default_mode;
  362. err = of_property_read_u32(of_node, led, &led_mode);
  363. if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
  364. phydev_err(phydev, "DT %s invalid\n", led);
  365. return -EINVAL;
  366. }
  367. return led_mode;
  368. }
  369. #else
  370. static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
  371. {
  372. return 0;
  373. }
  374. static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
  375. char *led,
  376. u8 default_mode)
  377. {
  378. return default_mode;
  379. }
  380. #endif /* CONFIG_OF_MDIO */
  381. static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
  382. u32 *default_mode)
  383. {
  384. struct vsc8531_private *priv = phydev->priv;
  385. char led_dt_prop[28];
  386. int i, ret;
  387. for (i = 0; i < priv->nleds; i++) {
  388. ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
  389. if (ret < 0)
  390. return ret;
  391. ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
  392. default_mode[i]);
  393. if (ret < 0)
  394. return ret;
  395. priv->leds_mode[i] = ret;
  396. }
  397. return 0;
  398. }
  399. static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
  400. {
  401. int rc;
  402. mutex_lock(&phydev->lock);
  403. rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
  404. MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
  405. edge_rate << EDGE_RATE_CNTL_POS);
  406. mutex_unlock(&phydev->lock);
  407. return rc;
  408. }
  409. static int vsc85xx_mac_if_set(struct phy_device *phydev,
  410. phy_interface_t interface)
  411. {
  412. int rc;
  413. u16 reg_val;
  414. mutex_lock(&phydev->lock);
  415. reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
  416. reg_val &= ~(MAC_IF_SELECTION_MASK);
  417. switch (interface) {
  418. case PHY_INTERFACE_MODE_RGMII_TXID:
  419. case PHY_INTERFACE_MODE_RGMII_RXID:
  420. case PHY_INTERFACE_MODE_RGMII_ID:
  421. case PHY_INTERFACE_MODE_RGMII:
  422. reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
  423. break;
  424. case PHY_INTERFACE_MODE_RMII:
  425. reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
  426. break;
  427. case PHY_INTERFACE_MODE_MII:
  428. case PHY_INTERFACE_MODE_GMII:
  429. reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
  430. break;
  431. default:
  432. rc = -EINVAL;
  433. goto out_unlock;
  434. }
  435. rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
  436. if (rc)
  437. goto out_unlock;
  438. rc = genphy_soft_reset(phydev);
  439. out_unlock:
  440. mutex_unlock(&phydev->lock);
  441. return rc;
  442. }
  443. /* Set the RGMII RX and TX clock skews individually, according to the PHY
  444. * interface type, to:
  445. * * 0.2 ns (their default, and lowest, hardware value) if delays should
  446. * not be enabled
  447. * * 2.0 ns (which causes the data to be sampled at exactly half way between
  448. * clock transitions at 1000 Mbps) if delays should be enabled
  449. */
  450. static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl,
  451. u16 rgmii_rx_delay_mask,
  452. u16 rgmii_tx_delay_mask)
  453. {
  454. u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
  455. u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
  456. int delay_size = ARRAY_SIZE(vsc85xx_internal_delay);
  457. struct device *dev = &phydev->mdio.dev;
  458. u16 reg_val = 0;
  459. u16 mask = 0;
  460. s32 rx_delay;
  461. s32 tx_delay;
  462. int rc = 0;
  463. /* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit
  464. * to be unset for all PHY modes, so do that as part of the paged
  465. * register modification.
  466. * For some family members (like VSC8530/31/40/41) this bit is reserved
  467. * and read-only, and the RX clock is enabled by default.
  468. */
  469. if (rgmii_cntl == VSC8502_RGMII_CNTL)
  470. mask |= VSC8502_RGMII_RX_CLK_DISABLE;
  471. if (phy_interface_is_rgmii(phydev))
  472. mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask;
  473. rx_delay = phy_get_internal_delay(phydev, dev, vsc85xx_internal_delay,
  474. delay_size, true);
  475. if (rx_delay < 0) {
  476. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
  477. phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  478. rx_delay = RGMII_CLK_DELAY_2_0_NS;
  479. else
  480. rx_delay = RGMII_CLK_DELAY_0_2_NS;
  481. }
  482. tx_delay = phy_get_internal_delay(phydev, dev, vsc85xx_internal_delay,
  483. delay_size, false);
  484. if (tx_delay < 0) {
  485. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
  486. phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  487. tx_delay = RGMII_CLK_DELAY_2_0_NS;
  488. else
  489. tx_delay = RGMII_CLK_DELAY_0_2_NS;
  490. }
  491. reg_val |= rx_delay << rgmii_rx_delay_pos;
  492. reg_val |= tx_delay << rgmii_tx_delay_pos;
  493. if (mask)
  494. rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
  495. rgmii_cntl, mask, reg_val);
  496. return rc;
  497. }
  498. static int vsc85xx_default_config(struct phy_device *phydev)
  499. {
  500. phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
  501. return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL,
  502. VSC8502_RGMII_RX_DELAY_MASK,
  503. VSC8502_RGMII_TX_DELAY_MASK);
  504. }
  505. static int vsc85xx_get_tunable(struct phy_device *phydev,
  506. struct ethtool_tunable *tuna, void *data)
  507. {
  508. switch (tuna->id) {
  509. case ETHTOOL_PHY_DOWNSHIFT:
  510. return vsc85xx_downshift_get(phydev, (u8 *)data);
  511. default:
  512. return -EINVAL;
  513. }
  514. }
  515. static int vsc85xx_set_tunable(struct phy_device *phydev,
  516. struct ethtool_tunable *tuna,
  517. const void *data)
  518. {
  519. switch (tuna->id) {
  520. case ETHTOOL_PHY_DOWNSHIFT:
  521. return vsc85xx_downshift_set(phydev, *(u8 *)data);
  522. default:
  523. return -EINVAL;
  524. }
  525. }
  526. /* mdiobus lock should be locked when using this function */
  527. static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
  528. {
  529. __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
  530. __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
  531. __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
  532. }
  533. static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
  534. {
  535. int rc;
  536. static const struct reg_val init_seq[] = {
  537. {0x0f90, 0x00688980},
  538. {0x0696, 0x00000003},
  539. {0x07fa, 0x0050100f},
  540. {0x1686, 0x00000004},
  541. };
  542. unsigned int i;
  543. int oldpage;
  544. rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
  545. MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
  546. SMI_BROADCAST_WR_EN);
  547. if (rc < 0)
  548. return rc;
  549. rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
  550. MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
  551. if (rc < 0)
  552. return rc;
  553. rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
  554. MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
  555. if (rc < 0)
  556. return rc;
  557. rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
  558. MSCC_PHY_TEST_PAGE_8, TR_CLK_DISABLE, TR_CLK_DISABLE);
  559. if (rc < 0)
  560. return rc;
  561. mutex_lock(&phydev->lock);
  562. oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
  563. if (oldpage < 0)
  564. goto out_unlock;
  565. for (i = 0; i < ARRAY_SIZE(init_seq); i++)
  566. vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
  567. out_unlock:
  568. oldpage = phy_restore_page(phydev, oldpage, oldpage);
  569. mutex_unlock(&phydev->lock);
  570. return oldpage;
  571. }
  572. static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
  573. {
  574. static const struct reg_val init_eee[] = {
  575. {0x0f82, 0x0012b00a},
  576. {0x1686, 0x00000004},
  577. {0x168c, 0x00d2c46f},
  578. {0x17a2, 0x00000620},
  579. {0x16a0, 0x00eeffdd},
  580. {0x16a6, 0x00071448},
  581. {0x16a4, 0x0013132f},
  582. {0x16a8, 0x00000000},
  583. {0x0ffc, 0x00c0a028},
  584. {0x0fe8, 0x0091b06c},
  585. {0x0fea, 0x00041600},
  586. {0x0f80, 0x00000af4},
  587. {0x0fec, 0x00901809},
  588. {0x0fee, 0x0000a6a1},
  589. {0x0ffe, 0x00b01007},
  590. {0x16b0, 0x00eeff00},
  591. {0x16b2, 0x00007000},
  592. {0x16b4, 0x00000814},
  593. };
  594. unsigned int i;
  595. int oldpage;
  596. mutex_lock(&phydev->lock);
  597. oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
  598. if (oldpage < 0)
  599. goto out_unlock;
  600. for (i = 0; i < ARRAY_SIZE(init_eee); i++)
  601. vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
  602. out_unlock:
  603. oldpage = phy_restore_page(phydev, oldpage, oldpage);
  604. mutex_unlock(&phydev->lock);
  605. return oldpage;
  606. }
  607. /* phydev->bus->mdio_lock should be locked when using this function */
  608. int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
  609. {
  610. if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
  611. dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
  612. dump_stack();
  613. }
  614. return __phy_package_write(phydev, VSC88XX_BASE_ADDR, regnum, val);
  615. }
  616. /* phydev->bus->mdio_lock should be locked when using this function */
  617. int phy_base_read(struct phy_device *phydev, u32 regnum)
  618. {
  619. if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
  620. dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
  621. dump_stack();
  622. }
  623. return __phy_package_read(phydev, VSC88XX_BASE_ADDR, regnum);
  624. }
  625. u32 vsc85xx_csr_read(struct phy_device *phydev,
  626. enum csr_target target, u32 reg)
  627. {
  628. unsigned long deadline;
  629. u32 val, val_l, val_h;
  630. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
  631. /* CSR registers are grouped under different Target IDs.
  632. * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
  633. * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
  634. * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
  635. * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
  636. */
  637. /* Setup the Target ID */
  638. phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
  639. MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
  640. if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
  641. /* non-MACsec access */
  642. target &= 0x3;
  643. else
  644. target = 0;
  645. /* Trigger CSR Action - Read into the CSR's */
  646. phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
  647. MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
  648. MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
  649. MSCC_PHY_CSR_CNTL_19_TARGET(target));
  650. /* Wait for register access*/
  651. deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
  652. do {
  653. usleep_range(500, 1000);
  654. val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
  655. } while (time_before(jiffies, deadline) &&
  656. !(val & MSCC_PHY_CSR_CNTL_19_CMD));
  657. if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
  658. return 0xffffffff;
  659. /* Read the Least Significant Word (LSW) (17) */
  660. val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
  661. /* Read the Most Significant Word (MSW) (18) */
  662. val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
  663. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  664. MSCC_PHY_PAGE_STANDARD);
  665. return (val_h << 16) | val_l;
  666. }
  667. int vsc85xx_csr_write(struct phy_device *phydev,
  668. enum csr_target target, u32 reg, u32 val)
  669. {
  670. unsigned long deadline;
  671. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
  672. /* CSR registers are grouped under different Target IDs.
  673. * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
  674. * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
  675. * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
  676. * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
  677. */
  678. /* Setup the Target ID */
  679. phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
  680. MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
  681. /* Write the Least Significant Word (LSW) (17) */
  682. phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
  683. /* Write the Most Significant Word (MSW) (18) */
  684. phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
  685. if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
  686. /* non-MACsec access */
  687. target &= 0x3;
  688. else
  689. target = 0;
  690. /* Trigger CSR Action - Write into the CSR's */
  691. phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
  692. MSCC_PHY_CSR_CNTL_19_CMD |
  693. MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
  694. MSCC_PHY_CSR_CNTL_19_TARGET(target));
  695. /* Wait for register access */
  696. deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
  697. do {
  698. usleep_range(500, 1000);
  699. val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
  700. } while (time_before(jiffies, deadline) &&
  701. !(val & MSCC_PHY_CSR_CNTL_19_CMD));
  702. if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
  703. return -ETIMEDOUT;
  704. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  705. MSCC_PHY_PAGE_STANDARD);
  706. return 0;
  707. }
  708. /* bus->mdio_lock should be locked when using this function */
  709. static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
  710. {
  711. phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
  712. phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
  713. phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
  714. }
  715. /* bus->mdio_lock should be locked when using this function */
  716. int vsc8584_cmd(struct phy_device *phydev, u16 val)
  717. {
  718. unsigned long deadline;
  719. u16 reg_val;
  720. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  721. MSCC_PHY_PAGE_EXTENDED_GPIO);
  722. phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
  723. deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
  724. do {
  725. reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
  726. } while (time_before(jiffies, deadline) &&
  727. (reg_val & PROC_CMD_NCOMPLETED) &&
  728. !(reg_val & PROC_CMD_FAILED));
  729. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  730. if (reg_val & PROC_CMD_FAILED)
  731. return -EIO;
  732. if (reg_val & PROC_CMD_NCOMPLETED)
  733. return -ETIMEDOUT;
  734. return 0;
  735. }
  736. /* bus->mdio_lock should be locked when using this function */
  737. static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
  738. bool patch_en)
  739. {
  740. u32 enable, release;
  741. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  742. MSCC_PHY_PAGE_EXTENDED_GPIO);
  743. enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
  744. release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
  745. MICRO_CLK_EN;
  746. if (patch_en) {
  747. enable |= MICRO_PATCH_EN;
  748. release |= MICRO_PATCH_EN;
  749. /* Clear all patches */
  750. phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
  751. }
  752. /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
  753. * override and addr. auto-incr; operate at 125 MHz
  754. */
  755. phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
  756. /* Release 8051 Micro SW reset */
  757. phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
  758. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  759. return 0;
  760. }
  761. /* bus->mdio_lock should be locked when using this function */
  762. static int vsc8584_micro_assert_reset(struct phy_device *phydev)
  763. {
  764. int ret;
  765. u16 reg;
  766. ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
  767. if (ret)
  768. return ret;
  769. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  770. MSCC_PHY_PAGE_EXTENDED_GPIO);
  771. reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
  772. reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
  773. phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
  774. phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
  775. phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
  776. reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
  777. reg |= EN_PATCH_RAM_TRAP_ADDR(4);
  778. phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
  779. phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
  780. reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
  781. reg &= ~MICRO_NSOFT_RESET;
  782. phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
  783. phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
  784. PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
  785. PROC_CMD_READ);
  786. reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
  787. reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
  788. phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
  789. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  790. return 0;
  791. }
  792. /* bus->mdio_lock should be locked when using this function */
  793. static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
  794. u16 *crc)
  795. {
  796. int ret;
  797. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
  798. phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
  799. phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
  800. /* Start Micro command */
  801. ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
  802. if (ret)
  803. goto out;
  804. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
  805. *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
  806. out:
  807. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  808. return ret;
  809. }
  810. /* bus->mdio_lock should be locked when using this function */
  811. static int vsc8584_patch_fw(struct phy_device *phydev,
  812. const struct firmware *fw)
  813. {
  814. int i, ret;
  815. ret = vsc8584_micro_assert_reset(phydev);
  816. if (ret) {
  817. dev_err(&phydev->mdio.dev,
  818. "%s: failed to assert reset of micro\n", __func__);
  819. return ret;
  820. }
  821. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  822. MSCC_PHY_PAGE_EXTENDED_GPIO);
  823. /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
  824. * Disable the 8051 Micro clock
  825. */
  826. phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
  827. AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
  828. MICRO_CLK_DIVIDE(2));
  829. phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
  830. INT_MEM_DATA(2));
  831. phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
  832. for (i = 0; i < fw->size; i++)
  833. phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
  834. INT_MEM_WRITE_EN | fw->data[i]);
  835. /* Clear internal memory access */
  836. phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
  837. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  838. return 0;
  839. }
  840. /* bus->mdio_lock should be locked when using this function */
  841. static bool vsc8574_is_serdes_init(struct phy_device *phydev)
  842. {
  843. u16 reg;
  844. bool ret;
  845. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  846. MSCC_PHY_PAGE_EXTENDED_GPIO);
  847. reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
  848. if (reg != 0x3eb7) {
  849. ret = false;
  850. goto out;
  851. }
  852. reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
  853. if (reg != 0x4012) {
  854. ret = false;
  855. goto out;
  856. }
  857. reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
  858. if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
  859. ret = false;
  860. goto out;
  861. }
  862. reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
  863. if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
  864. MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
  865. ret = false;
  866. goto out;
  867. }
  868. ret = true;
  869. out:
  870. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  871. return ret;
  872. }
  873. /* bus->mdio_lock should be locked when using this function */
  874. static int vsc8574_config_pre_init(struct phy_device *phydev)
  875. {
  876. static const struct reg_val pre_init1[] = {
  877. {0x0fae, 0x000401bd},
  878. {0x0fac, 0x000f000f},
  879. {0x17a0, 0x00a0f147},
  880. {0x0fe4, 0x00052f54},
  881. {0x1792, 0x0027303d},
  882. {0x07fe, 0x00000704},
  883. {0x0fe0, 0x00060150},
  884. {0x0f82, 0x0012b00a},
  885. {0x0f80, 0x00000d74},
  886. {0x02e0, 0x00000012},
  887. {0x03a2, 0x00050208},
  888. {0x03b2, 0x00009186},
  889. {0x0fb0, 0x000e3700},
  890. {0x1688, 0x00049f81},
  891. {0x0fd2, 0x0000ffff},
  892. {0x168a, 0x00039fa2},
  893. {0x1690, 0x0020640b},
  894. {0x0258, 0x00002220},
  895. {0x025a, 0x00002a20},
  896. {0x025c, 0x00003060},
  897. {0x025e, 0x00003fa0},
  898. {0x03a6, 0x0000e0f0},
  899. {0x0f92, 0x00001489},
  900. {0x16a2, 0x00007000},
  901. {0x16a6, 0x00071448},
  902. {0x16a0, 0x00eeffdd},
  903. {0x0fe8, 0x0091b06c},
  904. {0x0fea, 0x00041600},
  905. {0x16b0, 0x00eeff00},
  906. {0x16b2, 0x00007000},
  907. {0x16b4, 0x00000814},
  908. {0x0f90, 0x00688980},
  909. {0x03a4, 0x0000d8f0},
  910. {0x0fc0, 0x00000400},
  911. {0x07fa, 0x0050100f},
  912. {0x0796, 0x00000003},
  913. {0x07f8, 0x00c3ff98},
  914. {0x0fa4, 0x0018292a},
  915. {0x168c, 0x00d2c46f},
  916. {0x17a2, 0x00000620},
  917. {0x16a4, 0x0013132f},
  918. {0x16a8, 0x00000000},
  919. {0x0ffc, 0x00c0a028},
  920. {0x0fec, 0x00901c09},
  921. {0x0fee, 0x0004a6a1},
  922. {0x0ffe, 0x00b01807},
  923. };
  924. static const struct reg_val pre_init2[] = {
  925. {0x0486, 0x0008a518},
  926. {0x0488, 0x006dc696},
  927. {0x048a, 0x00000912},
  928. {0x048e, 0x00000db6},
  929. {0x049c, 0x00596596},
  930. {0x049e, 0x00000514},
  931. {0x04a2, 0x00410280},
  932. {0x04a4, 0x00000000},
  933. {0x04a6, 0x00000000},
  934. {0x04a8, 0x00000000},
  935. {0x04aa, 0x00000000},
  936. {0x04ae, 0x007df7dd},
  937. {0x04b0, 0x006d95d4},
  938. {0x04b2, 0x00492410},
  939. };
  940. struct device *dev = &phydev->mdio.dev;
  941. const struct firmware *fw;
  942. unsigned int i;
  943. u16 crc, reg;
  944. bool serdes_init;
  945. int ret;
  946. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  947. /* all writes below are broadcasted to all PHYs in the same package */
  948. reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
  949. reg |= SMI_BROADCAST_WR_EN;
  950. phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
  951. phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
  952. /* The below register writes are tweaking analog and electrical
  953. * configuration that were determined through characterization by PHY
  954. * engineers. These don't mean anything more than "these are the best
  955. * values".
  956. */
  957. phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
  958. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
  959. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
  960. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
  961. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
  962. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
  963. reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
  964. reg |= TR_CLK_DISABLE;
  965. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
  966. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
  967. for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
  968. vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
  969. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
  970. phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
  971. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
  972. for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
  973. vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
  974. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
  975. reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
  976. reg &= ~TR_CLK_DISABLE;
  977. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
  978. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  979. /* end of write broadcasting */
  980. reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
  981. reg &= ~SMI_BROADCAST_WR_EN;
  982. phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
  983. ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
  984. if (ret) {
  985. dev_err(dev, "failed to load firmware %s, ret: %d\n",
  986. MSCC_VSC8574_REVB_INT8051_FW, ret);
  987. return ret;
  988. }
  989. /* Add one byte to size for the one added by the patch_fw function */
  990. ret = vsc8584_get_fw_crc(phydev,
  991. MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
  992. fw->size + 1, &crc);
  993. if (ret)
  994. goto out;
  995. if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
  996. serdes_init = vsc8574_is_serdes_init(phydev);
  997. if (!serdes_init) {
  998. ret = vsc8584_micro_assert_reset(phydev);
  999. if (ret) {
  1000. dev_err(dev,
  1001. "%s: failed to assert reset of micro\n",
  1002. __func__);
  1003. goto out;
  1004. }
  1005. }
  1006. } else {
  1007. dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
  1008. serdes_init = false;
  1009. if (vsc8584_patch_fw(phydev, fw))
  1010. dev_warn(dev,
  1011. "failed to patch FW, expect non-optimal device\n");
  1012. }
  1013. if (!serdes_init) {
  1014. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1015. MSCC_PHY_PAGE_EXTENDED_GPIO);
  1016. phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
  1017. phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
  1018. phy_base_write(phydev, MSCC_INT_MEM_CNTL,
  1019. EN_PATCH_RAM_TRAP_ADDR(1));
  1020. vsc8584_micro_deassert_reset(phydev, false);
  1021. /* Add one byte to size for the one added by the patch_fw
  1022. * function
  1023. */
  1024. ret = vsc8584_get_fw_crc(phydev,
  1025. MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
  1026. fw->size + 1, &crc);
  1027. if (ret)
  1028. goto out;
  1029. if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
  1030. dev_warn(dev,
  1031. "FW CRC after patching is not the expected one, expect non-optimal device\n");
  1032. }
  1033. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1034. MSCC_PHY_PAGE_EXTENDED_GPIO);
  1035. ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
  1036. PROC_CMD_PHY_INIT);
  1037. out:
  1038. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  1039. release_firmware(fw);
  1040. return ret;
  1041. }
  1042. /* Access LCPLL Cfg_2 */
  1043. static void vsc8584_pll5g_cfg2_wr(struct phy_device *phydev,
  1044. bool disable_fsm)
  1045. {
  1046. u32 rd_dat;
  1047. rd_dat = vsc85xx_csr_read(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2);
  1048. rd_dat &= ~BIT(PHY_S6G_CFG2_FSM_DIS);
  1049. rd_dat |= (disable_fsm << PHY_S6G_CFG2_FSM_DIS);
  1050. vsc85xx_csr_write(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2, rd_dat);
  1051. }
  1052. /* trigger a read to the spcified MCB */
  1053. static int vsc8584_mcb_rd_trig(struct phy_device *phydev,
  1054. u32 mcb_reg_addr, u8 mcb_slave_num)
  1055. {
  1056. u32 rd_dat = 0;
  1057. /* read MCB */
  1058. vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
  1059. (0x40000000 | (1L << mcb_slave_num)));
  1060. return read_poll_timeout(vsc85xx_csr_read, rd_dat,
  1061. !(rd_dat & 0x40000000),
  1062. 4000, 200000, 0,
  1063. phydev, MACRO_CTRL, mcb_reg_addr);
  1064. }
  1065. /* trigger a write to the spcified MCB */
  1066. static int vsc8584_mcb_wr_trig(struct phy_device *phydev,
  1067. u32 mcb_reg_addr,
  1068. u8 mcb_slave_num)
  1069. {
  1070. u32 rd_dat = 0;
  1071. /* write back MCB */
  1072. vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
  1073. (0x80000000 | (1L << mcb_slave_num)));
  1074. return read_poll_timeout(vsc85xx_csr_read, rd_dat,
  1075. !(rd_dat & 0x80000000),
  1076. 4000, 200000, 0,
  1077. phydev, MACRO_CTRL, mcb_reg_addr);
  1078. }
  1079. /* Sequence to Reset LCPLL for the VIPER and ELISE PHY */
  1080. static int vsc8584_pll5g_reset(struct phy_device *phydev)
  1081. {
  1082. bool dis_fsm;
  1083. int ret = 0;
  1084. ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
  1085. if (ret < 0)
  1086. goto done;
  1087. dis_fsm = 1;
  1088. /* Reset LCPLL */
  1089. vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
  1090. /* write back LCPLL MCB */
  1091. ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
  1092. if (ret < 0)
  1093. goto done;
  1094. /* 10 mSec sleep while LCPLL is hold in reset */
  1095. usleep_range(10000, 20000);
  1096. /* read LCPLL MCB into CSRs */
  1097. ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
  1098. if (ret < 0)
  1099. goto done;
  1100. dis_fsm = 0;
  1101. /* Release the Reset of LCPLL */
  1102. vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
  1103. /* write back LCPLL MCB */
  1104. ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
  1105. if (ret < 0)
  1106. goto done;
  1107. usleep_range(110000, 200000);
  1108. done:
  1109. return ret;
  1110. }
  1111. /* bus->mdio_lock should be locked when using this function */
  1112. static int vsc8584_config_pre_init(struct phy_device *phydev)
  1113. {
  1114. static const struct reg_val pre_init1[] = {
  1115. {0x07fa, 0x0050100f},
  1116. {0x1688, 0x00049f81},
  1117. {0x0f90, 0x00688980},
  1118. {0x03a4, 0x0000d8f0},
  1119. {0x0fc0, 0x00000400},
  1120. {0x0f82, 0x0012b002},
  1121. {0x1686, 0x00000004},
  1122. {0x168c, 0x00d2c46f},
  1123. {0x17a2, 0x00000620},
  1124. {0x16a0, 0x00eeffdd},
  1125. {0x16a6, 0x00071448},
  1126. {0x16a4, 0x0013132f},
  1127. {0x16a8, 0x00000000},
  1128. {0x0ffc, 0x00c0a028},
  1129. {0x0fe8, 0x0091b06c},
  1130. {0x0fea, 0x00041600},
  1131. {0x0f80, 0x00fffaff},
  1132. {0x0fec, 0x00901809},
  1133. {0x0ffe, 0x00b01007},
  1134. {0x16b0, 0x00eeff00},
  1135. {0x16b2, 0x00007000},
  1136. {0x16b4, 0x00000814},
  1137. };
  1138. static const struct reg_val pre_init2[] = {
  1139. {0x0486, 0x0008a518},
  1140. {0x0488, 0x006dc696},
  1141. {0x048a, 0x00000912},
  1142. };
  1143. const struct firmware *fw;
  1144. struct device *dev = &phydev->mdio.dev;
  1145. unsigned int i;
  1146. u16 crc, reg;
  1147. int ret;
  1148. ret = vsc8584_pll5g_reset(phydev);
  1149. if (ret < 0) {
  1150. dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
  1151. return ret;
  1152. }
  1153. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  1154. /* all writes below are broadcasted to all PHYs in the same package */
  1155. reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
  1156. reg |= SMI_BROADCAST_WR_EN;
  1157. phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
  1158. phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
  1159. reg = phy_base_read(phydev, MSCC_PHY_BYPASS_CONTROL);
  1160. reg |= PARALLEL_DET_IGNORE_ADVERTISED;
  1161. phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
  1162. /* The below register writes are tweaking analog and electrical
  1163. * configuration that were determined through characterization by PHY
  1164. * engineers. These don't mean anything more than "these are the best
  1165. * values".
  1166. */
  1167. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
  1168. phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
  1169. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
  1170. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
  1171. reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
  1172. reg |= TR_CLK_DISABLE;
  1173. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
  1174. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
  1175. phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
  1176. reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
  1177. reg &= ~0x007f;
  1178. reg |= 0x0019;
  1179. phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
  1180. phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
  1181. for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
  1182. vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
  1183. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
  1184. phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
  1185. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
  1186. for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
  1187. vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
  1188. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
  1189. reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
  1190. reg &= ~TR_CLK_DISABLE;
  1191. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
  1192. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  1193. /* end of write broadcasting */
  1194. reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
  1195. reg &= ~SMI_BROADCAST_WR_EN;
  1196. phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
  1197. ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
  1198. if (ret) {
  1199. dev_err(dev, "failed to load firmware %s, ret: %d\n",
  1200. MSCC_VSC8584_REVB_INT8051_FW, ret);
  1201. return ret;
  1202. }
  1203. /* Add one byte to size for the one added by the patch_fw function */
  1204. ret = vsc8584_get_fw_crc(phydev,
  1205. MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
  1206. fw->size + 1, &crc);
  1207. if (ret)
  1208. goto out;
  1209. if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
  1210. dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
  1211. if (vsc8584_patch_fw(phydev, fw))
  1212. dev_warn(dev,
  1213. "failed to patch FW, expect non-optimal device\n");
  1214. }
  1215. vsc8584_micro_deassert_reset(phydev, false);
  1216. /* Add one byte to size for the one added by the patch_fw function */
  1217. ret = vsc8584_get_fw_crc(phydev,
  1218. MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
  1219. fw->size + 1, &crc);
  1220. if (ret)
  1221. goto out;
  1222. if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
  1223. dev_warn(dev,
  1224. "FW CRC after patching is not the expected one, expect non-optimal device\n");
  1225. ret = vsc8584_micro_assert_reset(phydev);
  1226. if (ret)
  1227. goto out;
  1228. /* Write patch vector 0, to skip IB cal polling */
  1229. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_GPIO);
  1230. reg = MSCC_ROM_TRAP_SERDES_6G_CFG; /* ROM address to trap, for patch vector 0 */
  1231. ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
  1232. if (ret)
  1233. goto out;
  1234. reg = MSCC_RAM_TRAP_SERDES_6G_CFG; /* RAM address to jump to, when patch vector 0 enabled */
  1235. ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
  1236. if (ret)
  1237. goto out;
  1238. reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
  1239. reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
  1240. ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
  1241. if (ret)
  1242. goto out;
  1243. vsc8584_micro_deassert_reset(phydev, true);
  1244. out:
  1245. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  1246. release_firmware(fw);
  1247. return ret;
  1248. }
  1249. static void vsc8584_get_base_addr(struct phy_device *phydev)
  1250. {
  1251. struct vsc8531_private *vsc8531 = phydev->priv;
  1252. u16 val, addr;
  1253. phy_lock_mdio_bus(phydev);
  1254. __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
  1255. addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
  1256. addr >>= PHY_CNTL_4_ADDR_POS;
  1257. val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
  1258. __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  1259. phy_unlock_mdio_bus(phydev);
  1260. /* In the package, there are two pairs of PHYs (PHY0 + PHY2 and
  1261. * PHY1 + PHY3). The first PHY of each pair (PHY0 and PHY1) is
  1262. * the base PHY for timestamping operations.
  1263. */
  1264. vsc8531->ts_base_addr = phydev->mdio.addr;
  1265. vsc8531->ts_base_phy = addr;
  1266. if (val & PHY_ADDR_REVERSED) {
  1267. vsc8531->base_addr = phydev->mdio.addr + addr;
  1268. if (addr > 1) {
  1269. vsc8531->ts_base_addr += 2;
  1270. vsc8531->ts_base_phy += 2;
  1271. }
  1272. } else {
  1273. vsc8531->base_addr = phydev->mdio.addr - addr;
  1274. if (addr > 1) {
  1275. vsc8531->ts_base_addr -= 2;
  1276. vsc8531->ts_base_phy -= 2;
  1277. }
  1278. }
  1279. vsc8531->addr = addr;
  1280. }
  1281. static void vsc85xx_coma_mode_release(struct phy_device *phydev)
  1282. {
  1283. /* The coma mode (pin or reg) provides an optional feature that
  1284. * may be used to control when the PHYs become active.
  1285. * Alternatively the COMA_MODE pin may be connected low
  1286. * so that the PHYs are fully active once out of reset.
  1287. */
  1288. /* Enable output (mode=0) and write zero to it */
  1289. vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_EXTENDED_GPIO);
  1290. __phy_modify(phydev, MSCC_PHY_GPIO_CONTROL_2,
  1291. MSCC_PHY_COMA_MODE | MSCC_PHY_COMA_OUTPUT, 0);
  1292. vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_STANDARD);
  1293. }
  1294. static int vsc8584_config_host_serdes(struct phy_device *phydev)
  1295. {
  1296. struct vsc8531_private *vsc8531 = phydev->priv;
  1297. int ret;
  1298. u16 val;
  1299. ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1300. MSCC_PHY_PAGE_EXTENDED_GPIO);
  1301. if (ret)
  1302. return ret;
  1303. val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
  1304. val &= ~MAC_CFG_MASK;
  1305. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
  1306. val |= MAC_CFG_QSGMII;
  1307. } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
  1308. val |= MAC_CFG_SGMII;
  1309. } else {
  1310. ret = -EINVAL;
  1311. return ret;
  1312. }
  1313. ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
  1314. if (ret)
  1315. return ret;
  1316. ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1317. MSCC_PHY_PAGE_STANDARD);
  1318. if (ret)
  1319. return ret;
  1320. val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
  1321. PROC_CMD_READ_MOD_WRITE_PORT;
  1322. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
  1323. val |= PROC_CMD_QSGMII_MAC;
  1324. else
  1325. val |= PROC_CMD_SGMII_MAC;
  1326. ret = vsc8584_cmd(phydev, val);
  1327. if (ret)
  1328. return ret;
  1329. usleep_range(10000, 20000);
  1330. /* Disable SerDes for 100Base-FX */
  1331. ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
  1332. PROC_CMD_FIBER_PORT(vsc8531->addr) |
  1333. PROC_CMD_FIBER_DISABLE |
  1334. PROC_CMD_READ_MOD_WRITE_PORT |
  1335. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
  1336. if (ret)
  1337. return ret;
  1338. /* Disable SerDes for 1000Base-X */
  1339. ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
  1340. PROC_CMD_FIBER_PORT(vsc8531->addr) |
  1341. PROC_CMD_FIBER_DISABLE |
  1342. PROC_CMD_READ_MOD_WRITE_PORT |
  1343. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
  1344. if (ret)
  1345. return ret;
  1346. return vsc85xx_sd6g_config_v2(phydev);
  1347. }
  1348. static int vsc8574_config_host_serdes(struct phy_device *phydev)
  1349. {
  1350. struct vsc8531_private *vsc8531 = phydev->priv;
  1351. int ret;
  1352. u16 val;
  1353. ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1354. MSCC_PHY_PAGE_EXTENDED_GPIO);
  1355. if (ret)
  1356. return ret;
  1357. val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
  1358. val &= ~MAC_CFG_MASK;
  1359. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
  1360. val |= MAC_CFG_QSGMII;
  1361. } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
  1362. val |= MAC_CFG_SGMII;
  1363. } else if (phy_interface_is_rgmii(phydev)) {
  1364. val |= MAC_CFG_RGMII;
  1365. } else {
  1366. ret = -EINVAL;
  1367. return ret;
  1368. }
  1369. ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
  1370. if (ret)
  1371. return ret;
  1372. ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1373. MSCC_PHY_PAGE_STANDARD);
  1374. if (ret)
  1375. return ret;
  1376. if (!phy_interface_is_rgmii(phydev)) {
  1377. val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
  1378. PROC_CMD_READ_MOD_WRITE_PORT;
  1379. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
  1380. val |= PROC_CMD_QSGMII_MAC;
  1381. else
  1382. val |= PROC_CMD_SGMII_MAC;
  1383. ret = vsc8584_cmd(phydev, val);
  1384. if (ret)
  1385. return ret;
  1386. usleep_range(10000, 20000);
  1387. }
  1388. /* Disable SerDes for 100Base-FX */
  1389. ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
  1390. PROC_CMD_FIBER_PORT(vsc8531->addr) |
  1391. PROC_CMD_FIBER_DISABLE |
  1392. PROC_CMD_READ_MOD_WRITE_PORT |
  1393. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
  1394. if (ret)
  1395. return ret;
  1396. /* Disable SerDes for 1000Base-X */
  1397. return vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
  1398. PROC_CMD_FIBER_PORT(vsc8531->addr) |
  1399. PROC_CMD_FIBER_DISABLE |
  1400. PROC_CMD_READ_MOD_WRITE_PORT |
  1401. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
  1402. }
  1403. static int vsc8584_config_init(struct phy_device *phydev)
  1404. {
  1405. struct vsc8531_private *vsc8531 = phydev->priv;
  1406. int ret, i;
  1407. u16 val;
  1408. phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
  1409. phy_lock_mdio_bus(phydev);
  1410. /* Some parts of the init sequence are identical for every PHY in the
  1411. * package. Some parts are modifying the GPIO register bank which is a
  1412. * set of registers that are affecting all PHYs, a few resetting the
  1413. * microprocessor common to all PHYs. The CRC check responsible of the
  1414. * checking the firmware within the 8051 microprocessor can only be
  1415. * accessed via the PHY whose internal address in the package is 0.
  1416. * All PHYs' interrupts mask register has to be zeroed before enabling
  1417. * any PHY's interrupt in this register.
  1418. * For all these reasons, we need to do the init sequence once and only
  1419. * once whatever is the first PHY in the package that is initialized and
  1420. * do the correct init sequence for all PHYs that are package-critical
  1421. * in this pre-init function.
  1422. */
  1423. if (phy_package_init_once(phydev)) {
  1424. /* The following switch statement assumes that the lowest
  1425. * nibble of the phy_id_mask is always 0. This works because
  1426. * the lowest nibble of the PHY_ID's below are also 0.
  1427. */
  1428. WARN_ON(phydev->drv->phy_id_mask & 0xf);
  1429. switch (phydev->phy_id & phydev->drv->phy_id_mask) {
  1430. case PHY_ID_VSC8504:
  1431. case PHY_ID_VSC8552:
  1432. case PHY_ID_VSC8572:
  1433. case PHY_ID_VSC8574:
  1434. ret = vsc8574_config_pre_init(phydev);
  1435. if (ret)
  1436. goto err;
  1437. ret = vsc8574_config_host_serdes(phydev);
  1438. if (ret)
  1439. goto err;
  1440. break;
  1441. case PHY_ID_VSC856X:
  1442. case PHY_ID_VSC8575:
  1443. case PHY_ID_VSC8582:
  1444. case PHY_ID_VSC8584:
  1445. ret = vsc8584_config_pre_init(phydev);
  1446. if (ret)
  1447. goto err;
  1448. ret = vsc8584_config_host_serdes(phydev);
  1449. if (ret)
  1450. goto err;
  1451. vsc85xx_coma_mode_release(phydev);
  1452. break;
  1453. default:
  1454. ret = -EINVAL;
  1455. break;
  1456. }
  1457. if (ret)
  1458. goto err;
  1459. }
  1460. phy_unlock_mdio_bus(phydev);
  1461. ret = vsc8584_macsec_init(phydev);
  1462. if (ret)
  1463. return ret;
  1464. ret = vsc8584_ptp_init(phydev);
  1465. if (ret)
  1466. return ret;
  1467. val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
  1468. val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
  1469. val |= (MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS) |
  1470. (VSC8584_MAC_IF_SELECTION_SGMII << VSC8584_MAC_IF_SELECTION_POS);
  1471. ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
  1472. if (ret)
  1473. return ret;
  1474. ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL,
  1475. VSC8572_RGMII_RX_DELAY_MASK,
  1476. VSC8572_RGMII_TX_DELAY_MASK);
  1477. if (ret)
  1478. return ret;
  1479. ret = genphy_soft_reset(phydev);
  1480. if (ret)
  1481. return ret;
  1482. for (i = 0; i < vsc8531->nleds; i++) {
  1483. ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
  1484. if (ret)
  1485. return ret;
  1486. }
  1487. return 0;
  1488. err:
  1489. phy_unlock_mdio_bus(phydev);
  1490. return ret;
  1491. }
  1492. static irqreturn_t vsc8584_handle_interrupt(struct phy_device *phydev)
  1493. {
  1494. irqreturn_t ret;
  1495. int irq_status;
  1496. irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
  1497. if (irq_status < 0)
  1498. return IRQ_NONE;
  1499. /* Timestamping IRQ does not set a bit in the global INT_STATUS, so
  1500. * irq_status would be 0.
  1501. */
  1502. ret = vsc8584_handle_ts_interrupt(phydev);
  1503. if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
  1504. return ret;
  1505. if (irq_status & MII_VSC85XX_INT_MASK_EXT)
  1506. vsc8584_handle_macsec_interrupt(phydev);
  1507. if (irq_status & MII_VSC85XX_INT_MASK_LINK_CHG)
  1508. phy_trigger_machine(phydev);
  1509. return IRQ_HANDLED;
  1510. }
  1511. static int vsc85xx_config_init(struct phy_device *phydev)
  1512. {
  1513. int rc, i, phy_id;
  1514. struct vsc8531_private *vsc8531 = phydev->priv;
  1515. rc = vsc85xx_default_config(phydev);
  1516. if (rc)
  1517. return rc;
  1518. rc = vsc85xx_mac_if_set(phydev, phydev->interface);
  1519. if (rc)
  1520. return rc;
  1521. rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
  1522. if (rc)
  1523. return rc;
  1524. phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
  1525. if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
  1526. PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
  1527. rc = vsc8531_pre_init_seq_set(phydev);
  1528. if (rc)
  1529. return rc;
  1530. }
  1531. rc = vsc85xx_eee_init_seq_set(phydev);
  1532. if (rc)
  1533. return rc;
  1534. for (i = 0; i < vsc8531->nleds; i++) {
  1535. rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
  1536. if (rc)
  1537. return rc;
  1538. }
  1539. return 0;
  1540. }
  1541. static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
  1542. u32 op)
  1543. {
  1544. unsigned long deadline;
  1545. u32 val;
  1546. int ret;
  1547. ret = vsc85xx_csr_write(phydev, PHY_MCB_TARGET, reg,
  1548. op | (1 << mcb));
  1549. if (ret)
  1550. return -EINVAL;
  1551. deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
  1552. do {
  1553. usleep_range(500, 1000);
  1554. val = vsc85xx_csr_read(phydev, PHY_MCB_TARGET, reg);
  1555. if (val == 0xffffffff)
  1556. return -EIO;
  1557. } while (time_before(jiffies, deadline) && (val & op));
  1558. if (val & op)
  1559. return -ETIMEDOUT;
  1560. return 0;
  1561. }
  1562. /* Trigger a read to the specified MCB */
  1563. int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
  1564. {
  1565. return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
  1566. }
  1567. /* Trigger a write to the specified MCB */
  1568. int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
  1569. {
  1570. return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
  1571. }
  1572. static int vsc8514_config_host_serdes(struct phy_device *phydev)
  1573. {
  1574. int ret;
  1575. u16 val;
  1576. ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1577. MSCC_PHY_PAGE_EXTENDED_GPIO);
  1578. if (ret)
  1579. return ret;
  1580. val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
  1581. val &= ~MAC_CFG_MASK;
  1582. val |= MAC_CFG_QSGMII;
  1583. ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
  1584. if (ret)
  1585. return ret;
  1586. ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1587. MSCC_PHY_PAGE_STANDARD);
  1588. if (ret)
  1589. return ret;
  1590. ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
  1591. if (ret)
  1592. return ret;
  1593. ret = vsc8584_cmd(phydev,
  1594. PROC_CMD_MCB_ACCESS_MAC_CONF |
  1595. PROC_CMD_RST_CONF_PORT |
  1596. PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
  1597. if (ret) {
  1598. dev_err(&phydev->mdio.dev, "%s: QSGMII error: %d\n",
  1599. __func__, ret);
  1600. return ret;
  1601. }
  1602. /* Apply 6G SerDes FOJI Algorithm
  1603. * Initial condition requirement:
  1604. * 1. hold 8051 in reset
  1605. * 2. disable patch vector 0, in order to allow IB cal poll during FoJi
  1606. * 3. deassert 8051 reset after change patch vector status
  1607. * 4. proceed with FoJi (vsc85xx_sd6g_config_v2)
  1608. */
  1609. vsc8584_micro_assert_reset(phydev);
  1610. val = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
  1611. /* clear bit 8, to disable patch vector 0 */
  1612. val &= ~PATCH_VEC_ZERO_EN;
  1613. ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, val);
  1614. /* Enable 8051 clock, don't set patch present, disable PRAM clock override */
  1615. vsc8584_micro_deassert_reset(phydev, false);
  1616. return vsc85xx_sd6g_config_v2(phydev);
  1617. }
  1618. static int vsc8514_config_pre_init(struct phy_device *phydev)
  1619. {
  1620. /* These are the settings to override the silicon default
  1621. * values to handle hardware performance of PHY. They
  1622. * are set at Power-On state and remain until PHY Reset.
  1623. */
  1624. static const struct reg_val pre_init1[] = {
  1625. {0x0f90, 0x00688980},
  1626. {0x0786, 0x00000003},
  1627. {0x07fa, 0x0050100f},
  1628. {0x0f82, 0x0012b002},
  1629. {0x1686, 0x00000004},
  1630. {0x168c, 0x00d2c46f},
  1631. {0x17a2, 0x00000620},
  1632. {0x16a0, 0x00eeffdd},
  1633. {0x16a6, 0x00071448},
  1634. {0x16a4, 0x0013132f},
  1635. {0x16a8, 0x00000000},
  1636. {0x0ffc, 0x00c0a028},
  1637. {0x0fe8, 0x0091b06c},
  1638. {0x0fea, 0x00041600},
  1639. {0x0f80, 0x00fffaff},
  1640. {0x0fec, 0x00901809},
  1641. {0x0ffe, 0x00b01007},
  1642. {0x16b0, 0x00eeff00},
  1643. {0x16b2, 0x00007000},
  1644. {0x16b4, 0x00000814},
  1645. };
  1646. struct device *dev = &phydev->mdio.dev;
  1647. unsigned int i;
  1648. u16 reg;
  1649. int ret;
  1650. ret = vsc8584_pll5g_reset(phydev);
  1651. if (ret < 0) {
  1652. dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
  1653. return ret;
  1654. }
  1655. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  1656. /* all writes below are broadcasted to all PHYs in the same package */
  1657. reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
  1658. reg |= SMI_BROADCAST_WR_EN;
  1659. phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
  1660. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
  1661. reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
  1662. reg |= BIT(15);
  1663. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
  1664. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
  1665. for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
  1666. vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
  1667. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
  1668. reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
  1669. reg &= ~BIT(15);
  1670. phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
  1671. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
  1672. reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
  1673. reg &= ~SMI_BROADCAST_WR_EN;
  1674. phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
  1675. /* Add pre-patching commands to:
  1676. * 1. enable 8051 clock, operate 8051 clock at 125 MHz
  1677. * instead of HW default 62.5MHz
  1678. * 2. write patch vector 0, to skip IB cal polling executed
  1679. * as part of the 0x80E0 ROM command
  1680. */
  1681. vsc8584_micro_deassert_reset(phydev, false);
  1682. vsc8584_micro_assert_reset(phydev);
  1683. phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
  1684. MSCC_PHY_PAGE_EXTENDED_GPIO);
  1685. /* ROM address to trap, for patch vector 0 */
  1686. reg = MSCC_ROM_TRAP_SERDES_6G_CFG;
  1687. ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
  1688. if (ret)
  1689. goto err;
  1690. /* RAM address to jump to, when patch vector 0 enabled */
  1691. reg = MSCC_RAM_TRAP_SERDES_6G_CFG;
  1692. ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
  1693. if (ret)
  1694. goto err;
  1695. reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
  1696. reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
  1697. ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
  1698. if (ret)
  1699. goto err;
  1700. /* Enable 8051 clock, don't set patch present
  1701. * yet, disable PRAM clock override
  1702. */
  1703. vsc8584_micro_deassert_reset(phydev, false);
  1704. return ret;
  1705. err:
  1706. /* restore 8051 and bail w error */
  1707. vsc8584_micro_deassert_reset(phydev, false);
  1708. return ret;
  1709. }
  1710. static int vsc8514_config_init(struct phy_device *phydev)
  1711. {
  1712. struct vsc8531_private *vsc8531 = phydev->priv;
  1713. int ret, i;
  1714. phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
  1715. phy_lock_mdio_bus(phydev);
  1716. /* Some parts of the init sequence are identical for every PHY in the
  1717. * package. Some parts are modifying the GPIO register bank which is a
  1718. * set of registers that are affecting all PHYs, a few resetting the
  1719. * microprocessor common to all PHYs.
  1720. * All PHYs' interrupts mask register has to be zeroed before enabling
  1721. * any PHY's interrupt in this register.
  1722. * For all these reasons, we need to do the init sequence once and only
  1723. * once whatever is the first PHY in the package that is initialized and
  1724. * do the correct init sequence for all PHYs that are package-critical
  1725. * in this pre-init function.
  1726. */
  1727. if (phy_package_init_once(phydev)) {
  1728. ret = vsc8514_config_pre_init(phydev);
  1729. if (ret)
  1730. goto err;
  1731. ret = vsc8514_config_host_serdes(phydev);
  1732. if (ret)
  1733. goto err;
  1734. vsc85xx_coma_mode_release(phydev);
  1735. }
  1736. phy_unlock_mdio_bus(phydev);
  1737. ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
  1738. MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
  1739. if (ret)
  1740. return ret;
  1741. ret = genphy_soft_reset(phydev);
  1742. if (ret)
  1743. return ret;
  1744. for (i = 0; i < vsc8531->nleds; i++) {
  1745. ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
  1746. if (ret)
  1747. return ret;
  1748. }
  1749. return ret;
  1750. err:
  1751. phy_unlock_mdio_bus(phydev);
  1752. return ret;
  1753. }
  1754. static int vsc85xx_ack_interrupt(struct phy_device *phydev)
  1755. {
  1756. int rc = 0;
  1757. if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  1758. rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
  1759. return (rc < 0) ? rc : 0;
  1760. }
  1761. static int vsc85xx_config_intr(struct phy_device *phydev)
  1762. {
  1763. int rc;
  1764. if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
  1765. rc = vsc85xx_ack_interrupt(phydev);
  1766. if (rc)
  1767. return rc;
  1768. vsc8584_config_macsec_intr(phydev);
  1769. vsc8584_config_ts_intr(phydev);
  1770. rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
  1771. MII_VSC85XX_INT_MASK_MASK);
  1772. } else {
  1773. rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
  1774. if (rc < 0)
  1775. return rc;
  1776. rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
  1777. if (rc < 0)
  1778. return rc;
  1779. rc = vsc85xx_ack_interrupt(phydev);
  1780. }
  1781. return rc;
  1782. }
  1783. static irqreturn_t vsc85xx_handle_interrupt(struct phy_device *phydev)
  1784. {
  1785. int irq_status;
  1786. irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
  1787. if (irq_status < 0) {
  1788. phy_error(phydev);
  1789. return IRQ_NONE;
  1790. }
  1791. if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
  1792. return IRQ_NONE;
  1793. phy_trigger_machine(phydev);
  1794. return IRQ_HANDLED;
  1795. }
  1796. static int vsc85xx_config_aneg(struct phy_device *phydev)
  1797. {
  1798. int rc;
  1799. rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
  1800. if (rc < 0)
  1801. return rc;
  1802. return genphy_config_aneg(phydev);
  1803. }
  1804. static int vsc85xx_read_status(struct phy_device *phydev)
  1805. {
  1806. int rc;
  1807. rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
  1808. if (rc < 0)
  1809. return rc;
  1810. return genphy_read_status(phydev);
  1811. }
  1812. static int vsc8514_probe(struct phy_device *phydev)
  1813. {
  1814. struct vsc8531_private *vsc8531;
  1815. u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
  1816. VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
  1817. VSC8531_DUPLEX_COLLISION};
  1818. vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
  1819. if (!vsc8531)
  1820. return -ENOMEM;
  1821. phydev->priv = vsc8531;
  1822. vsc8584_get_base_addr(phydev);
  1823. devm_phy_package_join(&phydev->mdio.dev, phydev,
  1824. vsc8531->base_addr, 0);
  1825. vsc8531->nleds = 4;
  1826. vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
  1827. vsc8531->hw_stats = vsc85xx_hw_stats;
  1828. vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
  1829. vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
  1830. sizeof(u64), GFP_KERNEL);
  1831. if (!vsc8531->stats)
  1832. return -ENOMEM;
  1833. return vsc85xx_dt_led_modes_get(phydev, default_mode);
  1834. }
  1835. static int vsc8574_probe(struct phy_device *phydev)
  1836. {
  1837. struct vsc8531_private *vsc8531;
  1838. u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
  1839. VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
  1840. VSC8531_DUPLEX_COLLISION};
  1841. vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
  1842. if (!vsc8531)
  1843. return -ENOMEM;
  1844. phydev->priv = vsc8531;
  1845. vsc8584_get_base_addr(phydev);
  1846. devm_phy_package_join(&phydev->mdio.dev, phydev,
  1847. vsc8531->base_addr, 0);
  1848. vsc8531->nleds = 4;
  1849. vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
  1850. vsc8531->hw_stats = vsc8584_hw_stats;
  1851. vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
  1852. vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
  1853. sizeof(u64), GFP_KERNEL);
  1854. if (!vsc8531->stats)
  1855. return -ENOMEM;
  1856. return vsc85xx_dt_led_modes_get(phydev, default_mode);
  1857. }
  1858. static int vsc8584_probe(struct phy_device *phydev)
  1859. {
  1860. struct vsc8531_private *vsc8531;
  1861. u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
  1862. VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
  1863. VSC8531_DUPLEX_COLLISION};
  1864. int ret;
  1865. if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
  1866. dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
  1867. return -ENOTSUPP;
  1868. }
  1869. vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
  1870. if (!vsc8531)
  1871. return -ENOMEM;
  1872. phydev->priv = vsc8531;
  1873. vsc8584_get_base_addr(phydev);
  1874. devm_phy_package_join(&phydev->mdio.dev, phydev, vsc8531->base_addr,
  1875. sizeof(struct vsc85xx_shared_private));
  1876. vsc8531->nleds = 4;
  1877. vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
  1878. vsc8531->hw_stats = vsc8584_hw_stats;
  1879. vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
  1880. vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
  1881. sizeof(u64), GFP_KERNEL);
  1882. if (!vsc8531->stats)
  1883. return -ENOMEM;
  1884. if (phy_package_probe_once(phydev)) {
  1885. ret = vsc8584_ptp_probe_once(phydev);
  1886. if (ret)
  1887. return ret;
  1888. }
  1889. ret = vsc8584_ptp_probe(phydev);
  1890. if (ret)
  1891. return ret;
  1892. return vsc85xx_dt_led_modes_get(phydev, default_mode);
  1893. }
  1894. static int vsc85xx_probe(struct phy_device *phydev)
  1895. {
  1896. struct vsc8531_private *vsc8531;
  1897. int rate_magic;
  1898. u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
  1899. VSC8531_LINK_100_ACTIVITY};
  1900. rate_magic = vsc85xx_edge_rate_magic_get(phydev);
  1901. if (rate_magic < 0)
  1902. return rate_magic;
  1903. vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
  1904. if (!vsc8531)
  1905. return -ENOMEM;
  1906. phydev->priv = vsc8531;
  1907. vsc8531->rate_magic = rate_magic;
  1908. vsc8531->nleds = 2;
  1909. vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
  1910. vsc8531->hw_stats = vsc85xx_hw_stats;
  1911. vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
  1912. vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
  1913. sizeof(u64), GFP_KERNEL);
  1914. if (!vsc8531->stats)
  1915. return -ENOMEM;
  1916. return vsc85xx_dt_led_modes_get(phydev, default_mode);
  1917. }
  1918. static void vsc85xx_remove(struct phy_device *phydev)
  1919. {
  1920. vsc8584_ptp_deinit(phydev);
  1921. }
  1922. /* Microsemi VSC85xx PHYs */
  1923. static struct phy_driver vsc85xx_driver[] = {
  1924. {
  1925. .phy_id = PHY_ID_VSC8501,
  1926. .name = "Microsemi GE VSC8501 SyncE",
  1927. .phy_id_mask = 0xfffffff0,
  1928. /* PHY_BASIC_FEATURES */
  1929. .soft_reset = &genphy_soft_reset,
  1930. .config_init = &vsc85xx_config_init,
  1931. .config_aneg = &vsc85xx_config_aneg,
  1932. .read_status = &vsc85xx_read_status,
  1933. .handle_interrupt = vsc85xx_handle_interrupt,
  1934. .config_intr = &vsc85xx_config_intr,
  1935. .suspend = &genphy_suspend,
  1936. .resume = &genphy_resume,
  1937. .probe = &vsc85xx_probe,
  1938. .set_wol = &vsc85xx_wol_set,
  1939. .get_wol = &vsc85xx_wol_get,
  1940. .get_tunable = &vsc85xx_get_tunable,
  1941. .set_tunable = &vsc85xx_set_tunable,
  1942. .read_page = &vsc85xx_phy_read_page,
  1943. .write_page = &vsc85xx_phy_write_page,
  1944. .get_sset_count = &vsc85xx_get_sset_count,
  1945. .get_strings = &vsc85xx_get_strings,
  1946. .get_stats = &vsc85xx_get_stats,
  1947. },
  1948. {
  1949. .phy_id = PHY_ID_VSC8502,
  1950. .name = "Microsemi GE VSC8502 SyncE",
  1951. .phy_id_mask = 0xfffffff0,
  1952. /* PHY_BASIC_FEATURES */
  1953. .soft_reset = &genphy_soft_reset,
  1954. .config_init = &vsc85xx_config_init,
  1955. .config_aneg = &vsc85xx_config_aneg,
  1956. .read_status = &vsc85xx_read_status,
  1957. .handle_interrupt = vsc85xx_handle_interrupt,
  1958. .config_intr = &vsc85xx_config_intr,
  1959. .suspend = &genphy_suspend,
  1960. .resume = &genphy_resume,
  1961. .probe = &vsc85xx_probe,
  1962. .set_wol = &vsc85xx_wol_set,
  1963. .get_wol = &vsc85xx_wol_get,
  1964. .get_tunable = &vsc85xx_get_tunable,
  1965. .set_tunable = &vsc85xx_set_tunable,
  1966. .read_page = &vsc85xx_phy_read_page,
  1967. .write_page = &vsc85xx_phy_write_page,
  1968. .get_sset_count = &vsc85xx_get_sset_count,
  1969. .get_strings = &vsc85xx_get_strings,
  1970. .get_stats = &vsc85xx_get_stats,
  1971. },
  1972. {
  1973. .phy_id = PHY_ID_VSC8504,
  1974. .name = "Microsemi GE VSC8504 SyncE",
  1975. .phy_id_mask = 0xfffffff0,
  1976. /* PHY_GBIT_FEATURES */
  1977. .soft_reset = &genphy_soft_reset,
  1978. .config_init = &vsc8584_config_init,
  1979. .config_aneg = &vsc85xx_config_aneg,
  1980. .aneg_done = &genphy_aneg_done,
  1981. .read_status = &vsc85xx_read_status,
  1982. .handle_interrupt = vsc85xx_handle_interrupt,
  1983. .config_intr = &vsc85xx_config_intr,
  1984. .suspend = &genphy_suspend,
  1985. .resume = &genphy_resume,
  1986. .probe = &vsc8574_probe,
  1987. .set_wol = &vsc85xx_wol_set,
  1988. .get_wol = &vsc85xx_wol_get,
  1989. .get_tunable = &vsc85xx_get_tunable,
  1990. .set_tunable = &vsc85xx_set_tunable,
  1991. .read_page = &vsc85xx_phy_read_page,
  1992. .write_page = &vsc85xx_phy_write_page,
  1993. .get_sset_count = &vsc85xx_get_sset_count,
  1994. .get_strings = &vsc85xx_get_strings,
  1995. .get_stats = &vsc85xx_get_stats,
  1996. },
  1997. {
  1998. .phy_id = PHY_ID_VSC8514,
  1999. .name = "Microsemi GE VSC8514 SyncE",
  2000. .phy_id_mask = 0xfffffff0,
  2001. .soft_reset = &genphy_soft_reset,
  2002. .config_init = &vsc8514_config_init,
  2003. .config_aneg = &vsc85xx_config_aneg,
  2004. .read_status = &vsc85xx_read_status,
  2005. .handle_interrupt = vsc85xx_handle_interrupt,
  2006. .config_intr = &vsc85xx_config_intr,
  2007. .suspend = &genphy_suspend,
  2008. .resume = &genphy_resume,
  2009. .probe = &vsc8514_probe,
  2010. .set_wol = &vsc85xx_wol_set,
  2011. .get_wol = &vsc85xx_wol_get,
  2012. .get_tunable = &vsc85xx_get_tunable,
  2013. .set_tunable = &vsc85xx_set_tunable,
  2014. .read_page = &vsc85xx_phy_read_page,
  2015. .write_page = &vsc85xx_phy_write_page,
  2016. .get_sset_count = &vsc85xx_get_sset_count,
  2017. .get_strings = &vsc85xx_get_strings,
  2018. .get_stats = &vsc85xx_get_stats,
  2019. },
  2020. {
  2021. .phy_id = PHY_ID_VSC8530,
  2022. .name = "Microsemi FE VSC8530",
  2023. .phy_id_mask = 0xfffffff0,
  2024. /* PHY_BASIC_FEATURES */
  2025. .soft_reset = &genphy_soft_reset,
  2026. .config_init = &vsc85xx_config_init,
  2027. .config_aneg = &vsc85xx_config_aneg,
  2028. .read_status = &vsc85xx_read_status,
  2029. .handle_interrupt = vsc85xx_handle_interrupt,
  2030. .config_intr = &vsc85xx_config_intr,
  2031. .suspend = &genphy_suspend,
  2032. .resume = &genphy_resume,
  2033. .probe = &vsc85xx_probe,
  2034. .set_wol = &vsc85xx_wol_set,
  2035. .get_wol = &vsc85xx_wol_get,
  2036. .get_tunable = &vsc85xx_get_tunable,
  2037. .set_tunable = &vsc85xx_set_tunable,
  2038. .read_page = &vsc85xx_phy_read_page,
  2039. .write_page = &vsc85xx_phy_write_page,
  2040. .get_sset_count = &vsc85xx_get_sset_count,
  2041. .get_strings = &vsc85xx_get_strings,
  2042. .get_stats = &vsc85xx_get_stats,
  2043. },
  2044. {
  2045. .phy_id = PHY_ID_VSC8531,
  2046. .name = "Microsemi VSC8531",
  2047. .phy_id_mask = 0xfffffff0,
  2048. /* PHY_GBIT_FEATURES */
  2049. .soft_reset = &genphy_soft_reset,
  2050. .config_init = &vsc85xx_config_init,
  2051. .config_aneg = &vsc85xx_config_aneg,
  2052. .read_status = &vsc85xx_read_status,
  2053. .handle_interrupt = vsc85xx_handle_interrupt,
  2054. .config_intr = &vsc85xx_config_intr,
  2055. .suspend = &genphy_suspend,
  2056. .resume = &genphy_resume,
  2057. .probe = &vsc85xx_probe,
  2058. .set_wol = &vsc85xx_wol_set,
  2059. .get_wol = &vsc85xx_wol_get,
  2060. .get_tunable = &vsc85xx_get_tunable,
  2061. .set_tunable = &vsc85xx_set_tunable,
  2062. .read_page = &vsc85xx_phy_read_page,
  2063. .write_page = &vsc85xx_phy_write_page,
  2064. .get_sset_count = &vsc85xx_get_sset_count,
  2065. .get_strings = &vsc85xx_get_strings,
  2066. .get_stats = &vsc85xx_get_stats,
  2067. },
  2068. {
  2069. .phy_id = PHY_ID_VSC8540,
  2070. .name = "Microsemi FE VSC8540 SyncE",
  2071. .phy_id_mask = 0xfffffff0,
  2072. /* PHY_BASIC_FEATURES */
  2073. .soft_reset = &genphy_soft_reset,
  2074. .config_init = &vsc85xx_config_init,
  2075. .config_aneg = &vsc85xx_config_aneg,
  2076. .read_status = &vsc85xx_read_status,
  2077. .handle_interrupt = vsc85xx_handle_interrupt,
  2078. .config_intr = &vsc85xx_config_intr,
  2079. .suspend = &genphy_suspend,
  2080. .resume = &genphy_resume,
  2081. .probe = &vsc85xx_probe,
  2082. .set_wol = &vsc85xx_wol_set,
  2083. .get_wol = &vsc85xx_wol_get,
  2084. .get_tunable = &vsc85xx_get_tunable,
  2085. .set_tunable = &vsc85xx_set_tunable,
  2086. .read_page = &vsc85xx_phy_read_page,
  2087. .write_page = &vsc85xx_phy_write_page,
  2088. .get_sset_count = &vsc85xx_get_sset_count,
  2089. .get_strings = &vsc85xx_get_strings,
  2090. .get_stats = &vsc85xx_get_stats,
  2091. },
  2092. {
  2093. .phy_id = PHY_ID_VSC8541,
  2094. .name = "Microsemi VSC8541 SyncE",
  2095. .phy_id_mask = 0xfffffff0,
  2096. /* PHY_GBIT_FEATURES */
  2097. .soft_reset = &genphy_soft_reset,
  2098. .config_init = &vsc85xx_config_init,
  2099. .config_aneg = &vsc85xx_config_aneg,
  2100. .read_status = &vsc85xx_read_status,
  2101. .handle_interrupt = vsc85xx_handle_interrupt,
  2102. .config_intr = &vsc85xx_config_intr,
  2103. .suspend = &genphy_suspend,
  2104. .resume = &genphy_resume,
  2105. .probe = &vsc85xx_probe,
  2106. .set_wol = &vsc85xx_wol_set,
  2107. .get_wol = &vsc85xx_wol_get,
  2108. .get_tunable = &vsc85xx_get_tunable,
  2109. .set_tunable = &vsc85xx_set_tunable,
  2110. .read_page = &vsc85xx_phy_read_page,
  2111. .write_page = &vsc85xx_phy_write_page,
  2112. .get_sset_count = &vsc85xx_get_sset_count,
  2113. .get_strings = &vsc85xx_get_strings,
  2114. .get_stats = &vsc85xx_get_stats,
  2115. },
  2116. {
  2117. .phy_id = PHY_ID_VSC8552,
  2118. .name = "Microsemi GE VSC8552 SyncE",
  2119. .phy_id_mask = 0xfffffff0,
  2120. /* PHY_GBIT_FEATURES */
  2121. .soft_reset = &genphy_soft_reset,
  2122. .config_init = &vsc8584_config_init,
  2123. .config_aneg = &vsc85xx_config_aneg,
  2124. .read_status = &vsc85xx_read_status,
  2125. .handle_interrupt = vsc85xx_handle_interrupt,
  2126. .config_intr = &vsc85xx_config_intr,
  2127. .suspend = &genphy_suspend,
  2128. .resume = &genphy_resume,
  2129. .probe = &vsc8574_probe,
  2130. .set_wol = &vsc85xx_wol_set,
  2131. .get_wol = &vsc85xx_wol_get,
  2132. .get_tunable = &vsc85xx_get_tunable,
  2133. .set_tunable = &vsc85xx_set_tunable,
  2134. .read_page = &vsc85xx_phy_read_page,
  2135. .write_page = &vsc85xx_phy_write_page,
  2136. .get_sset_count = &vsc85xx_get_sset_count,
  2137. .get_strings = &vsc85xx_get_strings,
  2138. .get_stats = &vsc85xx_get_stats,
  2139. },
  2140. {
  2141. .phy_id = PHY_ID_VSC856X,
  2142. .name = "Microsemi GE VSC856X SyncE",
  2143. .phy_id_mask = 0xfffffff0,
  2144. /* PHY_GBIT_FEATURES */
  2145. .soft_reset = &genphy_soft_reset,
  2146. .config_init = &vsc8584_config_init,
  2147. .config_aneg = &vsc85xx_config_aneg,
  2148. .read_status = &vsc85xx_read_status,
  2149. .handle_interrupt = vsc85xx_handle_interrupt,
  2150. .config_intr = &vsc85xx_config_intr,
  2151. .suspend = &genphy_suspend,
  2152. .resume = &genphy_resume,
  2153. .probe = &vsc8584_probe,
  2154. .get_tunable = &vsc85xx_get_tunable,
  2155. .set_tunable = &vsc85xx_set_tunable,
  2156. .read_page = &vsc85xx_phy_read_page,
  2157. .write_page = &vsc85xx_phy_write_page,
  2158. .get_sset_count = &vsc85xx_get_sset_count,
  2159. .get_strings = &vsc85xx_get_strings,
  2160. .get_stats = &vsc85xx_get_stats,
  2161. },
  2162. {
  2163. .phy_id = PHY_ID_VSC8572,
  2164. .name = "Microsemi GE VSC8572 SyncE",
  2165. .phy_id_mask = 0xfffffff0,
  2166. /* PHY_GBIT_FEATURES */
  2167. .soft_reset = &genphy_soft_reset,
  2168. .config_init = &vsc8584_config_init,
  2169. .config_aneg = &vsc85xx_config_aneg,
  2170. .aneg_done = &genphy_aneg_done,
  2171. .read_status = &vsc85xx_read_status,
  2172. .handle_interrupt = &vsc8584_handle_interrupt,
  2173. .config_intr = &vsc85xx_config_intr,
  2174. .suspend = &genphy_suspend,
  2175. .resume = &genphy_resume,
  2176. .remove = &vsc85xx_remove,
  2177. .probe = &vsc8574_probe,
  2178. .set_wol = &vsc85xx_wol_set,
  2179. .get_wol = &vsc85xx_wol_get,
  2180. .get_tunable = &vsc85xx_get_tunable,
  2181. .set_tunable = &vsc85xx_set_tunable,
  2182. .read_page = &vsc85xx_phy_read_page,
  2183. .write_page = &vsc85xx_phy_write_page,
  2184. .get_sset_count = &vsc85xx_get_sset_count,
  2185. .get_strings = &vsc85xx_get_strings,
  2186. .get_stats = &vsc85xx_get_stats,
  2187. },
  2188. {
  2189. .phy_id = PHY_ID_VSC8574,
  2190. .name = "Microsemi GE VSC8574 SyncE",
  2191. .phy_id_mask = 0xfffffff0,
  2192. /* PHY_GBIT_FEATURES */
  2193. .soft_reset = &genphy_soft_reset,
  2194. .config_init = &vsc8584_config_init,
  2195. .config_aneg = &vsc85xx_config_aneg,
  2196. .aneg_done = &genphy_aneg_done,
  2197. .read_status = &vsc85xx_read_status,
  2198. .handle_interrupt = vsc85xx_handle_interrupt,
  2199. .config_intr = &vsc85xx_config_intr,
  2200. .suspend = &genphy_suspend,
  2201. .resume = &genphy_resume,
  2202. .remove = &vsc85xx_remove,
  2203. .probe = &vsc8574_probe,
  2204. .set_wol = &vsc85xx_wol_set,
  2205. .get_wol = &vsc85xx_wol_get,
  2206. .get_tunable = &vsc85xx_get_tunable,
  2207. .set_tunable = &vsc85xx_set_tunable,
  2208. .read_page = &vsc85xx_phy_read_page,
  2209. .write_page = &vsc85xx_phy_write_page,
  2210. .get_sset_count = &vsc85xx_get_sset_count,
  2211. .get_strings = &vsc85xx_get_strings,
  2212. .get_stats = &vsc85xx_get_stats,
  2213. },
  2214. {
  2215. .phy_id = PHY_ID_VSC8575,
  2216. .name = "Microsemi GE VSC8575 SyncE",
  2217. .phy_id_mask = 0xfffffff0,
  2218. /* PHY_GBIT_FEATURES */
  2219. .soft_reset = &genphy_soft_reset,
  2220. .config_init = &vsc8584_config_init,
  2221. .config_aneg = &vsc85xx_config_aneg,
  2222. .aneg_done = &genphy_aneg_done,
  2223. .read_status = &vsc85xx_read_status,
  2224. .handle_interrupt = &vsc8584_handle_interrupt,
  2225. .config_intr = &vsc85xx_config_intr,
  2226. .suspend = &genphy_suspend,
  2227. .resume = &genphy_resume,
  2228. .remove = &vsc85xx_remove,
  2229. .probe = &vsc8584_probe,
  2230. .get_tunable = &vsc85xx_get_tunable,
  2231. .set_tunable = &vsc85xx_set_tunable,
  2232. .read_page = &vsc85xx_phy_read_page,
  2233. .write_page = &vsc85xx_phy_write_page,
  2234. .get_sset_count = &vsc85xx_get_sset_count,
  2235. .get_strings = &vsc85xx_get_strings,
  2236. .get_stats = &vsc85xx_get_stats,
  2237. },
  2238. {
  2239. .phy_id = PHY_ID_VSC8582,
  2240. .name = "Microsemi GE VSC8582 SyncE",
  2241. .phy_id_mask = 0xfffffff0,
  2242. /* PHY_GBIT_FEATURES */
  2243. .soft_reset = &genphy_soft_reset,
  2244. .config_init = &vsc8584_config_init,
  2245. .config_aneg = &vsc85xx_config_aneg,
  2246. .aneg_done = &genphy_aneg_done,
  2247. .read_status = &vsc85xx_read_status,
  2248. .handle_interrupt = &vsc8584_handle_interrupt,
  2249. .config_intr = &vsc85xx_config_intr,
  2250. .suspend = &genphy_suspend,
  2251. .resume = &genphy_resume,
  2252. .remove = &vsc85xx_remove,
  2253. .probe = &vsc8584_probe,
  2254. .get_tunable = &vsc85xx_get_tunable,
  2255. .set_tunable = &vsc85xx_set_tunable,
  2256. .read_page = &vsc85xx_phy_read_page,
  2257. .write_page = &vsc85xx_phy_write_page,
  2258. .get_sset_count = &vsc85xx_get_sset_count,
  2259. .get_strings = &vsc85xx_get_strings,
  2260. .get_stats = &vsc85xx_get_stats,
  2261. },
  2262. {
  2263. .phy_id = PHY_ID_VSC8584,
  2264. .name = "Microsemi GE VSC8584 SyncE",
  2265. .phy_id_mask = 0xfffffff0,
  2266. /* PHY_GBIT_FEATURES */
  2267. .soft_reset = &genphy_soft_reset,
  2268. .config_init = &vsc8584_config_init,
  2269. .config_aneg = &vsc85xx_config_aneg,
  2270. .aneg_done = &genphy_aneg_done,
  2271. .read_status = &vsc85xx_read_status,
  2272. .handle_interrupt = &vsc8584_handle_interrupt,
  2273. .config_intr = &vsc85xx_config_intr,
  2274. .suspend = &genphy_suspend,
  2275. .resume = &genphy_resume,
  2276. .remove = &vsc85xx_remove,
  2277. .probe = &vsc8584_probe,
  2278. .get_tunable = &vsc85xx_get_tunable,
  2279. .set_tunable = &vsc85xx_set_tunable,
  2280. .read_page = &vsc85xx_phy_read_page,
  2281. .write_page = &vsc85xx_phy_write_page,
  2282. .get_sset_count = &vsc85xx_get_sset_count,
  2283. .get_strings = &vsc85xx_get_strings,
  2284. .get_stats = &vsc85xx_get_stats,
  2285. .link_change_notify = &vsc85xx_link_change_notify,
  2286. }
  2287. };
  2288. module_phy_driver(vsc85xx_driver);
  2289. static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
  2290. { PHY_ID_MATCH_VENDOR(PHY_VENDOR_MSCC) },
  2291. { }
  2292. };
  2293. MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
  2294. MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
  2295. MODULE_AUTHOR("Nagaraju Lakkaraju");
  2296. MODULE_LICENSE("Dual MIT/GPL");
  2297. MODULE_FIRMWARE(MSCC_VSC8584_REVB_INT8051_FW);
  2298. MODULE_FIRMWARE(MSCC_VSC8574_REVB_INT8051_FW);