dp83td510.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Driver for the Texas Instruments DP83TD510 PHY
  3. * Copyright (c) 2022 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
  4. */
  5. #include <linux/bitfield.h>
  6. #include <linux/ethtool_netlink.h>
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/phy.h>
  10. #define DP83TD510E_PHY_ID 0x20000181
  11. /* MDIO_MMD_VEND2 registers */
  12. #define DP83TD510E_PHY_STS 0x10
  13. /* Bit 7 - mii_interrupt, active high. Clears on read.
  14. * Note: Clearing does not necessarily deactivate IRQ pin if interrupts pending.
  15. * This differs from the DP83TD510E datasheet (2020) which states this bit
  16. * clears on write 0.
  17. */
  18. #define DP83TD510E_STS_MII_INT BIT(7)
  19. #define DP83TD510E_LINK_STATUS BIT(0)
  20. #define DP83TD510E_GEN_CFG 0x11
  21. #define DP83TD510E_GENCFG_INT_POLARITY BIT(3)
  22. #define DP83TD510E_GENCFG_INT_EN BIT(1)
  23. #define DP83TD510E_GENCFG_INT_OE BIT(0)
  24. #define DP83TD510E_INTERRUPT_REG_1 0x12
  25. #define DP83TD510E_INT1_LINK BIT(13)
  26. #define DP83TD510E_INT1_LINK_EN BIT(5)
  27. #define DP83TD510E_CTRL 0x1f
  28. #define DP83TD510E_CTRL_HW_RESET BIT(15)
  29. #define DP83TD510E_CTRL_SW_RESET BIT(14)
  30. /*
  31. * DP83TD510E_PKT_STAT_x registers correspond to similarly named registers
  32. * in the datasheet (PKT_STAT_1 through PKT_STAT_6). These registers store
  33. * 32-bit or 16-bit counters for TX and RX statistics and must be read in
  34. * sequence to ensure the counters are cleared correctly.
  35. *
  36. * - DP83TD510E_PKT_STAT_1: Contains TX packet count bits [15:0].
  37. * - DP83TD510E_PKT_STAT_2: Contains TX packet count bits [31:16].
  38. * - DP83TD510E_PKT_STAT_3: Contains TX error packet count.
  39. * - DP83TD510E_PKT_STAT_4: Contains RX packet count bits [15:0].
  40. * - DP83TD510E_PKT_STAT_5: Contains RX packet count bits [31:16].
  41. * - DP83TD510E_PKT_STAT_6: Contains RX error packet count.
  42. *
  43. * Keeping the register names as defined in the datasheet helps maintain
  44. * clarity and alignment with the documentation.
  45. */
  46. #define DP83TD510E_PKT_STAT_1 0x12b
  47. #define DP83TD510E_PKT_STAT_2 0x12c
  48. #define DP83TD510E_PKT_STAT_3 0x12d
  49. #define DP83TD510E_PKT_STAT_4 0x12e
  50. #define DP83TD510E_PKT_STAT_5 0x12f
  51. #define DP83TD510E_PKT_STAT_6 0x130
  52. #define DP83TD510E_AN_STAT_1 0x60c
  53. #define DP83TD510E_MASTER_SLAVE_RESOL_FAIL BIT(15)
  54. #define DP83TD510E_MSE_DETECT 0xa85
  55. #define DP83TD510E_MSE_MAX U16_MAX
  56. #define DP83TD510_SQI_MAX 7
  57. /* Register values are converted to SNR(dB) as suggested by
  58. * "Application Report - DP83TD510E Cable Diagnostics Toolkit":
  59. * SNR(dB) = -10 * log10 (VAL/2^17) - 1.76 dB.
  60. * SQI ranges are implemented according to "OPEN ALLIANCE - Advanced diagnostic
  61. * features for 100BASE-T1 automotive Ethernet PHYs"
  62. */
  63. static const u16 dp83td510_mse_sqi_map[] = {
  64. 0x0569, /* < 18dB */
  65. 0x044c, /* 18dB =< SNR < 19dB */
  66. 0x0369, /* 19dB =< SNR < 20dB */
  67. 0x02b6, /* 20dB =< SNR < 21dB */
  68. 0x0227, /* 21dB =< SNR < 22dB */
  69. 0x01b6, /* 22dB =< SNR < 23dB */
  70. 0x015b, /* 23dB =< SNR < 24dB */
  71. 0x0000 /* 24dB =< SNR */
  72. };
  73. struct dp83td510_stats {
  74. u64 tx_pkt_cnt;
  75. u64 tx_err_pkt_cnt;
  76. u64 rx_pkt_cnt;
  77. u64 rx_err_pkt_cnt;
  78. };
  79. struct dp83td510_priv {
  80. bool alcd_test_active;
  81. struct dp83td510_stats stats;
  82. };
  83. /* Time Domain Reflectometry (TDR) Functionality of DP83TD510 PHY
  84. *
  85. * I assume that this PHY is using a variation of Spread Spectrum Time Domain
  86. * Reflectometry (SSTDR) rather than the commonly used TDR found in many PHYs.
  87. * Here are the following observations which likely confirm this:
  88. * - The DP83TD510 PHY transmits a modulated signal of configurable length
  89. * (default 16000 µs) instead of a single pulse pattern, which is typical
  90. * for traditional TDR.
  91. * - The pulse observed on the wire, triggered by the HW RESET register, is not
  92. * part of the cable testing process.
  93. *
  94. * I assume that SSTDR seems to be a logical choice for the 10BaseT1L
  95. * environment due to improved noise resistance, making it suitable for
  96. * environments with significant electrical noise, such as long 10BaseT1L cable
  97. * runs.
  98. *
  99. * Configuration Variables:
  100. * The SSTDR variation used in this PHY involves more configuration variables
  101. * that can dramatically affect the functionality and precision of cable
  102. * testing. Since most of these configuration options are either not well
  103. * documented or documented with minimal details, the following sections
  104. * describe my understanding and observations of these variables and their
  105. * impact on TDR functionality.
  106. *
  107. * Timeline:
  108. * ,<--cfg_pre_silence_time
  109. * | ,<-SSTDR Modulated Transmission
  110. * | | ,<--cfg_post_silence_time
  111. * | | | ,<--Force Link Mode
  112. * |<--'-->|<-------'------->|<--'-->|<--------'------->|
  113. *
  114. * - cfg_pre_silence_time: Optional silence time before TDR transmission starts.
  115. * - SSTDR Modulated Transmission: Transmission duration configured by
  116. * cfg_tdr_tx_duration and amplitude configured by cfg_tdr_tx_type.
  117. * - cfg_post_silence_time: Silence time after TDR transmission.
  118. * - Force Link Mode: If nothing is configured after cfg_post_silence_time,
  119. * the PHY continues in force link mode without autonegotiation.
  120. */
  121. #define DP83TD510E_TDR_CFG 0x1e
  122. #define DP83TD510E_TDR_START BIT(15)
  123. #define DP83TD510E_TDR_DONE BIT(1)
  124. #define DP83TD510E_TDR_FAIL BIT(0)
  125. #define DP83TD510E_TDR_CFG1 0x300
  126. /* cfg_tdr_tx_type: Transmit voltage level for TDR.
  127. * 0 = 1V, 1 = 2.4V
  128. * Note: Using different voltage levels may not work
  129. * in all configuration variations. For example, setting
  130. * 2.4V may give different cable length measurements.
  131. * Other settings may be needed to make it work properly.
  132. */
  133. #define DP83TD510E_TDR_TX_TYPE BIT(12)
  134. #define DP83TD510E_TDR_TX_TYPE_1V 0
  135. #define DP83TD510E_TDR_TX_TYPE_2_4V 1
  136. /* cfg_post_silence_time: Time after the TDR sequence. Since we force master mode
  137. * for the TDR will proceed with forced link state after this time. For Linux
  138. * it is better to set max value to avoid false link state detection.
  139. */
  140. #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME GENMASK(3, 2)
  141. #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_0MS 0
  142. #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_10MS 1
  143. #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_100MS 2
  144. #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_1000MS 3
  145. /* cfg_pre_silence_time: Time before the TDR sequence. It should be enough to
  146. * settle down all pulses and reflections. Since for 10BASE-T1L we have
  147. * maximum 2000m cable length, we can set it to 1ms.
  148. */
  149. #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME GENMASK(1, 0)
  150. #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_0MS 0
  151. #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_10MS 1
  152. #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_100MS 2
  153. #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_1000MS 3
  154. #define DP83TD510E_TDR_CFG2 0x301
  155. #define DP83TD510E_TDR_END_TAP_INDEX_1 GENMASK(14, 8)
  156. #define DP83TD510E_TDR_END_TAP_INDEX_1_DEF 36
  157. #define DP83TD510E_TDR_START_TAP_INDEX_1 GENMASK(6, 0)
  158. #define DP83TD510E_TDR_START_TAP_INDEX_1_DEF 4
  159. #define DP83TD510E_TDR_CFG3 0x302
  160. /* cfg_tdr_tx_duration: Duration of the TDR transmission in microseconds.
  161. * This value sets the duration of the modulated signal used for TDR
  162. * measurements.
  163. * - Default: 16000 µs
  164. * - Observation: A minimum duration of 6000 µs is recommended to ensure
  165. * accurate detection of cable faults. Durations shorter than 6000 µs may
  166. * result in incomplete data, especially for shorter cables (e.g., 20 meters),
  167. * leading to false "OK" results. Longer durations (e.g., 6000 µs or more)
  168. * provide better accuracy, particularly for detecting open circuits.
  169. */
  170. #define DP83TD510E_TDR_TX_DURATION_US GENMASK(15, 0)
  171. #define DP83TD510E_TDR_TX_DURATION_US_DEF 16000
  172. #define DP83TD510E_TDR_FAULT_CFG1 0x303
  173. #define DP83TD510E_TDR_FLT_LOC_OFFSET_1 GENMASK(14, 8)
  174. #define DP83TD510E_TDR_FLT_LOC_OFFSET_1_DEF 4
  175. #define DP83TD510E_TDR_FLT_INIT_1 GENMASK(7, 0)
  176. #define DP83TD510E_TDR_FLT_INIT_1_DEF 62
  177. #define DP83TD510E_TDR_FAULT_STAT 0x30c
  178. #define DP83TD510E_TDR_PEAK_DETECT BIT(11)
  179. #define DP83TD510E_TDR_PEAK_SIGN BIT(10)
  180. #define DP83TD510E_TDR_PEAK_LOCATION GENMASK(9, 0)
  181. /* Not documented registers and values but recommended according to
  182. * "DP83TD510E Cable Diagnostics Toolkit revC"
  183. */
  184. #define DP83TD510E_UNKN_030E 0x30e
  185. #define DP83TD510E_030E_VAL 0x2520
  186. #define DP83TD510E_LEDS_CFG_1 0x460
  187. #define DP83TD510E_LED_FN(idx, val) (((val) & 0xf) << ((idx) * 4))
  188. #define DP83TD510E_LED_FN_MASK(idx) (0xf << ((idx) * 4))
  189. /* link OK */
  190. #define DP83TD510E_LED_MODE_LINK_OK 0x0
  191. /* TX/RX activity */
  192. #define DP83TD510E_LED_MODE_TX_RX_ACTIVITY 0x1
  193. /* TX activity */
  194. #define DP83TD510E_LED_MODE_TX_ACTIVITY 0x2
  195. /* RX activity */
  196. #define DP83TD510E_LED_MODE_RX_ACTIVITY 0x3
  197. /* LR */
  198. #define DP83TD510E_LED_MODE_LR 0x4
  199. /* SR */
  200. #define DP83TD510E_LED_MODE_SR 0x5
  201. /* LED SPEED: High for 10Base-T */
  202. #define DP83TD510E_LED_MODE_LED_SPEED 0x6
  203. /* Duplex mode */
  204. #define DP83TD510E_LED_MODE_DUPLEX 0x7
  205. /* link + blink on activity with stretch option */
  206. #define DP83TD510E_LED_MODE_LINK_BLINK 0x8
  207. /* blink on activity with stretch option */
  208. #define DP83TD510E_LED_MODE_BLINK_ACTIVITY 0x9
  209. /* blink on tx activity with stretch option */
  210. #define DP83TD510E_LED_MODE_BLINK_TX 0xa
  211. /* blink on rx activity with stretch option */
  212. #define DP83TD510E_LED_MODE_BLINK_RX 0xb
  213. /* link_lost */
  214. #define DP83TD510E_LED_MODE_LINK_LOST 0xc
  215. /* PRBS error: toggles on error */
  216. #define DP83TD510E_LED_MODE_PRBS_ERROR 0xd
  217. /* XMII TX/RX Error with stretch option */
  218. #define DP83TD510E_LED_MODE_XMII_ERR 0xe
  219. #define DP83TD510E_LED_COUNT 4
  220. #define DP83TD510E_LEDS_CFG_2 0x469
  221. #define DP83TD510E_LED_POLARITY(idx) BIT((idx) * 4 + 2)
  222. #define DP83TD510E_LED_DRV_VAL(idx) BIT((idx) * 4 + 1)
  223. #define DP83TD510E_LED_DRV_EN(idx) BIT((idx) * 4)
  224. #define DP83TD510E_ALCD_STAT 0xa9f
  225. #define DP83TD510E_ALCD_COMPLETE BIT(15)
  226. #define DP83TD510E_ALCD_CABLE_LENGTH GENMASK(10, 0)
  227. static int dp83td510_get_mse_capability(struct phy_device *phydev,
  228. struct phy_mse_capability *cap)
  229. {
  230. /* DP83TD510E documents only a single (average) MSE register
  231. * (used to derive SQI); no peak or worst-peak counters are
  232. * described. Advertise only PHY_MSE_CAP_AVG.
  233. */
  234. cap->supported_caps = PHY_MSE_CAP_AVG;
  235. /* 10BASE-T1L is a single-pair medium, so there are no B/C/D channels.
  236. * We still advertise PHY_MSE_CAP_CHANNEL_A to indicate that the PHY
  237. * can attribute the measurement to a specific pair (the only one),
  238. * rather than exposing it only as a link-aggregate.
  239. *
  240. * Rationale:
  241. * - Keeps the ethtool MSE_GET selection logic consistent: per-channel
  242. * (A/B/C/D) is preferred over WORST/LINK, so userspace receives a
  243. * CHANNEL_A nest instead of LINK.
  244. * - Signals to tools that "per-pair" data is available (even if there's
  245. * just one pair), avoiding the impression that only aggregate values
  246. * are supported.
  247. * - Remains compatible with multi-pair PHYs and uniform UI handling.
  248. *
  249. * Note: WORST and other channels are not advertised on 10BASE-T1L.
  250. */
  251. cap->supported_caps |= PHY_MSE_CHANNEL_A | PHY_MSE_CAP_LINK;
  252. cap->max_average_mse = DP83TD510E_MSE_MAX;
  253. /* The datasheet does not specify the refresh rate or symbol count,
  254. * but based on similar PHYs and standards, we can assume a common
  255. * value. For 10BASE-T1L, the symbol rate is 7.5 MBd. A common
  256. * diagnostic interval is around 1ms.
  257. * 7.5e6 symbols/sec * 0.001 sec = 7500 symbols.
  258. */
  259. cap->refresh_rate_ps = 1000000000; /* 1 ms */
  260. cap->num_symbols = 7500;
  261. return 0;
  262. }
  263. static int dp83td510_get_mse_snapshot(struct phy_device *phydev,
  264. enum phy_mse_channel channel,
  265. struct phy_mse_snapshot *snapshot)
  266. {
  267. int ret;
  268. if (channel != PHY_MSE_CHANNEL_LINK &&
  269. channel != PHY_MSE_CHANNEL_A)
  270. return -EOPNOTSUPP;
  271. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_MSE_DETECT);
  272. if (ret < 0)
  273. return ret;
  274. snapshot->average_mse = ret;
  275. return 0;
  276. }
  277. static int dp83td510_led_brightness_set(struct phy_device *phydev, u8 index,
  278. enum led_brightness brightness)
  279. {
  280. u32 val;
  281. if (index >= DP83TD510E_LED_COUNT)
  282. return -EINVAL;
  283. val = DP83TD510E_LED_DRV_EN(index);
  284. if (brightness)
  285. val |= DP83TD510E_LED_DRV_VAL(index);
  286. return phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_2,
  287. DP83TD510E_LED_DRV_VAL(index) |
  288. DP83TD510E_LED_DRV_EN(index), val);
  289. }
  290. static int dp83td510_led_mode(u8 index, unsigned long rules)
  291. {
  292. if (index >= DP83TD510E_LED_COUNT)
  293. return -EINVAL;
  294. switch (rules) {
  295. case BIT(TRIGGER_NETDEV_LINK):
  296. return DP83TD510E_LED_MODE_LINK_OK;
  297. case BIT(TRIGGER_NETDEV_LINK_10):
  298. return DP83TD510E_LED_MODE_LED_SPEED;
  299. case BIT(TRIGGER_NETDEV_FULL_DUPLEX):
  300. return DP83TD510E_LED_MODE_DUPLEX;
  301. case BIT(TRIGGER_NETDEV_TX):
  302. return DP83TD510E_LED_MODE_TX_ACTIVITY;
  303. case BIT(TRIGGER_NETDEV_RX):
  304. return DP83TD510E_LED_MODE_RX_ACTIVITY;
  305. case BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX):
  306. return DP83TD510E_LED_MODE_TX_RX_ACTIVITY;
  307. case BIT(TRIGGER_NETDEV_LINK) | BIT(TRIGGER_NETDEV_TX) |
  308. BIT(TRIGGER_NETDEV_RX):
  309. return DP83TD510E_LED_MODE_LINK_BLINK;
  310. default:
  311. return -EOPNOTSUPP;
  312. }
  313. }
  314. static int dp83td510_led_hw_is_supported(struct phy_device *phydev, u8 index,
  315. unsigned long rules)
  316. {
  317. int ret;
  318. ret = dp83td510_led_mode(index, rules);
  319. if (ret < 0)
  320. return ret;
  321. return 0;
  322. }
  323. static int dp83td510_led_hw_control_set(struct phy_device *phydev, u8 index,
  324. unsigned long rules)
  325. {
  326. int mode, ret;
  327. mode = dp83td510_led_mode(index, rules);
  328. if (mode < 0)
  329. return mode;
  330. ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_1,
  331. DP83TD510E_LED_FN_MASK(index),
  332. DP83TD510E_LED_FN(index, mode));
  333. if (ret)
  334. return ret;
  335. return phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_2,
  336. DP83TD510E_LED_DRV_EN(index), 0);
  337. }
  338. static int dp83td510_led_hw_control_get(struct phy_device *phydev,
  339. u8 index, unsigned long *rules)
  340. {
  341. int val;
  342. val = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_1);
  343. if (val < 0)
  344. return val;
  345. val &= DP83TD510E_LED_FN_MASK(index);
  346. val >>= index * 4;
  347. switch (val) {
  348. case DP83TD510E_LED_MODE_LINK_OK:
  349. *rules = BIT(TRIGGER_NETDEV_LINK);
  350. break;
  351. /* LED mode: LED SPEED (10BaseT1L indicator) */
  352. case DP83TD510E_LED_MODE_LED_SPEED:
  353. *rules = BIT(TRIGGER_NETDEV_LINK_10);
  354. break;
  355. case DP83TD510E_LED_MODE_DUPLEX:
  356. *rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX);
  357. break;
  358. case DP83TD510E_LED_MODE_TX_ACTIVITY:
  359. *rules = BIT(TRIGGER_NETDEV_TX);
  360. break;
  361. case DP83TD510E_LED_MODE_RX_ACTIVITY:
  362. *rules = BIT(TRIGGER_NETDEV_RX);
  363. break;
  364. case DP83TD510E_LED_MODE_TX_RX_ACTIVITY:
  365. *rules = BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
  366. break;
  367. case DP83TD510E_LED_MODE_LINK_BLINK:
  368. *rules = BIT(TRIGGER_NETDEV_LINK) |
  369. BIT(TRIGGER_NETDEV_TX) |
  370. BIT(TRIGGER_NETDEV_RX);
  371. break;
  372. default:
  373. *rules = 0;
  374. break;
  375. }
  376. return 0;
  377. }
  378. static int dp83td510_led_polarity_set(struct phy_device *phydev, int index,
  379. unsigned long modes)
  380. {
  381. u16 polarity = DP83TD510E_LED_POLARITY(index);
  382. u32 mode;
  383. for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
  384. switch (mode) {
  385. case PHY_LED_ACTIVE_LOW:
  386. polarity = 0;
  387. break;
  388. default:
  389. return -EINVAL;
  390. }
  391. }
  392. return phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_LEDS_CFG_2,
  393. DP83TD510E_LED_POLARITY(index), polarity);
  394. }
  395. /**
  396. * dp83td510_update_stats - Update the PHY statistics for the DP83TD510 PHY.
  397. * @phydev: Pointer to the phy_device structure.
  398. *
  399. * The function reads the PHY statistics registers and updates the statistics
  400. * structure.
  401. *
  402. * Returns: 0 on success or a negative error code on failure.
  403. */
  404. static int dp83td510_update_stats(struct phy_device *phydev)
  405. {
  406. struct dp83td510_priv *priv = phydev->priv;
  407. u32 count;
  408. int ret;
  409. /* The DP83TD510E_PKT_STAT registers are divided into two groups:
  410. * - Group 1 (TX stats): DP83TD510E_PKT_STAT_1 to DP83TD510E_PKT_STAT_3
  411. * - Group 2 (RX stats): DP83TD510E_PKT_STAT_4 to DP83TD510E_PKT_STAT_6
  412. *
  413. * Registers in each group are cleared only after reading them in a
  414. * plain sequence (e.g., 1, 2, 3 for Group 1 or 4, 5, 6 for Group 2).
  415. * Any deviation from the sequence, such as reading 1, 2, 1, 2, 3, will
  416. * prevent the group from being cleared. Additionally, the counters
  417. * for a group are frozen as soon as the first register in that group
  418. * is accessed.
  419. */
  420. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PKT_STAT_1);
  421. if (ret < 0)
  422. return ret;
  423. /* tx_pkt_cnt_15_0 */
  424. count = ret;
  425. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PKT_STAT_2);
  426. if (ret < 0)
  427. return ret;
  428. /* tx_pkt_cnt_31_16 */
  429. count |= ret << 16;
  430. priv->stats.tx_pkt_cnt += count;
  431. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PKT_STAT_3);
  432. if (ret < 0)
  433. return ret;
  434. /* tx_err_pkt_cnt */
  435. priv->stats.tx_err_pkt_cnt += ret;
  436. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PKT_STAT_4);
  437. if (ret < 0)
  438. return ret;
  439. /* rx_pkt_cnt_15_0 */
  440. count = ret;
  441. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PKT_STAT_5);
  442. if (ret < 0)
  443. return ret;
  444. /* rx_pkt_cnt_31_16 */
  445. count |= ret << 16;
  446. priv->stats.rx_pkt_cnt += count;
  447. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PKT_STAT_6);
  448. if (ret < 0)
  449. return ret;
  450. /* rx_err_pkt_cnt */
  451. priv->stats.rx_err_pkt_cnt += ret;
  452. return 0;
  453. }
  454. static void dp83td510_get_phy_stats(struct phy_device *phydev,
  455. struct ethtool_eth_phy_stats *eth_stats,
  456. struct ethtool_phy_stats *stats)
  457. {
  458. struct dp83td510_priv *priv = phydev->priv;
  459. stats->tx_packets = priv->stats.tx_pkt_cnt;
  460. stats->tx_errors = priv->stats.tx_err_pkt_cnt;
  461. stats->rx_packets = priv->stats.rx_pkt_cnt;
  462. stats->rx_errors = priv->stats.rx_err_pkt_cnt;
  463. }
  464. static int dp83td510_config_intr(struct phy_device *phydev)
  465. {
  466. int ret;
  467. if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
  468. ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
  469. DP83TD510E_INTERRUPT_REG_1,
  470. DP83TD510E_INT1_LINK_EN);
  471. if (ret)
  472. return ret;
  473. ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
  474. DP83TD510E_GEN_CFG,
  475. DP83TD510E_GENCFG_INT_POLARITY |
  476. DP83TD510E_GENCFG_INT_EN |
  477. DP83TD510E_GENCFG_INT_OE);
  478. } else {
  479. ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
  480. DP83TD510E_INTERRUPT_REG_1, 0x0);
  481. if (ret)
  482. return ret;
  483. ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
  484. DP83TD510E_GEN_CFG,
  485. DP83TD510E_GENCFG_INT_EN);
  486. if (ret)
  487. return ret;
  488. }
  489. return ret;
  490. }
  491. static irqreturn_t dp83td510_handle_interrupt(struct phy_device *phydev)
  492. {
  493. int ret;
  494. /* Read the current enabled interrupts */
  495. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_INTERRUPT_REG_1);
  496. if (ret < 0) {
  497. phy_error(phydev);
  498. return IRQ_NONE;
  499. } else if (!(ret & DP83TD510E_INT1_LINK_EN) ||
  500. !(ret & DP83TD510E_INT1_LINK)) {
  501. return IRQ_NONE;
  502. }
  503. phy_trigger_machine(phydev);
  504. return IRQ_HANDLED;
  505. }
  506. static int dp83td510_read_status(struct phy_device *phydev)
  507. {
  508. u16 phy_sts;
  509. int ret;
  510. phydev->speed = SPEED_UNKNOWN;
  511. phydev->duplex = DUPLEX_UNKNOWN;
  512. phydev->pause = 0;
  513. phydev->asym_pause = 0;
  514. linkmode_zero(phydev->lp_advertising);
  515. phy_sts = phy_read(phydev, DP83TD510E_PHY_STS);
  516. phydev->link = !!(phy_sts & DP83TD510E_LINK_STATUS);
  517. if (phydev->link) {
  518. /* This PHY supports only one link mode: 10BaseT1L_Full */
  519. phydev->duplex = DUPLEX_FULL;
  520. phydev->speed = SPEED_10;
  521. if (phydev->autoneg == AUTONEG_ENABLE) {
  522. ret = genphy_c45_read_lpa(phydev);
  523. if (ret)
  524. return ret;
  525. phy_resolve_aneg_linkmode(phydev);
  526. }
  527. }
  528. if (phydev->autoneg == AUTONEG_ENABLE) {
  529. ret = genphy_c45_baset1_read_status(phydev);
  530. if (ret < 0)
  531. return ret;
  532. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2,
  533. DP83TD510E_AN_STAT_1);
  534. if (ret < 0)
  535. return ret;
  536. if (ret & DP83TD510E_MASTER_SLAVE_RESOL_FAIL)
  537. phydev->master_slave_state = MASTER_SLAVE_STATE_ERR;
  538. } else {
  539. return genphy_c45_pma_baset1_read_master_slave(phydev);
  540. }
  541. return 0;
  542. }
  543. static int dp83td510_config_aneg(struct phy_device *phydev)
  544. {
  545. bool changed = false;
  546. int ret;
  547. ret = genphy_c45_pma_baset1_setup_master_slave(phydev);
  548. if (ret < 0)
  549. return ret;
  550. if (phydev->autoneg == AUTONEG_DISABLE)
  551. return genphy_c45_an_disable_aneg(phydev);
  552. ret = genphy_c45_an_config_aneg(phydev);
  553. if (ret < 0)
  554. return ret;
  555. if (ret > 0)
  556. changed = true;
  557. return genphy_c45_check_and_restart_aneg(phydev, changed);
  558. }
  559. static int dp83td510_get_sqi(struct phy_device *phydev)
  560. {
  561. int sqi, ret;
  562. u16 mse_val;
  563. if (!phydev->link)
  564. return 0;
  565. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_MSE_DETECT);
  566. if (ret < 0)
  567. return ret;
  568. mse_val = 0xFFFF & ret;
  569. for (sqi = 0; sqi < ARRAY_SIZE(dp83td510_mse_sqi_map); sqi++) {
  570. if (mse_val >= dp83td510_mse_sqi_map[sqi])
  571. return sqi;
  572. }
  573. return -EINVAL;
  574. }
  575. static int dp83td510_get_sqi_max(struct phy_device *phydev)
  576. {
  577. return DP83TD510_SQI_MAX;
  578. }
  579. /**
  580. * dp83td510_cable_test_start - Start the cable test for the DP83TD510 PHY.
  581. * @phydev: Pointer to the phy_device structure.
  582. *
  583. * This sequence is implemented according to the "Application Note DP83TD510E
  584. * Cable Diagnostics Toolkit revC".
  585. *
  586. * Returns: 0 on success, a negative error code on failure.
  587. */
  588. static int dp83td510_cable_test_start(struct phy_device *phydev)
  589. {
  590. struct dp83td510_priv *priv = phydev->priv;
  591. int ret;
  592. /* If link partner is active, we won't be able to use TDR, since
  593. * we can't force link partner to be silent. The autonegotiation
  594. * pulses will be too frequent and the TDR sequence will be
  595. * too long. So, TDR will always fail. Since the link is established
  596. * we already know that the cable is working, so we can get some
  597. * extra information line the cable length using ALCD.
  598. */
  599. if (phydev->link) {
  600. priv->alcd_test_active = true;
  601. return 0;
  602. }
  603. priv->alcd_test_active = false;
  604. ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_CTRL,
  605. DP83TD510E_CTRL_HW_RESET);
  606. if (ret)
  607. return ret;
  608. ret = genphy_c45_an_disable_aneg(phydev);
  609. if (ret)
  610. return ret;
  611. /* Force master mode */
  612. ret = phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1_CTRL,
  613. MDIO_PMA_PMD_BT1_CTRL_CFG_MST);
  614. if (ret)
  615. return ret;
  616. /* There is no official recommendation for this register, but it is
  617. * better to use 1V for TDR since other values seems to be optimized
  618. * for this amplitude. Except of amplitude, it is better to configure
  619. * pre TDR silence time to 10ms to avoid false reflections (value 0
  620. * seems to be too short, otherwise we need to implement own silence
  621. * time). Also, post TDR silence time should be set to 1000ms to avoid
  622. * false link state detection, it fits to the polling time of the
  623. * PHY framework. The idea is to wait until
  624. * dp83td510_cable_test_get_status() will be called and reconfigure
  625. * the PHY to the default state within the post silence time window.
  626. */
  627. ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG1,
  628. DP83TD510E_TDR_TX_TYPE |
  629. DP83TD510E_TDR_CFG1_POST_SILENCE_TIME |
  630. DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME,
  631. DP83TD510E_TDR_TX_TYPE_1V |
  632. DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_10MS |
  633. DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_1000MS);
  634. if (ret)
  635. return ret;
  636. ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG2,
  637. FIELD_PREP(DP83TD510E_TDR_END_TAP_INDEX_1,
  638. DP83TD510E_TDR_END_TAP_INDEX_1_DEF) |
  639. FIELD_PREP(DP83TD510E_TDR_START_TAP_INDEX_1,
  640. DP83TD510E_TDR_START_TAP_INDEX_1_DEF));
  641. if (ret)
  642. return ret;
  643. ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_FAULT_CFG1,
  644. FIELD_PREP(DP83TD510E_TDR_FLT_LOC_OFFSET_1,
  645. DP83TD510E_TDR_FLT_LOC_OFFSET_1_DEF) |
  646. FIELD_PREP(DP83TD510E_TDR_FLT_INIT_1,
  647. DP83TD510E_TDR_FLT_INIT_1_DEF));
  648. if (ret)
  649. return ret;
  650. /* Undocumented register, from the "Application Note DP83TD510E Cable
  651. * Diagnostics Toolkit revC".
  652. */
  653. ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_UNKN_030E,
  654. DP83TD510E_030E_VAL);
  655. if (ret)
  656. return ret;
  657. ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG3,
  658. DP83TD510E_TDR_TX_DURATION_US_DEF);
  659. if (ret)
  660. return ret;
  661. ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_CTRL,
  662. DP83TD510E_CTRL_SW_RESET);
  663. if (ret)
  664. return ret;
  665. return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG,
  666. DP83TD510E_TDR_START);
  667. }
  668. /**
  669. * dp83td510_cable_test_get_tdr_status - Get the status of the TDR test for the
  670. * DP83TD510 PHY.
  671. * @phydev: Pointer to the phy_device structure.
  672. * @finished: Pointer to a boolean that indicates whether the test is finished.
  673. *
  674. * The function sets the @finished flag to true if the test is complete.
  675. *
  676. * Returns: 0 on success or a negative error code on failure.
  677. */
  678. static int dp83td510_cable_test_get_tdr_status(struct phy_device *phydev,
  679. bool *finished)
  680. {
  681. int ret, stat;
  682. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG);
  683. if (ret < 0)
  684. return ret;
  685. if (!(ret & DP83TD510E_TDR_DONE))
  686. return 0;
  687. if (!(ret & DP83TD510E_TDR_FAIL)) {
  688. int location;
  689. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2,
  690. DP83TD510E_TDR_FAULT_STAT);
  691. if (ret < 0)
  692. return ret;
  693. if (ret & DP83TD510E_TDR_PEAK_DETECT) {
  694. if (ret & DP83TD510E_TDR_PEAK_SIGN)
  695. stat = ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
  696. else
  697. stat = ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
  698. location = FIELD_GET(DP83TD510E_TDR_PEAK_LOCATION,
  699. ret) * 100;
  700. ethnl_cable_test_fault_length(phydev,
  701. ETHTOOL_A_CABLE_PAIR_A,
  702. location);
  703. } else {
  704. stat = ETHTOOL_A_CABLE_RESULT_CODE_OK;
  705. }
  706. } else {
  707. /* Most probably we have active link partner */
  708. stat = ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
  709. }
  710. *finished = true;
  711. ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, stat);
  712. return phy_init_hw(phydev);
  713. }
  714. /**
  715. * dp83td510_cable_test_get_alcd_status - Get the status of the ALCD test for the
  716. * DP83TD510 PHY.
  717. * @phydev: Pointer to the phy_device structure.
  718. * @finished: Pointer to a boolean that indicates whether the test is finished.
  719. *
  720. * The function sets the @finished flag to true if the test is complete.
  721. * The function reads the cable length and reports it to the user.
  722. *
  723. * Returns: 0 on success or a negative error code on failure.
  724. */
  725. static int dp83td510_cable_test_get_alcd_status(struct phy_device *phydev,
  726. bool *finished)
  727. {
  728. unsigned int location;
  729. int ret, phy_sts;
  730. phy_sts = phy_read(phydev, DP83TD510E_PHY_STS);
  731. if (!(phy_sts & DP83TD510E_LINK_STATUS)) {
  732. /* If the link is down, we can't do any thing usable now */
  733. ethnl_cable_test_result_with_src(phydev, ETHTOOL_A_CABLE_PAIR_A,
  734. ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC,
  735. ETHTOOL_A_CABLE_INF_SRC_ALCD);
  736. *finished = true;
  737. return 0;
  738. }
  739. ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_ALCD_STAT);
  740. if (ret < 0)
  741. return ret;
  742. if (!(ret & DP83TD510E_ALCD_COMPLETE))
  743. return 0;
  744. location = FIELD_GET(DP83TD510E_ALCD_CABLE_LENGTH, ret) * 100;
  745. ethnl_cable_test_fault_length_with_src(phydev, ETHTOOL_A_CABLE_PAIR_A,
  746. location,
  747. ETHTOOL_A_CABLE_INF_SRC_ALCD);
  748. ethnl_cable_test_result_with_src(phydev, ETHTOOL_A_CABLE_PAIR_A,
  749. ETHTOOL_A_CABLE_RESULT_CODE_OK,
  750. ETHTOOL_A_CABLE_INF_SRC_ALCD);
  751. *finished = true;
  752. return 0;
  753. }
  754. /**
  755. * dp83td510_cable_test_get_status - Get the status of the cable test for the
  756. * DP83TD510 PHY.
  757. * @phydev: Pointer to the phy_device structure.
  758. * @finished: Pointer to a boolean that indicates whether the test is finished.
  759. *
  760. * The function sets the @finished flag to true if the test is complete.
  761. *
  762. * Returns: 0 on success or a negative error code on failure.
  763. */
  764. static int dp83td510_cable_test_get_status(struct phy_device *phydev,
  765. bool *finished)
  766. {
  767. struct dp83td510_priv *priv = phydev->priv;
  768. *finished = false;
  769. if (priv->alcd_test_active)
  770. return dp83td510_cable_test_get_alcd_status(phydev, finished);
  771. return dp83td510_cable_test_get_tdr_status(phydev, finished);
  772. }
  773. static int dp83td510_get_features(struct phy_device *phydev)
  774. {
  775. /* This PHY can't respond on MDIO bus if no RMII clock is enabled.
  776. * In case RMII mode is used (most meaningful mode for this PHY) and
  777. * the PHY do not have own XTAL, and CLK providing MAC is not probed,
  778. * we won't be able to read all needed ability registers.
  779. * So provide it manually.
  780. */
  781. linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
  782. linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported);
  783. linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported);
  784. linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT,
  785. phydev->supported);
  786. return 0;
  787. }
  788. static int dp83td510_probe(struct phy_device *phydev)
  789. {
  790. struct device *dev = &phydev->mdio.dev;
  791. struct dp83td510_priv *priv;
  792. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  793. if (!priv)
  794. return -ENOMEM;
  795. phydev->priv = priv;
  796. return 0;
  797. }
  798. static struct phy_driver dp83td510_driver[] = {
  799. {
  800. PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID),
  801. .name = "TI DP83TD510E",
  802. .flags = PHY_POLL_CABLE_TEST,
  803. .probe = dp83td510_probe,
  804. .config_aneg = dp83td510_config_aneg,
  805. .read_status = dp83td510_read_status,
  806. .get_features = dp83td510_get_features,
  807. .config_intr = dp83td510_config_intr,
  808. .handle_interrupt = dp83td510_handle_interrupt,
  809. .get_sqi = dp83td510_get_sqi,
  810. .get_sqi_max = dp83td510_get_sqi_max,
  811. .cable_test_start = dp83td510_cable_test_start,
  812. .cable_test_get_status = dp83td510_cable_test_get_status,
  813. .get_phy_stats = dp83td510_get_phy_stats,
  814. .update_stats = dp83td510_update_stats,
  815. .get_mse_capability = dp83td510_get_mse_capability,
  816. .get_mse_snapshot = dp83td510_get_mse_snapshot,
  817. .led_brightness_set = dp83td510_led_brightness_set,
  818. .led_hw_is_supported = dp83td510_led_hw_is_supported,
  819. .led_hw_control_set = dp83td510_led_hw_control_set,
  820. .led_hw_control_get = dp83td510_led_hw_control_get,
  821. .led_polarity_set = dp83td510_led_polarity_set,
  822. .suspend = genphy_suspend,
  823. .resume = genphy_resume,
  824. } };
  825. module_phy_driver(dp83td510_driver);
  826. static const struct mdio_device_id __maybe_unused dp83td510_tbl[] = {
  827. { PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID) },
  828. { }
  829. };
  830. MODULE_DEVICE_TABLE(mdio, dp83td510_tbl);
  831. MODULE_DESCRIPTION("Texas Instruments DP83TD510E PHY driver");
  832. MODULE_AUTHOR("Oleksij Rempel <kernel@pengutronix.de>");
  833. MODULE_LICENSE("GPL v2");