2 * Copyright (C) 2013 Realtek Semiconductor Corp.
5 * Unless you and Realtek execute a separate written software license
6 * agreement governing use of this software, this software is licensed
7 * to you under the terms of the GNU General Public License version 2,
8 * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
11 * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $
13 * Purpose : RTL8367C switch high-level API for RTL8367C
14 * Feature : PHY related functions
17 #include <rtl8367c_asicdrv_phy.h>
19 #if defined(MDC_MDIO_OPERATION)
21 * rtl8367c_setAsicPHYOCPReg
23 * Set PHY OCP registers
25 * phyNo - Physical port number (0~7)
26 * ocpAddr - OCP address
27 * ocpData - Writing data
32 * RT_ERR_SMI - SMI access error
33 * RT_ERR_PHY_REG_ID - invalid PHY address
34 * RT_ERR_PHY_ID - invalid PHY no
35 * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
39 ret_t
rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo
, rtk_uint32 ocpAddr
, rtk_uint32 ocpData
)
43 rtk_uint32 ocpAddrPrefix
, ocpAddr9_6
, ocpAddr5_1
;
46 ocpAddrPrefix
= ((ocpAddr
& 0xFC00) >> 10);
47 if((retVal
= rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0
, RTL8367C_CFG_CPU_OCPADR_MSB_MASK
, ocpAddrPrefix
)) != RT_ERR_OK
)
50 /*prepare access address*/
51 ocpAddr9_6
= ((ocpAddr
>> 6) & 0x000F);
52 ocpAddr5_1
= ((ocpAddr
>> 1) & 0x001F);
53 regAddr
= RTL8367C_PHY_BASE
| (ocpAddr9_6
<< 8) | (phyNo
<< RTL8367C_PHY_OFFSET
) | ocpAddr5_1
;
54 if((retVal
= rtl8367c_setAsicReg(regAddr
, ocpData
)) != RT_ERR_OK
)
61 * rtl8367c_getAsicPHYOCPReg
63 * Get PHY OCP registers
65 * phyNo - Physical port number (0~7)
66 * ocpAddr - PHY address
67 * pRegData - read data
72 * RT_ERR_SMI - SMI access error
73 * RT_ERR_PHY_REG_ID - invalid PHY address
74 * RT_ERR_PHY_ID - invalid PHY no
75 * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
79 ret_t
rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo
, rtk_uint32 ocpAddr
, rtk_uint32
*pRegData
)
83 rtk_uint32 ocpAddrPrefix
, ocpAddr9_6
, ocpAddr5_1
;
85 ocpAddrPrefix
= ((ocpAddr
& 0xFC00) >> 10);
86 if((retVal
= rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0
, RTL8367C_CFG_CPU_OCPADR_MSB_MASK
, ocpAddrPrefix
)) != RT_ERR_OK
)
89 /*prepare access address*/
90 ocpAddr9_6
= ((ocpAddr
>> 6) & 0x000F);
91 ocpAddr5_1
= ((ocpAddr
>> 1) & 0x001F);
92 regAddr
= RTL8367C_PHY_BASE
| (ocpAddr9_6
<< 8) | (phyNo
<< RTL8367C_PHY_OFFSET
) | ocpAddr5_1
;
93 if((retVal
= rtl8367c_getAsicReg(regAddr
, pRegData
)) != RT_ERR_OK
)
102 * rtl8367c_setAsicPHYOCPReg
104 * Set PHY OCP registers
106 * phyNo - Physical port number (0~7)
107 * ocpAddr - OCP address
108 * ocpData - Writing data
112 * RT_ERR_OK - Success
113 * RT_ERR_SMI - SMI access error
114 * RT_ERR_PHY_REG_ID - invalid PHY address
115 * RT_ERR_PHY_ID - invalid PHY no
116 * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
120 ret_t
rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo
, rtk_uint32 ocpAddr
, rtk_uint32 ocpData
)
124 rtk_uint32 busyFlag
, checkCounter
;
125 rtk_uint32 ocpAddrPrefix
, ocpAddr9_6
, ocpAddr5_1
;
127 /*Check internal phy access busy or not*/
128 /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/
129 retVal
= rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS
,&busyFlag
);
130 if(retVal
!= RT_ERR_OK
)
134 return RT_ERR_BUSYWAIT_TIMEOUT
;
137 ocpAddrPrefix
= ((ocpAddr
& 0xFC00) >> 10);
138 if((retVal
= rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0
, RTL8367C_CFG_CPU_OCPADR_MSB_MASK
, ocpAddrPrefix
)) != RT_ERR_OK
)
141 /*prepare access data*/
142 retVal
= rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA
, ocpData
);
143 if(retVal
!= RT_ERR_OK
)
146 /*prepare access address*/
147 ocpAddr9_6
= ((ocpAddr
>> 6) & 0x000F);
148 ocpAddr5_1
= ((ocpAddr
>> 1) & 0x001F);
149 regData
= RTL8367C_PHY_BASE
| (ocpAddr9_6
<< 8) | (phyNo
<< RTL8367C_PHY_OFFSET
) | ocpAddr5_1
;
150 retVal
= rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS
, regData
);
151 if(retVal
!= RT_ERR_OK
)
154 /*Set WRITE Command*/
155 retVal
= rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL
, RTL8367C_CMD_MASK
| RTL8367C_RW_MASK
);
160 retVal
= rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS
,&busyFlag
);
161 if((retVal
!= RT_ERR_OK
) || busyFlag
)
164 if(0 == checkCounter
)
165 return RT_ERR_BUSYWAIT_TIMEOUT
;
176 * rtl8367c_getAsicPHYOCPReg
178 * Get PHY OCP registers
180 * phyNo - Physical port number (0~7)
181 * ocpAddr - PHY address
182 * pRegData - read data
186 * RT_ERR_OK - Success
187 * RT_ERR_SMI - SMI access error
188 * RT_ERR_PHY_REG_ID - invalid PHY address
189 * RT_ERR_PHY_ID - invalid PHY no
190 * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
194 ret_t
rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo
, rtk_uint32 ocpAddr
, rtk_uint32
*pRegData
)
198 rtk_uint32 busyFlag
,checkCounter
;
199 rtk_uint32 ocpAddrPrefix
, ocpAddr9_6
, ocpAddr5_1
;
200 /*Check internal phy access busy or not*/
201 /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/
202 retVal
= rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS
,&busyFlag
);
203 if(retVal
!= RT_ERR_OK
)
207 return RT_ERR_BUSYWAIT_TIMEOUT
;
210 ocpAddrPrefix
= ((ocpAddr
& 0xFC00) >> 10);
211 if((retVal
= rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0
, RTL8367C_CFG_CPU_OCPADR_MSB_MASK
, ocpAddrPrefix
)) != RT_ERR_OK
)
214 /*prepare access address*/
215 ocpAddr9_6
= ((ocpAddr
>> 6) & 0x000F);
216 ocpAddr5_1
= ((ocpAddr
>> 1) & 0x001F);
217 regData
= RTL8367C_PHY_BASE
| (ocpAddr9_6
<< 8) | (phyNo
<< RTL8367C_PHY_OFFSET
) | ocpAddr5_1
;
218 retVal
= rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS
, regData
);
219 if(retVal
!= RT_ERR_OK
)
223 retVal
= rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL
, RTL8367C_CMD_MASK
);
224 if(retVal
!= RT_ERR_OK
)
230 retVal
= rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS
,&busyFlag
);
231 if((retVal
!= RT_ERR_OK
) || busyFlag
)
234 if(0 == checkCounter
)
235 return RT_ERR_FAILED
;
244 retVal
= rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_READ_DATA
, ®Data
);
245 if(retVal
!= RT_ERR_OK
)
256 * rtl8367c_setAsicPHYReg
260 * phyNo - Physical port number (0~7)
261 * phyAddr - PHY address (0~31)
262 * phyData - Writing data
266 * RT_ERR_OK - Success
267 * RT_ERR_SMI - SMI access error
268 * RT_ERR_PHY_REG_ID - invalid PHY address
269 * RT_ERR_PHY_ID - invalid PHY no
270 * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
274 ret_t
rtl8367c_setAsicPHYReg(rtk_uint32 phyNo
, rtk_uint32 phyAddr
, rtk_uint32 phyData
)
278 if(phyAddr
> RTL8367C_PHY_REGNOMAX
)
279 return RT_ERR_PHY_REG_ID
;
281 ocp_addr
= 0xa400 + phyAddr
*2;
283 return rtl8367c_setAsicPHYOCPReg(phyNo
, ocp_addr
, phyData
);
286 * rtl8367c_getAsicPHYReg
290 * phyNo - Physical port number (0~7)
291 * phyAddr - PHY address (0~31)
292 * pRegData - Writing data
296 * RT_ERR_OK - Success
297 * RT_ERR_SMI - SMI access error
298 * RT_ERR_PHY_REG_ID - invalid PHY address
299 * RT_ERR_PHY_ID - invalid PHY no
300 * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
304 ret_t
rtl8367c_getAsicPHYReg(rtk_uint32 phyNo
, rtk_uint32 phyAddr
, rtk_uint32
*pRegData
)
308 if(phyAddr
> RTL8367C_PHY_REGNOMAX
)
309 return RT_ERR_PHY_REG_ID
;
311 ocp_addr
= 0xa400 + phyAddr
*2;
313 return rtl8367c_getAsicPHYOCPReg(phyNo
, ocp_addr
, pRegData
);
318 * rtl8367c_setAsicSdsReg
320 * Set Serdes registers
322 * sdsId - sdsid (0~1)
323 * sdsReg - reg address (0~31)
324 * sdsPage - Writing data
328 * RT_ERR_OK - Success
334 ret_t
rtl8367c_setAsicSdsReg(rtk_uint32 sdsId
, rtk_uint32 sdsReg
, rtk_uint32 sdsPage
, rtk_uint32 value
)
338 if( (retVal
= rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA
, value
)) != RT_ERR_OK
)
341 if( (retVal
= rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR
, (sdsPage
<<5) | sdsReg
)) != RT_ERR_OK
)
344 if( (retVal
= rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD
, 0x00C0|sdsId
)) != RT_ERR_OK
)
352 * rtl8367c_getAiscSdsReg
354 * Get Serdes registers
356 * sdsId - sdsid (0~1)
357 * sdsReg - reg address (0~31)
358 * sdsPage - Writing data
362 * RT_ERR_OK - Success
367 ret_t
rtl8367c_getAsicSdsReg(rtk_uint32 sdsId
, rtk_uint32 sdsReg
, rtk_uint32 sdsPage
, rtk_uint32
*value
)
369 rtk_uint32 retVal
, busy
;
371 if( (retVal
= rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR
, (sdsPage
<<5) | sdsReg
)) != RT_ERR_OK
)
374 if( (retVal
= rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD
, 0x0080|sdsId
)) != RT_ERR_OK
)
379 if ((retVal
= rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_CMD
, &busy
))!=RT_ERR_OK
)
382 if ((busy
& 0x100) == 0)
386 if ((retVal
= rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA
, value
))!=RT_ERR_OK
)