1 /* 2 * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /****************************************************************************** 17 * @file phy.h 18 * @brief header file for generic PHY Driver 19 * @version V1.0 20 * @date 21 March 2019 21 ******************************************************************************/ 22 #ifndef _ETH_PHY_H_ 23 #define _ETH_PHY_H_ 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #include <stdint.h> 30 #include "mmio.h" 31 #include "drv_ioremap.h" 32 33 /** 34 \brief Ethernet link speed 35 */ 36 #define CSI_ETH_SPEED_10M (0) ///< 10 Mbps link speed 37 #define CSI_ETH_SPEED_100M (1) ///< 100 Mbps link speed 38 #define CSI_ETH_SPEED_1G (2) ///< 1 Gpbs link speed 39 40 /** 41 \brief Ethernet duplex mode 42 */ 43 #define CSI_ETH_DUPLEX_HALF (0) ///< Half duplex link 44 #define CSI_ETH_DUPLEX_FULL (1) ///< Full duplex link 45 46 typedef void *eth_phy_handle_t; 47 48 typedef enum eth_power_state 49 { 50 CSI_ETH_POWER_OFF, ///< Power off: no operation possible 51 CSI_ETH_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events 52 CSI_ETH_POWER_FULL ///< Power on: full operation at maximum performance 53 } eth_power_state_t; 54 55 typedef int32_t (*csi_eth_phy_read_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Read Ethernet PHY Register. 56 typedef int32_t (*csi_eth_phy_write_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Write Ethernet PHY Register. 57 58 typedef volatile struct eth_link_info 59 { 60 uint32_t speed : 2; ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit 61 uint32_t duplex : 1; ///< Duplex mode: 0= Half, 1= Full 62 uint32_t autoneg : 1; ///< Set the interface to Auto Negotiation mode of transmission parameters 63 uint32_t loopback : 1; ///< Set the interface into a Loop-back test mode 64 uint32_t isolation : 1; ///< Set to indicate electrical isolation of PHY interface from MII/RMII interface 65 uint32_t reserved : 26; 66 } eth_link_info_t; 67 68 typedef struct 69 { 70 csi_eth_phy_read_t phy_read; 71 csi_eth_phy_write_t phy_write; 72 eth_link_info_t link_info; 73 } eth_phy_priv_t; 74 75 typedef enum eth_link_state 76 { 77 ETH_LINK_DOWN, ///< Link is down 78 ETH_LINK_UP ///< Link is up 79 } eth_link_state_t; 80 81 /* Basic mode control register */ 82 #define CVI_BMCR_RESV (0x003f) 83 #define CVI_BMCR_SPEED1000 (0x0040) 84 #define CVI_BMCR_CTST (0x0080) 85 #define CVI_BMCR_FULLDPLX (0x0100) 86 #define CVI_BMCR_ANRESTART (0x0200) 87 #define CVI_BMCR_ISOLATE (0x0400) 88 #define CVI_BMCR_PDOWN (0x0800) 89 #define CVI_BMCR_ANENABLE (0x1000) 90 #define CVI_BMCR_SPEED100 (0x2000) 91 #define CVI_BMCR_LOOPBACK (0x4000) 92 #define CVI_BMCR_RESET (0x8000) 93 #define BMCR_SPEED10 (0x0000) 94 95 96 /* Generic MII registers */ 97 #define CVI_MII_BMCR (0x00) 98 #define CVI_MII_BMSR (0x01) 99 #define CVI_MII_PHYSID1 (0x02) 100 #define CVI_MII_PHYSID2 (0x03) 101 #define CVI_MII_ADVERTISE (0x04) 102 #define CVI_MII_LPA (0x05) 103 #define CVI_MII_EXPANSION (0x06) 104 #define CVI_MII_CTRL1000 (0x09) 105 #define CVI_MII_STAT1000 (0x0a) 106 #define MII_MMD_CTRL (0x0d) 107 #define MII_MMD_DATA (0x0e) 108 #define CVI_MII_ESTATUS (0x0f) 109 #define CVI_MII_DCOUNTER (0x12) 110 #define CVI_MII_FCSCOUNTER (0x13) 111 #define CVI_MII_NWAYTEST (0x14) 112 #define CVI_MII_RERRCOUNTER (0x15) 113 #define CVI_MII_SREVISION (0x16) 114 #define CVI_MII_RESV1 (0x17) 115 #define CVI_MII_LBRERROR (0x18) 116 #define CVI_MII_PHYADDR (0x19) 117 #define CVI_MII_RESV2 (0x1a) 118 #define CVI_MII_TPISTATUS (0x1b) 119 #define CVI_MII_NCONFIG (0x1c) 120 121 /* Advertisement control register. */ 122 #define CVI_ADVERTISE_CSMA (0x0001) 123 #define CVI_ADVERTISE_SLCT (0x001f) 124 #define CVI_ADVERTISE_10HALF (0x0020) 125 #define CVI_ADVERTISE_1000XFULL (0x0020) 126 #define CVI_ADVERTISE_10FULL (0x0040) 127 #define CVI_ADVERTISE_1000XHALF (0x0040) 128 #define CVI_ADVERTISE_100HALF (0x0080) 129 #define CVI_ADVERTISE_1000XPAUSE (0x0080) 130 #define CVI_ADVERTISE_100FULL (0x0100) 131 #define CVI_ADVERTISE_1000XPSE_ASYM (0x0100) 132 #define CVI_ADVERTISE_100BASE4 (0x0200) 133 #define CVI_ADVERTISE_PAUSE_CAP (0x0400) 134 #define CVI_ADVERTISE_PAUSE_ASYM (0x0800) 135 #define CVI_ADVERTISE_RESV (0x1000) 136 #define CVI_ADVERTISE_RFAULT (0x2000) 137 #define CVI_ADVERTISE_LPACK (0x4000) 138 #define CVI_ADVERTISE_NPAGE (0x8000) 139 140 /* Basic mode status register. */ 141 #define CVI_BMSR_ERCAP (0x0001) 142 #define CVI_BMSR_JCD (0x0002) 143 #define CVI_BMSR_LSTATUS (0x0004) 144 #define CVI_BMSR_ANEGCAPABLE (0x0008) 145 #define CVI_BMSR_RFAULT (0x0010) 146 #define CVI_BMSR_ANEGCOMPLETE (0x0020) 147 #define CVI_BMSR_RESV (0x00c0) 148 #define CVI_BMSR_ESTATEN (0x0100) 149 #define CVI_BMSR_100HALF2 (0x0200) 150 #define CVI_BMSR_100FULL2 (0x0400) 151 #define CVI_BMSR_10HALF (0x0800) 152 #define CVI_BMSR_10FULL (0x1000) 153 #define CVI_BMSR_100HALF (0x2000) 154 #define CVI_BMSR_100FULL (0x4000) 155 #define CVI_BMSR_100BASE4 (0x8000) 156 157 #define CVI_ADVERTISE_FULL (CVI_ADVERTISE_100FULL | CVI_ADVERTISE_10FULL | \ 158 CVI_ADVERTISE_CSMA) 159 #define CVI_ADVERTISE_ALL (CVI_ADVERTISE_10HALF | CVI_ADVERTISE_10FULL | \ 160 CVI_ADVERTISE_100HALF | CVI_ADVERTISE_100FULL) 161 162 /* Link partner ability register. */ 163 #define CVI_LPA_SLCT (0x001f) /* Same as advertise selector */ 164 #define CVI_LPA_10HALF (0x0020) /* Can do 10mbps half-duplex */ 165 #define CVI_LPA_1000XFULL (0x0020) /* Can do 1000BASE-X full-duplex */ 166 #define CVI_LPA_10FULL (0x0040) /* Can do 10mbps full-duplex */ 167 #define CVI_LPA_1000XHALF (0x0040) /* Can do 1000BASE-X half-duplex */ 168 #define CVI_LPA_100HALF (0x0080) /* Can do 100mbps half-duplex */ 169 #define CVI_LPA_1000XPAUSE (0x0080) /* Can do 1000BASE-X pause */ 170 #define CVI_LPA_100FULL (0x0100) /* Can do 100mbps full-duplex */ 171 #define CVI_LPA_1000XPAUSE_ASYM (0x0100) /* Can do 1000BASE-X pause asym */ 172 #define CVI_LPA_100BASE4 (0x0200) /* Can do 100mbps 4k packets */ 173 #define CVI_LPA_PAUSE_CAP (0x0400) /* Can pause */ 174 #define CVI_LPA_PAUSE_ASYM (0x0800) /* Can pause asymetrically */ 175 #define CVI_LPA_RESV (0x1000) /* Unused */ 176 #define CVI_LPA_RFAULT (0x2000) /* Link partner faulted */ 177 #define CVI_LPA_LPACK (0x4000) /* Link partner acked us */ 178 #define CVI_LPA_NPAGE (0x8000) /* Next page bit */ 179 180 #define CVI_LPA_DUPLEX (CVI_LPA_10FULL | CVI_LPA_100FULL) 181 #define CVI_LPA_100 (CVI_LPA_100FULL | CVI_LPA_100HALF | CVI_LPA_100BASE4) 182 183 /* Expansion register for auto-negotiation. */ 184 #define CVI_EXPANSION_NWAY (0x0001) /* Can do N-way auto-nego */ 185 #define CVI_EXPANSION_LCWP (0x0002) /* Got new RX page code word */ 186 #define CVI_EXPANSION_ENABLENPAGE (0x0004) /* This enables npage words */ 187 #define CVI_EXPANSION_NPCAPABLE (0x0008) /* Link partner supports npage */ 188 #define CVI_EXPANSION_MFAULTS (0x0010) /* Multiple faults detected */ 189 #define CVI_EXPANSION_RESV (0xffe0) /* Unused */ 190 191 #define CVI_ESTATUS_1000_XFULL (0x8000) /* Can do 1000BX Full */ 192 #define CVI_ESTATUS_1000_XHALF (0x4000) /* Can do 1000BX Half */ 193 #define CVI_ESTATUS_1000_TFULL (0x2000) /* Can do 1000BT Full */ 194 #define CVI_ESTATUS_1000_THALF (0x1000) /* Can do 1000BT Half */ 195 196 /* N-way test register. */ 197 #define CVI_NWAYTEST_RESV1 (0x00ff) /* Unused */ 198 #define CVI_NWAYTEST_LOOPBACK (0x0100) /* Enable loopback for N-way */ 199 #define CVI_NWAYTEST_RESV2 (0xfe00) /* Unused */ 200 201 /* 1000BASE-T Control register */ 202 #define CVI_ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ 203 #define CVI_ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ 204 #define CTL1000_AS_MASTER 0x0800 205 #define CTL1000_ENABLE_MASTER 0x1000 206 207 /* 1000BASE-T Status register */ 208 #define CVI_LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ 209 #define CVI_LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ 210 #define CVI_LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ 211 #define CVI_LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ 212 213 /* Flow control flags */ 214 #define CVI_FLOW_CTRL_TX 0x01 215 #define CVI_FLOW_CTRL_RX 0x02 216 217 /* MMD Access Control register fields */ 218 #define CVI_MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/ 219 #define CVI_MII_MMD_CTRL_ADDR 0x0000 /* Address */ 220 #define CVI_MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */ 221 #define CVI_MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */ 222 #define CVI_MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */ 223 224 225 /* Indicates what features are advertised by the interface. */ 226 #define CVI_ADVERTISED_10baseT_Half (1 << 0) 227 #define CVI_ADVERTISED_10baseT_Full (1 << 1) 228 #define CVI_ADVERTISED_100baseT_Half (1 << 2) 229 #define CVI_ADVERTISED_100baseT_Full (1 << 3) 230 #define CVI_ADVERTISED_1000baseT_Half (1 << 4) 231 #define CVI_ADVERTISED_1000baseT_Full (1 << 5) 232 #define CVI_ADVERTISED_Autoneg (1 << 6) 233 #define CVI_ADVERTISED_TP (1 << 7) 234 #define CVI_ADVERTISED_AUI (1 << 8) 235 #define CVI_ADVERTISED_MII (1 << 9) 236 #define CVI_ADVERTISED_FIBRE (1 << 10) 237 #define CVI_ADVERTISED_BNC (1 << 11) 238 #define CVI_ADVERTISED_10000baseT_Full (1 << 12) 239 #define CVI_ADVERTISED_Pause (1 << 13) 240 #define CVI_ADVERTISED_Asym_Pause (1 << 14) 241 #define CVI_ADVERTISED_2500baseX_Full (1 << 15) 242 #define CVI_ADVERTISED_Backplane (1 << 16) 243 #define CVI_ADVERTISED_1000baseKX_Full (1 << 17) 244 #define CVI_ADVERTISED_10000baseKX4_Full (1 << 18) 245 #define CVI_ADVERTISED_10000baseKR_Full (1 << 19) 246 #define CVI_ADVERTISED_10000baseR_FEC (1 << 20) 247 #define CVI_ADVERTISED_1000baseX_Half (1 << 21) 248 #define CVI_ADVERTISED_1000baseX_Full (1 << 22) 249 250 251 /* Indicates what features are supported by the interface. */ 252 #define CVI_SUPPORTED_10baseT_Half (1 << 0) 253 #define CVI_SUPPORTED_10baseT_Full (1 << 1) 254 #define CVI_SUPPORTED_100baseT_Half (1 << 2) 255 #define CVI_SUPPORTED_100baseT_Full (1 << 3) 256 #define CVI_SUPPORTED_1000baseT_Half (1 << 4) 257 #define CVI_SUPPORTED_1000baseT_Full (1 << 5) 258 #define CVI_SUPPORTED_Autoneg (1 << 6) 259 #define CVI_SUPPORTED_TP (1 << 7) 260 #define CVI_SUPPORTED_AUI (1 << 8) 261 #define CVI_SUPPORTED_MII (1 << 9) 262 #define CVI_SUPPORTED_FIBRE (1 << 10) 263 #define CVI_SUPPORTED_BNC (1 << 11) 264 #define CVI_SUPPORTED_10000baseT_Full (1 << 12) 265 #define CVI_SUPPORTED_Pause (1 << 13) 266 #define CVI_SUPPORTED_Asym_Pause (1 << 14) 267 #define CVI_SUPPORTED_2500baseX_Full (1 << 15) 268 #define CVI_SUPPORTED_Backplane (1 << 16) 269 #define CVI_SUPPORTED_1000baseKX_Full (1 << 17) 270 #define CVI_SUPPORTED_10000baseKX4_Full (1 << 18) 271 #define CVI_SUPPORTED_10000baseKR_Full (1 << 19) 272 #define CVI_SUPPORTED_10000baseR_FEC (1 << 20) 273 #define CVI_SUPPORTED_1000baseX_Half (1 << 21) 274 #define CVI_SUPPORTED_1000baseX_Full (1 << 22) 275 276 /* PHY features */ 277 #define CVI_PHY_DEFAULT_FEATURES (CVI_SUPPORTED_Autoneg | \ 278 CVI_SUPPORTED_TP | \ 279 CVI_SUPPORTED_MII) 280 281 #define CVI_PHY_10BT_FEATURES (CVI_SUPPORTED_10baseT_Half | \ 282 CVI_SUPPORTED_10baseT_Full) 283 284 #define CVI_PHY_100BT_FEATURES (CVI_SUPPORTED_100baseT_Half | \ 285 CVI_SUPPORTED_100baseT_Full) 286 287 #define CVI_PHY_1000BT_FEATURES (CVI_SUPPORTED_1000baseT_Half | \ 288 CVI_SUPPORTED_1000baseT_Full) 289 290 #define CVI_PHY_BASIC_FEATURES (CVI_PHY_10BT_FEATURES | \ 291 CVI_PHY_100BT_FEATURES | \ 292 CVI_PHY_DEFAULT_FEATURES) 293 294 #define CVI_PHY_GBIT_FEATURES (CVI_PHY_BASIC_FEATURES | \ 295 CVI_PHY_1000BT_FEATURES) 296 297 #define CVI_PHY_ANEG_TIMEOUT 5000 /* in ms */ 298 299 typedef enum { 300 LOOPBACK_XMII2MAC, 301 LOOPBACK_PCS2MAC, 302 LOOPBACK_PMA2MAC, 303 LOOPBACK_RMII2PHY, 304 } phy_loopback_mode_t; 305 306 /* phy interface mode */ 307 typedef enum { 308 PHY_IF_MODE_MII, 309 PHY_IF_MODE_GMII, 310 PHY_IF_MODE_SGMII, 311 PHY_IF_MODE_TBI, 312 PHY_IF_MODE_RMII, 313 PHY_IF_MODE_RGMII, 314 PHY_IF_MODE_RGMII_ID, 315 PHY_IF_MODE_RGMII_RXID, 316 PHY_IF_MODE_RGMII_TXID, 317 PHY_IF_MODE_RTBI, 318 319 PHY_IF_MODE_NONE, /* Last One */ 320 PHY_IF_MODE_COUNT, 321 } phy_if_mode_t; 322 323 typedef struct { 324 eth_phy_priv_t *priv; 325 eth_link_state_t link_state; 326 327 uint32_t supported; 328 uint32_t advertising; 329 330 /* 331 * platform specific 332 */ 333 uint32_t phy_addr; 334 phy_if_mode_t interface; 335 336 /* 337 * driver specific 338 */ 339 uint32_t phy_id; 340 uint32_t mask; 341 uint32_t features; 342 int8_t name[20]; 343 /* config() should be called before calling start() */ 344 int32_t (*config)(eth_phy_handle_t phy_dev); 345 int32_t (*start)(eth_phy_handle_t phy_dev); 346 int32_t (*stop)(eth_phy_handle_t phy_dev); 347 int32_t (*loopback)(eth_phy_handle_t phy_dev); 348 int32_t (*update_link)(eth_phy_handle_t phy_dev); 349 } eth_phy_dev_t; 350 351 /* ethernet phy config */ 352 #define ETH_PHY_BASE (uintptr_t)DRV_IOREMAP((void *)0x03009000, 0x1000) 353 #define ETH_PHY_INIT_MASK 0xFFFFFFF9 354 #define ETH_PHY_SHUTDOWN (1 << 1) 355 #define ETH_PHY_POWERUP 0xFFFFFFFD 356 #define ETH_PHY_RESET 0xFFFFFFFB 357 #define ETH_PHY_RESET_N (1 << 2) 358 #define ETH_PHY_LED_LOW_ACTIVE (1 << 3) 359 360 int generic_phy_config_aneg(eth_phy_dev_t *dev); 361 int generic_phy_restart_aneg(eth_phy_dev_t *dev); 362 int generic_phy_update_link(eth_phy_dev_t *dev); 363 364 int32_t eth_phy_read(eth_phy_priv_t *priv, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); 365 int32_t eth_phy_write(eth_phy_priv_t *priv, uint8_t phy_addr, uint8_t reg_addr, uint16_t data); 366 367 int32_t eth_phy_reset(eth_phy_handle_t handle); 368 int32_t eth_phy_config(eth_phy_handle_t handle); 369 int32_t eth_phy_start(eth_phy_handle_t handle); 370 int32_t eth_phy_update_link(eth_phy_handle_t handle); 371 372 int32_t genphy_config(eth_phy_dev_t *phy_dev); 373 int32_t genphy_update_link(eth_phy_dev_t *phy_dev); 374 375 int32_t cvi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state); 376 377 eth_phy_handle_t cvi_eth_phy_init(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write); 378 379 380 #ifdef __cplusplus 381 } 382 #endif 383 384 #endif /* _ETH_PHY_H_ */ 385