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