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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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, ®Value);
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