aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/components/phy/device/phyar8031/fsl_phyar8031.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/components/phy/device/phyar8031/fsl_phyar8031.c')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/components/phy/device/phyar8031/fsl_phyar8031.c566
1 files changed, 566 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/phy/device/phyar8031/fsl_phyar8031.c b/lib/chibios-contrib/ext/mcux-sdk/components/phy/device/phyar8031/fsl_phyar8031.c
new file mode 100644
index 000000000..8fd5d09ce
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/components/phy/device/phyar8031/fsl_phyar8031.c
@@ -0,0 +1,566 @@
1/*
2 * Copyright 2020 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/*******************************************************************************
71 * Prototypes
72 ******************************************************************************/
73
74static status_t PHY_AR8031_MMD_SetDevice(phy_handle_t *handle,
75 uint8_t device,
76 uint16_t addr,
77 phy_mmd_access_mode_t mode);
78static inline status_t PHY_AR8031_MMD_ReadData(phy_handle_t *handle, uint32_t *data);
79static inline status_t PHY_AR8031_MMD_WriteData(phy_handle_t *handle, uint32_t data);
80static status_t PHY_AR8031_MMD_Read(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t *data);
81static status_t PHY_AR8031_MMD_Write(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t data);
82
83/*******************************************************************************
84 * Variables
85 ******************************************************************************/
86const phy_operations_t phyar8031_ops = {.phyInit = PHY_AR8031_Init,
87 .phyWrite = PHY_AR8031_Write,
88 .phyRead = PHY_AR8031_Read,
89 .getAutoNegoStatus = PHY_AR8031_GetAutoNegotiationStatus,
90 .getLinkStatus = PHY_AR8031_GetLinkStatus,
91 .getLinkSpeedDuplex = PHY_AR8031_GetLinkSpeedDuplex,
92 .setLinkSpeedDuplex = PHY_AR8031_SetLinkSpeedDuplex,
93 .enableLoopback = PHY_AR8031_EnableLoopback};
94
95/*******************************************************************************
96 * Code
97 ******************************************************************************/
98
99status_t PHY_AR8031_Init(phy_handle_t *handle, const phy_config_t *config)
100{
101 uint32_t counter = PHY_READID_TIMEOUT_COUNT;
102 status_t result = kStatus_Success;
103 uint32_t regValue = 0;
104
105 /* Init MDIO interface. */
106 MDIO_Init(handle->mdioHandle);
107
108 /* Assign phy address. */
109 handle->phyAddr = config->phyAddr;
110
111 /* Check PHY ID. */
112 do
113 {
114 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, &regValue);
115 if (result != kStatus_Success)
116 {
117 return result;
118 }
119 counter--;
120 } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U));
121
122 if (counter == 0U)
123 {
124 return kStatus_Fail;
125 }
126
127 /* Configure RMII voltage 1.8V */
128 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_ADDR_REG, 0x1F);
129 if (result != kStatus_Success)
130 {
131 return result;
132 }
133 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, 0x8);
134 if (result != kStatus_Success)
135 {
136 return result;
137 }
138
139 /* Reset PHY. */
140 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
141 if (result == kStatus_Success)
142 {
143 /* Close smartEEE. */
144 result = PHY_AR8031_MMD_SetDevice(handle, PHY_MMD_DEVICEID3, PHY_MMD_SMARTEEE_CTL_OFFSET,
145 kPHY_MMDAccessNoPostIncrement);
146 if (result == kStatus_Success)
147 {
148 result = PHY_AR8031_MMD_ReadData(handle, &regValue);
149 if (result == kStatus_Success)
150 {
151 result = PHY_AR8031_MMD_WriteData(handle, (regValue & ~((uint32_t)1 << PHY_MMD_SMARTEEE_LPI_EN_SHIFT)));
152 }
153 }
154 if (result != kStatus_Success)
155 {
156 return result;
157 }
158
159 /* Enable Tx clock delay */
160 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_ADDR_REG, 0x5);
161 if (result != kStatus_Success)
162 {
163 return result;
164 }
165 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, &regValue);
166 if (result != kStatus_Success)
167 {
168 return result;
169 }
170 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, (regValue | 0x0100U));
171 if (result != kStatus_Success)
172 {
173 return result;
174 }
175
176 /* Enable Rx clock delay */
177 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_ADDR_REG, 0x0);
178 if (result != kStatus_Success)
179 {
180 return result;
181 }
182 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, &regValue);
183 if (result != kStatus_Success)
184 {
185 return result;
186 }
187 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, (regValue | 0x8000U));
188 if (result != kStatus_Success)
189 {
190 return result;
191 }
192
193 /* Energy Efficient Ethernet config */
194 if (config->enableEEE)
195 {
196 /* Get capabilities */
197 result = PHY_AR8031_MMD_Read(handle, PHY_MDIO_MMD_PCS, PHY_MDIO_PCS_EEE_CAP, &regValue);
198 if (result == kStatus_Success)
199 {
200 /* Enable EEE for 100TX and 1000T */
201 result = PHY_AR8031_MMD_Write(handle, PHY_MDIO_MMD_AN, PHY_MDIO_AN_EEE_ADV,
202 regValue & (PHY_MDIO_EEE_1000T | PHY_MDIO_EEE_100TX));
203 }
204 }
205 else
206 {
207 result = PHY_AR8031_MMD_Write(handle, PHY_MDIO_MMD_AN, PHY_MDIO_AN_EEE_ADV, 0);
208 }
209 if (result != kStatus_Success)
210 {
211 return result;
212 }
213
214 if (config->autoNeg)
215 {
216 /* Set the negotiation. */
217 result =
218 MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG,
219 (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
220 PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK));
221 if (result == kStatus_Success)
222 {
223 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_1000BASET_CONTROL_REG,
224 PHY_1000BASET_FULLDUPLEX_MASK | PHY_1000BASET_HALFDUPLEX_MASK);
225 if (result == kStatus_Success)
226 {
227 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
228 if (result != kStatus_Success)
229 {
230 return result;
231 }
232 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
233 (regValue | PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
234 }
235 }
236 }
237 else
238 {
239 /* Disable isolate mode */
240 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
241 if (result != kStatus_Success)
242 {
243 return result;
244 }
245 regValue &= ~PHY_BCTL_ISOLATE_MASK;
246 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
247 if (result != kStatus_Success)
248 {
249 return result;
250 }
251
252 /* Disable the auto-negotiation and set user-defined speed/duplex configuration. */
253 result = PHY_AR8031_SetLinkSpeedDuplex(handle, config->speed, config->duplex);
254 }
255 }
256
257 return result;
258}
259
260status_t PHY_AR8031_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data)
261{
262 return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data);
263}
264
265status_t PHY_AR8031_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr)
266{
267 return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr);
268}
269
270status_t PHY_AR8031_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status)
271{
272 assert(status);
273
274 status_t result;
275 uint32_t regValue;
276
277 *status = false;
278
279 /* Check auto negotiation complete. */
280 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, &regValue);
281 if (result == kStatus_Success)
282 {
283 if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U)
284 {
285 *status = true;
286 }
287 }
288 return result;
289}
290
291status_t PHY_AR8031_GetLinkStatus(phy_handle_t *handle, bool *status)
292{
293 assert(status);
294
295 status_t result = kStatus_Success;
296 uint32_t regValue;
297
298 /* Read the basic status register. */
299 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, &regValue);
300 if (result == kStatus_Success)
301 {
302 if ((PHY_SSTATUS_LINKSTATUS_MASK & regValue) != 0U)
303 {
304 /* Link up. */
305 *status = true;
306 }
307 else
308 {
309 /* Link down. */
310 *status = false;
311 }
312 }
313 return result;
314}
315
316status_t PHY_AR8031_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex)
317{
318 assert(!((speed == NULL) && (duplex == NULL)));
319
320 status_t result;
321 uint32_t regValue;
322
323 /* Read the specfic status register. */
324 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, &regValue);
325 if (result == kStatus_Success)
326 {
327 if (speed != NULL)
328 {
329 switch ((regValue & PHY_SSTATUS_LINKSPEED_MASK) >> PHY_SSTATUS_LINKSPEED_SHIFT)
330 {
331 case (uint32_t)kPHY_Speed10M:
332 *speed = kPHY_Speed10M;
333 break;
334 case (uint32_t)kPHY_Speed100M:
335 *speed = kPHY_Speed100M;
336 break;
337 case (uint32_t)kPHY_Speed1000M:
338 *speed = kPHY_Speed1000M;
339 break;
340 default:
341 *speed = kPHY_Speed10M;
342 break;
343 }
344 }
345
346 if (duplex != NULL)
347 {
348 if ((regValue & PHY_SSTATUS_LINKDUPLEX_MASK) != 0U)
349 {
350 *duplex = kPHY_FullDuplex;
351 }
352 else
353 {
354 *duplex = kPHY_HalfDuplex;
355 }
356 }
357 }
358
359 return result;
360}
361
362status_t PHY_AR8031_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex)
363{
364 status_t result;
365 uint32_t regValue;
366
367 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
368 if (result == kStatus_Success)
369 {
370 /* Disable the auto-negotiation and set according to user-defined configuration. */
371 regValue &= ~PHY_BCTL_AUTONEG_MASK;
372 if (speed == kPHY_Speed1000M)
373 {
374 regValue &= PHY_BCTL_SPEED0_MASK;
375 regValue |= PHY_BCTL_SPEED1_MASK;
376 }
377 else if (speed == kPHY_Speed100M)
378 {
379 regValue |= PHY_BCTL_SPEED0_MASK;
380 regValue &= ~PHY_BCTL_SPEED1_MASK;
381 }
382 else
383 {
384 regValue &= ~PHY_BCTL_SPEED0_MASK;
385 regValue &= ~PHY_BCTL_SPEED1_MASK;
386 }
387 if (duplex == kPHY_FullDuplex)
388 {
389 regValue |= PHY_BCTL_DUPLEX_MASK;
390 }
391 else
392 {
393 regValue &= ~PHY_BCTL_DUPLEX_MASK;
394 }
395 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
396 }
397 return result;
398}
399
400status_t PHY_AR8031_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable)
401{
402 status_t result;
403 uint32_t regValue;
404
405 /* Set the loop mode. */
406 if (enable)
407 {
408 if (mode == kPHY_LocalLoop)
409 {
410 if (speed == kPHY_Speed1000M)
411 {
412 regValue = PHY_BCTL_SPEED1_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
413 }
414 else if (speed == kPHY_Speed100M)
415 {
416 regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
417 }
418 else
419 {
420 regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
421 }
422 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
423 }
424 else if (mode == kPHY_RemoteLoop)
425 {
426 result = PHY_AR8031_MMD_Write(handle, PHY_MMD_DEVICEID3, PHY_MMD_REMOTEPHY_LOOP_OFFSET, 1);
427 }
428 else
429 {
430 result =
431 MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_ADDR_REG, PHY_DEBUG_HIBECTL_REG_OFFSET);
432 if (result == kStatus_Success)
433 {
434 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, 0);
435 if (result == kStatus_Success)
436 {
437 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_ADDR_REG,
438 PHY_DEBUG_EXTLOOP_REG_OFFSET);
439 if (result == kStatus_Success)
440 {
441 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, 1);
442 if (result == kStatus_Success)
443 {
444 if (speed == kPHY_Speed1000M)
445 {
446 regValue = PHY_BCTL_SPEED1_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_RESET_MASK;
447 }
448 else if (speed == kPHY_Speed100M)
449 {
450 regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_RESET_MASK;
451 }
452 else
453 {
454 regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_RESET_MASK;
455 }
456 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
457 }
458 }
459 }
460 }
461 }
462 }
463 else
464 {
465 /* Disable the loop mode. */
466 if (mode == kPHY_LocalLoop)
467 {
468 /* First read the current status in control register. */
469 result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
470 if (result == kStatus_Success)
471 {
472 regValue &= ~PHY_BCTL_LOOP_MASK;
473 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
474 (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 =
484 MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_ADDR_REG, PHY_DEBUG_HIBECTL_REG_OFFSET);
485 if (result == kStatus_Success)
486 {
487 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, 0);
488 if (result == kStatus_Success)
489 {
490 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_ADDR_REG,
491 PHY_DEBUG_EXTLOOP_REG_OFFSET);
492 if (result == kStatus_Success)
493 {
494 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_DEBUGPORT_DATA_REG, 0);
495 if (result == kStatus_Success)
496 {
497 regValue = PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESET_MASK;
498 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
499 }
500 }
501 }
502 }
503 }
504 }
505 return result;
506}
507
508static status_t PHY_AR8031_MMD_SetDevice(phy_handle_t *handle,
509 uint8_t device,
510 uint16_t addr,
511 phy_mmd_access_mode_t mode)
512{
513 status_t result = kStatus_Success;
514
515 /* Set Function mode of address access(b00) and device address. */
516 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_CONTROL_REG, device);
517 if (result != kStatus_Success)
518 {
519 return result;
520 }
521
522 /* Set register address. */
523 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_DATA_REG, addr);
524 if (result != kStatus_Success)
525 {
526 return result;
527 }
528
529 /* Set Function mode of data access(b01~11) and device address. */
530 result =
531 MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_CONTROL_REG, (uint32_t)mode | (uint32_t)device);
532 return result;
533}
534
535static inline status_t PHY_AR8031_MMD_ReadData(phy_handle_t *handle, uint32_t *data)
536{
537 return MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_DATA_REG, data);
538}
539
540static inline status_t PHY_AR8031_MMD_WriteData(phy_handle_t *handle, uint32_t data)
541{
542 return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_MMD_ACCESS_DATA_REG, data);
543}
544
545static status_t PHY_AR8031_MMD_Read(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t *data)
546{
547 status_t result = kStatus_Success;
548 result = PHY_AR8031_MMD_SetDevice(handle, device, addr, kPHY_MMDAccessNoPostIncrement);
549 if (result == kStatus_Success)
550 {
551 result = PHY_AR8031_MMD_ReadData(handle, data);
552 }
553 return result;
554}
555
556static status_t PHY_AR8031_MMD_Write(phy_handle_t *handle, uint8_t device, uint16_t addr, uint32_t data)
557{
558 status_t result = kStatus_Success;
559
560 result = PHY_AR8031_MMD_SetDevice(handle, device, addr, kPHY_MMDAccessNoPostIncrement);
561 if (result == kStatus_Success)
562 {
563 result = PHY_AR8031_MMD_WriteData(handle, data);
564 }
565 return result;
566}