The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/cxgb/common/cxgb_ael1002.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /**************************************************************************
    2 
    3 Copyright (c) 2007, Chelsio Inc.
    4 All rights reserved.
    5 
    6 Redistribution and use in source and binary forms, with or without
    7 modification, are permitted provided that the following conditions are met:
    8 
    9  1. Redistributions of source code must retain the above copyright notice,
   10     this list of conditions and the following disclaimer.
   11 
   12  2. Neither the name of the Chelsio Corporation nor the names of its
   13     contributors may be used to endorse or promote products derived from
   14     this software without specific prior written permission.
   15 
   16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   26 POSSIBILITY OF SUCH DAMAGE.
   27 
   28 ***************************************************************************/
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/6.4/sys/dev/cxgb/common/cxgb_ael1002.c 170900 2007-06-17 23:52:17Z kmacy $");
   32 
   33 #ifdef CONFIG_DEFINED
   34 #include <cxgb_include.h>
   35 #else
   36 #include <dev/cxgb/cxgb_include.h>
   37 #endif
   38 
   39 enum {
   40         AEL100X_TX_DISABLE  = 9,
   41         AEL100X_TX_CONFIG1  = 0xc002,
   42         AEL1002_PWR_DOWN_HI = 0xc011,
   43         AEL1002_PWR_DOWN_LO = 0xc012,
   44         AEL1002_XFI_EQL     = 0xc015,
   45         AEL1002_LB_EN       = 0xc017,
   46 
   47         LASI_CTRL   = 0x9002,
   48         LASI_STAT   = 0x9005
   49 };
   50 
   51 static void ael100x_txon(struct cphy *phy)
   52 {
   53         int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
   54 
   55         t3_os_sleep(100);
   56         t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
   57         t3_os_sleep(30);
   58 }
   59 
   60 static int ael1002_power_down(struct cphy *phy, int enable)
   61 {
   62         int err;
   63 
   64         err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
   65         if (!err)
   66                 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
   67                                           BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
   68         return err;
   69 }
   70 
   71 static int ael1002_reset(struct cphy *phy, int wait)
   72 {
   73         int err;
   74 
   75         if ((err = ael1002_power_down(phy, 0)) ||
   76             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
   77             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
   78             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
   79             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
   80             (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
   81                                        0, 1 << 5)))
   82                 return err;
   83         return 0;
   84 }
   85 
   86 static int ael1002_intr_noop(struct cphy *phy)
   87 {
   88         return 0;
   89 }
   90 
   91 static int ael100x_get_link_status(struct cphy *phy, int *link_ok,
   92                                    int *speed, int *duplex, int *fc)
   93 {
   94         if (link_ok) {
   95                 unsigned int status;
   96                 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &status);
   97 
   98                 /*
   99                  * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
  100                  * once more to get the current link state.
  101                  */
  102                 if (!err && !(status & BMSR_LSTATUS))
  103                         err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR,
  104                                         &status);
  105                 if (err)
  106                         return err;
  107                 *link_ok = !!(status & BMSR_LSTATUS);
  108         }
  109         if (speed)
  110                 *speed = SPEED_10000;
  111         if (duplex)
  112                 *duplex = DUPLEX_FULL;
  113         return 0;
  114 }
  115 
  116 #ifdef C99_NOT_SUPPORTED
  117 static struct cphy_ops ael1002_ops = {
  118         NULL,
  119         ael1002_reset,
  120         ael1002_intr_noop,
  121         ael1002_intr_noop,
  122         ael1002_intr_noop,
  123         ael1002_intr_noop,
  124         NULL,
  125         NULL,
  126         NULL,
  127         NULL,
  128         NULL,
  129         ael100x_get_link_status,
  130         ael1002_power_down,
  131 };
  132 #else
  133 static struct cphy_ops ael1002_ops = {
  134         .reset           = ael1002_reset,
  135         .intr_enable     = ael1002_intr_noop,
  136         .intr_disable    = ael1002_intr_noop,
  137         .intr_clear      = ael1002_intr_noop,
  138         .intr_handler    = ael1002_intr_noop,
  139         .get_link_status = ael100x_get_link_status,
  140         .power_down      = ael1002_power_down,
  141 };
  142 #endif
  143 
  144 void t3_ael1002_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
  145                          const struct mdio_ops *mdio_ops)
  146 {
  147         cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops);
  148         ael100x_txon(phy);
  149 }
  150 
  151 static int ael1006_reset(struct cphy *phy, int wait)
  152 {
  153         return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
  154 }
  155 
  156 static int ael1006_intr_enable(struct cphy *phy)
  157 {
  158         return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
  159 }
  160 
  161 static int ael1006_intr_disable(struct cphy *phy)
  162 {
  163         return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
  164 }
  165 
  166 static int ael1006_intr_clear(struct cphy *phy)
  167 {
  168         u32 val;
  169 
  170         return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
  171 }
  172 
  173 static int ael1006_intr_handler(struct cphy *phy)
  174 {
  175         unsigned int status;
  176         int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
  177 
  178         if (err)
  179                 return err;
  180         return (status & 1) ?  cphy_cause_link_change : 0;
  181 }
  182 
  183 static int ael1006_power_down(struct cphy *phy, int enable)
  184 {
  185         return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
  186                                    BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
  187 }
  188 
  189 #ifdef C99_NOT_SUPPORTED
  190 static struct cphy_ops ael1006_ops = {
  191         NULL,
  192         ael1006_reset,
  193         ael1006_intr_enable,
  194         ael1006_intr_disable,
  195         ael1006_intr_clear,
  196         ael1006_intr_handler,
  197         NULL,
  198         NULL,
  199         NULL,
  200         NULL,
  201         NULL,
  202         ael100x_get_link_status,
  203         ael1006_power_down,
  204 };
  205 #else
  206 static struct cphy_ops ael1006_ops = {
  207         .reset           = ael1006_reset,
  208         .intr_enable     = ael1006_intr_enable,
  209         .intr_disable    = ael1006_intr_disable,
  210         .intr_clear      = ael1006_intr_clear,
  211         .intr_handler    = ael1006_intr_handler,
  212         .get_link_status = ael100x_get_link_status,
  213         .power_down      = ael1006_power_down,
  214 };
  215 #endif
  216 
  217 void t3_ael1006_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
  218                          const struct mdio_ops *mdio_ops)
  219 {
  220         cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops);
  221         ael100x_txon(phy);
  222 }
  223 
  224 #ifdef C99_NOT_SUPPORTED
  225 static struct cphy_ops qt2045_ops = {
  226         NULL,
  227         ael1006_reset,
  228         ael1006_intr_enable,
  229         ael1006_intr_disable,
  230         ael1006_intr_clear,
  231         ael1006_intr_handler,
  232         NULL,
  233         NULL,
  234         NULL,
  235         NULL,
  236         NULL,
  237         ael100x_get_link_status,
  238         ael1006_power_down,
  239 };
  240 #else
  241 static struct cphy_ops qt2045_ops = {
  242         .reset           = ael1006_reset,
  243         .intr_enable     = ael1006_intr_enable,
  244         .intr_disable    = ael1006_intr_disable,
  245         .intr_clear      = ael1006_intr_clear,
  246         .intr_handler    = ael1006_intr_handler,
  247         .get_link_status = ael100x_get_link_status,
  248         .power_down      = ael1006_power_down,
  249 };
  250 #endif
  251 
  252 void t3_qt2045_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
  253                         const struct mdio_ops *mdio_ops)
  254 {
  255         unsigned int stat;
  256 
  257         cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops);
  258 
  259         /*
  260          * Some cards where the PHY is supposed to be at address 0 actually
  261          * have it at 1.
  262          */
  263         if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
  264             stat == 0xffff)
  265                 phy->addr = 1;
  266 }
  267 
  268 static int xaui_direct_reset(struct cphy *phy, int wait)
  269 {
  270         return 0;
  271 }
  272 
  273 static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
  274                                        int *speed, int *duplex, int *fc)
  275 {
  276         if (link_ok) {
  277                 unsigned int status;
  278                 
  279                 status = t3_read_reg(phy->adapter,
  280                                      XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
  281                          t3_read_reg(phy->adapter,
  282                                      XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
  283                          t3_read_reg(phy->adapter,
  284                                      XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
  285                          t3_read_reg(phy->adapter,
  286                                      XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
  287                 *link_ok = !(status & F_LOWSIG0);
  288         }
  289         if (speed)
  290                 *speed = SPEED_10000;
  291         if (duplex)
  292                 *duplex = DUPLEX_FULL;
  293         return 0;
  294 }
  295 
  296 static int xaui_direct_power_down(struct cphy *phy, int enable)
  297 {
  298         return 0;
  299 }
  300 
  301 #ifdef C99_NOT_SUPPORTED
  302 static struct cphy_ops xaui_direct_ops = {
  303         NULL,
  304         xaui_direct_reset,
  305         ael1002_intr_noop,
  306         ael1002_intr_noop,
  307         ael1002_intr_noop,
  308         ael1002_intr_noop,
  309         NULL,
  310         NULL,
  311         NULL,
  312         NULL,
  313         NULL,
  314         xaui_direct_get_link_status,
  315         xaui_direct_power_down,
  316 };
  317 #else
  318 static struct cphy_ops xaui_direct_ops = {
  319         .reset           = xaui_direct_reset,
  320         .intr_enable     = ael1002_intr_noop,
  321         .intr_disable    = ael1002_intr_noop,
  322         .intr_clear      = ael1002_intr_noop,
  323         .intr_handler    = ael1002_intr_noop,
  324         .get_link_status = xaui_direct_get_link_status,
  325         .power_down      = xaui_direct_power_down,
  326 };
  327 #endif
  328 
  329 void t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
  330                              const struct mdio_ops *mdio_ops)
  331 {
  332         cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops);
  333 }

Cache object: dac18639400cb5f3c4ef9b94ad5d4f99


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.