at v4.5 7.9 kB view raw
1/* 2 * linux/mdio.h: definitions for MDIO (clause 45) transceivers 3 * Copyright 2006-2009 Solarflare Communications Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published 7 * by the Free Software Foundation, incorporated herein by reference. 8 */ 9#ifndef __LINUX_MDIO_H__ 10#define __LINUX_MDIO_H__ 11 12#include <uapi/linux/mdio.h> 13 14struct mii_bus; 15 16struct mdio_device { 17 struct device dev; 18 19 const struct dev_pm_ops *pm_ops; 20 struct mii_bus *bus; 21 22 int (*bus_match)(struct device *dev, struct device_driver *drv); 23 void (*device_free)(struct mdio_device *mdiodev); 24 void (*device_remove)(struct mdio_device *mdiodev); 25 26 /* Bus address of the MDIO device (0-31) */ 27 int addr; 28 int flags; 29}; 30#define to_mdio_device(d) container_of(d, struct mdio_device, dev) 31 32/* struct mdio_driver_common: Common to all MDIO drivers */ 33struct mdio_driver_common { 34 struct device_driver driver; 35 int flags; 36}; 37#define MDIO_DEVICE_FLAG_PHY 1 38#define to_mdio_common_driver(d) \ 39 container_of(d, struct mdio_driver_common, driver) 40 41/* struct mdio_driver: Generic MDIO driver */ 42struct mdio_driver { 43 struct mdio_driver_common mdiodrv; 44 45 /* 46 * Called during discovery. Used to set 47 * up device-specific structures, if any 48 */ 49 int (*probe)(struct mdio_device *mdiodev); 50 51 /* Clears up any memory if needed */ 52 void (*remove)(struct mdio_device *mdiodev); 53}; 54#define to_mdio_driver(d) \ 55 container_of(to_mdio_common_driver(d), struct mdio_driver, mdiodrv) 56 57void mdio_device_free(struct mdio_device *mdiodev); 58struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr); 59int mdio_device_register(struct mdio_device *mdiodev); 60void mdio_device_remove(struct mdio_device *mdiodev); 61int mdio_driver_register(struct mdio_driver *drv); 62void mdio_driver_unregister(struct mdio_driver *drv); 63 64static inline bool mdio_phy_id_is_c45(int phy_id) 65{ 66 return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK); 67} 68 69static inline __u16 mdio_phy_id_prtad(int phy_id) 70{ 71 return (phy_id & MDIO_PHY_ID_PRTAD) >> 5; 72} 73 74static inline __u16 mdio_phy_id_devad(int phy_id) 75{ 76 return phy_id & MDIO_PHY_ID_DEVAD; 77} 78 79/** 80 * struct mdio_if_info - Ethernet controller MDIO interface 81 * @prtad: PRTAD of the PHY (%MDIO_PRTAD_NONE if not present/unknown) 82 * @mmds: Mask of MMDs expected to be present in the PHY. This must be 83 * non-zero unless @prtad = %MDIO_PRTAD_NONE. 84 * @mode_support: MDIO modes supported. If %MDIO_SUPPORTS_C22 is set then 85 * MII register access will be passed through with @devad = 86 * %MDIO_DEVAD_NONE. If %MDIO_EMULATE_C22 is set then access to 87 * commonly used clause 22 registers will be translated into 88 * clause 45 registers. 89 * @dev: Net device structure 90 * @mdio_read: Register read function; returns value or negative error code 91 * @mdio_write: Register write function; returns 0 or negative error code 92 */ 93struct mdio_if_info { 94 int prtad; 95 u32 mmds; 96 unsigned mode_support; 97 98 struct net_device *dev; 99 int (*mdio_read)(struct net_device *dev, int prtad, int devad, 100 u16 addr); 101 int (*mdio_write)(struct net_device *dev, int prtad, int devad, 102 u16 addr, u16 val); 103}; 104 105#define MDIO_PRTAD_NONE (-1) 106#define MDIO_DEVAD_NONE (-1) 107#define MDIO_SUPPORTS_C22 1 108#define MDIO_SUPPORTS_C45 2 109#define MDIO_EMULATE_C22 4 110 111struct ethtool_cmd; 112struct ethtool_pauseparam; 113extern int mdio45_probe(struct mdio_if_info *mdio, int prtad); 114extern int mdio_set_flag(const struct mdio_if_info *mdio, 115 int prtad, int devad, u16 addr, int mask, 116 bool sense); 117extern int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmds); 118extern int mdio45_nway_restart(const struct mdio_if_info *mdio); 119extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, 120 struct ethtool_cmd *ecmd, 121 u32 npage_adv, u32 npage_lpa); 122 123/** 124 * mdio45_ethtool_gset - get settings for ETHTOOL_GSET 125 * @mdio: MDIO interface 126 * @ecmd: Ethtool request structure 127 * 128 * Since the CSRs for auto-negotiation using next pages are not fully 129 * standardised, this function does not attempt to decode them. Use 130 * mdio45_ethtool_gset_npage() to specify advertisement bits from next 131 * pages. 132 */ 133static inline void mdio45_ethtool_gset(const struct mdio_if_info *mdio, 134 struct ethtool_cmd *ecmd) 135{ 136 mdio45_ethtool_gset_npage(mdio, ecmd, 0, 0); 137} 138 139extern int mdio_mii_ioctl(const struct mdio_if_info *mdio, 140 struct mii_ioctl_data *mii_data, int cmd); 141 142/** 143 * mmd_eee_cap_to_ethtool_sup_t 144 * @eee_cap: value of the MMD EEE Capability register 145 * 146 * A small helper function that translates MMD EEE Capability (3.20) bits 147 * to ethtool supported settings. 148 */ 149static inline u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap) 150{ 151 u32 supported = 0; 152 153 if (eee_cap & MDIO_EEE_100TX) 154 supported |= SUPPORTED_100baseT_Full; 155 if (eee_cap & MDIO_EEE_1000T) 156 supported |= SUPPORTED_1000baseT_Full; 157 if (eee_cap & MDIO_EEE_10GT) 158 supported |= SUPPORTED_10000baseT_Full; 159 if (eee_cap & MDIO_EEE_1000KX) 160 supported |= SUPPORTED_1000baseKX_Full; 161 if (eee_cap & MDIO_EEE_10GKX4) 162 supported |= SUPPORTED_10000baseKX4_Full; 163 if (eee_cap & MDIO_EEE_10GKR) 164 supported |= SUPPORTED_10000baseKR_Full; 165 166 return supported; 167} 168 169/** 170 * mmd_eee_adv_to_ethtool_adv_t 171 * @eee_adv: value of the MMD EEE Advertisement/Link Partner Ability registers 172 * 173 * A small helper function that translates the MMD EEE Advertisment (7.60) 174 * and MMD EEE Link Partner Ability (7.61) bits to ethtool advertisement 175 * settings. 176 */ 177static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) 178{ 179 u32 adv = 0; 180 181 if (eee_adv & MDIO_EEE_100TX) 182 adv |= ADVERTISED_100baseT_Full; 183 if (eee_adv & MDIO_EEE_1000T) 184 adv |= ADVERTISED_1000baseT_Full; 185 if (eee_adv & MDIO_EEE_10GT) 186 adv |= ADVERTISED_10000baseT_Full; 187 if (eee_adv & MDIO_EEE_1000KX) 188 adv |= ADVERTISED_1000baseKX_Full; 189 if (eee_adv & MDIO_EEE_10GKX4) 190 adv |= ADVERTISED_10000baseKX4_Full; 191 if (eee_adv & MDIO_EEE_10GKR) 192 adv |= ADVERTISED_10000baseKR_Full; 193 194 return adv; 195} 196 197/** 198 * ethtool_adv_to_mmd_eee_adv_t 199 * @adv: the ethtool advertisement settings 200 * 201 * A small helper function that translates ethtool advertisement settings 202 * to EEE advertisements for the MMD EEE Advertisement (7.60) and 203 * MMD EEE Link Partner Ability (7.61) registers. 204 */ 205static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv) 206{ 207 u16 reg = 0; 208 209 if (adv & ADVERTISED_100baseT_Full) 210 reg |= MDIO_EEE_100TX; 211 if (adv & ADVERTISED_1000baseT_Full) 212 reg |= MDIO_EEE_1000T; 213 if (adv & ADVERTISED_10000baseT_Full) 214 reg |= MDIO_EEE_10GT; 215 if (adv & ADVERTISED_1000baseKX_Full) 216 reg |= MDIO_EEE_1000KX; 217 if (adv & ADVERTISED_10000baseKX4_Full) 218 reg |= MDIO_EEE_10GKX4; 219 if (adv & ADVERTISED_10000baseKR_Full) 220 reg |= MDIO_EEE_10GKR; 221 222 return reg; 223} 224 225int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum); 226int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum); 227int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val); 228int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val); 229 230int mdiobus_register_device(struct mdio_device *mdiodev); 231int mdiobus_unregister_device(struct mdio_device *mdiodev); 232bool mdiobus_is_registered_device(struct mii_bus *bus, int addr); 233struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr); 234 235/** 236 * module_mdio_driver() - Helper macro for registering mdio drivers 237 * 238 * Helper macro for MDIO drivers which do not do anything special in module 239 * init/exit. Each module may only use this macro once, and calling it 240 * replaces module_init() and module_exit(). 241 */ 242#define mdio_module_driver(_mdio_driver) \ 243static int __init mdio_module_init(void) \ 244{ \ 245 return mdio_driver_register(&_mdio_driver); \ 246} \ 247module_init(mdio_module_init); \ 248static void __exit mdio_module_exit(void) \ 249{ \ 250 mdio_driver_unregister(&_mdio_driver); \ 251} \ 252module_exit(mdio_module_exit) 253 254#endif /* __LINUX_MDIO_H__ */