1/* 2 * @TAG(OTHER_GPL) 3 */ 4 5/* 6 * Copyright 2011 Freescale Semiconductor, Inc. 7 * Andy Fleming <afleming@freescale.com> 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * MA 02111-1307 USA 23 */ 24 25/* 26 * This file derived from Linux's mii.h/ethtool.h/phy.h 27 */ 28 29#pragma once 30 31#include "list.h" 32#include <stdio.h> 33#include "mii.h" 34#include "ethtool.h" 35#include "mdio.h" 36 37#define PHY_MAX_ADDR 32 38 39#define PHY_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ 40 SUPPORTED_10baseT_Full | \ 41 SUPPORTED_100baseT_Half | \ 42 SUPPORTED_100baseT_Full | \ 43 SUPPORTED_Autoneg | \ 44 SUPPORTED_TP | \ 45 SUPPORTED_MII) 46 47#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \ 48 SUPPORTED_1000baseT_Half | \ 49 SUPPORTED_1000baseT_Full) 50 51#define PHY_10G_FEATURES (PHY_GBIT_FEATURES | \ 52 SUPPORTED_10000baseT_Full) 53 54#define PHY_ANEG_TIMEOUT 40000 55 56typedef enum { 57 PHY_INTERFACE_MODE_MII, 58 PHY_INTERFACE_MODE_GMII, 59 PHY_INTERFACE_MODE_SGMII, 60 PHY_INTERFACE_MODE_TBI, 61 PHY_INTERFACE_MODE_RMII, 62 PHY_INTERFACE_MODE_RGMII, 63 PHY_INTERFACE_MODE_RGMII_ID, 64 PHY_INTERFACE_MODE_RGMII_RXID, 65 PHY_INTERFACE_MODE_RGMII_TXID, 66 PHY_INTERFACE_MODE_RTBI, 67 PHY_INTERFACE_MODE_XGMII, 68 PHY_INTERFACE_MODE_NONE /* Must be last */ 69} phy_interface_t; 70 71static const char *phy_interface_strings[] = { 72 [PHY_INTERFACE_MODE_MII] = "mii", 73 [PHY_INTERFACE_MODE_GMII] = "gmii", 74 [PHY_INTERFACE_MODE_SGMII] = "sgmii", 75 [PHY_INTERFACE_MODE_TBI] = "tbi", 76 [PHY_INTERFACE_MODE_RMII] = "rmii", 77 [PHY_INTERFACE_MODE_RGMII] = "rgmii", 78 [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id", 79 [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid", 80 [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid", 81 [PHY_INTERFACE_MODE_RTBI] = "rtbi", 82 [PHY_INTERFACE_MODE_XGMII] = "xgmii", 83 [PHY_INTERFACE_MODE_NONE] = "", 84}; 85 86static inline const char *phy_string_for_interface(phy_interface_t i) 87{ 88 /* Default to unknown */ 89 if (i > PHY_INTERFACE_MODE_NONE) 90 i = PHY_INTERFACE_MODE_NONE; 91 92 return phy_interface_strings[i]; 93} 94 95struct phy_device; 96 97#define MDIO_NAME_LEN 32 98 99struct mii_dev { 100 struct list_head link; 101 char name[MDIO_NAME_LEN]; 102 void *priv; 103 int (*read)(struct mii_dev *bus, int addr, int devad, int reg); 104 int (*write)(struct mii_dev *bus, int addr, int devad, int reg, 105 uint16_t val); 106 int (*reset)(struct mii_dev *bus); 107 struct phy_device *phymap[PHY_MAX_ADDR]; 108 uint32_t phy_mask; 109}; 110 111/* struct phy_driver: a structure which defines PHY behavior 112 * 113 * uid will contain a number which represents the PHY. During 114 * startup, the driver will poll the PHY to find out what its 115 * UID--as defined by registers 2 and 3--is. The 32-bit result 116 * gotten from the PHY will be masked to 117 * discard any bits which may change based on revision numbers 118 * unimportant to functionality 119 * 120 */ 121struct phy_driver { 122 char *name; 123 unsigned int uid; 124 unsigned int mask; 125 unsigned int mmds; 126 127 uint32_t features; 128 129 /* Called to do any driver startup necessities */ 130 /* Will be called during phy_connect */ 131 int (*probe)(struct phy_device *phydev); 132 133 /* Called to configure the PHY, and modify the controller 134 * based on the results. Should be called after phy_connect */ 135 int (*config)(struct phy_device *phydev); 136 137 /* Called when starting up the controller */ 138 int (*startup)(struct phy_device *phydev); 139 140 /* Called when bringing down the controller */ 141 int (*shutdown)(struct phy_device *phydev); 142 143 struct list_head list; 144}; 145 146struct phy_device { 147 /* Information about the PHY type */ 148 /* And management functions */ 149 struct mii_dev *bus; 150 struct phy_driver *drv; 151 void *priv; 152 153 struct eth_device *dev; 154 155 /* forced speed & duplex (no autoneg) 156 * partner speed & duplex & pause (autoneg) 157 */ 158 int speed; 159 int duplex; 160 161 /* The most recently read link state */ 162 int link; 163 int port; 164 phy_interface_t interface; 165 166 uint32_t advertising; 167 uint32_t supported; 168 uint32_t mmds; 169 170 int autoneg; 171 int addr; 172 int pause; 173 int asym_pause; 174 uint32_t phy_id; 175 uint32_t flags; 176}; 177 178static inline int phy_read(struct phy_device *phydev, int devad, int regnum) 179{ 180 struct mii_dev *bus = phydev->bus; 181 182 return bus->read(bus, phydev->addr, devad, regnum); 183} 184 185static inline int phy_write(struct phy_device *phydev, int devad, int regnum, 186 uint16_t val) 187{ 188 struct mii_dev *bus = phydev->bus; 189 190 return bus->write(bus, phydev->addr, devad, regnum, val); 191} 192 193#ifdef CONFIG_PHYLIB_10G 194extern struct phy_driver gen10g_driver; 195 196/* For now, XGMII is the only 10G interface */ 197static inline int is_10g_interface(phy_interface_t interface) 198{ 199 return interface == PHY_INTERFACE_MODE_XGMII; 200} 201 202#endif 203 204int phy_init(void); 205int phy_reset(struct phy_device *phydev); 206struct phy_device *phy_connect(struct mii_dev *bus, int addr, 207 struct eth_device *dev, 208 phy_interface_t interface); 209struct phy_device *phy_connect_by_mask(struct mii_dev *bus, unsigned phy_mask, 210 struct eth_device *dev, phy_interface_t interface); 211int phy_startup(struct phy_device *phydev); 212int phy_config(struct phy_device *phydev); 213int phy_shutdown(struct phy_device *phydev); 214int phy_register(struct phy_driver *drv); 215int genphy_config_aneg(struct phy_device *phydev); 216int genphy_restart_aneg(struct phy_device *phydev); 217int genphy_update_link(struct phy_device *phydev); 218int genphy_config(struct phy_device *phydev); 219int genphy_startup(struct phy_device *phydev); 220int genphy_shutdown(struct phy_device *phydev); 221int gen10g_config(struct phy_device *phydev); 222int gen10g_startup(struct phy_device *phydev); 223int gen10g_shutdown(struct phy_device *phydev); 224int gen10g_discover_mmds(struct phy_device *phydev); 225 226int phy_atheros_init(void); 227int phy_broadcom_init(void); 228int phy_davicom_init(void); 229int phy_lxt_init(void); 230int phy_marvell_init(void); 231int phy_micrel_init(void); 232int phy_natsemi_init(void); 233int phy_realtek_init(void); 234int phy_smsc_init(void); 235int phy_teranetics_init(void); 236int phy_vitesse_init(void); 237 238/* PHY UIDs for various PHYs that are referenced in external code */ 239#define PHY_UID_TN2020 0x00a19410 240 241