cxgb_t3_hw.c revision 1.1.4.2       1  1.1.4.2  rmind /**************************************************************************
      2  1.1.4.2  rmind 
      3  1.1.4.2  rmind Copyright (c) 2007, Chelsio Inc.
      4  1.1.4.2  rmind All rights reserved.
      5  1.1.4.2  rmind 
      6  1.1.4.2  rmind Redistribution and use in source and binary forms, with or without
      7  1.1.4.2  rmind modification, are permitted provided that the following conditions are met:
      8  1.1.4.2  rmind 
      9  1.1.4.2  rmind  1. Redistributions of source code must retain the above copyright notice,
     10  1.1.4.2  rmind     this list of conditions and the following disclaimer.
     11  1.1.4.2  rmind 
     12  1.1.4.2  rmind  2. Neither the name of the Chelsio Corporation nor the names of its
     13  1.1.4.2  rmind     contributors may be used to endorse or promote products derived from
     14  1.1.4.2  rmind     this software without specific prior written permission.
     15  1.1.4.2  rmind 
     16  1.1.4.2  rmind THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17  1.1.4.2  rmind AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  1.1.4.2  rmind IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  1.1.4.2  rmind ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     20  1.1.4.2  rmind LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  1.1.4.2  rmind CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  1.1.4.2  rmind SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  1.1.4.2  rmind INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  1.1.4.2  rmind CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  1.1.4.2  rmind ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  1.1.4.2  rmind POSSIBILITY OF SUCH DAMAGE.
     27  1.1.4.2  rmind 
     28  1.1.4.2  rmind ***************************************************************************/
     29  1.1.4.2  rmind 
     30  1.1.4.2  rmind #include <sys/cdefs.h>
     31  1.1.4.2  rmind __KERNEL_RCSID(0, "$NetBSD: cxgb_t3_hw.c,v 1.1.4.2 2010/05/30 05:17:40 rmind Exp $");
     32  1.1.4.2  rmind 
     33  1.1.4.2  rmind 
     34  1.1.4.2  rmind #ifdef CONFIG_DEFINED
     35  1.1.4.2  rmind #include <cxgb_include.h>
     36  1.1.4.2  rmind #else
     37  1.1.4.2  rmind #include "cxgb_include.h"
     38  1.1.4.2  rmind #endif
     39  1.1.4.2  rmind 
     40  1.1.4.2  rmind #undef msleep
     41  1.1.4.2  rmind #define msleep t3_os_sleep
     42  1.1.4.2  rmind 
     43  1.1.4.2  rmind /**
     44  1.1.4.2  rmind  *  t3_wait_op_done_val - wait until an operation is completed
     45  1.1.4.2  rmind  *  @adapter: the adapter performing the operation
     46  1.1.4.2  rmind  *  @reg: the register to check for completion
     47  1.1.4.2  rmind  *  @mask: a single-bit field within @reg that indicates completion
     48  1.1.4.2  rmind  *  @polarity: the value of the field when the operation is completed
     49  1.1.4.2  rmind  *  @attempts: number of check iterations
     50  1.1.4.2  rmind  *  @delay: delay in usecs between iterations
     51  1.1.4.2  rmind  *  @valp: where to store the value of the register at completion time
     52  1.1.4.2  rmind  *
     53  1.1.4.2  rmind  *  Wait until an operation is completed by checking a bit in a register
     54  1.1.4.2  rmind  *  up to @attempts times.  If @valp is not NULL the value of the register
     55  1.1.4.2  rmind  *  at the time it indicated completion is stored there.  Returns 0 if the
     56  1.1.4.2  rmind  *  operation completes and -EAGAIN otherwise.
     57  1.1.4.2  rmind  */
     58  1.1.4.2  rmind int t3_wait_op_done_val(adapter_t *adapter, int reg, u32 mask, int polarity,
     59  1.1.4.2  rmind             int attempts, int delay, u32 *valp)
     60  1.1.4.2  rmind {
     61  1.1.4.2  rmind     while (1) {
     62  1.1.4.2  rmind         u32 val = t3_read_reg(adapter, reg);
     63  1.1.4.2  rmind 
     64  1.1.4.2  rmind         if (!!(val & mask) == polarity) {
     65  1.1.4.2  rmind             if (valp)
     66  1.1.4.2  rmind                 *valp = val;
     67  1.1.4.2  rmind             return 0;
     68  1.1.4.2  rmind         }
     69  1.1.4.2  rmind         if (--attempts == 0)
     70  1.1.4.2  rmind             return -EAGAIN;
     71  1.1.4.2  rmind         if (delay)
     72  1.1.4.2  rmind             udelay(delay);
     73  1.1.4.2  rmind     }
     74  1.1.4.2  rmind }
     75  1.1.4.2  rmind 
     76  1.1.4.2  rmind /**
     77  1.1.4.2  rmind  *  t3_write_regs - write a bunch of registers
     78  1.1.4.2  rmind  *  @adapter: the adapter to program
     79  1.1.4.2  rmind  *  @p: an array of register address/register value pairs
     80  1.1.4.2  rmind  *  @n: the number of address/value pairs
     81  1.1.4.2  rmind  *  @offset: register address offset
     82  1.1.4.2  rmind  *
     83  1.1.4.2  rmind  *  Takes an array of register address/register value pairs and writes each
     84  1.1.4.2  rmind  *  value to the corresponding register.  Register addresses are adjusted
     85  1.1.4.2  rmind  *  by the supplied offset.
     86  1.1.4.2  rmind  */
     87  1.1.4.2  rmind void t3_write_regs(adapter_t *adapter, const struct addr_val_pair *p, int n,
     88  1.1.4.2  rmind            unsigned int offset)
     89  1.1.4.2  rmind {
     90  1.1.4.2  rmind     while (n--) {
     91  1.1.4.2  rmind         t3_write_reg(adapter, p->reg_addr + offset, p->val);
     92  1.1.4.2  rmind         p++;
     93  1.1.4.2  rmind     }
     94  1.1.4.2  rmind }
     95  1.1.4.2  rmind 
     96  1.1.4.2  rmind /**
     97  1.1.4.2  rmind  *  t3_set_reg_field - set a register field to a value
     98  1.1.4.2  rmind  *  @adapter: the adapter to program
     99  1.1.4.2  rmind  *  @addr: the register address
    100  1.1.4.2  rmind  *  @mask: specifies the portion of the register to modify
    101  1.1.4.2  rmind  *  @val: the new value for the register field
    102  1.1.4.2  rmind  *
    103  1.1.4.2  rmind  *  Sets a register field specified by the supplied mask to the
    104  1.1.4.2  rmind  *  given value.
    105  1.1.4.2  rmind  */
    106  1.1.4.2  rmind void t3_set_reg_field(adapter_t *adapter, unsigned int addr, u32 mask, u32 val)
    107  1.1.4.2  rmind {
    108  1.1.4.2  rmind     u32 v = t3_read_reg(adapter, addr) & ~mask;
    109  1.1.4.2  rmind 
    110  1.1.4.2  rmind     t3_write_reg(adapter, addr, v | val);
    111  1.1.4.2  rmind     (void) t3_read_reg(adapter, addr);      /* flush */
    112  1.1.4.2  rmind }
    113  1.1.4.2  rmind 
    114  1.1.4.2  rmind /**
    115  1.1.4.2  rmind  *  t3_read_indirect - read indirectly addressed registers
    116  1.1.4.2  rmind  *  @adap: the adapter
    117  1.1.4.2  rmind  *  @addr_reg: register holding the indirect address
    118  1.1.4.2  rmind  *  @data_reg: register holding the value of the indirect register
    119  1.1.4.2  rmind  *  @vals: where the read register values are stored
    120  1.1.4.2  rmind  *  @start_idx: index of first indirect register to read
    121  1.1.4.2  rmind  *  @nregs: how many indirect registers to read
    122  1.1.4.2  rmind  *
    123  1.1.4.2  rmind  *  Reads registers that are accessed indirectly through an address/data
    124  1.1.4.2  rmind  *  register pair.
    125  1.1.4.2  rmind  */
    126  1.1.4.2  rmind static void t3_read_indirect(adapter_t *adap, unsigned int addr_reg,
    127  1.1.4.2  rmind               unsigned int data_reg, u32 *vals, unsigned int nregs,
    128  1.1.4.2  rmind               unsigned int start_idx)
    129  1.1.4.2  rmind {
    130  1.1.4.2  rmind     while (nregs--) {
    131  1.1.4.2  rmind         t3_write_reg(adap, addr_reg, start_idx);
    132  1.1.4.2  rmind         *vals++ = t3_read_reg(adap, data_reg);
    133  1.1.4.2  rmind         start_idx++;
    134  1.1.4.2  rmind     }
    135  1.1.4.2  rmind }
    136  1.1.4.2  rmind 
    137  1.1.4.2  rmind /**
    138  1.1.4.2  rmind  *  t3_mc7_bd_read - read from MC7 through backdoor accesses
    139  1.1.4.2  rmind  *  @mc7: identifies MC7 to read from
    140  1.1.4.2  rmind  *  @start: index of first 64-bit word to read
    141  1.1.4.2  rmind  *  @n: number of 64-bit words to read
    142  1.1.4.2  rmind  *  @buf: where to store the read result
    143  1.1.4.2  rmind  *
    144  1.1.4.2  rmind  *  Read n 64-bit words from MC7 starting at word start, using backdoor
    145  1.1.4.2  rmind  *  accesses.
    146  1.1.4.2  rmind  */
    147  1.1.4.2  rmind int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n,
    148  1.1.4.2  rmind                    u64 *buf)
    149  1.1.4.2  rmind {
    150  1.1.4.2  rmind     static int shift[] = { 0, 0, 16, 24 };
    151  1.1.4.2  rmind     static int step[]  = { 0, 32, 16, 8 };
    152  1.1.4.2  rmind 
    153  1.1.4.2  rmind     unsigned int size64 = mc7->size / 8;  /* # of 64-bit words */
    154  1.1.4.2  rmind     adapter_t *adap = mc7->adapter;
    155  1.1.4.2  rmind 
    156  1.1.4.2  rmind     if (start >= size64 || start + n > size64)
    157  1.1.4.2  rmind         return -EINVAL;
    158  1.1.4.2  rmind 
    159  1.1.4.2  rmind     start *= (8 << mc7->width);
    160  1.1.4.2  rmind     while (n--) {
    161  1.1.4.2  rmind         int i;
    162  1.1.4.2  rmind         u64 val64 = 0;
    163  1.1.4.2  rmind 
    164  1.1.4.2  rmind         for (i = (1 << mc7->width) - 1; i >= 0; --i) {
    165  1.1.4.2  rmind             int attempts = 10;
    166  1.1.4.2  rmind             u32 val;
    167  1.1.4.2  rmind 
    168  1.1.4.2  rmind             t3_write_reg(adap, mc7->offset + A_MC7_BD_ADDR,
    169  1.1.4.2  rmind                        start);
    170  1.1.4.2  rmind             t3_write_reg(adap, mc7->offset + A_MC7_BD_OP, 0);
    171  1.1.4.2  rmind             val = t3_read_reg(adap, mc7->offset + A_MC7_BD_OP);
    172  1.1.4.2  rmind             while ((val & F_BUSY) && attempts--)
    173  1.1.4.2  rmind                 val = t3_read_reg(adap,
    174  1.1.4.2  rmind                           mc7->offset + A_MC7_BD_OP);
    175  1.1.4.2  rmind             if (val & F_BUSY)
    176  1.1.4.2  rmind                 return -EIO;
    177  1.1.4.2  rmind 
    178  1.1.4.2  rmind             val = t3_read_reg(adap, mc7->offset + A_MC7_BD_DATA1);
    179  1.1.4.2  rmind             if (mc7->width == 0) {
    180  1.1.4.2  rmind                 val64 = t3_read_reg(adap,
    181  1.1.4.2  rmind                         mc7->offset + A_MC7_BD_DATA0);
    182  1.1.4.2  rmind                 val64 |= (u64)val << 32;
    183  1.1.4.2  rmind             } else {
    184  1.1.4.2  rmind                 if (mc7->width > 1)
    185  1.1.4.2  rmind                     val >>= shift[mc7->width];
    186  1.1.4.2  rmind                 val64 |= (u64)val << (step[mc7->width] * i);
    187  1.1.4.2  rmind             }
    188  1.1.4.2  rmind             start += 8;
    189  1.1.4.2  rmind         }
    190  1.1.4.2  rmind         *buf++ = val64;
    191  1.1.4.2  rmind     }
    192  1.1.4.2  rmind     return 0;
    193  1.1.4.2  rmind }
    194  1.1.4.2  rmind 
    195  1.1.4.2  rmind /*
    196  1.1.4.2  rmind  * Initialize MI1.
    197  1.1.4.2  rmind  */
    198  1.1.4.2  rmind static void mi1_init(adapter_t *adap, const struct adapter_info *ai)
    199  1.1.4.2  rmind {
    200  1.1.4.2  rmind         u32 clkdiv = adap->params.vpd.cclk / (2 * adap->params.vpd.mdc) - 1;
    201  1.1.4.2  rmind         u32 val = F_PREEN | V_MDIINV(ai->mdiinv) | V_MDIEN(ai->mdien) |
    202  1.1.4.2  rmind           V_CLKDIV(clkdiv);
    203  1.1.4.2  rmind 
    204  1.1.4.2  rmind     if (!(ai->caps & SUPPORTED_10000baseT_Full))
    205  1.1.4.2  rmind         val |= V_ST(1);
    206  1.1.4.2  rmind         t3_write_reg(adap, A_MI1_CFG, val);
    207  1.1.4.2  rmind }
    208  1.1.4.2  rmind 
    209  1.1.4.2  rmind #define MDIO_ATTEMPTS 20
    210  1.1.4.2  rmind 
    211  1.1.4.2  rmind /*
    212  1.1.4.2  rmind  * MI1 read/write operations for direct-addressed PHYs.
    213  1.1.4.2  rmind  */
    214  1.1.4.2  rmind static int mi1_read(adapter_t *adapter, int phy_addr, int mmd_addr,
    215  1.1.4.2  rmind             int reg_addr, unsigned int *valp)
    216  1.1.4.2  rmind {
    217  1.1.4.2  rmind     int ret;
    218  1.1.4.2  rmind     u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
    219  1.1.4.2  rmind 
    220  1.1.4.2  rmind     if (mmd_addr)
    221  1.1.4.2  rmind         return -EINVAL;
    222  1.1.4.2  rmind 
    223  1.1.4.2  rmind     MDIO_LOCK(adapter);
    224  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_ADDR, addr);
    225  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2));
    226  1.1.4.2  rmind     ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
    227  1.1.4.2  rmind     if (!ret)
    228  1.1.4.2  rmind         *valp = t3_read_reg(adapter, A_MI1_DATA);
    229  1.1.4.2  rmind     MDIO_UNLOCK(adapter);
    230  1.1.4.2  rmind     return ret;
    231  1.1.4.2  rmind }
    232  1.1.4.2  rmind 
    233  1.1.4.2  rmind static int mi1_write(adapter_t *adapter, int phy_addr, int mmd_addr,
    234  1.1.4.2  rmind              int reg_addr, unsigned int val)
    235  1.1.4.2  rmind {
    236  1.1.4.2  rmind     int ret;
    237  1.1.4.2  rmind     u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
    238  1.1.4.2  rmind 
    239  1.1.4.2  rmind     if (mmd_addr)
    240  1.1.4.2  rmind         return -EINVAL;
    241  1.1.4.2  rmind 
    242  1.1.4.2  rmind     MDIO_LOCK(adapter);
    243  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_ADDR, addr);
    244  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_DATA, val);
    245  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1));
    246  1.1.4.2  rmind     ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
    247  1.1.4.2  rmind     MDIO_UNLOCK(adapter);
    248  1.1.4.2  rmind     return ret;
    249  1.1.4.2  rmind }
    250  1.1.4.2  rmind 
    251  1.1.4.2  rmind static struct mdio_ops mi1_mdio_ops = {
    252  1.1.4.2  rmind     mi1_read,
    253  1.1.4.2  rmind     mi1_write
    254  1.1.4.2  rmind };
    255  1.1.4.2  rmind 
    256  1.1.4.2  rmind /*
    257  1.1.4.2  rmind  * MI1 read/write operations for indirect-addressed PHYs.
    258  1.1.4.2  rmind  */
    259  1.1.4.2  rmind static int mi1_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
    260  1.1.4.2  rmind             int reg_addr, unsigned int *valp)
    261  1.1.4.2  rmind {
    262  1.1.4.2  rmind     int ret;
    263  1.1.4.2  rmind     u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
    264  1.1.4.2  rmind 
    265  1.1.4.2  rmind     MDIO_LOCK(adapter);
    266  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_ADDR, addr);
    267  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_DATA, reg_addr);
    268  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0));
    269  1.1.4.2  rmind     ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
    270  1.1.4.2  rmind     if (!ret) {
    271  1.1.4.2  rmind         t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3));
    272  1.1.4.2  rmind         ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
    273  1.1.4.2  rmind                       MDIO_ATTEMPTS, 10);
    274  1.1.4.2  rmind         if (!ret)
    275  1.1.4.2  rmind             *valp = t3_read_reg(adapter, A_MI1_DATA);
    276  1.1.4.2  rmind     }
    277  1.1.4.2  rmind     MDIO_UNLOCK(adapter);
    278  1.1.4.2  rmind     return ret;
    279  1.1.4.2  rmind }
    280  1.1.4.2  rmind 
    281  1.1.4.2  rmind static int mi1_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
    282  1.1.4.2  rmind              int reg_addr, unsigned int val)
    283  1.1.4.2  rmind {
    284  1.1.4.2  rmind     int ret;
    285  1.1.4.2  rmind     u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
    286  1.1.4.2  rmind 
    287  1.1.4.2  rmind     MDIO_LOCK(adapter);
    288  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_ADDR, addr);
    289  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_DATA, reg_addr);
    290  1.1.4.2  rmind     t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0));
    291  1.1.4.2  rmind     ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
    292  1.1.4.2  rmind     if (!ret) {
    293  1.1.4.2  rmind         t3_write_reg(adapter, A_MI1_DATA, val);
    294  1.1.4.2  rmind         t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1));
    295  1.1.4.2  rmind         ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
    296  1.1.4.2  rmind                       MDIO_ATTEMPTS, 10);
    297  1.1.4.2  rmind     }
    298  1.1.4.2  rmind     MDIO_UNLOCK(adapter);
    299  1.1.4.2  rmind     return ret;
    300  1.1.4.2  rmind }
    301  1.1.4.2  rmind 
    302  1.1.4.2  rmind static struct mdio_ops mi1_mdio_ext_ops = {
    303  1.1.4.2  rmind     mi1_ext_read,
    304  1.1.4.2  rmind     mi1_ext_write
    305  1.1.4.2  rmind };
    306  1.1.4.2  rmind 
    307  1.1.4.2  rmind /**
    308  1.1.4.2  rmind  *  t3_mdio_change_bits - modify the value of a PHY register
    309  1.1.4.2  rmind  *  @phy: the PHY to operate on
    310  1.1.4.2  rmind  *  @mmd: the device address
    311  1.1.4.2  rmind  *  @reg: the register address
    312  1.1.4.2  rmind  *  @clear: what part of the register value to mask off
    313  1.1.4.2  rmind  *  @set: what part of the register value to set
    314  1.1.4.2  rmind  *
    315  1.1.4.2  rmind  *  Changes the value of a PHY register by applying a mask to its current
    316  1.1.4.2  rmind  *  value and ORing the result with a new value.
    317  1.1.4.2  rmind  */
    318  1.1.4.2  rmind int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear,
    319  1.1.4.2  rmind             unsigned int set)
    320  1.1.4.2  rmind {
    321  1.1.4.2  rmind     int ret;
    322  1.1.4.2  rmind     unsigned int val;
    323  1.1.4.2  rmind 
    324  1.1.4.2  rmind     ret = mdio_read(phy, mmd, reg, &val);
    325  1.1.4.2  rmind     if (!ret) {
    326  1.1.4.2  rmind         val &= ~clear;
    327  1.1.4.2  rmind         ret = mdio_write(phy, mmd, reg, val | set);
    328  1.1.4.2  rmind     }
    329  1.1.4.2  rmind     return ret;
    330  1.1.4.2  rmind }
    331  1.1.4.2  rmind 
    332  1.1.4.2  rmind /**
    333  1.1.4.2  rmind  *  t3_phy_reset - reset a PHY block
    334  1.1.4.2  rmind  *  @phy: the PHY to operate on
    335  1.1.4.2  rmind  *  @mmd: the device address of the PHY block to reset
    336  1.1.4.2  rmind  *  @wait: how long to wait for the reset to complete in 1ms increments
    337  1.1.4.2  rmind  *
    338  1.1.4.2  rmind  *  Resets a PHY block and optionally waits for the reset to complete.
    339  1.1.4.2  rmind  *  @mmd should be 0 for 10/100/1000 PHYs and the device address to reset
    340  1.1.4.2  rmind  *  for 10G PHYs.
    341  1.1.4.2  rmind  */
    342  1.1.4.2  rmind int t3_phy_reset(struct cphy *phy, int mmd, int wait)
    343  1.1.4.2  rmind {
    344  1.1.4.2  rmind     int err;
    345  1.1.4.2  rmind     unsigned int ctl;
    346  1.1.4.2  rmind 
    347  1.1.4.2  rmind     err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET);
    348  1.1.4.2  rmind     if (err || !wait)
    349  1.1.4.2  rmind         return err;
    350  1.1.4.2  rmind 
    351  1.1.4.2  rmind     do {
    352  1.1.4.2  rmind         err = mdio_read(phy, mmd, MII_BMCR, &ctl);
    353  1.1.4.2  rmind         if (err)
    354  1.1.4.2  rmind             return err;
    355  1.1.4.2  rmind         ctl &= BMCR_RESET;
    356  1.1.4.2  rmind         if (ctl)
    357  1.1.4.2  rmind             msleep(1);
    358  1.1.4.2  rmind     } while (ctl && --wait);
    359  1.1.4.2  rmind 
    360  1.1.4.2  rmind     return ctl ? -1 : 0;
    361  1.1.4.2  rmind }
    362  1.1.4.2  rmind 
    363  1.1.4.2  rmind /**
    364  1.1.4.2  rmind  *  t3_phy_advertise - set the PHY advertisement registers for autoneg
    365  1.1.4.2  rmind  *  @phy: the PHY to operate on
    366  1.1.4.2  rmind  *  @advert: bitmap of capabilities the PHY should advertise
    367  1.1.4.2  rmind  *
    368  1.1.4.2  rmind  *  Sets a 10/100/1000 PHY's advertisement registers to advertise the
    369  1.1.4.2  rmind  *  requested capabilities.
    370  1.1.4.2  rmind  */
    371  1.1.4.2  rmind int t3_phy_advertise(struct cphy *phy, unsigned int advert)
    372  1.1.4.2  rmind {
    373  1.1.4.2  rmind     int err;
    374  1.1.4.2  rmind     unsigned int val = 0;
    375  1.1.4.2  rmind 
    376  1.1.4.2  rmind     err = mdio_read(phy, 0, MII_CTRL1000, &val);
    377  1.1.4.2  rmind     if (err)
    378  1.1.4.2  rmind         return err;
    379  1.1.4.2  rmind 
    380  1.1.4.2  rmind     val &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
    381  1.1.4.2  rmind     if (advert & ADVERTISED_1000baseT_Half)
    382  1.1.4.2  rmind         val |= ADVERTISE_1000HALF;
    383  1.1.4.2  rmind     if (advert & ADVERTISED_1000baseT_Full)
    384  1.1.4.2  rmind         val |= ADVERTISE_1000FULL;
    385  1.1.4.2  rmind 
    386  1.1.4.2  rmind     err = mdio_write(phy, 0, MII_CTRL1000, val);
    387  1.1.4.2  rmind     if (err)
    388  1.1.4.2  rmind         return err;
    389  1.1.4.2  rmind 
    390  1.1.4.2  rmind     val = 1;
    391  1.1.4.2  rmind     if (advert & ADVERTISED_10baseT_Half)
    392  1.1.4.2  rmind         val |= ADVERTISE_10HALF;
    393  1.1.4.2  rmind     if (advert & ADVERTISED_10baseT_Full)
    394  1.1.4.2  rmind         val |= ADVERTISE_10FULL;
    395  1.1.4.2  rmind     if (advert & ADVERTISED_100baseT_Half)
    396  1.1.4.2  rmind         val |= ADVERTISE_100HALF;
    397  1.1.4.2  rmind     if (advert & ADVERTISED_100baseT_Full)
    398  1.1.4.2  rmind         val |= ADVERTISE_100FULL;
    399  1.1.4.2  rmind     if (advert & ADVERTISED_Pause)
    400  1.1.4.2  rmind         val |= ADVERTISE_PAUSE_CAP;
    401  1.1.4.2  rmind     if (advert & ADVERTISED_Asym_Pause)
    402  1.1.4.2  rmind         val |= ADVERTISE_PAUSE_ASYM;
    403  1.1.4.2  rmind     return mdio_write(phy, 0, MII_ADVERTISE, val);
    404  1.1.4.2  rmind }
    405  1.1.4.2  rmind 
    406  1.1.4.2  rmind /**
    407  1.1.4.2  rmind  *  t3_set_phy_speed_duplex - force PHY speed and duplex
    408  1.1.4.2  rmind  *  @phy: the PHY to operate on
    409  1.1.4.2  rmind  *  @speed: requested PHY speed
    410  1.1.4.2  rmind  *  @duplex: requested PHY duplex
    411  1.1.4.2  rmind  *
    412  1.1.4.2  rmind  *  Force a 10/100/1000 PHY's speed and duplex.  This also disables
    413  1.1.4.2  rmind  *  auto-negotiation except for GigE, where auto-negotiation is mandatory.
    414  1.1.4.2  rmind  */
    415  1.1.4.2  rmind int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
    416  1.1.4.2  rmind {
    417  1.1.4.2  rmind     int err;
    418  1.1.4.2  rmind     unsigned int ctl;
    419  1.1.4.2  rmind 
    420  1.1.4.2  rmind     err = mdio_read(phy, 0, MII_BMCR, &ctl);
    421  1.1.4.2  rmind     if (err)
    422  1.1.4.2  rmind         return err;
    423  1.1.4.2  rmind 
    424  1.1.4.2  rmind     if (speed >= 0) {
    425  1.1.4.2  rmind         ctl &= ~(BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
    426  1.1.4.2  rmind         if (speed == SPEED_100)
    427  1.1.4.2  rmind             ctl |= BMCR_SPEED100;
    428  1.1.4.2  rmind         else if (speed == SPEED_1000)
    429  1.1.4.2  rmind             ctl |= BMCR_SPEED1000;
    430  1.1.4.2  rmind     }
    431  1.1.4.2  rmind     if (duplex >= 0) {
    432  1.1.4.2  rmind         ctl &= ~(BMCR_FULLDPLX | BMCR_ANENABLE);
    433  1.1.4.2  rmind         if (duplex == DUPLEX_FULL)
    434  1.1.4.2  rmind             ctl |= BMCR_FULLDPLX;
    435  1.1.4.2  rmind     }
    436  1.1.4.2  rmind     if (ctl & BMCR_SPEED1000)  /* auto-negotiation required for GigE */
    437  1.1.4.2  rmind         ctl |= BMCR_ANENABLE;
    438  1.1.4.2  rmind     return mdio_write(phy, 0, MII_BMCR, ctl);
    439  1.1.4.2  rmind }
    440  1.1.4.2  rmind 
    441  1.1.4.2  rmind static struct adapter_info t3_adap_info[] = {
    442  1.1.4.2  rmind     { 1, 1, 0, 0, 0,
    443  1.1.4.2  rmind       F_GPIO2_OEN | F_GPIO4_OEN |
    444  1.1.4.2  rmind       F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
    445  1.1.4.2  rmind       0,
    446  1.1.4.2  rmind       &mi1_mdio_ops, "Chelsio PE9000" },
    447  1.1.4.2  rmind     { 1, 1, 0, 0, 0,
    448  1.1.4.2  rmind       F_GPIO2_OEN | F_GPIO4_OEN |
    449  1.1.4.2  rmind       F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
    450  1.1.4.2  rmind       0,
    451  1.1.4.2  rmind       &mi1_mdio_ops, "Chelsio T302" },
    452  1.1.4.2  rmind     { 1, 0, 0, 0, 0,
    453  1.1.4.2  rmind       F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
    454  1.1.4.2  rmind       F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
    455  1.1.4.2  rmind       SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
    456  1.1.4.2  rmind       &mi1_mdio_ext_ops, "Chelsio T310" },
    457  1.1.4.2  rmind     { 1, 1, 0, 0, 0,
    458  1.1.4.2  rmind       F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
    459  1.1.4.2  rmind       F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
    460  1.1.4.2  rmind       F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
    461  1.1.4.2  rmind       SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
    462  1.1.4.2  rmind       &mi1_mdio_ext_ops, "Chelsio T320" },
    463  1.1.4.2  rmind     { 4, 0, 0, 0, 0,
    464  1.1.4.2  rmind       F_GPIO5_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO5_OUT_VAL |
    465  1.1.4.2  rmind       F_GPIO6_OUT_VAL | F_GPIO7_OUT_VAL,
    466  1.1.4.2  rmind       F_GPIO1 | F_GPIO2 | F_GPIO3 | F_GPIO4, SUPPORTED_AUI,
    467  1.1.4.2  rmind       &mi1_mdio_ops, "Chelsio T304" },
    468  1.1.4.2  rmind };
    469  1.1.4.2  rmind 
    470  1.1.4.2  rmind /*
    471  1.1.4.2  rmind  * Return the adapter_info structure with a given index.  Out-of-range indices
    472  1.1.4.2  rmind  * return NULL.
    473  1.1.4.2  rmind  */
    474  1.1.4.2  rmind const struct adapter_info *t3_get_adapter_info(unsigned int id)
    475  1.1.4.2  rmind {
    476  1.1.4.2  rmind     return id < ARRAY_SIZE(t3_adap_info) ? &t3_adap_info[id] : NULL;
    477  1.1.4.2  rmind }
    478  1.1.4.2  rmind 
    479  1.1.4.2  rmind #define CAPS_1G (SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | \
    480  1.1.4.2  rmind          SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII)
    481  1.1.4.2  rmind #define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI)
    482  1.1.4.2  rmind 
    483  1.1.4.2  rmind static struct port_type_info port_types[] = {
    484  1.1.4.2  rmind     { NULL, 0, NULL },
    485  1.1.4.2  rmind     { t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE,
    486  1.1.4.2  rmind       "10GBASE-XR" },
    487  1.1.4.2  rmind     { t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ,
    488  1.1.4.2  rmind       "10/100/1000BASE-T" },
    489  1.1.4.2  rmind     { t3_mv88e1xxx_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ,
    490  1.1.4.2  rmind       "10/100/1000BASE-T" },
    491  1.1.4.2  rmind     { t3_xaui_direct_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4" },
    492  1.1.4.2  rmind     { NULL, CAPS_10G, "10GBASE-KX4" },
    493  1.1.4.2  rmind     { t3_qt2045_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4" },
    494  1.1.4.2  rmind     { t3_ael1006_phy_prep, CAPS_10G | SUPPORTED_FIBRE,
    495  1.1.4.2  rmind       "10GBASE-SR" },
    496  1.1.4.2  rmind     { NULL, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4" },
    497  1.1.4.2  rmind };
    498  1.1.4.2  rmind 
    499  1.1.4.2  rmind #undef CAPS_1G
    500  1.1.4.2  rmind #undef CAPS_10G
    501  1.1.4.2  rmind 
    502  1.1.4.2  rmind #define VPD_ENTRY(name, len) \
    503  1.1.4.2  rmind     u8 name##_kword[2]; u8 name##_len; char name##_data[len]
    504  1.1.4.2  rmind 
    505  1.1.4.2  rmind /*
    506  1.1.4.2  rmind  * Partial EEPROM Vital Product Data structure.  Includes only the ID and
    507  1.1.4.2  rmind  * VPD-R sections.
    508  1.1.4.2  rmind  */
    509  1.1.4.2  rmind struct t3_vpd {
    510  1.1.4.2  rmind     u8  id_tag;
    511  1.1.4.2  rmind     u8  id_len[2];
    512  1.1.4.2  rmind     u8  id_data[16];
    513  1.1.4.2  rmind     u8  vpdr_tag;
    514  1.1.4.2  rmind     u8  vpdr_len[2];
    515  1.1.4.2  rmind     VPD_ENTRY(pn, 16);                     /* part number */
    516  1.1.4.2  rmind     VPD_ENTRY(ec, 16);                     /* EC level */
    517  1.1.4.2  rmind     VPD_ENTRY(sn, SERNUM_LEN);             /* serial number */
    518  1.1.4.2  rmind     VPD_ENTRY(na, 12);                     /* MAC address base */
    519  1.1.4.2  rmind     VPD_ENTRY(cclk, 6);                    /* core clock */
    520  1.1.4.2  rmind     VPD_ENTRY(mclk, 6);                    /* mem clock */
    521  1.1.4.2  rmind     VPD_ENTRY(uclk, 6);                    /* uP clk */
    522  1.1.4.2  rmind     VPD_ENTRY(mdc, 6);                     /* MDIO clk */
    523  1.1.4.2  rmind     VPD_ENTRY(mt, 2);                      /* mem timing */
    524  1.1.4.2  rmind     VPD_ENTRY(xaui0cfg, 6);                /* XAUI0 config */
    525  1.1.4.2  rmind     VPD_ENTRY(xaui1cfg, 6);                /* XAUI1 config */
    526  1.1.4.2  rmind     VPD_ENTRY(port0, 2);                   /* PHY0 complex */
    527  1.1.4.2  rmind     VPD_ENTRY(port1, 2);                   /* PHY1 complex */
    528  1.1.4.2  rmind     VPD_ENTRY(port2, 2);                   /* PHY2 complex */
    529  1.1.4.2  rmind     VPD_ENTRY(port3, 2);                   /* PHY3 complex */
    530  1.1.4.2  rmind     VPD_ENTRY(rv, 1);                      /* csum */
    531  1.1.4.2  rmind     u32 pad;                  /* for multiple-of-4 sizing and alignment */
    532  1.1.4.2  rmind };
    533  1.1.4.2  rmind 
    534  1.1.4.2  rmind #define EEPROM_MAX_POLL   4
    535  1.1.4.2  rmind #define EEPROM_STAT_ADDR  0x4000
    536  1.1.4.2  rmind #define VPD_BASE          0xc00
    537  1.1.4.2  rmind 
    538  1.1.4.2  rmind /**
    539  1.1.4.2  rmind  *  t3_seeprom_read - read a VPD EEPROM location
    540  1.1.4.2  rmind  *  @adapter: adapter to read
    541  1.1.4.2  rmind  *  @addr: EEPROM address
    542  1.1.4.2  rmind  *  @data: where to store the read data
    543  1.1.4.2  rmind  *
    544  1.1.4.2  rmind  *  Read a 32-bit word from a location in VPD EEPROM using the card's PCI
    545  1.1.4.2  rmind  *  VPD ROM capability.  A zero is written to the flag bit when the
    546  1.1.4.2  rmind  *  addres is written to the control register.  The hardware device will
    547  1.1.4.2  rmind  *  set the flag to 1 when 4 bytes have been read into the data register.
    548  1.1.4.2  rmind  */
    549  1.1.4.2  rmind int t3_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
    550  1.1.4.2  rmind {
    551  1.1.4.2  rmind     u16 val;
    552  1.1.4.2  rmind     int attempts = EEPROM_MAX_POLL;
    553  1.1.4.2  rmind     unsigned int base = adapter->params.pci.vpd_cap_addr;
    554  1.1.4.2  rmind 
    555  1.1.4.2  rmind     if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3))
    556  1.1.4.2  rmind         return -EINVAL;
    557  1.1.4.2  rmind 
    558  1.1.4.2  rmind     t3_os_pci_write_config_2(adapter, base + PCI_VPD_ADDR, (u16)addr);
    559  1.1.4.2  rmind     do {
    560  1.1.4.2  rmind         udelay(10);
    561  1.1.4.2  rmind         t3_os_pci_read_config_2(adapter, base + PCI_VPD_ADDR, &val);
    562  1.1.4.2  rmind     } while (!(val & PCI_VPD_ADDR_F) && --attempts);
    563  1.1.4.2  rmind 
    564  1.1.4.2  rmind     if (!(val & PCI_VPD_ADDR_F)) {
    565  1.1.4.2  rmind         CH_ERR(adapter, "reading EEPROM address 0x%x failed\n", addr);
    566  1.1.4.2  rmind         return -EIO;
    567  1.1.4.2  rmind     }
    568  1.1.4.2  rmind     t3_os_pci_read_config_4(adapter, base + PCI_VPD_DATA, data);
    569  1.1.4.2  rmind     *data = le32_to_cpu(*data);
    570  1.1.4.2  rmind     return 0;
    571  1.1.4.2  rmind }
    572  1.1.4.2  rmind 
    573  1.1.4.2  rmind /**
    574  1.1.4.2  rmind  *  t3_seeprom_write - write a VPD EEPROM location
    575  1.1.4.2  rmind  *  @adapter: adapter to write
    576  1.1.4.2  rmind  *  @addr: EEPROM address
    577  1.1.4.2  rmind  *  @data: value to write
    578  1.1.4.2  rmind  *
    579  1.1.4.2  rmind  *  Write a 32-bit word to a location in VPD EEPROM using the card's PCI
    580  1.1.4.2  rmind  *  VPD ROM capability.
    581  1.1.4.2  rmind  */
    582  1.1.4.2  rmind int t3_seeprom_write(adapter_t *adapter, u32 addr, u32 data)
    583  1.1.4.2  rmind {
    584  1.1.4.2  rmind     u16 val;
    585  1.1.4.2  rmind     int attempts = EEPROM_MAX_POLL;
    586  1.1.4.2  rmind     unsigned int base = adapter->params.pci.vpd_cap_addr;
    587  1.1.4.2  rmind 
    588  1.1.4.2  rmind     if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3))
    589  1.1.4.2  rmind         return -EINVAL;
    590  1.1.4.2  rmind 
    591  1.1.4.2  rmind     t3_os_pci_write_config_4(adapter, base + PCI_VPD_DATA,
    592  1.1.4.2  rmind                  cpu_to_le32(data));
    593  1.1.4.2  rmind     t3_os_pci_write_config_2(adapter, base + PCI_VPD_ADDR,
    594  1.1.4.2  rmind                  (u16)addr | PCI_VPD_ADDR_F);
    595  1.1.4.2  rmind     do {
    596  1.1.4.2  rmind         msleep(1);
    597  1.1.4.2  rmind         t3_os_pci_read_config_2(adapter, base + PCI_VPD_ADDR, &val);
    598  1.1.4.2  rmind     } while ((val & PCI_VPD_ADDR_F) && --attempts);
    599  1.1.4.2  rmind 
    600  1.1.4.2  rmind     if (val & PCI_VPD_ADDR_F) {
    601  1.1.4.2  rmind         CH_ERR(adapter, "write to EEPROM address 0x%x failed\n", addr);
    602  1.1.4.2  rmind         return -EIO;
    603  1.1.4.2  rmind     }
    604  1.1.4.2  rmind     return 0;
    605  1.1.4.2  rmind }
    606  1.1.4.2  rmind 
    607  1.1.4.2  rmind /**
    608  1.1.4.2  rmind  *  t3_seeprom_wp - enable/disable EEPROM write protection
    609  1.1.4.2  rmind  *  @adapter: the adapter
    610  1.1.4.2  rmind  *  @enable: 1 to enable write protection, 0 to disable it
    611  1.1.4.2  rmind  *
    612  1.1.4.2  rmind  *  Enables or disables write protection on the serial EEPROM.
    613  1.1.4.2  rmind  */
    614  1.1.4.2  rmind int t3_seeprom_wp(adapter_t *adapter, int enable)
    615  1.1.4.2  rmind {
    616  1.1.4.2  rmind     return t3_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 0);
    617  1.1.4.2  rmind }
    618  1.1.4.2  rmind 
    619  1.1.4.2  rmind /*
    620  1.1.4.2  rmind  * Convert a character holding a hex digit to a number.
    621  1.1.4.2  rmind  */
    622  1.1.4.2  rmind static unsigned int hex2int(unsigned char c)
    623  1.1.4.2  rmind {
    624  1.1.4.2  rmind     return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
    625  1.1.4.2  rmind }
    626  1.1.4.2  rmind 
    627  1.1.4.2  rmind /**
    628  1.1.4.2  rmind  *  get_vpd_params - read VPD parameters from VPD EEPROM
    629  1.1.4.2  rmind  *  @adapter: adapter to read
    630  1.1.4.2  rmind  *  @p: where to store the parameters
    631  1.1.4.2  rmind  *
    632  1.1.4.2  rmind  *  Reads card parameters stored in VPD EEPROM.
    633  1.1.4.2  rmind  */
    634  1.1.4.2  rmind static int get_vpd_params(adapter_t *adapter, struct vpd_params *p)
    635  1.1.4.2  rmind {
    636  1.1.4.2  rmind     int i, addr, ret;
    637  1.1.4.2  rmind     struct t3_vpd vpd;
    638  1.1.4.2  rmind 
    639  1.1.4.2  rmind     /*
    640  1.1.4.2  rmind      * Card information is normally at VPD_BASE but some early cards had
    641  1.1.4.2  rmind      * it at 0.
    642  1.1.4.2  rmind      */
    643  1.1.4.2  rmind     ret = t3_seeprom_read(adapter, VPD_BASE, (u32 *)&vpd);
    644  1.1.4.2  rmind     if (ret)
    645  1.1.4.2  rmind         return ret;
    646  1.1.4.2  rmind     addr = vpd.id_tag == 0x82 ? VPD_BASE : 0;
    647  1.1.4.2  rmind 
    648  1.1.4.2  rmind     for (i = 0; i < sizeof(vpd); i += 4) {
    649  1.1.4.2  rmind         ret = t3_seeprom_read(adapter, addr + i,
    650  1.1.4.2  rmind                       (u32 *)((u8 *)&vpd + i));
    651  1.1.4.2  rmind         if (ret)
    652  1.1.4.2  rmind             return ret;
    653  1.1.4.2  rmind     }
    654  1.1.4.2  rmind 
    655  1.1.4.2  rmind     p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10);
    656  1.1.4.2  rmind     p->mclk = simple_strtoul(vpd.mclk_data, NULL, 10);
    657  1.1.4.2  rmind     p->uclk = simple_strtoul(vpd.uclk_data, NULL, 10);
    658  1.1.4.2  rmind     p->mdc = simple_strtoul(vpd.mdc_data, NULL, 10);
    659  1.1.4.2  rmind     p->mem_timing = simple_strtoul(vpd.mt_data, NULL, 10);
    660  1.1.4.2  rmind     memcpy(p->sn, vpd.sn_data, SERNUM_LEN);
    661  1.1.4.2  rmind 
    662  1.1.4.2  rmind     /* Old eeproms didn't have port information */
    663  1.1.4.2  rmind     if (adapter->params.rev == 0 && !vpd.port0_data[0]) {
    664  1.1.4.2  rmind         p->port_type[0] = uses_xaui(adapter) ? 1 : 2;
    665  1.1.4.2  rmind         p->port_type[1] = uses_xaui(adapter) ? 6 : 2;
    666  1.1.4.2  rmind     } else {
    667  1.1.4.2  rmind         p->port_type[0] = (u8)hex2int(vpd.port0_data[0]);
    668  1.1.4.2  rmind         p->port_type[1] = (u8)hex2int(vpd.port1_data[0]);
    669  1.1.4.2  rmind         p->port_type[2] = (u8)hex2int(vpd.port2_data[0]);
    670  1.1.4.2  rmind         p->port_type[3] = (u8)hex2int(vpd.port3_data[0]);
    671  1.1.4.2  rmind         p->xauicfg[0] = simple_strtoul(vpd.xaui0cfg_data, NULL, 16);
    672  1.1.4.2  rmind         p->xauicfg[1] = simple_strtoul(vpd.xaui1cfg_data, NULL, 16);
    673  1.1.4.2  rmind     }
    674  1.1.4.2  rmind 
    675  1.1.4.2  rmind     for (i = 0; i < 6; i++)
    676  1.1.4.2  rmind         p->eth_base[i] = hex2int(vpd.na_data[2 * i]) * 16 +
    677  1.1.4.2  rmind                  hex2int(vpd.na_data[2 * i + 1]);
    678  1.1.4.2  rmind     return 0;
    679  1.1.4.2  rmind }
    680  1.1.4.2  rmind 
    681  1.1.4.2  rmind /* serial flash and firmware constants */
    682  1.1.4.2  rmind enum {
    683  1.1.4.2  rmind     SF_ATTEMPTS = 5,           /* max retries for SF1 operations */
    684  1.1.4.2  rmind     SF_SEC_SIZE = 64 * 1024,   /* serial flash sector size */
    685  1.1.4.2  rmind     SF_SIZE = SF_SEC_SIZE * 8, /* serial flash size */
    686  1.1.4.2  rmind 
    687  1.1.4.2  rmind     /* flash command opcodes */
    688  1.1.4.2  rmind     SF_PROG_PAGE    = 2,       /* program page */
    689  1.1.4.2  rmind     SF_WR_DISABLE   = 4,       /* disable writes */
    690  1.1.4.2  rmind     SF_RD_STATUS    = 5,       /* read status register */
    691  1.1.4.2  rmind     SF_WR_ENABLE    = 6,       /* enable writes */
    692  1.1.4.2  rmind     SF_RD_DATA_FAST = 0xb,     /* read flash */
    693  1.1.4.2  rmind     SF_ERASE_SECTOR = 0xd8,    /* erase sector */
    694  1.1.4.2  rmind 
    695  1.1.4.2  rmind     FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */
    696  1.1.4.2  rmind     FW_VERS_ADDR = 0x77ffc,    /* flash address holding FW version */
    697  1.1.4.2  rmind     FW_MIN_SIZE = 8            /* at least version and csum */
    698  1.1.4.2  rmind };
    699  1.1.4.2  rmind 
    700  1.1.4.2  rmind /**
    701  1.1.4.2  rmind  *  sf1_read - read data from the serial flash
    702  1.1.4.2  rmind  *  @adapter: the adapter
    703  1.1.4.2  rmind  *  @byte_cnt: number of bytes to read
    704  1.1.4.2  rmind  *  @cont: whether another operation will be chained
    705  1.1.4.2  rmind  *  @valp: where to store the read data
    706  1.1.4.2  rmind  *
    707  1.1.4.2  rmind  *  Reads up to 4 bytes of data from the serial flash.  The location of
    708  1.1.4.2  rmind  *  the read needs to be specified prior to calling this by issuing the
    709  1.1.4.2  rmind  *  appropriate commands to the serial flash.
    710  1.1.4.2  rmind  */
    711  1.1.4.2  rmind static int sf1_read(adapter_t *adapter, unsigned int byte_cnt, int cont,
    712  1.1.4.2  rmind             u32 *valp)
    713  1.1.4.2  rmind {
    714  1.1.4.2  rmind     int ret;
    715  1.1.4.2  rmind 
    716  1.1.4.2  rmind     if (!byte_cnt || byte_cnt > 4)
    717  1.1.4.2  rmind         return -EINVAL;
    718  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SF_OP) & F_BUSY)
    719  1.1.4.2  rmind         return -EBUSY;
    720  1.1.4.2  rmind     t3_write_reg(adapter, A_SF_OP, V_CONT(cont) | V_BYTECNT(byte_cnt - 1));
    721  1.1.4.2  rmind     ret = t3_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 10);
    722  1.1.4.2  rmind     if (!ret)
    723  1.1.4.2  rmind         *valp = t3_read_reg(adapter, A_SF_DATA);
    724  1.1.4.2  rmind     return ret;
    725  1.1.4.2  rmind }
    726  1.1.4.2  rmind 
    727  1.1.4.2  rmind /**
    728  1.1.4.2  rmind  *  sf1_write - write data to the serial flash
    729  1.1.4.2  rmind  *  @adapter: the adapter
    730  1.1.4.2  rmind  *  @byte_cnt: number of bytes to write
    731  1.1.4.2  rmind  *  @cont: whether another operation will be chained
    732  1.1.4.2  rmind  *  @val: value to write
    733  1.1.4.2  rmind  *
    734  1.1.4.2  rmind  *  Writes up to 4 bytes of data to the serial flash.  The location of
    735  1.1.4.2  rmind  *  the write needs to be specified prior to calling this by issuing the
    736  1.1.4.2  rmind  *  appropriate commands to the serial flash.
    737  1.1.4.2  rmind  */
    738  1.1.4.2  rmind static int sf1_write(adapter_t *adapter, unsigned int byte_cnt, int cont,
    739  1.1.4.2  rmind              u32 val)
    740  1.1.4.2  rmind {
    741  1.1.4.2  rmind     if (!byte_cnt || byte_cnt > 4)
    742  1.1.4.2  rmind         return -EINVAL;
    743  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SF_OP) & F_BUSY)
    744  1.1.4.2  rmind         return -EBUSY;
    745  1.1.4.2  rmind     t3_write_reg(adapter, A_SF_DATA, val);
    746  1.1.4.2  rmind     t3_write_reg(adapter, A_SF_OP,
    747  1.1.4.2  rmind              V_CONT(cont) | V_BYTECNT(byte_cnt - 1) | V_OP(1));
    748  1.1.4.2  rmind     return t3_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 10);
    749  1.1.4.2  rmind }
    750  1.1.4.2  rmind 
    751  1.1.4.2  rmind /**
    752  1.1.4.2  rmind  *  flash_wait_op - wait for a flash operation to complete
    753  1.1.4.2  rmind  *  @adapter: the adapter
    754  1.1.4.2  rmind  *  @attempts: max number of polls of the status register
    755  1.1.4.2  rmind  *  @delay: delay between polls in ms
    756  1.1.4.2  rmind  *
    757  1.1.4.2  rmind  *  Wait for a flash operation to complete by polling the status register.
    758  1.1.4.2  rmind  */
    759  1.1.4.2  rmind static int flash_wait_op(adapter_t *adapter, int attempts, int delay)
    760  1.1.4.2  rmind {
    761  1.1.4.2  rmind     int ret;
    762  1.1.4.2  rmind     u32 status;
    763  1.1.4.2  rmind 
    764  1.1.4.2  rmind     while (1) {
    765  1.1.4.2  rmind         if ((ret = sf1_write(adapter, 1, 1, SF_RD_STATUS)) != 0 ||
    766  1.1.4.2  rmind             (ret = sf1_read(adapter, 1, 0, &status)) != 0)
    767  1.1.4.2  rmind             return ret;
    768  1.1.4.2  rmind         if (!(status & 1))
    769  1.1.4.2  rmind             return 0;
    770  1.1.4.2  rmind         if (--attempts == 0)
    771  1.1.4.2  rmind             return -EAGAIN;
    772  1.1.4.2  rmind         if (delay)
    773  1.1.4.2  rmind             msleep(delay);
    774  1.1.4.2  rmind     }
    775  1.1.4.2  rmind }
    776  1.1.4.2  rmind 
    777  1.1.4.2  rmind /**
    778  1.1.4.2  rmind  *  t3_read_flash - read words from serial flash
    779  1.1.4.2  rmind  *  @adapter: the adapter
    780  1.1.4.2  rmind  *  @addr: the start address for the read
    781  1.1.4.2  rmind  *  @nwords: how many 32-bit words to read
    782  1.1.4.2  rmind  *  @data: where to store the read data
    783  1.1.4.2  rmind  *  @byte_oriented: whether to store data as bytes or as words
    784  1.1.4.2  rmind  *
    785  1.1.4.2  rmind  *  Read the specified number of 32-bit words from the serial flash.
    786  1.1.4.2  rmind  *  If @byte_oriented is set the read data is stored as a byte array
    787  1.1.4.2  rmind  *  (i.e., big-endian), otherwise as 32-bit words in the platform's
    788  1.1.4.2  rmind  *  natural endianess.
    789  1.1.4.2  rmind  */
    790  1.1.4.2  rmind int t3_read_flash(adapter_t *adapter, unsigned int addr, unsigned int nwords,
    791  1.1.4.2  rmind           u32 *data, int byte_oriented)
    792  1.1.4.2  rmind {
    793  1.1.4.2  rmind     int ret;
    794  1.1.4.2  rmind 
    795  1.1.4.2  rmind     if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3))
    796  1.1.4.2  rmind         return -EINVAL;
    797  1.1.4.2  rmind 
    798  1.1.4.2  rmind     addr = swab32(addr) | SF_RD_DATA_FAST;
    799  1.1.4.2  rmind 
    800  1.1.4.2  rmind     if ((ret = sf1_write(adapter, 4, 1, addr)) != 0 ||
    801  1.1.4.2  rmind         (ret = sf1_read(adapter, 1, 1, data)) != 0)
    802  1.1.4.2  rmind         return ret;
    803  1.1.4.2  rmind 
    804  1.1.4.2  rmind     for ( ; nwords; nwords--, data++) {
    805  1.1.4.2  rmind         ret = sf1_read(adapter, 4, nwords > 1, data);
    806  1.1.4.2  rmind         if (ret)
    807  1.1.4.2  rmind             return ret;
    808  1.1.4.2  rmind         if (byte_oriented)
    809  1.1.4.2  rmind             *data = htonl(*data);
    810  1.1.4.2  rmind     }
    811  1.1.4.2  rmind     return 0;
    812  1.1.4.2  rmind }
    813  1.1.4.2  rmind 
    814  1.1.4.2  rmind /**
    815  1.1.4.2  rmind  *  t3_write_flash - write up to a page of data to the serial flash
    816  1.1.4.2  rmind  *  @adapter: the adapter
    817  1.1.4.2  rmind  *  @addr: the start address to write
    818  1.1.4.2  rmind  *  @n: length of data to write
    819  1.1.4.2  rmind  *  @data: the data to write
    820  1.1.4.2  rmind  *
    821  1.1.4.2  rmind  *  Writes up to a page of data (256 bytes) to the serial flash starting
    822  1.1.4.2  rmind  *  at the given address.
    823  1.1.4.2  rmind  */
    824  1.1.4.2  rmind static int t3_write_flash(adapter_t *adapter, unsigned int addr,
    825  1.1.4.2  rmind               unsigned int n, const u8 *data)
    826  1.1.4.2  rmind {
    827  1.1.4.2  rmind     int ret;
    828  1.1.4.2  rmind     u32 buf[64];
    829  1.1.4.2  rmind     unsigned int i, c, left, val, offset = addr & 0xff;
    830  1.1.4.2  rmind 
    831  1.1.4.2  rmind     if (addr + n > SF_SIZE || offset + n > 256)
    832  1.1.4.2  rmind         return -EINVAL;
    833  1.1.4.2  rmind 
    834  1.1.4.2  rmind     val = swab32(addr) | SF_PROG_PAGE;
    835  1.1.4.2  rmind 
    836  1.1.4.2  rmind     if ((ret = sf1_write(adapter, 1, 0, SF_WR_ENABLE)) != 0 ||
    837  1.1.4.2  rmind         (ret = sf1_write(adapter, 4, 1, val)) != 0)
    838  1.1.4.2  rmind         return ret;
    839  1.1.4.2  rmind 
    840  1.1.4.2  rmind     for (left = n; left; left -= c) {
    841  1.1.4.2  rmind         c = min(left, 4U);
    842  1.1.4.2  rmind         for (val = 0, i = 0; i < c; ++i)
    843  1.1.4.2  rmind             val = (val << 8) + *data++;
    844  1.1.4.2  rmind 
    845  1.1.4.2  rmind         ret = sf1_write(adapter, c, c != left, val);
    846  1.1.4.2  rmind         if (ret)
    847  1.1.4.2  rmind             return ret;
    848  1.1.4.2  rmind     }
    849  1.1.4.2  rmind     if ((ret = flash_wait_op(adapter, 5, 1)) != 0)
    850  1.1.4.2  rmind         return ret;
    851  1.1.4.2  rmind 
    852  1.1.4.2  rmind     /* Read the page to verify the write succeeded */
    853  1.1.4.2  rmind     ret = t3_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1);
    854  1.1.4.2  rmind     if (ret)
    855  1.1.4.2  rmind         return ret;
    856  1.1.4.2  rmind 
    857  1.1.4.2  rmind     if (memcmp(data - n, (u8 *)buf + offset, n))
    858  1.1.4.2  rmind         return -EIO;
    859  1.1.4.2  rmind     return 0;
    860  1.1.4.2  rmind }
    861  1.1.4.2  rmind 
    862  1.1.4.2  rmind /**
    863  1.1.4.2  rmind  *  t3_get_tp_version - read the tp sram version
    864  1.1.4.2  rmind  *  @adapter: the adapter
    865  1.1.4.2  rmind  *  @vers: where to place the version
    866  1.1.4.2  rmind  *
    867  1.1.4.2  rmind  *  Reads the protocol sram version from sram.
    868  1.1.4.2  rmind  */
    869  1.1.4.2  rmind int t3_get_tp_version(adapter_t *adapter, u32 *vers)
    870  1.1.4.2  rmind {
    871  1.1.4.2  rmind     int ret;
    872  1.1.4.2  rmind 
    873  1.1.4.2  rmind     /* Get version loaded in SRAM */
    874  1.1.4.2  rmind     t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
    875  1.1.4.2  rmind     ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
    876  1.1.4.2  rmind                   1, 1, 5, 1);
    877  1.1.4.2  rmind     if (ret)
    878  1.1.4.2  rmind         return ret;
    879  1.1.4.2  rmind 
    880  1.1.4.2  rmind     *vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
    881  1.1.4.2  rmind 
    882  1.1.4.2  rmind     return 0;
    883  1.1.4.2  rmind }
    884  1.1.4.2  rmind 
    885  1.1.4.2  rmind /**
    886  1.1.4.2  rmind  *  t3_check_tpsram_version - read the tp sram version
    887  1.1.4.2  rmind  *  @adapter: the adapter
    888  1.1.4.2  rmind  *
    889  1.1.4.2  rmind  */
    890  1.1.4.2  rmind int t3_check_tpsram_version(adapter_t *adapter)
    891  1.1.4.2  rmind {
    892  1.1.4.2  rmind     int ret;
    893  1.1.4.2  rmind     u32 vers;
    894  1.1.4.2  rmind     unsigned int major, minor;
    895  1.1.4.2  rmind 
    896  1.1.4.2  rmind     /* Get version loaded in SRAM */
    897  1.1.4.2  rmind     t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
    898  1.1.4.2  rmind     ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
    899  1.1.4.2  rmind                   1, 1, 5, 1);
    900  1.1.4.2  rmind     if (ret)
    901  1.1.4.2  rmind         return ret;
    902  1.1.4.2  rmind 
    903  1.1.4.2  rmind     vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
    904  1.1.4.2  rmind 
    905  1.1.4.2  rmind     major = G_TP_VERSION_MAJOR(vers);
    906  1.1.4.2  rmind     minor = G_TP_VERSION_MINOR(vers);
    907  1.1.4.2  rmind 
    908  1.1.4.2  rmind     if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
    909  1.1.4.2  rmind         return 0;
    910  1.1.4.2  rmind 
    911  1.1.4.2  rmind     CH_WARN(adapter, "found wrong TP version (%u.%u), "
    912  1.1.4.2  rmind            "driver needs version %d.%d\n", major, minor,
    913  1.1.4.2  rmind            TP_VERSION_MAJOR, TP_VERSION_MINOR);
    914  1.1.4.2  rmind     return -EINVAL;
    915  1.1.4.2  rmind }
    916  1.1.4.2  rmind 
    917  1.1.4.2  rmind /**
    918  1.1.4.2  rmind  *  t3_check_tpsram - check if provided protocol SRAM
    919  1.1.4.2  rmind  *            is compatible with this driver
    920  1.1.4.2  rmind  *  @adapter: the adapter
    921  1.1.4.2  rmind  *  @tp_sram: the firmware image to write
    922  1.1.4.2  rmind  *  @size: image size
    923  1.1.4.2  rmind  *
    924  1.1.4.2  rmind  *  Checks if an adapter's tp sram is compatible with the driver.
    925  1.1.4.2  rmind  *  Returns 0 if the versions are compatible, a negative error otherwise.
    926  1.1.4.2  rmind  */
    927  1.1.4.2  rmind int t3_check_tpsram(adapter_t *adapter, const u8 *tp_sram, unsigned int size)
    928  1.1.4.2  rmind {
    929  1.1.4.2  rmind     u32 csum;
    930  1.1.4.2  rmind     unsigned int i;
    931  1.1.4.2  rmind     const u32 *p = (const u32 *)tp_sram;
    932  1.1.4.2  rmind 
    933  1.1.4.2  rmind     /* Verify checksum */
    934  1.1.4.2  rmind     for (csum = 0, i = 0; i < size / sizeof(csum); i++)
    935  1.1.4.2  rmind         csum += ntohl(p[i]);
    936  1.1.4.2  rmind     if (csum != 0xffffffff) {
    937  1.1.4.2  rmind         CH_ERR(adapter, "corrupted protocol SRAM image, checksum %u\n",
    938  1.1.4.2  rmind                csum);
    939  1.1.4.2  rmind         return -EINVAL;
    940  1.1.4.2  rmind     }
    941  1.1.4.2  rmind 
    942  1.1.4.2  rmind     return 0;
    943  1.1.4.2  rmind }
    944  1.1.4.2  rmind 
    945  1.1.4.2  rmind enum fw_version_type {
    946  1.1.4.2  rmind     FW_VERSION_N3,
    947  1.1.4.2  rmind     FW_VERSION_T3
    948  1.1.4.2  rmind };
    949  1.1.4.2  rmind 
    950  1.1.4.2  rmind /**
    951  1.1.4.2  rmind  *  t3_get_fw_version - read the firmware version
    952  1.1.4.2  rmind  *  @adapter: the adapter
    953  1.1.4.2  rmind  *  @vers: where to place the version
    954  1.1.4.2  rmind  *
    955  1.1.4.2  rmind  *  Reads the FW version from flash.
    956  1.1.4.2  rmind  */
    957  1.1.4.2  rmind int t3_get_fw_version(adapter_t *adapter, u32 *vers)
    958  1.1.4.2  rmind {
    959  1.1.4.2  rmind     return t3_read_flash(adapter, FW_VERS_ADDR, 1, vers, 0);
    960  1.1.4.2  rmind }
    961  1.1.4.2  rmind 
    962  1.1.4.2  rmind /**
    963  1.1.4.2  rmind  *  t3_check_fw_version - check if the FW is compatible with this driver
    964  1.1.4.2  rmind  *  @adapter: the adapter
    965  1.1.4.2  rmind  *
    966  1.1.4.2  rmind  *  Checks if an adapter's FW is compatible with the driver.  Returns 0
    967  1.1.4.2  rmind  *  if the versions are compatible, a negative error otherwise.
    968  1.1.4.2  rmind  */
    969  1.1.4.2  rmind int t3_check_fw_version(adapter_t *adapter)
    970  1.1.4.2  rmind {
    971  1.1.4.2  rmind     int ret;
    972  1.1.4.2  rmind     u32 vers;
    973  1.1.4.2  rmind     unsigned int type, major, minor;
    974  1.1.4.2  rmind 
    975  1.1.4.2  rmind     ret = t3_get_fw_version(adapter, &vers);
    976  1.1.4.2  rmind     if (ret)
    977  1.1.4.2  rmind         return ret;
    978  1.1.4.2  rmind 
    979  1.1.4.2  rmind     type = G_FW_VERSION_TYPE(vers);
    980  1.1.4.2  rmind     major = G_FW_VERSION_MAJOR(vers);
    981  1.1.4.2  rmind     minor = G_FW_VERSION_MINOR(vers);
    982  1.1.4.2  rmind 
    983  1.1.4.2  rmind     if (type == FW_VERSION_T3 && major == FW_VERSION_MAJOR &&
    984  1.1.4.2  rmind         minor == FW_VERSION_MINOR)
    985  1.1.4.2  rmind         return 0;
    986  1.1.4.2  rmind 
    987  1.1.4.2  rmind     CH_WARN(adapter, "found wrong FW version (%u.%u), "
    988  1.1.4.2  rmind            "driver needs version %d.%d\n", major, minor,
    989  1.1.4.2  rmind            FW_VERSION_MAJOR, FW_VERSION_MINOR);
    990  1.1.4.2  rmind     return -EINVAL;
    991  1.1.4.2  rmind }
    992  1.1.4.2  rmind 
    993  1.1.4.2  rmind /**
    994  1.1.4.2  rmind  *  t3_flash_erase_sectors - erase a range of flash sectors
    995  1.1.4.2  rmind  *  @adapter: the adapter
    996  1.1.4.2  rmind  *  @start: the first sector to erase
    997  1.1.4.2  rmind  *  @end: the last sector to erase
    998  1.1.4.2  rmind  *
    999  1.1.4.2  rmind  *  Erases the sectors in the given range.
   1000  1.1.4.2  rmind  */
   1001  1.1.4.2  rmind static int t3_flash_erase_sectors(adapter_t *adapter, int start, int end)
   1002  1.1.4.2  rmind {
   1003  1.1.4.2  rmind     while (start <= end) {
   1004  1.1.4.2  rmind         int ret;
   1005  1.1.4.2  rmind 
   1006  1.1.4.2  rmind         if ((ret = sf1_write(adapter, 1, 0, SF_WR_ENABLE)) != 0 ||
   1007  1.1.4.2  rmind             (ret = sf1_write(adapter, 4, 0,
   1008  1.1.4.2  rmind                      SF_ERASE_SECTOR | (start << 8))) != 0 ||
   1009  1.1.4.2  rmind             (ret = flash_wait_op(adapter, 5, 500)) != 0)
   1010  1.1.4.2  rmind             return ret;
   1011  1.1.4.2  rmind         start++;
   1012  1.1.4.2  rmind     }
   1013  1.1.4.2  rmind     return 0;
   1014  1.1.4.2  rmind }
   1015  1.1.4.2  rmind 
   1016  1.1.4.2  rmind /*
   1017  1.1.4.2  rmind  *  t3_load_fw - download firmware
   1018  1.1.4.2  rmind  *  @adapter: the adapter
   1019  1.1.4.2  rmind  *  @fw_data: the firmware image to write
   1020  1.1.4.2  rmind  *  @size: image size
   1021  1.1.4.2  rmind  *
   1022  1.1.4.2  rmind  *  Write the supplied firmware image to the card's serial flash.
   1023  1.1.4.2  rmind  *  The FW image has the following sections: @size - 8 bytes of code and
   1024  1.1.4.2  rmind  *  data, followed by 4 bytes of FW version, followed by the 32-bit
   1025  1.1.4.2  rmind  *  1's complement checksum of the whole image.
   1026  1.1.4.2  rmind  */
   1027  1.1.4.2  rmind int t3_load_fw(adapter_t *adapter, const u8 *fw_data, unsigned int size)
   1028  1.1.4.2  rmind {
   1029  1.1.4.2  rmind     u32 csum;
   1030  1.1.4.2  rmind     unsigned int i;
   1031  1.1.4.2  rmind     const u32 *p = (const u32 *)fw_data;
   1032  1.1.4.2  rmind     int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
   1033  1.1.4.2  rmind 
   1034  1.1.4.2  rmind     if ((size & 3) || size < FW_MIN_SIZE)
   1035  1.1.4.2  rmind         return -EINVAL;
   1036  1.1.4.2  rmind     if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
   1037  1.1.4.2  rmind         return -EFBIG;
   1038  1.1.4.2  rmind 
   1039  1.1.4.2  rmind     for (csum = 0, i = 0; i < size / sizeof(csum); i++)
   1040  1.1.4.2  rmind         csum += ntohl(p[i]);
   1041  1.1.4.2  rmind     if (csum != 0xffffffff) {
   1042  1.1.4.2  rmind         CH_ERR(adapter, "corrupted firmware image, checksum %u\n",
   1043  1.1.4.2  rmind                csum);
   1044  1.1.4.2  rmind         return -EINVAL;
   1045  1.1.4.2  rmind     }
   1046  1.1.4.2  rmind 
   1047  1.1.4.2  rmind     ret = t3_flash_erase_sectors(adapter, fw_sector, fw_sector);
   1048  1.1.4.2  rmind     if (ret)
   1049  1.1.4.2  rmind         goto out;
   1050  1.1.4.2  rmind 
   1051  1.1.4.2  rmind     size -= 8;  /* trim off version and checksum */
   1052  1.1.4.2  rmind     for (addr = FW_FLASH_BOOT_ADDR; size; ) {
   1053  1.1.4.2  rmind         unsigned int chunk_size = min(size, 256U);
   1054  1.1.4.2  rmind 
   1055  1.1.4.2  rmind         ret = t3_write_flash(adapter, addr, chunk_size, fw_data);
   1056  1.1.4.2  rmind         if (ret)
   1057  1.1.4.2  rmind             goto out;
   1058  1.1.4.2  rmind 
   1059  1.1.4.2  rmind         addr += chunk_size;
   1060  1.1.4.2  rmind         fw_data += chunk_size;
   1061  1.1.4.2  rmind         size -= chunk_size;
   1062  1.1.4.2  rmind     }
   1063  1.1.4.2  rmind 
   1064  1.1.4.2  rmind     ret = t3_write_flash(adapter, FW_VERS_ADDR, 4, fw_data);
   1065  1.1.4.2  rmind out:
   1066  1.1.4.2  rmind     if (ret)
   1067  1.1.4.2  rmind         CH_ERR(adapter, "firmware download failed, error %d\n", ret);
   1068  1.1.4.2  rmind     return ret;
   1069  1.1.4.2  rmind }
   1070  1.1.4.2  rmind 
   1071  1.1.4.2  rmind #define CIM_CTL_BASE 0x2000
   1072  1.1.4.2  rmind 
   1073  1.1.4.2  rmind /**
   1074  1.1.4.2  rmind  *  t3_cim_ctl_blk_read - read a block from CIM control region
   1075  1.1.4.2  rmind  *  @adap: the adapter
   1076  1.1.4.2  rmind  *  @addr: the start address within the CIM control region
   1077  1.1.4.2  rmind  *  @n: number of words to read
   1078  1.1.4.2  rmind  *  @valp: where to store the result
   1079  1.1.4.2  rmind  *
   1080  1.1.4.2  rmind  *  Reads a block of 4-byte words from the CIM control region.
   1081  1.1.4.2  rmind  */
   1082  1.1.4.2  rmind int t3_cim_ctl_blk_read(adapter_t *adap, unsigned int addr, unsigned int n,
   1083  1.1.4.2  rmind             unsigned int *valp)
   1084  1.1.4.2  rmind {
   1085  1.1.4.2  rmind     int ret = 0;
   1086  1.1.4.2  rmind 
   1087  1.1.4.2  rmind     if (t3_read_reg(adap, A_CIM_HOST_ACC_CTRL) & F_HOSTBUSY)
   1088  1.1.4.2  rmind         return -EBUSY;
   1089  1.1.4.2  rmind 
   1090  1.1.4.2  rmind     for ( ; !ret && n--; addr += 4) {
   1091  1.1.4.2  rmind         t3_write_reg(adap, A_CIM_HOST_ACC_CTRL, CIM_CTL_BASE + addr);
   1092  1.1.4.2  rmind         ret = t3_wait_op_done(adap, A_CIM_HOST_ACC_CTRL, F_HOSTBUSY,
   1093  1.1.4.2  rmind                       0, 5, 2);
   1094  1.1.4.2  rmind         if (!ret)
   1095  1.1.4.2  rmind             *valp++ = t3_read_reg(adap, A_CIM_HOST_ACC_DATA);
   1096  1.1.4.2  rmind     }
   1097  1.1.4.2  rmind     return ret;
   1098  1.1.4.2  rmind }
   1099  1.1.4.2  rmind 
   1100  1.1.4.2  rmind /**
   1101  1.1.4.2  rmind  *  t3_link_changed - handle interface link changes
   1102  1.1.4.2  rmind  *  @adapter: the adapter
   1103  1.1.4.2  rmind  *  @port_id: the port index that changed link state
   1104  1.1.4.2  rmind  *
   1105  1.1.4.2  rmind  *  Called when a port's link settings change to propagate the new values
   1106  1.1.4.2  rmind  *  to the associated PHY and MAC.  After performing the common tasks it
   1107  1.1.4.2  rmind  *  invokes an OS-specific handler.
   1108  1.1.4.2  rmind  */
   1109  1.1.4.2  rmind void t3_link_changed(adapter_t *adapter, int port_id)
   1110  1.1.4.2  rmind {
   1111  1.1.4.2  rmind     int link_ok, speed, duplex, fc;
   1112  1.1.4.2  rmind     struct port_info *pi = adap2pinfo(adapter, port_id);
   1113  1.1.4.2  rmind     struct cphy *phy = &pi->phy;
   1114  1.1.4.2  rmind     struct cmac *mac = &pi->mac;
   1115  1.1.4.2  rmind     struct link_config *lc = &pi->link_config;
   1116  1.1.4.2  rmind 
   1117  1.1.4.2  rmind     phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
   1118  1.1.4.2  rmind 
   1119  1.1.4.2  rmind     if (link_ok != lc->link_ok && adapter->params.rev > 0 &&
   1120  1.1.4.2  rmind         uses_xaui(adapter)) {
   1121  1.1.4.2  rmind         if (link_ok)
   1122  1.1.4.2  rmind             t3b_pcs_reset(mac);
   1123  1.1.4.2  rmind         t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
   1124  1.1.4.2  rmind                  link_ok ? F_TXACTENABLE | F_RXEN : 0);
   1125  1.1.4.2  rmind     }
   1126  1.1.4.2  rmind     lc->link_ok = (unsigned char)link_ok;
   1127  1.1.4.2  rmind     lc->speed = speed < 0 ? SPEED_INVALID : speed;
   1128  1.1.4.2  rmind     lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
   1129  1.1.4.2  rmind     if (lc->requested_fc & PAUSE_AUTONEG)
   1130  1.1.4.2  rmind         fc &= lc->requested_fc;
   1131  1.1.4.2  rmind     else
   1132  1.1.4.2  rmind         fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
   1133  1.1.4.2  rmind 
   1134  1.1.4.2  rmind     if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
   1135  1.1.4.2  rmind         /* Set MAC speed, duplex, and flow control to match PHY. */
   1136  1.1.4.2  rmind         t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc);
   1137  1.1.4.2  rmind         lc->fc = (unsigned char)fc;
   1138  1.1.4.2  rmind     }
   1139  1.1.4.2  rmind 
   1140  1.1.4.2  rmind     t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
   1141  1.1.4.2  rmind }
   1142  1.1.4.2  rmind 
   1143  1.1.4.2  rmind /**
   1144  1.1.4.2  rmind  *  t3_link_start - apply link configuration to MAC/PHY
   1145  1.1.4.2  rmind  *  @phy: the PHY to setup
   1146  1.1.4.2  rmind  *  @mac: the MAC to setup
   1147  1.1.4.2  rmind  *  @lc: the requested link configuration
   1148  1.1.4.2  rmind  *
   1149  1.1.4.2  rmind  *  Set up a port's MAC and PHY according to a desired link configuration.
   1150  1.1.4.2  rmind  *  - If the PHY can auto-negotiate first decide what to advertise, then
   1151  1.1.4.2  rmind  *    enable/disable auto-negotiation as desired, and reset.
   1152  1.1.4.2  rmind  *  - If the PHY does not auto-negotiate just reset it.
   1153  1.1.4.2  rmind  *  - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
   1154  1.1.4.2  rmind  *    otherwise do it later based on the outcome of auto-negotiation.
   1155  1.1.4.2  rmind  */
   1156  1.1.4.2  rmind int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
   1157  1.1.4.2  rmind {
   1158  1.1.4.2  rmind     unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
   1159  1.1.4.2  rmind 
   1160  1.1.4.2  rmind     lc->link_ok = 0;
   1161  1.1.4.2  rmind     if (lc->supported & SUPPORTED_Autoneg) {
   1162  1.1.4.2  rmind         lc->advertising &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause);
   1163  1.1.4.2  rmind         if (fc) {
   1164  1.1.4.2  rmind             lc->advertising |= ADVERTISED_Asym_Pause;
   1165  1.1.4.2  rmind             if (fc & PAUSE_RX)
   1166  1.1.4.2  rmind                 lc->advertising |= ADVERTISED_Pause;
   1167  1.1.4.2  rmind         }
   1168  1.1.4.2  rmind         phy->ops->advertise(phy, lc->advertising);
   1169  1.1.4.2  rmind 
   1170  1.1.4.2  rmind         if (lc->autoneg == AUTONEG_DISABLE) {
   1171  1.1.4.2  rmind             lc->speed = lc->requested_speed;
   1172  1.1.4.2  rmind             lc->duplex = lc->requested_duplex;
   1173  1.1.4.2  rmind             lc->fc = (unsigned char)fc;
   1174  1.1.4.2  rmind             t3_mac_set_speed_duplex_fc(mac, lc->speed, lc->duplex,
   1175  1.1.4.2  rmind                            fc);
   1176  1.1.4.2  rmind             /* Also disables autoneg */
   1177  1.1.4.2  rmind             phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
   1178  1.1.4.2  rmind             phy->ops->reset(phy, 0);
   1179  1.1.4.2  rmind         } else
   1180  1.1.4.2  rmind             phy->ops->autoneg_enable(phy);
   1181  1.1.4.2  rmind     } else {
   1182  1.1.4.2  rmind         t3_mac_set_speed_duplex_fc(mac, -1, -1, fc);
   1183  1.1.4.2  rmind         lc->fc = (unsigned char)fc;
   1184  1.1.4.2  rmind         phy->ops->reset(phy, 0);
   1185  1.1.4.2  rmind     }
   1186  1.1.4.2  rmind     return 0;
   1187  1.1.4.2  rmind }
   1188  1.1.4.2  rmind 
   1189  1.1.4.2  rmind /**
   1190  1.1.4.2  rmind  *  t3_set_vlan_accel - control HW VLAN extraction
   1191  1.1.4.2  rmind  *  @adapter: the adapter
   1192  1.1.4.2  rmind  *  @ports: bitmap of adapter ports to operate on
   1193  1.1.4.2  rmind  *  @on: enable (1) or disable (0) HW VLAN extraction
   1194  1.1.4.2  rmind  *
   1195  1.1.4.2  rmind  *  Enables or disables HW extraction of VLAN tags for the given port.
   1196  1.1.4.2  rmind  */
   1197  1.1.4.2  rmind void t3_set_vlan_accel(adapter_t *adapter, unsigned int ports, int on)
   1198  1.1.4.2  rmind {
   1199  1.1.4.2  rmind     t3_set_reg_field(adapter, A_TP_OUT_CONFIG,
   1200  1.1.4.2  rmind              ports << S_VLANEXTRACTIONENABLE,
   1201  1.1.4.2  rmind              on ? (ports << S_VLANEXTRACTIONENABLE) : 0);
   1202  1.1.4.2  rmind }
   1203  1.1.4.2  rmind 
   1204  1.1.4.2  rmind struct intr_info {
   1205  1.1.4.2  rmind     unsigned int mask;       /* bits to check in interrupt status */
   1206  1.1.4.2  rmind     const char *msg;         /* message to print or NULL */
   1207  1.1.4.2  rmind     short stat_idx;          /* stat counter to increment or -1 */
   1208  1.1.4.2  rmind     unsigned short fatal:1;  /* whether the condition reported is fatal */
   1209  1.1.4.2  rmind };
   1210  1.1.4.2  rmind 
   1211  1.1.4.2  rmind /**
   1212  1.1.4.2  rmind  *  t3_handle_intr_status - table driven interrupt handler
   1213  1.1.4.2  rmind  *  @adapter: the adapter that generated the interrupt
   1214  1.1.4.2  rmind  *  @reg: the interrupt status register to process
   1215  1.1.4.2  rmind  *  @mask: a mask to apply to the interrupt status
   1216  1.1.4.2  rmind  *  @acts: table of interrupt actions
   1217  1.1.4.2  rmind  *  @stats: statistics counters tracking interrupt occurences
   1218  1.1.4.2  rmind  *
   1219  1.1.4.2  rmind  *  A table driven interrupt handler that applies a set of masks to an
   1220  1.1.4.2  rmind  *  interrupt status word and performs the corresponding actions if the
   1221  1.1.4.2  rmind  *  interrupts described by the mask have occured.  The actions include
   1222  1.1.4.2  rmind  *  optionally printing a warning or alert message, and optionally
   1223  1.1.4.2  rmind  *  incrementing a stat counter.  The table is terminated by an entry
   1224  1.1.4.2  rmind  *  specifying mask 0.  Returns the number of fatal interrupt conditions.
   1225  1.1.4.2  rmind  */
   1226  1.1.4.2  rmind static int t3_handle_intr_status(adapter_t *adapter, unsigned int reg,
   1227  1.1.4.2  rmind                  unsigned int mask,
   1228  1.1.4.2  rmind                  const struct intr_info *acts,
   1229  1.1.4.2  rmind                  unsigned long *stats)
   1230  1.1.4.2  rmind {
   1231  1.1.4.2  rmind     int fatal = 0;
   1232  1.1.4.2  rmind     unsigned int status = t3_read_reg(adapter, reg) & mask;
   1233  1.1.4.2  rmind 
   1234  1.1.4.2  rmind     for ( ; acts->mask; ++acts) {
   1235  1.1.4.2  rmind         if (!(status & acts->mask)) continue;
   1236  1.1.4.2  rmind         if (acts->fatal) {
   1237  1.1.4.2  rmind             fatal++;
   1238  1.1.4.2  rmind             CH_ALERT(adapter, "%s (0x%x)\n",
   1239  1.1.4.2  rmind                  acts->msg, status & acts->mask);
   1240  1.1.4.2  rmind         } else if (acts->msg)
   1241  1.1.4.2  rmind             CH_WARN(adapter, "%s (0x%x)\n",
   1242  1.1.4.2  rmind                 acts->msg, status & acts->mask);
   1243  1.1.4.2  rmind         if (acts->stat_idx >= 0)
   1244  1.1.4.2  rmind             stats[acts->stat_idx]++;
   1245  1.1.4.2  rmind     }
   1246  1.1.4.2  rmind     if (status)                           /* clear processed interrupts */
   1247  1.1.4.2  rmind         t3_write_reg(adapter, reg, status);
   1248  1.1.4.2  rmind     return fatal;
   1249  1.1.4.2  rmind }
   1250  1.1.4.2  rmind 
   1251  1.1.4.2  rmind #define SGE_INTR_MASK (F_RSPQDISABLED)
   1252  1.1.4.2  rmind #define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \
   1253  1.1.4.2  rmind                F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \
   1254  1.1.4.2  rmind                F_NFASRCHFAIL)
   1255  1.1.4.2  rmind #define MC7_INTR_MASK (F_AE | F_UE | F_CE | V_PE(M_PE))
   1256  1.1.4.2  rmind #define XGM_INTR_MASK (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \
   1257  1.1.4.2  rmind                V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR) | \
   1258  1.1.4.2  rmind                F_TXFIFO_UNDERRUN | F_RXFIFO_OVERFLOW)
   1259  1.1.4.2  rmind #define PCIX_INTR_MASK (F_MSTDETPARERR | F_SIGTARABT | F_RCVTARABT | \
   1260  1.1.4.2  rmind             F_RCVMSTABT | F_SIGSYSERR | F_DETPARERR | \
   1261  1.1.4.2  rmind             F_SPLCMPDIS | F_UNXSPLCMP | F_RCVSPLCMPERR | \
   1262  1.1.4.2  rmind             F_DETCORECCERR | F_DETUNCECCERR | F_PIOPARERR | \
   1263  1.1.4.2  rmind             V_WFPARERR(M_WFPARERR) | V_RFPARERR(M_RFPARERR) | \
   1264  1.1.4.2  rmind             V_CFPARERR(M_CFPARERR) /* | V_MSIXPARERR(M_MSIXPARERR) */)
   1265  1.1.4.2  rmind #define PCIE_INTR_MASK (F_UNXSPLCPLERRR | F_UNXSPLCPLERRC | F_PCIE_PIOPARERR |\
   1266  1.1.4.2  rmind             F_PCIE_WFPARERR | F_PCIE_RFPARERR | F_PCIE_CFPARERR | \
   1267  1.1.4.2  rmind             /* V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR) | */ \
   1268  1.1.4.2  rmind             V_BISTERR(M_BISTERR) | F_PEXERR)
   1269  1.1.4.2  rmind #define ULPRX_INTR_MASK F_PARERR
   1270  1.1.4.2  rmind #define ULPTX_INTR_MASK 0
   1271  1.1.4.2  rmind #define CPLSW_INTR_MASK (F_TP_FRAMING_ERROR | \
   1272  1.1.4.2  rmind              F_SGE_FRAMING_ERROR | F_CIM_FRAMING_ERROR | \
   1273  1.1.4.2  rmind              F_ZERO_SWITCH_ERROR)
   1274  1.1.4.2  rmind #define CIM_INTR_MASK (F_BLKWRPLINT | F_BLKRDPLINT | F_BLKWRCTLINT | \
   1275  1.1.4.2  rmind                F_BLKRDCTLINT | F_BLKWRFLASHINT | F_BLKRDFLASHINT | \
   1276  1.1.4.2  rmind                F_SGLWRFLASHINT | F_WRBLKFLASHINT | F_BLKWRBOOTINT | \
   1277  1.1.4.2  rmind                F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT)
   1278  1.1.4.2  rmind #define PMTX_INTR_MASK (F_ZERO_C_CMD_ERROR | ICSPI_FRM_ERR | OESPI_FRM_ERR | \
   1279  1.1.4.2  rmind             V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR) | \
   1280  1.1.4.2  rmind             V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR))
   1281  1.1.4.2  rmind #define PMRX_INTR_MASK (F_ZERO_E_CMD_ERROR | IESPI_FRM_ERR | OCSPI_FRM_ERR | \
   1282  1.1.4.2  rmind             V_IESPI_PAR_ERROR(M_IESPI_PAR_ERROR) | \
   1283  1.1.4.2  rmind             V_OCSPI_PAR_ERROR(M_OCSPI_PAR_ERROR))
   1284  1.1.4.2  rmind #define MPS_INTR_MASK (V_TX0TPPARERRENB(M_TX0TPPARERRENB) | \
   1285  1.1.4.2  rmind                V_TX1TPPARERRENB(M_TX1TPPARERRENB) | \
   1286  1.1.4.2  rmind                V_RXTPPARERRENB(M_RXTPPARERRENB) | \
   1287  1.1.4.2  rmind                V_MCAPARERRENB(M_MCAPARERRENB))
   1288  1.1.4.2  rmind #define PL_INTR_MASK (F_T3DBG | F_XGMAC0_0 | F_XGMAC0_1 | F_MC5A | F_PM1_TX | \
   1289  1.1.4.2  rmind               F_PM1_RX | F_ULP2_TX | F_ULP2_RX | F_TP1 | F_CIM | \
   1290  1.1.4.2  rmind               F_MC7_CM | F_MC7_PMTX | F_MC7_PMRX | F_SGE3 | F_PCIM0 | \
   1291  1.1.4.2  rmind               F_MPS0 | F_CPL_SWITCH)
   1292  1.1.4.2  rmind 
   1293  1.1.4.2  rmind /*
   1294  1.1.4.2  rmind  * Interrupt handler for the PCIX1 module.
   1295  1.1.4.2  rmind  */
   1296  1.1.4.2  rmind static void pci_intr_handler(adapter_t *adapter)
   1297  1.1.4.2  rmind {
   1298  1.1.4.2  rmind     static struct intr_info pcix1_intr_info[] = {
   1299  1.1.4.2  rmind         { F_MSTDETPARERR, "PCI master detected parity error", -1, 1 },
   1300  1.1.4.2  rmind         { F_SIGTARABT, "PCI signaled target abort", -1, 1 },
   1301  1.1.4.2  rmind         { F_RCVTARABT, "PCI received target abort", -1, 1 },
   1302  1.1.4.2  rmind         { F_RCVMSTABT, "PCI received master abort", -1, 1 },
   1303  1.1.4.2  rmind         { F_SIGSYSERR, "PCI signaled system error", -1, 1 },
   1304  1.1.4.2  rmind         { F_DETPARERR, "PCI detected parity error", -1, 1 },
   1305  1.1.4.2  rmind         { F_SPLCMPDIS, "PCI split completion discarded", -1, 1 },
   1306  1.1.4.2  rmind         { F_UNXSPLCMP, "PCI unexpected split completion error", -1, 1 },
   1307  1.1.4.2  rmind         { F_RCVSPLCMPERR, "PCI received split completion error", -1,
   1308  1.1.4.2  rmind           1 },
   1309  1.1.4.2  rmind         { F_DETCORECCERR, "PCI correctable ECC error",
   1310  1.1.4.2  rmind           STAT_PCI_CORR_ECC, 0 },
   1311  1.1.4.2  rmind         { F_DETUNCECCERR, "PCI uncorrectable ECC error", -1, 1 },
   1312  1.1.4.2  rmind         { F_PIOPARERR, "PCI PIO FIFO parity error", -1, 1 },
   1313  1.1.4.2  rmind         { V_WFPARERR(M_WFPARERR), "PCI write FIFO parity error", -1,
   1314  1.1.4.2  rmind           1 },
   1315  1.1.4.2  rmind         { V_RFPARERR(M_RFPARERR), "PCI read FIFO parity error", -1,
   1316  1.1.4.2  rmind           1 },
   1317  1.1.4.2  rmind         { V_CFPARERR(M_CFPARERR), "PCI command FIFO parity error", -1,
   1318  1.1.4.2  rmind           1 },
   1319  1.1.4.2  rmind         { V_MSIXPARERR(M_MSIXPARERR), "PCI MSI-X table/PBA parity "
   1320  1.1.4.2  rmind           "error", -1, 1 },
   1321  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1322  1.1.4.2  rmind     };
   1323  1.1.4.2  rmind 
   1324  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_PCIX_INT_CAUSE, PCIX_INTR_MASK,
   1325  1.1.4.2  rmind                   pcix1_intr_info, adapter->irq_stats))
   1326  1.1.4.2  rmind         t3_fatal_err(adapter);
   1327  1.1.4.2  rmind }
   1328  1.1.4.2  rmind 
   1329  1.1.4.2  rmind /*
   1330  1.1.4.2  rmind  * Interrupt handler for the PCIE module.
   1331  1.1.4.2  rmind  */
   1332  1.1.4.2  rmind static void pcie_intr_handler(adapter_t *adapter)
   1333  1.1.4.2  rmind {
   1334  1.1.4.2  rmind     static struct intr_info pcie_intr_info[] = {
   1335  1.1.4.2  rmind         { F_PEXERR, "PCI PEX error", -1, 1 },
   1336  1.1.4.2  rmind         { F_UNXSPLCPLERRR,
   1337  1.1.4.2  rmind           "PCI unexpected split completion DMA read error", -1, 1 },
   1338  1.1.4.2  rmind         { F_UNXSPLCPLERRC,
   1339  1.1.4.2  rmind           "PCI unexpected split completion DMA command error", -1, 1 },
   1340  1.1.4.2  rmind         { F_PCIE_PIOPARERR, "PCI PIO FIFO parity error", -1, 1 },
   1341  1.1.4.2  rmind         { F_PCIE_WFPARERR, "PCI write FIFO parity error", -1, 1 },
   1342  1.1.4.2  rmind         { F_PCIE_RFPARERR, "PCI read FIFO parity error", -1, 1 },
   1343  1.1.4.2  rmind         { F_PCIE_CFPARERR, "PCI command FIFO parity error", -1, 1 },
   1344  1.1.4.2  rmind         { V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR),
   1345  1.1.4.2  rmind           "PCI MSI-X table/PBA parity error", -1, 1 },
   1346  1.1.4.2  rmind         { V_BISTERR(M_BISTERR), "PCI BIST error", -1, 1 },
   1347  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1348  1.1.4.2  rmind     };
   1349  1.1.4.2  rmind 
   1350  1.1.4.2  rmind     if (t3_read_reg(adapter, A_PCIE_INT_CAUSE) & F_PEXERR)
   1351  1.1.4.2  rmind         CH_ALERT(adapter, "PEX error code 0x%x\n",
   1352  1.1.4.2  rmind              t3_read_reg(adapter, A_PCIE_PEX_ERR));
   1353  1.1.4.2  rmind 
   1354  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_PCIE_INT_CAUSE, PCIE_INTR_MASK,
   1355  1.1.4.2  rmind                   pcie_intr_info, adapter->irq_stats))
   1356  1.1.4.2  rmind         t3_fatal_err(adapter);
   1357  1.1.4.2  rmind }
   1358  1.1.4.2  rmind 
   1359  1.1.4.2  rmind /*
   1360  1.1.4.2  rmind  * TP interrupt handler.
   1361  1.1.4.2  rmind  */
   1362  1.1.4.2  rmind static void tp_intr_handler(adapter_t *adapter)
   1363  1.1.4.2  rmind {
   1364  1.1.4.2  rmind     static struct intr_info tp_intr_info[] = {
   1365  1.1.4.2  rmind         { 0xffffff,  "TP parity error", -1, 1 },
   1366  1.1.4.2  rmind         { 0x1000000, "TP out of Rx pages", -1, 1 },
   1367  1.1.4.2  rmind         { 0x2000000, "TP out of Tx pages", -1, 1 },
   1368  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1369  1.1.4.2  rmind     };
   1370  1.1.4.2  rmind 
   1371  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_TP_INT_CAUSE, 0xffffffff,
   1372  1.1.4.2  rmind                   tp_intr_info, NULL))
   1373  1.1.4.2  rmind         t3_fatal_err(adapter);
   1374  1.1.4.2  rmind }
   1375  1.1.4.2  rmind 
   1376  1.1.4.2  rmind /*
   1377  1.1.4.2  rmind  * CIM interrupt handler.
   1378  1.1.4.2  rmind  */
   1379  1.1.4.2  rmind static void cim_intr_handler(adapter_t *adapter)
   1380  1.1.4.2  rmind {
   1381  1.1.4.2  rmind     static struct intr_info cim_intr_info[] = {
   1382  1.1.4.2  rmind         { F_RSVDSPACEINT, "CIM reserved space write", -1, 1 },
   1383  1.1.4.2  rmind         { F_SDRAMRANGEINT, "CIM SDRAM address out of range", -1, 1 },
   1384  1.1.4.2  rmind         { F_FLASHRANGEINT, "CIM flash address out of range", -1, 1 },
   1385  1.1.4.2  rmind         { F_BLKWRBOOTINT, "CIM block write to boot space", -1, 1 },
   1386  1.1.4.2  rmind         { F_WRBLKFLASHINT, "CIM write to cached flash space", -1, 1 },
   1387  1.1.4.2  rmind         { F_SGLWRFLASHINT, "CIM single write to flash space", -1, 1 },
   1388  1.1.4.2  rmind         { F_BLKRDFLASHINT, "CIM block read from flash space", -1, 1 },
   1389  1.1.4.2  rmind         { F_BLKWRFLASHINT, "CIM block write to flash space", -1, 1 },
   1390  1.1.4.2  rmind         { F_BLKRDCTLINT, "CIM block read from CTL space", -1, 1 },
   1391  1.1.4.2  rmind         { F_BLKWRCTLINT, "CIM block write to CTL space", -1, 1 },
   1392  1.1.4.2  rmind         { F_BLKRDPLINT, "CIM block read from PL space", -1, 1 },
   1393  1.1.4.2  rmind         { F_BLKWRPLINT, "CIM block write to PL space", -1, 1 },
   1394  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1395  1.1.4.2  rmind         };
   1396  1.1.4.2  rmind 
   1397  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_CIM_HOST_INT_CAUSE, 0xffffffff,
   1398  1.1.4.2  rmind                   cim_intr_info, NULL))
   1399  1.1.4.2  rmind         t3_fatal_err(adapter);
   1400  1.1.4.2  rmind }
   1401  1.1.4.2  rmind 
   1402  1.1.4.2  rmind /*
   1403  1.1.4.2  rmind  * ULP RX interrupt handler.
   1404  1.1.4.2  rmind  */
   1405  1.1.4.2  rmind static void ulprx_intr_handler(adapter_t *adapter)
   1406  1.1.4.2  rmind {
   1407  1.1.4.2  rmind     static struct intr_info ulprx_intr_info[] = {
   1408  1.1.4.2  rmind         { F_PARERR, "ULP RX parity error", -1, 1 },
   1409  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1410  1.1.4.2  rmind         };
   1411  1.1.4.2  rmind 
   1412  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_ULPRX_INT_CAUSE, 0xffffffff,
   1413  1.1.4.2  rmind                   ulprx_intr_info, NULL))
   1414  1.1.4.2  rmind         t3_fatal_err(adapter);
   1415  1.1.4.2  rmind }
   1416  1.1.4.2  rmind 
   1417  1.1.4.2  rmind /*
   1418  1.1.4.2  rmind  * ULP TX interrupt handler.
   1419  1.1.4.2  rmind  */
   1420  1.1.4.2  rmind static void ulptx_intr_handler(adapter_t *adapter)
   1421  1.1.4.2  rmind {
   1422  1.1.4.2  rmind     static struct intr_info ulptx_intr_info[] = {
   1423  1.1.4.2  rmind         { F_PBL_BOUND_ERR_CH0, "ULP TX channel 0 PBL out of bounds",
   1424  1.1.4.2  rmind           STAT_ULP_CH0_PBL_OOB, 0 },
   1425  1.1.4.2  rmind         { F_PBL_BOUND_ERR_CH1, "ULP TX channel 1 PBL out of bounds",
   1426  1.1.4.2  rmind           STAT_ULP_CH1_PBL_OOB, 0 },
   1427  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1428  1.1.4.2  rmind         };
   1429  1.1.4.2  rmind 
   1430  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_ULPTX_INT_CAUSE, 0xffffffff,
   1431  1.1.4.2  rmind                   ulptx_intr_info, adapter->irq_stats))
   1432  1.1.4.2  rmind         t3_fatal_err(adapter);
   1433  1.1.4.2  rmind }
   1434  1.1.4.2  rmind 
   1435  1.1.4.2  rmind #define ICSPI_FRM_ERR (F_ICSPI0_FIFO2X_RX_FRAMING_ERROR | \
   1436  1.1.4.2  rmind     F_ICSPI1_FIFO2X_RX_FRAMING_ERROR | F_ICSPI0_RX_FRAMING_ERROR | \
   1437  1.1.4.2  rmind     F_ICSPI1_RX_FRAMING_ERROR | F_ICSPI0_TX_FRAMING_ERROR | \
   1438  1.1.4.2  rmind     F_ICSPI1_TX_FRAMING_ERROR)
   1439  1.1.4.2  rmind #define OESPI_FRM_ERR (F_OESPI0_RX_FRAMING_ERROR | \
   1440  1.1.4.2  rmind     F_OESPI1_RX_FRAMING_ERROR | F_OESPI0_TX_FRAMING_ERROR | \
   1441  1.1.4.2  rmind     F_OESPI1_TX_FRAMING_ERROR | F_OESPI0_OFIFO2X_TX_FRAMING_ERROR | \
   1442  1.1.4.2  rmind     F_OESPI1_OFIFO2X_TX_FRAMING_ERROR)
   1443  1.1.4.2  rmind 
   1444  1.1.4.2  rmind /*
   1445  1.1.4.2  rmind  * PM TX interrupt handler.
   1446  1.1.4.2  rmind  */
   1447  1.1.4.2  rmind static void pmtx_intr_handler(adapter_t *adapter)
   1448  1.1.4.2  rmind {
   1449  1.1.4.2  rmind     static struct intr_info pmtx_intr_info[] = {
   1450  1.1.4.2  rmind         { F_ZERO_C_CMD_ERROR, "PMTX 0-length pcmd", -1, 1 },
   1451  1.1.4.2  rmind         { ICSPI_FRM_ERR, "PMTX ispi framing error", -1, 1 },
   1452  1.1.4.2  rmind         { OESPI_FRM_ERR, "PMTX ospi framing error", -1, 1 },
   1453  1.1.4.2  rmind         { V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR),
   1454  1.1.4.2  rmind           "PMTX ispi parity error", -1, 1 },
   1455  1.1.4.2  rmind         { V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR),
   1456  1.1.4.2  rmind           "PMTX ospi parity error", -1, 1 },
   1457  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1458  1.1.4.2  rmind         };
   1459  1.1.4.2  rmind 
   1460  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_PM1_TX_INT_CAUSE, 0xffffffff,
   1461  1.1.4.2  rmind                   pmtx_intr_info, NULL))
   1462  1.1.4.2  rmind         t3_fatal_err(adapter);
   1463  1.1.4.2  rmind }
   1464  1.1.4.2  rmind 
   1465  1.1.4.2  rmind #define IESPI_FRM_ERR (F_IESPI0_FIFO2X_RX_FRAMING_ERROR | \
   1466  1.1.4.2  rmind     F_IESPI1_FIFO2X_RX_FRAMING_ERROR | F_IESPI0_RX_FRAMING_ERROR | \
   1467  1.1.4.2  rmind     F_IESPI1_RX_FRAMING_ERROR | F_IESPI0_TX_FRAMING_ERROR | \
   1468  1.1.4.2  rmind     F_IESPI1_TX_FRAMING_ERROR)
   1469  1.1.4.2  rmind #define OCSPI_FRM_ERR (F_OCSPI0_RX_FRAMING_ERROR | \
   1470  1.1.4.2  rmind     F_OCSPI1_RX_FRAMING_ERROR | F_OCSPI0_TX_FRAMING_ERROR | \
   1471  1.1.4.2  rmind     F_OCSPI1_TX_FRAMING_ERROR | F_OCSPI0_OFIFO2X_TX_FRAMING_ERROR | \
   1472  1.1.4.2  rmind     F_OCSPI1_OFIFO2X_TX_FRAMING_ERROR)
   1473  1.1.4.2  rmind 
   1474  1.1.4.2  rmind /*
   1475  1.1.4.2  rmind  * PM RX interrupt handler.
   1476  1.1.4.2  rmind  */
   1477  1.1.4.2  rmind static void pmrx_intr_handler(adapter_t *adapter)
   1478  1.1.4.2  rmind {
   1479  1.1.4.2  rmind     static struct intr_info pmrx_intr_info[] = {
   1480  1.1.4.2  rmind         { F_ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1 },
   1481  1.1.4.2  rmind         { IESPI_FRM_ERR, "PMRX ispi framing error", -1, 1 },
   1482  1.1.4.2  rmind         { OCSPI_FRM_ERR, "PMRX ospi framing error", -1, 1 },
   1483  1.1.4.2  rmind         { V_IESPI_PAR_ERROR(M_IESPI_PAR_ERROR),
   1484  1.1.4.2  rmind           "PMRX ispi parity error", -1, 1 },
   1485  1.1.4.2  rmind         { V_OCSPI_PAR_ERROR(M_OCSPI_PAR_ERROR),
   1486  1.1.4.2  rmind           "PMRX ospi parity error", -1, 1 },
   1487  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1488  1.1.4.2  rmind         };
   1489  1.1.4.2  rmind 
   1490  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_PM1_RX_INT_CAUSE, 0xffffffff,
   1491  1.1.4.2  rmind                   pmrx_intr_info, NULL))
   1492  1.1.4.2  rmind         t3_fatal_err(adapter);
   1493  1.1.4.2  rmind }
   1494  1.1.4.2  rmind 
   1495  1.1.4.2  rmind /*
   1496  1.1.4.2  rmind  * CPL switch interrupt handler.
   1497  1.1.4.2  rmind  */
   1498  1.1.4.2  rmind static void cplsw_intr_handler(adapter_t *adapter)
   1499  1.1.4.2  rmind {
   1500  1.1.4.2  rmind     static struct intr_info cplsw_intr_info[] = {
   1501  1.1.4.2  rmind //      { F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1 },
   1502  1.1.4.2  rmind         { F_TP_FRAMING_ERROR, "CPL switch TP framing error", -1, 1 },
   1503  1.1.4.2  rmind         { F_SGE_FRAMING_ERROR, "CPL switch SGE framing error", -1, 1 },
   1504  1.1.4.2  rmind         { F_CIM_FRAMING_ERROR, "CPL switch CIM framing error", -1, 1 },
   1505  1.1.4.2  rmind         { F_ZERO_SWITCH_ERROR, "CPL switch no-switch error", -1, 1 },
   1506  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1507  1.1.4.2  rmind         };
   1508  1.1.4.2  rmind 
   1509  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_CPL_INTR_CAUSE, 0xffffffff,
   1510  1.1.4.2  rmind                   cplsw_intr_info, NULL))
   1511  1.1.4.2  rmind         t3_fatal_err(adapter);
   1512  1.1.4.2  rmind }
   1513  1.1.4.2  rmind 
   1514  1.1.4.2  rmind /*
   1515  1.1.4.2  rmind  * MPS interrupt handler.
   1516  1.1.4.2  rmind  */
   1517  1.1.4.2  rmind static void mps_intr_handler(adapter_t *adapter)
   1518  1.1.4.2  rmind {
   1519  1.1.4.2  rmind     static struct intr_info mps_intr_info[] = {
   1520  1.1.4.2  rmind         { 0x1ff, "MPS parity error", -1, 1 },
   1521  1.1.4.2  rmind         { 0, NULL, 0, 0 }
   1522  1.1.4.2  rmind     };
   1523  1.1.4.2  rmind 
   1524  1.1.4.2  rmind     if (t3_handle_intr_status(adapter, A_MPS_INT_CAUSE, 0xffffffff,
   1525  1.1.4.2  rmind                   mps_intr_info, NULL))
   1526  1.1.4.2  rmind         t3_fatal_err(adapter);
   1527  1.1.4.2  rmind }
   1528  1.1.4.2  rmind 
   1529  1.1.4.2  rmind #define MC7_INTR_FATAL (F_UE | V_PE(M_PE) | F_AE)
   1530  1.1.4.2  rmind 
   1531  1.1.4.2  rmind /*
   1532  1.1.4.2  rmind  * MC7 interrupt handler.
   1533  1.1.4.2  rmind  */
   1534  1.1.4.2  rmind static void mc7_intr_handler(struct mc7 *mc7)
   1535  1.1.4.2  rmind {
   1536  1.1.4.2  rmind     adapter_t *adapter = mc7->adapter;
   1537  1.1.4.2  rmind     u32 cause = t3_read_reg(adapter, mc7->offset + A_MC7_INT_CAUSE);
   1538  1.1.4.2  rmind 
   1539  1.1.4.2  rmind     if (cause & F_CE) {
   1540  1.1.4.2  rmind         mc7->stats.corr_err++;
   1541  1.1.4.2  rmind         CH_WARN(adapter, "%s MC7 correctable error at addr 0x%x, "
   1542  1.1.4.2  rmind             "data 0x%x 0x%x 0x%x\n", mc7->name,
   1543  1.1.4.2  rmind             t3_read_reg(adapter, mc7->offset + A_MC7_CE_ADDR),
   1544  1.1.4.2  rmind             t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA0),
   1545  1.1.4.2  rmind             t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA1),
   1546  1.1.4.2  rmind             t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA2));
   1547  1.1.4.2  rmind     }
   1548  1.1.4.2  rmind 
   1549  1.1.4.2  rmind     if (cause & F_UE) {
   1550  1.1.4.2  rmind         mc7->stats.uncorr_err++;
   1551  1.1.4.2  rmind         CH_ALERT(adapter, "%s MC7 uncorrectable error at addr 0x%x, "
   1552  1.1.4.2  rmind              "data 0x%x 0x%x 0x%x\n", mc7->name,
   1553  1.1.4.2  rmind              t3_read_reg(adapter, mc7->offset + A_MC7_UE_ADDR),
   1554  1.1.4.2  rmind              t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA0),
   1555  1.1.4.2  rmind              t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA1),
   1556  1.1.4.2  rmind              t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA2));
   1557  1.1.4.2  rmind     }
   1558  1.1.4.2  rmind 
   1559  1.1.4.2  rmind     if (G_PE(cause)) {
   1560  1.1.4.2  rmind         mc7->stats.parity_err++;
   1561  1.1.4.2  rmind         CH_ALERT(adapter, "%s MC7 parity error 0x%x\n",
   1562  1.1.4.2  rmind              mc7->name, G_PE(cause));
   1563  1.1.4.2  rmind     }
   1564  1.1.4.2  rmind 
   1565  1.1.4.2  rmind     if (cause & F_AE) {
   1566  1.1.4.2  rmind         u32 addr = 0;
   1567  1.1.4.2  rmind 
   1568  1.1.4.2  rmind         if (adapter->params.rev > 0)
   1569  1.1.4.2  rmind             addr = t3_read_reg(adapter,
   1570  1.1.4.2  rmind                        mc7->offset + A_MC7_ERR_ADDR);
   1571  1.1.4.2  rmind         mc7->stats.addr_err++;
   1572  1.1.4.2  rmind         CH_ALERT(adapter, "%s MC7 address error: 0x%x\n",
   1573  1.1.4.2  rmind              mc7->name, addr);
   1574  1.1.4.2  rmind     }
   1575  1.1.4.2  rmind 
   1576  1.1.4.2  rmind     if (cause & MC7_INTR_FATAL)
   1577  1.1.4.2  rmind         t3_fatal_err(adapter);
   1578  1.1.4.2  rmind 
   1579  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_INT_CAUSE, cause);
   1580  1.1.4.2  rmind }
   1581  1.1.4.2  rmind 
   1582  1.1.4.2  rmind #define XGM_INTR_FATAL (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \
   1583  1.1.4.2  rmind             V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR))
   1584  1.1.4.2  rmind /*
   1585  1.1.4.2  rmind  * XGMAC interrupt handler.
   1586  1.1.4.2  rmind  */
   1587  1.1.4.2  rmind static int mac_intr_handler(adapter_t *adap, unsigned int idx)
   1588  1.1.4.2  rmind {
   1589  1.1.4.2  rmind     u32 cause;
   1590  1.1.4.2  rmind     struct cmac *mac;
   1591  1.1.4.2  rmind 
   1592  1.1.4.2  rmind     idx = idx == 0 ? 0 : adapter_info(adap)->nports0; /* MAC idx -> port */
   1593  1.1.4.2  rmind     mac = &adap2pinfo(adap, idx)->mac;
   1594  1.1.4.2  rmind     cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset);
   1595  1.1.4.2  rmind 
   1596  1.1.4.2  rmind     if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) {
   1597  1.1.4.2  rmind         mac->stats.tx_fifo_parity_err++;
   1598  1.1.4.2  rmind         CH_ALERT(adap, "port%d: MAC TX FIFO parity error\n", idx);
   1599  1.1.4.2  rmind     }
   1600  1.1.4.2  rmind     if (cause & V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR)) {
   1601  1.1.4.2  rmind         mac->stats.rx_fifo_parity_err++;
   1602  1.1.4.2  rmind         CH_ALERT(adap, "port%d: MAC RX FIFO parity error\n", idx);
   1603  1.1.4.2  rmind     }
   1604  1.1.4.2  rmind     if (cause & F_TXFIFO_UNDERRUN)
   1605  1.1.4.2  rmind         mac->stats.tx_fifo_urun++;
   1606  1.1.4.2  rmind     if (cause & F_RXFIFO_OVERFLOW)
   1607  1.1.4.2  rmind         mac->stats.rx_fifo_ovfl++;
   1608  1.1.4.2  rmind     if (cause & V_SERDES_LOS(M_SERDES_LOS))
   1609  1.1.4.2  rmind         mac->stats.serdes_signal_loss++;
   1610  1.1.4.2  rmind     if (cause & F_XAUIPCSCTCERR)
   1611  1.1.4.2  rmind         mac->stats.xaui_pcs_ctc_err++;
   1612  1.1.4.2  rmind     if (cause & F_XAUIPCSALIGNCHANGE)
   1613  1.1.4.2  rmind         mac->stats.xaui_pcs_align_change++;
   1614  1.1.4.2  rmind 
   1615  1.1.4.2  rmind     t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
   1616  1.1.4.2  rmind     if (cause & XGM_INTR_FATAL)
   1617  1.1.4.2  rmind         t3_fatal_err(adap);
   1618  1.1.4.2  rmind     return cause != 0;
   1619  1.1.4.2  rmind }
   1620  1.1.4.2  rmind 
   1621  1.1.4.2  rmind /*
   1622  1.1.4.2  rmind  * Interrupt handler for PHY events.
   1623  1.1.4.2  rmind  */
   1624  1.1.4.2  rmind int t3_phy_intr_handler(adapter_t *adapter)
   1625  1.1.4.2  rmind {
   1626  1.1.4.2  rmind     u32 mask, gpi = adapter_info(adapter)->gpio_intr;
   1627  1.1.4.2  rmind     u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE);
   1628  1.1.4.2  rmind 
   1629  1.1.4.2  rmind     for_each_port(adapter, i) {
   1630  1.1.4.2  rmind         struct port_info *p = adap2pinfo(adapter, i);
   1631  1.1.4.2  rmind 
   1632  1.1.4.2  rmind         mask = gpi - (gpi & (gpi - 1));
   1633  1.1.4.2  rmind         gpi -= mask;
   1634  1.1.4.2  rmind 
   1635  1.1.4.2  rmind         if (!(p->port_type->caps & SUPPORTED_IRQ))
   1636  1.1.4.2  rmind             continue;
   1637  1.1.4.2  rmind 
   1638  1.1.4.2  rmind         if (cause & mask) {
   1639  1.1.4.2  rmind             int phy_cause = p->phy.ops->intr_handler(&p->phy);
   1640  1.1.4.2  rmind 
   1641  1.1.4.2  rmind             if (phy_cause & cphy_cause_link_change)
   1642  1.1.4.2  rmind                 t3_link_changed(adapter, i);
   1643  1.1.4.2  rmind             if (phy_cause & cphy_cause_fifo_error)
   1644  1.1.4.2  rmind                 p->phy.fifo_errors++;
   1645  1.1.4.2  rmind         }
   1646  1.1.4.2  rmind     }
   1647  1.1.4.2  rmind 
   1648  1.1.4.2  rmind     t3_write_reg(adapter, A_T3DBG_INT_CAUSE, cause);
   1649  1.1.4.2  rmind     return 0;
   1650  1.1.4.2  rmind }
   1651  1.1.4.2  rmind 
   1652  1.1.4.2  rmind /**
   1653  1.1.4.2  rmind  *  t3_slow_intr_handler - control path interrupt handler
   1654  1.1.4.2  rmind  *  @adapter: the adapter
   1655  1.1.4.2  rmind  *
   1656  1.1.4.2  rmind  *  T3 interrupt handler for non-data interrupt events, e.g., errors.
   1657  1.1.4.2  rmind  *  The designation 'slow' is because it involves register reads, while
   1658  1.1.4.2  rmind  *  data interrupts typically don't involve any MMIOs.
   1659  1.1.4.2  rmind  */
   1660  1.1.4.2  rmind int t3_slow_intr_handler(adapter_t *adapter)
   1661  1.1.4.2  rmind {
   1662  1.1.4.2  rmind     u32 cause = t3_read_reg(adapter, A_PL_INT_CAUSE0);
   1663  1.1.4.2  rmind 
   1664  1.1.4.2  rmind     cause &= adapter->slow_intr_mask;
   1665  1.1.4.2  rmind     if (!cause)
   1666  1.1.4.2  rmind         return 0;
   1667  1.1.4.2  rmind     if (cause & F_PCIM0) {
   1668  1.1.4.2  rmind         if (is_pcie(adapter))
   1669  1.1.4.2  rmind             pcie_intr_handler(adapter);
   1670  1.1.4.2  rmind         else
   1671  1.1.4.2  rmind             pci_intr_handler(adapter);
   1672  1.1.4.2  rmind     }
   1673  1.1.4.2  rmind     if (cause & F_SGE3)
   1674  1.1.4.2  rmind         t3_sge_err_intr_handler(adapter);
   1675  1.1.4.2  rmind     if (cause & F_MC7_PMRX)
   1676  1.1.4.2  rmind         mc7_intr_handler(&adapter->pmrx);
   1677  1.1.4.2  rmind     if (cause & F_MC7_PMTX)
   1678  1.1.4.2  rmind         mc7_intr_handler(&adapter->pmtx);
   1679  1.1.4.2  rmind     if (cause & F_MC7_CM)
   1680  1.1.4.2  rmind         mc7_intr_handler(&adapter->cm);
   1681  1.1.4.2  rmind     if (cause & F_CIM)
   1682  1.1.4.2  rmind         cim_intr_handler(adapter);
   1683  1.1.4.2  rmind     if (cause & F_TP1)
   1684  1.1.4.2  rmind         tp_intr_handler(adapter);
   1685  1.1.4.2  rmind     if (cause & F_ULP2_RX)
   1686  1.1.4.2  rmind         ulprx_intr_handler(adapter);
   1687  1.1.4.2  rmind     if (cause & F_ULP2_TX)
   1688  1.1.4.2  rmind         ulptx_intr_handler(adapter);
   1689  1.1.4.2  rmind     if (cause & F_PM1_RX)
   1690  1.1.4.2  rmind         pmrx_intr_handler(adapter);
   1691  1.1.4.2  rmind     if (cause & F_PM1_TX)
   1692  1.1.4.2  rmind         pmtx_intr_handler(adapter);
   1693  1.1.4.2  rmind     if (cause & F_CPL_SWITCH)
   1694  1.1.4.2  rmind         cplsw_intr_handler(adapter);
   1695  1.1.4.2  rmind     if (cause & F_MPS0)
   1696  1.1.4.2  rmind         mps_intr_handler(adapter);
   1697  1.1.4.2  rmind     if (cause & F_MC5A)
   1698  1.1.4.2  rmind         t3_mc5_intr_handler(&adapter->mc5);
   1699  1.1.4.2  rmind     if (cause & F_XGMAC0_0)
   1700  1.1.4.2  rmind         mac_intr_handler(adapter, 0);
   1701  1.1.4.2  rmind     if (cause & F_XGMAC0_1)
   1702  1.1.4.2  rmind         mac_intr_handler(adapter, 1);
   1703  1.1.4.2  rmind     if (cause & F_T3DBG)
   1704  1.1.4.2  rmind         t3_os_ext_intr_handler(adapter);
   1705  1.1.4.2  rmind 
   1706  1.1.4.2  rmind     /* Clear the interrupts just processed. */
   1707  1.1.4.2  rmind     t3_write_reg(adapter, A_PL_INT_CAUSE0, cause);
   1708  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_PL_INT_CAUSE0); /* flush */
   1709  1.1.4.2  rmind     return 1;
   1710  1.1.4.2  rmind }
   1711  1.1.4.2  rmind 
   1712  1.1.4.2  rmind /**
   1713  1.1.4.2  rmind  *  t3_intr_enable - enable interrupts
   1714  1.1.4.2  rmind  *  @adapter: the adapter whose interrupts should be enabled
   1715  1.1.4.2  rmind  *
   1716  1.1.4.2  rmind  *  Enable interrupts by setting the interrupt enable registers of the
   1717  1.1.4.2  rmind  *  various HW modules and then enabling the top-level interrupt
   1718  1.1.4.2  rmind  *  concentrator.
   1719  1.1.4.2  rmind  */
   1720  1.1.4.2  rmind void t3_intr_enable(adapter_t *adapter)
   1721  1.1.4.2  rmind {
   1722  1.1.4.2  rmind     static struct addr_val_pair intr_en_avp[] = {
   1723  1.1.4.2  rmind         { A_SG_INT_ENABLE, SGE_INTR_MASK },
   1724  1.1.4.2  rmind         { A_MC7_INT_ENABLE, MC7_INTR_MASK },
   1725  1.1.4.2  rmind         { A_MC7_INT_ENABLE - MC7_PMRX_BASE_ADDR + MC7_PMTX_BASE_ADDR,
   1726  1.1.4.2  rmind             MC7_INTR_MASK },
   1727  1.1.4.2  rmind         { A_MC7_INT_ENABLE - MC7_PMRX_BASE_ADDR + MC7_CM_BASE_ADDR,
   1728  1.1.4.2  rmind             MC7_INTR_MASK },
   1729  1.1.4.2  rmind         { A_MC5_DB_INT_ENABLE, MC5_INTR_MASK },
   1730  1.1.4.2  rmind         { A_ULPRX_INT_ENABLE, ULPRX_INTR_MASK },
   1731  1.1.4.2  rmind         { A_TP_INT_ENABLE, 0x3bfffff },
   1732  1.1.4.2  rmind         { A_PM1_TX_INT_ENABLE, PMTX_INTR_MASK },
   1733  1.1.4.2  rmind         { A_PM1_RX_INT_ENABLE, PMRX_INTR_MASK },
   1734  1.1.4.2  rmind         { A_CIM_HOST_INT_ENABLE, CIM_INTR_MASK },
   1735  1.1.4.2  rmind         { A_MPS_INT_ENABLE, MPS_INTR_MASK },
   1736  1.1.4.2  rmind     };
   1737  1.1.4.2  rmind 
   1738  1.1.4.2  rmind     adapter->slow_intr_mask = PL_INTR_MASK;
   1739  1.1.4.2  rmind 
   1740  1.1.4.2  rmind     t3_write_regs(adapter, intr_en_avp, ARRAY_SIZE(intr_en_avp), 0);
   1741  1.1.4.2  rmind 
   1742  1.1.4.2  rmind     if (adapter->params.rev > 0) {
   1743  1.1.4.2  rmind         t3_write_reg(adapter, A_CPL_INTR_ENABLE,
   1744  1.1.4.2  rmind                  CPLSW_INTR_MASK | F_CIM_OVFL_ERROR);
   1745  1.1.4.2  rmind         t3_write_reg(adapter, A_ULPTX_INT_ENABLE,
   1746  1.1.4.2  rmind                  ULPTX_INTR_MASK | F_PBL_BOUND_ERR_CH0 |
   1747  1.1.4.2  rmind                  F_PBL_BOUND_ERR_CH1);
   1748  1.1.4.2  rmind     } else {
   1749  1.1.4.2  rmind         t3_write_reg(adapter, A_CPL_INTR_ENABLE, CPLSW_INTR_MASK);
   1750  1.1.4.2  rmind         t3_write_reg(adapter, A_ULPTX_INT_ENABLE, ULPTX_INTR_MASK);
   1751  1.1.4.2  rmind     }
   1752  1.1.4.2  rmind 
   1753  1.1.4.2  rmind     t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW,
   1754  1.1.4.2  rmind              adapter_info(adapter)->gpio_intr);
   1755  1.1.4.2  rmind     t3_write_reg(adapter, A_T3DBG_INT_ENABLE,
   1756  1.1.4.2  rmind              adapter_info(adapter)->gpio_intr);
   1757  1.1.4.2  rmind     if (is_pcie(adapter))
   1758  1.1.4.2  rmind         t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK);
   1759  1.1.4.2  rmind     else
   1760  1.1.4.2  rmind         t3_write_reg(adapter, A_PCIX_INT_ENABLE, PCIX_INTR_MASK);
   1761  1.1.4.2  rmind     t3_write_reg(adapter, A_PL_INT_ENABLE0, adapter->slow_intr_mask);
   1762  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_PL_INT_ENABLE0);          /* flush */
   1763  1.1.4.2  rmind }
   1764  1.1.4.2  rmind 
   1765  1.1.4.2  rmind /**
   1766  1.1.4.2  rmind  *  t3_intr_disable - disable a card's interrupts
   1767  1.1.4.2  rmind  *  @adapter: the adapter whose interrupts should be disabled
   1768  1.1.4.2  rmind  *
   1769  1.1.4.2  rmind  *  Disable interrupts.  We only disable the top-level interrupt
   1770  1.1.4.2  rmind  *  concentrator and the SGE data interrupts.
   1771  1.1.4.2  rmind  */
   1772  1.1.4.2  rmind void t3_intr_disable(adapter_t *adapter)
   1773  1.1.4.2  rmind {
   1774  1.1.4.2  rmind     t3_write_reg(adapter, A_PL_INT_ENABLE0, 0);
   1775  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_PL_INT_ENABLE0);  /* flush */
   1776  1.1.4.2  rmind     adapter->slow_intr_mask = 0;
   1777  1.1.4.2  rmind }
   1778  1.1.4.2  rmind 
   1779  1.1.4.2  rmind /**
   1780  1.1.4.2  rmind  *  t3_intr_clear - clear all interrupts
   1781  1.1.4.2  rmind  *  @adapter: the adapter whose interrupts should be cleared
   1782  1.1.4.2  rmind  *
   1783  1.1.4.2  rmind  *  Clears all interrupts.
   1784  1.1.4.2  rmind  */
   1785  1.1.4.2  rmind void t3_intr_clear(adapter_t *adapter)
   1786  1.1.4.2  rmind {
   1787  1.1.4.2  rmind     static const unsigned int cause_reg_addr[] = {
   1788  1.1.4.2  rmind         A_SG_INT_CAUSE,
   1789  1.1.4.2  rmind         A_SG_RSPQ_FL_STATUS,
   1790  1.1.4.2  rmind         A_PCIX_INT_CAUSE,
   1791  1.1.4.2  rmind         A_MC7_INT_CAUSE,
   1792  1.1.4.2  rmind         A_MC7_INT_CAUSE - MC7_PMRX_BASE_ADDR + MC7_PMTX_BASE_ADDR,
   1793  1.1.4.2  rmind         A_MC7_INT_CAUSE - MC7_PMRX_BASE_ADDR + MC7_CM_BASE_ADDR,
   1794  1.1.4.2  rmind         A_CIM_HOST_INT_CAUSE,
   1795  1.1.4.2  rmind         A_TP_INT_CAUSE,
   1796  1.1.4.2  rmind         A_MC5_DB_INT_CAUSE,
   1797  1.1.4.2  rmind         A_ULPRX_INT_CAUSE,
   1798  1.1.4.2  rmind         A_ULPTX_INT_CAUSE,
   1799  1.1.4.2  rmind         A_CPL_INTR_CAUSE,
   1800  1.1.4.2  rmind         A_PM1_TX_INT_CAUSE,
   1801  1.1.4.2  rmind         A_PM1_RX_INT_CAUSE,
   1802  1.1.4.2  rmind         A_MPS_INT_CAUSE,
   1803  1.1.4.2  rmind         A_T3DBG_INT_CAUSE,
   1804  1.1.4.2  rmind     };
   1805  1.1.4.2  rmind     unsigned int i;
   1806  1.1.4.2  rmind 
   1807  1.1.4.2  rmind     /* Clear PHY and MAC interrupts for each port. */
   1808  1.1.4.2  rmind     for_each_port(adapter, i)
   1809  1.1.4.2  rmind         t3_port_intr_clear(adapter, i);
   1810  1.1.4.2  rmind 
   1811  1.1.4.2  rmind     for (i = 0; i < ARRAY_SIZE(cause_reg_addr); ++i)
   1812  1.1.4.2  rmind         t3_write_reg(adapter, cause_reg_addr[i], 0xffffffff);
   1813  1.1.4.2  rmind 
   1814  1.1.4.2  rmind     if (is_pcie(adapter))
   1815  1.1.4.2  rmind         t3_write_reg(adapter, A_PCIE_PEX_ERR, 0xffffffff);
   1816  1.1.4.2  rmind     t3_write_reg(adapter, A_PL_INT_CAUSE0, 0xffffffff);
   1817  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_PL_INT_CAUSE0);          /* flush */
   1818  1.1.4.2  rmind }
   1819  1.1.4.2  rmind 
   1820  1.1.4.2  rmind /**
   1821  1.1.4.2  rmind  *  t3_port_intr_enable - enable port-specific interrupts
   1822  1.1.4.2  rmind  *  @adapter: associated adapter
   1823  1.1.4.2  rmind  *  @idx: index of port whose interrupts should be enabled
   1824  1.1.4.2  rmind  *
   1825  1.1.4.2  rmind  *  Enable port-specific (i.e., MAC and PHY) interrupts for the given
   1826  1.1.4.2  rmind  *  adapter port.
   1827  1.1.4.2  rmind  */
   1828  1.1.4.2  rmind void t3_port_intr_enable(adapter_t *adapter, int idx)
   1829  1.1.4.2  rmind {
   1830  1.1.4.2  rmind     struct port_info *pi = adap2pinfo(adapter, idx);
   1831  1.1.4.2  rmind 
   1832  1.1.4.2  rmind     t3_write_reg(adapter, A_XGM_INT_ENABLE + pi->mac.offset, XGM_INTR_MASK);
   1833  1.1.4.2  rmind     pi->phy.ops->intr_enable(&pi->phy);
   1834  1.1.4.2  rmind }
   1835  1.1.4.2  rmind 
   1836  1.1.4.2  rmind /**
   1837  1.1.4.2  rmind  *  t3_port_intr_disable - disable port-specific interrupts
   1838  1.1.4.2  rmind  *  @adapter: associated adapter
   1839  1.1.4.2  rmind  *  @idx: index of port whose interrupts should be disabled
   1840  1.1.4.2  rmind  *
   1841  1.1.4.2  rmind  *  Disable port-specific (i.e., MAC and PHY) interrupts for the given
   1842  1.1.4.2  rmind  *  adapter port.
   1843  1.1.4.2  rmind  */
   1844  1.1.4.2  rmind void t3_port_intr_disable(adapter_t *adapter, int idx)
   1845  1.1.4.2  rmind {
   1846  1.1.4.2  rmind     struct port_info *pi = adap2pinfo(adapter, idx);
   1847  1.1.4.2  rmind 
   1848  1.1.4.2  rmind     t3_write_reg(adapter, A_XGM_INT_ENABLE + pi->mac.offset, 0);
   1849  1.1.4.2  rmind     pi->phy.ops->intr_disable(&pi->phy);
   1850  1.1.4.2  rmind }
   1851  1.1.4.2  rmind 
   1852  1.1.4.2  rmind /**
   1853  1.1.4.2  rmind  *  t3_port_intr_clear - clear port-specific interrupts
   1854  1.1.4.2  rmind  *  @adapter: associated adapter
   1855  1.1.4.2  rmind  *  @idx: index of port whose interrupts to clear
   1856  1.1.4.2  rmind  *
   1857  1.1.4.2  rmind  *  Clear port-specific (i.e., MAC and PHY) interrupts for the given
   1858  1.1.4.2  rmind  *  adapter port.
   1859  1.1.4.2  rmind  */
   1860  1.1.4.2  rmind void t3_port_intr_clear(adapter_t *adapter, int idx)
   1861  1.1.4.2  rmind {
   1862  1.1.4.2  rmind     struct port_info *pi = adap2pinfo(adapter, idx);
   1863  1.1.4.2  rmind 
   1864  1.1.4.2  rmind     t3_write_reg(adapter, A_XGM_INT_CAUSE + pi->mac.offset, 0xffffffff);
   1865  1.1.4.2  rmind     pi->phy.ops->intr_clear(&pi->phy);
   1866  1.1.4.2  rmind }
   1867  1.1.4.2  rmind 
   1868  1.1.4.2  rmind #define SG_CONTEXT_CMD_ATTEMPTS 100
   1869  1.1.4.2  rmind 
   1870  1.1.4.2  rmind /**
   1871  1.1.4.2  rmind  *  t3_sge_write_context - write an SGE context
   1872  1.1.4.2  rmind  *  @adapter: the adapter
   1873  1.1.4.2  rmind  *  @id: the context id
   1874  1.1.4.2  rmind  *  @type: the context type
   1875  1.1.4.2  rmind  *
   1876  1.1.4.2  rmind  *  Program an SGE context with the values already loaded in the
   1877  1.1.4.2  rmind  *  CONTEXT_DATA? registers.
   1878  1.1.4.2  rmind  */
   1879  1.1.4.2  rmind static int t3_sge_write_context(adapter_t *adapter, unsigned int id,
   1880  1.1.4.2  rmind                 unsigned int type)
   1881  1.1.4.2  rmind {
   1882  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
   1883  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
   1884  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0xffffffff);
   1885  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
   1886  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_CMD,
   1887  1.1.4.2  rmind              V_CONTEXT_CMD_OPCODE(1) | type | V_CONTEXT(id));
   1888  1.1.4.2  rmind     return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
   1889  1.1.4.2  rmind                    0, SG_CONTEXT_CMD_ATTEMPTS, 1);
   1890  1.1.4.2  rmind }
   1891  1.1.4.2  rmind 
   1892  1.1.4.2  rmind /**
   1893  1.1.4.2  rmind  *  t3_sge_init_ecntxt - initialize an SGE egress context
   1894  1.1.4.2  rmind  *  @adapter: the adapter to configure
   1895  1.1.4.2  rmind  *  @id: the context id
   1896  1.1.4.2  rmind  *  @gts_enable: whether to enable GTS for the context
   1897  1.1.4.2  rmind  *  @type: the egress context type
   1898  1.1.4.2  rmind  *  @respq: associated response queue
   1899  1.1.4.2  rmind  *  @base_addr: base address of queue
   1900  1.1.4.2  rmind  *  @size: number of queue entries
   1901  1.1.4.2  rmind  *  @token: uP token
   1902  1.1.4.2  rmind  *  @gen: initial generation value for the context
   1903  1.1.4.2  rmind  *  @cidx: consumer pointer
   1904  1.1.4.2  rmind  *
   1905  1.1.4.2  rmind  *  Initialize an SGE egress context and make it ready for use.  If the
   1906  1.1.4.2  rmind  *  platform allows concurrent context operations, the caller is
   1907  1.1.4.2  rmind  *  responsible for appropriate locking.
   1908  1.1.4.2  rmind  */
   1909  1.1.4.2  rmind int t3_sge_init_ecntxt(adapter_t *adapter, unsigned int id, int gts_enable,
   1910  1.1.4.2  rmind                enum sge_context_type type, int respq, u64 base_addr,
   1911  1.1.4.2  rmind                unsigned int size, unsigned int token, int gen,
   1912  1.1.4.2  rmind                unsigned int cidx)
   1913  1.1.4.2  rmind {
   1914  1.1.4.2  rmind     unsigned int credits = type == SGE_CNTXT_OFLD ? 0 : FW_WR_NUM;
   1915  1.1.4.2  rmind 
   1916  1.1.4.2  rmind     if (base_addr & 0xfff)     /* must be 4K aligned */
   1917  1.1.4.2  rmind         return -EINVAL;
   1918  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   1919  1.1.4.2  rmind         return -EBUSY;
   1920  1.1.4.2  rmind 
   1921  1.1.4.2  rmind     base_addr >>= 12;
   1922  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_EC_INDEX(cidx) |
   1923  1.1.4.2  rmind              V_EC_CREDITS(credits) | V_EC_GTS(gts_enable));
   1924  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA1, V_EC_SIZE(size) |
   1925  1.1.4.2  rmind              V_EC_BASE_LO((u32)base_addr & 0xffff));
   1926  1.1.4.2  rmind     base_addr >>= 16;
   1927  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA2, (u32)base_addr);
   1928  1.1.4.2  rmind     base_addr >>= 32;
   1929  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA3,
   1930  1.1.4.2  rmind              V_EC_BASE_HI((u32)base_addr & 0xf) | V_EC_RESPQ(respq) |
   1931  1.1.4.2  rmind              V_EC_TYPE(type) | V_EC_GEN(gen) | V_EC_UP_TOKEN(token) |
   1932  1.1.4.2  rmind              F_EC_VALID);
   1933  1.1.4.2  rmind     return t3_sge_write_context(adapter, id, F_EGRESS);
   1934  1.1.4.2  rmind }
   1935  1.1.4.2  rmind 
   1936  1.1.4.2  rmind /**
   1937  1.1.4.2  rmind  *  t3_sge_init_flcntxt - initialize an SGE free-buffer list context
   1938  1.1.4.2  rmind  *  @adapter: the adapter to configure
   1939  1.1.4.2  rmind  *  @id: the context id
   1940  1.1.4.2  rmind  *  @gts_enable: whether to enable GTS for the context
   1941  1.1.4.2  rmind  *  @base_addr: base address of queue
   1942  1.1.4.2  rmind  *  @size: number of queue entries
   1943  1.1.4.2  rmind  *  @bsize: size of each buffer for this queue
   1944  1.1.4.2  rmind  *  @cong_thres: threshold to signal congestion to upstream producers
   1945  1.1.4.2  rmind  *  @gen: initial generation value for the context
   1946  1.1.4.2  rmind  *  @cidx: consumer pointer
   1947  1.1.4.2  rmind  *
   1948  1.1.4.2  rmind  *  Initialize an SGE free list context and make it ready for use.  The
   1949  1.1.4.2  rmind  *  caller is responsible for ensuring only one context operation occurs
   1950  1.1.4.2  rmind  *  at a time.
   1951  1.1.4.2  rmind  */
   1952  1.1.4.2  rmind int t3_sge_init_flcntxt(adapter_t *adapter, unsigned int id, int gts_enable,
   1953  1.1.4.2  rmind             u64 base_addr, unsigned int size, unsigned int bsize,
   1954  1.1.4.2  rmind             unsigned int cong_thres, int gen, unsigned int cidx)
   1955  1.1.4.2  rmind {
   1956  1.1.4.2  rmind     if (base_addr & 0xfff)     /* must be 4K aligned */
   1957  1.1.4.2  rmind         return -EINVAL;
   1958  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   1959  1.1.4.2  rmind         return -EBUSY;
   1960  1.1.4.2  rmind 
   1961  1.1.4.2  rmind     base_addr >>= 12;
   1962  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA0, (u32)base_addr);
   1963  1.1.4.2  rmind     base_addr >>= 32;
   1964  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA1,
   1965  1.1.4.2  rmind              V_FL_BASE_HI((u32)base_addr) |
   1966  1.1.4.2  rmind              V_FL_INDEX_LO(cidx & M_FL_INDEX_LO));
   1967  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA2, V_FL_SIZE(size) |
   1968  1.1.4.2  rmind              V_FL_GEN(gen) | V_FL_INDEX_HI(cidx >> 12) |
   1969  1.1.4.2  rmind              V_FL_ENTRY_SIZE_LO(bsize & M_FL_ENTRY_SIZE_LO));
   1970  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA3,
   1971  1.1.4.2  rmind              V_FL_ENTRY_SIZE_HI(bsize >> (32 - S_FL_ENTRY_SIZE_LO)) |
   1972  1.1.4.2  rmind              V_FL_CONG_THRES(cong_thres) | V_FL_GTS(gts_enable));
   1973  1.1.4.2  rmind     return t3_sge_write_context(adapter, id, F_FREELIST);
   1974  1.1.4.2  rmind }
   1975  1.1.4.2  rmind 
   1976  1.1.4.2  rmind /**
   1977  1.1.4.2  rmind  *  t3_sge_init_rspcntxt - initialize an SGE response queue context
   1978  1.1.4.2  rmind  *  @adapter: the adapter to configure
   1979  1.1.4.2  rmind  *  @id: the context id
   1980  1.1.4.2  rmind  *  @irq_vec_idx: MSI-X interrupt vector index, 0 if no MSI-X, -1 if no IRQ
   1981  1.1.4.2  rmind  *  @base_addr: base address of queue
   1982  1.1.4.2  rmind  *  @size: number of queue entries
   1983  1.1.4.2  rmind  *  @fl_thres: threshold for selecting the normal or jumbo free list
   1984  1.1.4.2  rmind  *  @gen: initial generation value for the context
   1985  1.1.4.2  rmind  *  @cidx: consumer pointer
   1986  1.1.4.2  rmind  *
   1987  1.1.4.2  rmind  *  Initialize an SGE response queue context and make it ready for use.
   1988  1.1.4.2  rmind  *  The caller is responsible for ensuring only one context operation
   1989  1.1.4.2  rmind  *  occurs at a time.
   1990  1.1.4.2  rmind  */
   1991  1.1.4.2  rmind int t3_sge_init_rspcntxt(adapter_t *adapter, unsigned int id, int irq_vec_idx,
   1992  1.1.4.2  rmind              u64 base_addr, unsigned int size,
   1993  1.1.4.2  rmind              unsigned int fl_thres, int gen, unsigned int cidx)
   1994  1.1.4.2  rmind {
   1995  1.1.4.2  rmind     unsigned int intr = 0;
   1996  1.1.4.2  rmind 
   1997  1.1.4.2  rmind     if (base_addr & 0xfff)     /* must be 4K aligned */
   1998  1.1.4.2  rmind         return -EINVAL;
   1999  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2000  1.1.4.2  rmind         return -EBUSY;
   2001  1.1.4.2  rmind 
   2002  1.1.4.2  rmind     base_addr >>= 12;
   2003  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_CQ_SIZE(size) |
   2004  1.1.4.2  rmind              V_CQ_INDEX(cidx));
   2005  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA1, (u32)base_addr);
   2006  1.1.4.2  rmind     base_addr >>= 32;
   2007  1.1.4.2  rmind     if (irq_vec_idx >= 0)
   2008  1.1.4.2  rmind         intr = V_RQ_MSI_VEC(irq_vec_idx) | F_RQ_INTR_EN;
   2009  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA2,
   2010  1.1.4.2  rmind              V_CQ_BASE_HI((u32)base_addr) | intr | V_RQ_GEN(gen));
   2011  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA3, fl_thres);
   2012  1.1.4.2  rmind     return t3_sge_write_context(adapter, id, F_RESPONSEQ);
   2013  1.1.4.2  rmind }
   2014  1.1.4.2  rmind 
   2015  1.1.4.2  rmind /**
   2016  1.1.4.2  rmind  *  t3_sge_init_cqcntxt - initialize an SGE completion queue context
   2017  1.1.4.2  rmind  *  @adapter: the adapter to configure
   2018  1.1.4.2  rmind  *  @id: the context id
   2019  1.1.4.2  rmind  *  @base_addr: base address of queue
   2020  1.1.4.2  rmind  *  @size: number of queue entries
   2021  1.1.4.2  rmind  *  @rspq: response queue for async notifications
   2022  1.1.4.2  rmind  *  @ovfl_mode: CQ overflow mode
   2023  1.1.4.2  rmind  *  @credits: completion queue credits
   2024  1.1.4.2  rmind  *  @credit_thres: the credit threshold
   2025  1.1.4.2  rmind  *
   2026  1.1.4.2  rmind  *  Initialize an SGE completion queue context and make it ready for use.
   2027  1.1.4.2  rmind  *  The caller is responsible for ensuring only one context operation
   2028  1.1.4.2  rmind  *  occurs at a time.
   2029  1.1.4.2  rmind  */
   2030  1.1.4.2  rmind int t3_sge_init_cqcntxt(adapter_t *adapter, unsigned int id, u64 base_addr,
   2031  1.1.4.2  rmind             unsigned int size, int rspq, int ovfl_mode,
   2032  1.1.4.2  rmind             unsigned int credits, unsigned int credit_thres)
   2033  1.1.4.2  rmind {
   2034  1.1.4.2  rmind     if (base_addr & 0xfff)     /* must be 4K aligned */
   2035  1.1.4.2  rmind         return -EINVAL;
   2036  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2037  1.1.4.2  rmind         return -EBUSY;
   2038  1.1.4.2  rmind 
   2039  1.1.4.2  rmind     base_addr >>= 12;
   2040  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_CQ_SIZE(size));
   2041  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA1, (u32)base_addr);
   2042  1.1.4.2  rmind     base_addr >>= 32;
   2043  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA2,
   2044  1.1.4.2  rmind              V_CQ_BASE_HI((u32)base_addr) | V_CQ_RSPQ(rspq) |
   2045  1.1.4.2  rmind              V_CQ_GEN(1) | V_CQ_OVERFLOW_MODE(ovfl_mode) |
   2046  1.1.4.2  rmind              V_CQ_ERR(ovfl_mode));
   2047  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA3, V_CQ_CREDITS(credits) |
   2048  1.1.4.2  rmind              V_CQ_CREDIT_THRES(credit_thres));
   2049  1.1.4.2  rmind     return t3_sge_write_context(adapter, id, F_CQ);
   2050  1.1.4.2  rmind }
   2051  1.1.4.2  rmind 
   2052  1.1.4.2  rmind /**
   2053  1.1.4.2  rmind  *  t3_sge_enable_ecntxt - enable/disable an SGE egress context
   2054  1.1.4.2  rmind  *  @adapter: the adapter
   2055  1.1.4.2  rmind  *  @id: the egress context id
   2056  1.1.4.2  rmind  *  @enable: enable (1) or disable (0) the context
   2057  1.1.4.2  rmind  *
   2058  1.1.4.2  rmind  *  Enable or disable an SGE egress context.  The caller is responsible for
   2059  1.1.4.2  rmind  *  ensuring only one context operation occurs at a time.
   2060  1.1.4.2  rmind  */
   2061  1.1.4.2  rmind int t3_sge_enable_ecntxt(adapter_t *adapter, unsigned int id, int enable)
   2062  1.1.4.2  rmind {
   2063  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2064  1.1.4.2  rmind         return -EBUSY;
   2065  1.1.4.2  rmind 
   2066  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0);
   2067  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
   2068  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0);
   2069  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK3, F_EC_VALID);
   2070  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA3, V_EC_VALID(enable));
   2071  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_CMD,
   2072  1.1.4.2  rmind              V_CONTEXT_CMD_OPCODE(1) | F_EGRESS | V_CONTEXT(id));
   2073  1.1.4.2  rmind     return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
   2074  1.1.4.2  rmind                    0, SG_CONTEXT_CMD_ATTEMPTS, 1);
   2075  1.1.4.2  rmind }
   2076  1.1.4.2  rmind 
   2077  1.1.4.2  rmind /**
   2078  1.1.4.2  rmind  *  t3_sge_disable_fl - disable an SGE free-buffer list
   2079  1.1.4.2  rmind  *  @adapter: the adapter
   2080  1.1.4.2  rmind  *  @id: the free list context id
   2081  1.1.4.2  rmind  *
   2082  1.1.4.2  rmind  *  Disable an SGE free-buffer list.  The caller is responsible for
   2083  1.1.4.2  rmind  *  ensuring only one context operation occurs at a time.
   2084  1.1.4.2  rmind  */
   2085  1.1.4.2  rmind int t3_sge_disable_fl(adapter_t *adapter, unsigned int id)
   2086  1.1.4.2  rmind {
   2087  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2088  1.1.4.2  rmind         return -EBUSY;
   2089  1.1.4.2  rmind 
   2090  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0);
   2091  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
   2092  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK2, V_FL_SIZE(M_FL_SIZE));
   2093  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0);
   2094  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA2, 0);
   2095  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_CMD,
   2096  1.1.4.2  rmind              V_CONTEXT_CMD_OPCODE(1) | F_FREELIST | V_CONTEXT(id));
   2097  1.1.4.2  rmind     return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
   2098  1.1.4.2  rmind                    0, SG_CONTEXT_CMD_ATTEMPTS, 1);
   2099  1.1.4.2  rmind }
   2100  1.1.4.2  rmind 
   2101  1.1.4.2  rmind /**
   2102  1.1.4.2  rmind  *  t3_sge_disable_rspcntxt - disable an SGE response queue
   2103  1.1.4.2  rmind  *  @adapter: the adapter
   2104  1.1.4.2  rmind  *  @id: the response queue context id
   2105  1.1.4.2  rmind  *
   2106  1.1.4.2  rmind  *  Disable an SGE response queue.  The caller is responsible for
   2107  1.1.4.2  rmind  *  ensuring only one context operation occurs at a time.
   2108  1.1.4.2  rmind  */
   2109  1.1.4.2  rmind int t3_sge_disable_rspcntxt(adapter_t *adapter, unsigned int id)
   2110  1.1.4.2  rmind {
   2111  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2112  1.1.4.2  rmind         return -EBUSY;
   2113  1.1.4.2  rmind 
   2114  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK0, V_CQ_SIZE(M_CQ_SIZE));
   2115  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
   2116  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0);
   2117  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0);
   2118  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA0, 0);
   2119  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_CMD,
   2120  1.1.4.2  rmind              V_CONTEXT_CMD_OPCODE(1) | F_RESPONSEQ | V_CONTEXT(id));
   2121  1.1.4.2  rmind     return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
   2122  1.1.4.2  rmind                    0, SG_CONTEXT_CMD_ATTEMPTS, 1);
   2123  1.1.4.2  rmind }
   2124  1.1.4.2  rmind 
   2125  1.1.4.2  rmind /**
   2126  1.1.4.2  rmind  *  t3_sge_disable_cqcntxt - disable an SGE completion queue
   2127  1.1.4.2  rmind  *  @adapter: the adapter
   2128  1.1.4.2  rmind  *  @id: the completion queue context id
   2129  1.1.4.2  rmind  *
   2130  1.1.4.2  rmind  *  Disable an SGE completion queue.  The caller is responsible for
   2131  1.1.4.2  rmind  *  ensuring only one context operation occurs at a time.
   2132  1.1.4.2  rmind  */
   2133  1.1.4.2  rmind int t3_sge_disable_cqcntxt(adapter_t *adapter, unsigned int id)
   2134  1.1.4.2  rmind {
   2135  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2136  1.1.4.2  rmind         return -EBUSY;
   2137  1.1.4.2  rmind 
   2138  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK0, V_CQ_SIZE(M_CQ_SIZE));
   2139  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
   2140  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0);
   2141  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0);
   2142  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA0, 0);
   2143  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_CMD,
   2144  1.1.4.2  rmind              V_CONTEXT_CMD_OPCODE(1) | F_CQ | V_CONTEXT(id));
   2145  1.1.4.2  rmind     return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
   2146  1.1.4.2  rmind                    0, SG_CONTEXT_CMD_ATTEMPTS, 1);
   2147  1.1.4.2  rmind }
   2148  1.1.4.2  rmind 
   2149  1.1.4.2  rmind /**
   2150  1.1.4.2  rmind  *  t3_sge_cqcntxt_op - perform an operation on a completion queue context
   2151  1.1.4.2  rmind  *  @adapter: the adapter
   2152  1.1.4.2  rmind  *  @id: the context id
   2153  1.1.4.2  rmind  *  @op: the operation to perform
   2154  1.1.4.2  rmind  *  @credits: credits to return to the CQ
   2155  1.1.4.2  rmind  *
   2156  1.1.4.2  rmind  *  Perform the selected operation on an SGE completion queue context.
   2157  1.1.4.2  rmind  *  The caller is responsible for ensuring only one context operation
   2158  1.1.4.2  rmind  *  occurs at a time.
   2159  1.1.4.2  rmind  *
   2160  1.1.4.2  rmind  *  For most operations the function returns the current HW position in
   2161  1.1.4.2  rmind  *  the completion queue.
   2162  1.1.4.2  rmind  */
   2163  1.1.4.2  rmind int t3_sge_cqcntxt_op(adapter_t *adapter, unsigned int id, unsigned int op,
   2164  1.1.4.2  rmind               unsigned int credits)
   2165  1.1.4.2  rmind {
   2166  1.1.4.2  rmind     u32 val;
   2167  1.1.4.2  rmind 
   2168  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2169  1.1.4.2  rmind         return -EBUSY;
   2170  1.1.4.2  rmind 
   2171  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_DATA0, credits << 16);
   2172  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_CMD, V_CONTEXT_CMD_OPCODE(op) |
   2173  1.1.4.2  rmind              V_CONTEXT(id) | F_CQ);
   2174  1.1.4.2  rmind     if (t3_wait_op_done_val(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
   2175  1.1.4.2  rmind                 0, SG_CONTEXT_CMD_ATTEMPTS, 1, &val))
   2176  1.1.4.2  rmind         return -EIO;
   2177  1.1.4.2  rmind 
   2178  1.1.4.2  rmind     if (op >= 2 && op < 7) {
   2179  1.1.4.2  rmind         if (adapter->params.rev > 0)
   2180  1.1.4.2  rmind             return G_CQ_INDEX(val);
   2181  1.1.4.2  rmind 
   2182  1.1.4.2  rmind         t3_write_reg(adapter, A_SG_CONTEXT_CMD,
   2183  1.1.4.2  rmind                  V_CONTEXT_CMD_OPCODE(0) | F_CQ | V_CONTEXT(id));
   2184  1.1.4.2  rmind         if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD,
   2185  1.1.4.2  rmind                     F_CONTEXT_CMD_BUSY, 0,
   2186  1.1.4.2  rmind                     SG_CONTEXT_CMD_ATTEMPTS, 1))
   2187  1.1.4.2  rmind             return -EIO;
   2188  1.1.4.2  rmind         return G_CQ_INDEX(t3_read_reg(adapter, A_SG_CONTEXT_DATA0));
   2189  1.1.4.2  rmind     }
   2190  1.1.4.2  rmind     return 0;
   2191  1.1.4.2  rmind }
   2192  1.1.4.2  rmind 
   2193  1.1.4.2  rmind /**
   2194  1.1.4.2  rmind  *  t3_sge_read_context - read an SGE context
   2195  1.1.4.2  rmind  *  @type: the context type
   2196  1.1.4.2  rmind  *  @adapter: the adapter
   2197  1.1.4.2  rmind  *  @id: the context id
   2198  1.1.4.2  rmind  *  @data: holds the retrieved context
   2199  1.1.4.2  rmind  *
   2200  1.1.4.2  rmind  *  Read an SGE egress context.  The caller is responsible for ensuring
   2201  1.1.4.2  rmind  *  only one context operation occurs at a time.
   2202  1.1.4.2  rmind  */
   2203  1.1.4.2  rmind static int t3_sge_read_context(unsigned int type, adapter_t *adapter,
   2204  1.1.4.2  rmind                    unsigned int id, u32 data[4])
   2205  1.1.4.2  rmind {
   2206  1.1.4.2  rmind     if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
   2207  1.1.4.2  rmind         return -EBUSY;
   2208  1.1.4.2  rmind 
   2209  1.1.4.2  rmind     t3_write_reg(adapter, A_SG_CONTEXT_CMD,
   2210  1.1.4.2  rmind              V_CONTEXT_CMD_OPCODE(0) | type | V_CONTEXT(id));
   2211  1.1.4.2  rmind     if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, 0,
   2212  1.1.4.2  rmind                 SG_CONTEXT_CMD_ATTEMPTS, 1))
   2213  1.1.4.2  rmind         return -EIO;
   2214  1.1.4.2  rmind     data[0] = t3_read_reg(adapter, A_SG_CONTEXT_DATA0);
   2215  1.1.4.2  rmind     data[1] = t3_read_reg(adapter, A_SG_CONTEXT_DATA1);
   2216  1.1.4.2  rmind     data[2] = t3_read_reg(adapter, A_SG_CONTEXT_DATA2);
   2217  1.1.4.2  rmind     data[3] = t3_read_reg(adapter, A_SG_CONTEXT_DATA3);
   2218  1.1.4.2  rmind     return 0;
   2219  1.1.4.2  rmind }
   2220  1.1.4.2  rmind 
   2221  1.1.4.2  rmind /**
   2222  1.1.4.2  rmind  *  t3_sge_read_ecntxt - read an SGE egress context
   2223  1.1.4.2  rmind  *  @adapter: the adapter
   2224  1.1.4.2  rmind  *  @id: the context id
   2225  1.1.4.2  rmind  *  @data: holds the retrieved context
   2226  1.1.4.2  rmind  *
   2227  1.1.4.2  rmind  *  Read an SGE egress context.  The caller is responsible for ensuring
   2228  1.1.4.2  rmind  *  only one context operation occurs at a time.
   2229  1.1.4.2  rmind  */
   2230  1.1.4.2  rmind int t3_sge_read_ecntxt(adapter_t *adapter, unsigned int id, u32 data[4])
   2231  1.1.4.2  rmind {
   2232  1.1.4.2  rmind     if (id >= 65536)
   2233  1.1.4.2  rmind         return -EINVAL;
   2234  1.1.4.2  rmind     return t3_sge_read_context(F_EGRESS, adapter, id, data);
   2235  1.1.4.2  rmind }
   2236  1.1.4.2  rmind 
   2237  1.1.4.2  rmind /**
   2238  1.1.4.2  rmind  *  t3_sge_read_cq - read an SGE CQ context
   2239  1.1.4.2  rmind  *  @adapter: the adapter
   2240  1.1.4.2  rmind  *  @id: the context id
   2241  1.1.4.2  rmind  *  @data: holds the retrieved context
   2242  1.1.4.2  rmind  *
   2243  1.1.4.2  rmind  *  Read an SGE CQ context.  The caller is responsible for ensuring
   2244  1.1.4.2  rmind  *  only one context operation occurs at a time.
   2245  1.1.4.2  rmind  */
   2246  1.1.4.2  rmind int t3_sge_read_cq(adapter_t *adapter, unsigned int id, u32 data[4])
   2247  1.1.4.2  rmind {
   2248  1.1.4.2  rmind     if (id >= 65536)
   2249  1.1.4.2  rmind         return -EINVAL;
   2250  1.1.4.2  rmind     return t3_sge_read_context(F_CQ, adapter, id, data);
   2251  1.1.4.2  rmind }
   2252  1.1.4.2  rmind 
   2253  1.1.4.2  rmind /**
   2254  1.1.4.2  rmind  *  t3_sge_read_fl - read an SGE free-list context
   2255  1.1.4.2  rmind  *  @adapter: the adapter
   2256  1.1.4.2  rmind  *  @id: the context id
   2257  1.1.4.2  rmind  *  @data: holds the retrieved context
   2258  1.1.4.2  rmind  *
   2259  1.1.4.2  rmind  *  Read an SGE free-list context.  The caller is responsible for ensuring
   2260  1.1.4.2  rmind  *  only one context operation occurs at a time.
   2261  1.1.4.2  rmind  */
   2262  1.1.4.2  rmind int t3_sge_read_fl(adapter_t *adapter, unsigned int id, u32 data[4])
   2263  1.1.4.2  rmind {
   2264  1.1.4.2  rmind     if (id >= SGE_QSETS * 2)
   2265  1.1.4.2  rmind         return -EINVAL;
   2266  1.1.4.2  rmind     return t3_sge_read_context(F_FREELIST, adapter, id, data);
   2267  1.1.4.2  rmind }
   2268  1.1.4.2  rmind 
   2269  1.1.4.2  rmind /**
   2270  1.1.4.2  rmind  *  t3_sge_read_rspq - read an SGE response queue context
   2271  1.1.4.2  rmind  *  @adapter: the adapter
   2272  1.1.4.2  rmind  *  @id: the context id
   2273  1.1.4.2  rmind  *  @data: holds the retrieved context
   2274  1.1.4.2  rmind  *
   2275  1.1.4.2  rmind  *  Read an SGE response queue context.  The caller is responsible for
   2276  1.1.4.2  rmind  *  ensuring only one context operation occurs at a time.
   2277  1.1.4.2  rmind  */
   2278  1.1.4.2  rmind int t3_sge_read_rspq(adapter_t *adapter, unsigned int id, u32 data[4])
   2279  1.1.4.2  rmind {
   2280  1.1.4.2  rmind     if (id >= SGE_QSETS)
   2281  1.1.4.2  rmind         return -EINVAL;
   2282  1.1.4.2  rmind     return t3_sge_read_context(F_RESPONSEQ, adapter, id, data);
   2283  1.1.4.2  rmind }
   2284  1.1.4.2  rmind 
   2285  1.1.4.2  rmind /**
   2286  1.1.4.2  rmind  *  t3_config_rss - configure Rx packet steering
   2287  1.1.4.2  rmind  *  @adapter: the adapter
   2288  1.1.4.2  rmind  *  @rss_config: RSS settings (written to TP_RSS_CONFIG)
   2289  1.1.4.2  rmind  *  @cpus: values for the CPU lookup table (0xff terminated)
   2290  1.1.4.2  rmind  *  @rspq: values for the response queue lookup table (0xffff terminated)
   2291  1.1.4.2  rmind  *
   2292  1.1.4.2  rmind  *  Programs the receive packet steering logic.  @cpus and @rspq provide
   2293  1.1.4.2  rmind  *  the values for the CPU and response queue lookup tables.  If they
   2294  1.1.4.2  rmind  *  provide fewer values than the size of the tables the supplied values
   2295  1.1.4.2  rmind  *  are used repeatedly until the tables are fully populated.
   2296  1.1.4.2  rmind  */
   2297  1.1.4.2  rmind void t3_config_rss(adapter_t *adapter, unsigned int rss_config, const u8 *cpus,
   2298  1.1.4.2  rmind            const u16 *rspq)
   2299  1.1.4.2  rmind {
   2300  1.1.4.2  rmind     int i, j, cpu_idx = 0, q_idx = 0;
   2301  1.1.4.2  rmind 
   2302  1.1.4.2  rmind     if (cpus)
   2303  1.1.4.2  rmind         for (i = 0; i < RSS_TABLE_SIZE; ++i) {
   2304  1.1.4.2  rmind             u32 val = i << 16;
   2305  1.1.4.2  rmind 
   2306  1.1.4.2  rmind             for (j = 0; j < 2; ++j) {
   2307  1.1.4.2  rmind                 val |= (cpus[cpu_idx++] & 0x3f) << (8 * j);
   2308  1.1.4.2  rmind                 if (cpus[cpu_idx] == 0xff)
   2309  1.1.4.2  rmind                     cpu_idx = 0;
   2310  1.1.4.2  rmind             }
   2311  1.1.4.2  rmind             t3_write_reg(adapter, A_TP_RSS_LKP_TABLE, val);
   2312  1.1.4.2  rmind         }
   2313  1.1.4.2  rmind 
   2314  1.1.4.2  rmind     if (rspq)
   2315  1.1.4.2  rmind         for (i = 0; i < RSS_TABLE_SIZE; ++i) {
   2316  1.1.4.2  rmind             t3_write_reg(adapter, A_TP_RSS_MAP_TABLE,
   2317  1.1.4.2  rmind                      (i << 16) | rspq[q_idx++]);
   2318  1.1.4.2  rmind             if (rspq[q_idx] == 0xffff)
   2319  1.1.4.2  rmind                 q_idx = 0;
   2320  1.1.4.2  rmind         }
   2321  1.1.4.2  rmind 
   2322  1.1.4.2  rmind     t3_write_reg(adapter, A_TP_RSS_CONFIG, rss_config);
   2323  1.1.4.2  rmind }
   2324  1.1.4.2  rmind 
   2325  1.1.4.2  rmind /**
   2326  1.1.4.2  rmind  *  t3_read_rss - read the contents of the RSS tables
   2327  1.1.4.2  rmind  *  @adapter: the adapter
   2328  1.1.4.2  rmind  *  @lkup: holds the contents of the RSS lookup table
   2329  1.1.4.2  rmind  *  @map: holds the contents of the RSS map table
   2330  1.1.4.2  rmind  *
   2331  1.1.4.2  rmind  *  Reads the contents of the receive packet steering tables.
   2332  1.1.4.2  rmind  */
   2333  1.1.4.2  rmind int t3_read_rss(adapter_t *adapter, u8 *lkup, u16 *map)
   2334  1.1.4.2  rmind {
   2335  1.1.4.2  rmind     int i;
   2336  1.1.4.2  rmind     u32 val;
   2337  1.1.4.2  rmind 
   2338  1.1.4.2  rmind     if (lkup)
   2339  1.1.4.2  rmind         for (i = 0; i < RSS_TABLE_SIZE; ++i) {
   2340  1.1.4.2  rmind             t3_write_reg(adapter, A_TP_RSS_LKP_TABLE,
   2341  1.1.4.2  rmind                      0xffff0000 | i);
   2342  1.1.4.2  rmind             val = t3_read_reg(adapter, A_TP_RSS_LKP_TABLE);
   2343  1.1.4.2  rmind             if (!(val & 0x80000000))
   2344  1.1.4.2  rmind                 return -EAGAIN;
   2345  1.1.4.2  rmind             *lkup++ = (u8)val;
   2346  1.1.4.2  rmind             *lkup++ = (u8)(val >> 8);
   2347  1.1.4.2  rmind         }
   2348  1.1.4.2  rmind 
   2349  1.1.4.2  rmind     if (map)
   2350  1.1.4.2  rmind         for (i = 0; i < RSS_TABLE_SIZE; ++i) {
   2351  1.1.4.2  rmind             t3_write_reg(adapter, A_TP_RSS_MAP_TABLE,
   2352  1.1.4.2  rmind                      0xffff0000 | i);
   2353  1.1.4.2  rmind             val = t3_read_reg(adapter, A_TP_RSS_MAP_TABLE);
   2354  1.1.4.2  rmind             if (!(val & 0x80000000))
   2355  1.1.4.2  rmind                 return -EAGAIN;
   2356  1.1.4.2  rmind             *map++ = (u16)val;
   2357  1.1.4.2  rmind         }
   2358  1.1.4.2  rmind     return 0;
   2359  1.1.4.2  rmind }
   2360  1.1.4.2  rmind 
   2361  1.1.4.2  rmind /**
   2362  1.1.4.2  rmind  *  t3_tp_set_offload_mode - put TP in NIC/offload mode
   2363  1.1.4.2  rmind  *  @adap: the adapter
   2364  1.1.4.2  rmind  *  @enable: 1 to select offload mode, 0 for regular NIC
   2365  1.1.4.2  rmind  *
   2366  1.1.4.2  rmind  *  Switches TP to NIC/offload mode.
   2367  1.1.4.2  rmind  */
   2368  1.1.4.2  rmind void t3_tp_set_offload_mode(adapter_t *adap, int enable)
   2369  1.1.4.2  rmind {
   2370  1.1.4.2  rmind     if (is_offload(adap) || !enable)
   2371  1.1.4.2  rmind         t3_set_reg_field(adap, A_TP_IN_CONFIG, F_NICMODE,
   2372  1.1.4.2  rmind                  V_NICMODE(!enable));
   2373  1.1.4.2  rmind }
   2374  1.1.4.2  rmind 
   2375  1.1.4.2  rmind /**
   2376  1.1.4.2  rmind  *  tp_wr_bits_indirect - set/clear bits in an indirect TP register
   2377  1.1.4.2  rmind  *  @adap: the adapter
   2378  1.1.4.2  rmind  *  @addr: the indirect TP register address
   2379  1.1.4.2  rmind  *  @mask: specifies the field within the register to modify
   2380  1.1.4.2  rmind  *  @val: new value for the field
   2381  1.1.4.2  rmind  *
   2382  1.1.4.2  rmind  *  Sets a field of an indirect TP register to the given value.
   2383  1.1.4.2  rmind  */
   2384  1.1.4.2  rmind static void tp_wr_bits_indirect(adapter_t *adap, unsigned int addr,
   2385  1.1.4.2  rmind                 unsigned int mask, unsigned int val)
   2386  1.1.4.2  rmind {
   2387  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PIO_ADDR, addr);
   2388  1.1.4.2  rmind     val |= t3_read_reg(adap, A_TP_PIO_DATA) & ~mask;
   2389  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PIO_DATA, val);
   2390  1.1.4.2  rmind }
   2391  1.1.4.2  rmind 
   2392  1.1.4.2  rmind /**
   2393  1.1.4.2  rmind  *  t3_enable_filters - enable the HW filters
   2394  1.1.4.2  rmind  *  @adap: the adapter
   2395  1.1.4.2  rmind  *
   2396  1.1.4.2  rmind  *  Enables the HW filters for NIC traffic.
   2397  1.1.4.2  rmind  */
   2398  1.1.4.2  rmind void t3_enable_filters(adapter_t *adap)
   2399  1.1.4.2  rmind {
   2400  1.1.4.2  rmind     t3_set_reg_field(adap, A_TP_IN_CONFIG, F_NICMODE, 0);
   2401  1.1.4.2  rmind     t3_set_reg_field(adap, A_MC5_DB_CONFIG, 0, F_FILTEREN);
   2402  1.1.4.2  rmind     t3_set_reg_field(adap, A_TP_GLOBAL_CONFIG, 0, V_FIVETUPLELOOKUP(3));
   2403  1.1.4.2  rmind     tp_wr_bits_indirect(adap, A_TP_INGRESS_CONFIG, 0, F_LOOKUPEVERYPKT);
   2404  1.1.4.2  rmind }
   2405  1.1.4.2  rmind 
   2406  1.1.4.2  rmind /**
   2407  1.1.4.2  rmind  *  pm_num_pages - calculate the number of pages of the payload memory
   2408  1.1.4.2  rmind  *  @mem_size: the size of the payload memory
   2409  1.1.4.2  rmind  *  @pg_size: the size of each payload memory page
   2410  1.1.4.2  rmind  *
   2411  1.1.4.2  rmind  *  Calculate the number of pages, each of the given size, that fit in a
   2412  1.1.4.2  rmind  *  memory of the specified size, respecting the HW requirement that the
   2413  1.1.4.2  rmind  *  number of pages must be a multiple of 24.
   2414  1.1.4.2  rmind  */
   2415  1.1.4.2  rmind static inline unsigned int pm_num_pages(unsigned int mem_size,
   2416  1.1.4.2  rmind                     unsigned int pg_size)
   2417  1.1.4.2  rmind {
   2418  1.1.4.2  rmind     unsigned int n = mem_size / pg_size;
   2419  1.1.4.2  rmind 
   2420  1.1.4.2  rmind     return n - n % 24;
   2421  1.1.4.2  rmind }
   2422  1.1.4.2  rmind 
   2423  1.1.4.2  rmind #define mem_region(adap, start, size, reg) \
   2424  1.1.4.2  rmind     t3_write_reg((adap), A_ ## reg, (start)); \
   2425  1.1.4.2  rmind     start += size
   2426  1.1.4.2  rmind 
   2427  1.1.4.2  rmind /*
   2428  1.1.4.2  rmind  * fls: find last bit set.
   2429  1.1.4.2  rmind  */
   2430  1.1.4.2  rmind static __inline int fls(int x)
   2431  1.1.4.2  rmind {
   2432  1.1.4.2  rmind     int r = 32;
   2433  1.1.4.2  rmind 
   2434  1.1.4.2  rmind     if (!x)
   2435  1.1.4.2  rmind         return 0;
   2436  1.1.4.2  rmind     if (!(x & 0xffff0000u)) {
   2437  1.1.4.2  rmind         x <<= 16;
   2438  1.1.4.2  rmind         r -= 16;
   2439  1.1.4.2  rmind     }
   2440  1.1.4.2  rmind     if (!(x & 0xff000000u)) {
   2441  1.1.4.2  rmind         x <<= 8;
   2442  1.1.4.2  rmind         r -= 8;
   2443  1.1.4.2  rmind     }
   2444  1.1.4.2  rmind     if (!(x & 0xf0000000u)) {
   2445  1.1.4.2  rmind         x <<= 4;
   2446  1.1.4.2  rmind         r -= 4;
   2447  1.1.4.2  rmind     }
   2448  1.1.4.2  rmind     if (!(x & 0xc0000000u)) {
   2449  1.1.4.2  rmind         x <<= 2;
   2450  1.1.4.2  rmind         r -= 2;
   2451  1.1.4.2  rmind     }
   2452  1.1.4.2  rmind     if (!(x & 0x80000000u)) {
   2453  1.1.4.2  rmind         x <<= 1;
   2454  1.1.4.2  rmind         r -= 1;
   2455  1.1.4.2  rmind     }
   2456  1.1.4.2  rmind     return r;
   2457  1.1.4.2  rmind }
   2458  1.1.4.2  rmind 
   2459  1.1.4.2  rmind /**
   2460  1.1.4.2  rmind  *  partition_mem - partition memory and configure TP memory settings
   2461  1.1.4.2  rmind  *  @adap: the adapter
   2462  1.1.4.2  rmind  *  @p: the TP parameters
   2463  1.1.4.2  rmind  *
   2464  1.1.4.2  rmind  *  Partitions context and payload memory and configures TP's memory
   2465  1.1.4.2  rmind  *  registers.
   2466  1.1.4.2  rmind  */
   2467  1.1.4.2  rmind static void partition_mem(adapter_t *adap, const struct tp_params *p)
   2468  1.1.4.2  rmind {
   2469  1.1.4.2  rmind     unsigned int m, pstructs, tids = t3_mc5_size(&adap->mc5);
   2470  1.1.4.2  rmind     unsigned int timers = 0, timers_shift = 22;
   2471  1.1.4.2  rmind 
   2472  1.1.4.2  rmind     if (adap->params.rev > 0) {
   2473  1.1.4.2  rmind         if (tids <= 16 * 1024) {
   2474  1.1.4.2  rmind             timers = 1;
   2475  1.1.4.2  rmind             timers_shift = 16;
   2476  1.1.4.2  rmind         } else if (tids <= 64 * 1024) {
   2477  1.1.4.2  rmind             timers = 2;
   2478  1.1.4.2  rmind             timers_shift = 18;
   2479  1.1.4.2  rmind         } else if (tids <= 256 * 1024) {
   2480  1.1.4.2  rmind             timers = 3;
   2481  1.1.4.2  rmind             timers_shift = 20;
   2482  1.1.4.2  rmind         }
   2483  1.1.4.2  rmind     }
   2484  1.1.4.2  rmind 
   2485  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PMM_SIZE,
   2486  1.1.4.2  rmind              p->chan_rx_size | (p->chan_tx_size >> 16));
   2487  1.1.4.2  rmind 
   2488  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PMM_TX_BASE, 0);
   2489  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PMM_TX_PAGE_SIZE, p->tx_pg_size);
   2490  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PMM_TX_MAX_PAGE, p->tx_num_pgs);
   2491  1.1.4.2  rmind     t3_set_reg_field(adap, A_TP_PARA_REG3, V_TXDATAACKIDX(M_TXDATAACKIDX),
   2492  1.1.4.2  rmind              V_TXDATAACKIDX(fls(p->tx_pg_size) - 12));
   2493  1.1.4.2  rmind 
   2494  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PMM_RX_BASE, 0);
   2495  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PMM_RX_PAGE_SIZE, p->rx_pg_size);
   2496  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PMM_RX_MAX_PAGE, p->rx_num_pgs);
   2497  1.1.4.2  rmind 
   2498  1.1.4.2  rmind     pstructs = p->rx_num_pgs + p->tx_num_pgs;
   2499  1.1.4.2  rmind     /* Add a bit of headroom and make multiple of 24 */
   2500  1.1.4.2  rmind     pstructs += 48;
   2501  1.1.4.2  rmind     pstructs -= pstructs % 24;
   2502  1.1.4.2  rmind     t3_write_reg(adap, A_TP_CMM_MM_MAX_PSTRUCT, pstructs);
   2503  1.1.4.2  rmind 
   2504  1.1.4.2  rmind     m = tids * TCB_SIZE;
   2505  1.1.4.2  rmind     mem_region(adap, m, (64 << 10) * 64, SG_EGR_CNTX_BADDR);
   2506  1.1.4.2  rmind     mem_region(adap, m, (64 << 10) * 64, SG_CQ_CONTEXT_BADDR);
   2507  1.1.4.2  rmind     t3_write_reg(adap, A_TP_CMM_TIMER_BASE, V_CMTIMERMAXNUM(timers) | m);
   2508  1.1.4.2  rmind     m += ((p->ntimer_qs - 1) << timers_shift) + (1 << 22);
   2509  1.1.4.2  rmind     mem_region(adap, m, pstructs * 64, TP_CMM_MM_BASE);
   2510  1.1.4.2  rmind     mem_region(adap, m, 64 * (pstructs / 24), TP_CMM_MM_PS_FLST_BASE);
   2511  1.1.4.2  rmind     mem_region(adap, m, 64 * (p->rx_num_pgs / 24), TP_CMM_MM_RX_FLST_BASE);
   2512  1.1.4.2  rmind     mem_region(adap, m, 64 * (p->tx_num_pgs / 24), TP_CMM_MM_TX_FLST_BASE);
   2513  1.1.4.2  rmind 
   2514  1.1.4.2  rmind     m = (m + 4095) & ~0xfff;
   2515  1.1.4.2  rmind     t3_write_reg(adap, A_CIM_SDRAM_BASE_ADDR, m);
   2516  1.1.4.2  rmind     t3_write_reg(adap, A_CIM_SDRAM_ADDR_SIZE, p->cm_size - m);
   2517  1.1.4.2  rmind 
   2518  1.1.4.2  rmind     tids = (p->cm_size - m - (3 << 20)) / 3072 - 32;
   2519  1.1.4.2  rmind     m = t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers -
   2520  1.1.4.2  rmind         adap->params.mc5.nfilters - adap->params.mc5.nroutes;
   2521  1.1.4.2  rmind     if (tids < m)
   2522  1.1.4.2  rmind         adap->params.mc5.nservers += m - tids;
   2523  1.1.4.2  rmind }
   2524  1.1.4.2  rmind 
   2525  1.1.4.2  rmind static inline void tp_wr_indirect(adapter_t *adap, unsigned int addr, u32 val)
   2526  1.1.4.2  rmind {
   2527  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PIO_ADDR, addr);
   2528  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PIO_DATA, val);
   2529  1.1.4.2  rmind }
   2530  1.1.4.2  rmind 
   2531  1.1.4.2  rmind static void tp_config(adapter_t *adap, const struct tp_params *p)
   2532  1.1.4.2  rmind {
   2533  1.1.4.2  rmind     t3_write_reg(adap, A_TP_GLOBAL_CONFIG, F_TXPACINGENABLE | F_PATHMTU |
   2534  1.1.4.2  rmind              F_IPCHECKSUMOFFLOAD | F_UDPCHECKSUMOFFLOAD |
   2535  1.1.4.2  rmind              F_TCPCHECKSUMOFFLOAD | V_IPTTL(64));
   2536  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) |
   2537  1.1.4.2  rmind              F_MTUENABLE | V_WINDOWSCALEMODE(1) |
   2538  1.1.4.2  rmind              V_TIMESTAMPSMODE(0) | V_SACKMODE(1) | V_SACKRX(1));
   2539  1.1.4.2  rmind     t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) |
   2540  1.1.4.2  rmind              V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
   2541  1.1.4.2  rmind              V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
   2542  1.1.4.2  rmind              F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1));
   2543  1.1.4.2  rmind     t3_set_reg_field(adap, A_TP_IN_CONFIG, F_IPV6ENABLE | F_NICMODE,
   2544  1.1.4.2  rmind              F_IPV6ENABLE | F_NICMODE);
   2545  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
   2546  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
   2547  1.1.4.2  rmind     t3_set_reg_field(adap, A_TP_PARA_REG6, 0,
   2548  1.1.4.2  rmind              adap->params.rev > 0 ? F_ENABLEESND :
   2549  1.1.4.2  rmind                         F_T3A_ENABLEESND);
   2550  1.1.4.2  rmind     t3_set_reg_field(adap, A_TP_PC_CONFIG,
   2551  1.1.4.2  rmind              F_ENABLEEPCMDAFULL,
   2552  1.1.4.2  rmind              F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
   2553  1.1.4.2  rmind              F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
   2554  1.1.4.2  rmind     t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
   2555  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
   2556  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
   2557  1.1.4.2  rmind 
   2558  1.1.4.2  rmind     if (adap->params.rev > 0) {
   2559  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
   2560  1.1.4.2  rmind         t3_set_reg_field(adap, A_TP_PARA_REG3, 0,
   2561  1.1.4.2  rmind                  F_TXPACEAUTO | F_TXPACEAUTOSTRICT);
   2562  1.1.4.2  rmind         t3_set_reg_field(adap, A_TP_PC_CONFIG, F_LOCKTID, F_LOCKTID);
   2563  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_VLAN_PRI_MAP, 0xfa50);
   2564  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_MAC_MATCH_MAP0, 0xfac688);
   2565  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_MAC_MATCH_MAP1, 0xfac688);
   2566  1.1.4.2  rmind     } else
   2567  1.1.4.2  rmind         t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
   2568  1.1.4.2  rmind 
   2569  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0);
   2570  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0);
   2571  1.1.4.2  rmind     t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0);
   2572  1.1.4.2  rmind     t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0xf2200000);
   2573  1.1.4.2  rmind 
   2574  1.1.4.2  rmind     if (adap->params.nports > 2) {
   2575  1.1.4.2  rmind         t3_set_reg_field(adap, A_TP_PC_CONFIG2, 0,
   2576  1.1.4.2  rmind                  F_ENABLETXPORTFROMDA | F_ENABLERXPORTFROMADDR);
   2577  1.1.4.2  rmind         tp_wr_bits_indirect(adap, A_TP_QOS_RX_MAP_MODE,
   2578  1.1.4.2  rmind                     V_RXMAPMODE(M_RXMAPMODE), 0);
   2579  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_INGRESS_CONFIG, V_BITPOS0(48) |
   2580  1.1.4.2  rmind                    V_BITPOS1(49) | V_BITPOS2(50) | V_BITPOS3(51) |
   2581  1.1.4.2  rmind                    F_ENABLEEXTRACT | F_ENABLEEXTRACTIONSFD |
   2582  1.1.4.2  rmind                    F_ENABLEINSERTION | F_ENABLEINSERTIONSFD);
   2583  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_PREAMBLE_MSB, 0xfb000000);
   2584  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_PREAMBLE_LSB, 0xd5);
   2585  1.1.4.2  rmind         tp_wr_indirect(adap, A_TP_INTF_FROM_TX_PKT, F_INTFFROMTXPKT);
   2586  1.1.4.2  rmind     }
   2587  1.1.4.2  rmind }
   2588  1.1.4.2  rmind 
   2589  1.1.4.2  rmind /* TCP timer values in ms */
   2590  1.1.4.2  rmind #define TP_DACK_TIMER 50
   2591  1.1.4.2  rmind #define TP_RTO_MIN    250
   2592  1.1.4.2  rmind 
   2593  1.1.4.2  rmind /**
   2594  1.1.4.2  rmind  *  tp_set_timers - set TP timing parameters
   2595  1.1.4.2  rmind  *  @adap: the adapter to set
   2596  1.1.4.2  rmind  *  @core_clk: the core clock frequency in Hz
   2597  1.1.4.2  rmind  *
   2598  1.1.4.2  rmind  *  Set TP's timing parameters, such as the various timer resolutions and
   2599  1.1.4.2  rmind  *  the TCP timer values.
   2600  1.1.4.2  rmind  */
   2601  1.1.4.2  rmind static void tp_set_timers(adapter_t *adap, unsigned int core_clk)
   2602  1.1.4.2  rmind {
   2603  1.1.4.2  rmind     unsigned int tre = adap->params.tp.tre;
   2604  1.1.4.2  rmind     unsigned int dack_re = adap->params.tp.dack_re;
   2605  1.1.4.2  rmind     unsigned int tstamp_re = fls(core_clk / 1000);     /* 1ms, at least */
   2606  1.1.4.2  rmind     unsigned int tps = core_clk >> tre;
   2607  1.1.4.2  rmind 
   2608  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TIMER_RESOLUTION, V_TIMERRESOLUTION(tre) |
   2609  1.1.4.2  rmind              V_DELAYEDACKRESOLUTION(dack_re) |
   2610  1.1.4.2  rmind              V_TIMESTAMPRESOLUTION(tstamp_re));
   2611  1.1.4.2  rmind     t3_write_reg(adap, A_TP_DACK_TIMER,
   2612  1.1.4.2  rmind              (core_clk >> dack_re) / (1000 / TP_DACK_TIMER));
   2613  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TCP_BACKOFF_REG0, 0x3020100);
   2614  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TCP_BACKOFF_REG1, 0x7060504);
   2615  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TCP_BACKOFF_REG2, 0xb0a0908);
   2616  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TCP_BACKOFF_REG3, 0xf0e0d0c);
   2617  1.1.4.2  rmind     t3_write_reg(adap, A_TP_SHIFT_CNT, V_SYNSHIFTMAX(6) |
   2618  1.1.4.2  rmind              V_RXTSHIFTMAXR1(4) | V_RXTSHIFTMAXR2(15) |
   2619  1.1.4.2  rmind              V_PERSHIFTBACKOFFMAX(8) | V_PERSHIFTMAX(8) |
   2620  1.1.4.2  rmind              V_KEEPALIVEMAX(9));
   2621  1.1.4.2  rmind 
   2622  1.1.4.2  rmind #define SECONDS * tps
   2623  1.1.4.2  rmind 
   2624  1.1.4.2  rmind     t3_write_reg(adap, A_TP_MSL,
   2625  1.1.4.2  rmind              adap->params.rev > 0 ? 0 : 2 SECONDS);
   2626  1.1.4.2  rmind     t3_write_reg(adap, A_TP_RXT_MIN, tps / (1000 / TP_RTO_MIN));
   2627  1.1.4.2  rmind     t3_write_reg(adap, A_TP_RXT_MAX, 64 SECONDS);
   2628  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PERS_MIN, 5 SECONDS);
   2629  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PERS_MAX, 64 SECONDS);
   2630  1.1.4.2  rmind     t3_write_reg(adap, A_TP_KEEP_IDLE, 7200 SECONDS);
   2631  1.1.4.2  rmind     t3_write_reg(adap, A_TP_KEEP_INTVL, 75 SECONDS);
   2632  1.1.4.2  rmind     t3_write_reg(adap, A_TP_INIT_SRTT, 3 SECONDS);
   2633  1.1.4.2  rmind     t3_write_reg(adap, A_TP_FINWAIT2_TIMER, 600 SECONDS);
   2634  1.1.4.2  rmind 
   2635  1.1.4.2  rmind #undef SECONDS
   2636  1.1.4.2  rmind }
   2637  1.1.4.2  rmind 
   2638  1.1.4.2  rmind #ifdef CONFIG_CHELSIO_T3_CORE
   2639  1.1.4.2  rmind /**
   2640  1.1.4.2  rmind  *  t3_tp_set_coalescing_size - set receive coalescing size
   2641  1.1.4.2  rmind  *  @adap: the adapter
   2642  1.1.4.2  rmind  *  @size: the receive coalescing size
   2643  1.1.4.2  rmind  *  @psh: whether a set PSH bit should deliver coalesced data
   2644  1.1.4.2  rmind  *
   2645  1.1.4.2  rmind  *  Set the receive coalescing size and PSH bit handling.
   2646  1.1.4.2  rmind  */
   2647  1.1.4.2  rmind int t3_tp_set_coalescing_size(adapter_t *adap, unsigned int size, int psh)
   2648  1.1.4.2  rmind {
   2649  1.1.4.2  rmind     u32 val;
   2650  1.1.4.2  rmind 
   2651  1.1.4.2  rmind     if (size > MAX_RX_COALESCING_LEN)
   2652  1.1.4.2  rmind         return -EINVAL;
   2653  1.1.4.2  rmind 
   2654  1.1.4.2  rmind     val = t3_read_reg(adap, A_TP_PARA_REG3);
   2655  1.1.4.2  rmind     val &= ~(F_RXCOALESCEENABLE | F_RXCOALESCEPSHEN);
   2656  1.1.4.2  rmind 
   2657  1.1.4.2  rmind     if (size) {
   2658  1.1.4.2  rmind         val |= F_RXCOALESCEENABLE;
   2659  1.1.4.2  rmind         if (psh)
   2660  1.1.4.2  rmind             val |= F_RXCOALESCEPSHEN;
   2661  1.1.4.2  rmind         size = min(MAX_RX_COALESCING_LEN, size);
   2662  1.1.4.2  rmind         t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) |
   2663  1.1.4.2  rmind                  V_MAXRXDATA(MAX_RX_COALESCING_LEN));
   2664  1.1.4.2  rmind     }
   2665  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PARA_REG3, val);
   2666  1.1.4.2  rmind     return 0;
   2667  1.1.4.2  rmind }
   2668  1.1.4.2  rmind 
   2669  1.1.4.2  rmind /**
   2670  1.1.4.2  rmind  *  t3_tp_set_max_rxsize - set the max receive size
   2671  1.1.4.2  rmind  *  @adap: the adapter
   2672  1.1.4.2  rmind  *  @size: the max receive size
   2673  1.1.4.2  rmind  *
   2674  1.1.4.2  rmind  *  Set TP's max receive size.  This is the limit that applies when
   2675  1.1.4.2  rmind  *  receive coalescing is disabled.
   2676  1.1.4.2  rmind  */
   2677  1.1.4.2  rmind void t3_tp_set_max_rxsize(adapter_t *adap, unsigned int size)
   2678  1.1.4.2  rmind {
   2679  1.1.4.2  rmind     t3_write_reg(adap, A_TP_PARA_REG7,
   2680  1.1.4.2  rmind              V_PMMAXXFERLEN0(size) | V_PMMAXXFERLEN1(size));
   2681  1.1.4.2  rmind }
   2682  1.1.4.2  rmind 
   2683  1.1.4.2  rmind static void __devinit init_mtus(unsigned short mtus[])
   2684  1.1.4.2  rmind {
   2685  1.1.4.2  rmind     /*
   2686  1.1.4.2  rmind      * See draft-mathis-plpmtud-00.txt for the values.  The min is 88 so
   2687  1.1.4.2  rmind      * it can accomodate max size TCP/IP headers when SACK and timestamps
   2688  1.1.4.2  rmind      * are enabled and still have at least 8 bytes of payload.
   2689  1.1.4.2  rmind      */
   2690  1.1.4.2  rmind     mtus[0] = 88;
   2691  1.1.4.2  rmind     mtus[1] = 88;
   2692  1.1.4.2  rmind     mtus[2] = 256;
   2693  1.1.4.2  rmind     mtus[3] = 512;
   2694  1.1.4.2  rmind     mtus[4] = 576;
   2695  1.1.4.2  rmind     mtus[5] = 1024;
   2696  1.1.4.2  rmind     mtus[6] = 1280;
   2697  1.1.4.2  rmind     mtus[7] = 1492;
   2698  1.1.4.2  rmind     mtus[8] = 1500;
   2699  1.1.4.2  rmind     mtus[9] = 2002;
   2700  1.1.4.2  rmind     mtus[10] = 2048;
   2701  1.1.4.2  rmind     mtus[11] = 4096;
   2702  1.1.4.2  rmind     mtus[12] = 4352;
   2703  1.1.4.2  rmind     mtus[13] = 8192;
   2704  1.1.4.2  rmind     mtus[14] = 9000;
   2705  1.1.4.2  rmind     mtus[15] = 9600;
   2706  1.1.4.2  rmind }
   2707  1.1.4.2  rmind 
   2708  1.1.4.2  rmind /**
   2709  1.1.4.2  rmind  *  init_cong_ctrl - initialize congestion control parameters
   2710  1.1.4.2  rmind  *  @a: the alpha values for congestion control
   2711  1.1.4.2  rmind  *  @b: the beta values for congestion control
   2712  1.1.4.2  rmind  *
   2713  1.1.4.2  rmind  *  Initialize the congestion control parameters.
   2714  1.1.4.2  rmind  */
   2715  1.1.4.2  rmind static void __devinit init_cong_ctrl(unsigned short *a, unsigned short *b)
   2716  1.1.4.2  rmind {
   2717  1.1.4.2  rmind     a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1;
   2718  1.1.4.2  rmind     a[9] = 2;
   2719  1.1.4.2  rmind     a[10] = 3;
   2720  1.1.4.2  rmind     a[11] = 4;
   2721  1.1.4.2  rmind     a[12] = 5;
   2722  1.1.4.2  rmind     a[13] = 6;
   2723  1.1.4.2  rmind     a[14] = 7;
   2724  1.1.4.2  rmind     a[15] = 8;
   2725  1.1.4.2  rmind     a[16] = 9;
   2726  1.1.4.2  rmind     a[17] = 10;
   2727  1.1.4.2  rmind     a[18] = 14;
   2728  1.1.4.2  rmind     a[19] = 17;
   2729  1.1.4.2  rmind     a[20] = 21;
   2730  1.1.4.2  rmind     a[21] = 25;
   2731  1.1.4.2  rmind     a[22] = 30;
   2732  1.1.4.2  rmind     a[23] = 35;
   2733  1.1.4.2  rmind     a[24] = 45;
   2734  1.1.4.2  rmind     a[25] = 60;
   2735  1.1.4.2  rmind     a[26] = 80;
   2736  1.1.4.2  rmind     a[27] = 100;
   2737  1.1.4.2  rmind     a[28] = 200;
   2738  1.1.4.2  rmind     a[29] = 300;
   2739  1.1.4.2  rmind     a[30] = 400;
   2740  1.1.4.2  rmind     a[31] = 500;
   2741  1.1.4.2  rmind 
   2742  1.1.4.2  rmind     b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0;
   2743  1.1.4.2  rmind     b[9] = b[10] = 1;
   2744  1.1.4.2  rmind     b[11] = b[12] = 2;
   2745  1.1.4.2  rmind     b[13] = b[14] = b[15] = b[16] = 3;
   2746  1.1.4.2  rmind     b[17] = b[18] = b[19] = b[20] = b[21] = 4;
   2747  1.1.4.2  rmind     b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5;
   2748  1.1.4.2  rmind     b[28] = b[29] = 6;
   2749  1.1.4.2  rmind     b[30] = b[31] = 7;
   2750  1.1.4.2  rmind }
   2751  1.1.4.2  rmind 
   2752  1.1.4.2  rmind /* The minimum additive increment value for the congestion control table */
   2753  1.1.4.2  rmind #define CC_MIN_INCR 2U
   2754  1.1.4.2  rmind 
   2755  1.1.4.2  rmind /**
   2756  1.1.4.2  rmind  *  t3_load_mtus - write the MTU and congestion control HW tables
   2757  1.1.4.2  rmind  *  @adap: the adapter
   2758  1.1.4.2  rmind  *  @mtus: the unrestricted values for the MTU table
   2759  1.1.4.2  rmind  *  @alpha: the values for the congestion control alpha parameter
   2760  1.1.4.2  rmind  *  @beta: the values for the congestion control beta parameter
   2761  1.1.4.2  rmind  *  @mtu_cap: the maximum permitted effective MTU
   2762  1.1.4.2  rmind  *
   2763  1.1.4.2  rmind  *  Write the MTU table with the supplied MTUs capping each at &mtu_cap.
   2764  1.1.4.2  rmind  *  Update the high-speed congestion control table with the supplied alpha,
   2765  1.1.4.2  rmind  *  beta, and MTUs.
   2766  1.1.4.2  rmind  */
   2767  1.1.4.2  rmind void t3_load_mtus(adapter_t *adap, unsigned short mtus[NMTUS],
   2768  1.1.4.2  rmind           unsigned short alpha[NCCTRL_WIN],
   2769  1.1.4.2  rmind           unsigned short beta[NCCTRL_WIN], unsigned short mtu_cap)
   2770  1.1.4.2  rmind {
   2771  1.1.4.2  rmind     static const unsigned int avg_pkts[NCCTRL_WIN] = {
   2772  1.1.4.2  rmind         2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640,
   2773  1.1.4.2  rmind         896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480,
   2774  1.1.4.2  rmind         28672, 40960, 57344, 81920, 114688, 163840, 229376 };
   2775  1.1.4.2  rmind 
   2776  1.1.4.2  rmind     unsigned int i, w;
   2777  1.1.4.2  rmind 
   2778  1.1.4.2  rmind     for (i = 0; i < NMTUS; ++i) {
   2779  1.1.4.2  rmind         unsigned int mtu = min(mtus[i], mtu_cap);
   2780  1.1.4.2  rmind         unsigned int log2 = fls(mtu);
   2781  1.1.4.2  rmind 
   2782  1.1.4.2  rmind         if (!(mtu & ((1 << log2) >> 2)))     /* round */
   2783  1.1.4.2  rmind             log2--;
   2784  1.1.4.2  rmind         t3_write_reg(adap, A_TP_MTU_TABLE,
   2785  1.1.4.2  rmind                  (i << 24) | (log2 << 16) | mtu);
   2786  1.1.4.2  rmind 
   2787  1.1.4.2  rmind         for (w = 0; w < NCCTRL_WIN; ++w) {
   2788  1.1.4.2  rmind             unsigned int inc;
   2789  1.1.4.2  rmind 
   2790  1.1.4.2  rmind             inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w],
   2791  1.1.4.2  rmind                   CC_MIN_INCR);
   2792  1.1.4.2  rmind 
   2793  1.1.4.2  rmind             t3_write_reg(adap, A_TP_CCTRL_TABLE, (i << 21) |
   2794  1.1.4.2  rmind                      (w << 16) | (beta[w] << 13) | inc);
   2795  1.1.4.2  rmind         }
   2796  1.1.4.2  rmind     }
   2797  1.1.4.2  rmind }
   2798  1.1.4.2  rmind 
   2799  1.1.4.2  rmind /**
   2800  1.1.4.2  rmind  *  t3_read_hw_mtus - returns the values in the HW MTU table
   2801  1.1.4.2  rmind  *  @adap: the adapter
   2802  1.1.4.2  rmind  *  @mtus: where to store the HW MTU values
   2803  1.1.4.2  rmind  *
   2804  1.1.4.2  rmind  *  Reads the HW MTU table.
   2805  1.1.4.2  rmind  */
   2806  1.1.4.2  rmind void t3_read_hw_mtus(adapter_t *adap, unsigned short mtus[NMTUS])
   2807  1.1.4.2  rmind {
   2808  1.1.4.2  rmind     int i;
   2809  1.1.4.2  rmind 
   2810  1.1.4.2  rmind     for (i = 0; i < NMTUS; ++i) {
   2811  1.1.4.2  rmind         unsigned int val;
   2812  1.1.4.2  rmind 
   2813  1.1.4.2  rmind         t3_write_reg(adap, A_TP_MTU_TABLE, 0xff000000 | i);
   2814  1.1.4.2  rmind         val = t3_read_reg(adap, A_TP_MTU_TABLE);
   2815  1.1.4.2  rmind         mtus[i] = val & 0x3fff;
   2816  1.1.4.2  rmind     }
   2817  1.1.4.2  rmind }
   2818  1.1.4.2  rmind 
   2819  1.1.4.2  rmind /**
   2820  1.1.4.2  rmind  *  t3_get_cong_cntl_tab - reads the congestion control table
   2821  1.1.4.2  rmind  *  @adap: the adapter
   2822  1.1.4.2  rmind  *  @incr: where to store the alpha values
   2823  1.1.4.2  rmind  *
   2824  1.1.4.2  rmind  *  Reads the additive increments programmed into the HW congestion
   2825  1.1.4.2  rmind  *  control table.
   2826  1.1.4.2  rmind  */
   2827  1.1.4.2  rmind void t3_get_cong_cntl_tab(adapter_t *adap,
   2828  1.1.4.2  rmind               unsigned short incr[NMTUS][NCCTRL_WIN])
   2829  1.1.4.2  rmind {
   2830  1.1.4.2  rmind     unsigned int mtu, w;
   2831  1.1.4.2  rmind 
   2832  1.1.4.2  rmind     for (mtu = 0; mtu < NMTUS; ++mtu)
   2833  1.1.4.2  rmind         for (w = 0; w < NCCTRL_WIN; ++w) {
   2834  1.1.4.2  rmind             t3_write_reg(adap, A_TP_CCTRL_TABLE,
   2835  1.1.4.2  rmind                      0xffff0000 | (mtu << 5) | w);
   2836  1.1.4.2  rmind             incr[mtu][w] = (unsigned short)t3_read_reg(adap,
   2837  1.1.4.2  rmind                         A_TP_CCTRL_TABLE) & 0x1fff;
   2838  1.1.4.2  rmind         }
   2839  1.1.4.2  rmind }
   2840  1.1.4.2  rmind 
   2841  1.1.4.2  rmind /**
   2842  1.1.4.2  rmind  *  t3_tp_get_mib_stats - read TP's MIB counters
   2843  1.1.4.2  rmind  *  @adap: the adapter
   2844  1.1.4.2  rmind  *  @tps: holds the returned counter values
   2845  1.1.4.2  rmind  *
   2846  1.1.4.2  rmind  *  Returns the values of TP's MIB counters.
   2847  1.1.4.2  rmind  */
   2848  1.1.4.2  rmind void t3_tp_get_mib_stats(adapter_t *adap, struct tp_mib_stats *tps)
   2849  1.1.4.2  rmind {
   2850  1.1.4.2  rmind     t3_read_indirect(adap, A_TP_MIB_INDEX, A_TP_MIB_RDATA, (u32 *)tps,
   2851  1.1.4.2  rmind              sizeof(*tps) / sizeof(u32), 0);
   2852  1.1.4.2  rmind }
   2853  1.1.4.2  rmind 
   2854  1.1.4.2  rmind /**
   2855  1.1.4.2  rmind  *  t3_read_pace_tbl - read the pace table
   2856  1.1.4.2  rmind  *  @adap: the adapter
   2857  1.1.4.2  rmind  *  @pace_vals: holds the returned values
   2858  1.1.4.2  rmind  *
   2859  1.1.4.2  rmind  *  Returns the values of TP's pace table in nanoseconds.
   2860  1.1.4.2  rmind  */
   2861  1.1.4.2  rmind void t3_read_pace_tbl(adapter_t *adap, unsigned int pace_vals[NTX_SCHED])
   2862  1.1.4.2  rmind {
   2863  1.1.4.2  rmind     unsigned int i, tick_ns = dack_ticks_to_usec(adap, 1000);
   2864  1.1.4.2  rmind 
   2865  1.1.4.2  rmind     for (i = 0; i < NTX_SCHED; i++) {
   2866  1.1.4.2  rmind         t3_write_reg(adap, A_TP_PACE_TABLE, 0xffff0000 + i);
   2867  1.1.4.2  rmind         pace_vals[i] = t3_read_reg(adap, A_TP_PACE_TABLE) * tick_ns;
   2868  1.1.4.2  rmind     }
   2869  1.1.4.2  rmind }
   2870  1.1.4.2  rmind 
   2871  1.1.4.2  rmind /**
   2872  1.1.4.2  rmind  *  t3_set_pace_tbl - set the pace table
   2873  1.1.4.2  rmind  *  @adap: the adapter
   2874  1.1.4.2  rmind  *  @pace_vals: the pace values in nanoseconds
   2875  1.1.4.2  rmind  *  @start: index of the first entry in the HW pace table to set
   2876  1.1.4.2  rmind  *  @n: how many entries to set
   2877  1.1.4.2  rmind  *
   2878  1.1.4.2  rmind  *  Sets (a subset of the) HW pace table.
   2879  1.1.4.2  rmind  */
   2880  1.1.4.2  rmind void t3_set_pace_tbl(adapter_t *adap, unsigned int *pace_vals,
   2881  1.1.4.2  rmind              unsigned int start, unsigned int n)
   2882  1.1.4.2  rmind {
   2883  1.1.4.2  rmind     unsigned int tick_ns = dack_ticks_to_usec(adap, 1000);
   2884  1.1.4.2  rmind 
   2885  1.1.4.2  rmind     for ( ; n; n--, start++, pace_vals++)
   2886  1.1.4.2  rmind         t3_write_reg(adap, A_TP_PACE_TABLE, (start << 16) |
   2887  1.1.4.2  rmind                  ((*pace_vals + tick_ns / 2) / tick_ns));
   2888  1.1.4.2  rmind }
   2889  1.1.4.2  rmind 
   2890  1.1.4.2  rmind #define ulp_region(adap, name, start, len) \
   2891  1.1.4.2  rmind     t3_write_reg((adap), A_ULPRX_ ## name ## _LLIMIT, (start)); \
   2892  1.1.4.2  rmind     t3_write_reg((adap), A_ULPRX_ ## name ## _ULIMIT, \
   2893  1.1.4.2  rmind              (start) + (len) - 1); \
   2894  1.1.4.2  rmind     start += len
   2895  1.1.4.2  rmind 
   2896  1.1.4.2  rmind #define ulptx_region(adap, name, start, len) \
   2897  1.1.4.2  rmind     t3_write_reg((adap), A_ULPTX_ ## name ## _LLIMIT, (start)); \
   2898  1.1.4.2  rmind     t3_write_reg((adap), A_ULPTX_ ## name ## _ULIMIT, \
   2899  1.1.4.2  rmind              (start) + (len) - 1)
   2900  1.1.4.2  rmind 
   2901  1.1.4.2  rmind static void ulp_config(adapter_t *adap, const struct tp_params *p)
   2902  1.1.4.2  rmind {
   2903  1.1.4.2  rmind     unsigned int m = p->chan_rx_size;
   2904  1.1.4.2  rmind 
   2905  1.1.4.2  rmind     ulp_region(adap, ISCSI, m, p->chan_rx_size / 8);
   2906  1.1.4.2  rmind     ulp_region(adap, TDDP, m, p->chan_rx_size / 8);
   2907  1.1.4.2  rmind     ulptx_region(adap, TPT, m, p->chan_rx_size / 4);
   2908  1.1.4.2  rmind     ulp_region(adap, STAG, m, p->chan_rx_size / 4);
   2909  1.1.4.2  rmind     ulp_region(adap, RQ, m, p->chan_rx_size / 4);
   2910  1.1.4.2  rmind     ulptx_region(adap, PBL, m, p->chan_rx_size / 4);
   2911  1.1.4.2  rmind     ulp_region(adap, PBL, m, p->chan_rx_size / 4);
   2912  1.1.4.2  rmind     t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff);
   2913  1.1.4.2  rmind }
   2914  1.1.4.2  rmind 
   2915  1.1.4.2  rmind 
   2916  1.1.4.2  rmind /**
   2917  1.1.4.2  rmind  *  t3_set_proto_sram - set the contents of the protocol sram
   2918  1.1.4.2  rmind  *  @adapter: the adapter
   2919  1.1.4.2  rmind  *  @data: the protocol image
   2920  1.1.4.2  rmind  *
   2921  1.1.4.2  rmind  *  Write the contents of the protocol SRAM.
   2922  1.1.4.2  rmind  */
   2923  1.1.4.2  rmind int t3_set_proto_sram(adapter_t *adap, const u8 *data)
   2924  1.1.4.2  rmind {
   2925  1.1.4.2  rmind     int i;
   2926  1.1.4.2  rmind     const u32 *buf = (const u32 *)data;
   2927  1.1.4.2  rmind 
   2928  1.1.4.2  rmind     for (i = 0; i < PROTO_SRAM_LINES; i++) {
   2929  1.1.4.2  rmind         t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
   2930  1.1.4.2  rmind         t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
   2931  1.1.4.2  rmind         t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
   2932  1.1.4.2  rmind         t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
   2933  1.1.4.2  rmind         t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
   2934  1.1.4.2  rmind 
   2935  1.1.4.2  rmind         t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
   2936  1.1.4.2  rmind         if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
   2937  1.1.4.2  rmind             return -EIO;
   2938  1.1.4.2  rmind     }
   2939  1.1.4.2  rmind     return 0;
   2940  1.1.4.2  rmind }
   2941  1.1.4.2  rmind #endif
   2942  1.1.4.2  rmind 
   2943  1.1.4.2  rmind /**
   2944  1.1.4.2  rmind  *  t3_config_trace_filter - configure one of the tracing filters
   2945  1.1.4.2  rmind  *  @adapter: the adapter
   2946  1.1.4.2  rmind  *  @tp: the desired trace filter parameters
   2947  1.1.4.2  rmind  *  @filter_index: which filter to configure
   2948  1.1.4.2  rmind  *  @invert: if set non-matching packets are traced instead of matching ones
   2949  1.1.4.2  rmind  *  @enable: whether to enable or disable the filter
   2950  1.1.4.2  rmind  *
   2951  1.1.4.2  rmind  *  Configures one of the tracing filters available in HW.
   2952  1.1.4.2  rmind  */
   2953  1.1.4.2  rmind void t3_config_trace_filter(adapter_t *adapter, const struct trace_params *tp,
   2954  1.1.4.2  rmind                 int filter_index, int invert, int enable)
   2955  1.1.4.2  rmind {
   2956  1.1.4.2  rmind     u32 addr, key[4], mask[4];
   2957  1.1.4.2  rmind 
   2958  1.1.4.2  rmind     key[0] = tp->sport | (tp->sip << 16);
   2959  1.1.4.2  rmind     key[1] = (tp->sip >> 16) | (tp->dport << 16);
   2960  1.1.4.2  rmind     key[2] = tp->dip;
   2961  1.1.4.2  rmind     key[3] = tp->proto | (tp->vlan << 8) | (tp->intf << 20);
   2962  1.1.4.2  rmind 
   2963  1.1.4.2  rmind     mask[0] = tp->sport_mask | (tp->sip_mask << 16);
   2964  1.1.4.2  rmind     mask[1] = (tp->sip_mask >> 16) | (tp->dport_mask << 16);
   2965  1.1.4.2  rmind     mask[2] = tp->dip_mask;
   2966  1.1.4.2  rmind     mask[3] = tp->proto_mask | (tp->vlan_mask << 8) | (tp->intf_mask << 20);
   2967  1.1.4.2  rmind 
   2968  1.1.4.2  rmind     if (invert)
   2969  1.1.4.2  rmind         key[3] |= (1 << 29);
   2970  1.1.4.2  rmind     if (enable)
   2971  1.1.4.2  rmind         key[3] |= (1 << 28);
   2972  1.1.4.2  rmind 
   2973  1.1.4.2  rmind     addr = filter_index ? A_TP_RX_TRC_KEY0 : A_TP_TX_TRC_KEY0;
   2974  1.1.4.2  rmind     tp_wr_indirect(adapter, addr++, key[0]);
   2975  1.1.4.2  rmind     tp_wr_indirect(adapter, addr++, mask[0]);
   2976  1.1.4.2  rmind     tp_wr_indirect(adapter, addr++, key[1]);
   2977  1.1.4.2  rmind     tp_wr_indirect(adapter, addr++, mask[1]);
   2978  1.1.4.2  rmind     tp_wr_indirect(adapter, addr++, key[2]);
   2979  1.1.4.2  rmind     tp_wr_indirect(adapter, addr++, mask[2]);
   2980  1.1.4.2  rmind     tp_wr_indirect(adapter, addr++, key[3]);
   2981  1.1.4.2  rmind     tp_wr_indirect(adapter, addr,   mask[3]);
   2982  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_TP_PIO_DATA);
   2983  1.1.4.2  rmind }
   2984  1.1.4.2  rmind 
   2985  1.1.4.2  rmind /**
   2986  1.1.4.2  rmind  *  t3_config_sched - configure a HW traffic scheduler
   2987  1.1.4.2  rmind  *  @adap: the adapter
   2988  1.1.4.2  rmind  *  @kbps: target rate in Kbps
   2989  1.1.4.2  rmind  *  @sched: the scheduler index
   2990  1.1.4.2  rmind  *
   2991  1.1.4.2  rmind  *  Configure a Tx HW scheduler for the target rate.
   2992  1.1.4.2  rmind  */
   2993  1.1.4.2  rmind int t3_config_sched(adapter_t *adap, unsigned int kbps, int sched)
   2994  1.1.4.2  rmind {
   2995  1.1.4.2  rmind     unsigned int v, tps, cpt, bpt, delta, mindelta = ~0;
   2996  1.1.4.2  rmind     unsigned int clk = adap->params.vpd.cclk * 1000;
   2997  1.1.4.2  rmind     unsigned int selected_cpt = 0, selected_bpt = 0;
   2998  1.1.4.2  rmind 
   2999  1.1.4.2  rmind     if (kbps > 0) {
   3000  1.1.4.2  rmind         kbps *= 125;     /* -> bytes */
   3001  1.1.4.2  rmind         for (cpt = 1; cpt <= 255; cpt++) {
   3002  1.1.4.2  rmind             tps = clk / cpt;
   3003  1.1.4.2  rmind             bpt = (kbps + tps / 2) / tps;
   3004  1.1.4.2  rmind             if (bpt > 0 && bpt <= 255) {
   3005  1.1.4.2  rmind                 v = bpt * tps;
   3006  1.1.4.2  rmind                 delta = v >= kbps ? v - kbps : kbps - v;
   3007  1.1.4.2  rmind                 if (delta <= mindelta) {
   3008  1.1.4.2  rmind                     mindelta = delta;
   3009  1.1.4.2  rmind                     selected_cpt = cpt;
   3010  1.1.4.2  rmind                     selected_bpt = bpt;
   3011  1.1.4.2  rmind                 }
   3012  1.1.4.2  rmind             } else if (selected_cpt)
   3013  1.1.4.2  rmind                 break;
   3014  1.1.4.2  rmind         }
   3015  1.1.4.2  rmind         if (!selected_cpt)
   3016  1.1.4.2  rmind             return -EINVAL;
   3017  1.1.4.2  rmind     }
   3018  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TM_PIO_ADDR,
   3019  1.1.4.2  rmind              A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2);
   3020  1.1.4.2  rmind     v = t3_read_reg(adap, A_TP_TM_PIO_DATA);
   3021  1.1.4.2  rmind     if (sched & 1)
   3022  1.1.4.2  rmind         v = (v & 0xffff) | (selected_cpt << 16) | (selected_bpt << 24);
   3023  1.1.4.2  rmind     else
   3024  1.1.4.2  rmind         v = (v & 0xffff0000) | selected_cpt | (selected_bpt << 8);
   3025  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TM_PIO_DATA, v);
   3026  1.1.4.2  rmind     return 0;
   3027  1.1.4.2  rmind }
   3028  1.1.4.2  rmind 
   3029  1.1.4.2  rmind /**
   3030  1.1.4.2  rmind  *  t3_set_sched_ipg - set the IPG for a Tx HW packet rate scheduler
   3031  1.1.4.2  rmind  *  @adap: the adapter
   3032  1.1.4.2  rmind  *  @sched: the scheduler index
   3033  1.1.4.2  rmind  *  @ipg: the interpacket delay in tenths of nanoseconds
   3034  1.1.4.2  rmind  *
   3035  1.1.4.2  rmind  *  Set the interpacket delay for a HW packet rate scheduler.
   3036  1.1.4.2  rmind  */
   3037  1.1.4.2  rmind int t3_set_sched_ipg(adapter_t *adap, int sched, unsigned int ipg)
   3038  1.1.4.2  rmind {
   3039  1.1.4.2  rmind     unsigned int v, addr = A_TP_TX_MOD_Q1_Q0_TIMER_SEPARATOR - sched / 2;
   3040  1.1.4.2  rmind 
   3041  1.1.4.2  rmind     /* convert ipg to nearest number of core clocks */
   3042  1.1.4.2  rmind     ipg *= core_ticks_per_usec(adap);
   3043  1.1.4.2  rmind     ipg = (ipg + 5000) / 10000;
   3044  1.1.4.2  rmind     if (ipg > 0xffff)
   3045  1.1.4.2  rmind         return -EINVAL;
   3046  1.1.4.2  rmind 
   3047  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TM_PIO_ADDR, addr);
   3048  1.1.4.2  rmind     v = t3_read_reg(adap, A_TP_TM_PIO_DATA);
   3049  1.1.4.2  rmind     if (sched & 1)
   3050  1.1.4.2  rmind         v = (v & 0xffff) | (ipg << 16);
   3051  1.1.4.2  rmind     else
   3052  1.1.4.2  rmind         v = (v & 0xffff0000) | ipg;
   3053  1.1.4.2  rmind     t3_write_reg(adap, A_TP_TM_PIO_DATA, v);
   3054  1.1.4.2  rmind     t3_read_reg(adap, A_TP_TM_PIO_DATA);
   3055  1.1.4.2  rmind     return 0;
   3056  1.1.4.2  rmind }
   3057  1.1.4.2  rmind 
   3058  1.1.4.2  rmind /**
   3059  1.1.4.2  rmind  *  t3_get_tx_sched - get the configuration of a Tx HW traffic scheduler
   3060  1.1.4.2  rmind  *  @adap: the adapter
   3061  1.1.4.2  rmind  *  @sched: the scheduler index
   3062  1.1.4.2  rmind  *  @kbps: the byte rate in Kbps
   3063  1.1.4.2  rmind  *  @ipg: the interpacket delay in tenths of nanoseconds
   3064  1.1.4.2  rmind  *
   3065  1.1.4.2  rmind  *  Return the current configuration of a HW Tx scheduler.
   3066  1.1.4.2  rmind  */
   3067  1.1.4.2  rmind void t3_get_tx_sched(adapter_t *adap, unsigned int sched, unsigned int *kbps,
   3068  1.1.4.2  rmind              unsigned int *ipg)
   3069  1.1.4.2  rmind {
   3070  1.1.4.2  rmind     unsigned int v, addr, bpt, cpt;
   3071  1.1.4.2  rmind 
   3072  1.1.4.2  rmind     if (kbps) {
   3073  1.1.4.2  rmind         addr = A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2;
   3074  1.1.4.2  rmind         t3_write_reg(adap, A_TP_TM_PIO_ADDR, addr);
   3075  1.1.4.2  rmind         v = t3_read_reg(adap, A_TP_TM_PIO_DATA);
   3076  1.1.4.2  rmind         if (sched & 1)
   3077  1.1.4.2  rmind             v >>= 16;
   3078  1.1.4.2  rmind         bpt = (v >> 8) & 0xff;
   3079  1.1.4.2  rmind         cpt = v & 0xff;
   3080  1.1.4.2  rmind         if (!cpt)
   3081  1.1.4.2  rmind             *kbps = 0;        /* scheduler disabled */
   3082  1.1.4.2  rmind         else {
   3083  1.1.4.2  rmind             v = (adap->params.vpd.cclk * 1000) / cpt;
   3084  1.1.4.2  rmind             *kbps = (v * bpt) / 125;
   3085  1.1.4.2  rmind         }
   3086  1.1.4.2  rmind     }
   3087  1.1.4.2  rmind     if (ipg) {
   3088  1.1.4.2  rmind         addr = A_TP_TX_MOD_Q1_Q0_TIMER_SEPARATOR - sched / 2;
   3089  1.1.4.2  rmind         t3_write_reg(adap, A_TP_TM_PIO_ADDR, addr);
   3090  1.1.4.2  rmind         v = t3_read_reg(adap, A_TP_TM_PIO_DATA);
   3091  1.1.4.2  rmind         if (sched & 1)
   3092  1.1.4.2  rmind             v >>= 16;
   3093  1.1.4.2  rmind         v &= 0xffff;
   3094  1.1.4.2  rmind         *ipg = (10000 * v) / core_ticks_per_usec(adap);
   3095  1.1.4.2  rmind     }
   3096  1.1.4.2  rmind }
   3097  1.1.4.2  rmind 
   3098  1.1.4.2  rmind /**
   3099  1.1.4.2  rmind  *  tp_init - configure TP
   3100  1.1.4.2  rmind  *  @adap: the adapter
   3101  1.1.4.2  rmind  *  @p: TP configuration parameters
   3102  1.1.4.2  rmind  *
   3103  1.1.4.2  rmind  *  Initializes the TP HW module.
   3104  1.1.4.2  rmind  */
   3105  1.1.4.2  rmind static int tp_init(adapter_t *adap, const struct tp_params *p)
   3106  1.1.4.2  rmind {
   3107  1.1.4.2  rmind     int busy = 0;
   3108  1.1.4.2  rmind 
   3109  1.1.4.2  rmind     tp_config(adap, p);
   3110  1.1.4.2  rmind     t3_set_vlan_accel(adap, 3, 0);
   3111  1.1.4.2  rmind 
   3112  1.1.4.2  rmind     if (is_offload(adap)) {
   3113  1.1.4.2  rmind         tp_set_timers(adap, adap->params.vpd.cclk * 1000);
   3114  1.1.4.2  rmind         t3_write_reg(adap, A_TP_RESET, F_FLSTINITENABLE);
   3115  1.1.4.2  rmind         busy = t3_wait_op_done(adap, A_TP_RESET, F_FLSTINITENABLE,
   3116  1.1.4.2  rmind                        0, 1000, 5);
   3117  1.1.4.2  rmind         if (busy)
   3118  1.1.4.2  rmind             CH_ERR(adap, "TP initialization timed out\n");
   3119  1.1.4.2  rmind     }
   3120  1.1.4.2  rmind 
   3121  1.1.4.2  rmind     if (!busy)
   3122  1.1.4.2  rmind         t3_write_reg(adap, A_TP_RESET, F_TPRESET);
   3123  1.1.4.2  rmind     return busy;
   3124  1.1.4.2  rmind }
   3125  1.1.4.2  rmind 
   3126  1.1.4.2  rmind /**
   3127  1.1.4.2  rmind  *  t3_mps_set_active_ports - configure port failover
   3128  1.1.4.2  rmind  *  @adap: the adapter
   3129  1.1.4.2  rmind  *  @port_mask: bitmap of active ports
   3130  1.1.4.2  rmind  *
   3131  1.1.4.2  rmind  *  Sets the active ports according to the supplied bitmap.
   3132  1.1.4.2  rmind  */
   3133  1.1.4.2  rmind int t3_mps_set_active_ports(adapter_t *adap, unsigned int port_mask)
   3134  1.1.4.2  rmind {
   3135  1.1.4.2  rmind     if (port_mask & ~((1 << adap->params.nports) - 1))
   3136  1.1.4.2  rmind         return -EINVAL;
   3137  1.1.4.2  rmind     t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE | F_PORT0ACTIVE,
   3138  1.1.4.2  rmind              port_mask << S_PORT0ACTIVE);
   3139  1.1.4.2  rmind     return 0;
   3140  1.1.4.2  rmind }
   3141  1.1.4.2  rmind 
   3142  1.1.4.2  rmind /**
   3143  1.1.4.2  rmind  *  chan_init_hw - channel-dependent HW initialization
   3144  1.1.4.2  rmind  *  @adap: the adapter
   3145  1.1.4.2  rmind  *  @chan_map: bitmap of Tx channels being used
   3146  1.1.4.2  rmind  *
   3147  1.1.4.2  rmind  *  Perform the bits of HW initialization that are dependent on the Tx
   3148  1.1.4.2  rmind  *  channels being used.
   3149  1.1.4.2  rmind  */
   3150  1.1.4.2  rmind static void chan_init_hw(adapter_t *adap, unsigned int chan_map)
   3151  1.1.4.2  rmind {
   3152  1.1.4.2  rmind     int i;
   3153  1.1.4.2  rmind 
   3154  1.1.4.2  rmind     if (chan_map != 3) {                                 /* one channel */
   3155  1.1.4.2  rmind         t3_set_reg_field(adap, A_ULPRX_CTL, F_ROUND_ROBIN, 0);
   3156  1.1.4.2  rmind         t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0);
   3157  1.1.4.2  rmind         t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_ENFORCEPKT |
   3158  1.1.4.2  rmind                  (chan_map == 1 ? F_TPTXPORT0EN | F_PORT0ACTIVE :
   3159  1.1.4.2  rmind                           F_TPTXPORT1EN | F_PORT1ACTIVE));
   3160  1.1.4.2  rmind         t3_write_reg(adap, A_PM1_TX_CFG,
   3161  1.1.4.2  rmind                  chan_map == 1 ? 0xffffffff : 0);
   3162  1.1.4.2  rmind         if (chan_map == 2)
   3163  1.1.4.2  rmind             t3_write_reg(adap, A_TP_TX_MOD_QUEUE_REQ_MAP,
   3164  1.1.4.2  rmind                      V_TX_MOD_QUEUE_REQ_MAP(0xff));
   3165  1.1.4.2  rmind         t3_write_reg(adap, A_TP_TX_MOD_QUE_TABLE, (12 << 16) | 0xd9c8);
   3166  1.1.4.2  rmind         t3_write_reg(adap, A_TP_TX_MOD_QUE_TABLE, (13 << 16) | 0xfbea);
   3167  1.1.4.2  rmind     } else {                                             /* two channels */
   3168  1.1.4.2  rmind         t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN);
   3169  1.1.4.2  rmind         t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB);
   3170  1.1.4.2  rmind         t3_write_reg(adap, A_ULPTX_DMA_WEIGHT,
   3171  1.1.4.2  rmind                  V_D1_WEIGHT(16) | V_D0_WEIGHT(16));
   3172  1.1.4.2  rmind         t3_write_reg(adap, A_MPS_CFG, F_TPTXPORT0EN | F_TPTXPORT1EN |
   3173  1.1.4.2  rmind                  F_TPRXPORTEN | F_PORT0ACTIVE | F_PORT1ACTIVE |
   3174  1.1.4.2  rmind                  F_ENFORCEPKT);
   3175  1.1.4.2  rmind         t3_write_reg(adap, A_PM1_TX_CFG, 0x80008000);
   3176  1.1.4.2  rmind         t3_set_reg_field(adap, A_TP_PC_CONFIG, 0, F_TXTOSQUEUEMAPMODE);
   3177  1.1.4.2  rmind         t3_write_reg(adap, A_TP_TX_MOD_QUEUE_REQ_MAP,
   3178  1.1.4.2  rmind                  V_TX_MOD_QUEUE_REQ_MAP(0xaa));
   3179  1.1.4.2  rmind         for (i = 0; i < 16; i++)
   3180  1.1.4.2  rmind             t3_write_reg(adap, A_TP_TX_MOD_QUE_TABLE,
   3181  1.1.4.2  rmind                      (i << 16) | 0x1010);
   3182  1.1.4.2  rmind         t3_write_reg(adap, A_TP_TX_MOD_QUE_TABLE, (12 << 16) | 0xba98);
   3183  1.1.4.2  rmind         t3_write_reg(adap, A_TP_TX_MOD_QUE_TABLE, (13 << 16) | 0xfedc);
   3184  1.1.4.2  rmind     }
   3185  1.1.4.2  rmind }
   3186  1.1.4.2  rmind 
   3187  1.1.4.2  rmind static int calibrate_xgm(adapter_t *adapter)
   3188  1.1.4.2  rmind {
   3189  1.1.4.2  rmind     if (uses_xaui(adapter)) {
   3190  1.1.4.2  rmind         unsigned int v, i;
   3191  1.1.4.2  rmind 
   3192  1.1.4.2  rmind         for (i = 0; i < 5; ++i) {
   3193  1.1.4.2  rmind             t3_write_reg(adapter, A_XGM_XAUI_IMP, 0);
   3194  1.1.4.2  rmind             (void) t3_read_reg(adapter, A_XGM_XAUI_IMP);
   3195  1.1.4.2  rmind             msleep(1);
   3196  1.1.4.2  rmind             v = t3_read_reg(adapter, A_XGM_XAUI_IMP);
   3197  1.1.4.2  rmind             if (!(v & (F_XGM_CALFAULT | F_CALBUSY))) {
   3198  1.1.4.2  rmind                 t3_write_reg(adapter, A_XGM_XAUI_IMP,
   3199  1.1.4.2  rmind                          V_XAUIIMP(G_CALIMP(v) >> 2));
   3200  1.1.4.2  rmind                 return 0;
   3201  1.1.4.2  rmind             }
   3202  1.1.4.2  rmind         }
   3203  1.1.4.2  rmind         CH_ERR(adapter, "MAC calibration failed\n");
   3204  1.1.4.2  rmind         return -1;
   3205  1.1.4.2  rmind     } else {
   3206  1.1.4.2  rmind         t3_write_reg(adapter, A_XGM_RGMII_IMP,
   3207  1.1.4.2  rmind                  V_RGMIIIMPPD(2) | V_RGMIIIMPPU(3));
   3208  1.1.4.2  rmind         t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_XGM_IMPSETUPDATE,
   3209  1.1.4.2  rmind                  F_XGM_IMPSETUPDATE);
   3210  1.1.4.2  rmind     }
   3211  1.1.4.2  rmind     return 0;
   3212  1.1.4.2  rmind }
   3213  1.1.4.2  rmind 
   3214  1.1.4.2  rmind static void calibrate_xgm_t3b(adapter_t *adapter)
   3215  1.1.4.2  rmind {
   3216  1.1.4.2  rmind     if (!uses_xaui(adapter)) {
   3217  1.1.4.2  rmind         t3_write_reg(adapter, A_XGM_RGMII_IMP, F_CALRESET |
   3218  1.1.4.2  rmind                  F_CALUPDATE | V_RGMIIIMPPD(2) | V_RGMIIIMPPU(3));
   3219  1.1.4.2  rmind         t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_CALRESET, 0);
   3220  1.1.4.2  rmind         t3_set_reg_field(adapter, A_XGM_RGMII_IMP, 0,
   3221  1.1.4.2  rmind                  F_XGM_IMPSETUPDATE);
   3222  1.1.4.2  rmind         t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_XGM_IMPSETUPDATE,
   3223  1.1.4.2  rmind                  0);
   3224  1.1.4.2  rmind         t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_CALUPDATE, 0);
   3225  1.1.4.2  rmind         t3_set_reg_field(adapter, A_XGM_RGMII_IMP, 0, F_CALUPDATE);
   3226  1.1.4.2  rmind     }
   3227  1.1.4.2  rmind }
   3228  1.1.4.2  rmind 
   3229  1.1.4.2  rmind struct mc7_timing_params {
   3230  1.1.4.2  rmind     unsigned char ActToPreDly;
   3231  1.1.4.2  rmind     unsigned char ActToRdWrDly;
   3232  1.1.4.2  rmind     unsigned char PreCyc;
   3233  1.1.4.2  rmind     unsigned char RefCyc[5];
   3234  1.1.4.2  rmind     unsigned char BkCyc;
   3235  1.1.4.2  rmind     unsigned char WrToRdDly;
   3236  1.1.4.2  rmind     unsigned char RdToWrDly;
   3237  1.1.4.2  rmind };
   3238  1.1.4.2  rmind 
   3239  1.1.4.2  rmind /*
   3240  1.1.4.2  rmind  * Write a value to a register and check that the write completed.  These
   3241  1.1.4.2  rmind  * writes normally complete in a cycle or two, so one read should suffice.
   3242  1.1.4.2  rmind  * The very first read exists to flush the posted write to the device.
   3243  1.1.4.2  rmind  */
   3244  1.1.4.2  rmind static int wrreg_wait(adapter_t *adapter, unsigned int addr, u32 val)
   3245  1.1.4.2  rmind {
   3246  1.1.4.2  rmind     t3_write_reg(adapter,   addr, val);
   3247  1.1.4.2  rmind     (void) t3_read_reg(adapter, addr);                   /* flush */
   3248  1.1.4.2  rmind     if (!(t3_read_reg(adapter, addr) & F_BUSY))
   3249  1.1.4.2  rmind         return 0;
   3250  1.1.4.2  rmind     CH_ERR(adapter, "write to MC7 register 0x%x timed out\n", addr);
   3251  1.1.4.2  rmind     return -EIO;
   3252  1.1.4.2  rmind }
   3253  1.1.4.2  rmind 
   3254  1.1.4.2  rmind static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
   3255  1.1.4.2  rmind {
   3256  1.1.4.2  rmind     static const unsigned int mc7_mode[] = {
   3257  1.1.4.2  rmind         0x632, 0x642, 0x652, 0x432, 0x442
   3258  1.1.4.2  rmind     };
   3259  1.1.4.2  rmind     static const struct mc7_timing_params mc7_timings[] = {
   3260  1.1.4.2  rmind         { 12, 3, 4, { 20, 28, 34, 52, 0 }, 15, 6, 4 },
   3261  1.1.4.2  rmind         { 12, 4, 5, { 20, 28, 34, 52, 0 }, 16, 7, 4 },
   3262  1.1.4.2  rmind         { 12, 5, 6, { 20, 28, 34, 52, 0 }, 17, 8, 4 },
   3263  1.1.4.2  rmind         { 9,  3, 4, { 15, 21, 26, 39, 0 }, 12, 6, 4 },
   3264  1.1.4.2  rmind         { 9,  4, 5, { 15, 21, 26, 39, 0 }, 13, 7, 4 }
   3265  1.1.4.2  rmind     };
   3266  1.1.4.2  rmind 
   3267  1.1.4.2  rmind     u32 val;
   3268  1.1.4.2  rmind     unsigned int width, density, slow, attempts;
   3269  1.1.4.2  rmind     adapter_t *adapter = mc7->adapter;
   3270  1.1.4.2  rmind     const struct mc7_timing_params *p = &mc7_timings[mem_type];
   3271  1.1.4.2  rmind 
   3272  1.1.4.2  rmind     if (!mc7->size)
   3273  1.1.4.2  rmind         return 0;
   3274  1.1.4.2  rmind 
   3275  1.1.4.2  rmind     val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
   3276  1.1.4.2  rmind     slow = val & F_SLOW;
   3277  1.1.4.2  rmind     width = G_WIDTH(val);
   3278  1.1.4.2  rmind     density = G_DEN(val);
   3279  1.1.4.2  rmind 
   3280  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_CFG, val | F_IFEN);
   3281  1.1.4.2  rmind     val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);  /* flush */
   3282  1.1.4.2  rmind     msleep(1);
   3283  1.1.4.2  rmind 
   3284  1.1.4.2  rmind     if (!slow) {
   3285  1.1.4.2  rmind         t3_write_reg(adapter, mc7->offset + A_MC7_CAL, F_SGL_CAL_EN);
   3286  1.1.4.2  rmind         (void) t3_read_reg(adapter, mc7->offset + A_MC7_CAL);
   3287  1.1.4.2  rmind         msleep(1);
   3288  1.1.4.2  rmind         if (t3_read_reg(adapter, mc7->offset + A_MC7_CAL) &
   3289  1.1.4.2  rmind             (F_BUSY | F_SGL_CAL_EN | F_CAL_FAULT)) {
   3290  1.1.4.2  rmind             CH_ERR(adapter, "%s MC7 calibration timed out\n",
   3291  1.1.4.2  rmind                    mc7->name);
   3292  1.1.4.2  rmind             goto out_fail;
   3293  1.1.4.2  rmind         }
   3294  1.1.4.2  rmind     }
   3295  1.1.4.2  rmind 
   3296  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_PARM,
   3297  1.1.4.2  rmind              V_ACTTOPREDLY(p->ActToPreDly) |
   3298  1.1.4.2  rmind              V_ACTTORDWRDLY(p->ActToRdWrDly) | V_PRECYC(p->PreCyc) |
   3299  1.1.4.2  rmind              V_REFCYC(p->RefCyc[density]) | V_BKCYC(p->BkCyc) |
   3300  1.1.4.2  rmind              V_WRTORDDLY(p->WrToRdDly) | V_RDTOWRDLY(p->RdToWrDly));
   3301  1.1.4.2  rmind 
   3302  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_CFG,
   3303  1.1.4.2  rmind              val | F_CLKEN | F_TERM150);
   3304  1.1.4.2  rmind     (void) t3_read_reg(adapter, mc7->offset + A_MC7_CFG); /* flush */
   3305  1.1.4.2  rmind 
   3306  1.1.4.2  rmind     if (!slow)
   3307  1.1.4.2  rmind         t3_set_reg_field(adapter, mc7->offset + A_MC7_DLL, F_DLLENB,
   3308  1.1.4.2  rmind                  F_DLLENB);
   3309  1.1.4.2  rmind     udelay(1);
   3310  1.1.4.2  rmind 
   3311  1.1.4.2  rmind     val = slow ? 3 : 6;
   3312  1.1.4.2  rmind     if (wrreg_wait(adapter, mc7->offset + A_MC7_PRE, 0) ||
   3313  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE2, 0) ||
   3314  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE3, 0) ||
   3315  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val))
   3316  1.1.4.2  rmind         goto out_fail;
   3317  1.1.4.2  rmind 
   3318  1.1.4.2  rmind     if (!slow) {
   3319  1.1.4.2  rmind         t3_write_reg(adapter, mc7->offset + A_MC7_MODE, 0x100);
   3320  1.1.4.2  rmind         t3_set_reg_field(adapter, mc7->offset + A_MC7_DLL,
   3321  1.1.4.2  rmind                  F_DLLRST, 0);
   3322  1.1.4.2  rmind         udelay(5);
   3323  1.1.4.2  rmind     }
   3324  1.1.4.2  rmind 
   3325  1.1.4.2  rmind     if (wrreg_wait(adapter, mc7->offset + A_MC7_PRE, 0) ||
   3326  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_REF, 0) ||
   3327  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_REF, 0) ||
   3328  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_MODE,
   3329  1.1.4.2  rmind                mc7_mode[mem_type]) ||
   3330  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val | 0x380) ||
   3331  1.1.4.2  rmind         wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val))
   3332  1.1.4.2  rmind         goto out_fail;
   3333  1.1.4.2  rmind 
   3334  1.1.4.2  rmind     /* clock value is in KHz */
   3335  1.1.4.2  rmind     mc7_clock = mc7_clock * 7812 + mc7_clock / 2;  /* ns */
   3336  1.1.4.2  rmind     mc7_clock /= 1000000;                          /* KHz->MHz, ns->us */
   3337  1.1.4.2  rmind 
   3338  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_REF,
   3339  1.1.4.2  rmind              F_PERREFEN | V_PREREFDIV(mc7_clock));
   3340  1.1.4.2  rmind     (void) t3_read_reg(adapter, mc7->offset + A_MC7_REF); /* flush */
   3341  1.1.4.2  rmind 
   3342  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_ECC,
   3343  1.1.4.2  rmind              F_ECCGENEN | F_ECCCHKEN);
   3344  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_BIST_DATA, 0);
   3345  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_BIST_ADDR_BEG, 0);
   3346  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_BIST_ADDR_END,
   3347  1.1.4.2  rmind              (mc7->size << width) - 1);
   3348  1.1.4.2  rmind     t3_write_reg(adapter, mc7->offset + A_MC7_BIST_OP, V_OP(1));
   3349  1.1.4.2  rmind     (void) t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP); /* flush */
   3350  1.1.4.2  rmind 
   3351  1.1.4.2  rmind     attempts = 50;
   3352  1.1.4.2  rmind     do {
   3353  1.1.4.2  rmind         msleep(250);
   3354  1.1.4.2  rmind         val = t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP);
   3355  1.1.4.2  rmind     } while ((val & F_BUSY) && --attempts);
   3356  1.1.4.2  rmind     if (val & F_BUSY) {
   3357  1.1.4.2  rmind         CH_ERR(adapter, "%s MC7 BIST timed out\n", mc7->name);
   3358  1.1.4.2  rmind         goto out_fail;
   3359  1.1.4.2  rmind     }
   3360  1.1.4.2  rmind 
   3361  1.1.4.2  rmind     /* Enable normal memory accesses. */
   3362  1.1.4.2  rmind     t3_set_reg_field(adapter, mc7->offset + A_MC7_CFG, 0, F_RDY);
   3363  1.1.4.2  rmind     return 0;
   3364  1.1.4.2  rmind 
   3365  1.1.4.2  rmind  out_fail:
   3366  1.1.4.2  rmind     return -1;
   3367  1.1.4.2  rmind }
   3368  1.1.4.2  rmind 
   3369  1.1.4.2  rmind static void config_pcie(adapter_t *adap)
   3370  1.1.4.2  rmind {
   3371  1.1.4.2  rmind     static const u16 ack_lat[4][6] = {
   3372  1.1.4.2  rmind         { 237, 416, 559, 1071, 2095, 4143 },
   3373  1.1.4.2  rmind         { 128, 217, 289, 545, 1057, 2081 },
   3374  1.1.4.2  rmind         { 73, 118, 154, 282, 538, 1050 },
   3375  1.1.4.2  rmind         { 67, 107, 86, 150, 278, 534 }
   3376  1.1.4.2  rmind     };
   3377  1.1.4.2  rmind     static const u16 rpl_tmr[4][6] = {
   3378  1.1.4.2  rmind         { 711, 1248, 1677, 3213, 6285, 12429 },
   3379  1.1.4.2  rmind         { 384, 651, 867, 1635, 3171, 6243 },
   3380  1.1.4.2  rmind         { 219, 354, 462, 846, 1614, 3150 },
   3381  1.1.4.2  rmind         { 201, 321, 258, 450, 834, 1602 }
   3382  1.1.4.2  rmind     };
   3383  1.1.4.2  rmind 
   3384  1.1.4.2  rmind     u16 val;
   3385  1.1.4.2  rmind     unsigned int log2_width, pldsize;
   3386  1.1.4.2  rmind     unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt;
   3387  1.1.4.2  rmind 
   3388  1.1.4.2  rmind     t3_os_pci_read_config_2(adap,
   3389  1.1.4.2  rmind                 adap->params.pci.pcie_cap_addr + PCI_EXP_DEVCTL,
   3390  1.1.4.2  rmind                 &val);
   3391  1.1.4.2  rmind     pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
   3392  1.1.4.2  rmind 
   3393  1.1.4.2  rmind     t3_os_pci_read_config_2(adap,
   3394  1.1.4.2  rmind                 adap->params.pci.pcie_cap_addr + PCI_EXP_LNKCTL,
   3395  1.1.4.2  rmind                     &val);
   3396  1.1.4.2  rmind 
   3397  1.1.4.2  rmind     fst_trn_tx = G_NUMFSTTRNSEQ(t3_read_reg(adap, A_PCIE_PEX_CTRL0));
   3398  1.1.4.2  rmind     fst_trn_rx = adap->params.rev == 0 ? fst_trn_tx :
   3399  1.1.4.2  rmind             G_NUMFSTTRNSEQRX(t3_read_reg(adap, A_PCIE_MODE));
   3400  1.1.4.2  rmind     log2_width = fls(adap->params.pci.width) - 1;
   3401  1.1.4.2  rmind     acklat = ack_lat[log2_width][pldsize];
   3402  1.1.4.2  rmind     if (val & 1)                            /* check LOsEnable */
   3403  1.1.4.2  rmind         acklat += fst_trn_tx * 4;
   3404  1.1.4.2  rmind     rpllmt = rpl_tmr[log2_width][pldsize] + fst_trn_rx * 4;
   3405  1.1.4.2  rmind 
   3406  1.1.4.2  rmind     if (adap->params.rev == 0)
   3407  1.1.4.2  rmind         t3_set_reg_field(adap, A_PCIE_PEX_CTRL1,
   3408  1.1.4.2  rmind                  V_T3A_ACKLAT(M_T3A_ACKLAT),
   3409  1.1.4.2  rmind                  V_T3A_ACKLAT(acklat));
   3410  1.1.4.2  rmind     else
   3411  1.1.4.2  rmind         t3_set_reg_field(adap, A_PCIE_PEX_CTRL1, V_ACKLAT(M_ACKLAT),
   3412  1.1.4.2  rmind                  V_ACKLAT(acklat));
   3413  1.1.4.2  rmind 
   3414  1.1.4.2  rmind     t3_set_reg_field(adap, A_PCIE_PEX_CTRL0, V_REPLAYLMT(M_REPLAYLMT),
   3415  1.1.4.2  rmind              V_REPLAYLMT(rpllmt));
   3416  1.1.4.2  rmind 
   3417  1.1.4.2  rmind     t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
   3418  1.1.4.2  rmind     t3_set_reg_field(adap, A_PCIE_CFG, F_PCIE_CLIDECEN, F_PCIE_CLIDECEN);
   3419  1.1.4.2  rmind }
   3420  1.1.4.2  rmind 
   3421  1.1.4.2  rmind /**
   3422  1.1.4.2  rmind  *  t3_init_hw - initialize and configure T3 HW modules
   3423  1.1.4.2  rmind  *  @adapter: the adapter
   3424  1.1.4.2  rmind  *  @fw_params: initial parameters to pass to firmware (optional)
   3425  1.1.4.2  rmind  *
   3426  1.1.4.2  rmind  *  Initialize and configure T3 HW modules.  This performs the
   3427  1.1.4.2  rmind  *  initialization steps that need to be done once after a card is reset.
   3428  1.1.4.2  rmind  *  MAC and PHY initialization is handled separarely whenever a port is
   3429  1.1.4.2  rmind  *  enabled.
   3430  1.1.4.2  rmind  *
   3431  1.1.4.2  rmind  *  @fw_params are passed to FW and their value is platform dependent.
   3432  1.1.4.2  rmind  *  Only the top 8 bits are available for use, the rest must be 0.
   3433  1.1.4.2  rmind  */
   3434  1.1.4.2  rmind int t3_init_hw(adapter_t *adapter, u32 fw_params)
   3435  1.1.4.2  rmind {
   3436  1.1.4.2  rmind     int err = -EIO, attempts = 100;
   3437  1.1.4.2  rmind     const struct vpd_params *vpd = &adapter->params.vpd;
   3438  1.1.4.2  rmind 
   3439  1.1.4.2  rmind     if (adapter->params.rev > 0)
   3440  1.1.4.2  rmind         calibrate_xgm_t3b(adapter);
   3441  1.1.4.2  rmind     else if (calibrate_xgm(adapter))
   3442  1.1.4.2  rmind         goto out_err;
   3443  1.1.4.2  rmind 
   3444  1.1.4.2  rmind     if (adapter->params.nports > 2)
   3445  1.1.4.2  rmind         t3_mac_reset(&adap2pinfo(adapter, 0)->mac);
   3446  1.1.4.2  rmind 
   3447  1.1.4.2  rmind     if (vpd->mclk) {
   3448  1.1.4.2  rmind         partition_mem(adapter, &adapter->params.tp);
   3449  1.1.4.2  rmind 
   3450  1.1.4.2  rmind         if (mc7_init(&adapter->pmrx, vpd->mclk, vpd->mem_timing) ||
   3451  1.1.4.2  rmind             mc7_init(&adapter->pmtx, vpd->mclk, vpd->mem_timing) ||
   3452  1.1.4.2  rmind             mc7_init(&adapter->cm, vpd->mclk, vpd->mem_timing) ||
   3453  1.1.4.2  rmind             t3_mc5_init(&adapter->mc5, adapter->params.mc5.nservers,
   3454  1.1.4.2  rmind                     adapter->params.mc5.nfilters,
   3455  1.1.4.2  rmind                     adapter->params.mc5.nroutes))
   3456  1.1.4.2  rmind             goto out_err;
   3457  1.1.4.2  rmind     }
   3458  1.1.4.2  rmind 
   3459  1.1.4.2  rmind     if (tp_init(adapter, &adapter->params.tp))
   3460  1.1.4.2  rmind         goto out_err;
   3461  1.1.4.2  rmind 
   3462  1.1.4.2  rmind #ifdef CONFIG_CHELSIO_T3_CORE
   3463  1.1.4.2  rmind     t3_tp_set_coalescing_size(adapter,
   3464  1.1.4.2  rmind                   min(adapter->params.sge.max_pkt_size,
   3465  1.1.4.2  rmind                       MAX_RX_COALESCING_LEN), 1);
   3466  1.1.4.2  rmind     t3_tp_set_max_rxsize(adapter,
   3467  1.1.4.2  rmind                  min(adapter->params.sge.max_pkt_size, 16384U));
   3468  1.1.4.2  rmind     ulp_config(adapter, &adapter->params.tp);
   3469  1.1.4.2  rmind #endif
   3470  1.1.4.2  rmind     if (is_pcie(adapter))
   3471  1.1.4.2  rmind         config_pcie(adapter);
   3472  1.1.4.2  rmind     else
   3473  1.1.4.2  rmind         t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
   3474  1.1.4.2  rmind 
   3475  1.1.4.2  rmind     t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
   3476  1.1.4.2  rmind     t3_write_reg(adapter, A_PM1_RX_MODE, 0);
   3477  1.1.4.2  rmind     t3_write_reg(adapter, A_PM1_TX_MODE, 0);
   3478  1.1.4.2  rmind     chan_init_hw(adapter, adapter->params.chan_map);
   3479  1.1.4.2  rmind     t3_sge_init(adapter, &adapter->params.sge);
   3480  1.1.4.2  rmind 
   3481  1.1.4.2  rmind     t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params);
   3482  1.1.4.2  rmind     t3_write_reg(adapter, A_CIM_BOOT_CFG,
   3483  1.1.4.2  rmind              V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2));
   3484  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_CIM_BOOT_CFG);    /* flush */
   3485  1.1.4.2  rmind 
   3486  1.1.4.2  rmind     do {                          /* wait for uP to initialize */
   3487  1.1.4.2  rmind         msleep(20);
   3488  1.1.4.2  rmind     } while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
   3489  1.1.4.2  rmind     if (!attempts) {
   3490  1.1.4.2  rmind         CH_ERR(adapter, "uP initialization timed out\n");
   3491  1.1.4.2  rmind         goto out_err;
   3492  1.1.4.2  rmind     }
   3493  1.1.4.2  rmind 
   3494  1.1.4.2  rmind     err = 0;
   3495  1.1.4.2  rmind  out_err:
   3496  1.1.4.2  rmind     return err;
   3497  1.1.4.2  rmind }
   3498  1.1.4.2  rmind 
   3499  1.1.4.2  rmind /**
   3500  1.1.4.2  rmind  *  get_pci_mode - determine a card's PCI mode
   3501  1.1.4.2  rmind  *  @adapter: the adapter
   3502  1.1.4.2  rmind  *  @p: where to store the PCI settings
   3503  1.1.4.2  rmind  *
   3504  1.1.4.2  rmind  *  Determines a card's PCI mode and associated parameters, such as speed
   3505  1.1.4.2  rmind  *  and width.
   3506  1.1.4.2  rmind  */
   3507  1.1.4.2  rmind static void __devinit get_pci_mode(adapter_t *adapter, struct pci_params *p)
   3508  1.1.4.2  rmind {
   3509  1.1.4.2  rmind     static unsigned short speed_map[] = { 33, 66, 100, 133 };
   3510  1.1.4.2  rmind     u32 pcie_mode, pcie_cap;
   3511  1.1.4.2  rmind 
   3512  1.1.4.2  rmind     pcie_cap = t3_os_find_pci_capability(adapter, PCI_CAP_ID_EXP);
   3513  1.1.4.2  rmind     if (pcie_cap) {
   3514  1.1.4.2  rmind         u16 val;
   3515  1.1.4.2  rmind 
   3516  1.1.4.2  rmind         p->variant = PCI_VARIANT_PCIE;
   3517  1.1.4.2  rmind         p->pcie_cap_addr = pcie_cap;
   3518  1.1.4.2  rmind         t3_os_pci_read_config_2(adapter, pcie_cap + PCI_EXP_LNKSTA,
   3519  1.1.4.2  rmind                     &val);
   3520  1.1.4.2  rmind         p->width = (val >> 4) & 0x3f;
   3521  1.1.4.2  rmind         return;
   3522  1.1.4.2  rmind     }
   3523  1.1.4.2  rmind 
   3524  1.1.4.2  rmind     pcie_mode = t3_read_reg(adapter, A_PCIX_MODE);
   3525  1.1.4.2  rmind     p->speed = speed_map[G_PCLKRANGE(pcie_mode)];
   3526  1.1.4.2  rmind     p->width = (pcie_mode & F_64BIT) ? 64 : 32;
   3527  1.1.4.2  rmind     pcie_mode = G_PCIXINITPAT(pcie_mode);
   3528  1.1.4.2  rmind     if (pcie_mode == 0)
   3529  1.1.4.2  rmind         p->variant = PCI_VARIANT_PCI;
   3530  1.1.4.2  rmind     else if (pcie_mode < 4)
   3531  1.1.4.2  rmind         p->variant = PCI_VARIANT_PCIX_MODE1_PARITY;
   3532  1.1.4.2  rmind     else if (pcie_mode < 8)
   3533  1.1.4.2  rmind         p->variant = PCI_VARIANT_PCIX_MODE1_ECC;
   3534  1.1.4.2  rmind     else
   3535  1.1.4.2  rmind         p->variant = PCI_VARIANT_PCIX_266_MODE2;
   3536  1.1.4.2  rmind }
   3537  1.1.4.2  rmind 
   3538  1.1.4.2  rmind /**
   3539  1.1.4.2  rmind  *  init_link_config - initialize a link's SW state
   3540  1.1.4.2  rmind  *  @lc: structure holding the link state
   3541  1.1.4.2  rmind  *  @caps: link capabilities
   3542  1.1.4.2  rmind  *
   3543  1.1.4.2  rmind  *  Initializes the SW state maintained for each link, including the link's
   3544  1.1.4.2  rmind  *  capabilities and default speed/duplex/flow-control/autonegotiation
   3545  1.1.4.2  rmind  *  settings.
   3546  1.1.4.2  rmind  */
   3547  1.1.4.2  rmind static void __devinit init_link_config(struct link_config *lc,
   3548  1.1.4.2  rmind                        unsigned int caps)
   3549  1.1.4.2  rmind {
   3550  1.1.4.2  rmind     lc->supported = caps;
   3551  1.1.4.2  rmind     lc->requested_speed = lc->speed = SPEED_INVALID;
   3552  1.1.4.2  rmind     lc->requested_duplex = lc->duplex = DUPLEX_INVALID;
   3553  1.1.4.2  rmind     lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
   3554  1.1.4.2  rmind     if (lc->supported & SUPPORTED_Autoneg) {
   3555  1.1.4.2  rmind         lc->advertising = lc->supported;
   3556  1.1.4.2  rmind         lc->autoneg = AUTONEG_ENABLE;
   3557  1.1.4.2  rmind         lc->requested_fc |= PAUSE_AUTONEG;
   3558  1.1.4.2  rmind     } else {
   3559  1.1.4.2  rmind         lc->advertising = 0;
   3560  1.1.4.2  rmind         lc->autoneg = AUTONEG_DISABLE;
   3561  1.1.4.2  rmind     }
   3562  1.1.4.2  rmind }
   3563  1.1.4.2  rmind 
   3564  1.1.4.2  rmind /**
   3565  1.1.4.2  rmind  *  mc7_calc_size - calculate MC7 memory size
   3566  1.1.4.2  rmind  *  @cfg: the MC7 configuration
   3567  1.1.4.2  rmind  *
   3568  1.1.4.2  rmind  *  Calculates the size of an MC7 memory in bytes from the value of its
   3569  1.1.4.2  rmind  *  configuration register.
   3570  1.1.4.2  rmind  */
   3571  1.1.4.2  rmind static unsigned int __devinit mc7_calc_size(u32 cfg)
   3572  1.1.4.2  rmind {
   3573  1.1.4.2  rmind     unsigned int width = G_WIDTH(cfg);
   3574  1.1.4.2  rmind     unsigned int banks = !!(cfg & F_BKS) + 1;
   3575  1.1.4.2  rmind     unsigned int org = !!(cfg & F_ORG) + 1;
   3576  1.1.4.2  rmind     unsigned int density = G_DEN(cfg);
   3577  1.1.4.2  rmind     unsigned int MBs = ((256 << density) * banks) / (org << width);
   3578  1.1.4.2  rmind 
   3579  1.1.4.2  rmind     return MBs << 20;
   3580  1.1.4.2  rmind }
   3581  1.1.4.2  rmind 
   3582  1.1.4.2  rmind static void __devinit mc7_prep(adapter_t *adapter, struct mc7 *mc7,
   3583  1.1.4.2  rmind                    unsigned int base_addr, const char *name)
   3584  1.1.4.2  rmind {
   3585  1.1.4.2  rmind     u32 cfg;
   3586  1.1.4.2  rmind 
   3587  1.1.4.2  rmind     mc7->adapter = adapter;
   3588  1.1.4.2  rmind     mc7->name = name;
   3589  1.1.4.2  rmind     mc7->offset = base_addr - MC7_PMRX_BASE_ADDR;
   3590  1.1.4.2  rmind     cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
   3591  1.1.4.2  rmind     mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
   3592  1.1.4.2  rmind     mc7->width = G_WIDTH(cfg);
   3593  1.1.4.2  rmind }
   3594  1.1.4.2  rmind 
   3595  1.1.4.2  rmind void mac_prep(struct cmac *mac, adapter_t *adapter, int index)
   3596  1.1.4.2  rmind {
   3597  1.1.4.2  rmind     mac->adapter = adapter;
   3598  1.1.4.2  rmind     mac->multiport = adapter->params.nports > 2;
   3599  1.1.4.2  rmind     if (mac->multiport) {
   3600  1.1.4.2  rmind         mac->ext_port = (unsigned char)index;
   3601  1.1.4.2  rmind         mac->nucast = 8;
   3602  1.1.4.2  rmind         index = 0;
   3603  1.1.4.2  rmind     } else
   3604  1.1.4.2  rmind         mac->nucast = 1;
   3605  1.1.4.2  rmind 
   3606  1.1.4.2  rmind     mac->offset = (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR) * index;
   3607  1.1.4.2  rmind 
   3608  1.1.4.2  rmind     if (adapter->params.rev == 0 && uses_xaui(adapter)) {
   3609  1.1.4.2  rmind         t3_write_reg(adapter, A_XGM_SERDES_CTRL + mac->offset,
   3610  1.1.4.2  rmind                  is_10G(adapter) ? 0x2901c04 : 0x2301c04);
   3611  1.1.4.2  rmind         t3_set_reg_field(adapter, A_XGM_PORT_CFG + mac->offset,
   3612  1.1.4.2  rmind                  F_ENRGMII, 0);
   3613  1.1.4.2  rmind     }
   3614  1.1.4.2  rmind }
   3615  1.1.4.2  rmind 
   3616  1.1.4.2  rmind /**
   3617  1.1.4.2  rmind  *  early_hw_init - HW initialization done at card detection time
   3618  1.1.4.2  rmind  *  @adapter: the adapter
   3619  1.1.4.2  rmind  *  @ai: contains information about the adapter type and properties
   3620  1.1.4.2  rmind  *
   3621  1.1.4.2  rmind  *  Perfoms the part of HW initialization that is done early on when the
   3622  1.1.4.2  rmind  *  driver first detecs the card.  Most of the HW state is initialized
   3623  1.1.4.2  rmind  *  lazily later on when a port or an offload function are first used.
   3624  1.1.4.2  rmind  */
   3625  1.1.4.2  rmind void early_hw_init(adapter_t *adapter, const struct adapter_info *ai)
   3626  1.1.4.2  rmind {
   3627  1.1.4.2  rmind     u32 val = V_PORTSPEED(is_10G(adapter) || adapter->params.nports > 2 ?
   3628  1.1.4.2  rmind                   3 : 2);
   3629  1.1.4.2  rmind 
   3630  1.1.4.2  rmind     mi1_init(adapter, ai);
   3631  1.1.4.2  rmind     t3_write_reg(adapter, A_I2C_CFG,                  /* set for 80KHz */
   3632  1.1.4.2  rmind              V_I2C_CLKDIV(adapter->params.vpd.cclk / 80 - 1));
   3633  1.1.4.2  rmind     t3_write_reg(adapter, A_T3DBG_GPIO_EN,
   3634  1.1.4.2  rmind              ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
   3635  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
   3636  1.1.4.2  rmind 
   3637  1.1.4.2  rmind     if (adapter->params.rev == 0 || !uses_xaui(adapter))
   3638  1.1.4.2  rmind         val |= F_ENRGMII;
   3639  1.1.4.2  rmind 
   3640  1.1.4.2  rmind     /* Enable MAC clocks so we can access the registers */
   3641  1.1.4.2  rmind     t3_write_reg(adapter, A_XGM_PORT_CFG, val);
   3642  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_XGM_PORT_CFG);
   3643  1.1.4.2  rmind 
   3644  1.1.4.2  rmind     val |= F_CLKDIVRESET_;
   3645  1.1.4.2  rmind     t3_write_reg(adapter, A_XGM_PORT_CFG, val);
   3646  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_XGM_PORT_CFG);
   3647  1.1.4.2  rmind     t3_write_reg(adapter, XGM_REG(A_XGM_PORT_CFG, 1), val);
   3648  1.1.4.2  rmind     (void) t3_read_reg(adapter, A_XGM_PORT_CFG);
   3649  1.1.4.2  rmind }
   3650  1.1.4.2  rmind 
   3651  1.1.4.2  rmind /**
   3652  1.1.4.2  rmind  *  t3_reset_adapter - reset the adapter
   3653  1.1.4.2  rmind  *  @adapter: the adapter
   3654  1.1.4.2  rmind  *
   3655  1.1.4.2  rmind  *  Reset the adapter.
   3656  1.1.4.2  rmind  */
   3657  1.1.4.2  rmind static int t3_reset_adapter(adapter_t *adapter)
   3658  1.1.4.2  rmind {
   3659  1.1.4.2  rmind     int i, save_and_restore_pcie =
   3660  1.1.4.2  rmind         adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
   3661  1.1.4.2  rmind     uint16_t devid = 0;
   3662  1.1.4.2  rmind 
   3663  1.1.4.2  rmind     if (save_and_restore_pcie)
   3664  1.1.4.2  rmind         t3_os_pci_save_state(adapter);
   3665  1.1.4.2  rmind     t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE);
   3666  1.1.4.2  rmind 
   3667  1.1.4.2  rmind     /*
   3668  1.1.4.2  rmind      * Delay. Give Some time to device to reset fully.
   3669  1.1.4.2  rmind      * XXX The delay time should be modified.
   3670  1.1.4.2  rmind      */
   3671  1.1.4.2  rmind     for (i = 0; i < 10; i++) {
   3672  1.1.4.2  rmind         msleep(50);
   3673  1.1.4.2  rmind         t3_os_pci_read_config_2(adapter, 0x00, &devid);
   3674  1.1.4.2  rmind         if (devid == 0x1425)
   3675  1.1.4.2  rmind             break;
   3676  1.1.4.2  rmind     }
   3677  1.1.4.2  rmind 
   3678  1.1.4.2  rmind     if (devid != 0x1425)
   3679  1.1.4.2  rmind         return -1;
   3680  1.1.4.2  rmind 
   3681  1.1.4.2  rmind     if (save_and_restore_pcie)
   3682  1.1.4.2  rmind         t3_os_pci_restore_state(adapter);
   3683  1.1.4.2  rmind     return 0;
   3684  1.1.4.2  rmind }
   3685  1.1.4.2  rmind 
   3686  1.1.4.2  rmind /**
   3687  1.1.4.2  rmind  *  t3_prep_adapter - prepare SW and HW for operation
   3688  1.1.4.2  rmind  *  @adapter: the adapter
   3689  1.1.4.2  rmind  *  @ai: contains information about the adapter type and properties
   3690  1.1.4.2  rmind  *
   3691  1.1.4.2  rmind  *  Initialize adapter SW state for the various HW modules, set initial
   3692  1.1.4.2  rmind  *  values for some adapter tunables, take PHYs out of reset, and
   3693  1.1.4.2  rmind  *  initialize the MDIO interface.
   3694  1.1.4.2  rmind  */
   3695  1.1.4.2  rmind int __devinit t3_prep_adapter(adapter_t *adapter,
   3696  1.1.4.2  rmind                   const struct adapter_info *ai, int reset)
   3697  1.1.4.2  rmind {
   3698  1.1.4.2  rmind     int ret;
   3699  1.1.4.2  rmind     unsigned int i, j = 0;
   3700  1.1.4.2  rmind 
   3701  1.1.4.2  rmind     get_pci_mode(adapter, &adapter->params.pci);
   3702  1.1.4.2  rmind 
   3703  1.1.4.2  rmind     adapter->params.info = ai;
   3704  1.1.4.2  rmind     adapter->params.nports = ai->nports0 + ai->nports1;
   3705  1.1.4.2  rmind     adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1);
   3706  1.1.4.2  rmind     adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
   3707  1.1.4.2  rmind     adapter->params.linkpoll_period = 0;
   3708  1.1.4.2  rmind     if (adapter->params.nports > 2)
   3709  1.1.4.2  rmind         adapter->params.stats_update_period = VSC_STATS_ACCUM_SECS;
   3710  1.1.4.2  rmind     else
   3711  1.1.4.2  rmind         adapter->params.stats_update_period = is_10G(adapter) ?
   3712  1.1.4.2  rmind             MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
   3713  1.1.4.2  rmind     adapter->params.pci.vpd_cap_addr =
   3714  1.1.4.2  rmind         t3_os_find_pci_capability(adapter, PCI_CAP_ID_VPD);
   3715  1.1.4.2  rmind 
   3716  1.1.4.2  rmind     ret = get_vpd_params(adapter, &adapter->params.vpd);
   3717  1.1.4.2  rmind     if (ret < 0)
   3718  1.1.4.2  rmind         return ret;
   3719  1.1.4.2  rmind 
   3720  1.1.4.2  rmind     if (reset && t3_reset_adapter(adapter))
   3721  1.1.4.2  rmind         return -1;
   3722  1.1.4.2  rmind 
   3723  1.1.4.2  rmind     t3_sge_prep(adapter, &adapter->params.sge);
   3724  1.1.4.2  rmind 
   3725  1.1.4.2  rmind     if (adapter->params.vpd.mclk) {
   3726  1.1.4.2  rmind         struct tp_params *p = &adapter->params.tp;
   3727  1.1.4.2  rmind 
   3728  1.1.4.2  rmind         mc7_prep(adapter, &adapter->pmrx, MC7_PMRX_BASE_ADDR, "PMRX");
   3729  1.1.4.2  rmind         mc7_prep(adapter, &adapter->pmtx, MC7_PMTX_BASE_ADDR, "PMTX");
   3730  1.1.4.2  rmind         mc7_prep(adapter, &adapter->cm, MC7_CM_BASE_ADDR, "CM");
   3731  1.1.4.2  rmind 
   3732  1.1.4.2  rmind         p->nchan = adapter->params.chan_map == 3 ? 2 : 1;
   3733  1.1.4.2  rmind         p->pmrx_size = t3_mc7_size(&adapter->pmrx);
   3734  1.1.4.2  rmind         p->pmtx_size = t3_mc7_size(&adapter->pmtx);
   3735  1.1.4.2  rmind         p->cm_size = t3_mc7_size(&adapter->cm);
   3736  1.1.4.2  rmind         p->chan_rx_size = p->pmrx_size / 2;     /* only 1 Rx channel */
   3737  1.1.4.2  rmind         p->chan_tx_size = p->pmtx_size / p->nchan;
   3738  1.1.4.2  rmind         p->rx_pg_size = 64 * 1024;
   3739  1.1.4.2  rmind         p->tx_pg_size = is_10G(adapter) ? 64 * 1024 : 16 * 1024;
   3740  1.1.4.2  rmind         p->rx_num_pgs = pm_num_pages(p->chan_rx_size, p->rx_pg_size);
   3741  1.1.4.2  rmind         p->tx_num_pgs = pm_num_pages(p->chan_tx_size, p->tx_pg_size);
   3742  1.1.4.2  rmind         p->ntimer_qs = p->cm_size >= (128 << 20) ||
   3743  1.1.4.2  rmind                    adapter->params.rev > 0 ? 12 : 6;
   3744  1.1.4.2  rmind         p->tre = fls(adapter->params.vpd.cclk / (1000 / TP_TMR_RES)) -
   3745  1.1.4.2  rmind              1;
   3746  1.1.4.2  rmind         p->dack_re = fls(adapter->params.vpd.cclk / 10) - 1; /* 100us */
   3747  1.1.4.2  rmind     }
   3748  1.1.4.2  rmind 
   3749  1.1.4.2  rmind     adapter->params.offload = t3_mc7_size(&adapter->pmrx) &&
   3750  1.1.4.2  rmind                   t3_mc7_size(&adapter->pmtx) &&
   3751  1.1.4.2  rmind                   t3_mc7_size(&adapter->cm);
   3752  1.1.4.2  rmind 
   3753  1.1.4.2  rmind     if (is_offload(adapter)) {
   3754  1.1.4.2  rmind         adapter->params.mc5.nservers = DEFAULT_NSERVERS;
   3755  1.1.4.2  rmind         adapter->params.mc5.nfilters = adapter->params.rev > 0 ?
   3756  1.1.4.2  rmind                            DEFAULT_NFILTERS : 0;
   3757  1.1.4.2  rmind         adapter->params.mc5.nroutes = 0;
   3758  1.1.4.2  rmind         t3_mc5_prep(adapter, &adapter->mc5, MC5_MODE_144_BIT);
   3759  1.1.4.2  rmind 
   3760  1.1.4.2  rmind #ifdef CONFIG_CHELSIO_T3_CORE
   3761  1.1.4.2  rmind         init_mtus(adapter->params.mtus);
   3762  1.1.4.2  rmind         init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
   3763  1.1.4.2  rmind #endif
   3764  1.1.4.2  rmind     }
   3765  1.1.4.2  rmind 
   3766  1.1.4.2  rmind     early_hw_init(adapter, ai);
   3767  1.1.4.2  rmind 
   3768  1.1.4.2  rmind     if (adapter->params.nports > 2 &&
   3769  1.1.4.2  rmind         (ret = t3_vsc7323_init(adapter, adapter->params.nports)))
   3770  1.1.4.2  rmind         return ret;
   3771  1.1.4.2  rmind 
   3772  1.1.4.2  rmind     for_each_port(adapter, i) {
   3773  1.1.4.2  rmind         u8 hw_addr[6];
   3774  1.1.4.2  rmind         struct port_info *p = adap2pinfo(adapter, i);
   3775  1.1.4.2  rmind 
   3776  1.1.4.2  rmind         while (!adapter->params.vpd.port_type[j])
   3777  1.1.4.2  rmind             ++j;
   3778  1.1.4.2  rmind 
   3779  1.1.4.2  rmind         p->port_type = &port_types[adapter->params.vpd.port_type[j]];
   3780  1.1.4.2  rmind         p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
   3781  1.1.4.2  rmind                        ai->mdio_ops);
   3782  1.1.4.2  rmind         mac_prep(&p->mac, adapter, j);
   3783  1.1.4.2  rmind         ++j;
   3784  1.1.4.2  rmind 
   3785  1.1.4.2  rmind         /*
   3786  1.1.4.2  rmind          * The VPD EEPROM stores the base Ethernet address for the
   3787  1.1.4.2  rmind          * card.  A port's address is derived from the base by adding
   3788  1.1.4.2  rmind          * the port's index to the base's low octet.
   3789  1.1.4.2  rmind          */
   3790  1.1.4.2  rmind         memcpy(hw_addr, adapter->params.vpd.eth_base, 5);
   3791  1.1.4.2  rmind         hw_addr[5] = adapter->params.vpd.eth_base[5] + i;
   3792  1.1.4.2  rmind 
   3793  1.1.4.2  rmind         t3_os_set_hw_addr(adapter, i, hw_addr);
   3794  1.1.4.2  rmind         init_link_config(&p->link_config, p->port_type->caps);
   3795  1.1.4.2  rmind         p->phy.ops->power_down(&p->phy, 1);
   3796  1.1.4.2  rmind         if (!(p->port_type->caps & SUPPORTED_IRQ))
   3797  1.1.4.2  rmind             adapter->params.linkpoll_period = 10;
   3798  1.1.4.2  rmind     }
   3799  1.1.4.2  rmind 
   3800  1.1.4.2  rmind     return 0;
   3801  1.1.4.2  rmind }
   3802  1.1.4.2  rmind 
   3803  1.1.4.2  rmind void t3_led_ready(adapter_t *adapter)
   3804  1.1.4.2  rmind {
   3805  1.1.4.2  rmind     t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
   3806  1.1.4.2  rmind              F_GPIO0_OUT_VAL);
   3807  1.1.4.2  rmind }
   3808  1.1.4.2  rmind 
   3809  1.1.4.2  rmind void t3_port_failover(adapter_t *adapter, int port)
   3810  1.1.4.2  rmind {
   3811  1.1.4.2  rmind     u32 val;
   3812  1.1.4.2  rmind 
   3813  1.1.4.2  rmind     val = port ? F_PORT1ACTIVE : F_PORT0ACTIVE;
   3814  1.1.4.2  rmind     t3_set_reg_field(adapter, A_MPS_CFG, F_PORT0ACTIVE | F_PORT1ACTIVE,
   3815  1.1.4.2  rmind              val);
   3816  1.1.4.2  rmind }
   3817  1.1.4.2  rmind 
   3818  1.1.4.2  rmind void t3_failover_done(adapter_t *adapter, int port)
   3819  1.1.4.2  rmind {
   3820  1.1.4.2  rmind     t3_set_reg_field(adapter, A_MPS_CFG, F_PORT0ACTIVE | F_PORT1ACTIVE,
   3821  1.1.4.2  rmind              F_PORT0ACTIVE | F_PORT1ACTIVE);
   3822  1.1.4.2  rmind }
   3823  1.1.4.2  rmind 
   3824  1.1.4.2  rmind void t3_failover_clear(adapter_t *adapter)
   3825  1.1.4.2  rmind {
   3826  1.1.4.2  rmind     t3_set_reg_field(adapter, A_MPS_CFG, F_PORT0ACTIVE | F_PORT1ACTIVE,
   3827  1.1.4.2  rmind              F_PORT0ACTIVE | F_PORT1ACTIVE);
   3828  1.1.4.2  rmind }
   3829