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