1/* 2 * @TAG(OTHER_GPL) 3 */ 4/* 5 * Copyright 2011 Freescale Semiconductor, Inc. 6 * Andy Fleming <afleming@gmail.com> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 * 10 * This file pretty much stolen from Linux's mii.h/ethtool.h/phy.h 11 */ 12 13#pragma once 14 15#include "list.h" 16#include <stdio.h> 17#include "mii.h" 18#include "ethtool.h" 19#include "mdio.h" 20 21#define PHY_MAX_ADDR 32 22 23#define PHY_FLAG_BROKEN_RESET (1 << 0) /* soft reset not supported */ 24 25#define PHY_DEFAULT_FEATURES (SUPPORTED_Autoneg | \ 26 SUPPORTED_TP | \ 27 SUPPORTED_MII) 28 29#define PHY_10BT_FEATURES (SUPPORTED_10baseT_Half | \ 30 SUPPORTED_10baseT_Full) 31 32#define PHY_100BT_FEATURES (SUPPORTED_100baseT_Half | \ 33 SUPPORTED_100baseT_Full) 34 35#define PHY_1000BT_FEATURES (SUPPORTED_1000baseT_Half | \ 36 SUPPORTED_1000baseT_Full) 37 38#define PHY_BASIC_FEATURES (PHY_10BT_FEATURES | \ 39 PHY_100BT_FEATURES | \ 40 PHY_DEFAULT_FEATURES) 41 42#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \ 43 PHY_1000BT_FEATURES) 44 45#define PHY_10G_FEATURES (PHY_GBIT_FEATURES | \ 46 SUPPORTED_10000baseT_Full) 47 48#ifndef PHY_ANEG_TIMEOUT 49#define PHY_ANEG_TIMEOUT 4000 50#endif 51 52 53typedef enum { 54 PHY_INTERFACE_MODE_MII, 55 PHY_INTERFACE_MODE_GMII, 56 PHY_INTERFACE_MODE_SGMII, 57 PHY_INTERFACE_MODE_SGMII_2500, 58 PHY_INTERFACE_MODE_QSGMII, 59 PHY_INTERFACE_MODE_TBI, 60 PHY_INTERFACE_MODE_RMII, 61 PHY_INTERFACE_MODE_RGMII, 62 PHY_INTERFACE_MODE_RGMII_ID, 63 PHY_INTERFACE_MODE_RGMII_RXID, 64 PHY_INTERFACE_MODE_RGMII_TXID, 65 PHY_INTERFACE_MODE_RTBI, 66 PHY_INTERFACE_MODE_XGMII, 67 PHY_INTERFACE_MODE_NONE, /* Must be last */ 68 69 PHY_INTERFACE_MODE_COUNT, 70} phy_interface_t; 71 72static const char *phy_interface_strings[] = { 73 [PHY_INTERFACE_MODE_MII] = "mii", 74 [PHY_INTERFACE_MODE_GMII] = "gmii", 75 [PHY_INTERFACE_MODE_SGMII] = "sgmii", 76 [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500", 77 [PHY_INTERFACE_MODE_QSGMII] = "qsgmii", 78 [PHY_INTERFACE_MODE_TBI] = "tbi", 79 [PHY_INTERFACE_MODE_RMII] = "rmii", 80 [PHY_INTERFACE_MODE_RGMII] = "rgmii", 81 [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id", 82 [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid", 83 [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid", 84 [PHY_INTERFACE_MODE_RTBI] = "rtbi", 85 [PHY_INTERFACE_MODE_XGMII] = "xgmii", 86 [PHY_INTERFACE_MODE_NONE] = "", 87}; 88 89static inline const char *phy_string_for_interface(phy_interface_t i) 90{ 91 /* Default to unknown */ 92 if (i > PHY_INTERFACE_MODE_NONE) { 93 i = PHY_INTERFACE_MODE_NONE; 94 } 95 96 return phy_interface_strings[i]; 97} 98 99 100struct phy_device; 101 102#define MDIO_NAME_LEN 32 103 104struct mii_dev { 105 struct list_head link; 106 char name[MDIO_NAME_LEN]; 107 void *priv; 108 int (*read)(struct mii_dev *bus, int addr, int devad, int reg); 109 int (*write)(struct mii_dev *bus, int addr, int devad, int reg, 110 uint16_t val); 111 int (*reset)(struct mii_dev *bus); 112 struct phy_device *phymap[PHY_MAX_ADDR]; 113 u32 phy_mask; 114}; 115 116/* struct phy_driver: a structure which defines PHY behavior 117 * 118 * uid will contain a number which represents the PHY. During 119 * startup, the driver will poll the PHY to find out what its 120 * UID--as defined by registers 2 and 3--is. The 32-bit result 121 * gotten from the PHY will be masked to 122 * discard any bits which may change based on revision numbers 123 * unimportant to functionality 124 * 125 */ 126struct phy_driver { 127 char *name; 128 unsigned int uid; 129 unsigned int mask; 130 unsigned int mmds; 131 132 uint32_t features; 133 134 /* Called to do any driver startup necessities */ 135 /* Will be called during phy_connect */ 136 int (*probe)(struct phy_device *phydev); 137 138 /* Called to configure the PHY, and modify the controller 139 * based on the results. Should be called after phy_connect */ 140 int (*config)(struct phy_device *phydev); 141 142 /* Called when starting up the controller */ 143 int (*startup)(struct phy_device *phydev); 144 145 /* Called when bringing down the controller */ 146 int (*shutdown)(struct phy_device *phydev); 147 148 int (*readext)(struct phy_device *phydev, int addr, int devad, int reg); 149 int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg, 150 u16 val); 151 struct list_head list; 152}; 153 154struct phy_device { 155 /* Information about the PHY type */ 156 /* And management functions */ 157 struct mii_dev *bus; 158 struct phy_driver *drv; 159 void *priv; 160 161#ifdef CONFIG_DM_ETH 162 struct udevice *dev; 163#else 164 struct eth_device *dev; 165#endif 166 167 /* forced speed & duplex (no autoneg) 168 * partner speed & duplex & pause (autoneg) 169 */ 170 int speed; 171 int duplex; 172 173 /* The most recently read link state */ 174 int link; 175 int port; 176 phy_interface_t interface; 177 178 uint32_t advertising; 179 uint32_t supported; 180 uint32_t mmds; 181 182 int autoneg; 183 int addr; 184 int pause; 185 int asym_pause; 186 uint32_t phy_id; 187 uint32_t flags; 188}; 189 190struct fixed_link { 191 int phy_id; 192 int duplex; 193 int link_speed; 194 int pause; 195 int asym_pause; 196}; 197 198static inline int phy_read(struct phy_device *phydev, int devad, int regnum) 199{ 200 struct mii_dev *bus = phydev->bus; 201 202 return bus->read(bus, phydev->addr, devad, regnum); 203} 204 205static inline int phy_write(struct phy_device *phydev, int devad, int regnum, 206 uint16_t val) 207{ 208 struct mii_dev *bus = phydev->bus; 209 210 return bus->write(bus, phydev->addr, devad, regnum, val); 211} 212 213#ifdef CONFIG_PHYLIB_10G 214extern struct phy_driver gen10g_driver; 215 216/* For now, XGMII is the only 10G interface */ 217static inline int is_10g_interface(phy_interface_t interface) 218{ 219 return interface == PHY_INTERFACE_MODE_XGMII; 220} 221 222#endif 223 224int phy_init(void); 225int phy_reset(struct phy_device *phydev); 226struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask, 227 phy_interface_t interface); 228#ifdef CONFIG_DM_ETH 229void phy_connect_dev(struct phy_device *phydev, struct udevice *dev); 230struct phy_device *phy_connect(struct mii_dev *bus, int addr, 231 struct udevice *dev, 232 phy_interface_t interface); 233#else 234void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev); 235struct phy_device *phy_connect(struct mii_dev *bus, int addr, 236 struct eth_device *dev, 237 phy_interface_t interface); 238#endif 239int phy_startup(struct phy_device *phydev); 240int phy_config(struct phy_device *phydev); 241int phy_shutdown(struct phy_device *phydev); 242int phy_register(struct phy_driver *drv); 243int phy_set_supported(struct phy_device *phydev, u32 max_speed); 244int genphy_config_aneg(struct phy_device *phydev); 245int genphy_restart_aneg(struct phy_device *phydev); 246int genphy_update_link(struct phy_device *phydev); 247int genphy_parse_link(struct phy_device *phydev); 248int genphy_config(struct phy_device *phydev); 249int genphy_startup(struct phy_device *phydev); 250int genphy_shutdown(struct phy_device *phydev); 251int gen10g_config(struct phy_device *phydev); 252int gen10g_startup(struct phy_device *phydev); 253int gen10g_shutdown(struct phy_device *phydev); 254int gen10g_discover_mmds(struct phy_device *phydev); 255 256int phy_mv88e61xx_init(void); 257int phy_aquantia_init(void); 258int phy_atheros_init(void); 259int phy_broadcom_init(void); 260int phy_cortina_init(void); 261int phy_davicom_init(void); 262int phy_et1011c_init(void); 263int phy_lxt_init(void); 264int phy_marvell_init(void); 265int phy_micrel_init(void); 266int phy_natsemi_init(void); 267int phy_realtek_init(void); 268int phy_smsc_init(void); 269int phy_teranetics_init(void); 270int phy_ti_init(void); 271int phy_vitesse_init(void); 272int phy_xilinx_init(void); 273 274int board_phy_config(struct phy_device *phydev); 275int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id); 276 277/** 278 * phy_get_interface_by_name() - Look up a PHY interface name 279 * 280 * @str: PHY interface name, e.g. "mii" 281 * @return PHY_INTERFACE_MODE_... value, or -1 if not found 282 */ 283int phy_get_interface_by_name(const char *str); 284 285/** 286 * phy_interface_is_rgmii - Convenience function for testing if a PHY interface 287 * is RGMII (all variants) 288 * @phydev: the phy_device struct 289 */ 290static inline u8 phy_interface_is_rgmii(struct phy_device *phydev) 291{ 292 return phydev->interface >= PHY_INTERFACE_MODE_RGMII && 293 phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID; 294} 295 296/** 297 * phy_interface_is_sgmii - Convenience function for testing if a PHY interface 298 * is SGMII (all variants) 299 * @phydev: the phy_device struct 300 */ 301static inline u8 phy_interface_is_sgmii(struct phy_device *phydev) 302{ 303 return phydev->interface >= PHY_INTERFACE_MODE_SGMII && 304 phydev->interface <= PHY_INTERFACE_MODE_QSGMII; 305} 306 307/* PHY UIDs for various PHYs that are referenced in external code */ 308#define PHY_UID_CS4340 0x13e51002 309#define PHY_UID_TN2020 0x00a19410 310