marvell.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * drivers/net/phy/marvell.c
  4. *
  5. * Driver for Marvell PHYs
  6. *
  7. * Author: Andy Fleming
  8. *
  9. * Copyright (c) 2004 Freescale Semiconductor, Inc.
  10. *
  11. * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de>
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/string.h>
  15. #include <linux/ctype.h>
  16. #include <linux/errno.h>
  17. #include <linux/unistd.h>
  18. #include <linux/hwmon.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/init.h>
  21. #include <linux/delay.h>
  22. #include <linux/netdevice.h>
  23. #include <linux/etherdevice.h>
  24. #include <linux/skbuff.h>
  25. #include <linux/spinlock.h>
  26. #include <linux/mm.h>
  27. #include <linux/module.h>
  28. #include <linux/mii.h>
  29. #include <linux/ethtool.h>
  30. #include <linux/phy.h>
  31. #include <linux/marvell_phy.h>
  32. #include <linux/bitfield.h>
  33. #include <linux/of.h>
  34. #include <linux/io.h>
  35. #include <asm/irq.h>
  36. #include <linux/uaccess.h>
  37. #define MII_MARVELL_PHY_PAGE 22
  38. #define MII_MARVELL_COPPER_PAGE 0x00
  39. #define MII_MARVELL_FIBER_PAGE 0x01
  40. #define MII_MARVELL_MSCR_PAGE 0x02
  41. #define MII_MARVELL_LED_PAGE 0x03
  42. #define MII_MARVELL_MISC_TEST_PAGE 0x06
  43. #define MII_MARVELL_WOL_PAGE 0x11
  44. #define MII_M1011_IEVENT 0x13
  45. #define MII_M1011_IEVENT_CLEAR 0x0000
  46. #define MII_M1011_IMASK 0x12
  47. #define MII_M1011_IMASK_INIT 0x6400
  48. #define MII_M1011_IMASK_CLEAR 0x0000
  49. #define MII_M1011_PHY_SCR 0x10
  50. #define MII_M1011_PHY_SCR_DOWNSHIFT_EN BIT(11)
  51. #define MII_M1011_PHY_SCR_DOWNSHIFT_SHIFT 12
  52. #define MII_M1011_PHY_SRC_DOWNSHIFT_MASK 0x7800
  53. #define MII_M1011_PHY_SCR_MDI (0x0 << 5)
  54. #define MII_M1011_PHY_SCR_MDI_X (0x1 << 5)
  55. #define MII_M1011_PHY_SCR_AUTO_CROSS (0x3 << 5)
  56. #define MII_M1111_PHY_LED_CONTROL 0x18
  57. #define MII_M1111_PHY_LED_DIRECT 0x4100
  58. #define MII_M1111_PHY_LED_COMBINE 0x411c
  59. #define MII_M1111_PHY_EXT_CR 0x14
  60. #define MII_M1111_RGMII_RX_DELAY BIT(7)
  61. #define MII_M1111_RGMII_TX_DELAY BIT(1)
  62. #define MII_M1111_PHY_EXT_SR 0x1b
  63. #define MII_M1111_HWCFG_MODE_MASK 0xf
  64. #define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3
  65. #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4
  66. #define MII_M1111_HWCFG_MODE_RTBI 0x7
  67. #define MII_M1111_HWCFG_MODE_COPPER_RTBI 0x9
  68. #define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb
  69. #define MII_M1111_HWCFG_FIBER_COPPER_RES BIT(13)
  70. #define MII_M1111_HWCFG_FIBER_COPPER_AUTO BIT(15)
  71. #define MII_88E1121_PHY_MSCR_REG 21
  72. #define MII_88E1121_PHY_MSCR_RX_DELAY BIT(5)
  73. #define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4)
  74. #define MII_88E1121_PHY_MSCR_DELAY_MASK (BIT(5) | BIT(4))
  75. #define MII_88E1121_MISC_TEST 0x1a
  76. #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK 0x1f00
  77. #define MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT 8
  78. #define MII_88E1510_MISC_TEST_TEMP_IRQ_EN BIT(7)
  79. #define MII_88E1510_MISC_TEST_TEMP_IRQ BIT(6)
  80. #define MII_88E1121_MISC_TEST_TEMP_SENSOR_EN BIT(5)
  81. #define MII_88E1121_MISC_TEST_TEMP_MASK 0x1f
  82. #define MII_88E1510_TEMP_SENSOR 0x1b
  83. #define MII_88E1510_TEMP_SENSOR_MASK 0xff
  84. #define MII_88E1540_COPPER_CTRL3 0x1a
  85. #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK GENMASK(11, 10)
  86. #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS 0
  87. #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS 1
  88. #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS 2
  89. #define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS 3
  90. #define MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN BIT(9)
  91. #define MII_88E6390_MISC_TEST 0x1b
  92. #define MII_88E6390_MISC_TEST_SAMPLE_1S 0
  93. #define MII_88E6390_MISC_TEST_SAMPLE_10MS BIT(14)
  94. #define MII_88E6390_MISC_TEST_SAMPLE_DISABLE BIT(15)
  95. #define MII_88E6390_MISC_TEST_SAMPLE_ENABLE 0
  96. #define MII_88E6390_MISC_TEST_SAMPLE_MASK (0x3 << 14)
  97. #define MII_88E6390_TEMP_SENSOR 0x1c
  98. #define MII_88E6390_TEMP_SENSOR_MASK 0xff
  99. #define MII_88E6390_TEMP_SENSOR_SAMPLES 10
  100. #define MII_88E1318S_PHY_MSCR1_REG 16
  101. #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6)
  102. /* Copper Specific Interrupt Enable Register */
  103. #define MII_88E1318S_PHY_CSIER 0x12
  104. /* WOL Event Interrupt Enable */
  105. #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7)
  106. /* LED Timer Control Register */
  107. #define MII_88E1318S_PHY_LED_TCR 0x12
  108. #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
  109. #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
  110. #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11)
  111. /* Magic Packet MAC address registers */
  112. #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17
  113. #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1 0x18
  114. #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0 0x19
  115. #define MII_88E1318S_PHY_WOL_CTRL 0x10
  116. #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS BIT(12)
  117. #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14)
  118. #define MII_PHY_LED_CTRL 16
  119. #define MII_88E1121_PHY_LED_DEF 0x0030
  120. #define MII_88E1510_PHY_LED_DEF 0x1177
  121. #define MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE 0x1040
  122. #define MII_M1011_PHY_STATUS 0x11
  123. #define MII_M1011_PHY_STATUS_1000 0x8000
  124. #define MII_M1011_PHY_STATUS_100 0x4000
  125. #define MII_M1011_PHY_STATUS_SPD_MASK 0xc000
  126. #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000
  127. #define MII_M1011_PHY_STATUS_RESOLVED 0x0800
  128. #define MII_M1011_PHY_STATUS_LINK 0x0400
  129. #define MII_88E3016_PHY_SPEC_CTRL 0x10
  130. #define MII_88E3016_DISABLE_SCRAMBLER 0x0200
  131. #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030
  132. #define MII_88E1510_GEN_CTRL_REG_1 0x14
  133. #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7
  134. #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1 /* SGMII to copper */
  135. #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */
  136. #define LPA_FIBER_1000HALF 0x40
  137. #define LPA_FIBER_1000FULL 0x20
  138. #define LPA_PAUSE_FIBER 0x180
  139. #define LPA_PAUSE_ASYM_FIBER 0x100
  140. #define ADVERTISE_FIBER_1000HALF 0x40
  141. #define ADVERTISE_FIBER_1000FULL 0x20
  142. #define ADVERTISE_PAUSE_FIBER 0x180
  143. #define ADVERTISE_PAUSE_ASYM_FIBER 0x100
  144. #define REGISTER_LINK_STATUS 0x400
  145. #define NB_FIBER_STATS 1
  146. MODULE_DESCRIPTION("Marvell PHY driver");
  147. MODULE_AUTHOR("Andy Fleming");
  148. MODULE_LICENSE("GPL");
  149. struct marvell_hw_stat {
  150. const char *string;
  151. u8 page;
  152. u8 reg;
  153. u8 bits;
  154. };
  155. static struct marvell_hw_stat marvell_hw_stats[] = {
  156. { "phy_receive_errors_copper", 0, 21, 16},
  157. { "phy_idle_errors", 0, 10, 8 },
  158. { "phy_receive_errors_fiber", 1, 21, 16},
  159. };
  160. struct marvell_priv {
  161. u64 stats[ARRAY_SIZE(marvell_hw_stats)];
  162. char *hwmon_name;
  163. struct device *hwmon_dev;
  164. };
  165. static int marvell_read_page(struct phy_device *phydev)
  166. {
  167. return __phy_read(phydev, MII_MARVELL_PHY_PAGE);
  168. }
  169. static int marvell_write_page(struct phy_device *phydev, int page)
  170. {
  171. return __phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
  172. }
  173. static int marvell_set_page(struct phy_device *phydev, int page)
  174. {
  175. return phy_write(phydev, MII_MARVELL_PHY_PAGE, page);
  176. }
  177. static int marvell_ack_interrupt(struct phy_device *phydev)
  178. {
  179. int err;
  180. /* Clear the interrupts by reading the reg */
  181. err = phy_read(phydev, MII_M1011_IEVENT);
  182. if (err < 0)
  183. return err;
  184. return 0;
  185. }
  186. static int marvell_config_intr(struct phy_device *phydev)
  187. {
  188. int err;
  189. if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  190. err = phy_write(phydev, MII_M1011_IMASK,
  191. MII_M1011_IMASK_INIT);
  192. else
  193. err = phy_write(phydev, MII_M1011_IMASK,
  194. MII_M1011_IMASK_CLEAR);
  195. return err;
  196. }
  197. static int marvell_set_polarity(struct phy_device *phydev, int polarity)
  198. {
  199. int reg;
  200. int err;
  201. int val;
  202. /* get the current settings */
  203. reg = phy_read(phydev, MII_M1011_PHY_SCR);
  204. if (reg < 0)
  205. return reg;
  206. val = reg;
  207. val &= ~MII_M1011_PHY_SCR_AUTO_CROSS;
  208. switch (polarity) {
  209. case ETH_TP_MDI:
  210. val |= MII_M1011_PHY_SCR_MDI;
  211. break;
  212. case ETH_TP_MDI_X:
  213. val |= MII_M1011_PHY_SCR_MDI_X;
  214. break;
  215. case ETH_TP_MDI_AUTO:
  216. case ETH_TP_MDI_INVALID:
  217. default:
  218. val |= MII_M1011_PHY_SCR_AUTO_CROSS;
  219. break;
  220. }
  221. if (val != reg) {
  222. /* Set the new polarity value in the register */
  223. err = phy_write(phydev, MII_M1011_PHY_SCR, val);
  224. if (err)
  225. return err;
  226. }
  227. return val != reg;
  228. }
  229. static int marvell_set_downshift(struct phy_device *phydev, bool enable,
  230. u8 retries)
  231. {
  232. int reg;
  233. reg = phy_read(phydev, MII_M1011_PHY_SCR);
  234. if (reg < 0)
  235. return reg;
  236. reg &= MII_M1011_PHY_SRC_DOWNSHIFT_MASK;
  237. reg |= ((retries - 1) << MII_M1011_PHY_SCR_DOWNSHIFT_SHIFT);
  238. if (enable)
  239. reg |= MII_M1011_PHY_SCR_DOWNSHIFT_EN;
  240. return phy_write(phydev, MII_M1011_PHY_SCR, reg);
  241. }
  242. static int marvell_config_aneg(struct phy_device *phydev)
  243. {
  244. int changed = 0;
  245. int err;
  246. err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
  247. if (err < 0)
  248. return err;
  249. changed = err;
  250. err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
  251. MII_M1111_PHY_LED_DIRECT);
  252. if (err < 0)
  253. return err;
  254. err = genphy_config_aneg(phydev);
  255. if (err < 0)
  256. return err;
  257. if (phydev->autoneg != AUTONEG_ENABLE || changed) {
  258. /* A write to speed/duplex bits (that is performed by
  259. * genphy_config_aneg() call above) must be followed by
  260. * a software reset. Otherwise, the write has no effect.
  261. */
  262. err = genphy_soft_reset(phydev);
  263. if (err < 0)
  264. return err;
  265. }
  266. return 0;
  267. }
  268. static int m88e1101_config_aneg(struct phy_device *phydev)
  269. {
  270. int err;
  271. /* This Marvell PHY has an errata which requires
  272. * that certain registers get written in order
  273. * to restart autonegotiation
  274. */
  275. err = genphy_soft_reset(phydev);
  276. if (err < 0)
  277. return err;
  278. err = phy_write(phydev, 0x1d, 0x1f);
  279. if (err < 0)
  280. return err;
  281. err = phy_write(phydev, 0x1e, 0x200c);
  282. if (err < 0)
  283. return err;
  284. err = phy_write(phydev, 0x1d, 0x5);
  285. if (err < 0)
  286. return err;
  287. err = phy_write(phydev, 0x1e, 0);
  288. if (err < 0)
  289. return err;
  290. err = phy_write(phydev, 0x1e, 0x100);
  291. if (err < 0)
  292. return err;
  293. return marvell_config_aneg(phydev);
  294. }
  295. #if IS_ENABLED(CONFIG_OF_MDIO)
  296. /* Set and/or override some configuration registers based on the
  297. * marvell,reg-init property stored in the of_node for the phydev.
  298. *
  299. * marvell,reg-init = <reg-page reg mask value>,...;
  300. *
  301. * There may be one or more sets of <reg-page reg mask value>:
  302. *
  303. * reg-page: which register bank to use.
  304. * reg: the register.
  305. * mask: if non-zero, ANDed with existing register value.
  306. * value: ORed with the masked value and written to the regiser.
  307. *
  308. */
  309. static int marvell_of_reg_init(struct phy_device *phydev)
  310. {
  311. const __be32 *paddr;
  312. int len, i, saved_page, current_page, ret = 0;
  313. if (!phydev->mdio.dev.of_node)
  314. return 0;
  315. paddr = of_get_property(phydev->mdio.dev.of_node,
  316. "marvell,reg-init", &len);
  317. if (!paddr || len < (4 * sizeof(*paddr)))
  318. return 0;
  319. saved_page = phy_save_page(phydev);
  320. if (saved_page < 0)
  321. goto err;
  322. current_page = saved_page;
  323. len /= sizeof(*paddr);
  324. for (i = 0; i < len - 3; i += 4) {
  325. u16 page = be32_to_cpup(paddr + i);
  326. u16 reg = be32_to_cpup(paddr + i + 1);
  327. u16 mask = be32_to_cpup(paddr + i + 2);
  328. u16 val_bits = be32_to_cpup(paddr + i + 3);
  329. int val;
  330. if (page != current_page) {
  331. current_page = page;
  332. ret = marvell_write_page(phydev, page);
  333. if (ret < 0)
  334. goto err;
  335. }
  336. val = 0;
  337. if (mask) {
  338. val = __phy_read(phydev, reg);
  339. if (val < 0) {
  340. ret = val;
  341. goto err;
  342. }
  343. val &= mask;
  344. }
  345. val |= val_bits;
  346. ret = __phy_write(phydev, reg, val);
  347. if (ret < 0)
  348. goto err;
  349. }
  350. err:
  351. return phy_restore_page(phydev, saved_page, ret);
  352. }
  353. #else
  354. static int marvell_of_reg_init(struct phy_device *phydev)
  355. {
  356. return 0;
  357. }
  358. #endif /* CONFIG_OF_MDIO */
  359. static int m88e1121_config_aneg_rgmii_delays(struct phy_device *phydev)
  360. {
  361. int mscr;
  362. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  363. mscr = MII_88E1121_PHY_MSCR_RX_DELAY |
  364. MII_88E1121_PHY_MSCR_TX_DELAY;
  365. else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
  366. mscr = MII_88E1121_PHY_MSCR_RX_DELAY;
  367. else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
  368. mscr = MII_88E1121_PHY_MSCR_TX_DELAY;
  369. else
  370. mscr = 0;
  371. return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
  372. MII_88E1121_PHY_MSCR_REG,
  373. MII_88E1121_PHY_MSCR_DELAY_MASK, mscr);
  374. }
  375. static int m88e1121_config_aneg(struct phy_device *phydev)
  376. {
  377. int changed = 0;
  378. int err = 0;
  379. if (phy_interface_is_rgmii(phydev)) {
  380. err = m88e1121_config_aneg_rgmii_delays(phydev);
  381. if (err < 0)
  382. return err;
  383. }
  384. err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
  385. if (err < 0)
  386. return err;
  387. changed = err;
  388. err = genphy_config_aneg(phydev);
  389. if (err < 0)
  390. return err;
  391. if (phydev->autoneg != AUTONEG_ENABLE || changed) {
  392. /* A software reset is used to ensure a "commit" of the
  393. * changes is done.
  394. */
  395. err = genphy_soft_reset(phydev);
  396. if (err < 0)
  397. return err;
  398. }
  399. return 0;
  400. }
  401. static int m88e1318_config_aneg(struct phy_device *phydev)
  402. {
  403. int err;
  404. err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
  405. MII_88E1318S_PHY_MSCR1_REG,
  406. 0, MII_88E1318S_PHY_MSCR1_PAD_ODD);
  407. if (err < 0)
  408. return err;
  409. return m88e1121_config_aneg(phydev);
  410. }
  411. /**
  412. * linkmode_adv_to_fiber_adv_t
  413. * @advertise: the linkmode advertisement settings
  414. *
  415. * A small helper function that translates linkmode advertisement
  416. * settings to phy autonegotiation advertisements for the MII_ADV
  417. * register for fiber link.
  418. */
  419. static inline u32 linkmode_adv_to_fiber_adv_t(unsigned long *advertise)
  420. {
  421. u32 result = 0;
  422. if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertise))
  423. result |= ADVERTISE_FIBER_1000HALF;
  424. if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertise))
  425. result |= ADVERTISE_FIBER_1000FULL;
  426. if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertise) &&
  427. linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
  428. result |= LPA_PAUSE_ASYM_FIBER;
  429. else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
  430. result |= (ADVERTISE_PAUSE_FIBER
  431. & (~ADVERTISE_PAUSE_ASYM_FIBER));
  432. return result;
  433. }
  434. /**
  435. * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR
  436. * @phydev: target phy_device struct
  437. *
  438. * Description: If auto-negotiation is enabled, we configure the
  439. * advertising, and then restart auto-negotiation. If it is not
  440. * enabled, then we write the BMCR. Adapted for fiber link in
  441. * some Marvell's devices.
  442. */
  443. static int marvell_config_aneg_fiber(struct phy_device *phydev)
  444. {
  445. int changed = 0;
  446. int err;
  447. int adv, oldadv;
  448. if (phydev->autoneg != AUTONEG_ENABLE)
  449. return genphy_setup_forced(phydev);
  450. /* Only allow advertising what this PHY supports */
  451. linkmode_and(phydev->advertising, phydev->advertising,
  452. phydev->supported);
  453. /* Setup fiber advertisement */
  454. adv = phy_read(phydev, MII_ADVERTISE);
  455. if (adv < 0)
  456. return adv;
  457. oldadv = adv;
  458. adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL
  459. | LPA_PAUSE_FIBER);
  460. adv |= linkmode_adv_to_fiber_adv_t(phydev->advertising);
  461. if (adv != oldadv) {
  462. err = phy_write(phydev, MII_ADVERTISE, adv);
  463. if (err < 0)
  464. return err;
  465. changed = 1;
  466. }
  467. if (changed == 0) {
  468. /* Advertisement hasn't changed, but maybe aneg was never on to
  469. * begin with? Or maybe phy was isolated?
  470. */
  471. int ctl = phy_read(phydev, MII_BMCR);
  472. if (ctl < 0)
  473. return ctl;
  474. if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
  475. changed = 1; /* do restart aneg */
  476. }
  477. /* Only restart aneg if we are advertising something different
  478. * than we were before.
  479. */
  480. if (changed > 0)
  481. changed = genphy_restart_aneg(phydev);
  482. return changed;
  483. }
  484. static int m88e1510_config_aneg(struct phy_device *phydev)
  485. {
  486. int err;
  487. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  488. if (err < 0)
  489. goto error;
  490. /* Configure the copper link first */
  491. err = m88e1318_config_aneg(phydev);
  492. if (err < 0)
  493. goto error;
  494. /* Do not touch the fiber page if we're in copper->sgmii mode */
  495. if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
  496. return 0;
  497. /* Then the fiber link */
  498. err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
  499. if (err < 0)
  500. goto error;
  501. err = marvell_config_aneg_fiber(phydev);
  502. if (err < 0)
  503. goto error;
  504. return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  505. error:
  506. marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  507. return err;
  508. }
  509. static void marvell_config_led(struct phy_device *phydev)
  510. {
  511. u16 def_config;
  512. int err;
  513. switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
  514. /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
  515. case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
  516. case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
  517. def_config = MII_88E1121_PHY_LED_DEF;
  518. break;
  519. /* Default PHY LED config:
  520. * LED[0] .. 1000Mbps Link
  521. * LED[1] .. 100Mbps Link
  522. * LED[2] .. Blink, Activity
  523. */
  524. case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
  525. if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
  526. def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
  527. else
  528. def_config = MII_88E1510_PHY_LED_DEF;
  529. break;
  530. default:
  531. return;
  532. }
  533. err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, MII_PHY_LED_CTRL,
  534. def_config);
  535. if (err < 0)
  536. phydev_warn(phydev, "Fail to config marvell phy LED.\n");
  537. }
  538. static int marvell_config_init(struct phy_device *phydev)
  539. {
  540. /* Set defalut LED */
  541. marvell_config_led(phydev);
  542. /* Set registers from marvell,reg-init DT property */
  543. return marvell_of_reg_init(phydev);
  544. }
  545. static int m88e1116r_config_init(struct phy_device *phydev)
  546. {
  547. int err;
  548. err = genphy_soft_reset(phydev);
  549. if (err < 0)
  550. return err;
  551. msleep(500);
  552. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  553. if (err < 0)
  554. return err;
  555. err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
  556. if (err < 0)
  557. return err;
  558. err = marvell_set_downshift(phydev, true, 8);
  559. if (err < 0)
  560. return err;
  561. if (phy_interface_is_rgmii(phydev)) {
  562. err = m88e1121_config_aneg_rgmii_delays(phydev);
  563. if (err < 0)
  564. return err;
  565. }
  566. err = genphy_soft_reset(phydev);
  567. if (err < 0)
  568. return err;
  569. return marvell_config_init(phydev);
  570. }
  571. static int m88e3016_config_init(struct phy_device *phydev)
  572. {
  573. int ret;
  574. /* Enable Scrambler and Auto-Crossover */
  575. ret = phy_modify(phydev, MII_88E3016_PHY_SPEC_CTRL,
  576. MII_88E3016_DISABLE_SCRAMBLER,
  577. MII_88E3016_AUTO_MDIX_CROSSOVER);
  578. if (ret < 0)
  579. return ret;
  580. return marvell_config_init(phydev);
  581. }
  582. static int m88e1111_config_init_hwcfg_mode(struct phy_device *phydev,
  583. u16 mode,
  584. int fibre_copper_auto)
  585. {
  586. if (fibre_copper_auto)
  587. mode |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
  588. return phy_modify(phydev, MII_M1111_PHY_EXT_SR,
  589. MII_M1111_HWCFG_MODE_MASK |
  590. MII_M1111_HWCFG_FIBER_COPPER_AUTO |
  591. MII_M1111_HWCFG_FIBER_COPPER_RES,
  592. mode);
  593. }
  594. static int m88e1111_config_init_rgmii_delays(struct phy_device *phydev)
  595. {
  596. int delay;
  597. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
  598. delay = MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY;
  599. } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
  600. delay = MII_M1111_RGMII_RX_DELAY;
  601. } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
  602. delay = MII_M1111_RGMII_TX_DELAY;
  603. } else {
  604. delay = 0;
  605. }
  606. return phy_modify(phydev, MII_M1111_PHY_EXT_CR,
  607. MII_M1111_RGMII_RX_DELAY | MII_M1111_RGMII_TX_DELAY,
  608. delay);
  609. }
  610. static int m88e1111_config_init_rgmii(struct phy_device *phydev)
  611. {
  612. int temp;
  613. int err;
  614. err = m88e1111_config_init_rgmii_delays(phydev);
  615. if (err < 0)
  616. return err;
  617. temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
  618. if (temp < 0)
  619. return temp;
  620. temp &= ~(MII_M1111_HWCFG_MODE_MASK);
  621. if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
  622. temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
  623. else
  624. temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
  625. return phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
  626. }
  627. static int m88e1111_config_init_sgmii(struct phy_device *phydev)
  628. {
  629. int err;
  630. err = m88e1111_config_init_hwcfg_mode(
  631. phydev,
  632. MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
  633. MII_M1111_HWCFG_FIBER_COPPER_AUTO);
  634. if (err < 0)
  635. return err;
  636. /* make sure copper is selected */
  637. return marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  638. }
  639. static int m88e1111_config_init_rtbi(struct phy_device *phydev)
  640. {
  641. int err;
  642. err = m88e1111_config_init_rgmii_delays(phydev);
  643. if (err < 0)
  644. return err;
  645. err = m88e1111_config_init_hwcfg_mode(
  646. phydev,
  647. MII_M1111_HWCFG_MODE_RTBI,
  648. MII_M1111_HWCFG_FIBER_COPPER_AUTO);
  649. if (err < 0)
  650. return err;
  651. /* soft reset */
  652. err = genphy_soft_reset(phydev);
  653. if (err < 0)
  654. return err;
  655. return m88e1111_config_init_hwcfg_mode(
  656. phydev,
  657. MII_M1111_HWCFG_MODE_RTBI,
  658. MII_M1111_HWCFG_FIBER_COPPER_AUTO);
  659. }
  660. static int m88e1111_config_init(struct phy_device *phydev)
  661. {
  662. int err;
  663. if (phy_interface_is_rgmii(phydev)) {
  664. err = m88e1111_config_init_rgmii(phydev);
  665. if (err < 0)
  666. return err;
  667. }
  668. if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
  669. err = m88e1111_config_init_sgmii(phydev);
  670. if (err < 0)
  671. return err;
  672. }
  673. if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
  674. err = m88e1111_config_init_rtbi(phydev);
  675. if (err < 0)
  676. return err;
  677. }
  678. err = marvell_of_reg_init(phydev);
  679. if (err < 0)
  680. return err;
  681. return genphy_soft_reset(phydev);
  682. }
  683. static int m88e1318_config_init(struct phy_device *phydev)
  684. {
  685. if (phy_interrupt_is_valid(phydev)) {
  686. int err = phy_modify_paged(
  687. phydev, MII_MARVELL_LED_PAGE,
  688. MII_88E1318S_PHY_LED_TCR,
  689. MII_88E1318S_PHY_LED_TCR_FORCE_INT,
  690. MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
  691. MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
  692. if (err < 0)
  693. return err;
  694. }
  695. return marvell_config_init(phydev);
  696. }
  697. static int m88e1510_config_init(struct phy_device *phydev)
  698. {
  699. int err;
  700. /* SGMII-to-Copper mode initialization */
  701. if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
  702. /* Select page 18 */
  703. err = marvell_set_page(phydev, 18);
  704. if (err < 0)
  705. return err;
  706. /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
  707. err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
  708. MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
  709. MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII);
  710. if (err < 0)
  711. return err;
  712. /* PHY reset is necessary after changing MODE[2:0] */
  713. err = phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1, 0,
  714. MII_88E1510_GEN_CTRL_REG_1_RESET);
  715. if (err < 0)
  716. return err;
  717. /* Reset page selection */
  718. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  719. if (err < 0)
  720. return err;
  721. }
  722. return m88e1318_config_init(phydev);
  723. }
  724. static int m88e1118_config_aneg(struct phy_device *phydev)
  725. {
  726. int err;
  727. err = genphy_soft_reset(phydev);
  728. if (err < 0)
  729. return err;
  730. err = marvell_set_polarity(phydev, phydev->mdix_ctrl);
  731. if (err < 0)
  732. return err;
  733. err = genphy_config_aneg(phydev);
  734. return 0;
  735. }
  736. static int m88e1118_config_init(struct phy_device *phydev)
  737. {
  738. int err;
  739. /* Change address */
  740. err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
  741. if (err < 0)
  742. return err;
  743. /* Enable 1000 Mbit */
  744. err = phy_write(phydev, 0x15, 0x1070);
  745. if (err < 0)
  746. return err;
  747. /* Change address */
  748. err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE);
  749. if (err < 0)
  750. return err;
  751. /* Adjust LED Control */
  752. if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS)
  753. err = phy_write(phydev, 0x10, 0x1100);
  754. else
  755. err = phy_write(phydev, 0x10, 0x021e);
  756. if (err < 0)
  757. return err;
  758. err = marvell_of_reg_init(phydev);
  759. if (err < 0)
  760. return err;
  761. /* Reset address */
  762. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  763. if (err < 0)
  764. return err;
  765. return genphy_soft_reset(phydev);
  766. }
  767. static int m88e1149_config_init(struct phy_device *phydev)
  768. {
  769. int err;
  770. /* Change address */
  771. err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
  772. if (err < 0)
  773. return err;
  774. /* Enable 1000 Mbit */
  775. err = phy_write(phydev, 0x15, 0x1048);
  776. if (err < 0)
  777. return err;
  778. err = marvell_of_reg_init(phydev);
  779. if (err < 0)
  780. return err;
  781. /* Reset address */
  782. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  783. if (err < 0)
  784. return err;
  785. return genphy_soft_reset(phydev);
  786. }
  787. static int m88e1145_config_init_rgmii(struct phy_device *phydev)
  788. {
  789. int err;
  790. err = m88e1111_config_init_rgmii_delays(phydev);
  791. if (err < 0)
  792. return err;
  793. if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
  794. err = phy_write(phydev, 0x1d, 0x0012);
  795. if (err < 0)
  796. return err;
  797. err = phy_modify(phydev, 0x1e, 0x0fc0,
  798. 2 << 9 | /* 36 ohm */
  799. 2 << 6); /* 39 ohm */
  800. if (err < 0)
  801. return err;
  802. err = phy_write(phydev, 0x1d, 0x3);
  803. if (err < 0)
  804. return err;
  805. err = phy_write(phydev, 0x1e, 0x8000);
  806. }
  807. return err;
  808. }
  809. static int m88e1145_config_init_sgmii(struct phy_device *phydev)
  810. {
  811. return m88e1111_config_init_hwcfg_mode(
  812. phydev, MII_M1111_HWCFG_MODE_SGMII_NO_CLK,
  813. MII_M1111_HWCFG_FIBER_COPPER_AUTO);
  814. }
  815. static int m88e1145_config_init(struct phy_device *phydev)
  816. {
  817. int err;
  818. /* Take care of errata E0 & E1 */
  819. err = phy_write(phydev, 0x1d, 0x001b);
  820. if (err < 0)
  821. return err;
  822. err = phy_write(phydev, 0x1e, 0x418f);
  823. if (err < 0)
  824. return err;
  825. err = phy_write(phydev, 0x1d, 0x0016);
  826. if (err < 0)
  827. return err;
  828. err = phy_write(phydev, 0x1e, 0xa2da);
  829. if (err < 0)
  830. return err;
  831. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
  832. err = m88e1145_config_init_rgmii(phydev);
  833. if (err < 0)
  834. return err;
  835. }
  836. if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
  837. err = m88e1145_config_init_sgmii(phydev);
  838. if (err < 0)
  839. return err;
  840. }
  841. err = marvell_of_reg_init(phydev);
  842. if (err < 0)
  843. return err;
  844. return 0;
  845. }
  846. static int m88e1540_get_fld(struct phy_device *phydev, u8 *msecs)
  847. {
  848. int val;
  849. val = phy_read(phydev, MII_88E1540_COPPER_CTRL3);
  850. if (val < 0)
  851. return val;
  852. if (!(val & MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN)) {
  853. *msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF;
  854. return 0;
  855. }
  856. val = FIELD_GET(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
  857. switch (val) {
  858. case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS:
  859. *msecs = 0;
  860. break;
  861. case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS:
  862. *msecs = 10;
  863. break;
  864. case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS:
  865. *msecs = 20;
  866. break;
  867. case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS:
  868. *msecs = 40;
  869. break;
  870. default:
  871. return -EINVAL;
  872. }
  873. return 0;
  874. }
  875. static int m88e1540_set_fld(struct phy_device *phydev, const u8 *msecs)
  876. {
  877. struct ethtool_eee eee;
  878. int val, ret;
  879. if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF)
  880. return phy_clear_bits(phydev, MII_88E1540_COPPER_CTRL3,
  881. MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
  882. /* According to the Marvell data sheet EEE must be disabled for
  883. * Fast Link Down detection to work properly
  884. */
  885. ret = phy_ethtool_get_eee(phydev, &eee);
  886. if (!ret && eee.eee_enabled) {
  887. phydev_warn(phydev, "Fast Link Down detection requires EEE to be disabled!\n");
  888. return -EBUSY;
  889. }
  890. if (*msecs <= 5)
  891. val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS;
  892. else if (*msecs <= 15)
  893. val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS;
  894. else if (*msecs <= 30)
  895. val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS;
  896. else
  897. val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS;
  898. val = FIELD_PREP(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
  899. ret = phy_modify(phydev, MII_88E1540_COPPER_CTRL3,
  900. MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
  901. if (ret)
  902. return ret;
  903. return phy_set_bits(phydev, MII_88E1540_COPPER_CTRL3,
  904. MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
  905. }
  906. static int m88e1540_get_tunable(struct phy_device *phydev,
  907. struct ethtool_tunable *tuna, void *data)
  908. {
  909. switch (tuna->id) {
  910. case ETHTOOL_PHY_FAST_LINK_DOWN:
  911. return m88e1540_get_fld(phydev, data);
  912. default:
  913. return -EOPNOTSUPP;
  914. }
  915. }
  916. static int m88e1540_set_tunable(struct phy_device *phydev,
  917. struct ethtool_tunable *tuna, const void *data)
  918. {
  919. switch (tuna->id) {
  920. case ETHTOOL_PHY_FAST_LINK_DOWN:
  921. return m88e1540_set_fld(phydev, data);
  922. default:
  923. return -EOPNOTSUPP;
  924. }
  925. }
  926. /* The VOD can be out of specification on link up. Poke an
  927. * undocumented register, in an undocumented page, with a magic value
  928. * to fix this.
  929. */
  930. static int m88e6390_errata(struct phy_device *phydev)
  931. {
  932. int err;
  933. err = phy_write(phydev, MII_BMCR,
  934. BMCR_ANENABLE | BMCR_SPEED1000 | BMCR_FULLDPLX);
  935. if (err)
  936. return err;
  937. usleep_range(300, 400);
  938. err = phy_write_paged(phydev, 0xf8, 0x08, 0x36);
  939. if (err)
  940. return err;
  941. return genphy_soft_reset(phydev);
  942. }
  943. static int m88e6390_config_aneg(struct phy_device *phydev)
  944. {
  945. int err;
  946. err = m88e6390_errata(phydev);
  947. if (err)
  948. return err;
  949. return m88e1510_config_aneg(phydev);
  950. }
  951. /**
  952. * fiber_lpa_mod_linkmode_lpa_t
  953. * @advertising: the linkmode advertisement settings
  954. * @lpa: value of the MII_LPA register for fiber link
  955. *
  956. * A small helper function that translates MII_LPA bits to linkmode LP
  957. * advertisement settings. Other bits in advertising are left
  958. * unchanged.
  959. */
  960. static void fiber_lpa_mod_linkmode_lpa_t(unsigned long *advertising, u32 lpa)
  961. {
  962. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
  963. advertising, lpa & LPA_FIBER_1000HALF);
  964. linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
  965. advertising, lpa & LPA_FIBER_1000FULL);
  966. }
  967. /**
  968. * marvell_update_link - update link status in real time in @phydev
  969. * @phydev: target phy_device struct
  970. *
  971. * Description: Update the value in phydev->link to reflect the
  972. * current link value.
  973. */
  974. static int marvell_update_link(struct phy_device *phydev, int fiber)
  975. {
  976. int status;
  977. /* Use the generic register for copper link, or specific
  978. * register for fiber case
  979. */
  980. if (fiber) {
  981. status = phy_read(phydev, MII_M1011_PHY_STATUS);
  982. if (status < 0)
  983. return status;
  984. if ((status & REGISTER_LINK_STATUS) == 0)
  985. phydev->link = 0;
  986. else
  987. phydev->link = 1;
  988. } else {
  989. return genphy_update_link(phydev);
  990. }
  991. return 0;
  992. }
  993. static int marvell_read_status_page_an(struct phy_device *phydev,
  994. int fiber)
  995. {
  996. int status;
  997. int lpa;
  998. int lpagb;
  999. status = phy_read(phydev, MII_M1011_PHY_STATUS);
  1000. if (status < 0)
  1001. return status;
  1002. lpa = phy_read(phydev, MII_LPA);
  1003. if (lpa < 0)
  1004. return lpa;
  1005. lpagb = phy_read(phydev, MII_STAT1000);
  1006. if (lpagb < 0)
  1007. return lpagb;
  1008. if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
  1009. phydev->duplex = DUPLEX_FULL;
  1010. else
  1011. phydev->duplex = DUPLEX_HALF;
  1012. status = status & MII_M1011_PHY_STATUS_SPD_MASK;
  1013. phydev->pause = 0;
  1014. phydev->asym_pause = 0;
  1015. switch (status) {
  1016. case MII_M1011_PHY_STATUS_1000:
  1017. phydev->speed = SPEED_1000;
  1018. break;
  1019. case MII_M1011_PHY_STATUS_100:
  1020. phydev->speed = SPEED_100;
  1021. break;
  1022. default:
  1023. phydev->speed = SPEED_10;
  1024. break;
  1025. }
  1026. if (!fiber) {
  1027. mii_lpa_to_linkmode_lpa_t(phydev->lp_advertising, lpa);
  1028. mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, lpagb);
  1029. if (phydev->duplex == DUPLEX_FULL) {
  1030. phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
  1031. phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
  1032. }
  1033. } else {
  1034. /* The fiber link is only 1000M capable */
  1035. fiber_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
  1036. if (phydev->duplex == DUPLEX_FULL) {
  1037. if (!(lpa & LPA_PAUSE_FIBER)) {
  1038. phydev->pause = 0;
  1039. phydev->asym_pause = 0;
  1040. } else if ((lpa & LPA_PAUSE_ASYM_FIBER)) {
  1041. phydev->pause = 1;
  1042. phydev->asym_pause = 1;
  1043. } else {
  1044. phydev->pause = 1;
  1045. phydev->asym_pause = 0;
  1046. }
  1047. }
  1048. }
  1049. return 0;
  1050. }
  1051. static int marvell_read_status_page_fixed(struct phy_device *phydev)
  1052. {
  1053. int bmcr = phy_read(phydev, MII_BMCR);
  1054. if (bmcr < 0)
  1055. return bmcr;
  1056. if (bmcr & BMCR_FULLDPLX)
  1057. phydev->duplex = DUPLEX_FULL;
  1058. else
  1059. phydev->duplex = DUPLEX_HALF;
  1060. if (bmcr & BMCR_SPEED1000)
  1061. phydev->speed = SPEED_1000;
  1062. else if (bmcr & BMCR_SPEED100)
  1063. phydev->speed = SPEED_100;
  1064. else
  1065. phydev->speed = SPEED_10;
  1066. phydev->pause = 0;
  1067. phydev->asym_pause = 0;
  1068. linkmode_zero(phydev->lp_advertising);
  1069. return 0;
  1070. }
  1071. /* marvell_read_status_page
  1072. *
  1073. * Description:
  1074. * Check the link, then figure out the current state
  1075. * by comparing what we advertise with what the link partner
  1076. * advertises. Start by checking the gigabit possibilities,
  1077. * then move on to 10/100.
  1078. */
  1079. static int marvell_read_status_page(struct phy_device *phydev, int page)
  1080. {
  1081. int fiber;
  1082. int err;
  1083. /* Detect and update the link, but return if there
  1084. * was an error
  1085. */
  1086. if (page == MII_MARVELL_FIBER_PAGE)
  1087. fiber = 1;
  1088. else
  1089. fiber = 0;
  1090. err = marvell_update_link(phydev, fiber);
  1091. if (err)
  1092. return err;
  1093. if (phydev->autoneg == AUTONEG_ENABLE)
  1094. err = marvell_read_status_page_an(phydev, fiber);
  1095. else
  1096. err = marvell_read_status_page_fixed(phydev);
  1097. return err;
  1098. }
  1099. /* marvell_read_status
  1100. *
  1101. * Some Marvell's phys have two modes: fiber and copper.
  1102. * Both need status checked.
  1103. * Description:
  1104. * First, check the fiber link and status.
  1105. * If the fiber link is down, check the copper link and status which
  1106. * will be the default value if both link are down.
  1107. */
  1108. static int marvell_read_status(struct phy_device *phydev)
  1109. {
  1110. int err;
  1111. /* Check the fiber mode first */
  1112. if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
  1113. phydev->supported) &&
  1114. phydev->interface != PHY_INTERFACE_MODE_SGMII) {
  1115. err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
  1116. if (err < 0)
  1117. goto error;
  1118. err = marvell_read_status_page(phydev, MII_MARVELL_FIBER_PAGE);
  1119. if (err < 0)
  1120. goto error;
  1121. /* If the fiber link is up, it is the selected and
  1122. * used link. In this case, we need to stay in the
  1123. * fiber page. Please to be careful about that, avoid
  1124. * to restore Copper page in other functions which
  1125. * could break the behaviour for some fiber phy like
  1126. * 88E1512.
  1127. */
  1128. if (phydev->link)
  1129. return 0;
  1130. /* If fiber link is down, check and save copper mode state */
  1131. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  1132. if (err < 0)
  1133. goto error;
  1134. }
  1135. return marvell_read_status_page(phydev, MII_MARVELL_COPPER_PAGE);
  1136. error:
  1137. marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  1138. return err;
  1139. }
  1140. /* marvell_suspend
  1141. *
  1142. * Some Marvell's phys have two modes: fiber and copper.
  1143. * Both need to be suspended
  1144. */
  1145. static int marvell_suspend(struct phy_device *phydev)
  1146. {
  1147. int err;
  1148. /* Suspend the fiber mode first */
  1149. if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
  1150. phydev->supported)) {
  1151. err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
  1152. if (err < 0)
  1153. goto error;
  1154. /* With the page set, use the generic suspend */
  1155. err = genphy_suspend(phydev);
  1156. if (err < 0)
  1157. goto error;
  1158. /* Then, the copper link */
  1159. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  1160. if (err < 0)
  1161. goto error;
  1162. }
  1163. /* With the page set, use the generic suspend */
  1164. return genphy_suspend(phydev);
  1165. error:
  1166. marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  1167. return err;
  1168. }
  1169. /* marvell_resume
  1170. *
  1171. * Some Marvell's phys have two modes: fiber and copper.
  1172. * Both need to be resumed
  1173. */
  1174. static int marvell_resume(struct phy_device *phydev)
  1175. {
  1176. int err;
  1177. /* Resume the fiber mode first */
  1178. if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
  1179. phydev->supported)) {
  1180. err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
  1181. if (err < 0)
  1182. goto error;
  1183. /* With the page set, use the generic resume */
  1184. err = genphy_resume(phydev);
  1185. if (err < 0)
  1186. goto error;
  1187. /* Then, the copper link */
  1188. err = marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  1189. if (err < 0)
  1190. goto error;
  1191. }
  1192. /* With the page set, use the generic resume */
  1193. return genphy_resume(phydev);
  1194. error:
  1195. marvell_set_page(phydev, MII_MARVELL_COPPER_PAGE);
  1196. return err;
  1197. }
  1198. static int marvell_aneg_done(struct phy_device *phydev)
  1199. {
  1200. int retval = phy_read(phydev, MII_M1011_PHY_STATUS);
  1201. return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED);
  1202. }
  1203. static int m88e1121_did_interrupt(struct phy_device *phydev)
  1204. {
  1205. int imask;
  1206. imask = phy_read(phydev, MII_M1011_IEVENT);
  1207. if (imask & MII_M1011_IMASK_INIT)
  1208. return 1;
  1209. return 0;
  1210. }
  1211. static void m88e1318_get_wol(struct phy_device *phydev,
  1212. struct ethtool_wolinfo *wol)
  1213. {
  1214. int oldpage, ret = 0;
  1215. wol->supported = WAKE_MAGIC;
  1216. wol->wolopts = 0;
  1217. oldpage = phy_select_page(phydev, MII_MARVELL_WOL_PAGE);
  1218. if (oldpage < 0)
  1219. goto error;
  1220. ret = __phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL);
  1221. if (ret & MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
  1222. wol->wolopts |= WAKE_MAGIC;
  1223. error:
  1224. phy_restore_page(phydev, oldpage, ret);
  1225. }
  1226. static int m88e1318_set_wol(struct phy_device *phydev,
  1227. struct ethtool_wolinfo *wol)
  1228. {
  1229. int err = 0, oldpage;
  1230. oldpage = phy_save_page(phydev);
  1231. if (oldpage < 0)
  1232. goto error;
  1233. if (wol->wolopts & WAKE_MAGIC) {
  1234. /* Explicitly switch to page 0x00, just to be sure */
  1235. err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
  1236. if (err < 0)
  1237. goto error;
  1238. /* If WOL event happened once, the LED[2] interrupt pin
  1239. * will not be cleared unless we reading the interrupt status
  1240. * register. If interrupts are in use, the normal interrupt
  1241. * handling will clear the WOL event. Clear the WOL event
  1242. * before enabling it if !phy_interrupt_is_valid()
  1243. */
  1244. if (!phy_interrupt_is_valid(phydev))
  1245. __phy_read(phydev, MII_M1011_IEVENT);
  1246. /* Enable the WOL interrupt */
  1247. err = __phy_modify(phydev, MII_88E1318S_PHY_CSIER, 0,
  1248. MII_88E1318S_PHY_CSIER_WOL_EIE);
  1249. if (err < 0)
  1250. goto error;
  1251. err = marvell_write_page(phydev, MII_MARVELL_LED_PAGE);
  1252. if (err < 0)
  1253. goto error;
  1254. /* Setup LED[2] as interrupt pin (active low) */
  1255. err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR,
  1256. MII_88E1318S_PHY_LED_TCR_FORCE_INT,
  1257. MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
  1258. MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
  1259. if (err < 0)
  1260. goto error;
  1261. err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
  1262. if (err < 0)
  1263. goto error;
  1264. /* Store the device address for the magic packet */
  1265. err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2,
  1266. ((phydev->attached_dev->dev_addr[5] << 8) |
  1267. phydev->attached_dev->dev_addr[4]));
  1268. if (err < 0)
  1269. goto error;
  1270. err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1,
  1271. ((phydev->attached_dev->dev_addr[3] << 8) |
  1272. phydev->attached_dev->dev_addr[2]));
  1273. if (err < 0)
  1274. goto error;
  1275. err = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0,
  1276. ((phydev->attached_dev->dev_addr[1] << 8) |
  1277. phydev->attached_dev->dev_addr[0]));
  1278. if (err < 0)
  1279. goto error;
  1280. /* Clear WOL status and enable magic packet matching */
  1281. err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0,
  1282. MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |
  1283. MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE);
  1284. if (err < 0)
  1285. goto error;
  1286. } else {
  1287. err = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);
  1288. if (err < 0)
  1289. goto error;
  1290. /* Clear WOL status and disable magic packet matching */
  1291. err = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,
  1292. MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE,
  1293. MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
  1294. if (err < 0)
  1295. goto error;
  1296. }
  1297. error:
  1298. return phy_restore_page(phydev, oldpage, err);
  1299. }
  1300. static int marvell_get_sset_count(struct phy_device *phydev)
  1301. {
  1302. if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
  1303. phydev->supported))
  1304. return ARRAY_SIZE(marvell_hw_stats);
  1305. else
  1306. return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS;
  1307. }
  1308. static void marvell_get_strings(struct phy_device *phydev, u8 *data)
  1309. {
  1310. int count = marvell_get_sset_count(phydev);
  1311. int i;
  1312. for (i = 0; i < count; i++) {
  1313. strlcpy(data + i * ETH_GSTRING_LEN,
  1314. marvell_hw_stats[i].string, ETH_GSTRING_LEN);
  1315. }
  1316. }
  1317. static u64 marvell_get_stat(struct phy_device *phydev, int i)
  1318. {
  1319. struct marvell_hw_stat stat = marvell_hw_stats[i];
  1320. struct marvell_priv *priv = phydev->priv;
  1321. int val;
  1322. u64 ret;
  1323. val = phy_read_paged(phydev, stat.page, stat.reg);
  1324. if (val < 0) {
  1325. ret = U64_MAX;
  1326. } else {
  1327. val = val & ((1 << stat.bits) - 1);
  1328. priv->stats[i] += val;
  1329. ret = priv->stats[i];
  1330. }
  1331. return ret;
  1332. }
  1333. static void marvell_get_stats(struct phy_device *phydev,
  1334. struct ethtool_stats *stats, u64 *data)
  1335. {
  1336. int count = marvell_get_sset_count(phydev);
  1337. int i;
  1338. for (i = 0; i < count; i++)
  1339. data[i] = marvell_get_stat(phydev, i);
  1340. }
  1341. #ifdef CONFIG_HWMON
  1342. static int m88e1121_get_temp(struct phy_device *phydev, long *temp)
  1343. {
  1344. int oldpage;
  1345. int ret = 0;
  1346. int val;
  1347. *temp = 0;
  1348. oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
  1349. if (oldpage < 0)
  1350. goto error;
  1351. /* Enable temperature sensor */
  1352. ret = __phy_read(phydev, MII_88E1121_MISC_TEST);
  1353. if (ret < 0)
  1354. goto error;
  1355. ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
  1356. ret | MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
  1357. if (ret < 0)
  1358. goto error;
  1359. /* Wait for temperature to stabilize */
  1360. usleep_range(10000, 12000);
  1361. val = __phy_read(phydev, MII_88E1121_MISC_TEST);
  1362. if (val < 0) {
  1363. ret = val;
  1364. goto error;
  1365. }
  1366. /* Disable temperature sensor */
  1367. ret = __phy_write(phydev, MII_88E1121_MISC_TEST,
  1368. ret & ~MII_88E1121_MISC_TEST_TEMP_SENSOR_EN);
  1369. if (ret < 0)
  1370. goto error;
  1371. *temp = ((val & MII_88E1121_MISC_TEST_TEMP_MASK) - 5) * 5000;
  1372. error:
  1373. return phy_restore_page(phydev, oldpage, ret);
  1374. }
  1375. static int m88e1121_hwmon_read(struct device *dev,
  1376. enum hwmon_sensor_types type,
  1377. u32 attr, int channel, long *temp)
  1378. {
  1379. struct phy_device *phydev = dev_get_drvdata(dev);
  1380. int err;
  1381. switch (attr) {
  1382. case hwmon_temp_input:
  1383. err = m88e1121_get_temp(phydev, temp);
  1384. break;
  1385. default:
  1386. return -EOPNOTSUPP;
  1387. }
  1388. return err;
  1389. }
  1390. static umode_t m88e1121_hwmon_is_visible(const void *data,
  1391. enum hwmon_sensor_types type,
  1392. u32 attr, int channel)
  1393. {
  1394. if (type != hwmon_temp)
  1395. return 0;
  1396. switch (attr) {
  1397. case hwmon_temp_input:
  1398. return 0444;
  1399. default:
  1400. return 0;
  1401. }
  1402. }
  1403. static u32 m88e1121_hwmon_chip_config[] = {
  1404. HWMON_C_REGISTER_TZ,
  1405. 0
  1406. };
  1407. static const struct hwmon_channel_info m88e1121_hwmon_chip = {
  1408. .type = hwmon_chip,
  1409. .config = m88e1121_hwmon_chip_config,
  1410. };
  1411. static u32 m88e1121_hwmon_temp_config[] = {
  1412. HWMON_T_INPUT,
  1413. 0
  1414. };
  1415. static const struct hwmon_channel_info m88e1121_hwmon_temp = {
  1416. .type = hwmon_temp,
  1417. .config = m88e1121_hwmon_temp_config,
  1418. };
  1419. static const struct hwmon_channel_info *m88e1121_hwmon_info[] = {
  1420. &m88e1121_hwmon_chip,
  1421. &m88e1121_hwmon_temp,
  1422. NULL
  1423. };
  1424. static const struct hwmon_ops m88e1121_hwmon_hwmon_ops = {
  1425. .is_visible = m88e1121_hwmon_is_visible,
  1426. .read = m88e1121_hwmon_read,
  1427. };
  1428. static const struct hwmon_chip_info m88e1121_hwmon_chip_info = {
  1429. .ops = &m88e1121_hwmon_hwmon_ops,
  1430. .info = m88e1121_hwmon_info,
  1431. };
  1432. static int m88e1510_get_temp(struct phy_device *phydev, long *temp)
  1433. {
  1434. int ret;
  1435. *temp = 0;
  1436. ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
  1437. MII_88E1510_TEMP_SENSOR);
  1438. if (ret < 0)
  1439. return ret;
  1440. *temp = ((ret & MII_88E1510_TEMP_SENSOR_MASK) - 25) * 1000;
  1441. return 0;
  1442. }
  1443. static int m88e1510_get_temp_critical(struct phy_device *phydev, long *temp)
  1444. {
  1445. int ret;
  1446. *temp = 0;
  1447. ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
  1448. MII_88E1121_MISC_TEST);
  1449. if (ret < 0)
  1450. return ret;
  1451. *temp = (((ret & MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK) >>
  1452. MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT) * 5) - 25;
  1453. /* convert to mC */
  1454. *temp *= 1000;
  1455. return 0;
  1456. }
  1457. static int m88e1510_set_temp_critical(struct phy_device *phydev, long temp)
  1458. {
  1459. temp = temp / 1000;
  1460. temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
  1461. return phy_modify_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
  1462. MII_88E1121_MISC_TEST,
  1463. MII_88E1510_MISC_TEST_TEMP_THRESHOLD_MASK,
  1464. temp << MII_88E1510_MISC_TEST_TEMP_THRESHOLD_SHIFT);
  1465. }
  1466. static int m88e1510_get_temp_alarm(struct phy_device *phydev, long *alarm)
  1467. {
  1468. int ret;
  1469. *alarm = false;
  1470. ret = phy_read_paged(phydev, MII_MARVELL_MISC_TEST_PAGE,
  1471. MII_88E1121_MISC_TEST);
  1472. if (ret < 0)
  1473. return ret;
  1474. *alarm = !!(ret & MII_88E1510_MISC_TEST_TEMP_IRQ);
  1475. return 0;
  1476. }
  1477. static int m88e1510_hwmon_read(struct device *dev,
  1478. enum hwmon_sensor_types type,
  1479. u32 attr, int channel, long *temp)
  1480. {
  1481. struct phy_device *phydev = dev_get_drvdata(dev);
  1482. int err;
  1483. switch (attr) {
  1484. case hwmon_temp_input:
  1485. err = m88e1510_get_temp(phydev, temp);
  1486. break;
  1487. case hwmon_temp_crit:
  1488. err = m88e1510_get_temp_critical(phydev, temp);
  1489. break;
  1490. case hwmon_temp_max_alarm:
  1491. err = m88e1510_get_temp_alarm(phydev, temp);
  1492. break;
  1493. default:
  1494. return -EOPNOTSUPP;
  1495. }
  1496. return err;
  1497. }
  1498. static int m88e1510_hwmon_write(struct device *dev,
  1499. enum hwmon_sensor_types type,
  1500. u32 attr, int channel, long temp)
  1501. {
  1502. struct phy_device *phydev = dev_get_drvdata(dev);
  1503. int err;
  1504. switch (attr) {
  1505. case hwmon_temp_crit:
  1506. err = m88e1510_set_temp_critical(phydev, temp);
  1507. break;
  1508. default:
  1509. return -EOPNOTSUPP;
  1510. }
  1511. return err;
  1512. }
  1513. static umode_t m88e1510_hwmon_is_visible(const void *data,
  1514. enum hwmon_sensor_types type,
  1515. u32 attr, int channel)
  1516. {
  1517. if (type != hwmon_temp)
  1518. return 0;
  1519. switch (attr) {
  1520. case hwmon_temp_input:
  1521. case hwmon_temp_max_alarm:
  1522. return 0444;
  1523. case hwmon_temp_crit:
  1524. return 0644;
  1525. default:
  1526. return 0;
  1527. }
  1528. }
  1529. static u32 m88e1510_hwmon_temp_config[] = {
  1530. HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM,
  1531. 0
  1532. };
  1533. static const struct hwmon_channel_info m88e1510_hwmon_temp = {
  1534. .type = hwmon_temp,
  1535. .config = m88e1510_hwmon_temp_config,
  1536. };
  1537. static const struct hwmon_channel_info *m88e1510_hwmon_info[] = {
  1538. &m88e1121_hwmon_chip,
  1539. &m88e1510_hwmon_temp,
  1540. NULL
  1541. };
  1542. static const struct hwmon_ops m88e1510_hwmon_hwmon_ops = {
  1543. .is_visible = m88e1510_hwmon_is_visible,
  1544. .read = m88e1510_hwmon_read,
  1545. .write = m88e1510_hwmon_write,
  1546. };
  1547. static const struct hwmon_chip_info m88e1510_hwmon_chip_info = {
  1548. .ops = &m88e1510_hwmon_hwmon_ops,
  1549. .info = m88e1510_hwmon_info,
  1550. };
  1551. static int m88e6390_get_temp(struct phy_device *phydev, long *temp)
  1552. {
  1553. int sum = 0;
  1554. int oldpage;
  1555. int ret = 0;
  1556. int i;
  1557. *temp = 0;
  1558. oldpage = phy_select_page(phydev, MII_MARVELL_MISC_TEST_PAGE);
  1559. if (oldpage < 0)
  1560. goto error;
  1561. /* Enable temperature sensor */
  1562. ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
  1563. if (ret < 0)
  1564. goto error;
  1565. ret = ret & ~MII_88E6390_MISC_TEST_SAMPLE_MASK;
  1566. ret |= MII_88E6390_MISC_TEST_SAMPLE_ENABLE |
  1567. MII_88E6390_MISC_TEST_SAMPLE_1S;
  1568. ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
  1569. if (ret < 0)
  1570. goto error;
  1571. /* Wait for temperature to stabilize */
  1572. usleep_range(10000, 12000);
  1573. /* Reading the temperature sense has an errata. You need to read
  1574. * a number of times and take an average.
  1575. */
  1576. for (i = 0; i < MII_88E6390_TEMP_SENSOR_SAMPLES; i++) {
  1577. ret = __phy_read(phydev, MII_88E6390_TEMP_SENSOR);
  1578. if (ret < 0)
  1579. goto error;
  1580. sum += ret & MII_88E6390_TEMP_SENSOR_MASK;
  1581. }
  1582. sum /= MII_88E6390_TEMP_SENSOR_SAMPLES;
  1583. *temp = (sum - 75) * 1000;
  1584. /* Disable temperature sensor */
  1585. ret = __phy_read(phydev, MII_88E6390_MISC_TEST);
  1586. if (ret < 0)
  1587. goto error;
  1588. ret = ret & ~MII_88E6390_MISC_TEST_SAMPLE_MASK;
  1589. ret |= MII_88E6390_MISC_TEST_SAMPLE_DISABLE;
  1590. ret = __phy_write(phydev, MII_88E6390_MISC_TEST, ret);
  1591. error:
  1592. phy_restore_page(phydev, oldpage, ret);
  1593. return ret;
  1594. }
  1595. static int m88e6390_hwmon_read(struct device *dev,
  1596. enum hwmon_sensor_types type,
  1597. u32 attr, int channel, long *temp)
  1598. {
  1599. struct phy_device *phydev = dev_get_drvdata(dev);
  1600. int err;
  1601. switch (attr) {
  1602. case hwmon_temp_input:
  1603. err = m88e6390_get_temp(phydev, temp);
  1604. break;
  1605. default:
  1606. return -EOPNOTSUPP;
  1607. }
  1608. return err;
  1609. }
  1610. static umode_t m88e6390_hwmon_is_visible(const void *data,
  1611. enum hwmon_sensor_types type,
  1612. u32 attr, int channel)
  1613. {
  1614. if (type != hwmon_temp)
  1615. return 0;
  1616. switch (attr) {
  1617. case hwmon_temp_input:
  1618. return 0444;
  1619. default:
  1620. return 0;
  1621. }
  1622. }
  1623. static u32 m88e6390_hwmon_temp_config[] = {
  1624. HWMON_T_INPUT,
  1625. 0
  1626. };
  1627. static const struct hwmon_channel_info m88e6390_hwmon_temp = {
  1628. .type = hwmon_temp,
  1629. .config = m88e6390_hwmon_temp_config,
  1630. };
  1631. static const struct hwmon_channel_info *m88e6390_hwmon_info[] = {
  1632. &m88e1121_hwmon_chip,
  1633. &m88e6390_hwmon_temp,
  1634. NULL
  1635. };
  1636. static const struct hwmon_ops m88e6390_hwmon_hwmon_ops = {
  1637. .is_visible = m88e6390_hwmon_is_visible,
  1638. .read = m88e6390_hwmon_read,
  1639. };
  1640. static const struct hwmon_chip_info m88e6390_hwmon_chip_info = {
  1641. .ops = &m88e6390_hwmon_hwmon_ops,
  1642. .info = m88e6390_hwmon_info,
  1643. };
  1644. static int marvell_hwmon_name(struct phy_device *phydev)
  1645. {
  1646. struct marvell_priv *priv = phydev->priv;
  1647. struct device *dev = &phydev->mdio.dev;
  1648. const char *devname = dev_name(dev);
  1649. size_t len = strlen(devname);
  1650. int i, j;
  1651. priv->hwmon_name = devm_kzalloc(dev, len, GFP_KERNEL);
  1652. if (!priv->hwmon_name)
  1653. return -ENOMEM;
  1654. for (i = j = 0; i < len && devname[i]; i++) {
  1655. if (isalnum(devname[i]))
  1656. priv->hwmon_name[j++] = devname[i];
  1657. }
  1658. return 0;
  1659. }
  1660. static int marvell_hwmon_probe(struct phy_device *phydev,
  1661. const struct hwmon_chip_info *chip)
  1662. {
  1663. struct marvell_priv *priv = phydev->priv;
  1664. struct device *dev = &phydev->mdio.dev;
  1665. int err;
  1666. err = marvell_hwmon_name(phydev);
  1667. if (err)
  1668. return err;
  1669. priv->hwmon_dev = devm_hwmon_device_register_with_info(
  1670. dev, priv->hwmon_name, phydev, chip, NULL);
  1671. return PTR_ERR_OR_ZERO(priv->hwmon_dev);
  1672. }
  1673. static int m88e1121_hwmon_probe(struct phy_device *phydev)
  1674. {
  1675. return marvell_hwmon_probe(phydev, &m88e1121_hwmon_chip_info);
  1676. }
  1677. static int m88e1510_hwmon_probe(struct phy_device *phydev)
  1678. {
  1679. return marvell_hwmon_probe(phydev, &m88e1510_hwmon_chip_info);
  1680. }
  1681. static int m88e6390_hwmon_probe(struct phy_device *phydev)
  1682. {
  1683. return marvell_hwmon_probe(phydev, &m88e6390_hwmon_chip_info);
  1684. }
  1685. #else
  1686. static int m88e1121_hwmon_probe(struct phy_device *phydev)
  1687. {
  1688. return 0;
  1689. }
  1690. static int m88e1510_hwmon_probe(struct phy_device *phydev)
  1691. {
  1692. return 0;
  1693. }
  1694. static int m88e6390_hwmon_probe(struct phy_device *phydev)
  1695. {
  1696. return 0;
  1697. }
  1698. #endif
  1699. static int marvell_probe(struct phy_device *phydev)
  1700. {
  1701. struct marvell_priv *priv;
  1702. priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
  1703. if (!priv)
  1704. return -ENOMEM;
  1705. phydev->priv = priv;
  1706. return 0;
  1707. }
  1708. static int m88e1121_probe(struct phy_device *phydev)
  1709. {
  1710. int err;
  1711. err = marvell_probe(phydev);
  1712. if (err)
  1713. return err;
  1714. return m88e1121_hwmon_probe(phydev);
  1715. }
  1716. static int m88e1510_probe(struct phy_device *phydev)
  1717. {
  1718. int err;
  1719. err = marvell_probe(phydev);
  1720. if (err)
  1721. return err;
  1722. return m88e1510_hwmon_probe(phydev);
  1723. }
  1724. static int m88e6390_probe(struct phy_device *phydev)
  1725. {
  1726. int err;
  1727. err = marvell_probe(phydev);
  1728. if (err)
  1729. return err;
  1730. return m88e6390_hwmon_probe(phydev);
  1731. }
  1732. static struct phy_driver marvell_drivers[] = {
  1733. {
  1734. .phy_id = MARVELL_PHY_ID_88E1101,
  1735. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1736. .name = "Marvell 88E1101",
  1737. /* PHY_GBIT_FEATURES */
  1738. .probe = marvell_probe,
  1739. .config_init = &marvell_config_init,
  1740. .config_aneg = &m88e1101_config_aneg,
  1741. .ack_interrupt = &marvell_ack_interrupt,
  1742. .config_intr = &marvell_config_intr,
  1743. .resume = &genphy_resume,
  1744. .suspend = &genphy_suspend,
  1745. .read_page = marvell_read_page,
  1746. .write_page = marvell_write_page,
  1747. .get_sset_count = marvell_get_sset_count,
  1748. .get_strings = marvell_get_strings,
  1749. .get_stats = marvell_get_stats,
  1750. },
  1751. {
  1752. .phy_id = MARVELL_PHY_ID_88E1112,
  1753. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1754. .name = "Marvell 88E1112",
  1755. /* PHY_GBIT_FEATURES */
  1756. .probe = marvell_probe,
  1757. .config_init = &m88e1111_config_init,
  1758. .config_aneg = &marvell_config_aneg,
  1759. .ack_interrupt = &marvell_ack_interrupt,
  1760. .config_intr = &marvell_config_intr,
  1761. .resume = &genphy_resume,
  1762. .suspend = &genphy_suspend,
  1763. .read_page = marvell_read_page,
  1764. .write_page = marvell_write_page,
  1765. .get_sset_count = marvell_get_sset_count,
  1766. .get_strings = marvell_get_strings,
  1767. .get_stats = marvell_get_stats,
  1768. },
  1769. {
  1770. .phy_id = MARVELL_PHY_ID_88E1111,
  1771. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1772. .name = "Marvell 88E1111",
  1773. /* PHY_GBIT_FEATURES */
  1774. .probe = marvell_probe,
  1775. .config_init = &m88e1111_config_init,
  1776. .config_aneg = &marvell_config_aneg,
  1777. .read_status = &marvell_read_status,
  1778. .ack_interrupt = &marvell_ack_interrupt,
  1779. .config_intr = &marvell_config_intr,
  1780. .resume = &genphy_resume,
  1781. .suspend = &genphy_suspend,
  1782. .read_page = marvell_read_page,
  1783. .write_page = marvell_write_page,
  1784. .get_sset_count = marvell_get_sset_count,
  1785. .get_strings = marvell_get_strings,
  1786. .get_stats = marvell_get_stats,
  1787. },
  1788. {
  1789. .phy_id = MARVELL_PHY_ID_88E1118,
  1790. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1791. .name = "Marvell 88E1118",
  1792. /* PHY_GBIT_FEATURES */
  1793. .probe = marvell_probe,
  1794. .config_init = &m88e1118_config_init,
  1795. .config_aneg = &m88e1118_config_aneg,
  1796. .ack_interrupt = &marvell_ack_interrupt,
  1797. .config_intr = &marvell_config_intr,
  1798. .resume = &genphy_resume,
  1799. .suspend = &genphy_suspend,
  1800. .read_page = marvell_read_page,
  1801. .write_page = marvell_write_page,
  1802. .get_sset_count = marvell_get_sset_count,
  1803. .get_strings = marvell_get_strings,
  1804. .get_stats = marvell_get_stats,
  1805. },
  1806. {
  1807. .phy_id = MARVELL_PHY_ID_88E1121R,
  1808. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1809. .name = "Marvell 88E1121R",
  1810. /* PHY_GBIT_FEATURES */
  1811. .probe = &m88e1121_probe,
  1812. .config_init = &marvell_config_init,
  1813. .config_aneg = &m88e1121_config_aneg,
  1814. .read_status = &marvell_read_status,
  1815. .ack_interrupt = &marvell_ack_interrupt,
  1816. .config_intr = &marvell_config_intr,
  1817. .did_interrupt = &m88e1121_did_interrupt,
  1818. .resume = &genphy_resume,
  1819. .suspend = &genphy_suspend,
  1820. .read_page = marvell_read_page,
  1821. .write_page = marvell_write_page,
  1822. .get_sset_count = marvell_get_sset_count,
  1823. .get_strings = marvell_get_strings,
  1824. .get_stats = marvell_get_stats,
  1825. },
  1826. {
  1827. .phy_id = MARVELL_PHY_ID_88E1318S,
  1828. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1829. .name = "Marvell 88E1318S",
  1830. /* PHY_GBIT_FEATURES */
  1831. .probe = marvell_probe,
  1832. .config_init = &m88e1318_config_init,
  1833. .config_aneg = &m88e1318_config_aneg,
  1834. .read_status = &marvell_read_status,
  1835. .ack_interrupt = &marvell_ack_interrupt,
  1836. .config_intr = &marvell_config_intr,
  1837. .did_interrupt = &m88e1121_did_interrupt,
  1838. .get_wol = &m88e1318_get_wol,
  1839. .set_wol = &m88e1318_set_wol,
  1840. .resume = &genphy_resume,
  1841. .suspend = &genphy_suspend,
  1842. .read_page = marvell_read_page,
  1843. .write_page = marvell_write_page,
  1844. .get_sset_count = marvell_get_sset_count,
  1845. .get_strings = marvell_get_strings,
  1846. .get_stats = marvell_get_stats,
  1847. },
  1848. {
  1849. .phy_id = MARVELL_PHY_ID_88E1145,
  1850. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1851. .name = "Marvell 88E1145",
  1852. /* PHY_GBIT_FEATURES */
  1853. .probe = marvell_probe,
  1854. .config_init = &m88e1145_config_init,
  1855. .config_aneg = &m88e1101_config_aneg,
  1856. .read_status = &genphy_read_status,
  1857. .ack_interrupt = &marvell_ack_interrupt,
  1858. .config_intr = &marvell_config_intr,
  1859. .resume = &genphy_resume,
  1860. .suspend = &genphy_suspend,
  1861. .read_page = marvell_read_page,
  1862. .write_page = marvell_write_page,
  1863. .get_sset_count = marvell_get_sset_count,
  1864. .get_strings = marvell_get_strings,
  1865. .get_stats = marvell_get_stats,
  1866. },
  1867. {
  1868. .phy_id = MARVELL_PHY_ID_88E1149R,
  1869. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1870. .name = "Marvell 88E1149R",
  1871. /* PHY_GBIT_FEATURES */
  1872. .probe = marvell_probe,
  1873. .config_init = &m88e1149_config_init,
  1874. .config_aneg = &m88e1118_config_aneg,
  1875. .ack_interrupt = &marvell_ack_interrupt,
  1876. .config_intr = &marvell_config_intr,
  1877. .resume = &genphy_resume,
  1878. .suspend = &genphy_suspend,
  1879. .read_page = marvell_read_page,
  1880. .write_page = marvell_write_page,
  1881. .get_sset_count = marvell_get_sset_count,
  1882. .get_strings = marvell_get_strings,
  1883. .get_stats = marvell_get_stats,
  1884. },
  1885. {
  1886. .phy_id = MARVELL_PHY_ID_88E1240,
  1887. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1888. .name = "Marvell 88E1240",
  1889. /* PHY_GBIT_FEATURES */
  1890. .probe = marvell_probe,
  1891. .config_init = &m88e1111_config_init,
  1892. .config_aneg = &marvell_config_aneg,
  1893. .ack_interrupt = &marvell_ack_interrupt,
  1894. .config_intr = &marvell_config_intr,
  1895. .resume = &genphy_resume,
  1896. .suspend = &genphy_suspend,
  1897. .read_page = marvell_read_page,
  1898. .write_page = marvell_write_page,
  1899. .get_sset_count = marvell_get_sset_count,
  1900. .get_strings = marvell_get_strings,
  1901. .get_stats = marvell_get_stats,
  1902. },
  1903. {
  1904. .phy_id = MARVELL_PHY_ID_88E1116R,
  1905. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1906. .name = "Marvell 88E1116R",
  1907. /* PHY_GBIT_FEATURES */
  1908. .probe = marvell_probe,
  1909. .config_init = &m88e1116r_config_init,
  1910. .ack_interrupt = &marvell_ack_interrupt,
  1911. .config_intr = &marvell_config_intr,
  1912. .resume = &genphy_resume,
  1913. .suspend = &genphy_suspend,
  1914. .read_page = marvell_read_page,
  1915. .write_page = marvell_write_page,
  1916. .get_sset_count = marvell_get_sset_count,
  1917. .get_strings = marvell_get_strings,
  1918. .get_stats = marvell_get_stats,
  1919. },
  1920. {
  1921. .phy_id = MARVELL_PHY_ID_88E1510,
  1922. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1923. .name = "Marvell 88E1510",
  1924. .features = PHY_GBIT_FIBRE_FEATURES,
  1925. .probe = &m88e1510_probe,
  1926. .config_init = &m88e1510_config_init,
  1927. .config_aneg = &m88e1510_config_aneg,
  1928. .read_status = &marvell_read_status,
  1929. .ack_interrupt = &marvell_ack_interrupt,
  1930. .config_intr = &marvell_config_intr,
  1931. .did_interrupt = &m88e1121_did_interrupt,
  1932. .get_wol = &m88e1318_get_wol,
  1933. .set_wol = &m88e1318_set_wol,
  1934. .resume = &marvell_resume,
  1935. .suspend = &marvell_suspend,
  1936. .read_page = marvell_read_page,
  1937. .write_page = marvell_write_page,
  1938. .get_sset_count = marvell_get_sset_count,
  1939. .get_strings = marvell_get_strings,
  1940. .get_stats = marvell_get_stats,
  1941. .set_loopback = genphy_loopback,
  1942. },
  1943. {
  1944. .phy_id = MARVELL_PHY_ID_88E1540,
  1945. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1946. .name = "Marvell 88E1540",
  1947. /* PHY_GBIT_FEATURES */
  1948. .probe = m88e1510_probe,
  1949. .config_init = &marvell_config_init,
  1950. .config_aneg = &m88e1510_config_aneg,
  1951. .read_status = &marvell_read_status,
  1952. .ack_interrupt = &marvell_ack_interrupt,
  1953. .config_intr = &marvell_config_intr,
  1954. .did_interrupt = &m88e1121_did_interrupt,
  1955. .resume = &genphy_resume,
  1956. .suspend = &genphy_suspend,
  1957. .read_page = marvell_read_page,
  1958. .write_page = marvell_write_page,
  1959. .get_sset_count = marvell_get_sset_count,
  1960. .get_strings = marvell_get_strings,
  1961. .get_stats = marvell_get_stats,
  1962. .get_tunable = m88e1540_get_tunable,
  1963. .set_tunable = m88e1540_set_tunable,
  1964. },
  1965. {
  1966. .phy_id = MARVELL_PHY_ID_88E1545,
  1967. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1968. .name = "Marvell 88E1545",
  1969. .probe = m88e1510_probe,
  1970. /* PHY_GBIT_FEATURES */
  1971. .config_init = &marvell_config_init,
  1972. .config_aneg = &m88e1510_config_aneg,
  1973. .read_status = &marvell_read_status,
  1974. .ack_interrupt = &marvell_ack_interrupt,
  1975. .config_intr = &marvell_config_intr,
  1976. .did_interrupt = &m88e1121_did_interrupt,
  1977. .resume = &genphy_resume,
  1978. .suspend = &genphy_suspend,
  1979. .read_page = marvell_read_page,
  1980. .write_page = marvell_write_page,
  1981. .get_sset_count = marvell_get_sset_count,
  1982. .get_strings = marvell_get_strings,
  1983. .get_stats = marvell_get_stats,
  1984. },
  1985. {
  1986. .phy_id = MARVELL_PHY_ID_88E3016,
  1987. .phy_id_mask = MARVELL_PHY_ID_MASK,
  1988. .name = "Marvell 88E3016",
  1989. /* PHY_BASIC_FEATURES */
  1990. .probe = marvell_probe,
  1991. .config_init = &m88e3016_config_init,
  1992. .aneg_done = &marvell_aneg_done,
  1993. .read_status = &marvell_read_status,
  1994. .ack_interrupt = &marvell_ack_interrupt,
  1995. .config_intr = &marvell_config_intr,
  1996. .did_interrupt = &m88e1121_did_interrupt,
  1997. .resume = &genphy_resume,
  1998. .suspend = &genphy_suspend,
  1999. .read_page = marvell_read_page,
  2000. .write_page = marvell_write_page,
  2001. .get_sset_count = marvell_get_sset_count,
  2002. .get_strings = marvell_get_strings,
  2003. .get_stats = marvell_get_stats,
  2004. },
  2005. {
  2006. .phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
  2007. .phy_id_mask = MARVELL_PHY_ID_MASK,
  2008. .name = "Marvell 88E6341 Family",
  2009. /* PHY_GBIT_FEATURES */
  2010. .probe = m88e1510_probe,
  2011. .config_init = &marvell_config_init,
  2012. .config_aneg = &m88e6390_config_aneg,
  2013. .read_status = &marvell_read_status,
  2014. .ack_interrupt = &marvell_ack_interrupt,
  2015. .config_intr = &marvell_config_intr,
  2016. .did_interrupt = &m88e1121_did_interrupt,
  2017. .resume = &genphy_resume,
  2018. .suspend = &genphy_suspend,
  2019. .read_page = marvell_read_page,
  2020. .write_page = marvell_write_page,
  2021. .get_sset_count = marvell_get_sset_count,
  2022. .get_strings = marvell_get_strings,
  2023. .get_stats = marvell_get_stats,
  2024. .get_tunable = m88e1540_get_tunable,
  2025. .set_tunable = m88e1540_set_tunable,
  2026. },
  2027. {
  2028. .phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
  2029. .phy_id_mask = MARVELL_PHY_ID_MASK,
  2030. .name = "Marvell 88E6390 Family",
  2031. /* PHY_GBIT_FEATURES */
  2032. .probe = m88e6390_probe,
  2033. .config_init = &marvell_config_init,
  2034. .config_aneg = &m88e6390_config_aneg,
  2035. .read_status = &marvell_read_status,
  2036. .ack_interrupt = &marvell_ack_interrupt,
  2037. .config_intr = &marvell_config_intr,
  2038. .did_interrupt = &m88e1121_did_interrupt,
  2039. .resume = &genphy_resume,
  2040. .suspend = &genphy_suspend,
  2041. .read_page = marvell_read_page,
  2042. .write_page = marvell_write_page,
  2043. .get_sset_count = marvell_get_sset_count,
  2044. .get_strings = marvell_get_strings,
  2045. .get_stats = marvell_get_stats,
  2046. .get_tunable = m88e1540_get_tunable,
  2047. .set_tunable = m88e1540_set_tunable,
  2048. },
  2049. };
  2050. module_phy_driver(marvell_drivers);
  2051. static struct mdio_device_id __maybe_unused marvell_tbl[] = {
  2052. { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
  2053. { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
  2054. { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
  2055. { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
  2056. { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
  2057. { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
  2058. { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
  2059. { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
  2060. { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
  2061. { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
  2062. { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
  2063. { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
  2064. { MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
  2065. { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
  2066. { MARVELL_PHY_ID_88E6341_FAMILY, MARVELL_PHY_ID_MASK },
  2067. { MARVELL_PHY_ID_88E6390_FAMILY, MARVELL_PHY_ID_MASK },
  2068. { }
  2069. };
  2070. MODULE_DEVICE_TABLE(mdio, marvell_tbl);