linux/drivers/net/chelsio/subr.c
<<
>>
Prefs
   1/*****************************************************************************
   2 *                                                                           *
   3 * File: subr.c                                                              *
   4 * $Revision: 1.27 $                                                         *
   5 * $Date: 2005/06/22 01:08:36 $                                              *
   6 * Description:                                                              *
   7 *  Various subroutines (intr,pio,etc.) used by Chelsio 10G Ethernet driver. *
   8 *  part of the Chelsio 10Gb Ethernet Driver.                                *
   9 *                                                                           *
  10 * This program is free software; you can redistribute it and/or modify      *
  11 * it under the terms of the GNU General Public License, version 2, as       *
  12 * published by the Free Software Foundation.                                *
  13 *                                                                           *
  14 * You should have received a copy of the GNU General Public License along   *
  15 * with this program; if not, write to the Free Software Foundation, Inc.,   *
  16 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
  17 *                                                                           *
  18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
  19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
  20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.                     *
  21 *                                                                           *
  22 * http://www.chelsio.com                                                    *
  23 *                                                                           *
  24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc.                    *
  25 * All rights reserved.                                                      *
  26 *                                                                           *
  27 * Maintainers: maintainers@chelsio.com                                      *
  28 *                                                                           *
  29 * Authors: Dimitrios Michailidis   <dm@chelsio.com>                         *
  30 *          Tina Yang               <tainay@chelsio.com>                     *
  31 *          Felix Marti             <felix@chelsio.com>                      *
  32 *          Scott Bardone           <sbardone@chelsio.com>                   *
  33 *          Kurt Ottaway            <kottaway@chelsio.com>                   *
  34 *          Frank DiMambro          <frank@chelsio.com>                      *
  35 *                                                                           *
  36 * History:                                                                  *
  37 *                                                                           *
  38 ****************************************************************************/
  39
  40#include "common.h"
  41#include "elmer0.h"
  42#include "regs.h"
  43#include "gmac.h"
  44#include "cphy.h"
  45#include "sge.h"
  46#include "tp.h"
  47#include "espi.h"
  48
  49/**
  50 *      t1_wait_op_done - wait until an operation is completed
  51 *      @adapter: the adapter performing the operation
  52 *      @reg: the register to check for completion
  53 *      @mask: a single-bit field within @reg that indicates completion
  54 *      @polarity: the value of the field when the operation is completed
  55 *      @attempts: number of check iterations
  56 *      @delay: delay in usecs between iterations
  57 *
  58 *      Wait until an operation is completed by checking a bit in a register
  59 *      up to @attempts times.  Returns %0 if the operation completes and %1
  60 *      otherwise.
  61 */
  62static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity,
  63                           int attempts, int delay)
  64{
  65        while (1) {
  66                u32 val = readl(adapter->regs + reg) & mask;
  67
  68                if (!!val == polarity)
  69                        return 0;
  70                if (--attempts == 0)
  71                        return 1;
  72                if (delay)
  73                        udelay(delay);
  74        }
  75}
  76
  77#define TPI_ATTEMPTS 50
  78
  79/*
  80 * Write a register over the TPI interface (unlocked and locked versions).
  81 */
  82int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
  83{
  84        int tpi_busy;
  85
  86        writel(addr, adapter->regs + A_TPI_ADDR);
  87        writel(value, adapter->regs + A_TPI_WR_DATA);
  88        writel(F_TPIWR, adapter->regs + A_TPI_CSR);
  89
  90        tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
  91                                   TPI_ATTEMPTS, 3);
  92        if (tpi_busy)
  93                CH_ALERT("%s: TPI write to 0x%x failed\n",
  94                         adapter->name, addr);
  95        return tpi_busy;
  96}
  97
  98int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
  99{
 100        int ret;
 101
 102        spin_lock(&adapter->tpi_lock);
 103        ret = __t1_tpi_write(adapter, addr, value);
 104        spin_unlock(&adapter->tpi_lock);
 105        return ret;
 106}
 107
 108/*
 109 * Read a register over the TPI interface (unlocked and locked versions).
 110 */
 111int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
 112{
 113        int tpi_busy;
 114
 115        writel(addr, adapter->regs + A_TPI_ADDR);
 116        writel(0, adapter->regs + A_TPI_CSR);
 117
 118        tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
 119                                   TPI_ATTEMPTS, 3);
 120        if (tpi_busy)
 121                CH_ALERT("%s: TPI read from 0x%x failed\n",
 122                         adapter->name, addr);
 123        else
 124                *valp = readl(adapter->regs + A_TPI_RD_DATA);
 125        return tpi_busy;
 126}
 127
 128int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
 129{
 130        int ret;
 131
 132        spin_lock(&adapter->tpi_lock);
 133        ret = __t1_tpi_read(adapter, addr, valp);
 134        spin_unlock(&adapter->tpi_lock);
 135        return ret;
 136}
 137
 138/*
 139 * Set a TPI parameter.
 140 */
 141static void t1_tpi_par(adapter_t *adapter, u32 value)
 142{
 143        writel(V_TPIPAR(value), adapter->regs + A_TPI_PAR);
 144}
 145
 146/*
 147 * Called when a port's link settings change to propagate the new values to the
 148 * associated PHY and MAC.  After performing the common tasks it invokes an
 149 * OS-specific handler.
 150 */
 151void t1_link_changed(adapter_t *adapter, int port_id)
 152{
 153        int link_ok, speed, duplex, fc;
 154        struct cphy *phy = adapter->port[port_id].phy;
 155        struct link_config *lc = &adapter->port[port_id].link_config;
 156
 157        phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
 158
 159        lc->speed = speed < 0 ? SPEED_INVALID : speed;
 160        lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
 161        if (!(lc->requested_fc & PAUSE_AUTONEG))
 162                fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
 163
 164        if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
 165                /* Set MAC speed, duplex, and flow control to match PHY. */
 166                struct cmac *mac = adapter->port[port_id].mac;
 167
 168                mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc);
 169                lc->fc = (unsigned char)fc;
 170        }
 171        t1_link_negotiated(adapter, port_id, link_ok, speed, duplex, fc);
 172}
 173
 174static int t1_pci_intr_handler(adapter_t *adapter)
 175{
 176        u32 pcix_cause;
 177
 178        pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause);
 179
 180        if (pcix_cause) {
 181                pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE,
 182                                       pcix_cause);
 183                t1_fatal_err(adapter);    /* PCI errors are fatal */
 184        }
 185        return 0;
 186}
 187
 188#ifdef CONFIG_CHELSIO_T1_COUGAR
 189#include "cspi.h"
 190#endif
 191#ifdef CONFIG_CHELSIO_T1_1G
 192#include "fpga_defs.h"
 193
 194/*
 195 * PHY interrupt handler for FPGA boards.
 196 */
 197static int fpga_phy_intr_handler(adapter_t *adapter)
 198{
 199        int p;
 200        u32 cause = readl(adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
 201
 202        for_each_port(adapter, p)
 203                if (cause & (1 << p)) {
 204                        struct cphy *phy = adapter->port[p].phy;
 205                        int phy_cause = phy->ops->interrupt_handler(phy);
 206
 207                        if (phy_cause & cphy_cause_link_change)
 208                                t1_link_changed(adapter, p);
 209                }
 210        writel(cause, adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
 211        return 0;
 212}
 213
 214/*
 215 * Slow path interrupt handler for FPGAs.
 216 */
 217static int fpga_slow_intr(adapter_t *adapter)
 218{
 219        u32 cause = readl(adapter->regs + A_PL_CAUSE);
 220
 221        cause &= ~F_PL_INTR_SGE_DATA;
 222        if (cause & F_PL_INTR_SGE_ERR)
 223                t1_sge_intr_error_handler(adapter->sge);
 224
 225        if (cause & FPGA_PCIX_INTERRUPT_GMAC)
 226                fpga_phy_intr_handler(adapter);
 227
 228        if (cause & FPGA_PCIX_INTERRUPT_TP) {
 229                /*
 230                 * FPGA doesn't support MC4 interrupts and it requires
 231                 * this odd layer of indirection for MC5.
 232                 */
 233                u32 tp_cause = readl(adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE);
 234
 235                /* Clear TP interrupt */
 236                writel(tp_cause, adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE);
 237        }
 238        if (cause & FPGA_PCIX_INTERRUPT_PCIX)
 239                t1_pci_intr_handler(adapter);
 240
 241        /* Clear the interrupts just processed. */
 242        if (cause)
 243                writel(cause, adapter->regs + A_PL_CAUSE);
 244
 245        return cause != 0;
 246}
 247#endif
 248
 249/*
 250 * Wait until Elmer's MI1 interface is ready for new operations.
 251 */
 252static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg)
 253{
 254        int attempts = 100, busy;
 255
 256        do {
 257                u32 val;
 258
 259                __t1_tpi_read(adapter, mi1_reg, &val);
 260                busy = val & F_MI1_OP_BUSY;
 261                if (busy)
 262                        udelay(10);
 263        } while (busy && --attempts);
 264        if (busy)
 265                CH_ALERT("%s: MDIO operation timed out\n", adapter->name);
 266        return busy;
 267}
 268
 269/*
 270 * MI1 MDIO initialization.
 271 */
 272static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
 273{
 274        u32 clkdiv = bi->clock_elmer0 / (2 * bi->mdio_mdc) - 1;
 275        u32 val = F_MI1_PREAMBLE_ENABLE | V_MI1_MDI_INVERT(bi->mdio_mdiinv) |
 276                V_MI1_MDI_ENABLE(bi->mdio_mdien) | V_MI1_CLK_DIV(clkdiv);
 277
 278        if (!(bi->caps & SUPPORTED_10000baseT_Full))
 279                val |= V_MI1_SOF(1);
 280        t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val);
 281}
 282
 283#if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR)
 284/*
 285 * Elmer MI1 MDIO read/write operations.
 286 */
 287static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr,
 288                         u16 reg_addr)
 289{
 290        struct adapter *adapter = dev->ml_priv;
 291        u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
 292        unsigned int val;
 293
 294        spin_lock(&adapter->tpi_lock);
 295        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
 296        __t1_tpi_write(adapter,
 297                        A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
 298        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
 299        __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
 300        spin_unlock(&adapter->tpi_lock);
 301        return val;
 302}
 303
 304static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
 305                          u16 reg_addr, u16 val)
 306{
 307        struct adapter *adapter = dev->ml_priv;
 308        u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
 309
 310        spin_lock(&adapter->tpi_lock);
 311        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
 312        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
 313        __t1_tpi_write(adapter,
 314                        A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_WRITE);
 315        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
 316        spin_unlock(&adapter->tpi_lock);
 317        return 0;
 318}
 319
 320#if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR)
 321static const struct mdio_ops mi1_mdio_ops = {
 322        .init = mi1_mdio_init,
 323        .read = mi1_mdio_read,
 324        .write = mi1_mdio_write,
 325        .mode_support = MDIO_SUPPORTS_C22
 326};
 327#endif
 328
 329#endif
 330
 331static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
 332                             u16 reg_addr)
 333{
 334        struct adapter *adapter = dev->ml_priv;
 335        u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
 336        unsigned int val;
 337
 338        spin_lock(&adapter->tpi_lock);
 339
 340        /* Write the address we want. */
 341        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
 342        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
 343        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
 344                       MI1_OP_INDIRECT_ADDRESS);
 345        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
 346
 347        /* Write the operation we want. */
 348        __t1_tpi_write(adapter,
 349                        A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ);
 350        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
 351
 352        /* Read the data. */
 353        __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
 354        spin_unlock(&adapter->tpi_lock);
 355        return val;
 356}
 357
 358static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr,
 359                              int mmd_addr, u16 reg_addr, u16 val)
 360{
 361        struct adapter *adapter = dev->ml_priv;
 362        u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
 363
 364        spin_lock(&adapter->tpi_lock);
 365
 366        /* Write the address we want. */
 367        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
 368        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
 369        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
 370                       MI1_OP_INDIRECT_ADDRESS);
 371        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
 372
 373        /* Write the data. */
 374        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
 375        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE);
 376        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
 377        spin_unlock(&adapter->tpi_lock);
 378        return 0;
 379}
 380
 381static const struct mdio_ops mi1_mdio_ext_ops = {
 382        .init = mi1_mdio_init,
 383        .read = mi1_mdio_ext_read,
 384        .write = mi1_mdio_ext_write,
 385        .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
 386};
 387
 388enum {
 389        CH_BRD_T110_1CU,
 390        CH_BRD_N110_1F,
 391        CH_BRD_N210_1F,
 392        CH_BRD_T210_1F,
 393        CH_BRD_T210_1CU,
 394        CH_BRD_N204_4CU,
 395};
 396
 397static const struct board_info t1_board[] = {
 398        {
 399                .board          = CHBT_BOARD_CHT110,
 400                .port_number    = 1,
 401                .caps           = SUPPORTED_10000baseT_Full,
 402                .chip_term      = CHBT_TERM_T1,
 403                .chip_mac       = CHBT_MAC_PM3393,
 404                .chip_phy       = CHBT_PHY_MY3126,
 405                .clock_core     = 125000000,
 406                .clock_mc3      = 150000000,
 407                .clock_mc4      = 125000000,
 408                .espi_nports    = 1,
 409                .clock_elmer0   = 44,
 410                .mdio_mdien     = 1,
 411                .mdio_mdiinv    = 1,
 412                .mdio_mdc       = 1,
 413                .mdio_phybaseaddr = 1,
 414                .gmac           = &t1_pm3393_ops,
 415                .gphy           = &t1_my3126_ops,
 416                .mdio_ops       = &mi1_mdio_ext_ops,
 417                .desc           = "Chelsio T110 1x10GBase-CX4 TOE",
 418        },
 419
 420        {
 421                .board          = CHBT_BOARD_N110,
 422                .port_number    = 1,
 423                .caps           = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
 424                .chip_term      = CHBT_TERM_T1,
 425                .chip_mac       = CHBT_MAC_PM3393,
 426                .chip_phy       = CHBT_PHY_88X2010,
 427                .clock_core     = 125000000,
 428                .espi_nports    = 1,
 429                .clock_elmer0   = 44,
 430                .mdio_mdien     = 0,
 431                .mdio_mdiinv    = 0,
 432                .mdio_mdc       = 1,
 433                .mdio_phybaseaddr = 0,
 434                .gmac           = &t1_pm3393_ops,
 435                .gphy           = &t1_mv88x201x_ops,
 436                .mdio_ops       = &mi1_mdio_ext_ops,
 437                .desc           = "Chelsio N110 1x10GBaseX NIC",
 438        },
 439
 440        {
 441                .board          = CHBT_BOARD_N210,
 442                .port_number    = 1,
 443                .caps           = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
 444                .chip_term      = CHBT_TERM_T2,
 445                .chip_mac       = CHBT_MAC_PM3393,
 446                .chip_phy       = CHBT_PHY_88X2010,
 447                .clock_core     = 125000000,
 448                .espi_nports    = 1,
 449                .clock_elmer0   = 44,
 450                .mdio_mdien     = 0,
 451                .mdio_mdiinv    = 0,
 452                .mdio_mdc       = 1,
 453                .mdio_phybaseaddr = 0,
 454                .gmac           = &t1_pm3393_ops,
 455                .gphy           = &t1_mv88x201x_ops,
 456                .mdio_ops       = &mi1_mdio_ext_ops,
 457                .desc           = "Chelsio N210 1x10GBaseX NIC",
 458        },
 459
 460        {
 461                .board          = CHBT_BOARD_CHT210,
 462                .port_number    = 1,
 463                .caps           = SUPPORTED_10000baseT_Full,
 464                .chip_term      = CHBT_TERM_T2,
 465                .chip_mac       = CHBT_MAC_PM3393,
 466                .chip_phy       = CHBT_PHY_88X2010,
 467                .clock_core     = 125000000,
 468                .clock_mc3      = 133000000,
 469                .clock_mc4      = 125000000,
 470                .espi_nports    = 1,
 471                .clock_elmer0   = 44,
 472                .mdio_mdien     = 0,
 473                .mdio_mdiinv    = 0,
 474                .mdio_mdc       = 1,
 475                .mdio_phybaseaddr = 0,
 476                .gmac           = &t1_pm3393_ops,
 477                .gphy           = &t1_mv88x201x_ops,
 478                .mdio_ops       = &mi1_mdio_ext_ops,
 479                .desc           = "Chelsio T210 1x10GBaseX TOE",
 480        },
 481
 482        {
 483                .board          = CHBT_BOARD_CHT210,
 484                .port_number    = 1,
 485                .caps           = SUPPORTED_10000baseT_Full,
 486                .chip_term      = CHBT_TERM_T2,
 487                .chip_mac       = CHBT_MAC_PM3393,
 488                .chip_phy       = CHBT_PHY_MY3126,
 489                .clock_core     = 125000000,
 490                .clock_mc3      = 133000000,
 491                .clock_mc4      = 125000000,
 492                .espi_nports    = 1,
 493                .clock_elmer0   = 44,
 494                .mdio_mdien     = 1,
 495                .mdio_mdiinv    = 1,
 496                .mdio_mdc       = 1,
 497                .mdio_phybaseaddr = 1,
 498                .gmac           = &t1_pm3393_ops,
 499                .gphy           = &t1_my3126_ops,
 500                .mdio_ops       = &mi1_mdio_ext_ops,
 501                .desc           = "Chelsio T210 1x10GBase-CX4 TOE",
 502        },
 503
 504#ifdef CONFIG_CHELSIO_T1_1G
 505        {
 506                .board          = CHBT_BOARD_CHN204,
 507                .port_number    = 4,
 508                .caps           = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full
 509                                | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full
 510                                | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
 511                                  SUPPORTED_PAUSE | SUPPORTED_TP,
 512                .chip_term      = CHBT_TERM_T2,
 513                .chip_mac       = CHBT_MAC_VSC7321,
 514                .chip_phy       = CHBT_PHY_88E1111,
 515                .clock_core     = 100000000,
 516                .espi_nports    = 4,
 517                .clock_elmer0   = 44,
 518                .mdio_mdien     = 0,
 519                .mdio_mdiinv    = 0,
 520                .mdio_mdc       = 0,
 521                .mdio_phybaseaddr = 4,
 522                .gmac           = &t1_vsc7326_ops,
 523                .gphy           = &t1_mv88e1xxx_ops,
 524                .mdio_ops       = &mi1_mdio_ops,
 525                .desc           = "Chelsio N204 4x100/1000BaseT NIC",
 526        },
 527#endif
 528
 529};
 530
 531struct pci_device_id t1_pci_tbl[] = {
 532        CH_DEVICE(8, 0, CH_BRD_T110_1CU),
 533        CH_DEVICE(8, 1, CH_BRD_T110_1CU),
 534        CH_DEVICE(7, 0, CH_BRD_N110_1F),
 535        CH_DEVICE(10, 1, CH_BRD_N210_1F),
 536        CH_DEVICE(11, 1, CH_BRD_T210_1F),
 537        CH_DEVICE(14, 1, CH_BRD_T210_1CU),
 538        CH_DEVICE(16, 1, CH_BRD_N204_4CU),
 539        { 0 }
 540};
 541
 542MODULE_DEVICE_TABLE(pci, t1_pci_tbl);
 543
 544/*
 545 * Return the board_info structure with a given index.  Out-of-range indices
 546 * return NULL.
 547 */
 548const struct board_info *t1_get_board_info(unsigned int board_id)
 549{
 550        return board_id < ARRAY_SIZE(t1_board) ? &t1_board[board_id] : NULL;
 551}
 552
 553struct chelsio_vpd_t {
 554        u32 format_version;
 555        u8 serial_number[16];
 556        u8 mac_base_address[6];
 557        u8 pad[2];           /* make multiple-of-4 size requirement explicit */
 558};
 559
 560#define EEPROMSIZE        (8 * 1024)
 561#define EEPROM_MAX_POLL   4
 562
 563/*
 564 * Read SEEPROM. A zero is written to the flag register when the addres is
 565 * written to the Control register. The hardware device will set the flag to a
 566 * one when 4B have been transferred to the Data register.
 567 */
 568int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data)
 569{
 570        int i = EEPROM_MAX_POLL;
 571        u16 val;
 572        u32 v;
 573
 574        if (addr >= EEPROMSIZE || (addr & 3))
 575                return -EINVAL;
 576
 577        pci_write_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, (u16)addr);
 578        do {
 579                udelay(50);
 580                pci_read_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, &val);
 581        } while (!(val & F_VPD_OP_FLAG) && --i);
 582
 583        if (!(val & F_VPD_OP_FLAG)) {
 584                CH_ERR("%s: reading EEPROM address 0x%x failed\n",
 585                       adapter->name, addr);
 586                return -EIO;
 587        }
 588        pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, &v);
 589        *data = cpu_to_le32(v);
 590        return 0;
 591}
 592
 593static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd)
 594{
 595        int addr, ret = 0;
 596
 597        for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32))
 598                ret = t1_seeprom_read(adapter, addr,
 599                                      (__le32 *)((u8 *)vpd + addr));
 600
 601        return ret;
 602}
 603
 604/*
 605 * Read a port's MAC address from the VPD ROM.
 606 */
 607static int vpd_macaddress_get(adapter_t *adapter, int index, u8 mac_addr[])
 608{
 609        struct chelsio_vpd_t vpd;
 610
 611        if (t1_eeprom_vpd_get(adapter, &vpd))
 612                return 1;
 613        memcpy(mac_addr, vpd.mac_base_address, 5);
 614        mac_addr[5] = vpd.mac_base_address[5] + index;
 615        return 0;
 616}
 617
 618/*
 619 * Set up the MAC/PHY according to the requested link settings.
 620 *
 621 * If the PHY can auto-negotiate first decide what to advertise, then
 622 * enable/disable auto-negotiation as desired and reset.
 623 *
 624 * If the PHY does not auto-negotiate we just reset it.
 625 *
 626 * If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
 627 * otherwise do it later based on the outcome of auto-negotiation.
 628 */
 629int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
 630{
 631        unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
 632
 633        if (lc->supported & SUPPORTED_Autoneg) {
 634                lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE);
 635                if (fc) {
 636                        if (fc == ((PAUSE_RX | PAUSE_TX) &
 637                                   (mac->adapter->params.nports < 2)))
 638                                lc->advertising |= ADVERTISED_PAUSE;
 639                        else {
 640                                lc->advertising |= ADVERTISED_ASYM_PAUSE;
 641                                if (fc == PAUSE_RX)
 642                                        lc->advertising |= ADVERTISED_PAUSE;
 643                        }
 644                }
 645                phy->ops->advertise(phy, lc->advertising);
 646
 647                if (lc->autoneg == AUTONEG_DISABLE) {
 648                        lc->speed = lc->requested_speed;
 649                        lc->duplex = lc->requested_duplex;
 650                        lc->fc = (unsigned char)fc;
 651                        mac->ops->set_speed_duplex_fc(mac, lc->speed,
 652                                                      lc->duplex, fc);
 653                        /* Also disables autoneg */
 654                        phy->state = PHY_AUTONEG_RDY;
 655                        phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
 656                        phy->ops->reset(phy, 0);
 657                } else {
 658                        phy->state = PHY_AUTONEG_EN;
 659                        phy->ops->autoneg_enable(phy); /* also resets PHY */
 660                }
 661        } else {
 662                phy->state = PHY_AUTONEG_RDY;
 663                mac->ops->set_speed_duplex_fc(mac, -1, -1, fc);
 664                lc->fc = (unsigned char)fc;
 665                phy->ops->reset(phy, 0);
 666        }
 667        return 0;
 668}
 669
 670/*
 671 * External interrupt handler for boards using elmer0.
 672 */
 673int t1_elmer0_ext_intr_handler(adapter_t *adapter)
 674{
 675        struct cphy *phy;
 676        int phy_cause;
 677        u32 cause;
 678
 679        t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause);
 680
 681        switch (board_info(adapter)->board) {
 682#ifdef CONFIG_CHELSIO_T1_1G
 683        case CHBT_BOARD_CHT204:
 684        case CHBT_BOARD_CHT204E:
 685        case CHBT_BOARD_CHN204:
 686        case CHBT_BOARD_CHT204V: {
 687                int i, port_bit;
 688                for_each_port(adapter, i) {
 689                        port_bit = i + 1;
 690                        if (!(cause & (1 << port_bit)))
 691                                continue;
 692
 693                        phy = adapter->port[i].phy;
 694                        phy_cause = phy->ops->interrupt_handler(phy);
 695                        if (phy_cause & cphy_cause_link_change)
 696                                t1_link_changed(adapter, i);
 697                }
 698                break;
 699        }
 700        case CHBT_BOARD_CHT101:
 701                if (cause & ELMER0_GP_BIT1) { /* Marvell 88E1111 interrupt */
 702                        phy = adapter->port[0].phy;
 703                        phy_cause = phy->ops->interrupt_handler(phy);
 704                        if (phy_cause & cphy_cause_link_change)
 705                                t1_link_changed(adapter, 0);
 706                }
 707                break;
 708        case CHBT_BOARD_7500: {
 709                int p;
 710                /*
 711                 * Elmer0's interrupt cause isn't useful here because there is
 712                 * only one bit that can be set for all 4 ports.  This means
 713                 * we are forced to check every PHY's interrupt status
 714                 * register to see who initiated the interrupt.
 715                 */
 716                for_each_port(adapter, p) {
 717                        phy = adapter->port[p].phy;
 718                        phy_cause = phy->ops->interrupt_handler(phy);
 719                        if (phy_cause & cphy_cause_link_change)
 720                            t1_link_changed(adapter, p);
 721                }
 722                break;
 723        }
 724#endif
 725        case CHBT_BOARD_CHT210:
 726        case CHBT_BOARD_N210:
 727        case CHBT_BOARD_N110:
 728                if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */
 729                        phy = adapter->port[0].phy;
 730                        phy_cause = phy->ops->interrupt_handler(phy);
 731                        if (phy_cause & cphy_cause_link_change)
 732                                t1_link_changed(adapter, 0);
 733                }
 734                break;
 735        case CHBT_BOARD_8000:
 736        case CHBT_BOARD_CHT110:
 737                CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n",
 738                       cause);
 739                if (cause & ELMER0_GP_BIT1) {        /* PMC3393 INTB */
 740                        struct cmac *mac = adapter->port[0].mac;
 741
 742                        mac->ops->interrupt_handler(mac);
 743                }
 744                if (cause & ELMER0_GP_BIT5) {        /* XPAK MOD_DETECT */
 745                        u32 mod_detect;
 746
 747                        t1_tpi_read(adapter,
 748                                        A_ELMER0_GPI_STAT, &mod_detect);
 749                        CH_MSG(adapter, INFO, LINK, "XPAK %s\n",
 750                               mod_detect ? "removed" : "inserted");
 751                }
 752                break;
 753#ifdef CONFIG_CHELSIO_T1_COUGAR
 754        case CHBT_BOARD_COUGAR:
 755                if (adapter->params.nports == 1) {
 756                        if (cause & ELMER0_GP_BIT1) {         /* Vitesse MAC */
 757                                struct cmac *mac = adapter->port[0].mac;
 758                                mac->ops->interrupt_handler(mac);
 759                        }
 760                        if (cause & ELMER0_GP_BIT5) {     /* XPAK MOD_DETECT */
 761                        }
 762                } else {
 763                        int i, port_bit;
 764
 765                        for_each_port(adapter, i) {
 766                                port_bit = i ? i + 1 : 0;
 767                                if (!(cause & (1 << port_bit)))
 768                                        continue;
 769
 770                                phy = adapter->port[i].phy;
 771                                phy_cause = phy->ops->interrupt_handler(phy);
 772                                if (phy_cause & cphy_cause_link_change)
 773                                        t1_link_changed(adapter, i);
 774                        }
 775                }
 776                break;
 777#endif
 778        }
 779        t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause);
 780        return 0;
 781}
 782
 783/* Enables all interrupts. */
 784void t1_interrupts_enable(adapter_t *adapter)
 785{
 786        unsigned int i;
 787
 788        adapter->slow_intr_mask = F_PL_INTR_SGE_ERR | F_PL_INTR_TP;
 789
 790        t1_sge_intr_enable(adapter->sge);
 791        t1_tp_intr_enable(adapter->tp);
 792        if (adapter->espi) {
 793                adapter->slow_intr_mask |= F_PL_INTR_ESPI;
 794                t1_espi_intr_enable(adapter->espi);
 795        }
 796
 797        /* Enable MAC/PHY interrupts for each port. */
 798        for_each_port(adapter, i) {
 799                adapter->port[i].mac->ops->interrupt_enable(adapter->port[i].mac);
 800                adapter->port[i].phy->ops->interrupt_enable(adapter->port[i].phy);
 801        }
 802
 803        /* Enable PCIX & external chip interrupts on ASIC boards. */
 804        if (t1_is_asic(adapter)) {
 805                u32 pl_intr = readl(adapter->regs + A_PL_ENABLE);
 806
 807                /* PCI-X interrupts */
 808                pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE,
 809                                       0xffffffff);
 810
 811                adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
 812                pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
 813                writel(pl_intr, adapter->regs + A_PL_ENABLE);
 814        }
 815}
 816
 817/* Disables all interrupts. */
 818void t1_interrupts_disable(adapter_t* adapter)
 819{
 820        unsigned int i;
 821
 822        t1_sge_intr_disable(adapter->sge);
 823        t1_tp_intr_disable(adapter->tp);
 824        if (adapter->espi)
 825                t1_espi_intr_disable(adapter->espi);
 826
 827        /* Disable MAC/PHY interrupts for each port. */
 828        for_each_port(adapter, i) {
 829                adapter->port[i].mac->ops->interrupt_disable(adapter->port[i].mac);
 830                adapter->port[i].phy->ops->interrupt_disable(adapter->port[i].phy);
 831        }
 832
 833        /* Disable PCIX & external chip interrupts. */
 834        if (t1_is_asic(adapter))
 835                writel(0, adapter->regs + A_PL_ENABLE);
 836
 837        /* PCI-X interrupts */
 838        pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0);
 839
 840        adapter->slow_intr_mask = 0;
 841}
 842
 843/* Clears all interrupts */
 844void t1_interrupts_clear(adapter_t* adapter)
 845{
 846        unsigned int i;
 847
 848        t1_sge_intr_clear(adapter->sge);
 849        t1_tp_intr_clear(adapter->tp);
 850        if (adapter->espi)
 851                t1_espi_intr_clear(adapter->espi);
 852
 853        /* Clear MAC/PHY interrupts for each port. */
 854        for_each_port(adapter, i) {
 855                adapter->port[i].mac->ops->interrupt_clear(adapter->port[i].mac);
 856                adapter->port[i].phy->ops->interrupt_clear(adapter->port[i].phy);
 857        }
 858
 859        /* Enable interrupts for external devices. */
 860        if (t1_is_asic(adapter)) {
 861                u32 pl_intr = readl(adapter->regs + A_PL_CAUSE);
 862
 863                writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX,
 864                       adapter->regs + A_PL_CAUSE);
 865        }
 866
 867        /* PCI-X interrupts */
 868        pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff);
 869}
 870
 871/*
 872 * Slow path interrupt handler for ASICs.
 873 */
 874static int asic_slow_intr(adapter_t *adapter)
 875{
 876        u32 cause = readl(adapter->regs + A_PL_CAUSE);
 877
 878        cause &= adapter->slow_intr_mask;
 879        if (!cause)
 880                return 0;
 881        if (cause & F_PL_INTR_SGE_ERR)
 882                t1_sge_intr_error_handler(adapter->sge);
 883        if (cause & F_PL_INTR_TP)
 884                t1_tp_intr_handler(adapter->tp);
 885        if (cause & F_PL_INTR_ESPI)
 886                t1_espi_intr_handler(adapter->espi);
 887        if (cause & F_PL_INTR_PCIX)
 888                t1_pci_intr_handler(adapter);
 889        if (cause & F_PL_INTR_EXT)
 890                t1_elmer0_ext_intr(adapter);
 891
 892        /* Clear the interrupts just processed. */
 893        writel(cause, adapter->regs + A_PL_CAUSE);
 894        readl(adapter->regs + A_PL_CAUSE); /* flush writes */
 895        return 1;
 896}
 897
 898int t1_slow_intr_handler(adapter_t *adapter)
 899{
 900#ifdef CONFIG_CHELSIO_T1_1G
 901        if (!t1_is_asic(adapter))
 902                return fpga_slow_intr(adapter);
 903#endif
 904        return asic_slow_intr(adapter);
 905}
 906
 907/* Power sequencing is a work-around for Intel's XPAKs. */
 908static void power_sequence_xpak(adapter_t* adapter)
 909{
 910        u32 mod_detect;
 911        u32 gpo;
 912
 913        /* Check for XPAK */
 914        t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect);
 915        if (!(ELMER0_GP_BIT5 & mod_detect)) {
 916                /* XPAK is present */
 917                t1_tpi_read(adapter, A_ELMER0_GPO, &gpo);
 918                gpo |= ELMER0_GP_BIT18;
 919                t1_tpi_write(adapter, A_ELMER0_GPO, gpo);
 920        }
 921}
 922
 923int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
 924                               struct adapter_params *p)
 925{
 926        p->chip_version = bi->chip_term;
 927        p->is_asic = (p->chip_version != CHBT_TERM_FPGA);
 928        if (p->chip_version == CHBT_TERM_T1 ||
 929            p->chip_version == CHBT_TERM_T2 ||
 930            p->chip_version == CHBT_TERM_FPGA) {
 931                u32 val = readl(adapter->regs + A_TP_PC_CONFIG);
 932
 933                val = G_TP_PC_REV(val);
 934                if (val == 2)
 935                        p->chip_revision = TERM_T1B;
 936                else if (val == 3)
 937                        p->chip_revision = TERM_T2;
 938                else
 939                        return -1;
 940        } else
 941                return -1;
 942        return 0;
 943}
 944
 945/*
 946 * Enable board components other than the Chelsio chip, such as external MAC
 947 * and PHY.
 948 */
 949static int board_init(adapter_t *adapter, const struct board_info *bi)
 950{
 951        switch (bi->board) {
 952        case CHBT_BOARD_8000:
 953        case CHBT_BOARD_N110:
 954        case CHBT_BOARD_N210:
 955        case CHBT_BOARD_CHT210:
 956        case CHBT_BOARD_COUGAR:
 957                t1_tpi_par(adapter, 0xf);
 958                t1_tpi_write(adapter, A_ELMER0_GPO, 0x800);
 959                break;
 960        case CHBT_BOARD_CHT110:
 961                t1_tpi_par(adapter, 0xf);
 962                t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800);
 963
 964                /* TBD XXX Might not need.  This fixes a problem
 965                 *         described in the Intel SR XPAK errata.
 966                 */
 967                power_sequence_xpak(adapter);
 968                break;
 969#ifdef CONFIG_CHELSIO_T1_1G
 970        case CHBT_BOARD_CHT204E:
 971                /* add config space write here */
 972        case CHBT_BOARD_CHT204:
 973        case CHBT_BOARD_CHT204V:
 974        case CHBT_BOARD_CHN204:
 975                t1_tpi_par(adapter, 0xf);
 976                t1_tpi_write(adapter, A_ELMER0_GPO, 0x804);
 977                break;
 978        case CHBT_BOARD_CHT101:
 979        case CHBT_BOARD_7500:
 980                t1_tpi_par(adapter, 0xf);
 981                t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804);
 982                break;
 983#endif
 984        }
 985        return 0;
 986}
 987
 988/*
 989 * Initialize and configure the Terminator HW modules.  Note that external
 990 * MAC and PHYs are initialized separately.
 991 */
 992int t1_init_hw_modules(adapter_t *adapter)
 993{
 994        int err = -EIO;
 995        const struct board_info *bi = board_info(adapter);
 996
 997        if (!bi->clock_mc4) {
 998                u32 val = readl(adapter->regs + A_MC4_CFG);
 999
1000                writel(val | F_READY | F_MC4_SLOW, adapter->regs + A_MC4_CFG);
1001                writel(F_M_BUS_ENABLE | F_TCAM_RESET,
1002                       adapter->regs + A_MC5_CONFIG);
1003        }
1004
1005#ifdef CONFIG_CHELSIO_T1_COUGAR
1006        if (adapter->cspi && t1_cspi_init(adapter->cspi))
1007                goto out_err;
1008#endif
1009        if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac,
1010                                          bi->espi_nports))
1011                goto out_err;
1012
1013        if (t1_tp_reset(adapter->tp, &adapter->params.tp, bi->clock_core))
1014                goto out_err;
1015
1016        err = t1_sge_configure(adapter->sge, &adapter->params.sge);
1017        if (err)
1018                goto out_err;
1019
1020        err = 0;
1021out_err:
1022        return err;
1023}
1024
1025/*
1026 * Determine a card's PCI mode.
1027 */
1028static void __devinit get_pci_mode(adapter_t *adapter, struct chelsio_pci_params *p)
1029{
1030        static const unsigned short speed_map[] = { 33, 66, 100, 133 };
1031        u32 pci_mode;
1032
1033        pci_read_config_dword(adapter->pdev, A_PCICFG_MODE, &pci_mode);
1034        p->speed = speed_map[G_PCI_MODE_CLK(pci_mode)];
1035        p->width = (pci_mode & F_PCI_MODE_64BIT) ? 64 : 32;
1036        p->is_pcix = (pci_mode & F_PCI_MODE_PCIX) != 0;
1037}
1038
1039/*
1040 * Release the structures holding the SW per-Terminator-HW-module state.
1041 */
1042void t1_free_sw_modules(adapter_t *adapter)
1043{
1044        unsigned int i;
1045
1046        for_each_port(adapter, i) {
1047                struct cmac *mac = adapter->port[i].mac;
1048                struct cphy *phy = adapter->port[i].phy;
1049
1050                if (mac)
1051                        mac->ops->destroy(mac);
1052                if (phy)
1053                        phy->ops->destroy(phy);
1054        }
1055
1056        if (adapter->sge)
1057                t1_sge_destroy(adapter->sge);
1058        if (adapter->tp)
1059                t1_tp_destroy(adapter->tp);
1060        if (adapter->espi)
1061                t1_espi_destroy(adapter->espi);
1062#ifdef CONFIG_CHELSIO_T1_COUGAR
1063        if (adapter->cspi)
1064                t1_cspi_destroy(adapter->cspi);
1065#endif
1066}
1067
1068static void __devinit init_link_config(struct link_config *lc,
1069                                       const struct board_info *bi)
1070{
1071        lc->supported = bi->caps;
1072        lc->requested_speed = lc->speed = SPEED_INVALID;
1073        lc->requested_duplex = lc->duplex = DUPLEX_INVALID;
1074        lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
1075        if (lc->supported & SUPPORTED_Autoneg) {
1076                lc->advertising = lc->supported;
1077                lc->autoneg = AUTONEG_ENABLE;
1078                lc->requested_fc |= PAUSE_AUTONEG;
1079        } else {
1080                lc->advertising = 0;
1081                lc->autoneg = AUTONEG_DISABLE;
1082        }
1083}
1084
1085#ifdef CONFIG_CHELSIO_T1_COUGAR
1086        if (bi->clock_cspi && !(adapter->cspi = t1_cspi_create(adapter))) {
1087                CH_ERR("%s: CSPI initialization failed\n",
1088                       adapter->name);
1089                goto error;
1090        }
1091#endif
1092
1093/*
1094 * Allocate and initialize the data structures that hold the SW state of
1095 * the Terminator HW modules.
1096 */
1097int __devinit t1_init_sw_modules(adapter_t *adapter,
1098                                 const struct board_info *bi)
1099{
1100        unsigned int i;
1101
1102        adapter->params.brd_info = bi;
1103        adapter->params.nports = bi->port_number;
1104        adapter->params.stats_update_period = bi->gmac->stats_update_period;
1105
1106        adapter->sge = t1_sge_create(adapter, &adapter->params.sge);
1107        if (!adapter->sge) {
1108                CH_ERR("%s: SGE initialization failed\n",
1109                       adapter->name);
1110                goto error;
1111        }
1112
1113        if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) {
1114                CH_ERR("%s: ESPI initialization failed\n",
1115                       adapter->name);
1116                goto error;
1117        }
1118
1119        adapter->tp = t1_tp_create(adapter, &adapter->params.tp);
1120        if (!adapter->tp) {
1121                CH_ERR("%s: TP initialization failed\n",
1122                       adapter->name);
1123                goto error;
1124        }
1125
1126        board_init(adapter, bi);
1127        bi->mdio_ops->init(adapter, bi);
1128        if (bi->gphy->reset)
1129                bi->gphy->reset(adapter);
1130        if (bi->gmac->reset)
1131                bi->gmac->reset(adapter);
1132
1133        for_each_port(adapter, i) {
1134                u8 hw_addr[6];
1135                struct cmac *mac;
1136                int phy_addr = bi->mdio_phybaseaddr + i;
1137
1138                adapter->port[i].phy = bi->gphy->create(adapter->port[i].dev,
1139                                                        phy_addr, bi->mdio_ops);
1140                if (!adapter->port[i].phy) {
1141                        CH_ERR("%s: PHY %d initialization failed\n",
1142                               adapter->name, i);
1143                        goto error;
1144                }
1145
1146                adapter->port[i].mac = mac = bi->gmac->create(adapter, i);
1147                if (!mac) {
1148                        CH_ERR("%s: MAC %d initialization failed\n",
1149                               adapter->name, i);
1150                        goto error;
1151                }
1152
1153                /*
1154                 * Get the port's MAC addresses either from the EEPROM if one
1155                 * exists or the one hardcoded in the MAC.
1156                 */
1157                if (!t1_is_asic(adapter) || bi->chip_mac == CHBT_MAC_DUMMY)
1158                        mac->ops->macaddress_get(mac, hw_addr);
1159                else if (vpd_macaddress_get(adapter, i, hw_addr)) {
1160                        CH_ERR("%s: could not read MAC address from VPD ROM\n",
1161                               adapter->port[i].dev->name);
1162                        goto error;
1163                }
1164                memcpy(adapter->port[i].dev->dev_addr, hw_addr, ETH_ALEN);
1165                init_link_config(&adapter->port[i].link_config, bi);
1166        }
1167
1168        get_pci_mode(adapter, &adapter->params.pci);
1169        t1_interrupts_clear(adapter);
1170        return 0;
1171
1172error:
1173        t1_free_sw_modules(adapter);
1174        return -1;
1175}
1176