1 /*
2  * Copyright 2020-2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_phyar8031.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /*! @brief Defines the PHY AR8031 vendor defined registers. */
15 #define PHY_SPECIFIC_STATUS_REG    0x11U /*!< The PHY specific status register. */
16 #define PHY_COPPERFIBER_STATUS_REG 0x1BU /*!< The PHY copper/fiber status register. */
17 #define PHY_DEBUGPORT_ADDR_REG     0x1DU /*!< The PHY Debug port address register.*/
18 #define PHY_DEBUGPORT_DATA_REG     0x1EU /*!< The PHY Debug port data register.*/
19 #define PHY_CHIP_CFG_REG           0x1FU /*!< The PHY chip configure register. */
20 
21 /*! @brief Defines the Debug register offset. */
22 #define PHY_DEBUG_HIBECTL_REG_OFFSET 0x0BU /*!< The PHY Debug register offset 0xB.*/
23 #define PHY_DEBUG_EXTLOOP_REG_OFFSET 0x11U /*!< The PHY Debug register offset 0x11.*/
24 
25 /*! @brief Defines the PHY AR8031 ID number. */
26 #define PHY_CONTROL_ID1 0x004DU /*!< The PHY ID1 is 0x004D. */
27 
28 /*!@brief Defines the mask flag of operation mode in control two register*/
29 #define PHY_CTL2_REMOTELOOP_MASK    0x0004U /*!< The PHY remote loopback mask. */
30 #define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */
31 #define PHY_CTL1_10HALFDUPLEX_MASK  0x0001U /*!< The PHY 10M half duplex mask. */
32 #define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */
33 #define PHY_CTL1_10FULLDUPLEX_MASK  0x0005U /*!< The PHY 10M full duplex mask. */
34 #define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */
35 
36 /*! @brief Defines the mask flag in specific status register. */
37 #define PHY_SSTATUS_LINKSTATUS_MASK 0x0400U /*!< The PHY link status mask. */
38 #define PHY_SSTATUS_LINKSPEED_MASK  0xC000U /*!< The PHY link speed mask. */
39 #define PHY_SSTATUS_LINKDUPLEX_MASK 0x2000U /*!< The PHY link duplex mask. */
40 #define PHY_SSTATUS_LINKSPEED_SHIFT 14U     /*!< The link speed shift */
41 
42 /*! @brief Defines the mask flag in PHY debug register- hibernate control register. */
43 #define PHY_DEBUG_HIBERNATECTL_REG 0x8000U /*!< The power hibernate control mask. */
44 
45 /*! @brief Defines the PHY MMD access. */
46 #define PHY_MMD_DEVICEID3             3U     /*!< The PHY device id 3. */
47 #define PHY_MMD_REMOTEPHY_LOOP_OFFSET 0x805A /*!< The PHY MMD phy register */
48 #define PHY_MMD_SMARTEEE_CTL_OFFSET   0x805D /*!< The PHY MMD smartEEE register */
49 #define PHY_MMD_SMARTEEE_LPI_EN_SHIFT 8U     /*!< The SmartEEE enable/disable bit shift */
50 /*! @brief Defines the chip configure register. */
51 #define PHY_MODE_CFG_MASK 0xFU /*!< The PHY mode configure mask. */
52 
53 /*! @brief MDIO MMD Devices .*/
54 #define PHY_MDIO_MMD_PCS 3U
55 #define PHY_MDIO_MMD_AN  7U
56 
57 /*! @brief MDIO MMD Physical Coding layer device registers .*/
58 #define PHY_MDIO_PCS_EEE_CAP 0x14U /* EEE capability */
59 
60 /*! @brief MDIO MMD AutoNegotiation device registers .*/
61 #define PHY_MDIO_AN_EEE_ADV 0x3CU /* EEE advertisement */
62 
63 /*! @brief MDIO MMD EEE mask flags. (common for adv and cap) */
64 #define PHY_MDIO_EEE_100TX 0x2U
65 #define PHY_MDIO_EEE_1000T 0x4U
66 
67 /*! @brief Defines the timeout macro. */
68 #define PHY_READID_TIMEOUT_COUNT 1000U
69 
70 /*! @brief Defines the PHY resource interface. */
71 #define PHY_AR8031_WRITE(handle, regAddr, data) \
72     ((phy_ar8031_resource_t *)(handle)->resource)->write((handle)->phyAddr, regAddr, data)
73 #define PHY_AR8031_READ(handle, regAddr, pData) \
74     ((phy_ar8031_resource_t *)(handle)->resource)->read((handle)->phyAddr, regAddr, pData)
75 
76 /*******************************************************************************
77  * Prototypes
78  ******************************************************************************/
79 
80 static status_t PHY_AR8031_MMD_SetDevice(phy_handle_t *handle,
81                                          uint8_t device,
82                                          uint16_t addr,
83                                          phy_mmd_access_mode_t mode);
84 static inline status_t PHY_AR8031_MMD_ReadData(phy_handle_t *handle, uint16_t *data);
85 static inline status_t PHY_AR8031_MMD_WriteData(phy_handle_t *handle, uint16_t data);
86 static status_t PHY_AR8031_MMD_Read(phy_handle_t *handle, uint8_t device, uint16_t addr, uint16_t *data);
87 static status_t PHY_AR8031_MMD_Write(phy_handle_t *handle, uint8_t device, uint16_t addr, uint16_t data);
88 
89 /*******************************************************************************
90  * Variables
91  ******************************************************************************/
92 const phy_operations_t phyar8031_ops = {.phyInit            = PHY_AR8031_Init,
93                                         .phyWrite           = PHY_AR8031_Write,
94                                         .phyRead            = PHY_AR8031_Read,
95                                         .getAutoNegoStatus  = PHY_AR8031_GetAutoNegotiationStatus,
96                                         .getLinkStatus      = PHY_AR8031_GetLinkStatus,
97                                         .getLinkSpeedDuplex = PHY_AR8031_GetLinkSpeedDuplex,
98                                         .setLinkSpeedDuplex = PHY_AR8031_SetLinkSpeedDuplex,
99                                         .enableLoopback     = PHY_AR8031_EnableLoopback};
100 
101 /*******************************************************************************
102  * Code
103  ******************************************************************************/
104 
PHY_AR8031_Init(phy_handle_t * handle,const phy_config_t * config)105 status_t PHY_AR8031_Init(phy_handle_t *handle, const phy_config_t *config)
106 {
107     uint32_t counter  = PHY_READID_TIMEOUT_COUNT;
108     status_t result   = kStatus_Success;
109     uint16_t regValue = 0;
110 
111     /* Assign PHY address and operation resource. */
112     handle->phyAddr  = config->phyAddr;
113     handle->resource = config->resource;
114 
115     /* Check PHY ID. */
116     do
117     {
118         result = PHY_AR8031_READ(handle, PHY_ID1_REG, &regValue);
119         if (result != kStatus_Success)
120         {
121             return result;
122         }
123         counter--;
124     } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U));
125 
126     if (counter == 0U)
127     {
128         return kStatus_Fail;
129     }
130 
131     /* Configure RMII voltage 1.8V */
132     result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_ADDR_REG, 0x1F);
133     if (result != kStatus_Success)
134     {
135         return result;
136     }
137     result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_DATA_REG, 0x8);
138     if (result != kStatus_Success)
139     {
140         return result;
141     }
142 
143     /* Reset PHY. */
144     result = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
145     if (result == kStatus_Success)
146     {
147         /* Close smartEEE. */
148         result = PHY_AR8031_MMD_SetDevice(handle, PHY_MMD_DEVICEID3, PHY_MMD_SMARTEEE_CTL_OFFSET,
149                                           kPHY_MMDAccessNoPostIncrement);
150         if (result == kStatus_Success)
151         {
152             result = PHY_AR8031_MMD_ReadData(handle, &regValue);
153             if (result == kStatus_Success)
154             {
155                 result = PHY_AR8031_MMD_WriteData(handle, (regValue & ~((uint32_t)1 << PHY_MMD_SMARTEEE_LPI_EN_SHIFT)));
156             }
157         }
158         if (result != kStatus_Success)
159         {
160             return result;
161         }
162 
163         /* Enable Tx clock delay */
164         result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_ADDR_REG, 0x5);
165         if (result != kStatus_Success)
166         {
167             return result;
168         }
169         result = PHY_AR8031_READ(handle, PHY_DEBUGPORT_DATA_REG, &regValue);
170         if (result != kStatus_Success)
171         {
172             return result;
173         }
174         result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_DATA_REG, regValue | 0x0100U);
175         if (result != kStatus_Success)
176         {
177             return result;
178         }
179 
180         /* Enable Rx clock delay */
181         result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_ADDR_REG, 0x0);
182         if (result != kStatus_Success)
183         {
184             return result;
185         }
186         result = PHY_AR8031_READ(handle, PHY_DEBUGPORT_DATA_REG, &regValue);
187         if (result != kStatus_Success)
188         {
189             return result;
190         }
191         result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_DATA_REG, regValue | 0x8000U);
192         if (result != kStatus_Success)
193         {
194             return result;
195         }
196 
197         /* Energy Efficient Ethernet config */
198         if (config->enableEEE)
199         {
200             /* Get capabilities */
201             result = PHY_AR8031_MMD_Read(handle, PHY_MDIO_MMD_PCS, PHY_MDIO_PCS_EEE_CAP, &regValue);
202             if (result == kStatus_Success)
203             {
204                 /* Enable EEE for 100TX and 1000T */
205                 result = PHY_AR8031_MMD_Write(handle, PHY_MDIO_MMD_AN, PHY_MDIO_AN_EEE_ADV,
206                                               regValue & (PHY_MDIO_EEE_1000T | PHY_MDIO_EEE_100TX));
207             }
208         }
209         else
210         {
211             result = PHY_AR8031_MMD_Write(handle, PHY_MDIO_MMD_AN, PHY_MDIO_AN_EEE_ADV, 0);
212         }
213         if (result != kStatus_Success)
214         {
215             return result;
216         }
217 
218         if (config->autoNeg)
219         {
220             /* Set the negotiation. */
221             result = PHY_AR8031_WRITE(handle, PHY_AUTONEG_ADVERTISE_REG,
222                                       PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
223                                           PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK |
224                                           PHY_IEEE802_3_SELECTOR_MASK);
225             if (result == kStatus_Success)
226             {
227                 result = PHY_AR8031_WRITE(handle, PHY_1000BASET_CONTROL_REG,
228                                           PHY_1000BASET_FULLDUPLEX_MASK | PHY_1000BASET_HALFDUPLEX_MASK);
229                 if (result == kStatus_Success)
230                 {
231                     result = PHY_AR8031_READ(handle, PHY_BASICCONTROL_REG, &regValue);
232                     if (result != kStatus_Success)
233                     {
234                         return result;
235                     }
236                     result = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG,
237                                               regValue | PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK);
238                 }
239             }
240         }
241         else
242         {
243             /* Disable isolate mode. */
244             result = PHY_AR8031_READ(handle, PHY_BASICCONTROL_REG, &regValue);
245             if (result != kStatus_Success)
246             {
247                 return result;
248             }
249             result = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG, regValue & ~PHY_BCTL_ISOLATE_MASK);
250             if (result != kStatus_Success)
251             {
252                 return result;
253             }
254 
255             /* Disable the auto-negotiation and set user-defined speed/duplex configuration. */
256             result = PHY_AR8031_SetLinkSpeedDuplex(handle, config->speed, config->duplex);
257         }
258     }
259 
260     return result;
261 }
262 
PHY_AR8031_Write(phy_handle_t * handle,uint8_t phyReg,uint16_t data)263 status_t PHY_AR8031_Write(phy_handle_t *handle, uint8_t phyReg, uint16_t data)
264 {
265     return PHY_AR8031_WRITE(handle, phyReg, data);
266 }
267 
PHY_AR8031_Read(phy_handle_t * handle,uint8_t phyReg,uint16_t * pData)268 status_t PHY_AR8031_Read(phy_handle_t *handle, uint8_t phyReg, uint16_t *pData)
269 {
270     return PHY_AR8031_READ(handle, phyReg, pData);
271 }
272 
PHY_AR8031_GetAutoNegotiationStatus(phy_handle_t * handle,bool * status)273 status_t PHY_AR8031_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status)
274 {
275     assert(status);
276 
277     status_t result;
278     uint16_t regValue;
279 
280     *status = false;
281 
282     /* Check auto negotiation complete. */
283     result = PHY_AR8031_READ(handle, PHY_BASICSTATUS_REG, &regValue);
284     if (result == kStatus_Success)
285     {
286         if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U)
287         {
288             *status = true;
289         }
290     }
291     return result;
292 }
293 
PHY_AR8031_GetLinkStatus(phy_handle_t * handle,bool * status)294 status_t PHY_AR8031_GetLinkStatus(phy_handle_t *handle, bool *status)
295 {
296     assert(status);
297 
298     status_t result = kStatus_Success;
299     uint16_t regValue;
300 
301     /* Read the basic status register. */
302     result = PHY_AR8031_READ(handle, PHY_SPECIFIC_STATUS_REG, &regValue);
303     if (result == kStatus_Success)
304     {
305         if ((PHY_SSTATUS_LINKSTATUS_MASK & regValue) != 0U)
306         {
307             /* Link up. */
308             *status = true;
309         }
310         else
311         {
312             /* Link down. */
313             *status = false;
314         }
315     }
316     return result;
317 }
318 
PHY_AR8031_GetLinkSpeedDuplex(phy_handle_t * handle,phy_speed_t * speed,phy_duplex_t * duplex)319 status_t PHY_AR8031_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex)
320 {
321     assert(!((speed == NULL) && (duplex == NULL)));
322 
323     status_t result;
324     uint16_t regValue;
325 
326     /* Read the specfic status register. */
327     result = PHY_AR8031_READ(handle, PHY_SPECIFIC_STATUS_REG, &regValue);
328     if (result == kStatus_Success)
329     {
330         if (speed != NULL)
331         {
332             switch ((regValue & PHY_SSTATUS_LINKSPEED_MASK) >> PHY_SSTATUS_LINKSPEED_SHIFT)
333             {
334                 case (uint32_t)kPHY_Speed10M:
335                     *speed = kPHY_Speed10M;
336                     break;
337                 case (uint32_t)kPHY_Speed100M:
338                     *speed = kPHY_Speed100M;
339                     break;
340                 case (uint32_t)kPHY_Speed1000M:
341                     *speed = kPHY_Speed1000M;
342                     break;
343                 default:
344                     *speed = kPHY_Speed10M;
345                     break;
346             }
347         }
348 
349         if (duplex != NULL)
350         {
351             if ((regValue & PHY_SSTATUS_LINKDUPLEX_MASK) != 0U)
352             {
353                 *duplex = kPHY_FullDuplex;
354             }
355             else
356             {
357                 *duplex = kPHY_HalfDuplex;
358             }
359         }
360     }
361 
362     return result;
363 }
364 
PHY_AR8031_SetLinkSpeedDuplex(phy_handle_t * handle,phy_speed_t speed,phy_duplex_t duplex)365 status_t PHY_AR8031_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex)
366 {
367     status_t result;
368     uint16_t regValue;
369 
370     result = PHY_AR8031_READ(handle, PHY_BASICCONTROL_REG, &regValue);
371     if (result == kStatus_Success)
372     {
373         /* Disable the auto-negotiation and set according to user-defined configuration. */
374         regValue &= ~PHY_BCTL_AUTONEG_MASK;
375         if (speed == kPHY_Speed1000M)
376         {
377             regValue &= PHY_BCTL_SPEED0_MASK;
378             regValue |= PHY_BCTL_SPEED1_MASK;
379         }
380         else if (speed == kPHY_Speed100M)
381         {
382             regValue |= PHY_BCTL_SPEED0_MASK;
383             regValue &= ~PHY_BCTL_SPEED1_MASK;
384         }
385         else
386         {
387             regValue &= ~PHY_BCTL_SPEED0_MASK;
388             regValue &= ~PHY_BCTL_SPEED1_MASK;
389         }
390         if (duplex == kPHY_FullDuplex)
391         {
392             regValue |= PHY_BCTL_DUPLEX_MASK;
393         }
394         else
395         {
396             regValue &= ~PHY_BCTL_DUPLEX_MASK;
397         }
398         result = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG, regValue);
399     }
400     return result;
401 }
402 
PHY_AR8031_EnableLoopback(phy_handle_t * handle,phy_loop_t mode,phy_speed_t speed,bool enable)403 status_t PHY_AR8031_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable)
404 {
405     status_t result;
406     uint16_t regValue;
407 
408     /* Set the loop mode. */
409     if (enable)
410     {
411         if (mode == kPHY_LocalLoop)
412         {
413             if (speed == kPHY_Speed1000M)
414             {
415                 regValue = PHY_BCTL_SPEED1_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
416             }
417             else if (speed == kPHY_Speed100M)
418             {
419                 regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
420             }
421             else
422             {
423                 regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
424             }
425             result = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG, regValue);
426         }
427         else if (mode == kPHY_RemoteLoop)
428         {
429             result = PHY_AR8031_MMD_Write(handle, PHY_MMD_DEVICEID3, PHY_MMD_REMOTEPHY_LOOP_OFFSET, 1);
430         }
431         else
432         {
433             result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_ADDR_REG, PHY_DEBUG_HIBECTL_REG_OFFSET);
434             if (result == kStatus_Success)
435             {
436                 result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_DATA_REG, 0);
437                 if (result == kStatus_Success)
438                 {
439                     result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_ADDR_REG, PHY_DEBUG_EXTLOOP_REG_OFFSET);
440                     if (result == kStatus_Success)
441                     {
442                         result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_DATA_REG, 1);
443                         if (result == kStatus_Success)
444                         {
445                             if (speed == kPHY_Speed1000M)
446                             {
447                                 regValue = PHY_BCTL_SPEED1_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_RESET_MASK;
448                             }
449                             else if (speed == kPHY_Speed100M)
450                             {
451                                 regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_RESET_MASK;
452                             }
453                             else
454                             {
455                                 regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_RESET_MASK;
456                             }
457                             result = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG, regValue);
458                         }
459                     }
460                 }
461             }
462         }
463     }
464     else
465     {
466         /* Disable the loop mode. */
467         if (mode == kPHY_LocalLoop)
468         {
469             /* First read the current status in control register. */
470             result = PHY_AR8031_READ(handle, PHY_BASICCONTROL_REG, &regValue);
471             if (result == kStatus_Success)
472             {
473                 regValue &= ~PHY_BCTL_LOOP_MASK;
474                 result = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG, regValue | PHY_BCTL_RESTART_AUTONEG_MASK);
475             }
476         }
477         else if (mode == kPHY_RemoteLoop)
478         {
479             result = PHY_AR8031_MMD_Write(handle, PHY_MMD_DEVICEID3, PHY_MMD_REMOTEPHY_LOOP_OFFSET, 0);
480         }
481         else
482         {
483             result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_ADDR_REG, PHY_DEBUG_HIBECTL_REG_OFFSET);
484             if (result == kStatus_Success)
485             {
486                 result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_DATA_REG, 0);
487                 if (result == kStatus_Success)
488                 {
489                     result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_ADDR_REG, PHY_DEBUG_EXTLOOP_REG_OFFSET);
490                     if (result == kStatus_Success)
491                     {
492                         result = PHY_AR8031_WRITE(handle, PHY_DEBUGPORT_DATA_REG, 0);
493                         if (result == kStatus_Success)
494                         {
495                             regValue = PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESET_MASK;
496                             result   = PHY_AR8031_WRITE(handle, PHY_BASICCONTROL_REG, regValue);
497                         }
498                     }
499                 }
500             }
501         }
502     }
503     return result;
504 }
505 
PHY_AR8031_MMD_SetDevice(phy_handle_t * handle,uint8_t device,uint16_t addr,phy_mmd_access_mode_t mode)506 static status_t PHY_AR8031_MMD_SetDevice(phy_handle_t *handle,
507                                          uint8_t device,
508                                          uint16_t addr,
509                                          phy_mmd_access_mode_t mode)
510 {
511     status_t result = kStatus_Success;
512 
513     /* Set Function mode of address access(b00) and device address. */
514     result = PHY_AR8031_WRITE(handle, PHY_MMD_ACCESS_CONTROL_REG, device);
515     if (result != kStatus_Success)
516     {
517         return result;
518     }
519 
520     /* Set register address. */
521     result = PHY_AR8031_WRITE(handle, PHY_MMD_ACCESS_DATA_REG, addr);
522     if (result != kStatus_Success)
523     {
524         return result;
525     }
526 
527     /* Set Function mode of data access(b01~11) and device address. */
528     result = PHY_AR8031_WRITE(handle, PHY_MMD_ACCESS_CONTROL_REG, (uint16_t)mode | (uint16_t)device);
529     return result;
530 }
531 
PHY_AR8031_MMD_ReadData(phy_handle_t * handle,uint16_t * data)532 static inline status_t PHY_AR8031_MMD_ReadData(phy_handle_t *handle, uint16_t *data)
533 {
534     return PHY_AR8031_READ(handle, PHY_MMD_ACCESS_DATA_REG, data);
535 }
536 
PHY_AR8031_MMD_WriteData(phy_handle_t * handle,uint16_t data)537 static inline status_t PHY_AR8031_MMD_WriteData(phy_handle_t *handle, uint16_t data)
538 {
539     return PHY_AR8031_WRITE(handle, PHY_MMD_ACCESS_DATA_REG, data);
540 }
541 
PHY_AR8031_MMD_Read(phy_handle_t * handle,uint8_t device,uint16_t addr,uint16_t * data)542 static status_t PHY_AR8031_MMD_Read(phy_handle_t *handle, uint8_t device, uint16_t addr, uint16_t *data)
543 {
544     status_t result = kStatus_Success;
545     result          = PHY_AR8031_MMD_SetDevice(handle, device, addr, kPHY_MMDAccessNoPostIncrement);
546     if (result == kStatus_Success)
547     {
548         result = PHY_AR8031_MMD_ReadData(handle, data);
549     }
550     return result;
551 }
552 
PHY_AR8031_MMD_Write(phy_handle_t * handle,uint8_t device,uint16_t addr,uint16_t data)553 static status_t PHY_AR8031_MMD_Write(phy_handle_t *handle, uint8_t device, uint16_t addr, uint16_t data)
554 {
555     status_t result = kStatus_Success;
556 
557     result = PHY_AR8031_MMD_SetDevice(handle, device, addr, kPHY_MMDAccessNoPostIncrement);
558     if (result == kStatus_Success)
559     {
560         result = PHY_AR8031_MMD_WriteData(handle, data);
561     }
562     return result;
563 }
564