linux/include/linux/mii.h
<<
>>
Prefs
   1/*
   2 * linux/mii.h: definitions for MII-compatible transceivers
   3 * Originally drivers/net/sunhme.h.
   4 *
   5 * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
   6 */
   7#ifndef __LINUX_MII_H__
   8#define __LINUX_MII_H__
   9
  10
  11#include <linux/if.h>
  12#include <uapi/linux/mii.h>
  13
  14struct ethtool_cmd;
  15
  16struct mii_if_info {
  17        int phy_id;
  18        int advertising;
  19        int phy_id_mask;
  20        int reg_num_mask;
  21
  22        unsigned int full_duplex : 1;   /* is full duplex? */
  23        unsigned int force_media : 1;   /* is autoneg. disabled? */
  24        unsigned int supports_gmii : 1; /* are GMII registers supported? */
  25
  26        struct net_device *dev;
  27        int (*mdio_read) (struct net_device *dev, int phy_id, int location);
  28        void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
  29};
  30
  31extern int mii_link_ok (struct mii_if_info *mii);
  32extern int mii_nway_restart (struct mii_if_info *mii);
  33extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
  34extern void mii_ethtool_get_link_ksettings(
  35        struct mii_if_info *mii, struct ethtool_link_ksettings *cmd);
  36extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
  37extern int mii_ethtool_set_link_ksettings(
  38        struct mii_if_info *mii, const struct ethtool_link_ksettings *cmd);
  39extern int mii_check_gmii_support(struct mii_if_info *mii);
  40extern void mii_check_link (struct mii_if_info *mii);
  41extern unsigned int mii_check_media (struct mii_if_info *mii,
  42                                     unsigned int ok_to_print,
  43                                     unsigned int init_media);
  44extern int generic_mii_ioctl(struct mii_if_info *mii_if,
  45                             struct mii_ioctl_data *mii_data, int cmd,
  46                             unsigned int *duplex_changed);
  47
  48
  49static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
  50{
  51        return (struct mii_ioctl_data *) &rq->ifr_ifru;
  52}
  53
  54/**
  55 * mii_nway_result
  56 * @negotiated: value of MII ANAR and'd with ANLPAR
  57 *
  58 * Given a set of MII abilities, check each bit and returns the
  59 * currently supported media, in the priority order defined by
  60 * IEEE 802.3u.  We use LPA_xxx constants but note this is not the
  61 * value of LPA solely, as described above.
  62 *
  63 * The one exception to IEEE 802.3u is that 100baseT4 is placed
  64 * between 100T-full and 100T-half.  If your phy does not support
  65 * 100T4 this is fine.  If your phy places 100T4 elsewhere in the
  66 * priority order, you will need to roll your own function.
  67 */
  68static inline unsigned int mii_nway_result (unsigned int negotiated)
  69{
  70        unsigned int ret;
  71
  72        if (negotiated & LPA_100FULL)
  73                ret = LPA_100FULL;
  74        else if (negotiated & LPA_100BASE4)
  75                ret = LPA_100BASE4;
  76        else if (negotiated & LPA_100HALF)
  77                ret = LPA_100HALF;
  78        else if (negotiated & LPA_10FULL)
  79                ret = LPA_10FULL;
  80        else
  81                ret = LPA_10HALF;
  82
  83        return ret;
  84}
  85
  86/**
  87 * mii_duplex
  88 * @duplex_lock: Non-zero if duplex is locked at full
  89 * @negotiated: value of MII ANAR and'd with ANLPAR
  90 *
  91 * A small helper function for a common case.  Returns one
  92 * if the media is operating or locked at full duplex, and
  93 * returns zero otherwise.
  94 */
  95static inline unsigned int mii_duplex (unsigned int duplex_lock,
  96                                       unsigned int negotiated)
  97{
  98        if (duplex_lock)
  99                return 1;
 100        if (mii_nway_result(negotiated) & LPA_DUPLEX)
 101                return 1;
 102        return 0;
 103}
 104
 105/**
 106 * ethtool_adv_to_mii_adv_t
 107 * @ethadv: the ethtool advertisement settings
 108 *
 109 * A small helper function that translates ethtool advertisement
 110 * settings to phy autonegotiation advertisements for the
 111 * MII_ADVERTISE register.
 112 */
 113static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
 114{
 115        u32 result = 0;
 116
 117        if (ethadv & ADVERTISED_10baseT_Half)
 118                result |= ADVERTISE_10HALF;
 119        if (ethadv & ADVERTISED_10baseT_Full)
 120                result |= ADVERTISE_10FULL;
 121        if (ethadv & ADVERTISED_100baseT_Half)
 122                result |= ADVERTISE_100HALF;
 123        if (ethadv & ADVERTISED_100baseT_Full)
 124                result |= ADVERTISE_100FULL;
 125        if (ethadv & ADVERTISED_Pause)
 126                result |= ADVERTISE_PAUSE_CAP;
 127        if (ethadv & ADVERTISED_Asym_Pause)
 128                result |= ADVERTISE_PAUSE_ASYM;
 129
 130        return result;
 131}
 132
 133/**
 134 * mii_adv_to_ethtool_adv_t
 135 * @adv: value of the MII_ADVERTISE register
 136 *
 137 * A small helper function that translates MII_ADVERTISE bits
 138 * to ethtool advertisement settings.
 139 */
 140static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
 141{
 142        u32 result = 0;
 143
 144        if (adv & ADVERTISE_10HALF)
 145                result |= ADVERTISED_10baseT_Half;
 146        if (adv & ADVERTISE_10FULL)
 147                result |= ADVERTISED_10baseT_Full;
 148        if (adv & ADVERTISE_100HALF)
 149                result |= ADVERTISED_100baseT_Half;
 150        if (adv & ADVERTISE_100FULL)
 151                result |= ADVERTISED_100baseT_Full;
 152        if (adv & ADVERTISE_PAUSE_CAP)
 153                result |= ADVERTISED_Pause;
 154        if (adv & ADVERTISE_PAUSE_ASYM)
 155                result |= ADVERTISED_Asym_Pause;
 156
 157        return result;
 158}
 159
 160/**
 161 * ethtool_adv_to_mii_ctrl1000_t
 162 * @ethadv: the ethtool advertisement settings
 163 *
 164 * A small helper function that translates ethtool advertisement
 165 * settings to phy autonegotiation advertisements for the
 166 * MII_CTRL1000 register when in 1000T mode.
 167 */
 168static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
 169{
 170        u32 result = 0;
 171
 172        if (ethadv & ADVERTISED_1000baseT_Half)
 173                result |= ADVERTISE_1000HALF;
 174        if (ethadv & ADVERTISED_1000baseT_Full)
 175                result |= ADVERTISE_1000FULL;
 176
 177        return result;
 178}
 179
 180/**
 181 * mii_ctrl1000_to_ethtool_adv_t
 182 * @adv: value of the MII_CTRL1000 register
 183 *
 184 * A small helper function that translates MII_CTRL1000
 185 * bits, when in 1000Base-T mode, to ethtool
 186 * advertisement settings.
 187 */
 188static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
 189{
 190        u32 result = 0;
 191
 192        if (adv & ADVERTISE_1000HALF)
 193                result |= ADVERTISED_1000baseT_Half;
 194        if (adv & ADVERTISE_1000FULL)
 195                result |= ADVERTISED_1000baseT_Full;
 196
 197        return result;
 198}
 199
 200/**
 201 * mii_lpa_to_ethtool_lpa_t
 202 * @adv: value of the MII_LPA register
 203 *
 204 * A small helper function that translates MII_LPA
 205 * bits, when in 1000Base-T mode, to ethtool
 206 * LP advertisement settings.
 207 */
 208static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
 209{
 210        u32 result = 0;
 211
 212        if (lpa & LPA_LPACK)
 213                result |= ADVERTISED_Autoneg;
 214
 215        return result | mii_adv_to_ethtool_adv_t(lpa);
 216}
 217
 218/**
 219 * mii_stat1000_to_ethtool_lpa_t
 220 * @adv: value of the MII_STAT1000 register
 221 *
 222 * A small helper function that translates MII_STAT1000
 223 * bits, when in 1000Base-T mode, to ethtool
 224 * advertisement settings.
 225 */
 226static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
 227{
 228        u32 result = 0;
 229
 230        if (lpa & LPA_1000HALF)
 231                result |= ADVERTISED_1000baseT_Half;
 232        if (lpa & LPA_1000FULL)
 233                result |= ADVERTISED_1000baseT_Full;
 234
 235        return result;
 236}
 237
 238/**
 239 * ethtool_adv_to_mii_adv_x
 240 * @ethadv: the ethtool advertisement settings
 241 *
 242 * A small helper function that translates ethtool advertisement
 243 * settings to phy autonegotiation advertisements for the
 244 * MII_CTRL1000 register when in 1000Base-X mode.
 245 */
 246static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
 247{
 248        u32 result = 0;
 249
 250        if (ethadv & ADVERTISED_1000baseT_Half)
 251                result |= ADVERTISE_1000XHALF;
 252        if (ethadv & ADVERTISED_1000baseT_Full)
 253                result |= ADVERTISE_1000XFULL;
 254        if (ethadv & ADVERTISED_Pause)
 255                result |= ADVERTISE_1000XPAUSE;
 256        if (ethadv & ADVERTISED_Asym_Pause)
 257                result |= ADVERTISE_1000XPSE_ASYM;
 258
 259        return result;
 260}
 261
 262/**
 263 * mii_adv_to_ethtool_adv_x
 264 * @adv: value of the MII_CTRL1000 register
 265 *
 266 * A small helper function that translates MII_CTRL1000
 267 * bits, when in 1000Base-X mode, to ethtool
 268 * advertisement settings.
 269 */
 270static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
 271{
 272        u32 result = 0;
 273
 274        if (adv & ADVERTISE_1000XHALF)
 275                result |= ADVERTISED_1000baseT_Half;
 276        if (adv & ADVERTISE_1000XFULL)
 277                result |= ADVERTISED_1000baseT_Full;
 278        if (adv & ADVERTISE_1000XPAUSE)
 279                result |= ADVERTISED_Pause;
 280        if (adv & ADVERTISE_1000XPSE_ASYM)
 281                result |= ADVERTISED_Asym_Pause;
 282
 283        return result;
 284}
 285
 286/**
 287 * mii_lpa_to_ethtool_lpa_x
 288 * @adv: value of the MII_LPA register
 289 *
 290 * A small helper function that translates MII_LPA
 291 * bits, when in 1000Base-X mode, to ethtool
 292 * LP advertisement settings.
 293 */
 294static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
 295{
 296        u32 result = 0;
 297
 298        if (lpa & LPA_LPACK)
 299                result |= ADVERTISED_Autoneg;
 300
 301        return result | mii_adv_to_ethtool_adv_x(lpa);
 302}
 303
 304/**
 305 * mii_advertise_flowctrl - get flow control advertisement flags
 306 * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
 307 */
 308static inline u16 mii_advertise_flowctrl(int cap)
 309{
 310        u16 adv = 0;
 311
 312        if (cap & FLOW_CTRL_RX)
 313                adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 314        if (cap & FLOW_CTRL_TX)
 315                adv ^= ADVERTISE_PAUSE_ASYM;
 316
 317        return adv;
 318}
 319
 320/**
 321 * mii_resolve_flowctrl_fdx
 322 * @lcladv: value of MII ADVERTISE register
 323 * @rmtadv: value of MII LPA register
 324 *
 325 * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3
 326 */
 327static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
 328{
 329        u8 cap = 0;
 330
 331        if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
 332                cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
 333        } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
 334                if (lcladv & ADVERTISE_PAUSE_CAP)
 335                        cap = FLOW_CTRL_RX;
 336                else if (rmtadv & ADVERTISE_PAUSE_CAP)
 337                        cap = FLOW_CTRL_TX;
 338        }
 339
 340        return cap;
 341}
 342
 343#endif /* __LINUX_MII_H__ */
 344