Home | History | Annotate | Line # | Download | only in cxgb
cxgb_mv88e1xxx.c revision 1.1.2.2
      1  1.1.2.2  uebayasi /**************************************************************************
      2  1.1.2.2  uebayasi 
      3  1.1.2.2  uebayasi Copyright (c) 2007, Chelsio Inc.
      4  1.1.2.2  uebayasi All rights reserved.
      5  1.1.2.2  uebayasi 
      6  1.1.2.2  uebayasi Redistribution and use in source and binary forms, with or without
      7  1.1.2.2  uebayasi modification, are permitted provided that the following conditions are met:
      8  1.1.2.2  uebayasi 
      9  1.1.2.2  uebayasi  1. Redistributions of source code must retain the above copyright notice,
     10  1.1.2.2  uebayasi     this list of conditions and the following disclaimer.
     11  1.1.2.2  uebayasi 
     12  1.1.2.2  uebayasi  2. Neither the name of the Chelsio Corporation nor the names of its
     13  1.1.2.2  uebayasi     contributors may be used to endorse or promote products derived from
     14  1.1.2.2  uebayasi     this software without specific prior written permission.
     15  1.1.2.2  uebayasi 
     16  1.1.2.2  uebayasi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17  1.1.2.2  uebayasi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  1.1.2.2  uebayasi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  1.1.2.2  uebayasi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     20  1.1.2.2  uebayasi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  1.1.2.2  uebayasi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  1.1.2.2  uebayasi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  1.1.2.2  uebayasi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  1.1.2.2  uebayasi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  1.1.2.2  uebayasi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  1.1.2.2  uebayasi POSSIBILITY OF SUCH DAMAGE.
     27  1.1.2.2  uebayasi 
     28  1.1.2.2  uebayasi ***************************************************************************/
     29  1.1.2.2  uebayasi 
     30  1.1.2.2  uebayasi #include <sys/cdefs.h>
     31  1.1.2.2  uebayasi __KERNEL_RCSID(0, "$NetBSD: cxgb_mv88e1xxx.c,v 1.1.2.2 2010/04/30 14:43:45 uebayasi Exp $");
     32  1.1.2.2  uebayasi 
     33  1.1.2.2  uebayasi #ifdef CONFIG_DEFINED
     34  1.1.2.2  uebayasi #include <cxgb_include.h>
     35  1.1.2.2  uebayasi #else
     36  1.1.2.2  uebayasi #include <dev/pci/cxgb/cxgb_include.h>
     37  1.1.2.2  uebayasi #endif
     38  1.1.2.2  uebayasi 
     39  1.1.2.2  uebayasi /* Marvell PHY interrupt status bits. */
     40  1.1.2.2  uebayasi #define MV_INTR_JABBER          0x0001
     41  1.1.2.2  uebayasi #define MV_INTR_POLARITY_CHNG   0x0002
     42  1.1.2.2  uebayasi #define MV_INTR_ENG_DETECT_CHNG 0x0010
     43  1.1.2.2  uebayasi #define MV_INTR_DOWNSHIFT       0x0020
     44  1.1.2.2  uebayasi #define MV_INTR_MDI_XOVER_CHNG  0x0040
     45  1.1.2.2  uebayasi #define MV_INTR_FIFO_OVER_UNDER 0x0080
     46  1.1.2.2  uebayasi #define MV_INTR_FALSE_CARRIER   0x0100
     47  1.1.2.2  uebayasi #define MV_INTR_SYMBOL_ERROR    0x0200
     48  1.1.2.2  uebayasi #define MV_INTR_LINK_CHNG       0x0400
     49  1.1.2.2  uebayasi #define MV_INTR_AUTONEG_DONE    0x0800
     50  1.1.2.2  uebayasi #define MV_INTR_PAGE_RECV       0x1000
     51  1.1.2.2  uebayasi #define MV_INTR_DUPLEX_CHNG     0x2000
     52  1.1.2.2  uebayasi #define MV_INTR_SPEED_CHNG      0x4000
     53  1.1.2.2  uebayasi #define MV_INTR_AUTONEG_ERR     0x8000
     54  1.1.2.2  uebayasi 
     55  1.1.2.2  uebayasi /* Marvell PHY specific registers. */
     56  1.1.2.2  uebayasi #define MV88E1XXX_SPECIFIC_CNTRL          16
     57  1.1.2.2  uebayasi #define MV88E1XXX_SPECIFIC_STATUS         17
     58  1.1.2.2  uebayasi #define MV88E1XXX_INTR_ENABLE             18
     59  1.1.2.2  uebayasi #define MV88E1XXX_INTR_STATUS             19
     60  1.1.2.2  uebayasi #define MV88E1XXX_EXT_SPECIFIC_CNTRL      20
     61  1.1.2.2  uebayasi #define MV88E1XXX_RECV_ERR                21
     62  1.1.2.2  uebayasi #define MV88E1XXX_EXT_ADDR                22
     63  1.1.2.2  uebayasi #define MV88E1XXX_GLOBAL_STATUS           23
     64  1.1.2.2  uebayasi #define MV88E1XXX_LED_CNTRL               24
     65  1.1.2.2  uebayasi #define MV88E1XXX_LED_OVERRIDE            25
     66  1.1.2.2  uebayasi #define MV88E1XXX_EXT_SPECIFIC_CNTRL2     26
     67  1.1.2.2  uebayasi #define MV88E1XXX_EXT_SPECIFIC_STATUS     27
     68  1.1.2.2  uebayasi #define MV88E1XXX_VIRTUAL_CABLE_TESTER    28
     69  1.1.2.2  uebayasi #define MV88E1XXX_EXTENDED_ADDR           29
     70  1.1.2.2  uebayasi #define MV88E1XXX_EXTENDED_DATA           30
     71  1.1.2.2  uebayasi 
     72  1.1.2.2  uebayasi /* PHY specific control register fields */
     73  1.1.2.2  uebayasi #define S_PSCR_MDI_XOVER_MODE    5
     74  1.1.2.2  uebayasi #define M_PSCR_MDI_XOVER_MODE    0x3
     75  1.1.2.2  uebayasi #define V_PSCR_MDI_XOVER_MODE(x) ((x) << S_PSCR_MDI_XOVER_MODE)
     76  1.1.2.2  uebayasi 
     77  1.1.2.2  uebayasi /* Extended PHY specific control register fields */
     78  1.1.2.2  uebayasi #define S_DOWNSHIFT_ENABLE 8
     79  1.1.2.2  uebayasi #define V_DOWNSHIFT_ENABLE (1 << S_DOWNSHIFT_ENABLE)
     80  1.1.2.2  uebayasi 
     81  1.1.2.2  uebayasi #define S_DOWNSHIFT_CNT    9
     82  1.1.2.2  uebayasi #define M_DOWNSHIFT_CNT    0x7
     83  1.1.2.2  uebayasi #define V_DOWNSHIFT_CNT(x) ((x) << S_DOWNSHIFT_CNT)
     84  1.1.2.2  uebayasi 
     85  1.1.2.2  uebayasi /* PHY specific status register fields */
     86  1.1.2.2  uebayasi #define S_PSSR_JABBER 0
     87  1.1.2.2  uebayasi #define V_PSSR_JABBER (1 << S_PSSR_JABBER)
     88  1.1.2.2  uebayasi 
     89  1.1.2.2  uebayasi #define S_PSSR_POLARITY 1
     90  1.1.2.2  uebayasi #define V_PSSR_POLARITY (1 << S_PSSR_POLARITY)
     91  1.1.2.2  uebayasi 
     92  1.1.2.2  uebayasi #define S_PSSR_RX_PAUSE 2
     93  1.1.2.2  uebayasi #define V_PSSR_RX_PAUSE (1 << S_PSSR_RX_PAUSE)
     94  1.1.2.2  uebayasi 
     95  1.1.2.2  uebayasi #define S_PSSR_TX_PAUSE 3
     96  1.1.2.2  uebayasi #define V_PSSR_TX_PAUSE (1 << S_PSSR_TX_PAUSE)
     97  1.1.2.2  uebayasi 
     98  1.1.2.2  uebayasi #define S_PSSR_ENERGY_DETECT 4
     99  1.1.2.2  uebayasi #define V_PSSR_ENERGY_DETECT (1 << S_PSSR_ENERGY_DETECT)
    100  1.1.2.2  uebayasi 
    101  1.1.2.2  uebayasi #define S_PSSR_DOWNSHIFT_STATUS 5
    102  1.1.2.2  uebayasi #define V_PSSR_DOWNSHIFT_STATUS (1 << S_PSSR_DOWNSHIFT_STATUS)
    103  1.1.2.2  uebayasi 
    104  1.1.2.2  uebayasi #define S_PSSR_MDI 6
    105  1.1.2.2  uebayasi #define V_PSSR_MDI (1 << S_PSSR_MDI)
    106  1.1.2.2  uebayasi 
    107  1.1.2.2  uebayasi #define S_PSSR_CABLE_LEN    7
    108  1.1.2.2  uebayasi #define M_PSSR_CABLE_LEN    0x7
    109  1.1.2.2  uebayasi #define V_PSSR_CABLE_LEN(x) ((x) << S_PSSR_CABLE_LEN)
    110  1.1.2.2  uebayasi #define G_PSSR_CABLE_LEN(x) (((x) >> S_PSSR_CABLE_LEN) & M_PSSR_CABLE_LEN)
    111  1.1.2.2  uebayasi 
    112  1.1.2.2  uebayasi #define S_PSSR_LINK 10
    113  1.1.2.2  uebayasi #define V_PSSR_LINK (1 << S_PSSR_LINK)
    114  1.1.2.2  uebayasi 
    115  1.1.2.2  uebayasi #define S_PSSR_STATUS_RESOLVED 11
    116  1.1.2.2  uebayasi #define V_PSSR_STATUS_RESOLVED (1 << S_PSSR_STATUS_RESOLVED)
    117  1.1.2.2  uebayasi 
    118  1.1.2.2  uebayasi #define S_PSSR_PAGE_RECEIVED 12
    119  1.1.2.2  uebayasi #define V_PSSR_PAGE_RECEIVED (1 << S_PSSR_PAGE_RECEIVED)
    120  1.1.2.2  uebayasi 
    121  1.1.2.2  uebayasi #define S_PSSR_DUPLEX 13
    122  1.1.2.2  uebayasi #define V_PSSR_DUPLEX (1 << S_PSSR_DUPLEX)
    123  1.1.2.2  uebayasi 
    124  1.1.2.2  uebayasi #define S_PSSR_SPEED    14
    125  1.1.2.2  uebayasi #define M_PSSR_SPEED    0x3
    126  1.1.2.2  uebayasi #define V_PSSR_SPEED(x) ((x) << S_PSSR_SPEED)
    127  1.1.2.2  uebayasi #define G_PSSR_SPEED(x) (((x) >> S_PSSR_SPEED) & M_PSSR_SPEED)
    128  1.1.2.2  uebayasi 
    129  1.1.2.2  uebayasi /* MV88E1XXX MDI crossover register values */
    130  1.1.2.2  uebayasi #define CROSSOVER_MDI   0
    131  1.1.2.2  uebayasi #define CROSSOVER_MDIX  1
    132  1.1.2.2  uebayasi #define CROSSOVER_AUTO  3
    133  1.1.2.2  uebayasi 
    134  1.1.2.2  uebayasi #define INTR_ENABLE_MASK (MV_INTR_SPEED_CHNG | MV_INTR_DUPLEX_CHNG | \
    135  1.1.2.2  uebayasi     MV_INTR_AUTONEG_DONE | MV_INTR_LINK_CHNG | MV_INTR_FIFO_OVER_UNDER | \
    136  1.1.2.2  uebayasi     MV_INTR_ENG_DETECT_CHNG)
    137  1.1.2.2  uebayasi 
    138  1.1.2.2  uebayasi /*
    139  1.1.2.2  uebayasi  * Reset the PHY.  If 'wait' is set wait until the reset completes.
    140  1.1.2.2  uebayasi  */
    141  1.1.2.2  uebayasi static int mv88e1xxx_reset(struct cphy *cphy, int wait)
    142  1.1.2.2  uebayasi {
    143  1.1.2.2  uebayasi     return t3_phy_reset(cphy, 0, wait);
    144  1.1.2.2  uebayasi }
    145  1.1.2.2  uebayasi 
    146  1.1.2.2  uebayasi static int mv88e1xxx_intr_enable(struct cphy *cphy)
    147  1.1.2.2  uebayasi {
    148  1.1.2.2  uebayasi     return mdio_write(cphy, 0, MV88E1XXX_INTR_ENABLE, INTR_ENABLE_MASK);
    149  1.1.2.2  uebayasi }
    150  1.1.2.2  uebayasi 
    151  1.1.2.2  uebayasi static int mv88e1xxx_intr_disable(struct cphy *cphy)
    152  1.1.2.2  uebayasi {
    153  1.1.2.2  uebayasi     return mdio_write(cphy, 0, MV88E1XXX_INTR_ENABLE, 0);
    154  1.1.2.2  uebayasi }
    155  1.1.2.2  uebayasi 
    156  1.1.2.2  uebayasi static int mv88e1xxx_intr_clear(struct cphy *cphy)
    157  1.1.2.2  uebayasi {
    158  1.1.2.2  uebayasi     u32 val;
    159  1.1.2.2  uebayasi 
    160  1.1.2.2  uebayasi     /* Clear PHY interrupts by reading the register. */
    161  1.1.2.2  uebayasi     return mdio_read(cphy, 0, MV88E1XXX_INTR_STATUS, &val);
    162  1.1.2.2  uebayasi }
    163  1.1.2.2  uebayasi 
    164  1.1.2.2  uebayasi static int mv88e1xxx_crossover_set(struct cphy *cphy, int crossover)
    165  1.1.2.2  uebayasi {
    166  1.1.2.2  uebayasi     return t3_mdio_change_bits(cphy, 0, MV88E1XXX_SPECIFIC_CNTRL,
    167  1.1.2.2  uebayasi                    V_PSCR_MDI_XOVER_MODE(M_PSCR_MDI_XOVER_MODE),
    168  1.1.2.2  uebayasi                    V_PSCR_MDI_XOVER_MODE(crossover));
    169  1.1.2.2  uebayasi }
    170  1.1.2.2  uebayasi 
    171  1.1.2.2  uebayasi static int mv88e1xxx_autoneg_enable(struct cphy *cphy)
    172  1.1.2.2  uebayasi {
    173  1.1.2.2  uebayasi     mv88e1xxx_crossover_set(cphy, CROSSOVER_AUTO);
    174  1.1.2.2  uebayasi 
    175  1.1.2.2  uebayasi     /* restart autoneg for change to take effect */
    176  1.1.2.2  uebayasi     return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
    177  1.1.2.2  uebayasi                    BMCR_ANENABLE | BMCR_ANRESTART);
    178  1.1.2.2  uebayasi }
    179  1.1.2.2  uebayasi 
    180  1.1.2.2  uebayasi static int mv88e1xxx_autoneg_restart(struct cphy *cphy)
    181  1.1.2.2  uebayasi {
    182  1.1.2.2  uebayasi     return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
    183  1.1.2.2  uebayasi                    BMCR_ANRESTART);
    184  1.1.2.2  uebayasi }
    185  1.1.2.2  uebayasi 
    186  1.1.2.2  uebayasi static int mv88e1xxx_set_loopback(struct cphy *cphy, int mmd, int dir, int on)
    187  1.1.2.2  uebayasi {
    188  1.1.2.2  uebayasi     return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_LOOPBACK,
    189  1.1.2.2  uebayasi                    on ? BMCR_LOOPBACK : 0);
    190  1.1.2.2  uebayasi }
    191  1.1.2.2  uebayasi 
    192  1.1.2.2  uebayasi static int mv88e1xxx_get_link_status(struct cphy *cphy, int *link_ok,
    193  1.1.2.2  uebayasi                      int *speed, int *duplex, int *fc)
    194  1.1.2.2  uebayasi {
    195  1.1.2.2  uebayasi     u32 status;
    196  1.1.2.2  uebayasi     int sp = -1, dplx = -1, pause = 0;
    197  1.1.2.2  uebayasi 
    198  1.1.2.2  uebayasi     mdio_read(cphy, 0, MV88E1XXX_SPECIFIC_STATUS, &status);
    199  1.1.2.2  uebayasi     if ((status & V_PSSR_STATUS_RESOLVED) != 0) {
    200  1.1.2.2  uebayasi         if (status & V_PSSR_RX_PAUSE)
    201  1.1.2.2  uebayasi             pause |= PAUSE_RX;
    202  1.1.2.2  uebayasi         if (status & V_PSSR_TX_PAUSE)
    203  1.1.2.2  uebayasi             pause |= PAUSE_TX;
    204  1.1.2.2  uebayasi         dplx = (status & V_PSSR_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF;
    205  1.1.2.2  uebayasi         sp = G_PSSR_SPEED(status);
    206  1.1.2.2  uebayasi         if (sp == 0)
    207  1.1.2.2  uebayasi             sp = SPEED_10;
    208  1.1.2.2  uebayasi         else if (sp == 1)
    209  1.1.2.2  uebayasi             sp = SPEED_100;
    210  1.1.2.2  uebayasi         else
    211  1.1.2.2  uebayasi             sp = SPEED_1000;
    212  1.1.2.2  uebayasi     }
    213  1.1.2.2  uebayasi     if (link_ok)
    214  1.1.2.2  uebayasi         *link_ok = (status & V_PSSR_LINK) != 0;
    215  1.1.2.2  uebayasi     if (speed)
    216  1.1.2.2  uebayasi         *speed = sp;
    217  1.1.2.2  uebayasi     if (duplex)
    218  1.1.2.2  uebayasi         *duplex = dplx;
    219  1.1.2.2  uebayasi     if (fc)
    220  1.1.2.2  uebayasi         *fc = pause;
    221  1.1.2.2  uebayasi     return 0;
    222  1.1.2.2  uebayasi }
    223  1.1.2.2  uebayasi 
    224  1.1.2.2  uebayasi static int mv88e1xxx_downshift_set(struct cphy *cphy, int downshift_enable)
    225  1.1.2.2  uebayasi {
    226  1.1.2.2  uebayasi     /*
    227  1.1.2.2  uebayasi      * Set the downshift counter to 2 so we try to establish Gb link
    228  1.1.2.2  uebayasi      * twice before downshifting.
    229  1.1.2.2  uebayasi      */
    230  1.1.2.2  uebayasi     return t3_mdio_change_bits(cphy, 0, MV88E1XXX_EXT_SPECIFIC_CNTRL,
    231  1.1.2.2  uebayasi         V_DOWNSHIFT_ENABLE | V_DOWNSHIFT_CNT(M_DOWNSHIFT_CNT),
    232  1.1.2.2  uebayasi         downshift_enable ? V_DOWNSHIFT_ENABLE | V_DOWNSHIFT_CNT(2) : 0);
    233  1.1.2.2  uebayasi }
    234  1.1.2.2  uebayasi 
    235  1.1.2.2  uebayasi static int mv88e1xxx_power_down(struct cphy *cphy, int enable)
    236  1.1.2.2  uebayasi {
    237  1.1.2.2  uebayasi     return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN,
    238  1.1.2.2  uebayasi                    enable ? BMCR_PDOWN : 0);
    239  1.1.2.2  uebayasi }
    240  1.1.2.2  uebayasi 
    241  1.1.2.2  uebayasi static int mv88e1xxx_intr_handler(struct cphy *cphy)
    242  1.1.2.2  uebayasi {
    243  1.1.2.2  uebayasi     const u32 link_change_intrs = MV_INTR_LINK_CHNG |
    244  1.1.2.2  uebayasi         MV_INTR_AUTONEG_DONE | MV_INTR_DUPLEX_CHNG |
    245  1.1.2.2  uebayasi         MV_INTR_SPEED_CHNG | MV_INTR_DOWNSHIFT;
    246  1.1.2.2  uebayasi 
    247  1.1.2.2  uebayasi     u32 cause;
    248  1.1.2.2  uebayasi     int cphy_cause = 0;
    249  1.1.2.2  uebayasi 
    250  1.1.2.2  uebayasi     mdio_read(cphy, 0, MV88E1XXX_INTR_STATUS, &cause);
    251  1.1.2.2  uebayasi     cause &= INTR_ENABLE_MASK;
    252  1.1.2.2  uebayasi     if (cause & link_change_intrs)
    253  1.1.2.2  uebayasi         cphy_cause |= cphy_cause_link_change;
    254  1.1.2.2  uebayasi     if (cause & MV_INTR_FIFO_OVER_UNDER)
    255  1.1.2.2  uebayasi         cphy_cause |= cphy_cause_fifo_error;
    256  1.1.2.2  uebayasi     return cphy_cause;
    257  1.1.2.2  uebayasi }
    258  1.1.2.2  uebayasi 
    259  1.1.2.2  uebayasi #ifdef C99_NOT_SUPPORTED
    260  1.1.2.2  uebayasi static struct cphy_ops mv88e1xxx_ops = {
    261  1.1.2.2  uebayasi     NULL,
    262  1.1.2.2  uebayasi     mv88e1xxx_reset,
    263  1.1.2.2  uebayasi     mv88e1xxx_intr_enable,
    264  1.1.2.2  uebayasi     mv88e1xxx_intr_disable,
    265  1.1.2.2  uebayasi     mv88e1xxx_intr_clear,
    266  1.1.2.2  uebayasi     mv88e1xxx_intr_handler,
    267  1.1.2.2  uebayasi     mv88e1xxx_autoneg_enable,
    268  1.1.2.2  uebayasi     mv88e1xxx_autoneg_restart,
    269  1.1.2.2  uebayasi     t3_phy_advertise,
    270  1.1.2.2  uebayasi     mv88e1xxx_set_loopback,
    271  1.1.2.2  uebayasi     t3_set_phy_speed_duplex,
    272  1.1.2.2  uebayasi     mv88e1xxx_get_link_status,
    273  1.1.2.2  uebayasi     mv88e1xxx_power_down,
    274  1.1.2.2  uebayasi };
    275  1.1.2.2  uebayasi #else
    276  1.1.2.2  uebayasi static struct cphy_ops mv88e1xxx_ops = {
    277  1.1.2.2  uebayasi     .reset             = mv88e1xxx_reset,
    278  1.1.2.2  uebayasi     .intr_enable       = mv88e1xxx_intr_enable,
    279  1.1.2.2  uebayasi     .intr_disable      = mv88e1xxx_intr_disable,
    280  1.1.2.2  uebayasi     .intr_clear        = mv88e1xxx_intr_clear,
    281  1.1.2.2  uebayasi     .intr_handler      = mv88e1xxx_intr_handler,
    282  1.1.2.2  uebayasi     .autoneg_enable    = mv88e1xxx_autoneg_enable,
    283  1.1.2.2  uebayasi     .autoneg_restart   = mv88e1xxx_autoneg_restart,
    284  1.1.2.2  uebayasi     .advertise         = t3_phy_advertise,
    285  1.1.2.2  uebayasi     .set_loopback      = mv88e1xxx_set_loopback,
    286  1.1.2.2  uebayasi     .set_speed_duplex  = t3_set_phy_speed_duplex,
    287  1.1.2.2  uebayasi     .get_link_status   = mv88e1xxx_get_link_status,
    288  1.1.2.2  uebayasi     .power_down        = mv88e1xxx_power_down,
    289  1.1.2.2  uebayasi };
    290  1.1.2.2  uebayasi #endif
    291  1.1.2.2  uebayasi 
    292  1.1.2.2  uebayasi void t3_mv88e1xxx_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
    293  1.1.2.2  uebayasi                const struct mdio_ops *mdio_ops)
    294  1.1.2.2  uebayasi {
    295  1.1.2.2  uebayasi     cphy_init(phy, adapter, phy_addr, &mv88e1xxx_ops, mdio_ops);
    296  1.1.2.2  uebayasi 
    297  1.1.2.2  uebayasi     /* Configure copper PHY transmitter as class A to reduce EMI. */
    298  1.1.2.2  uebayasi     mdio_write(phy, 0, MV88E1XXX_EXTENDED_ADDR, 0xb);
    299  1.1.2.2  uebayasi     mdio_write(phy, 0, MV88E1XXX_EXTENDED_DATA, 0x8004);
    300  1.1.2.2  uebayasi 
    301  1.1.2.2  uebayasi     mv88e1xxx_downshift_set(phy, 1);   /* Enable downshift */
    302  1.1.2.2  uebayasi }
    303