Home | History | Annotate | Line # | Download | only in cxgb
cxgb_mc5.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_mc5.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 #ifdef CONFIG_DEFINED
     34  1.1.4.2  rmind #include <common/cxgb_common.h>
     35  1.1.4.2  rmind #include <common/cxgb_regs.h>
     36  1.1.4.2  rmind #else
     37  1.1.4.2  rmind #include <dev/pci/cxgb/cxgb_common.h>
     38  1.1.4.2  rmind #include <dev/pci/cxgb/cxgb_regs.h>
     39  1.1.4.2  rmind #endif
     40  1.1.4.2  rmind 
     41  1.1.4.2  rmind enum {
     42  1.1.4.2  rmind     IDT75P52100 = 4,
     43  1.1.4.2  rmind     IDT75N43102 = 5
     44  1.1.4.2  rmind };
     45  1.1.4.2  rmind 
     46  1.1.4.2  rmind /* DBGI command mode */
     47  1.1.4.2  rmind enum {
     48  1.1.4.2  rmind     DBGI_MODE_MBUS = 0,
     49  1.1.4.2  rmind     DBGI_MODE_IDT52100 = 5
     50  1.1.4.2  rmind };
     51  1.1.4.2  rmind 
     52  1.1.4.2  rmind /* IDT 75P52100 commands */
     53  1.1.4.2  rmind #define IDT_CMD_READ   0
     54  1.1.4.2  rmind #define IDT_CMD_WRITE  1
     55  1.1.4.2  rmind #define IDT_CMD_SEARCH 2
     56  1.1.4.2  rmind #define IDT_CMD_LEARN  3
     57  1.1.4.2  rmind 
     58  1.1.4.2  rmind /* IDT LAR register address and value for 144-bit mode (low 32 bits) */
     59  1.1.4.2  rmind #define IDT_LAR_ADR0    0x180006
     60  1.1.4.2  rmind #define IDT_LAR_MODE144 0xffff0000
     61  1.1.4.2  rmind 
     62  1.1.4.2  rmind /* IDT SCR and SSR addresses (low 32 bits) */
     63  1.1.4.2  rmind #define IDT_SCR_ADR0  0x180000
     64  1.1.4.2  rmind #define IDT_SSR0_ADR0 0x180002
     65  1.1.4.2  rmind #define IDT_SSR1_ADR0 0x180004
     66  1.1.4.2  rmind 
     67  1.1.4.2  rmind /* IDT GMR base address (low 32 bits) */
     68  1.1.4.2  rmind #define IDT_GMR_BASE_ADR0 0x180020
     69  1.1.4.2  rmind 
     70  1.1.4.2  rmind /* IDT data and mask array base addresses (low 32 bits) */
     71  1.1.4.2  rmind #define IDT_DATARY_BASE_ADR0 0
     72  1.1.4.2  rmind #define IDT_MSKARY_BASE_ADR0 0x80000
     73  1.1.4.2  rmind 
     74  1.1.4.2  rmind /* IDT 75N43102 commands */
     75  1.1.4.2  rmind #define IDT4_CMD_SEARCH144 3
     76  1.1.4.2  rmind #define IDT4_CMD_WRITE     4
     77  1.1.4.2  rmind #define IDT4_CMD_READ      5
     78  1.1.4.2  rmind 
     79  1.1.4.2  rmind /* IDT 75N43102 SCR address (low 32 bits) */
     80  1.1.4.2  rmind #define IDT4_SCR_ADR0  0x3
     81  1.1.4.2  rmind 
     82  1.1.4.2  rmind /* IDT 75N43102 GMR base addresses (low 32 bits) */
     83  1.1.4.2  rmind #define IDT4_GMR_BASE0 0x10
     84  1.1.4.2  rmind #define IDT4_GMR_BASE1 0x20
     85  1.1.4.2  rmind #define IDT4_GMR_BASE2 0x30
     86  1.1.4.2  rmind 
     87  1.1.4.2  rmind /* IDT 75N43102 data and mask array base addresses (low 32 bits) */
     88  1.1.4.2  rmind #define IDT4_DATARY_BASE_ADR0 0x1000000
     89  1.1.4.2  rmind #define IDT4_MSKARY_BASE_ADR0 0x2000000
     90  1.1.4.2  rmind 
     91  1.1.4.2  rmind #define MAX_WRITE_ATTEMPTS 5
     92  1.1.4.2  rmind 
     93  1.1.4.2  rmind #define MAX_ROUTES 2048
     94  1.1.4.2  rmind 
     95  1.1.4.2  rmind /*
     96  1.1.4.2  rmind  * Issue a command to the TCAM and wait for its completion.  The address and
     97  1.1.4.2  rmind  * any data required by the command must have been setup by the caller.
     98  1.1.4.2  rmind  */
     99  1.1.4.2  rmind static int mc5_cmd_write(adapter_t *adapter, u32 cmd)
    100  1.1.4.2  rmind {
    101  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_CMD, cmd);
    102  1.1.4.2  rmind     return t3_wait_op_done(adapter, A_MC5_DB_DBGI_RSP_STATUS,
    103  1.1.4.2  rmind                    F_DBGIRSPVALID, 1, MAX_WRITE_ATTEMPTS, 1);
    104  1.1.4.2  rmind }
    105  1.1.4.2  rmind 
    106  1.1.4.2  rmind static inline void dbgi_wr_addr3(adapter_t *adapter, u32 v1, u32 v2, u32 v3)
    107  1.1.4.2  rmind {
    108  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, v1);
    109  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR1, v2);
    110  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR2, v3);
    111  1.1.4.2  rmind }
    112  1.1.4.2  rmind 
    113  1.1.4.2  rmind static inline void dbgi_wr_data3(adapter_t *adapter, u32 v1, u32 v2, u32 v3)
    114  1.1.4.2  rmind {
    115  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA0, v1);
    116  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA1, v2);
    117  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA2, v3);
    118  1.1.4.2  rmind }
    119  1.1.4.2  rmind 
    120  1.1.4.2  rmind static inline void dbgi_rd_rsp3(adapter_t *adapter, u32 *v1, u32 *v2, u32 *v3)
    121  1.1.4.2  rmind {
    122  1.1.4.2  rmind     *v1 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA0);
    123  1.1.4.2  rmind     *v2 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA1);
    124  1.1.4.2  rmind     *v3 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA2);
    125  1.1.4.2  rmind }
    126  1.1.4.2  rmind 
    127  1.1.4.2  rmind /*
    128  1.1.4.2  rmind  * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM
    129  1.1.4.2  rmind  * command cmd.  The data to be written must have been set up by the caller.
    130  1.1.4.2  rmind  * Returns -1 on failure, 0 on success.
    131  1.1.4.2  rmind  */
    132  1.1.4.2  rmind static int mc5_write(adapter_t *adapter, u32 addr_lo, u32 cmd)
    133  1.1.4.2  rmind {
    134  1.1.4.2  rmind     t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, addr_lo);
    135  1.1.4.2  rmind     if (mc5_cmd_write(adapter, cmd) == 0)
    136  1.1.4.2  rmind         return 0;
    137  1.1.4.2  rmind     CH_ERR(adapter, "MC5 timeout writing to TCAM address 0x%x\n", addr_lo);
    138  1.1.4.2  rmind     return -1;
    139  1.1.4.2  rmind }
    140  1.1.4.2  rmind 
    141  1.1.4.2  rmind static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base,
    142  1.1.4.2  rmind                 u32 data_array_base, u32 write_cmd,
    143  1.1.4.2  rmind                     int addr_shift)
    144  1.1.4.2  rmind {
    145  1.1.4.2  rmind     unsigned int i;
    146  1.1.4.2  rmind     adapter_t *adap = mc5->adapter;
    147  1.1.4.2  rmind 
    148  1.1.4.2  rmind     /*
    149  1.1.4.2  rmind      * We need the size of the TCAM data and mask arrays in terms of
    150  1.1.4.2  rmind      * 72-bit entries.
    151  1.1.4.2  rmind      */
    152  1.1.4.2  rmind     unsigned int size72 = mc5->tcam_size;
    153  1.1.4.2  rmind     unsigned int server_base = t3_read_reg(adap, A_MC5_DB_SERVER_INDEX);
    154  1.1.4.2  rmind 
    155  1.1.4.2  rmind     if (mc5->mode == MC5_MODE_144_BIT) {
    156  1.1.4.2  rmind         size72 *= 2;      /* 1 144-bit entry is 2 72-bit entries */
    157  1.1.4.2  rmind         server_base *= 2;
    158  1.1.4.2  rmind     }
    159  1.1.4.2  rmind 
    160  1.1.4.2  rmind     /* Clear the data array */
    161  1.1.4.2  rmind     dbgi_wr_data3(adap, 0, 0, 0);
    162  1.1.4.2  rmind     for (i = 0; i < size72; i++)
    163  1.1.4.2  rmind         if (mc5_write(adap, data_array_base + (i << addr_shift),
    164  1.1.4.2  rmind                   write_cmd))
    165  1.1.4.2  rmind             return -1;
    166  1.1.4.2  rmind 
    167  1.1.4.2  rmind     /* Initialize the mask array. */
    168  1.1.4.2  rmind     for (i = 0; i < server_base; i++) {
    169  1.1.4.2  rmind         dbgi_wr_data3(adap, 0x3fffffff, 0xfff80000, 0xff);
    170  1.1.4.2  rmind         if (mc5_write(adap, mask_array_base + (i << addr_shift),
    171  1.1.4.2  rmind                   write_cmd))
    172  1.1.4.2  rmind             return -1;
    173  1.1.4.2  rmind         i++;
    174  1.1.4.2  rmind         dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
    175  1.1.4.2  rmind         if (mc5_write(adap, mask_array_base + (i << addr_shift),
    176  1.1.4.2  rmind                   write_cmd))
    177  1.1.4.2  rmind             return -1;
    178  1.1.4.2  rmind     }
    179  1.1.4.2  rmind 
    180  1.1.4.2  rmind     dbgi_wr_data3(adap,
    181  1.1.4.2  rmind               mc5->mode == MC5_MODE_144_BIT ? 0xfffffff9 : 0xfffffffd,
    182  1.1.4.2  rmind               0xffffffff, 0xff);
    183  1.1.4.2  rmind     for (; i < size72; i++)
    184  1.1.4.2  rmind         if (mc5_write(adap, mask_array_base + (i << addr_shift),
    185  1.1.4.2  rmind                   write_cmd))
    186  1.1.4.2  rmind             return -1;
    187  1.1.4.2  rmind 
    188  1.1.4.2  rmind     return 0;
    189  1.1.4.2  rmind }
    190  1.1.4.2  rmind 
    191  1.1.4.2  rmind static int init_idt52100(struct mc5 *mc5)
    192  1.1.4.2  rmind {
    193  1.1.4.2  rmind     int i;
    194  1.1.4.2  rmind     adapter_t *adap = mc5->adapter;
    195  1.1.4.2  rmind 
    196  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_RSP_LATENCY,
    197  1.1.4.2  rmind              V_RDLAT(0x15) | V_LRNLAT(0x15) | V_SRCHLAT(0x15));
    198  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 2);
    199  1.1.4.2  rmind 
    200  1.1.4.2  rmind     /*
    201  1.1.4.2  rmind      * Use GMRs 14-15 for ELOOKUP, GMRs 12-13 for SYN lookups, and
    202  1.1.4.2  rmind      * GMRs 8-9 for ACK- and AOPEN searches.
    203  1.1.4.2  rmind      */
    204  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT_CMD_WRITE);
    205  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT_CMD_WRITE);
    206  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, IDT_CMD_SEARCH);
    207  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_AOPEN_LRN_CMD, IDT_CMD_LEARN);
    208  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT_CMD_SEARCH | 0x6000);
    209  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_SYN_LRN_CMD, IDT_CMD_LEARN);
    210  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT_CMD_SEARCH);
    211  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ACK_LRN_CMD, IDT_CMD_LEARN);
    212  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT_CMD_SEARCH);
    213  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT_CMD_SEARCH | 0x7000);
    214  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT_CMD_WRITE);
    215  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT_CMD_READ);
    216  1.1.4.2  rmind 
    217  1.1.4.2  rmind     /* Set DBGI command mode for IDT TCAM. */
    218  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100);
    219  1.1.4.2  rmind 
    220  1.1.4.2  rmind     /* Set up LAR */
    221  1.1.4.2  rmind     dbgi_wr_data3(adap, IDT_LAR_MODE144, 0, 0);
    222  1.1.4.2  rmind     if (mc5_write(adap, IDT_LAR_ADR0, IDT_CMD_WRITE))
    223  1.1.4.2  rmind         goto err;
    224  1.1.4.2  rmind 
    225  1.1.4.2  rmind     /* Set up SSRs */
    226  1.1.4.2  rmind     dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0);
    227  1.1.4.2  rmind     if (mc5_write(adap, IDT_SSR0_ADR0, IDT_CMD_WRITE) ||
    228  1.1.4.2  rmind         mc5_write(adap, IDT_SSR1_ADR0, IDT_CMD_WRITE))
    229  1.1.4.2  rmind         goto err;
    230  1.1.4.2  rmind 
    231  1.1.4.2  rmind     /* Set up GMRs */
    232  1.1.4.2  rmind     for (i = 0; i < 32; ++i) {
    233  1.1.4.2  rmind         if (i >= 12 && i < 15)
    234  1.1.4.2  rmind             dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
    235  1.1.4.2  rmind         else if (i == 15)
    236  1.1.4.2  rmind             dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
    237  1.1.4.2  rmind         else
    238  1.1.4.2  rmind             dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
    239  1.1.4.2  rmind 
    240  1.1.4.2  rmind         if (mc5_write(adap, IDT_GMR_BASE_ADR0 + i, IDT_CMD_WRITE))
    241  1.1.4.2  rmind             goto err;
    242  1.1.4.2  rmind     }
    243  1.1.4.2  rmind 
    244  1.1.4.2  rmind     /* Set up SCR */
    245  1.1.4.2  rmind     dbgi_wr_data3(adap, 1, 0, 0);
    246  1.1.4.2  rmind     if (mc5_write(adap, IDT_SCR_ADR0, IDT_CMD_WRITE))
    247  1.1.4.2  rmind         goto err;
    248  1.1.4.2  rmind 
    249  1.1.4.2  rmind     return init_mask_data_array(mc5, IDT_MSKARY_BASE_ADR0,
    250  1.1.4.2  rmind                     IDT_DATARY_BASE_ADR0, IDT_CMD_WRITE, 0);
    251  1.1.4.2  rmind  err:
    252  1.1.4.2  rmind     return -EIO;
    253  1.1.4.2  rmind }
    254  1.1.4.2  rmind 
    255  1.1.4.2  rmind static int init_idt43102(struct mc5 *mc5)
    256  1.1.4.2  rmind {
    257  1.1.4.2  rmind     int i;
    258  1.1.4.2  rmind     adapter_t *adap = mc5->adapter;
    259  1.1.4.2  rmind 
    260  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_RSP_LATENCY,
    261  1.1.4.2  rmind              adap->params.rev == 0 ? V_RDLAT(0xd) | V_SRCHLAT(0x11) :
    262  1.1.4.2  rmind                          V_RDLAT(0xd) | V_SRCHLAT(0x12));
    263  1.1.4.2  rmind 
    264  1.1.4.2  rmind     /*
    265  1.1.4.2  rmind      * Use GMRs 24-25 for ELOOKUP, GMRs 20-21 for SYN lookups, and no mask
    266  1.1.4.2  rmind      * for ACK- and AOPEN searches.
    267  1.1.4.2  rmind      */
    268  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT4_CMD_WRITE);
    269  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT4_CMD_WRITE);
    270  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD,
    271  1.1.4.2  rmind              IDT4_CMD_SEARCH144 | 0x3800);
    272  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT4_CMD_SEARCH144);
    273  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT4_CMD_SEARCH144 | 0x3800);
    274  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x3800);
    275  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x800);
    276  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT4_CMD_WRITE);
    277  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT4_CMD_READ);
    278  1.1.4.2  rmind 
    279  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 3);
    280  1.1.4.2  rmind 
    281  1.1.4.2  rmind     /* Set DBGI command mode for IDT TCAM. */
    282  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100);
    283  1.1.4.2  rmind 
    284  1.1.4.2  rmind     /* Set up GMRs */
    285  1.1.4.2  rmind     dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
    286  1.1.4.2  rmind     for (i = 0; i < 7; ++i)
    287  1.1.4.2  rmind         if (mc5_write(adap, IDT4_GMR_BASE0 + i, IDT4_CMD_WRITE))
    288  1.1.4.2  rmind             goto err;
    289  1.1.4.2  rmind 
    290  1.1.4.2  rmind     for (i = 0; i < 4; ++i)
    291  1.1.4.2  rmind         if (mc5_write(adap, IDT4_GMR_BASE2 + i, IDT4_CMD_WRITE))
    292  1.1.4.2  rmind             goto err;
    293  1.1.4.2  rmind 
    294  1.1.4.2  rmind     dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
    295  1.1.4.2  rmind     if (mc5_write(adap, IDT4_GMR_BASE1, IDT4_CMD_WRITE) ||
    296  1.1.4.2  rmind         mc5_write(adap, IDT4_GMR_BASE1 + 1, IDT4_CMD_WRITE) ||
    297  1.1.4.2  rmind         mc5_write(adap, IDT4_GMR_BASE1 + 4, IDT4_CMD_WRITE))
    298  1.1.4.2  rmind         goto err;
    299  1.1.4.2  rmind 
    300  1.1.4.2  rmind     dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
    301  1.1.4.2  rmind     if (mc5_write(adap, IDT4_GMR_BASE1 + 5, IDT4_CMD_WRITE))
    302  1.1.4.2  rmind         goto err;
    303  1.1.4.2  rmind 
    304  1.1.4.2  rmind     /* Set up SCR */
    305  1.1.4.2  rmind     dbgi_wr_data3(adap, 0xf0000000, 0, 0);
    306  1.1.4.2  rmind     if (mc5_write(adap, IDT4_SCR_ADR0, IDT4_CMD_WRITE))
    307  1.1.4.2  rmind         goto err;
    308  1.1.4.2  rmind 
    309  1.1.4.2  rmind     return init_mask_data_array(mc5, IDT4_MSKARY_BASE_ADR0,
    310  1.1.4.2  rmind                     IDT4_DATARY_BASE_ADR0, IDT4_CMD_WRITE, 1);
    311  1.1.4.2  rmind  err:
    312  1.1.4.2  rmind     return -EIO;
    313  1.1.4.2  rmind }
    314  1.1.4.2  rmind 
    315  1.1.4.2  rmind /* Put MC5 in DBGI mode. */
    316  1.1.4.2  rmind static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5)
    317  1.1.4.2  rmind {
    318  1.1.4.2  rmind     t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_PRTYEN | F_MBUSEN,
    319  1.1.4.2  rmind              F_DBGIEN);
    320  1.1.4.2  rmind }
    321  1.1.4.2  rmind 
    322  1.1.4.2  rmind /* Put MC5 in M-Bus mode. */
    323  1.1.4.2  rmind static void mc5_dbgi_mode_disable(const struct mc5 *mc5)
    324  1.1.4.2  rmind {
    325  1.1.4.2  rmind     t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_DBGIEN,
    326  1.1.4.2  rmind              V_PRTYEN(mc5->parity_enabled) | F_MBUSEN);
    327  1.1.4.2  rmind }
    328  1.1.4.2  rmind 
    329  1.1.4.2  rmind /*
    330  1.1.4.2  rmind  * Initialization that requires the OS and protocol layers to already
    331  1.1.4.2  rmind  * be intialized goes here.
    332  1.1.4.2  rmind  */
    333  1.1.4.2  rmind int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
    334  1.1.4.2  rmind         unsigned int nroutes)
    335  1.1.4.2  rmind {
    336  1.1.4.2  rmind     int err;
    337  1.1.4.2  rmind     unsigned int tcam_size = mc5->tcam_size;
    338  1.1.4.2  rmind     unsigned int mode72 = mc5->mode == MC5_MODE_72_BIT;
    339  1.1.4.2  rmind     adapter_t *adap = mc5->adapter;
    340  1.1.4.2  rmind 
    341  1.1.4.2  rmind     if (!tcam_size)
    342  1.1.4.2  rmind         return 0;
    343  1.1.4.2  rmind 
    344  1.1.4.2  rmind     if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
    345  1.1.4.2  rmind         return -EINVAL;
    346  1.1.4.2  rmind 
    347  1.1.4.2  rmind     if (nfilters && adap->params.rev < T3_REV_C)
    348  1.1.4.2  rmind         mc5->parity_enabled = 0;
    349  1.1.4.2  rmind 
    350  1.1.4.2  rmind     /* Reset the TCAM */
    351  1.1.4.2  rmind     t3_set_reg_field(adap, A_MC5_DB_CONFIG, F_TMMODE | F_COMPEN,
    352  1.1.4.2  rmind              V_COMPEN(mode72) | V_TMMODE(mode72) | F_TMRST);
    353  1.1.4.2  rmind     if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) {
    354  1.1.4.2  rmind         CH_ERR(adap, "TCAM reset timed out\n");
    355  1.1.4.2  rmind         return -1;
    356  1.1.4.2  rmind     }
    357  1.1.4.2  rmind 
    358  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_ROUTING_TABLE_INDEX, tcam_size - nroutes);
    359  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_FILTER_TABLE,
    360  1.1.4.2  rmind              tcam_size - nroutes - nfilters);
    361  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_SERVER_INDEX,
    362  1.1.4.2  rmind              tcam_size - nroutes - nfilters - nservers);
    363  1.1.4.2  rmind 
    364  1.1.4.2  rmind     /* All the TCAM addresses we access have only the low 32 bits non 0 */
    365  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0);
    366  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0);
    367  1.1.4.2  rmind 
    368  1.1.4.2  rmind     mc5_dbgi_mode_enable(mc5);
    369  1.1.4.2  rmind 
    370  1.1.4.2  rmind     switch (mc5->part_type) {
    371  1.1.4.2  rmind     case IDT75P52100:
    372  1.1.4.2  rmind         err = init_idt52100(mc5);
    373  1.1.4.2  rmind         break;
    374  1.1.4.2  rmind     case IDT75N43102:
    375  1.1.4.2  rmind         err = init_idt43102(mc5);
    376  1.1.4.2  rmind         break;
    377  1.1.4.2  rmind     default:
    378  1.1.4.2  rmind         CH_ERR(adap, "Unsupported TCAM type %d\n", mc5->part_type);
    379  1.1.4.2  rmind         err = -EINVAL;
    380  1.1.4.2  rmind         break;
    381  1.1.4.2  rmind     }
    382  1.1.4.2  rmind 
    383  1.1.4.2  rmind     mc5_dbgi_mode_disable(mc5);
    384  1.1.4.2  rmind     return err;
    385  1.1.4.2  rmind }
    386  1.1.4.2  rmind 
    387  1.1.4.2  rmind /*
    388  1.1.4.2  rmind  *  read_mc5_range - dump a part of the memory managed by MC5
    389  1.1.4.2  rmind  *  @mc5: the MC5 handle
    390  1.1.4.2  rmind  *  @start: the start address for the dump
    391  1.1.4.2  rmind  *  @n: number of 72-bit words to read
    392  1.1.4.2  rmind  *  @buf: result buffer
    393  1.1.4.2  rmind  *
    394  1.1.4.2  rmind  *  Read n 72-bit words from MC5 memory from the given start location.
    395  1.1.4.2  rmind  */
    396  1.1.4.2  rmind int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start,
    397  1.1.4.2  rmind               unsigned int n, u32 *buf)
    398  1.1.4.2  rmind {
    399  1.1.4.2  rmind     u32 read_cmd;
    400  1.1.4.2  rmind     int err = 0;
    401  1.1.4.2  rmind     adapter_t *adap = mc5->adapter;
    402  1.1.4.2  rmind 
    403  1.1.4.2  rmind     if (mc5->part_type == IDT75P52100)
    404  1.1.4.2  rmind         read_cmd = IDT_CMD_READ;
    405  1.1.4.2  rmind     else if (mc5->part_type == IDT75N43102)
    406  1.1.4.2  rmind         read_cmd = IDT4_CMD_READ;
    407  1.1.4.2  rmind     else
    408  1.1.4.2  rmind         return -EINVAL;
    409  1.1.4.2  rmind 
    410  1.1.4.2  rmind     mc5_dbgi_mode_enable(mc5);
    411  1.1.4.2  rmind 
    412  1.1.4.2  rmind     while (n--) {
    413  1.1.4.2  rmind         t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++);
    414  1.1.4.2  rmind         if (mc5_cmd_write(adap, read_cmd)) {
    415  1.1.4.2  rmind             err = -EIO;
    416  1.1.4.2  rmind             break;
    417  1.1.4.2  rmind         }
    418  1.1.4.2  rmind         dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf);
    419  1.1.4.2  rmind         buf += 3;
    420  1.1.4.2  rmind     }
    421  1.1.4.2  rmind 
    422  1.1.4.2  rmind     mc5_dbgi_mode_disable(mc5);
    423  1.1.4.2  rmind     return 0;
    424  1.1.4.2  rmind }
    425  1.1.4.2  rmind 
    426  1.1.4.2  rmind #define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR)
    427  1.1.4.2  rmind 
    428  1.1.4.2  rmind /*
    429  1.1.4.2  rmind  * MC5 interrupt handler
    430  1.1.4.2  rmind  */
    431  1.1.4.2  rmind void t3_mc5_intr_handler(struct mc5 *mc5)
    432  1.1.4.2  rmind {
    433  1.1.4.2  rmind     adapter_t *adap = mc5->adapter;
    434  1.1.4.2  rmind     u32 cause = t3_read_reg(adap, A_MC5_DB_INT_CAUSE);
    435  1.1.4.2  rmind 
    436  1.1.4.2  rmind     if ((cause & F_PARITYERR) && mc5->parity_enabled) {
    437  1.1.4.2  rmind         CH_ALERT(adap, "MC5 parity error\n");
    438  1.1.4.2  rmind         mc5->stats.parity_err++;
    439  1.1.4.2  rmind     }
    440  1.1.4.2  rmind 
    441  1.1.4.2  rmind     if (cause & F_REQQPARERR) {
    442  1.1.4.2  rmind         CH_ALERT(adap, "MC5 request queue parity error\n");
    443  1.1.4.2  rmind         mc5->stats.reqq_parity_err++;
    444  1.1.4.2  rmind     }
    445  1.1.4.2  rmind 
    446  1.1.4.2  rmind     if (cause & F_DISPQPARERR) {
    447  1.1.4.2  rmind         CH_ALERT(adap, "MC5 dispatch queue parity error\n");
    448  1.1.4.2  rmind         mc5->stats.dispq_parity_err++;
    449  1.1.4.2  rmind     }
    450  1.1.4.2  rmind 
    451  1.1.4.2  rmind     if (cause & F_ACTRGNFULL)
    452  1.1.4.2  rmind         mc5->stats.active_rgn_full++;
    453  1.1.4.2  rmind     if (cause & F_NFASRCHFAIL)
    454  1.1.4.2  rmind         mc5->stats.nfa_srch_err++;
    455  1.1.4.2  rmind     if (cause & F_UNKNOWNCMD)
    456  1.1.4.2  rmind         mc5->stats.unknown_cmd++;
    457  1.1.4.2  rmind     if (cause & F_DELACTEMPTY)
    458  1.1.4.2  rmind         mc5->stats.del_act_empty++;
    459  1.1.4.2  rmind     if (cause & MC5_INT_FATAL)
    460  1.1.4.2  rmind         t3_fatal_err(adap);
    461  1.1.4.2  rmind 
    462  1.1.4.2  rmind     t3_write_reg(adap, A_MC5_DB_INT_CAUSE, cause);
    463  1.1.4.2  rmind }
    464  1.1.4.2  rmind 
    465  1.1.4.2  rmind void __devinit t3_mc5_prep(adapter_t *adapter, struct mc5 *mc5, int mode)
    466  1.1.4.2  rmind {
    467  1.1.4.2  rmind #define K * 1024
    468  1.1.4.2  rmind 
    469  1.1.4.2  rmind     static unsigned int tcam_part_size[] = {  /* in K 72-bit entries */
    470  1.1.4.2  rmind         64 K, 128 K, 256 K, 32 K
    471  1.1.4.2  rmind     };
    472  1.1.4.2  rmind 
    473  1.1.4.2  rmind #undef K
    474  1.1.4.2  rmind 
    475  1.1.4.2  rmind     u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG);
    476  1.1.4.2  rmind 
    477  1.1.4.2  rmind     mc5->adapter = adapter;
    478  1.1.4.2  rmind     mc5->parity_enabled = 1;
    479  1.1.4.2  rmind     mc5->mode = (unsigned char) mode;
    480  1.1.4.2  rmind     mc5->part_type = (unsigned char) G_TMTYPE(cfg);
    481  1.1.4.2  rmind     if (cfg & F_TMTYPEHI)
    482  1.1.4.2  rmind         mc5->part_type |= 4;
    483  1.1.4.2  rmind 
    484  1.1.4.2  rmind     mc5->tcam_size = tcam_part_size[G_TMPARTSIZE(cfg)];
    485  1.1.4.2  rmind     if (mode == MC5_MODE_144_BIT)
    486  1.1.4.2  rmind         mc5->tcam_size /= 2;
    487  1.1.4.2  rmind }
    488