broadcom.c 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * drivers/net/phy/broadcom.c
  4. *
  5. * Broadcom BCM5411, BCM5421 and BCM5461 Gigabit Ethernet
  6. * transceivers.
  7. *
  8. * Broadcom BCM54810, BCM54811 BroadR-Reach transceivers.
  9. *
  10. * Copyright (c) 2006 Maciej W. Rozycki
  11. *
  12. * Inspired by code written by Amy Fong.
  13. */
  14. #include "bcm-phy-lib.h"
  15. #include <linux/delay.h>
  16. #include <linux/module.h>
  17. #include <linux/phy.h>
  18. #include <linux/device.h>
  19. #include <linux/brcmphy.h>
  20. #include <linux/of.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/irq.h>
  23. #include <linux/gpio/consumer.h>
  24. #define BRCM_PHY_REV(phydev) \
  25. ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
  26. MODULE_DESCRIPTION("Broadcom PHY driver");
  27. MODULE_AUTHOR("Maciej W. Rozycki");
  28. MODULE_LICENSE("GPL");
  29. struct bcm54xx_phy_priv {
  30. u64 *stats;
  31. struct bcm_ptp_private *ptp;
  32. int wake_irq;
  33. bool wake_irq_enabled;
  34. bool brr_mode;
  35. };
  36. /* Link modes for BCM58411 PHY */
  37. static const int bcm54811_linkmodes[] = {
  38. ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
  39. ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
  40. ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
  41. ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
  42. ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
  43. ETHTOOL_LINK_MODE_100baseT_Full_BIT,
  44. ETHTOOL_LINK_MODE_100baseT_Half_BIT,
  45. ETHTOOL_LINK_MODE_10baseT_Full_BIT,
  46. ETHTOOL_LINK_MODE_10baseT_Half_BIT
  47. };
  48. /* Long-Distance Signaling (BroadR-Reach mode aneg) relevant linkmode bits */
  49. static const int lds_br_bits[] = {
  50. ETHTOOL_LINK_MODE_Autoneg_BIT,
  51. ETHTOOL_LINK_MODE_Pause_BIT,
  52. ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  53. ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
  54. ETHTOOL_LINK_MODE_100baseT1_Full_BIT
  55. };
  56. static bool bcm54xx_phy_can_wakeup(struct phy_device *phydev)
  57. {
  58. struct bcm54xx_phy_priv *priv = phydev->priv;
  59. return phy_interrupt_is_valid(phydev) || priv->wake_irq >= 0;
  60. }
  61. static int bcm54xx_config_clock_delay(struct phy_device *phydev)
  62. {
  63. int rc, val;
  64. /* handling PHY's internal RX clock delay */
  65. val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
  66. val |= MII_BCM54XX_AUXCTL_MISC_WREN;
  67. if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
  68. phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
  69. /* Disable RGMII RXC-RXD skew */
  70. val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
  71. }
  72. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
  73. phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
  74. /* Enable RGMII RXC-RXD skew */
  75. val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
  76. }
  77. rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
  78. val);
  79. if (rc < 0)
  80. return rc;
  81. /* handling PHY's internal TX clock delay */
  82. val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
  83. if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
  84. phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
  85. /* Disable internal TX clock delay */
  86. val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
  87. }
  88. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
  89. phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
  90. /* Enable internal TX clock delay */
  91. val |= BCM54810_SHD_CLK_CTL_GTXCLK_EN;
  92. }
  93. rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
  94. if (rc < 0)
  95. return rc;
  96. return 0;
  97. }
  98. static int bcm54210e_config_init(struct phy_device *phydev)
  99. {
  100. int val;
  101. bcm54xx_config_clock_delay(phydev);
  102. if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) {
  103. val = phy_read(phydev, MII_CTRL1000);
  104. val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
  105. phy_write(phydev, MII_CTRL1000, val);
  106. }
  107. return 0;
  108. }
  109. static int bcm54612e_config_init(struct phy_device *phydev)
  110. {
  111. int reg;
  112. bcm54xx_config_clock_delay(phydev);
  113. /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
  114. if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
  115. int err;
  116. reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
  117. err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
  118. BCM54612E_LED4_CLK125OUT_EN | reg);
  119. if (err < 0)
  120. return err;
  121. }
  122. return 0;
  123. }
  124. static int bcm54616s_config_init(struct phy_device *phydev)
  125. {
  126. int rc, val;
  127. if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
  128. phydev->interface != PHY_INTERFACE_MODE_1000BASEX)
  129. return 0;
  130. /* Ensure proper interface mode is selected. */
  131. /* Disable RGMII mode */
  132. val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
  133. if (val < 0)
  134. return val;
  135. val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN;
  136. val |= MII_BCM54XX_AUXCTL_MISC_WREN;
  137. rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
  138. val);
  139. if (rc < 0)
  140. return rc;
  141. /* Select 1000BASE-X register set (primary SerDes) */
  142. val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
  143. if (val < 0)
  144. return val;
  145. val |= BCM54XX_SHD_MODE_1000BX;
  146. rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
  147. if (rc < 0)
  148. return rc;
  149. /* Power down SerDes interface */
  150. rc = phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
  151. if (rc < 0)
  152. return rc;
  153. /* Select proper interface mode */
  154. val &= ~BCM54XX_SHD_INTF_SEL_MASK;
  155. val |= phydev->interface == PHY_INTERFACE_MODE_SGMII ?
  156. BCM54XX_SHD_INTF_SEL_SGMII :
  157. BCM54XX_SHD_INTF_SEL_GBIC;
  158. rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
  159. if (rc < 0)
  160. return rc;
  161. /* Power up SerDes interface */
  162. rc = phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
  163. if (rc < 0)
  164. return rc;
  165. /* Select copper register set */
  166. val &= ~BCM54XX_SHD_MODE_1000BX;
  167. rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
  168. if (rc < 0)
  169. return rc;
  170. /* Power up copper interface */
  171. return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
  172. }
  173. /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
  174. static int bcm50610_a0_workaround(struct phy_device *phydev)
  175. {
  176. int err;
  177. err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH0,
  178. MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
  179. MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
  180. if (err < 0)
  181. return err;
  182. err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH3,
  183. MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
  184. if (err < 0)
  185. return err;
  186. err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75,
  187. MII_BCM54XX_EXP_EXP75_VDACCTRL);
  188. if (err < 0)
  189. return err;
  190. err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP96,
  191. MII_BCM54XX_EXP_EXP96_MYST);
  192. if (err < 0)
  193. return err;
  194. err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP97,
  195. MII_BCM54XX_EXP_EXP97_MYST);
  196. return err;
  197. }
  198. static int bcm54xx_phydsp_config(struct phy_device *phydev)
  199. {
  200. int err, err2;
  201. /* Enable the SMDSP clock */
  202. err = bcm54xx_auxctl_write(phydev,
  203. MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
  204. MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
  205. MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
  206. if (err < 0)
  207. return err;
  208. if (phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610) ||
  209. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610M)) {
  210. /* Clear bit 9 to fix a phy interop issue. */
  211. err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08,
  212. MII_BCM54XX_EXP_EXP08_RJCT_2MHZ);
  213. if (err < 0)
  214. goto error;
  215. if (phydev->drv->phy_id == PHY_ID_BCM50610) {
  216. err = bcm50610_a0_workaround(phydev);
  217. if (err < 0)
  218. goto error;
  219. }
  220. }
  221. if (phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM57780)) {
  222. int val;
  223. val = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP75);
  224. if (val < 0)
  225. goto error;
  226. val |= MII_BCM54XX_EXP_EXP75_CM_OSC;
  227. err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75, val);
  228. }
  229. error:
  230. /* Disable the SMDSP clock */
  231. err2 = bcm54xx_auxctl_write(phydev,
  232. MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
  233. MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
  234. /* Return the first error reported. */
  235. return err ? err : err2;
  236. }
  237. static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
  238. {
  239. u32 orig;
  240. int val;
  241. bool clk125en = true;
  242. /* Abort if we are using an untested phy. */
  243. if (!(phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM57780) ||
  244. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610) ||
  245. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610M) ||
  246. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54210E) ||
  247. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54810) ||
  248. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54811)))
  249. return;
  250. val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
  251. if (val < 0)
  252. return;
  253. orig = val;
  254. if ((phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610) ||
  255. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610M)) &&
  256. BRCM_PHY_REV(phydev) >= 0x3) {
  257. /*
  258. * Here, bit 0 _disables_ CLK125 when set.
  259. * This bit is set by default.
  260. */
  261. clk125en = false;
  262. } else {
  263. if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
  264. if (!phy_id_compare_model(phydev->drv->phy_id,
  265. PHY_ID_BCM54811)) {
  266. /* Here, bit 0 _enables_ CLK125 when set */
  267. val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
  268. }
  269. clk125en = false;
  270. }
  271. }
  272. if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
  273. val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
  274. else
  275. val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
  276. if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) {
  277. if (phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54210E) ||
  278. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54810) ||
  279. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54811))
  280. val |= BCM54XX_SHD_SCR3_RXCTXC_DIS;
  281. else
  282. val |= BCM54XX_SHD_SCR3_TRDDAPD;
  283. }
  284. if (orig != val)
  285. bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
  286. val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD);
  287. if (val < 0)
  288. return;
  289. orig = val;
  290. if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
  291. val |= BCM54XX_SHD_APD_EN;
  292. else
  293. val &= ~BCM54XX_SHD_APD_EN;
  294. if (orig != val)
  295. bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val);
  296. }
  297. static void bcm54xx_ptp_stop(struct phy_device *phydev)
  298. {
  299. struct bcm54xx_phy_priv *priv = phydev->priv;
  300. if (priv->ptp)
  301. bcm_ptp_stop(priv->ptp);
  302. }
  303. static void bcm54xx_ptp_config_init(struct phy_device *phydev)
  304. {
  305. struct bcm54xx_phy_priv *priv = phydev->priv;
  306. if (priv->ptp)
  307. bcm_ptp_config_init(phydev);
  308. }
  309. static int bcm5481x_set_brrmode(struct phy_device *phydev, bool on)
  310. {
  311. int reg;
  312. int err;
  313. u16 val;
  314. reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
  315. if (reg < 0)
  316. return reg;
  317. if (on)
  318. reg |= BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
  319. else
  320. reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
  321. err = bcm_phy_write_exp(phydev,
  322. BCM54810_EXP_BROADREACH_LRE_MISC_CTL, reg);
  323. if (err)
  324. return err;
  325. /* Ensure LRE or IEEE register set is accessed according to the brr
  326. * on/off, thus set the override
  327. */
  328. val = BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL_EN;
  329. if (!on)
  330. val |= BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL_OVERRIDE_VAL;
  331. return bcm_phy_write_exp(phydev,
  332. BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL, val);
  333. }
  334. static int bcm54811_config_init(struct phy_device *phydev)
  335. {
  336. struct bcm54xx_phy_priv *priv = phydev->priv;
  337. int err, reg, exp_sync_ethernet, aux_rgmii_en;
  338. /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
  339. if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
  340. reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
  341. if (reg < 0)
  342. return reg;
  343. err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
  344. BCM54612E_LED4_CLK125OUT_EN | reg);
  345. if (err < 0)
  346. return err;
  347. }
  348. /* With BCM54811, BroadR-Reach implies no autoneg */
  349. if (priv->brr_mode)
  350. phydev->autoneg = 0;
  351. /* Enable MII Lite (No TXER, RXER, CRS, COL) if configured */
  352. if (phydev->interface == PHY_INTERFACE_MODE_MIILITE)
  353. exp_sync_ethernet = BCM_EXP_SYNC_ETHERNET_MII_LITE;
  354. else
  355. exp_sync_ethernet = 0;
  356. err = bcm_phy_modify_exp(phydev, BCM_EXP_SYNC_ETHERNET,
  357. BCM_EXP_SYNC_ETHERNET_MII_LITE,
  358. exp_sync_ethernet);
  359. if (err < 0)
  360. return err;
  361. /* Enable RGMII if configured */
  362. if (phy_interface_is_rgmii(phydev))
  363. aux_rgmii_en = MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN |
  364. MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
  365. else
  366. aux_rgmii_en = 0;
  367. /* Also writing Reserved bits 6:5 because the documentation requires
  368. * them to be written to 0b11
  369. */
  370. err = bcm54xx_auxctl_write(phydev,
  371. MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
  372. MII_BCM54XX_AUXCTL_MISC_WREN |
  373. aux_rgmii_en |
  374. MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RSVD);
  375. if (err < 0)
  376. return err;
  377. return bcm5481x_set_brrmode(phydev, priv->brr_mode);
  378. }
  379. static int bcm54xx_config_init(struct phy_device *phydev)
  380. {
  381. int reg, err, val;
  382. reg = phy_read(phydev, MII_BCM54XX_ECR);
  383. if (reg < 0)
  384. return reg;
  385. /* Mask interrupts globally. */
  386. reg |= MII_BCM54XX_ECR_IM;
  387. err = phy_write(phydev, MII_BCM54XX_ECR, reg);
  388. if (err < 0)
  389. return err;
  390. /* Unmask events we are interested in. */
  391. reg = ~(MII_BCM54XX_INT_DUPLEX |
  392. MII_BCM54XX_INT_SPEED |
  393. MII_BCM54XX_INT_LINK);
  394. err = phy_write(phydev, MII_BCM54XX_IMR, reg);
  395. if (err < 0)
  396. return err;
  397. if ((phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610) ||
  398. phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610M)) &&
  399. (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
  400. bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
  401. bcm54xx_adjust_rxrefclk(phydev);
  402. switch (phydev->drv->phy_id & PHY_ID_MATCH_MODEL_MASK) {
  403. case PHY_ID_BCM50610:
  404. case PHY_ID_BCM50610M:
  405. err = bcm54xx_config_clock_delay(phydev);
  406. break;
  407. case PHY_ID_BCM54210E:
  408. err = bcm54210e_config_init(phydev);
  409. break;
  410. case PHY_ID_BCM54612E:
  411. err = bcm54612e_config_init(phydev);
  412. break;
  413. case PHY_ID_BCM54616S:
  414. err = bcm54616s_config_init(phydev);
  415. break;
  416. case PHY_ID_BCM54810:
  417. /* For BCM54810, we need to disable BroadR-Reach function */
  418. val = bcm_phy_read_exp(phydev,
  419. BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
  420. val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
  421. err = bcm_phy_write_exp(phydev,
  422. BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
  423. val);
  424. break;
  425. case PHY_ID_BCM54811:
  426. err = bcm54811_config_init(phydev);
  427. break;
  428. }
  429. if (err)
  430. return err;
  431. bcm54xx_phydsp_config(phydev);
  432. /* For non-SFP setups, encode link speed into LED1 and LED3 pair
  433. * (green/amber).
  434. * Also flash these two LEDs on activity. This means configuring
  435. * them for MULTICOLOR and encoding link/activity into them.
  436. * Don't do this for devices on an SFP module, since some of these
  437. * use the LED outputs to control the SFP LOS signal, and changing
  438. * these settings will cause LOS to malfunction.
  439. */
  440. if (!phy_on_sfp(phydev)) {
  441. val = BCM54XX_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
  442. BCM54XX_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
  443. bcm_phy_write_shadow(phydev, BCM54XX_SHD_LEDS1, val);
  444. val = BCM_LED_MULTICOLOR_IN_PHASE |
  445. BCM54XX_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
  446. BCM54XX_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
  447. bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
  448. }
  449. bcm54xx_ptp_config_init(phydev);
  450. /* Acknowledge any left over interrupt and charge the device for
  451. * wake-up.
  452. */
  453. err = bcm_phy_read_exp(phydev, BCM54XX_WOL_INT_STATUS);
  454. if (err < 0)
  455. return err;
  456. if (err)
  457. pm_wakeup_event(&phydev->mdio.dev, 0);
  458. return 0;
  459. }
  460. static int bcm54xx_iddq_set(struct phy_device *phydev, bool enable)
  461. {
  462. int ret = 0;
  463. if (!(phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND))
  464. return ret;
  465. ret = bcm_phy_read_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL);
  466. if (ret < 0)
  467. goto out;
  468. if (enable)
  469. ret |= BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP;
  470. else
  471. ret &= ~(BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP);
  472. ret = bcm_phy_write_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL, ret);
  473. out:
  474. return ret;
  475. }
  476. static int bcm54xx_set_wakeup_irq(struct phy_device *phydev, bool state)
  477. {
  478. struct bcm54xx_phy_priv *priv = phydev->priv;
  479. int ret = 0;
  480. if (!bcm54xx_phy_can_wakeup(phydev))
  481. return ret;
  482. if (priv->wake_irq_enabled != state) {
  483. if (state)
  484. ret = enable_irq_wake(priv->wake_irq);
  485. else
  486. ret = disable_irq_wake(priv->wake_irq);
  487. priv->wake_irq_enabled = state;
  488. }
  489. return ret;
  490. }
  491. static int bcm54xx_suspend(struct phy_device *phydev)
  492. {
  493. int ret = 0;
  494. bcm54xx_ptp_stop(phydev);
  495. /* Acknowledge any Wake-on-LAN interrupt prior to suspend */
  496. ret = bcm_phy_read_exp(phydev, BCM54XX_WOL_INT_STATUS);
  497. if (ret < 0)
  498. return ret;
  499. if (phydev->wol_enabled)
  500. return bcm54xx_set_wakeup_irq(phydev, true);
  501. /* We cannot use a read/modify/write here otherwise the PHY gets into
  502. * a bad state where its LEDs keep flashing, thus defeating the purpose
  503. * of low power mode.
  504. */
  505. ret = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
  506. if (ret < 0)
  507. return ret;
  508. return bcm54xx_iddq_set(phydev, true);
  509. }
  510. static int bcm54xx_resume(struct phy_device *phydev)
  511. {
  512. int ret = 0;
  513. if (phydev->wol_enabled) {
  514. ret = bcm54xx_set_wakeup_irq(phydev, false);
  515. if (ret)
  516. return ret;
  517. }
  518. ret = bcm54xx_iddq_set(phydev, false);
  519. if (ret < 0)
  520. return ret;
  521. /* Writes to register other than BMCR would be ignored
  522. * unless we clear the PDOWN bit first
  523. */
  524. ret = genphy_resume(phydev);
  525. if (ret < 0)
  526. return ret;
  527. /* Upon exiting power down, the PHY remains in an internal reset state
  528. * for 40us
  529. */
  530. fsleep(40);
  531. /* Issue a soft reset after clearing the power down bit
  532. * and before doing any other configuration.
  533. */
  534. if (phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND) {
  535. ret = genphy_soft_reset(phydev);
  536. if (ret < 0)
  537. return ret;
  538. }
  539. return bcm54xx_config_init(phydev);
  540. }
  541. static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
  542. {
  543. return -EOPNOTSUPP;
  544. }
  545. static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
  546. u16 val)
  547. {
  548. return -EOPNOTSUPP;
  549. }
  550. /**
  551. * bcm5481x_read_abilities - read PHY abilities from LRESR or Clause 22
  552. * (BMSR) registers, based on whether the PHY is in BroadR-Reach or IEEE mode
  553. * @phydev: target phy_device struct
  554. *
  555. * Description: Reads the PHY's abilities and populates phydev->supported
  556. * accordingly. The register to read the abilities from is determined by
  557. * the brr mode setting of the PHY as read from the device tree.
  558. * Note that the LRE and IEEE sets of abilities are disjunct, in other words,
  559. * not only the link modes differ, but also the auto-negotiation and
  560. * master-slave setup is controlled differently.
  561. *
  562. * Returns: 0 on success, < 0 on failure
  563. */
  564. static int bcm5481x_read_abilities(struct phy_device *phydev)
  565. {
  566. struct device_node *np = phydev->mdio.dev.of_node;
  567. struct bcm54xx_phy_priv *priv = phydev->priv;
  568. int i, val, err, aneg;
  569. for (i = 0; i < ARRAY_SIZE(bcm54811_linkmodes); i++)
  570. linkmode_clear_bit(bcm54811_linkmodes[i], phydev->supported);
  571. priv->brr_mode = of_property_read_bool(np, "brr-mode");
  572. /* Set BroadR-Reach mode as configured in the DT. */
  573. err = bcm5481x_set_brrmode(phydev, priv->brr_mode);
  574. if (err)
  575. return err;
  576. if (priv->brr_mode) {
  577. linkmode_set_bit_array(phy_basic_ports_array,
  578. ARRAY_SIZE(phy_basic_ports_array),
  579. phydev->supported);
  580. val = phy_read(phydev, MII_BCM54XX_LRESR);
  581. if (val < 0)
  582. return val;
  583. /* BCM54811 is not capable of LDS but the corresponding bit
  584. * in LRESR is set to 1 and marked "Ignore" in the datasheet.
  585. * So we must read the bcm54811 as unable to auto-negotiate
  586. * in BroadR-Reach mode.
  587. */
  588. if (phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54811))
  589. aneg = 0;
  590. else
  591. aneg = val & LRESR_LDSABILITY;
  592. linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
  593. phydev->supported,
  594. aneg);
  595. linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
  596. phydev->supported,
  597. val & LRESR_100_1PAIR);
  598. linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
  599. phydev->supported,
  600. val & LRESR_10_1PAIR);
  601. return 0;
  602. }
  603. return genphy_read_abilities(phydev);
  604. }
  605. static int bcm5481x_config_delay_swap(struct phy_device *phydev)
  606. {
  607. struct device_node *np = phydev->mdio.dev.of_node;
  608. /* Set up the delay. */
  609. bcm54xx_config_clock_delay(phydev);
  610. if (of_property_read_bool(np, "enet-phy-lane-swap")) {
  611. /* Lane Swap - Undocumented register...magic! */
  612. int ret = bcm_phy_write_exp(phydev,
  613. MII_BCM54XX_EXP_SEL_ER + 0x9,
  614. 0x11B);
  615. if (ret < 0)
  616. return ret;
  617. }
  618. return 0;
  619. }
  620. static int bcm5481_config_aneg(struct phy_device *phydev)
  621. {
  622. struct bcm54xx_phy_priv *priv = phydev->priv;
  623. int ret;
  624. /* Aneg firstly. */
  625. if (priv->brr_mode)
  626. ret = bcm_config_lre_aneg(phydev, false);
  627. else
  628. ret = genphy_config_aneg(phydev);
  629. if (ret)
  630. return ret;
  631. /* Then we can set up the delay and swap. */
  632. return bcm5481x_config_delay_swap(phydev);
  633. }
  634. static int bcm54811_config_aneg(struct phy_device *phydev)
  635. {
  636. struct bcm54xx_phy_priv *priv = phydev->priv;
  637. int ret;
  638. /* Aneg firstly. */
  639. if (priv->brr_mode) {
  640. /* BCM54811 is only capable of autonegotiation in IEEE mode.
  641. * In BroadR-Reach mode, disable the Long Distance Signaling,
  642. * the BRR mode autoneg as supported in other Broadcom PHYs.
  643. * This bit is marked as "Reserved" and "Default 1, must be
  644. * written to 0 after every device reset" in the datasheet.
  645. */
  646. ret = phy_modify(phydev, MII_BCM54XX_LRECR, LRECR_LDSEN, 0);
  647. if (ret < 0)
  648. return ret;
  649. ret = bcm_config_lre_aneg(phydev, false);
  650. } else {
  651. ret = genphy_config_aneg(phydev);
  652. }
  653. if (ret)
  654. return ret;
  655. /* Then we can set up the delay and swap. */
  656. return bcm5481x_config_delay_swap(phydev);
  657. }
  658. struct bcm54616s_phy_priv {
  659. bool mode_1000bx_en;
  660. };
  661. static int bcm54616s_probe(struct phy_device *phydev)
  662. {
  663. struct bcm54616s_phy_priv *priv;
  664. int val;
  665. priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
  666. if (!priv)
  667. return -ENOMEM;
  668. phydev->priv = priv;
  669. val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
  670. if (val < 0)
  671. return val;
  672. /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
  673. * is 01b, and the link between PHY and its link partner can be
  674. * either 1000Base-X or 100Base-FX.
  675. * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
  676. * support is still missing as of now.
  677. */
  678. if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
  679. val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
  680. if (val < 0)
  681. return val;
  682. /* Bit 0 of the SerDes 100-FX Control register, when set
  683. * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
  684. * When this bit is set to 0, it sets the GMII/RGMII ->
  685. * 1000BASE-X configuration.
  686. */
  687. if (!(val & BCM54616S_100FX_MODE))
  688. priv->mode_1000bx_en = true;
  689. phydev->port = PORT_FIBRE;
  690. }
  691. return 0;
  692. }
  693. static int bcm54616s_config_aneg(struct phy_device *phydev)
  694. {
  695. struct bcm54616s_phy_priv *priv = phydev->priv;
  696. int ret;
  697. /* Aneg firstly. */
  698. if (priv->mode_1000bx_en)
  699. ret = genphy_c37_config_aneg(phydev);
  700. else
  701. ret = genphy_config_aneg(phydev);
  702. /* Then we can set up the delay. */
  703. bcm54xx_config_clock_delay(phydev);
  704. return ret;
  705. }
  706. static int bcm54616s_read_status(struct phy_device *phydev)
  707. {
  708. struct bcm54616s_phy_priv *priv = phydev->priv;
  709. bool changed;
  710. int err;
  711. if (priv->mode_1000bx_en)
  712. err = genphy_c37_read_status(phydev, &changed);
  713. else
  714. err = genphy_read_status(phydev);
  715. return err;
  716. }
  717. static int brcm_fet_config_init(struct phy_device *phydev)
  718. {
  719. int reg, err, err2, brcmtest;
  720. /* Reset the PHY to bring it to a known state. */
  721. err = phy_write(phydev, MII_BMCR, BMCR_RESET);
  722. if (err < 0)
  723. return err;
  724. /* The datasheet indicates the PHY needs up to 1us to complete a reset,
  725. * build some slack here.
  726. */
  727. usleep_range(1000, 2000);
  728. /* The PHY requires 65 MDC clock cycles to complete a write operation
  729. * and turnaround the line properly.
  730. *
  731. * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
  732. * may flag the lack of turn-around as a read failure. This is
  733. * particularly true with this combination since the MDIO controller
  734. * only used 64 MDC cycles. This is not a critical failure in this
  735. * specific case and it has no functional impact otherwise, so we let
  736. * that one go through. If there is a genuine bus error, the next read
  737. * of MII_BRCM_FET_INTREG will error out.
  738. */
  739. err = phy_read(phydev, MII_BMCR);
  740. if (err < 0 && err != -EIO)
  741. return err;
  742. /* Read to clear status bits */
  743. reg = phy_read(phydev, MII_BRCM_FET_INTREG);
  744. if (reg < 0)
  745. return reg;
  746. /* Unmask events we are interested in and mask interrupts globally. */
  747. if (phydev->drv->phy_id == PHY_ID_BCM5221)
  748. reg = MII_BRCM_FET_IR_ENABLE |
  749. MII_BRCM_FET_IR_MASK;
  750. else
  751. reg = MII_BRCM_FET_IR_DUPLEX_EN |
  752. MII_BRCM_FET_IR_SPEED_EN |
  753. MII_BRCM_FET_IR_LINK_EN |
  754. MII_BRCM_FET_IR_ENABLE |
  755. MII_BRCM_FET_IR_MASK;
  756. err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
  757. if (err < 0)
  758. return err;
  759. /* Enable shadow register access */
  760. brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
  761. if (brcmtest < 0)
  762. return brcmtest;
  763. reg = brcmtest | MII_BRCM_FET_BT_SRE;
  764. phy_lock_mdio_bus(phydev);
  765. err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
  766. if (err < 0) {
  767. phy_unlock_mdio_bus(phydev);
  768. return err;
  769. }
  770. if (phydev->drv->phy_id != PHY_ID_BCM5221) {
  771. /* Set the LED mode */
  772. reg = __phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
  773. if (reg < 0) {
  774. err = reg;
  775. goto done;
  776. }
  777. err = __phy_modify(phydev, MII_BRCM_FET_SHDW_AUXMODE4,
  778. MII_BRCM_FET_SHDW_AM4_LED_MASK,
  779. MII_BRCM_FET_SHDW_AM4_LED_MODE1);
  780. if (err < 0)
  781. goto done;
  782. /* Enable auto MDIX */
  783. err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
  784. MII_BRCM_FET_SHDW_MC_FAME);
  785. if (err < 0)
  786. goto done;
  787. }
  788. if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
  789. /* Enable auto power down */
  790. err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
  791. MII_BRCM_FET_SHDW_AS2_APDE);
  792. }
  793. done:
  794. /* Disable shadow register access */
  795. err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
  796. if (!err)
  797. err = err2;
  798. phy_unlock_mdio_bus(phydev);
  799. return err;
  800. }
  801. static int brcm_fet_ack_interrupt(struct phy_device *phydev)
  802. {
  803. int reg;
  804. /* Clear pending interrupts. */
  805. reg = phy_read(phydev, MII_BRCM_FET_INTREG);
  806. if (reg < 0)
  807. return reg;
  808. return 0;
  809. }
  810. static int brcm_fet_config_intr(struct phy_device *phydev)
  811. {
  812. int reg, err;
  813. reg = phy_read(phydev, MII_BRCM_FET_INTREG);
  814. if (reg < 0)
  815. return reg;
  816. if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
  817. err = brcm_fet_ack_interrupt(phydev);
  818. if (err)
  819. return err;
  820. reg &= ~MII_BRCM_FET_IR_MASK;
  821. err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
  822. } else {
  823. reg |= MII_BRCM_FET_IR_MASK;
  824. err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
  825. if (err)
  826. return err;
  827. err = brcm_fet_ack_interrupt(phydev);
  828. }
  829. return err;
  830. }
  831. static irqreturn_t brcm_fet_handle_interrupt(struct phy_device *phydev)
  832. {
  833. int irq_status;
  834. irq_status = phy_read(phydev, MII_BRCM_FET_INTREG);
  835. if (irq_status < 0) {
  836. phy_error(phydev);
  837. return IRQ_NONE;
  838. }
  839. if (irq_status == 0)
  840. return IRQ_NONE;
  841. phy_trigger_machine(phydev);
  842. return IRQ_HANDLED;
  843. }
  844. static int brcm_fet_suspend(struct phy_device *phydev)
  845. {
  846. int reg, err, err2, brcmtest;
  847. /* We cannot use a read/modify/write here otherwise the PHY continues
  848. * to drive LEDs which defeats the purpose of low power mode.
  849. */
  850. err = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
  851. if (err < 0)
  852. return err;
  853. /* Enable shadow register access */
  854. brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
  855. if (brcmtest < 0)
  856. return brcmtest;
  857. reg = brcmtest | MII_BRCM_FET_BT_SRE;
  858. phy_lock_mdio_bus(phydev);
  859. err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
  860. if (err < 0) {
  861. phy_unlock_mdio_bus(phydev);
  862. return err;
  863. }
  864. if (phydev->drv->phy_id == PHY_ID_BCM5221)
  865. /* Force Low Power Mode with clock enabled */
  866. reg = BCM5221_SHDW_AM4_EN_CLK_LPM | BCM5221_SHDW_AM4_FORCE_LPM;
  867. else
  868. /* Set standby mode */
  869. reg = MII_BRCM_FET_SHDW_AM4_STANDBY;
  870. err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
  871. /* Disable shadow register access */
  872. err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
  873. if (!err)
  874. err = err2;
  875. phy_unlock_mdio_bus(phydev);
  876. return err;
  877. }
  878. static int bcm5221_config_aneg(struct phy_device *phydev)
  879. {
  880. int ret, val;
  881. ret = genphy_config_aneg(phydev);
  882. if (ret)
  883. return ret;
  884. switch (phydev->mdix_ctrl) {
  885. case ETH_TP_MDI:
  886. val = BCM5221_AEGSR_MDIX_DIS;
  887. break;
  888. case ETH_TP_MDI_X:
  889. val = BCM5221_AEGSR_MDIX_DIS | BCM5221_AEGSR_MDIX_MAN_SWAP;
  890. break;
  891. case ETH_TP_MDI_AUTO:
  892. val = 0;
  893. break;
  894. default:
  895. return 0;
  896. }
  897. return phy_modify(phydev, BCM5221_AEGSR, BCM5221_AEGSR_MDIX_MAN_SWAP |
  898. BCM5221_AEGSR_MDIX_DIS,
  899. val);
  900. }
  901. static int bcm5221_read_status(struct phy_device *phydev)
  902. {
  903. int ret;
  904. /* Read MDIX status */
  905. ret = phy_read(phydev, BCM5221_AEGSR);
  906. if (ret < 0)
  907. return ret;
  908. if (ret & BCM5221_AEGSR_MDIX_DIS) {
  909. if (ret & BCM5221_AEGSR_MDIX_MAN_SWAP)
  910. phydev->mdix_ctrl = ETH_TP_MDI_X;
  911. else
  912. phydev->mdix_ctrl = ETH_TP_MDI;
  913. } else {
  914. phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
  915. }
  916. if (ret & BCM5221_AEGSR_MDIX_STATUS)
  917. phydev->mdix = ETH_TP_MDI_X;
  918. else
  919. phydev->mdix = ETH_TP_MDI;
  920. return genphy_read_status(phydev);
  921. }
  922. static void bcm54xx_phy_get_wol(struct phy_device *phydev,
  923. struct ethtool_wolinfo *wol)
  924. {
  925. /* We cannot wake-up if we do not have a dedicated PHY interrupt line
  926. * or an out of band GPIO descriptor for wake-up. Zeroing
  927. * wol->supported allows the caller (MAC driver) to play through and
  928. * offer its own Wake-on-LAN scheme if available.
  929. */
  930. if (!bcm54xx_phy_can_wakeup(phydev)) {
  931. wol->supported = 0;
  932. return;
  933. }
  934. bcm_phy_get_wol(phydev, wol);
  935. }
  936. static int bcm54xx_phy_set_wol(struct phy_device *phydev,
  937. struct ethtool_wolinfo *wol)
  938. {
  939. int ret;
  940. /* We cannot wake-up if we do not have a dedicated PHY interrupt line
  941. * or an out of band GPIO descriptor for wake-up. Returning -EOPNOTSUPP
  942. * allows the caller (MAC driver) to play through and offer its own
  943. * Wake-on-LAN scheme if available.
  944. */
  945. if (!bcm54xx_phy_can_wakeup(phydev))
  946. return -EOPNOTSUPP;
  947. ret = bcm_phy_set_wol(phydev, wol);
  948. if (ret < 0)
  949. return ret;
  950. return 0;
  951. }
  952. static int bcm54xx_phy_probe(struct phy_device *phydev)
  953. {
  954. struct bcm54xx_phy_priv *priv;
  955. struct gpio_desc *wakeup_gpio;
  956. int ret = 0;
  957. priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
  958. if (!priv)
  959. return -ENOMEM;
  960. priv->wake_irq = -ENXIO;
  961. phydev->priv = priv;
  962. priv->stats = devm_kcalloc(&phydev->mdio.dev,
  963. bcm_phy_get_sset_count(phydev), sizeof(u64),
  964. GFP_KERNEL);
  965. if (!priv->stats)
  966. return -ENOMEM;
  967. priv->ptp = bcm_ptp_probe(phydev);
  968. if (IS_ERR(priv->ptp))
  969. return PTR_ERR(priv->ptp);
  970. /* We cannot utilize the _optional variant here since we want to know
  971. * whether the GPIO descriptor exists or not to advertise Wake-on-LAN
  972. * support or not.
  973. */
  974. wakeup_gpio = devm_gpiod_get(&phydev->mdio.dev, "wakeup", GPIOD_IN);
  975. if (PTR_ERR(wakeup_gpio) == -EPROBE_DEFER)
  976. return PTR_ERR(wakeup_gpio);
  977. if (!IS_ERR(wakeup_gpio)) {
  978. priv->wake_irq = gpiod_to_irq(wakeup_gpio);
  979. /* Dummy interrupt handler which is not enabled but is provided
  980. * in order for the interrupt descriptor to be fully set-up.
  981. */
  982. ret = devm_request_irq(&phydev->mdio.dev, priv->wake_irq,
  983. bcm_phy_wol_isr,
  984. IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
  985. dev_name(&phydev->mdio.dev), phydev);
  986. if (ret)
  987. return ret;
  988. }
  989. /* If we do not have a main interrupt or a side-band wake-up interrupt,
  990. * then the device cannot be marked as wake-up capable.
  991. */
  992. if (!bcm54xx_phy_can_wakeup(phydev))
  993. return 0;
  994. return device_init_wakeup(&phydev->mdio.dev, true);
  995. }
  996. static void bcm54xx_get_stats(struct phy_device *phydev,
  997. struct ethtool_stats *stats, u64 *data)
  998. {
  999. struct bcm54xx_phy_priv *priv = phydev->priv;
  1000. bcm_phy_get_stats(phydev, priv->stats, stats, data);
  1001. }
  1002. static void bcm54xx_link_change_notify(struct phy_device *phydev)
  1003. {
  1004. u16 mask = MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE |
  1005. MII_BCM54XX_EXP_EXP08_FORCE_DAC_WAKE;
  1006. int ret;
  1007. if (phydev->state != PHY_RUNNING)
  1008. return;
  1009. /* Don't change the DAC wake settings if auto power down
  1010. * is not requested.
  1011. */
  1012. if (!(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
  1013. return;
  1014. ret = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP08);
  1015. if (ret < 0)
  1016. return;
  1017. /* Enable/disable 10BaseT auto and forced early DAC wake depending
  1018. * on the negotiated speed, those settings should only be done
  1019. * for 10Mbits/sec.
  1020. */
  1021. if (phydev->speed == SPEED_10)
  1022. ret |= mask;
  1023. else
  1024. ret &= ~mask;
  1025. bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret);
  1026. }
  1027. static int lre_read_master_slave(struct phy_device *phydev)
  1028. {
  1029. int cfg = MASTER_SLAVE_CFG_UNKNOWN, state;
  1030. int val;
  1031. /* In BroadR-Reach mode we are always capable of master-slave
  1032. * and there is no preferred master or slave configuration
  1033. */
  1034. phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
  1035. phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
  1036. val = phy_read(phydev, MII_BCM54XX_LRECR);
  1037. if (val < 0)
  1038. return val;
  1039. if ((val & LRECR_LDSEN) == 0) {
  1040. if (val & LRECR_MASTER)
  1041. cfg = MASTER_SLAVE_CFG_MASTER_FORCE;
  1042. else
  1043. cfg = MASTER_SLAVE_CFG_SLAVE_FORCE;
  1044. }
  1045. val = phy_read(phydev, MII_BCM54XX_LRELDSE);
  1046. if (val < 0)
  1047. return val;
  1048. if (val & LDSE_MASTER)
  1049. state = MASTER_SLAVE_STATE_MASTER;
  1050. else
  1051. state = MASTER_SLAVE_STATE_SLAVE;
  1052. phydev->master_slave_get = cfg;
  1053. phydev->master_slave_state = state;
  1054. return 0;
  1055. }
  1056. /* Read LDS Link Partner Ability in BroadR-Reach mode */
  1057. static int lre_read_lpa(struct phy_device *phydev)
  1058. {
  1059. int i, lrelpa;
  1060. if (phydev->autoneg != AUTONEG_ENABLE) {
  1061. if (!phydev->autoneg_complete) {
  1062. /* aneg not yet done, reset all relevant bits */
  1063. for (i = 0; i < ARRAY_SIZE(lds_br_bits); i++)
  1064. linkmode_clear_bit(lds_br_bits[i],
  1065. phydev->lp_advertising);
  1066. return 0;
  1067. }
  1068. /* Long-Distance Signaling Link Partner Ability */
  1069. lrelpa = phy_read(phydev, MII_BCM54XX_LRELPA);
  1070. if (lrelpa < 0)
  1071. return lrelpa;
  1072. linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  1073. phydev->lp_advertising,
  1074. lrelpa & LRELPA_PAUSE_ASYM);
  1075. linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
  1076. phydev->lp_advertising,
  1077. lrelpa & LRELPA_PAUSE);
  1078. linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
  1079. phydev->lp_advertising,
  1080. lrelpa & LRELPA_100_1PAIR);
  1081. linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
  1082. phydev->lp_advertising,
  1083. lrelpa & LRELPA_10_1PAIR);
  1084. } else {
  1085. linkmode_zero(phydev->lp_advertising);
  1086. }
  1087. return 0;
  1088. }
  1089. static int lre_read_status_fixed(struct phy_device *phydev)
  1090. {
  1091. int lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
  1092. if (lrecr < 0)
  1093. return lrecr;
  1094. phydev->duplex = DUPLEX_FULL;
  1095. if (lrecr & LRECR_SPEED100)
  1096. phydev->speed = SPEED_100;
  1097. else
  1098. phydev->speed = SPEED_10;
  1099. return 0;
  1100. }
  1101. /**
  1102. * lre_update_link - update link status in @phydev
  1103. * @phydev: target phy_device struct
  1104. * Return: 0 on success, < 0 on error
  1105. *
  1106. * Description: Update the value in phydev->link to reflect the
  1107. * current link value. In order to do this, we need to read
  1108. * the status register twice, keeping the second value.
  1109. * This is a genphy_update_link modified to work on LRE registers
  1110. * of BroadR-Reach PHY
  1111. */
  1112. static int lre_update_link(struct phy_device *phydev)
  1113. {
  1114. int status = 0, lrecr;
  1115. lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
  1116. if (lrecr < 0)
  1117. return lrecr;
  1118. /* Autoneg is being started, therefore disregard BMSR value and
  1119. * report link as down.
  1120. */
  1121. if (lrecr & BMCR_ANRESTART)
  1122. goto done;
  1123. /* The link state is latched low so that momentary link
  1124. * drops can be detected. Do not double-read the status
  1125. * in polling mode to detect such short link drops except
  1126. * the link was already down.
  1127. */
  1128. if (!phy_polling_mode(phydev) || !phydev->link) {
  1129. status = phy_read(phydev, MII_BCM54XX_LRESR);
  1130. if (status < 0)
  1131. return status;
  1132. else if (status & LRESR_LSTATUS)
  1133. goto done;
  1134. }
  1135. /* Read link and autonegotiation status */
  1136. status = phy_read(phydev, MII_BCM54XX_LRESR);
  1137. if (status < 0)
  1138. return status;
  1139. done:
  1140. phydev->link = status & LRESR_LSTATUS ? 1 : 0;
  1141. phydev->autoneg_complete = status & LRESR_LDSCOMPLETE ? 1 : 0;
  1142. /* Consider the case that autoneg was started and "aneg complete"
  1143. * bit has been reset, but "link up" bit not yet.
  1144. */
  1145. if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete)
  1146. phydev->link = 0;
  1147. return 0;
  1148. }
  1149. /* Get the status in BroadRReach mode just like genphy_read_status does
  1150. * in normal mode
  1151. */
  1152. static int bcm54811_lre_read_status(struct phy_device *phydev)
  1153. {
  1154. int err, old_link = phydev->link;
  1155. /* Update the link, but return if there was an error */
  1156. err = lre_update_link(phydev);
  1157. if (err)
  1158. return err;
  1159. /* why bother the PHY if nothing can have changed */
  1160. if (phydev->autoneg ==
  1161. AUTONEG_ENABLE && old_link && phydev->link)
  1162. return 0;
  1163. phydev->speed = SPEED_UNKNOWN;
  1164. phydev->duplex = DUPLEX_UNKNOWN;
  1165. phydev->pause = 0;
  1166. phydev->asym_pause = 0;
  1167. err = lre_read_master_slave(phydev);
  1168. if (err < 0)
  1169. return err;
  1170. /* Read LDS Link Partner Ability */
  1171. err = lre_read_lpa(phydev);
  1172. if (err < 0)
  1173. return err;
  1174. if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
  1175. phy_resolve_aneg_linkmode(phydev);
  1176. else if (phydev->autoneg == AUTONEG_DISABLE)
  1177. err = lre_read_status_fixed(phydev);
  1178. return err;
  1179. }
  1180. static int bcm54811_read_status(struct phy_device *phydev)
  1181. {
  1182. struct bcm54xx_phy_priv *priv = phydev->priv;
  1183. if (priv->brr_mode)
  1184. return bcm54811_lre_read_status(phydev);
  1185. return genphy_read_status(phydev);
  1186. }
  1187. static struct phy_driver broadcom_drivers[] = {
  1188. {
  1189. PHY_ID_MATCH_MODEL(PHY_ID_BCM5411),
  1190. .name = "Broadcom BCM5411",
  1191. /* PHY_GBIT_FEATURES */
  1192. .get_sset_count = bcm_phy_get_sset_count,
  1193. .get_strings = bcm_phy_get_strings,
  1194. .get_stats = bcm54xx_get_stats,
  1195. .probe = bcm54xx_phy_probe,
  1196. .config_init = bcm54xx_config_init,
  1197. .config_intr = bcm_phy_config_intr,
  1198. .handle_interrupt = bcm_phy_handle_interrupt,
  1199. .link_change_notify = bcm54xx_link_change_notify,
  1200. }, {
  1201. PHY_ID_MATCH_MODEL(PHY_ID_BCM5421),
  1202. .name = "Broadcom BCM5421",
  1203. /* PHY_GBIT_FEATURES */
  1204. .get_sset_count = bcm_phy_get_sset_count,
  1205. .get_strings = bcm_phy_get_strings,
  1206. .get_stats = bcm54xx_get_stats,
  1207. .probe = bcm54xx_phy_probe,
  1208. .config_init = bcm54xx_config_init,
  1209. .config_intr = bcm_phy_config_intr,
  1210. .handle_interrupt = bcm_phy_handle_interrupt,
  1211. .link_change_notify = bcm54xx_link_change_notify,
  1212. }, {
  1213. PHY_ID_MATCH_MODEL(PHY_ID_BCM54210E),
  1214. .name = "Broadcom BCM54210E",
  1215. /* PHY_GBIT_FEATURES */
  1216. .flags = PHY_ALWAYS_CALL_SUSPEND,
  1217. .get_sset_count = bcm_phy_get_sset_count,
  1218. .get_strings = bcm_phy_get_strings,
  1219. .get_stats = bcm54xx_get_stats,
  1220. .probe = bcm54xx_phy_probe,
  1221. .config_init = bcm54xx_config_init,
  1222. .config_intr = bcm_phy_config_intr,
  1223. .handle_interrupt = bcm_phy_handle_interrupt,
  1224. .link_change_notify = bcm54xx_link_change_notify,
  1225. .suspend = bcm54xx_suspend,
  1226. .resume = bcm54xx_resume,
  1227. .get_wol = bcm54xx_phy_get_wol,
  1228. .set_wol = bcm54xx_phy_set_wol,
  1229. .led_brightness_set = bcm_phy_led_brightness_set,
  1230. }, {
  1231. PHY_ID_MATCH_MODEL(PHY_ID_BCM5461),
  1232. .name = "Broadcom BCM5461",
  1233. /* PHY_GBIT_FEATURES */
  1234. .get_sset_count = bcm_phy_get_sset_count,
  1235. .get_strings = bcm_phy_get_strings,
  1236. .get_stats = bcm54xx_get_stats,
  1237. .probe = bcm54xx_phy_probe,
  1238. .config_init = bcm54xx_config_init,
  1239. .config_intr = bcm_phy_config_intr,
  1240. .handle_interrupt = bcm_phy_handle_interrupt,
  1241. .link_change_notify = bcm54xx_link_change_notify,
  1242. .led_brightness_set = bcm_phy_led_brightness_set,
  1243. }, {
  1244. PHY_ID_MATCH_MODEL(PHY_ID_BCM54612E),
  1245. .name = "Broadcom BCM54612E",
  1246. /* PHY_GBIT_FEATURES */
  1247. .get_sset_count = bcm_phy_get_sset_count,
  1248. .get_strings = bcm_phy_get_strings,
  1249. .get_stats = bcm54xx_get_stats,
  1250. .probe = bcm54xx_phy_probe,
  1251. .config_init = bcm54xx_config_init,
  1252. .config_intr = bcm_phy_config_intr,
  1253. .handle_interrupt = bcm_phy_handle_interrupt,
  1254. .link_change_notify = bcm54xx_link_change_notify,
  1255. .led_brightness_set = bcm_phy_led_brightness_set,
  1256. .suspend = bcm54xx_suspend,
  1257. .resume = bcm54xx_resume,
  1258. }, {
  1259. PHY_ID_MATCH_MODEL(PHY_ID_BCM54616S),
  1260. .name = "Broadcom BCM54616S",
  1261. /* PHY_GBIT_FEATURES */
  1262. .soft_reset = genphy_soft_reset,
  1263. .config_init = bcm54xx_config_init,
  1264. .config_aneg = bcm54616s_config_aneg,
  1265. .config_intr = bcm_phy_config_intr,
  1266. .handle_interrupt = bcm_phy_handle_interrupt,
  1267. .read_status = bcm54616s_read_status,
  1268. .probe = bcm54616s_probe,
  1269. .link_change_notify = bcm54xx_link_change_notify,
  1270. .led_brightness_set = bcm_phy_led_brightness_set,
  1271. }, {
  1272. PHY_ID_MATCH_MODEL(PHY_ID_BCM5464),
  1273. .name = "Broadcom BCM5464",
  1274. /* PHY_GBIT_FEATURES */
  1275. .get_sset_count = bcm_phy_get_sset_count,
  1276. .get_strings = bcm_phy_get_strings,
  1277. .get_stats = bcm54xx_get_stats,
  1278. .probe = bcm54xx_phy_probe,
  1279. .config_init = bcm54xx_config_init,
  1280. .config_intr = bcm_phy_config_intr,
  1281. .handle_interrupt = bcm_phy_handle_interrupt,
  1282. .suspend = genphy_suspend,
  1283. .resume = genphy_resume,
  1284. .link_change_notify = bcm54xx_link_change_notify,
  1285. .led_brightness_set = bcm_phy_led_brightness_set,
  1286. }, {
  1287. PHY_ID_MATCH_MODEL(PHY_ID_BCM5481),
  1288. .name = "Broadcom BCM5481",
  1289. /* PHY_GBIT_FEATURES */
  1290. .get_sset_count = bcm_phy_get_sset_count,
  1291. .get_strings = bcm_phy_get_strings,
  1292. .get_stats = bcm54xx_get_stats,
  1293. .probe = bcm54xx_phy_probe,
  1294. .config_init = bcm54xx_config_init,
  1295. .config_aneg = bcm5481_config_aneg,
  1296. .config_intr = bcm_phy_config_intr,
  1297. .handle_interrupt = bcm_phy_handle_interrupt,
  1298. .link_change_notify = bcm54xx_link_change_notify,
  1299. .led_brightness_set = bcm_phy_led_brightness_set,
  1300. }, {
  1301. PHY_ID_MATCH_MODEL(PHY_ID_BCM54810),
  1302. .name = "Broadcom BCM54810",
  1303. /* PHY_GBIT_FEATURES */
  1304. .get_sset_count = bcm_phy_get_sset_count,
  1305. .get_strings = bcm_phy_get_strings,
  1306. .get_stats = bcm54xx_get_stats,
  1307. .probe = bcm54xx_phy_probe,
  1308. .read_mmd = bcm54810_read_mmd,
  1309. .write_mmd = bcm54810_write_mmd,
  1310. .config_init = bcm54xx_config_init,
  1311. .config_aneg = bcm5481_config_aneg,
  1312. .config_intr = bcm_phy_config_intr,
  1313. .handle_interrupt = bcm_phy_handle_interrupt,
  1314. .suspend = bcm54xx_suspend,
  1315. .resume = bcm54xx_resume,
  1316. .link_change_notify = bcm54xx_link_change_notify,
  1317. .led_brightness_set = bcm_phy_led_brightness_set,
  1318. }, {
  1319. PHY_ID_MATCH_MODEL(PHY_ID_BCM54811),
  1320. .name = "Broadcom BCM54811",
  1321. /* PHY_GBIT_FEATURES */
  1322. .get_sset_count = bcm_phy_get_sset_count,
  1323. .get_strings = bcm_phy_get_strings,
  1324. .get_stats = bcm54xx_get_stats,
  1325. .probe = bcm54xx_phy_probe,
  1326. .config_init = bcm54xx_config_init,
  1327. .config_aneg = bcm54811_config_aneg,
  1328. .config_intr = bcm_phy_config_intr,
  1329. .handle_interrupt = bcm_phy_handle_interrupt,
  1330. .read_status = bcm54811_read_status,
  1331. .get_features = bcm5481x_read_abilities,
  1332. .suspend = bcm54xx_suspend,
  1333. .resume = bcm54xx_resume,
  1334. .link_change_notify = bcm54xx_link_change_notify,
  1335. .led_brightness_set = bcm_phy_led_brightness_set,
  1336. }, {
  1337. PHY_ID_MATCH_MODEL(PHY_ID_BCM5482),
  1338. .name = "Broadcom BCM5482",
  1339. /* PHY_GBIT_FEATURES */
  1340. .get_sset_count = bcm_phy_get_sset_count,
  1341. .get_strings = bcm_phy_get_strings,
  1342. .get_stats = bcm54xx_get_stats,
  1343. .probe = bcm54xx_phy_probe,
  1344. .config_init = bcm54xx_config_init,
  1345. .config_intr = bcm_phy_config_intr,
  1346. .handle_interrupt = bcm_phy_handle_interrupt,
  1347. .link_change_notify = bcm54xx_link_change_notify,
  1348. .led_brightness_set = bcm_phy_led_brightness_set,
  1349. }, {
  1350. PHY_ID_MATCH_MODEL(PHY_ID_BCM50610),
  1351. .name = "Broadcom BCM50610",
  1352. /* PHY_GBIT_FEATURES */
  1353. .get_sset_count = bcm_phy_get_sset_count,
  1354. .get_strings = bcm_phy_get_strings,
  1355. .get_stats = bcm54xx_get_stats,
  1356. .probe = bcm54xx_phy_probe,
  1357. .config_init = bcm54xx_config_init,
  1358. .config_intr = bcm_phy_config_intr,
  1359. .handle_interrupt = bcm_phy_handle_interrupt,
  1360. .link_change_notify = bcm54xx_link_change_notify,
  1361. .suspend = bcm54xx_suspend,
  1362. .resume = bcm54xx_resume,
  1363. .led_brightness_set = bcm_phy_led_brightness_set,
  1364. }, {
  1365. PHY_ID_MATCH_MODEL(PHY_ID_BCM50610M),
  1366. .name = "Broadcom BCM50610M",
  1367. /* PHY_GBIT_FEATURES */
  1368. .get_sset_count = bcm_phy_get_sset_count,
  1369. .get_strings = bcm_phy_get_strings,
  1370. .get_stats = bcm54xx_get_stats,
  1371. .probe = bcm54xx_phy_probe,
  1372. .config_init = bcm54xx_config_init,
  1373. .config_intr = bcm_phy_config_intr,
  1374. .handle_interrupt = bcm_phy_handle_interrupt,
  1375. .link_change_notify = bcm54xx_link_change_notify,
  1376. .suspend = bcm54xx_suspend,
  1377. .resume = bcm54xx_resume,
  1378. .led_brightness_set = bcm_phy_led_brightness_set,
  1379. }, {
  1380. PHY_ID_MATCH_MODEL(PHY_ID_BCM57780),
  1381. .name = "Broadcom BCM57780",
  1382. /* PHY_GBIT_FEATURES */
  1383. .get_sset_count = bcm_phy_get_sset_count,
  1384. .get_strings = bcm_phy_get_strings,
  1385. .get_stats = bcm54xx_get_stats,
  1386. .probe = bcm54xx_phy_probe,
  1387. .config_init = bcm54xx_config_init,
  1388. .config_intr = bcm_phy_config_intr,
  1389. .handle_interrupt = bcm_phy_handle_interrupt,
  1390. .link_change_notify = bcm54xx_link_change_notify,
  1391. .led_brightness_set = bcm_phy_led_brightness_set,
  1392. }, {
  1393. PHY_ID_MATCH_MODEL(PHY_ID_BCMAC131),
  1394. .name = "Broadcom BCMAC131",
  1395. /* PHY_BASIC_FEATURES */
  1396. .config_init = brcm_fet_config_init,
  1397. .config_intr = brcm_fet_config_intr,
  1398. .handle_interrupt = brcm_fet_handle_interrupt,
  1399. .suspend = brcm_fet_suspend,
  1400. .resume = brcm_fet_config_init,
  1401. }, {
  1402. PHY_ID_MATCH_MODEL(PHY_ID_BCM5241),
  1403. .name = "Broadcom BCM5241",
  1404. /* PHY_BASIC_FEATURES */
  1405. .config_init = brcm_fet_config_init,
  1406. .config_intr = brcm_fet_config_intr,
  1407. .handle_interrupt = brcm_fet_handle_interrupt,
  1408. .suspend = brcm_fet_suspend,
  1409. .resume = brcm_fet_config_init,
  1410. }, {
  1411. PHY_ID_MATCH_MODEL(PHY_ID_BCM5221),
  1412. .name = "Broadcom BCM5221",
  1413. /* PHY_BASIC_FEATURES */
  1414. .config_init = brcm_fet_config_init,
  1415. .config_intr = brcm_fet_config_intr,
  1416. .handle_interrupt = brcm_fet_handle_interrupt,
  1417. .suspend = brcm_fet_suspend,
  1418. .resume = brcm_fet_config_init,
  1419. .config_aneg = bcm5221_config_aneg,
  1420. .read_status = bcm5221_read_status,
  1421. }, {
  1422. PHY_ID_MATCH_MODEL(PHY_ID_BCM5395),
  1423. .name = "Broadcom BCM5395",
  1424. .flags = PHY_IS_INTERNAL,
  1425. /* PHY_GBIT_FEATURES */
  1426. .get_sset_count = bcm_phy_get_sset_count,
  1427. .get_strings = bcm_phy_get_strings,
  1428. .get_stats = bcm54xx_get_stats,
  1429. .probe = bcm54xx_phy_probe,
  1430. .link_change_notify = bcm54xx_link_change_notify,
  1431. .led_brightness_set = bcm_phy_led_brightness_set,
  1432. }, {
  1433. PHY_ID_MATCH_MODEL(PHY_ID_BCM53125),
  1434. .name = "Broadcom BCM53125",
  1435. .flags = PHY_IS_INTERNAL,
  1436. /* PHY_GBIT_FEATURES */
  1437. .get_sset_count = bcm_phy_get_sset_count,
  1438. .get_strings = bcm_phy_get_strings,
  1439. .get_stats = bcm54xx_get_stats,
  1440. .probe = bcm54xx_phy_probe,
  1441. .config_init = bcm54xx_config_init,
  1442. .config_intr = bcm_phy_config_intr,
  1443. .handle_interrupt = bcm_phy_handle_interrupt,
  1444. .link_change_notify = bcm54xx_link_change_notify,
  1445. .led_brightness_set = bcm_phy_led_brightness_set,
  1446. }, {
  1447. PHY_ID_MATCH_MODEL(PHY_ID_BCM53128),
  1448. .name = "Broadcom BCM53128",
  1449. .flags = PHY_IS_INTERNAL,
  1450. /* PHY_GBIT_FEATURES */
  1451. .get_sset_count = bcm_phy_get_sset_count,
  1452. .get_strings = bcm_phy_get_strings,
  1453. .get_stats = bcm54xx_get_stats,
  1454. .probe = bcm54xx_phy_probe,
  1455. .config_init = bcm54xx_config_init,
  1456. .config_intr = bcm_phy_config_intr,
  1457. .handle_interrupt = bcm_phy_handle_interrupt,
  1458. .link_change_notify = bcm54xx_link_change_notify,
  1459. .led_brightness_set = bcm_phy_led_brightness_set,
  1460. }, {
  1461. PHY_ID_MATCH_MODEL(PHY_ID_BCM89610),
  1462. .name = "Broadcom BCM89610",
  1463. /* PHY_GBIT_FEATURES */
  1464. .get_sset_count = bcm_phy_get_sset_count,
  1465. .get_strings = bcm_phy_get_strings,
  1466. .get_stats = bcm54xx_get_stats,
  1467. .probe = bcm54xx_phy_probe,
  1468. .config_init = bcm54xx_config_init,
  1469. .config_intr = bcm_phy_config_intr,
  1470. .handle_interrupt = bcm_phy_handle_interrupt,
  1471. .link_change_notify = bcm54xx_link_change_notify,
  1472. } };
  1473. module_phy_driver(broadcom_drivers);
  1474. static const struct mdio_device_id __maybe_unused broadcom_tbl[] = {
  1475. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5411) },
  1476. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5421) },
  1477. { PHY_ID_MATCH_MODEL(PHY_ID_BCM54210E) },
  1478. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5461) },
  1479. { PHY_ID_MATCH_MODEL(PHY_ID_BCM54612E) },
  1480. { PHY_ID_MATCH_MODEL(PHY_ID_BCM54616S) },
  1481. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5464) },
  1482. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5481) },
  1483. { PHY_ID_MATCH_MODEL(PHY_ID_BCM54810) },
  1484. { PHY_ID_MATCH_MODEL(PHY_ID_BCM54811) },
  1485. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5482) },
  1486. { PHY_ID_MATCH_MODEL(PHY_ID_BCM50610) },
  1487. { PHY_ID_MATCH_MODEL(PHY_ID_BCM50610M) },
  1488. { PHY_ID_MATCH_MODEL(PHY_ID_BCM57780) },
  1489. { PHY_ID_MATCH_MODEL(PHY_ID_BCMAC131) },
  1490. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5221) },
  1491. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5241) },
  1492. { PHY_ID_MATCH_MODEL(PHY_ID_BCM5395) },
  1493. { PHY_ID_MATCH_MODEL(PHY_ID_BCM53125) },
  1494. { PHY_ID_MATCH_MODEL(PHY_ID_BCM53128) },
  1495. { PHY_ID_MATCH_MODEL(PHY_ID_BCM89610) },
  1496. { }
  1497. };
  1498. MODULE_DEVICE_TABLE(mdio, broadcom_tbl);