Print this page
NEX-5717 import QLogic 16G FC drivers
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/fibre-channel/fca/qlc/ql_nx.c
+++ new/usr/src/uts/common/io/fibre-channel/fca/qlc/ql_nx.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 - * Copyright 2010 QLogic Corporation. All rights reserved.
23 + * Copyright 2015 QLogic Corporation. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "Copyright 2010 QLogic Corporation; ql_nx.c"
27 +#pragma ident "Copyright 2015 QLogic Corporation; ql_nx.c"
28 28
29 29 /*
30 30 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
31 31 *
32 32 * ***********************************************************************
33 33 * * **
34 34 * * NOTICE **
35 - * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
35 + * * COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION **
36 36 * * ALL RIGHTS RESERVED **
37 37 * * **
38 38 * ***********************************************************************
39 39 *
40 40 */
41 41
42 42 #include <ql_apps.h>
43 43 #include <ql_api.h>
44 44 #include <ql_debug.h>
45 +#include <ql_init.h>
45 46 #include <ql_mbx.h>
46 47 #include <ql_nx.h>
47 48
48 49 /*
49 50 * Local Function Prototypes.
50 51 */
51 -static void *ql_8021_pci_base_offsetfset(ql_adapter_state_t *, uint64_t);
52 52 static void ql_crb_addr_transform_setup(ql_adapter_state_t *);
53 53 static void ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *, uint64_t *);
54 -static void ql_8021_wr_32(ql_adapter_state_t *, uint64_t, uint32_t);
55 -static void ql_8021_rd_32(ql_adapter_state_t *, uint64_t, uint32_t *);
56 54 static int ql_8021_crb_win_lock(ql_adapter_state_t *);
57 55 static void ql_8021_crb_win_unlock(ql_adapter_state_t *);
58 56 static int ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *, uint64_t *);
59 57 static uint32_t ql_8021_pci_mem_bound_check(ql_adapter_state_t *, uint64_t,
60 58 uint32_t);
61 59 static uint64_t ql_8021_pci_set_window(ql_adapter_state_t *, uint64_t);
62 60 static int ql_8021_pci_is_same_window(ql_adapter_state_t *, uint64_t);
63 61 static int ql_8021_pci_mem_read_direct(ql_adapter_state_t *, uint64_t, void *,
64 62 uint32_t);
65 63 static int ql_8021_pci_mem_write_direct(ql_adapter_state_t *, uint64_t, void *,
66 64 uint32_t);
67 65 static int ql_8021_pci_mem_read_2M(ql_adapter_state_t *, uint64_t, void *,
68 66 uint32_t);
69 67 static int ql_8021_pci_mem_write_2M(ql_adapter_state_t *, uint64_t, void *,
70 68 uint32_t);
71 69 static uint32_t ql_8021_decode_crb_addr(ql_adapter_state_t *, uint32_t);
72 70 static int ql_8021_rom_lock(ql_adapter_state_t *);
73 71 static void ql_8021_rom_unlock(ql_adapter_state_t *);
74 72 static int ql_8021_wait_rom_done(ql_adapter_state_t *);
75 73 static int ql_8021_wait_flash_done(ql_adapter_state_t *);
76 74 static int ql_8021_do_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
77 75 static int ql_8021_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
78 76 static int ql_8021_do_rom_write(ql_adapter_state_t *, uint32_t, uint32_t);
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
79 77 static int ql_8021_do_rom_erase(ql_adapter_state_t *, uint32_t);
80 78 static int ql_8021_phantom_init(ql_adapter_state_t *);
81 79 static int ql_8021_pinit_from_rom(ql_adapter_state_t *);
82 80 static int ql_8021_load_from_flash(ql_adapter_state_t *);
83 81 static int ql_8021_load_firmware(ql_adapter_state_t *);
84 82 static int ql_8021_reset_hw(ql_adapter_state_t *, int);
85 83 static int ql_8021_init_p3p(ql_adapter_state_t *);
86 84 static int ql_8021_hw_lock(ql_adapter_state_t *, uint32_t);
87 85 static void ql_8021_hw_unlock(ql_adapter_state_t *);
88 86 static void ql_8021_need_reset_handler(ql_adapter_state_t *);
87 +static int ql_8021_load_fw(ql_adapter_state_t *);
88 +static uint32_t ql_8021_check_fw_alive(ql_adapter_state_t *);
89 +static int ql_8021_get_fw_dump(ql_adapter_state_t *);
90 +static void ql_8021_md_parse_template(ql_adapter_state_t *, caddr_t, caddr_t,
91 + uint32_t, uint32_t);
92 +static int ql_8021_md_rdcrb(ql_adapter_state_t *, md_entry_rdcrb_t *,
93 + uint32_t *);
94 +static int ql_8021_md_L2Cache(ql_adapter_state_t *, md_entry_cache_t *,
95 + uint32_t *);
96 +static int ql_8021_md_L1Cache(ql_adapter_state_t *, md_entry_cache_t *,
97 + uint32_t *);
98 +static int ql_8021_md_rdocm(ql_adapter_state_t *, md_entry_rdocm_t *,
99 + uint32_t *);
100 +static int ql_8021_md_rdmem(ql_adapter_state_t *, md_entry_rdmem_t *,
101 + uint32_t *);
102 +static int ql_8021_md_rdrom(ql_adapter_state_t *, md_entry_rdrom_t *,
103 + uint32_t *);
104 +static int ql_8021_md_rdmux(ql_adapter_state_t *, md_entry_mux_t *,
105 + uint32_t *);
106 +static int ql_8021_md_rdqueue(ql_adapter_state_t *, md_entry_queue_t *,
107 + uint32_t *);
108 +static int ql_8021_md_cntrl(ql_adapter_state_t *, md_template_hdr_t *,
109 + md_entry_cntrl_t *);
110 +static void ql_8021_md_entry_err_chk(ql_adapter_state_t *, md_entry_t *,
111 + uint32_t, int);
112 +static uint32_t ql_8021_md_template_checksum(ql_adapter_state_t *);
113 +static uint32_t ql_8021_read_reg(ql_adapter_state_t *, uint32_t);
114 +static void ql_8021_write_reg(ql_adapter_state_t *, uint32_t, uint32_t);
115 +static uint32_t ql_8021_read_ocm(ql_adapter_state_t *, uint32_t);
89 116
90 117 /*
91 118 * Local Data.
92 119 */
93 120 static uint32_t crb_addr_xform[MAX_CRB_XFORM];
94 121 static int crb_table_initialized = 0;
95 122 static int pci_set_window_warning_count = 0;
96 123
97 124 static struct legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
98 125
99 126 static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
100 127 {{{0, 0, 0, 0}}}, /* 0: PCI */
101 128 {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
102 129 {1, 0x0110000, 0x0120000, 0x130000},
103 130 {1, 0x0120000, 0x0122000, 0x124000},
104 131 {1, 0x0130000, 0x0132000, 0x126000},
105 132 {1, 0x0140000, 0x0142000, 0x128000},
106 133 {1, 0x0150000, 0x0152000, 0x12a000},
107 134 {1, 0x0160000, 0x0170000, 0x110000},
108 135 {1, 0x0170000, 0x0172000, 0x12e000},
109 136 {0, 0x0000000, 0x0000000, 0x000000},
110 137 {0, 0x0000000, 0x0000000, 0x000000},
111 138 {0, 0x0000000, 0x0000000, 0x000000},
112 139 {0, 0x0000000, 0x0000000, 0x000000},
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
113 140 {0, 0x0000000, 0x0000000, 0x000000},
114 141 {0, 0x0000000, 0x0000000, 0x000000},
115 142 {1, 0x01e0000, 0x01e0800, 0x122000},
116 143 {0, 0x0000000, 0x0000000, 0x000000}}},
117 144 {{{1, 0x0200000, 0x0210000, 0x180000}}}, /* 2: MN */
118 145 {{{0, 0, 0, 0}}}, /* 3: */
119 146 {{{1, 0x0400000, 0x0401000, 0x169000}}}, /* 4: P2NR1 */
120 147 {{{1, 0x0500000, 0x0510000, 0x140000}}}, /* 5: SRE */
121 148 {{{1, 0x0600000, 0x0610000, 0x1c0000}}}, /* 6: NIU */
122 149 {{{1, 0x0700000, 0x0704000, 0x1b8000}}}, /* 7: QM */
123 - {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0 */
150 + {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0 */
124 151 {0, 0x0000000, 0x0000000, 0x000000},
125 152 {0, 0x0000000, 0x0000000, 0x000000},
126 153 {0, 0x0000000, 0x0000000, 0x000000},
127 154 {0, 0x0000000, 0x0000000, 0x000000},
128 155 {0, 0x0000000, 0x0000000, 0x000000},
129 156 {0, 0x0000000, 0x0000000, 0x000000},
130 157 {0, 0x0000000, 0x0000000, 0x000000},
131 158 {0, 0x0000000, 0x0000000, 0x000000},
132 159 {0, 0x0000000, 0x0000000, 0x000000},
133 160 {0, 0x0000000, 0x0000000, 0x000000},
134 161 {0, 0x0000000, 0x0000000, 0x000000},
135 162 {0, 0x0000000, 0x0000000, 0x000000},
136 163 {0, 0x0000000, 0x0000000, 0x000000},
137 164 {0, 0x0000000, 0x0000000, 0x000000},
138 165 {1, 0x08f0000, 0x08f2000, 0x172000}}},
139 166 {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1 */
140 167 {0, 0x0000000, 0x0000000, 0x000000},
141 168 {0, 0x0000000, 0x0000000, 0x000000},
142 169 {0, 0x0000000, 0x0000000, 0x000000},
143 170 {0, 0x0000000, 0x0000000, 0x000000},
144 171 {0, 0x0000000, 0x0000000, 0x000000},
145 172 {0, 0x0000000, 0x0000000, 0x000000},
146 173 {0, 0x0000000, 0x0000000, 0x000000},
147 174 {0, 0x0000000, 0x0000000, 0x000000},
148 175 {0, 0x0000000, 0x0000000, 0x000000},
149 176 {0, 0x0000000, 0x0000000, 0x000000},
150 177 {0, 0x0000000, 0x0000000, 0x000000},
151 178 {0, 0x0000000, 0x0000000, 0x000000},
152 179 {0, 0x0000000, 0x0000000, 0x000000},
153 180 {0, 0x0000000, 0x0000000, 0x000000},
154 181 {1, 0x09f0000, 0x09f2000, 0x176000}}},
155 182 {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2 */
156 183 {0, 0x0000000, 0x0000000, 0x000000},
157 184 {0, 0x0000000, 0x0000000, 0x000000},
158 185 {0, 0x0000000, 0x0000000, 0x000000},
159 186 {0, 0x0000000, 0x0000000, 0x000000},
160 187 {0, 0x0000000, 0x0000000, 0x000000},
161 188 {0, 0x0000000, 0x0000000, 0x000000},
162 189 {0, 0x0000000, 0x0000000, 0x000000},
163 190 {0, 0x0000000, 0x0000000, 0x000000},
164 191 {0, 0x0000000, 0x0000000, 0x000000},
165 192 {0, 0x0000000, 0x0000000, 0x000000},
166 193 {0, 0x0000000, 0x0000000, 0x000000},
167 194 {0, 0x0000000, 0x0000000, 0x000000},
168 195 {0, 0x0000000, 0x0000000, 0x000000},
169 196 {0, 0x0000000, 0x0000000, 0x000000},
170 197 {1, 0x0af0000, 0x0af2000, 0x17a000}}},
171 198 {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3 */
172 199 {0, 0x0000000, 0x0000000, 0x000000},
173 200 {0, 0x0000000, 0x0000000, 0x000000},
174 201 {0, 0x0000000, 0x0000000, 0x000000},
175 202 {0, 0x0000000, 0x0000000, 0x000000},
176 203 {0, 0x0000000, 0x0000000, 0x000000},
177 204 {0, 0x0000000, 0x0000000, 0x000000},
178 205 {0, 0x0000000, 0x0000000, 0x000000},
179 206 {0, 0x0000000, 0x0000000, 0x000000},
180 207 {0, 0x0000000, 0x0000000, 0x000000},
181 208 {0, 0x0000000, 0x0000000, 0x000000},
182 209 {0, 0x0000000, 0x0000000, 0x000000},
183 210 {0, 0x0000000, 0x0000000, 0x000000},
184 211 {0, 0x0000000, 0x0000000, 0x000000},
185 212 {0, 0x0000000, 0x0000000, 0x000000},
186 213 {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
187 214 {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}}, /* 12: I2Q */
188 215 {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}}, /* 13: TMR */
189 216 {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}}, /* 14: ROMUSB */
190 217 {{{1, 0x0f00000, 0x0f01000, 0x164000}}}, /* 15: PEG4 */
191 218 {{{0, 0x1000000, 0x1004000, 0x1a8000}}}, /* 16: XDMA */
192 219 {{{1, 0x1100000, 0x1101000, 0x160000}}}, /* 17: PEG0 */
193 220 {{{1, 0x1200000, 0x1201000, 0x161000}}}, /* 18: PEG1 */
194 221 {{{1, 0x1300000, 0x1301000, 0x162000}}}, /* 19: PEG2 */
195 222 {{{1, 0x1400000, 0x1401000, 0x163000}}}, /* 20: PEG3 */
196 223 {{{1, 0x1500000, 0x1501000, 0x165000}}}, /* 21: P2ND */
197 224 {{{1, 0x1600000, 0x1601000, 0x166000}}}, /* 22: P2NI */
198 225 {{{0, 0, 0, 0}}}, /* 23: */
199 226 {{{0, 0, 0, 0}}}, /* 24: */
200 227 {{{0, 0, 0, 0}}}, /* 25: */
201 228 {{{0, 0, 0, 0}}}, /* 26: */
202 229 {{{0, 0, 0, 0}}}, /* 27: */
203 230 {{{0, 0, 0, 0}}}, /* 28: */
204 231 {{{1, 0x1d00000, 0x1d10000, 0x190000}}}, /* 29: MS */
205 232 {{{1, 0x1e00000, 0x1e01000, 0x16a000}}}, /* 30: P2NR2 */
206 233 {{{1, 0x1f00000, 0x1f10000, 0x150000}}}, /* 31: EPG */
207 234 {{{0}}}, /* 32: PCI */
208 235 {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */
209 236 {1, 0x2110000, 0x2120000, 0x130000},
210 237 {1, 0x2120000, 0x2122000, 0x124000},
211 238 {1, 0x2130000, 0x2132000, 0x126000},
212 239 {1, 0x2140000, 0x2142000, 0x128000},
213 240 {1, 0x2150000, 0x2152000, 0x12a000},
214 241 {1, 0x2160000, 0x2170000, 0x110000},
215 242 {1, 0x2170000, 0x2172000, 0x12e000},
216 243 {0, 0x0000000, 0x0000000, 0x000000},
217 244 {0, 0x0000000, 0x0000000, 0x000000},
218 245 {0, 0x0000000, 0x0000000, 0x000000},
219 246 {0, 0x0000000, 0x0000000, 0x000000},
220 247 {0, 0x0000000, 0x0000000, 0x000000},
221 248 {0, 0x0000000, 0x0000000, 0x000000},
222 249 {0, 0x0000000, 0x0000000, 0x000000},
223 250 {0, 0x0000000, 0x0000000, 0x000000}}},
224 251 {{{1, 0x2200000, 0x2204000, 0x1b0000}}}, /* 34: CAM */
225 252 {{{0}}}, /* 35: */
226 253 {{{0}}}, /* 36: */
227 254 {{{0}}}, /* 37: */
228 255 {{{0}}}, /* 38: */
229 256 {{{0}}}, /* 39: */
230 257 {{{1, 0x2800000, 0x2804000, 0x1a4000}}}, /* 40: TMR */
231 258 {{{1, 0x2900000, 0x2901000, 0x16b000}}}, /* 41: P2NR3 */
232 259 {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}}, /* 42: RPMX1 */
233 260 {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}}, /* 43: RPMX2 */
234 261 {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}}, /* 44: RPMX3 */
235 262 {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}}, /* 45: RPMX4 */
236 263 {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}}, /* 46: RPMX5 */
237 264 {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}}, /* 47: RPMX6 */
238 265 {{{1, 0x3000000, 0x3000400, 0x1adc00}}}, /* 48: RPMX7 */
239 266 {{{0, 0x3100000, 0x3104000, 0x1a8000}}}, /* 49: XDMA */
240 267 {{{1, 0x3200000, 0x3204000, 0x1d4000}}}, /* 50: I2Q */
241 268 {{{1, 0x3300000, 0x3304000, 0x1a0000}}}, /* 51: ROMUSB */
242 269 {{{0}}}, /* 52: */
243 270 {{{1, 0x3500000, 0x3500400, 0x1ac000}}}, /* 53: RPMX0 */
244 271 {{{1, 0x3600000, 0x3600400, 0x1ae000}}}, /* 54: RPMX8 */
245 272 {{{1, 0x3700000, 0x3700400, 0x1ae400}}}, /* 55: RPMX9 */
246 273 {{{1, 0x3800000, 0x3804000, 0x1d0000}}}, /* 56: OCM0 */
247 274 {{{1, 0x3900000, 0x3904000, 0x1b4000}}}, /* 57: CRYPTO */
248 275 {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}}, /* 58: SMB */
249 276 {{{0}}}, /* 59: I2C0 */
250 277 {{{0}}}, /* 60: I2C1 */
251 278 {{{1, 0x3d00000, 0x3d04000, 0x1dc000}}}, /* 61: LPC */
252 279 {{{1, 0x3e00000, 0x3e01000, 0x167000}}}, /* 62: P2NC */
253 280 {{{1, 0x3f00000, 0x3f01000, 0x168000}}} /* 63: P2NR0 */
254 281 };
255 282
256 283 /*
257 284 * top 12 bits of crb internal address (hub, agent)
258 285 */
259 286 static uint32_t crb_hub_agt[64] = {
260 287 0,
261 288 UNM_HW_CRB_HUB_AGT_ADR_PS,
262 289 UNM_HW_CRB_HUB_AGT_ADR_MN,
263 290 UNM_HW_CRB_HUB_AGT_ADR_MS,
264 291 0,
265 292 UNM_HW_CRB_HUB_AGT_ADR_SRE,
266 293 UNM_HW_CRB_HUB_AGT_ADR_NIU,
267 294 UNM_HW_CRB_HUB_AGT_ADR_QMN,
268 295 UNM_HW_CRB_HUB_AGT_ADR_SQN0,
269 296 UNM_HW_CRB_HUB_AGT_ADR_SQN1,
270 297 UNM_HW_CRB_HUB_AGT_ADR_SQN2,
271 298 UNM_HW_CRB_HUB_AGT_ADR_SQN3,
272 299 UNM_HW_CRB_HUB_AGT_ADR_I2Q,
273 300 UNM_HW_CRB_HUB_AGT_ADR_TIMR,
274 301 UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
275 302 UNM_HW_CRB_HUB_AGT_ADR_PGN4,
276 303 UNM_HW_CRB_HUB_AGT_ADR_XDMA,
277 304 UNM_HW_CRB_HUB_AGT_ADR_PGN0,
278 305 UNM_HW_CRB_HUB_AGT_ADR_PGN1,
279 306 UNM_HW_CRB_HUB_AGT_ADR_PGN2,
280 307 UNM_HW_CRB_HUB_AGT_ADR_PGN3,
281 308 UNM_HW_CRB_HUB_AGT_ADR_PGND,
282 309 UNM_HW_CRB_HUB_AGT_ADR_PGNI,
283 310 UNM_HW_CRB_HUB_AGT_ADR_PGS0,
284 311 UNM_HW_CRB_HUB_AGT_ADR_PGS1,
285 312 UNM_HW_CRB_HUB_AGT_ADR_PGS2,
286 313 UNM_HW_CRB_HUB_AGT_ADR_PGS3,
287 314 0,
288 315 UNM_HW_CRB_HUB_AGT_ADR_PGSI,
289 316 UNM_HW_CRB_HUB_AGT_ADR_SN,
290 317 0,
291 318 UNM_HW_CRB_HUB_AGT_ADR_EG,
292 319 0,
293 320 UNM_HW_CRB_HUB_AGT_ADR_PS,
294 321 UNM_HW_CRB_HUB_AGT_ADR_CAM,
295 322 0,
296 323 0,
297 324 0,
298 325 0,
299 326 0,
300 327 UNM_HW_CRB_HUB_AGT_ADR_TIMR,
301 328 0,
302 329 UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
303 330 UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
304 331 UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
305 332 UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
306 333 UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
307 334 UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
308 335 UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
309 336 UNM_HW_CRB_HUB_AGT_ADR_XDMA,
310 337 UNM_HW_CRB_HUB_AGT_ADR_I2Q,
311 338 UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
312 339 0,
313 340 UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
314 341 UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
315 342 UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
|
↓ open down ↓ |
182 lines elided |
↑ open up ↑ |
316 343 UNM_HW_CRB_HUB_AGT_ADR_OCM0,
317 344 0,
318 345 UNM_HW_CRB_HUB_AGT_ADR_SMB,
319 346 UNM_HW_CRB_HUB_AGT_ADR_I2C0,
320 347 UNM_HW_CRB_HUB_AGT_ADR_I2C1,
321 348 0,
322 349 UNM_HW_CRB_HUB_AGT_ADR_PGNC,
323 350 0,
324 351 };
325 352
326 -static void *
327 -ql_8021_pci_base_offsetfset(ql_adapter_state_t *ha, uint64_t off)
328 -{
329 - if ((off < ha->first_page_group_end) &&
330 - (off >= ha->first_page_group_start)) {
331 - return ((void *)(ha->nx_pcibase + off));
332 - }
333 -
334 - return (NULL);
335 -}
336 -
337 353 /* ARGSUSED */
338 354 static void
339 355 ql_crb_addr_transform_setup(ql_adapter_state_t *ha)
340 356 {
341 357 crb_addr_transform(XDMA);
342 358 crb_addr_transform(TIMR);
343 359 crb_addr_transform(SRE);
344 360 crb_addr_transform(SQN3);
345 361 crb_addr_transform(SQN2);
346 362 crb_addr_transform(SQN1);
347 363 crb_addr_transform(SQN0);
348 364 crb_addr_transform(SQS3);
349 365 crb_addr_transform(SQS2);
350 366 crb_addr_transform(SQS1);
351 367 crb_addr_transform(SQS0);
352 368 crb_addr_transform(RPMX7);
353 369 crb_addr_transform(RPMX6);
354 370 crb_addr_transform(RPMX5);
355 371 crb_addr_transform(RPMX4);
356 372 crb_addr_transform(RPMX3);
357 373 crb_addr_transform(RPMX2);
358 374 crb_addr_transform(RPMX1);
359 375 crb_addr_transform(RPMX0);
360 376 crb_addr_transform(ROMUSB);
361 377 crb_addr_transform(SN);
362 378 crb_addr_transform(QMN);
363 379 crb_addr_transform(QMS);
364 380 crb_addr_transform(PGNI);
365 381 crb_addr_transform(PGND);
366 382 crb_addr_transform(PGN3);
367 383 crb_addr_transform(PGN2);
368 384 crb_addr_transform(PGN1);
369 385 crb_addr_transform(PGN0);
370 386 crb_addr_transform(PGSI);
371 387 crb_addr_transform(PGSD);
372 388 crb_addr_transform(PGS3);
373 389 crb_addr_transform(PGS2);
374 390 crb_addr_transform(PGS1);
375 391 crb_addr_transform(PGS0);
376 392 crb_addr_transform(PS);
377 393 crb_addr_transform(PH);
378 394 crb_addr_transform(NIU);
379 395 crb_addr_transform(I2Q);
380 396 crb_addr_transform(EG);
381 397 crb_addr_transform(MN);
382 398 crb_addr_transform(MS);
383 399 crb_addr_transform(CAS2);
384 400 crb_addr_transform(CAS1);
385 401 crb_addr_transform(CAS0);
386 402 crb_addr_transform(CAM);
387 403 crb_addr_transform(C2C1);
388 404 crb_addr_transform(C2C0);
389 405 crb_addr_transform(SMB);
390 406 crb_addr_transform(OCM0);
391 407 /*
392 408 * Used only in P3 just define it for P2 also.
393 409 */
394 410 crb_addr_transform(I2C0);
395 411
396 412 crb_table_initialized = 1;
|
↓ open down ↓ |
50 lines elided |
↑ open up ↑ |
397 413 }
398 414
399 415 /*
400 416 * In: 'off' is offset from CRB space in 128M pci map
401 417 * Out: 'off' is 2M pci map addr
402 418 * side effect: lock crb window
403 419 */
404 420 static void
405 421 ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *ha, uint64_t *off)
406 422 {
407 - uint32_t win_read;
423 + uint32_t win_read, crb_win;
408 424
409 - ha->crb_win = (uint32_t)CRB_HI(*off);
410 - WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, ha->crb_win);
425 + crb_win = (uint32_t)CRB_HI(*off);
426 + WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, crb_win);
411 427
412 428 /*
413 429 * Read back value to make sure write has gone through before trying
414 430 * to use it.
415 431 */
416 432 win_read = RD_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase);
417 - if (win_read != ha->crb_win) {
433 + if (win_read != crb_win) {
418 434 EL(ha, "Written crbwin (0x%x) != Read crbwin (0x%x), "
419 - "off=0x%llx\n", ha->crb_win, win_read, *off);
435 + "off=0x%llx\n", crb_win, win_read, *off);
420 436 }
421 437 *off = (*off & MASK(16)) + CRB_INDIRECT_2M + (uintptr_t)ha->nx_pcibase;
422 438 }
423 439
424 -static void
440 +void
425 441 ql_8021_wr_32(ql_adapter_state_t *ha, uint64_t off, uint32_t data)
426 442 {
427 443 int rv;
428 444
429 445 rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
430 446 if (rv == -1) {
431 447 cmn_err(CE_PANIC, "ql_8021_wr_32, ql_8021_pci_get_crb_addr_"
432 448 "2M=-1\n");
433 449 }
434 450 if (rv == 1) {
435 451 (void) ql_8021_crb_win_lock(ha);
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
436 452 ql_8021_pci_set_crbwindow_2M(ha, &off);
437 453 }
438 454
439 455 WRT_REG_DWORD(ha, (uintptr_t)off, data);
440 456
441 457 if (rv == 1) {
442 458 ql_8021_crb_win_unlock(ha);
443 459 }
444 460 }
445 461
446 -static void
462 +void
447 463 ql_8021_rd_32(ql_adapter_state_t *ha, uint64_t off, uint32_t *data)
448 464 {
449 465 int rv;
450 466 uint32_t n;
451 467
452 468 rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
453 469 if (rv == -1) {
454 470 cmn_err(CE_PANIC, "ql_8021_rd_32, ql_8021_pci_get_crb_addr_"
455 471 "2M=-1\n");
456 472 }
457 473
458 474 if (rv == 1) {
459 475 (void) ql_8021_crb_win_lock(ha);
460 476 ql_8021_pci_set_crbwindow_2M(ha, &off);
461 477 }
462 478 n = RD_REG_DWORD(ha, (uintptr_t)off);
463 479
464 480 if (data != NULL) {
465 481 *data = n;
466 482 }
467 483
468 484 if (rv == 1) {
469 485 ql_8021_crb_win_unlock(ha);
470 486 }
471 487 }
472 488
473 489 static int
474 490 ql_8021_crb_win_lock(ql_adapter_state_t *ha)
475 491 {
476 492 uint32_t done = 0, timeout = 0;
477 493
478 494 while (!done) {
479 495 /* acquire semaphore3 from PCI HW block */
480 496 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_LOCK), &done);
481 497 if (done == 1) {
482 498 break;
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
483 499 }
484 500 if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
485 501 EL(ha, "timeout\n");
486 502 return (-1);
487 503 }
488 504 timeout++;
489 505
490 506 /* Yield CPU */
491 507 delay(1);
492 508 }
493 - ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->function_number);
509 + ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->pci_function_number);
494 510
495 511 return (0);
496 512 }
497 513
498 514 static void
499 515 ql_8021_crb_win_unlock(ql_adapter_state_t *ha)
500 516 {
501 517 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_UNLOCK), NULL);
502 518 }
503 519
504 520 static int
505 521 ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *ha, uint64_t *off)
506 522 {
507 523 crb_128M_2M_sub_block_map_t *m;
508 524
509 525 if (*off >= UNM_CRB_MAX) {
510 526 EL(ha, "%llx >= %llx\n", *off, UNM_CRB_MAX);
511 527 return (-1);
512 528 }
513 529
514 530 if (*off >= UNM_PCI_CAMQM && (*off < UNM_PCI_CAMQM_2M_END)) {
515 531 *off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
516 532 (uintptr_t)ha->nx_pcibase;
517 533 return (0);
518 534 }
519 535
520 536 if (*off < UNM_PCI_CRBSPACE) {
521 537 EL(ha, "%llx < %llx\n", *off, UNM_PCI_CRBSPACE);
522 538 return (-1);
523 539 }
524 540
525 541 *off -= UNM_PCI_CRBSPACE;
526 542 /*
527 543 * Try direct map
528 544 */
529 545
530 546 m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
531 547
532 548 if (m->valid && ((uint64_t)m->start_128M <= *off) &&
533 549 ((uint64_t)m->end_128M > *off)) {
534 550 *off = (uint64_t)(*off + m->start_2M - m->start_128M +
535 551 (uintptr_t)ha->nx_pcibase);
536 552 return (0);
537 553 }
538 554
539 555 /*
540 556 * Not in direct map, use crb window
541 557 */
542 558 return (1);
543 559 }
544 560
545 561 /*
546 562 * check memory access boundary.
547 563 * used by test agent. support ddr access only for now
548 564 */
549 565 /* ARGSUSED */
550 566 static uint32_t
551 567 ql_8021_pci_mem_bound_check(ql_adapter_state_t *ha, uint64_t addr,
552 568 uint32_t size)
553 569 {
554 570 /*LINTED suspicious 0 comparison*/
555 571 if (!QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
556 572 UNM_ADDR_DDR_NET_MAX) ||
557 573 /*LINTED suspicious 0 comparison*/
558 574 !QL_8021_ADDR_IN_RANGE(addr + size - 1, UNM_ADDR_DDR_NET,
559 575 UNM_ADDR_DDR_NET_MAX) ||
560 576 ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
561 577 return (0);
562 578 }
563 579
564 580 return (1);
565 581 }
566 582
|
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
567 583 static uint64_t
568 584 ql_8021_pci_set_window(ql_adapter_state_t *ha, uint64_t addr)
569 585 {
570 586 uint32_t window, win_read;
571 587
572 588 /*LINTED suspicious 0 comparison*/
573 589 if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
574 590 UNM_ADDR_DDR_NET_MAX)) {
575 591 /* DDR network side */
576 592 window = (uint32_t)MN_WIN(addr);
577 - ha->ddr_mn_window = window;
578 - ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
579 - ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
580 - &win_read);
593 + ql_8021_wr_32(ha, UNM_PCI_CRBSPACE, window);
594 + ql_8021_rd_32(ha, UNM_PCI_CRBSPACE, &win_read);
581 595 if ((win_read << 17) != window) {
582 596 EL(ha, "Warning, Written MNwin (0x%x) != Read MNwin "
583 597 "(0x%x)\n", window, win_read);
584 598 }
585 599 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
586 600 } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
587 601 UNM_ADDR_OCM0_MAX)) {
588 602 uint32_t temp1;
589 603
590 604 if ((addr & 0x00ff800) == 0xff800) {
591 605 /* if bits 19:18&17:11 are on */
592 606 EL(ha, "QM access not handled\n");
593 607 addr = -1UL;
594 608 }
595 609
596 610 window = (uint32_t)OCM_WIN(addr);
597 - ha->ddr_mn_window = window;
598 - ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
599 - ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
600 - &win_read);
611 + ql_8021_wr_32(ha, UNM_PCI_CRBSPACE, window);
612 + ql_8021_rd_32(ha, UNM_PCI_CRBSPACE, &win_read);
601 613 temp1 = ((window & 0x1FF) << 7) |
602 614 ((window & 0x0FFFE0000) >> 17);
603 615 if (win_read != temp1) {
604 616 EL(ha, "Written OCMwin (0x%x) != Read OCMwin (0x%x)\n",
605 617 temp1, win_read);
606 618 }
607 619 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
608 620 } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
609 621 NX_P3_ADDR_QDR_NET_MAX)) {
610 622 /* QDR network side */
611 623 window = (uint32_t)MS_WIN(addr);
612 624 ha->qdr_sn_window = window;
613 - ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
614 - ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
615 - &win_read);
625 + ql_8021_wr_32(ha, UNM_PCI_CRBSPACE, window);
626 + ql_8021_rd_32(ha, UNM_PCI_CRBSPACE, &win_read);
616 627 if (win_read != window) {
617 628 EL(ha, "Written MSwin (0x%x) != Read MSwin (0x%x)\n",
618 629 window, win_read);
619 630 }
620 631 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
621 632 } else {
622 633 /*
623 634 * peg gdb frequently accesses memory that doesn't exist,
624 635 * this limits the chit chat so debugging isn't slowed down.
625 636 */
626 637 if ((pci_set_window_warning_count++ < 8) ||
627 638 (pci_set_window_warning_count % 64 == 0)) {
628 639 EL(ha, "Unknown address range\n");
629 640 }
630 641 addr = -1UL;
631 642 }
632 643
633 644 return (addr);
634 645 }
635 646
636 647 /* check if address is in the same windows as the previous access */
637 648 static int
638 649 ql_8021_pci_is_same_window(ql_adapter_state_t *ha, uint64_t addr)
639 650 {
640 651 uint32_t window;
641 652 uint64_t qdr_max;
642 653
643 654 qdr_max = NX_P3_ADDR_QDR_NET_MAX;
644 655
645 656 /*LINTED suspicious 0 comparison*/
646 657 if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
647 658 UNM_ADDR_DDR_NET_MAX)) {
648 659 /* DDR network side */
649 660 EL(ha, "DDR network side\n");
650 661 return (0); /* MN access can not come here */
651 662 } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
652 663 UNM_ADDR_OCM0_MAX)) {
653 664 return (1);
654 665 } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM1,
655 666 UNM_ADDR_OCM1_MAX)) {
656 667 return (1);
657 668 } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
658 669 /* QDR network side */
659 670 window = (uint32_t)(((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f);
660 671 if (ha->qdr_sn_window == window) {
661 672 return (1);
662 673 }
663 674 }
664 675
665 676 return (0);
666 677 }
667 678
668 679 static int
669 680 ql_8021_pci_mem_read_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
670 681 uint32_t size)
671 682 {
672 683 void *addr;
673 684 int ret = 0;
674 685 uint64_t start;
675 686
676 687 /*
|
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
677 688 * If attempting to access unknown address or straddle hw windows,
678 689 * do not access.
679 690 */
680 691 if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
681 692 (ql_8021_pci_is_same_window(ha, off + size - 1) == 0)) {
682 693 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
683 694 off);
684 695 return (-1);
685 696 }
686 697
687 - addr = ql_8021_pci_base_offsetfset(ha, start);
688 - if (!addr) {
689 - addr = (void *)((uint8_t *)ha->nx_pcibase + start);
690 - }
698 + addr = (void *)((uint8_t *)ha->nx_pcibase + start);
691 699
692 700 switch (size) {
693 701 case 1:
694 - *(uint8_t *)data = RD_REG_BYTE(ha, addr);
702 + *(uint8_t *)data = RD_REG_BYTE(ha, addr);
695 703 break;
696 704 case 2:
697 - *(uint16_t *)data = RD_REG_WORD(ha, addr);
705 + *(uint16_t *)data = RD_REG_WORD(ha, addr);
698 706 break;
699 707 case 4:
700 - *(uint32_t *)data = RD_REG_DWORD(ha, addr);
708 + *(uint32_t *)data = RD_REG_DWORD(ha, addr);
701 709 break;
702 710 case 8:
703 - *(uint64_t *)data = RD_REG_DDWORD(ha, addr);
711 + *(uint64_t *)data = RD_REG_DDWORD(ha, addr);
704 712 break;
705 713 default:
706 714 EL(ha, "invalid size=%x\n", size);
707 715 ret = -1;
708 716 break;
709 717 }
710 718
711 719 return (ret);
712 720 }
713 721
714 722 static int
715 723 ql_8021_pci_mem_write_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
716 724 uint32_t size)
717 725 {
718 726 void *addr;
719 727 int ret = 0;
720 728 uint64_t start;
721 729
722 730 /*
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
723 731 * If attempting to access unknown address or straddle hw windows,
724 732 * do not access.
725 733 */
726 734 if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
727 735 (ql_8021_pci_is_same_window(ha, off + size -1) == 0)) {
728 736 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
729 737 off);
730 738 return (-1);
731 739 }
732 740
733 - addr = ql_8021_pci_base_offsetfset(ha, start);
734 - if (!addr) {
735 - addr = (void *)((uint8_t *)ha->nx_pcibase + start);
736 - }
741 + addr = (void *)((uint8_t *)ha->nx_pcibase + start);
737 742
738 743 switch (size) {
739 744 case 1:
740 745 WRT_REG_BYTE(ha, addr, *(uint8_t *)data);
741 746 break;
742 747 case 2:
743 748 WRT_REG_WORD(ha, addr, *(uint16_t *)data);
744 749 break;
745 750 case 4:
746 751 WRT_REG_DWORD(ha, addr, *(uint32_t *)data);
747 752 break;
748 753 case 8:
749 754 WRT_REG_DDWORD(ha, addr, *(uint64_t *)data);
750 755 break;
751 756 default:
752 757 EL(ha, "invalid size=%x\n", size);
753 758 ret = -1;
754 759 break;
755 760 }
756 761
757 762 return (ret);
758 763 }
759 764
760 765 static int
761 766 ql_8021_pci_mem_read_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
762 767 uint32_t size)
763 768 {
764 769 int j = 0;
765 770 uint32_t i, temp, sz[2], loop, shift_amount;
766 771 uint64_t start, end, k;
767 772 uint64_t off8, off0[2], val, mem_crb, word[2] = {0, 0};
768 773
769 774 /*
770 775 * If not MN, go check for MS or invalid.
771 776 */
772 777
773 778 if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
774 779 mem_crb = UNM_CRB_QDR_NET;
775 780 } else {
776 781 mem_crb = UNM_CRB_DDR_NET;
777 782 if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
778 783 return (ql_8021_pci_mem_read_direct(ha, off, data,
779 784 size));
780 785 }
781 786 }
782 787
783 788 if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
784 789 off8 = off & 0xfffffff0;
785 790 off0[0] = off & 0xf;
786 791 sz[0] = (uint32_t)(((uint64_t)size < (16 - off0[0])) ? size :
787 792 (16 - off0[0]));
788 793 shift_amount = 4;
789 794 } else {
790 795 off8 = off & 0xfffffff8;
791 796 off0[0] = off & 0x7;
792 797 sz[0] = (uint32_t)(((uint64_t)size < (8 - off0[0])) ? size :
793 798 (8 - off0[0]));
794 799 shift_amount = 3;
795 800 }
796 801 loop = (uint32_t)(((off0[0] + size - 1) >> shift_amount) + 1);
797 802 off0[1] = 0;
798 803 sz[1] = size - sz[0];
799 804
800 805 /*
801 806 * don't lock here - write_wx gets the lock if each time
802 807 * write_lock_irqsave(&adapter->adapter_lock, flags);
803 808 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
804 809 */
805 810
806 811 for (i = 0; i < loop; i++) {
807 812 temp = (uint32_t)(off8 + (i << shift_amount));
808 813 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
809 814 temp = 0;
810 815 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
811 816 temp = MIU_TA_CTL_ENABLE;
812 817 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
813 818 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
814 819 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
815 820
816 821 for (j = 0; j < MAX_CTL_CHECK; j++) {
817 822 ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
818 823 if ((temp & MIU_TA_CTL_BUSY) == 0) {
819 824 break;
820 825 }
821 826 }
822 827
823 828 if (j >= MAX_CTL_CHECK) {
824 829 EL(ha, "failed to read through agent\n");
825 830 break;
826 831 }
827 832
828 833 start = off0[i] >> 2;
829 834 end = (off0[i] + sz[i] - 1) >> 2;
830 835 for (k = start; k <= end; k++) {
831 836 ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_RDDATA(k),
832 837 &temp);
833 838 word[i] |= ((uint64_t)temp << (32 * (k & 1)));
834 839 }
835 840 }
836 841
837 842 /*
838 843 * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
839 844 * write_unlock_irqrestore(&adapter->adapter_lock, flags);
840 845 */
841 846
842 847 if (j >= MAX_CTL_CHECK) {
843 848 return (-1);
844 849 }
845 850
846 851 if ((off0[0] & 7) == 0) {
847 852 val = word[0];
848 853 } else {
849 854 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
850 855 ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
851 856 }
852 857
853 858 switch (size) {
854 859 case 1:
855 860 *(uint8_t *)data = (uint8_t)val;
856 861 break;
857 862 case 2:
858 863 *(uint16_t *)data = (uint16_t)val;
859 864 break;
860 865 case 4:
861 866 *(uint32_t *)data = (uint32_t)val;
862 867 break;
863 868 case 8:
864 869 *(uint64_t *)data = val;
865 870 break;
866 871 }
867 872
868 873 return (0);
869 874 }
870 875
871 876 static int
872 877 ql_8021_pci_mem_write_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
873 878 uint32_t size)
874 879 {
875 880 int j, ret = 0;
876 881 uint32_t i, temp, loop, sz[2];
877 882 uint32_t scale, shift_amount, p3p, startword;
878 883 uint64_t off8, off0, mem_crb, tmpw, word[2] = {0, 0};
879 884
880 885 /*
881 886 * If not MN, go check for MS or invalid.
882 887 */
883 888 if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
884 889 mem_crb = UNM_CRB_QDR_NET;
885 890 } else {
886 891 mem_crb = UNM_CRB_DDR_NET;
887 892 if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
888 893 return (ql_8021_pci_mem_write_direct(ha, off, data,
889 894 size));
890 895 }
891 896 }
892 897
893 898 off0 = off & 0x7;
894 899 sz[0] = (uint32_t)(((uint64_t)size < (8 - off0)) ? size : (8 - off0));
895 900 sz[1] = size - sz[0];
896 901
897 902 if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
898 903 off8 = off & 0xfffffff0;
899 904 loop = (uint32_t)((((off & 0xf) + size - 1) >> 4) + 1);
900 905 shift_amount = 4;
901 906 scale = 2;
902 907 p3p = 1;
903 908 startword = (uint32_t)((off & 0xf) / 8);
904 909 } else {
905 910 off8 = off & 0xfffffff8;
906 911 loop = (uint32_t)(((off0 + size - 1) >> 3) + 1);
907 912 shift_amount = 3;
908 913 scale = 1;
909 914 p3p = 0;
910 915 startword = 0;
911 916 }
912 917
913 918 if (p3p || (size != 8) || (off0 != 0)) {
914 919 for (i = 0; i < loop; i++) {
915 920 if (ql_8021_pci_mem_read_2M(ha, off8 +
916 921 (i << shift_amount), &word[i * scale], 8)) {
917 922 EL(ha, "8021_pci_mem_read_2M != 0\n");
918 923 return (-1);
919 924 }
920 925 }
921 926 }
922 927
923 928 switch (size) {
924 929 case 1:
925 930 tmpw = (uint64_t)(*((uint8_t *)data));
926 931 break;
927 932 case 2:
928 933 tmpw = (uint64_t)(*((uint16_t *)data));
929 934 break;
930 935 case 4:
931 936 tmpw = (uint64_t)(*((uint32_t *)data));
932 937 break;
933 938 case 8:
934 939 default:
935 940 tmpw = *((uint64_t *)data);
936 941 break;
937 942 }
|
↓ open down ↓ |
191 lines elided |
↑ open up ↑ |
938 943
939 944 if (p3p) {
940 945 if (sz[0] == 8) {
941 946 word[startword] = tmpw;
942 947 } else {
943 948 word[startword] &= ~((~(~0ULL << (sz[0] * 8))) <<
944 949 (off0 * 8));
945 950 word[startword] |= tmpw << (off0 * 8);
946 951 }
947 952 if (sz[1] != 0) {
948 - word[startword+1] &= ~(~0ULL << (sz[1] * 8));
949 - word[startword+1] |= tmpw >> (sz[0] * 8);
953 + word[startword + 1] &= ~(~0ULL << (sz[1] * 8));
954 + word[startword + 1] |= tmpw >> (sz[0] * 8);
950 955 }
951 956 } else {
952 957 word[startword] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
953 958 word[startword] |= tmpw << (off0 * 8);
954 959
955 960 if (loop == 2) {
956 961 word[1] &= ~(~0ULL << (sz[1] * 8));
957 962 word[1] |= tmpw >> (sz[0] * 8);
958 963 }
959 964 }
960 965
961 966 /*
962 967 * don't lock here - write_wx gets the lock if each time
963 968 * write_lock_irqsave(&adapter->adapter_lock, flags);
964 969 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
965 970 */
966 971
967 972 for (i = 0; i < loop; i++) {
968 973 temp = (uint32_t)(off8 + (i << shift_amount));
969 974 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
970 975 temp = 0;
971 976 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
972 977 temp = (uint32_t)(word[i * scale] & 0xffffffff);
973 978 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_LO, temp);
974 979 temp = (uint32_t)((word[i * scale] >> 32) & 0xffffffff);
975 980 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_HI, temp);
976 981 if (p3p) {
977 982 temp = (uint32_t)(word[i * scale + 1] & 0xffffffff);
978 983 ql_8021_wr_32(ha,
979 984 mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
980 985 temp = (uint32_t)((word[i * scale + 1] >> 32) &
981 986 0xffffffff);
982 987 ql_8021_wr_32(ha,
983 988 mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI, temp);
984 989 }
985 990 temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
986 991 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
987 992 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
988 993 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
989 994
990 995 for (j = 0; j < MAX_CTL_CHECK; j++) {
991 996 ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
992 997 if ((temp & MIU_TA_CTL_BUSY) == 0)
993 998 break;
994 999 }
995 1000
996 1001 if (j >= MAX_CTL_CHECK) {
997 1002 EL(ha, "failed to write through agent\n");
998 1003 ret = -1;
999 1004 break;
1000 1005 }
1001 1006 }
1002 1007
1003 1008 return (ret);
1004 1009 }
1005 1010
1006 1011 static uint32_t
1007 1012 ql_8021_decode_crb_addr(ql_adapter_state_t *ha, uint32_t addr)
1008 1013 {
1009 1014 int i;
1010 1015 uint32_t base_addr, offset, pci_base;
1011 1016
1012 1017 if (!crb_table_initialized) {
1013 1018 ql_crb_addr_transform_setup(ha);
1014 1019 }
1015 1020
1016 1021 pci_base = ADDR_ERROR;
1017 1022 base_addr = addr & 0xfff00000;
1018 1023 offset = addr & 0x000fffff;
1019 1024
1020 1025 for (i = 0; i < MAX_CRB_XFORM; i++) {
1021 1026 if (crb_addr_xform[i] == base_addr) {
1022 1027 pci_base = i << 20;
1023 1028 break;
1024 1029 }
1025 1030 }
1026 1031 if (pci_base == ADDR_ERROR) {
1027 1032 return (pci_base);
1028 1033 } else {
1029 1034 return (pci_base + offset);
1030 1035 }
1031 1036 }
1032 1037
1033 1038 static int
1034 1039 ql_8021_hw_lock(ql_adapter_state_t *ha, uint32_t timer)
1035 1040 {
1036 1041 uint32_t done = 0, timeout = 0;
1037 1042
1038 1043 while (!done) {
1039 1044 /* acquire semaphore5 from PCI HW block */
1040 1045 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
1041 1046 if (done == 1) {
1042 1047 break;
1043 1048 }
1044 1049 if (timeout >= timer) {
1045 1050 EL(ha, "timeout\n");
1046 1051 return (-1);
1047 1052 }
1048 1053 timeout++;
1049 1054
1050 1055 /*
1051 1056 * Yield CPU
1052 1057 */
1053 1058 delay(1);
1054 1059 }
1055 1060
1056 1061 return (0);
1057 1062 }
1058 1063
1059 1064 static void
1060 1065 ql_8021_hw_unlock(ql_adapter_state_t *ha)
1061 1066 {
1062 1067 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_UNLOCK), NULL);
1063 1068 }
1064 1069
1065 1070 static int
1066 1071 ql_8021_rom_lock(ql_adapter_state_t *ha)
1067 1072 {
1068 1073 uint32_t done = 0, timeout = 0;
1069 1074
1070 1075 while (!done) {
1071 1076 /* acquire semaphore2 from PCI HW block */
1072 1077 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
1073 1078 if (done == 1) {
1074 1079 break;
1075 1080 }
1076 1081 if (timeout >= ROM_LOCK_TIMEOUT) {
1077 1082 EL(ha, "timeout\n");
1078 1083 return (-1);
1079 1084 }
1080 1085 timeout++;
1081 1086
1082 1087 /*
1083 1088 * Yield CPU
1084 1089 */
1085 1090 delay(1);
1086 1091 }
1087 1092 ql_8021_wr_32(ha, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
1088 1093
1089 1094 return (0);
1090 1095 }
1091 1096
1092 1097 static void
1093 1098 ql_8021_rom_unlock(ql_adapter_state_t *ha)
1094 1099 {
1095 1100 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), NULL);
1096 1101 }
1097 1102
1098 1103 static int
1099 1104 ql_8021_wait_rom_done(ql_adapter_state_t *ha)
1100 1105 {
1101 1106 uint32_t timeout = 0, done = 0;
1102 1107
1103 1108 while (done == 0) {
1104 1109 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_STATUS, &done);
1105 1110 done &= 2;
1106 1111 timeout++;
1107 1112 if (timeout >= ROM_MAX_TIMEOUT) {
1108 1113 EL(ha, "Timeout reached waiting for rom done\n");
1109 1114 return (-1);
1110 1115 }
1111 1116 }
|
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
1112 1117
1113 1118 return (0);
1114 1119 }
1115 1120
1116 1121 static int
1117 1122 ql_8021_wait_flash_done(ql_adapter_state_t *ha)
1118 1123 {
1119 1124 clock_t timer;
1120 1125 uint32_t status;
1121 1126
1122 - for (timer = 30 * drv_usectohz(1000000); timer; timer--) {
1127 + for (timer = 500000; timer; timer--) {
1123 1128 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1124 1129 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1125 1130 UNM_ROMUSB_ROM_RDSR_INSTR);
1126 1131 if (ql_8021_wait_rom_done(ha)) {
1127 1132 EL(ha, "Error waiting for rom done2\n");
1128 1133 return (-1);
1129 1134 }
1130 1135
1131 1136 /* Get status. */
1132 1137 ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, &status);
1133 1138 if (!(status & BIT_0)) {
1134 1139 return (0);
1135 1140 }
1136 - delay(1);
1141 + drv_usecwait(10);
1137 1142 }
1138 1143
1139 1144 EL(ha, "timeout status=%x\n", status);
1140 1145 return (-1);
1141 1146 }
1142 1147
1143 1148 static int
1144 1149 ql_8021_do_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1145 1150 {
1146 1151 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1147 1152 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1148 1153 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1149 1154 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1150 1155 UNM_ROMUSB_ROM_FAST_RD_INSTR);
1151 1156 if (ql_8021_wait_rom_done(ha)) {
1152 1157 EL(ha, "Error waiting for rom done\n");
1153 1158 return (-1);
1154 1159 }
1155 1160 /* reset abyte_cnt and dummy_byte_cnt */
1156 1161 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1157 1162 drv_usecwait(10);
1158 1163 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1159 1164
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
1160 1165 ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, valp);
1161 1166
1162 1167 return (0);
1163 1168 }
1164 1169
1165 1170 int
1166 1171 ql_8021_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1167 1172 {
1168 1173 int ret, loops = 0;
1169 1174
1170 - while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1171 - drv_usecwait(100);
1175 + while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1176 + drv_usecwait(10);
1172 1177 loops++;
1173 1178 }
1174 1179 if (loops >= 50000) {
1175 1180 EL(ha, "rom_lock failed\n");
1176 1181 return (-1);
1177 1182 }
1178 1183 ret = ql_8021_do_rom_fast_read(ha, addr, valp);
1179 1184 ql_8021_rom_unlock(ha);
1180 1185
1181 1186 return (ret);
1182 1187 }
1183 1188
1184 1189 static int
1185 1190 ql_8021_do_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1186 1191 {
1187 1192 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1188 1193 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1189 1194 UNM_ROMUSB_ROM_WREN_INSTR);
1190 1195 if (ql_8021_wait_rom_done(ha)) {
1191 1196 EL(ha, "Error waiting for rom done\n");
1192 1197 return (-1);
1193 1198 }
1194 1199
1195 1200 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1196 1201 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1197 1202 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1198 1203 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1199 1204 UNM_ROMUSB_ROM_PP_INSTR);
1200 1205 if (ql_8021_wait_rom_done(ha)) {
1201 1206 EL(ha, "Error waiting for rom done1\n");
1202 1207 return (-1);
1203 1208 }
1204 1209
1205 1210 if (ql_8021_wait_flash_done(ha)) {
1206 1211 EL(ha, "Error waiting for flash done\n");
1207 1212 return (-1);
1208 1213 }
1209 1214
1210 1215 return (0);
1211 1216 }
1212 1217
1213 1218 static int
1214 1219 ql_8021_do_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1215 1220 {
1216 1221 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1217 1222 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1218 1223 UNM_ROMUSB_ROM_WREN_INSTR);
1219 1224 if (ql_8021_wait_rom_done(ha)) {
1220 1225 EL(ha, "Error waiting for rom done\n");
1221 1226 return (-1);
1222 1227 }
1223 1228
1224 1229 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1225 1230 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1226 1231 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1227 1232 UNM_ROMUSB_ROM_SE_INSTR);
1228 1233 if (ql_8021_wait_rom_done(ha)) {
1229 1234 EL(ha, "Error waiting for rom done1\n");
1230 1235 return (-1);
1231 1236 }
1232 1237
1233 1238 if (ql_8021_wait_flash_done(ha)) {
1234 1239 EL(ha, "Error waiting for flash done\n");
1235 1240 return (-1);
1236 1241 }
1237 1242
1238 1243 return (0);
1239 1244 }
1240 1245
1241 1246 int
1242 1247 ql_8021_rom_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *bp)
1243 1248 {
1244 1249 int ret;
1245 1250
1246 1251 ret = ql_8021_rom_fast_read(ha, addr << 2, bp) == 0 ? QL_SUCCESS :
|
↓ open down ↓ |
65 lines elided |
↑ open up ↑ |
1247 1252 QL_FUNCTION_FAILED;
1248 1253
1249 1254 return (ret);
1250 1255 }
1251 1256
1252 1257 int
1253 1258 ql_8021_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1254 1259 {
1255 1260 int ret, loops = 0;
1256 1261
1257 - while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1258 - drv_usecwait(100);
1262 + while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1263 + drv_usecwait(10);
1259 1264 loops++;
1260 1265 }
1261 1266 if (loops >= 50000) {
1262 1267 EL(ha, "rom_lock failed\n");
1263 1268 ret = QL_FUNCTION_TIMEOUT;
1264 1269 } else {
1265 1270 ret = ql_8021_do_rom_write(ha, addr << 2, data) == 0 ?
1266 1271 QL_SUCCESS : QL_FUNCTION_FAILED;
1267 1272 ql_8021_rom_unlock(ha);
1268 1273 }
1269 1274
1270 1275 return (ret);
1271 1276 }
1272 1277
1273 1278 int
1274 1279 ql_8021_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1275 1280 {
1276 1281 int ret, loops = 0;
1277 1282
1278 - while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1279 - drv_usecwait(100);
1283 + while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1284 + drv_usecwait(10);
1280 1285 loops++;
1281 1286 }
1282 1287 if (loops >= 50000) {
1283 1288 EL(ha, "rom_lock failed\n");
1284 1289 ret = QL_FUNCTION_TIMEOUT;
1285 1290 } else {
1286 1291 ret = ql_8021_do_rom_erase(ha, addr << 2) == 0 ? QL_SUCCESS :
1287 1292 QL_FUNCTION_FAILED;
1288 1293 ql_8021_rom_unlock(ha);
1289 1294 }
1290 1295
1291 1296 return (ret);
1292 1297 }
1293 1298
1294 1299 int
1295 1300 ql_8021_rom_wrsr(ql_adapter_state_t *ha, uint32_t data)
1296 1301 {
1297 1302 int ret = QL_SUCCESS, loops = 0;
1298 1303
1299 - while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1300 - drv_usecwait(100);
1304 + while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1305 + drv_usecwait(10);
1301 1306 loops++;
1302 1307 }
1303 1308 if (loops >= 50000) {
1304 1309 EL(ha, "rom_lock failed\n");
1305 1310 ret = QL_FUNCTION_TIMEOUT;
1306 1311 } else {
1307 1312 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1308 1313 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1309 1314 UNM_ROMUSB_ROM_WREN_INSTR);
1310 1315 if (ql_8021_wait_rom_done(ha)) {
1311 1316 EL(ha, "Error waiting for rom done\n");
1312 1317 ret = QL_FUNCTION_FAILED;
1313 1318 } else {
1314 1319 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1315 1320 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1316 1321 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1317 1322 UNM_ROMUSB_ROM_WRSR_INSTR);
1318 1323 if (ql_8021_wait_rom_done(ha)) {
1319 1324 EL(ha, "Error waiting for rom done1\n");
1320 1325 ret = QL_FUNCTION_FAILED;
1321 1326 } else if (ql_8021_wait_flash_done(ha)) {
1322 1327 EL(ha, "Error waiting for flash done\n");
1323 1328 ret = QL_FUNCTION_FAILED;
1324 1329 }
1325 1330 }
1326 1331 ql_8021_rom_unlock(ha);
1327 1332 }
1328 1333
1329 1334 return (ret);
1330 1335 }
1331 1336
1332 1337 static int
1333 1338 ql_8021_phantom_init(ql_adapter_state_t *ha)
1334 1339 {
1335 1340 uint32_t val = 0, err = 0;
1336 1341 int retries = 60;
1337 1342
1338 1343 do {
1339 1344 ql_8021_rd_32(ha, CRB_CMDPEG_STATE, &val);
1340 1345
1341 1346 switch (val) {
1342 1347 case PHAN_INITIALIZE_COMPLETE:
1343 1348 case PHAN_INITIALIZE_ACK:
1344 1349 EL(ha, "success=%xh\n", val);
1345 1350 return (0);
1346 1351 case PHAN_INITIALIZE_FAILED:
1347 1352 EL(ha, "PHAN_INITIALIZE_FAILED\n");
1348 1353 err = 1;
1349 1354 break;
1350 1355 default:
1351 1356 break;
1352 1357 }
1353 1358
1354 1359 if (err) {
1355 1360 break;
1356 1361 }
1357 1362 /* 500 msec wait */
1358 1363 delay(50);
1359 1364
1360 1365 } while (--retries);
1361 1366
1362 1367 if (!err) {
1363 1368 ql_8021_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
1364 1369 }
1365 1370
1366 1371 EL(ha, "firmware init failed=%x\n", val);
1367 1372 return (-1);
1368 1373 }
1369 1374
1370 1375 static int
1371 1376 ql_8021_pinit_from_rom(ql_adapter_state_t *ha)
|
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
1372 1377 {
1373 1378 int init_delay = 0;
1374 1379 struct crb_addr_pair *buf;
1375 1380 uint32_t offset, off, i, n, addr, val;
1376 1381
1377 1382 /* Grab the lock so that no one can read flash when we reset the chip */
1378 1383 (void) ql_8021_rom_lock(ha);
1379 1384 ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0xffffffff);
1380 1385 /* Just in case it was held when we reset the chip */
1381 1386 ql_8021_rom_unlock(ha);
1387 + delay(100);
1382 1388
1383 1389 if (ql_8021_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafe ||
1384 1390 ql_8021_rom_fast_read(ha, 4, &n) != 0) {
1385 1391 EL(ha, "ERROR Reading crb_init area: n: %08x\n", n);
1386 1392 return (-1);
1387 1393 }
1388 1394 offset = n & 0xffff;
1389 1395 n = (n >> 16) & 0xffff;
1390 1396 if (n >= 1024) {
1391 1397 EL(ha, "n=0x%x Error! NetXen card flash not initialized\n", n);
1392 1398 return (-1);
1393 1399 }
1394 1400
1395 1401 buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
1396 1402 if (buf == NULL) {
1397 1403 EL(ha, "Unable to zalloc memory\n");
1398 1404 return (-1);
1399 1405 }
1400 1406
1401 1407 for (i = 0; i < n; i++) {
1402 1408 if (ql_8021_rom_fast_read(ha, 8 * i + 4 * offset, &val) != 0 ||
1403 1409 ql_8021_rom_fast_read(ha, 8 * i + 4 * offset + 4, &addr) !=
1404 1410 0) {
1405 1411 kmem_free(buf, n * sizeof (struct crb_addr_pair));
1406 1412 EL(ha, "ql_8021_rom_fast_read != 0 to zalloc memory\n");
1407 1413 return (-1);
1408 1414 }
1409 1415
1410 1416 buf[i].addr = addr;
1411 1417 buf[i].data = val;
1412 1418 }
1413 1419
1414 1420 for (i = 0; i < n; i++) {
1415 1421 off = ql_8021_decode_crb_addr(ha, buf[i].addr);
1416 1422 if (off == ADDR_ERROR) {
1417 1423 EL(ha, "Err: Unknown addr: 0x%lx\n", buf[i].addr);
1418 1424 continue;
1419 1425 }
1420 1426 off += UNM_PCI_CRBSPACE;
1421 1427
1422 1428 if (off & 1) {
1423 1429 continue;
1424 1430 }
1425 1431
1426 1432 /* skipping cold reboot MAGIC */
1427 1433 if (off == UNM_RAM_COLD_BOOT) {
1428 1434 continue;
1429 1435 }
1430 1436 if (off == (UNM_CRB_I2C0 + 0x1c)) {
1431 1437 continue;
1432 1438 }
1433 1439 /* do not reset PCI */
1434 1440 if (off == (ROMUSB_GLB + 0xbc)) {
1435 1441 continue;
1436 1442 }
1437 1443 if (off == (ROMUSB_GLB + 0xa8)) {
1438 1444 continue;
1439 1445 }
1440 1446 if (off == (ROMUSB_GLB + 0xc8)) { /* core clock */
1441 1447 continue;
1442 1448 }
1443 1449 if (off == (ROMUSB_GLB + 0x24)) { /* MN clock */
1444 1450 continue;
1445 1451 }
1446 1452 if (off == (ROMUSB_GLB + 0x1c)) { /* MS clock */
1447 1453 continue;
1448 1454 }
1449 1455 if ((off & 0x0ff00000) == UNM_CRB_DDR_NET) {
1450 1456 continue;
1451 1457 }
1452 1458 if (off == (UNM_CRB_PEG_NET_1 + 0x18) &&
1453 1459 !NX_IS_REVISION_P3PLUS(ha->rev_id)) {
1454 1460 buf[i].data = 0x1020;
1455 1461 }
1456 1462 /* skip the function enable register */
1457 1463 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
1458 1464 continue;
1459 1465 }
1460 1466 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
1461 1467 continue;
1462 1468 }
1463 1469 if ((off & 0x0ff00000) == UNM_CRB_SMB) {
1464 1470 continue;
1465 1471 }
1466 1472
1467 1473 /* After writing this register, HW needs time for CRB */
1468 1474 /* to quiet down (else crb_window returns 0xffffffff) */
1469 1475 init_delay = 1;
1470 1476 if (off == UNM_ROMUSB_GLB_SW_RESET) {
1471 1477 init_delay = 100; /* Sleep 1000 msecs */
1472 1478 }
1473 1479
1474 1480 ql_8021_wr_32(ha, off, buf[i].data);
1475 1481
1476 1482 delay(init_delay);
1477 1483 }
1478 1484 kmem_free(buf, n * sizeof (struct crb_addr_pair));
1479 1485
1480 1486 /* disable_peg_cache_all */
1481 1487
1482 1488 /* p2dn replyCount */
1483 1489 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0xec, 0x1e);
1484 1490 /* disable_peg_cache 0 */
1485 1491 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0x4c, 8);
1486 1492 /* disable_peg_cache 1 */
1487 1493 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_I + 0x4c, 8);
1488 1494
1489 1495 /* peg_clr_all */
1490 1496 /* peg_clr 0 */
1491 1497 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x8, 0);
1492 1498 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0xc, 0);
1493 1499 /* peg_clr 1 */
1494 1500 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x8, 0);
1495 1501 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0xc, 0);
1496 1502 /* peg_clr 2 */
1497 1503 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x8, 0);
1498 1504 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0xc, 0);
1499 1505 /* peg_clr 3 */
1500 1506 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x8, 0);
1501 1507 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0xc, 0);
1502 1508
1503 1509 return (0);
1504 1510 }
|
↓ open down ↓ |
113 lines elided |
↑ open up ↑ |
1505 1511
1506 1512 static int
1507 1513 ql_8021_load_from_flash(ql_adapter_state_t *ha)
1508 1514 {
1509 1515 int i;
1510 1516 uint32_t flashaddr, memaddr;
1511 1517 uint32_t high, low, size;
1512 1518 uint64_t data;
1513 1519
1514 1520 size = ha->bootloader_size / 2;
1515 - flashaddr = ha->bootloader_addr << 2;
1516 - memaddr = BOOTLD_START;
1521 + memaddr = flashaddr = ha->bootloader_addr << 2;
1517 1522
1518 1523 for (i = 0; i < size; i++) {
1519 1524 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1520 1525 (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1521 1526 EL(ha, "ql_8021_rom_fast_read != 0\n");
1522 1527 return (-1);
1523 1528 }
1524 1529 data = ((uint64_t)high << 32) | low;
1525 - (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1530 + if (ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8)) {
1531 + EL(ha, "qla_fc_8021_pci_mem_write_2M != 0\n");
1532 + return (-1);
1533 + }
1526 1534 flashaddr += 8;
1527 1535 memaddr += 8;
1536 +
1537 + /* Allow other system activity. */
1538 + if (i % 0x1000 == 0) {
1539 + /* Delay for 1 tick (10ms). */
1540 + delay(1);
1541 + }
1528 1542 }
1529 1543
1544 +#if 0
1545 + /* Allow other system activity, delay for 1 tick (10ms). */
1546 + delay(1);
1547 +
1530 1548 size = ha->flash_fw_size / 2;
1531 - flashaddr = ha->flash_fw_addr << 2;
1532 - memaddr = IMAGE_START;
1549 + memaddr = flashaddr = ha->flash_fw_addr << 2;
1533 1550
1534 1551 for (i = 0; i < size; i++) {
1535 1552 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1536 1553 (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1537 1554 EL(ha, "ql_8021_rom_fast_read3 != 0\n");
1538 1555 return (-1);
1539 1556 }
1540 1557 data = ((uint64_t)high << 32) | low;
1541 1558 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1542 1559 flashaddr += 8;
1543 1560 memaddr += 8;
1544 - }
1545 1561
1562 + /* Allow other system activity. */
1563 + if (i % 0x1000 == 0) {
1564 + /* Delay for 1 tick (10ms). */
1565 + delay(1);
1566 + }
1567 + }
1568 +#endif
1546 1569 return (0);
1547 1570 }
1548 1571
1549 1572 static int
1550 1573 ql_8021_load_firmware(ql_adapter_state_t *ha)
1551 1574 {
1552 1575 uint64_t data;
1553 1576 uint32_t i, flashaddr, size;
1554 1577 uint8_t *bp, n, *dp;
1555 1578
1556 1579 bp = (uint8_t *)(ha->risc_fw[0].code);
1557 1580 dp = (uint8_t *)&size;
1558 1581 for (n = 0; n < 4; n++) {
1559 1582 dp[n] = *bp++;
1560 1583 }
1561 1584 LITTLE_ENDIAN_32(&size);
1562 1585 EL(ha, "signature=%x\n", size);
1563 1586
1564 - size = (IMAGE_START - BOOTLD_START) / 8;
1587 + size = ha->bootloader_size / 2;
1588 + flashaddr = ha->bootloader_addr << 2;
1565 1589
1566 - bp = (uint8_t *)(ha->risc_fw[0].code + BOOTLD_START);
1567 - flashaddr = BOOTLD_START;
1568 -
1590 + bp = (uint8_t *)(ha->risc_fw[0].code + flashaddr);
1569 1591 dp = (uint8_t *)&data;
1570 1592 for (i = 0; i < size; i++) {
1571 1593 for (n = 0; n < 8; n++) {
1572 1594 dp[n] = *bp++;
1573 1595 }
1574 1596 LITTLE_ENDIAN_64(&data);
1575 - (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1597 + if (ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8)) {
1598 + EL(ha, "qla_fc_8021_pci_mem_write_2M != 0\n");
1599 + return (-1);
1600 + }
1576 1601 flashaddr += 8;
1577 1602 }
1578 1603
1579 1604 bp = (uint8_t *)(ha->risc_fw[0].code + FW_SIZE_OFFSET);
1580 1605 dp = (uint8_t *)&size;
1581 1606 for (n = 0; n < 4; n++) {
1582 1607 dp[n] = *bp++;
1583 1608 }
1584 1609 LITTLE_ENDIAN_32(&size);
1585 1610 EL(ha, "IMAGE_START size=%llx\n", size);
1586 1611 size = (size + 7) / 8;
1587 1612
1588 - bp = (uint8_t *)(ha->risc_fw[0].code + IMAGE_START);
1589 - flashaddr = IMAGE_START;
1613 + flashaddr = ha->flash_fw_addr << 2;
1614 + bp = (uint8_t *)(ha->risc_fw[0].code + flashaddr);
1590 1615
1591 1616 dp = (uint8_t *)&data;
1592 1617 for (i = 0; i < size; i++) {
1593 1618 for (n = 0; n < 8; n++) {
1594 1619 dp[n] = *bp++;
1595 1620 }
1596 1621 LITTLE_ENDIAN_64(&data);
1597 - (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1622 + if (ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8)) {
1623 + EL(ha, "qla_fc_8021_pci_mem_write_2M != 0\n");
1624 + return (-1);
1625 + }
1598 1626 flashaddr += 8;
1599 1627 }
1600 1628
1601 1629 return (0);
1602 1630 }
1603 1631
1604 1632 static int
1605 1633 ql_8021_init_p3p(ql_adapter_state_t *ha)
1606 1634 {
1607 1635 uint32_t data;
1608 1636
1609 1637 /* ??? */
1610 1638 ql_8021_wr_32(ha, UNM_PORT_MODE_ADDR, UNM_PORT_MODE_AUTO_NEG);
1611 1639 delay(drv_usectohz(1000000));
1612 1640
1613 1641 /* CAM RAM Cold Boot Register */
1614 1642 ql_8021_rd_32(ha, UNM_RAM_COLD_BOOT, &data);
1615 1643 if (data == 0x55555555) {
1616 1644 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &data);
1617 1645 if (data != 0x80000f) {
1618 1646 EL(ha, "CRB_UNM_GLB_SW_RST=%x exit\n", data);
1619 1647 return (-1);
1620 1648 }
1621 1649 ql_8021_wr_32(ha, UNM_RAM_COLD_BOOT, 0);
1622 1650 }
1623 1651 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, &data);
1624 1652 data |= 1;
1625 1653 ql_8021_wr_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, data);
1626 1654
1627 1655 /*
1628 1656 * ???
1629 1657 * data = ha->pci_bus_addr | BIT_31;
1630 1658 * ql_8021_wr_32(ha, UNM_BUS_DEV_NO, data);
1631 1659 */
1632 1660
1633 1661 return (0);
1634 1662 }
1635 1663
1636 1664 /* ARGSUSED */
1637 1665 void
1638 1666 ql_8021_reset_chip(ql_adapter_state_t *ha)
|
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
1639 1667 {
1640 1668 /*
1641 1669 * Disable interrupts does not work on a per function bases
1642 1670 * leave them enabled
1643 1671 */
1644 1672 ql_8021_enable_intrs(ha);
1645 1673
1646 1674 ADAPTER_STATE_LOCK(ha);
1647 1675 ha->flags |= INTERRUPTS_ENABLED;
1648 1676 ADAPTER_STATE_UNLOCK(ha);
1649 -
1650 - (void) ql_stop_firmware(ha);
1677 + if (!(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
1678 + (void) ql_stop_firmware(ha);
1679 + }
1651 1680 }
1652 1681
1653 1682 static int
1654 1683 ql_8021_reset_hw(ql_adapter_state_t *ha, int type)
1655 1684 {
1656 1685 int ret;
1657 1686 uint32_t rst;
1658 1687
1659 1688 /* scrub dma mask expansion register */
1660 1689 ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1661 1690
1662 1691 /* Overwrite stale initialization register values */
1663 1692 ql_8021_wr_32(ha, CRB_CMDPEG_STATE, 0);
1664 1693 ql_8021_wr_32(ha, CRB_RCVPEG_STATE, 0);
1665 1694 ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0);
1666 1695 ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0);
1667 1696
1668 - (void) ql_8021_pinit_from_rom(ha);
1697 + /*
1698 + * This reset sequence is to provide a graceful shutdown of the
1699 + * different hardware blocks prior to performing an ASIC Reset,
1700 + * has to be done before writing 0xffffffff to ASIC_RESET.
1701 + */
1702 + ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x10, 0);
1703 + ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x14, 0);
1704 + ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x18, 0);
1705 + ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x1c, 0);
1706 + ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x20, 0);
1707 + ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x24, 0);
1708 + ql_8021_wr_32(ha, UNM_CRB_NIU + 0x40, 0xff);
1709 + ql_8021_wr_32(ha, UNM_CRB_NIU + 0x70000, 0x0);
1710 + ql_8021_wr_32(ha, UNM_CRB_NIU + 0x80000, 0x0);
1711 + ql_8021_wr_32(ha, UNM_CRB_NIU + 0x90000, 0x0);
1712 + ql_8021_wr_32(ha, UNM_CRB_NIU + 0xa0000, 0x0);
1713 + ql_8021_wr_32(ha, UNM_CRB_NIU + 0xb0000, 0x0);
1714 + ql_8021_wr_32(ha, UNM_CRB_SRE + 0x1000, 0x28ff000c);
1715 + ql_8021_wr_32(ha, UNM_CRB_EPG + 0x1300, 0x1);
1716 + ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x0, 0x0);
1717 + ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x8, 0x0);
1718 + ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x10, 0x0);
1719 + ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x18, 0x0);
1720 + ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x100, 0x0);
1721 + ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x200, 0x0);
1722 + ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x3C, 0x1);
1723 + ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x3C, 0x1);
1724 + ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x3C, 0x1);
1725 + ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x3C, 0x1);
1726 + ql_8021_wr_32(ha, UNM_CRB_PEG_NET_4 + 0x3C, 0x1);
1669 1727 delay(1);
1670 1728
1729 + ret = ql_8021_pinit_from_rom(ha);
1730 + if (ret) {
1731 + EL(ha, "pinit_from_rom ret=%d\n", ret);
1732 + return (ret);
1733 + }
1734 + delay(1);
1735 +
1671 1736 /* Bring QM and CAMRAM out of reset */
1672 1737 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &rst);
1673 1738 rst &= ~((1 << 28) | (1 << 24));
1674 1739 ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, rst);
1675 1740
1676 1741 switch (type) {
1677 1742 case 0:
1678 1743 ret = ql_8021_init_p3p(ha);
1679 1744 break;
1680 1745 case 1:
1681 1746 ret = ql_8021_load_from_flash(ha);
1682 1747 break;
1683 1748 case 2:
1684 1749 ret = ql_8021_load_firmware(ha);
1685 1750 break;
1686 1751 }
1687 1752 delay(1);
1688 1753
1689 1754 ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x18, 0x1020);
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
1690 1755 ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0x80001e);
1691 1756
1692 1757 if (ret) {
1693 1758 EL(ha, "type=%d, ret=%d\n", type, ret);
1694 1759 } else {
1695 1760 ret = ql_8021_phantom_init(ha);
1696 1761 }
1697 1762 return (ret);
1698 1763 }
1699 1764
1700 -int
1701 -ql_8021_load_risc(ql_adapter_state_t *ha)
1765 +static int
1766 +ql_8021_load_fw(ql_adapter_state_t *ha)
1702 1767 {
1703 - int rv = 0;
1704 - static int ql_8021_fw_loaded = 0;
1768 + int rv = 0;
1705 1769
1706 1770 GLOBAL_HW_LOCK();
1707 - if (!ql_8021_fw_loaded) {
1708 - if (ha->risc_fw[0].code) {
1709 - EL(ha, "from driver\n");
1710 - rv = ql_8021_reset_hw(ha, 2);
1711 - } else {
1712 - /*
1713 - * BIOS method
1714 - * ql_8021_reset_hw(ha, 0)
1715 - */
1716 - EL(ha, "from flash\n");
1717 - rv = ql_8021_reset_hw(ha, 1);
1718 - }
1719 - if (rv == 0) {
1720 - ql_8021_fw_loaded = 1;
1771 + if (ha->risc_fw[0].code) {
1772 + EL(ha, "from driver\n");
1773 + rv = ql_8021_reset_hw(ha, 2);
1774 + } else {
1775 + /*
1776 + * BIOS method
1777 + * ql_8021_reset_hw(ha, 0)
1778 + */
1779 + EL(ha, "from flash\n");
1780 + rv = ql_8021_reset_hw(ha, 1);
1781 + }
1782 + if (rv == 0) {
1783 + ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1784 + ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
1785 + ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
1721 1786
1722 - ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1723 - ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
1724 - ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
1787 + GLOBAL_HW_UNLOCK();
1725 1788
1726 - GLOBAL_HW_UNLOCK();
1789 + ADAPTER_STATE_LOCK(ha);
1790 + ha->flags &= ~INTERRUPTS_ENABLED;
1791 + ADAPTER_STATE_UNLOCK(ha);
1727 1792
1728 - ADAPTER_STATE_LOCK(ha);
1729 - ha->flags &= ~INTERRUPTS_ENABLED;
1730 - ADAPTER_STATE_UNLOCK(ha);
1793 + /* clear the mailbox command pointer. */
1794 + INTR_LOCK(ha);
1795 + ha->mcp = NULL;
1796 + INTR_UNLOCK(ha);
1731 1797
1732 - (void) ql_8021_enable_intrs(ha);
1798 + MBX_REGISTER_LOCK(ha);
1799 + ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
1800 + ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
1801 + MBX_REGISTER_UNLOCK(ha);
1733 1802
1734 - ADAPTER_STATE_LOCK(ha);
1735 - ha->flags |= INTERRUPTS_ENABLED;
1736 - ADAPTER_STATE_UNLOCK(ha);
1737 - } else {
1738 - GLOBAL_HW_UNLOCK();
1739 - }
1803 + (void) ql_8021_enable_intrs(ha);
1804 +
1805 + ADAPTER_STATE_LOCK(ha);
1806 + ha->flags |= INTERRUPTS_ENABLED;
1807 + ADAPTER_STATE_UNLOCK(ha);
1740 1808 } else {
1741 1809 GLOBAL_HW_UNLOCK();
1742 - EL(ha, "Firmware loaded by other function\n");
1743 1810 }
1744 1811
1745 1812 if (rv == 0) {
1746 1813 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR, &ha->fw_major_version);
1747 1814 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR, &ha->fw_minor_version);
1748 1815 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB, &ha->fw_subminor_version);
1749 1816 EL(ha, "fw v%d.%02d.%02d\n", ha->fw_major_version,
1750 1817 ha->fw_minor_version, ha->fw_subminor_version);
1751 1818 } else {
1752 1819 EL(ha, "status = -1\n");
1753 - return (QL_FUNCTION_FAILED);
1754 1820 }
1755 1821
1756 - return (QL_SUCCESS);
1822 + return (rv);
1757 1823 }
1758 1824
1759 1825 void
1760 1826 ql_8021_clr_hw_intr(ql_adapter_state_t *ha)
1761 1827 {
1762 1828 ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
1763 1829 ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1764 1830 ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1765 1831 }
1766 1832
1767 1833 void
1768 1834 ql_8021_clr_fw_intr(ql_adapter_state_t *ha)
1769 1835 {
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1770 1836 WRT32_IO_REG(ha, nx_risc_int, 0);
1771 1837 ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xfbff);
1772 1838 }
1773 1839
1774 1840 void
1775 1841 ql_8021_enable_intrs(ql_adapter_state_t *ha)
1776 1842 {
1777 1843 GLOBAL_HW_LOCK();
1778 1844 ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
1779 1845 GLOBAL_HW_UNLOCK();
1780 - (void) ql_toggle_interrupt(ha, 1);
1846 + if (!(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
1847 + (void) ql_toggle_interrupt(ha, 1);
1848 + }
1781 1849 }
1782 1850
1783 1851 void
1784 1852 ql_8021_disable_intrs(ql_adapter_state_t *ha)
1785 1853 {
1786 1854 (void) ql_toggle_interrupt(ha, 0);
1787 1855 GLOBAL_HW_LOCK();
1788 1856 ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
1789 1857 GLOBAL_HW_UNLOCK();
1790 1858 }
1791 1859
1792 1860 void
1793 1861 ql_8021_update_crb_int_ptr(ql_adapter_state_t *ha)
1794 1862 {
1795 1863 struct legacy_intr_set *nx_legacy_intr;
1796 1864
1797 1865 ha->qdr_sn_window = (uint32_t)-1;
1798 - ha->ddr_mn_window = (uint32_t)-1;
1799 - nx_legacy_intr = &legacy_intr[ha->function_number];
1866 + nx_legacy_intr = &legacy_intr[ha->pci_function_number];
1800 1867
1801 1868 ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
1802 1869 ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
1803 1870 ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
1804 1871 ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
1805 1872 }
1806 1873
1807 1874 void
1808 1875 ql_8021_set_drv_active(ql_adapter_state_t *ha)
1809 1876 {
1810 1877 uint32_t val;
1811 1878
1812 1879 if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1813 1880 return;
1814 1881 }
1815 1882
1816 1883 ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1817 1884 if (val == 0xffffffff) {
1818 - val = (1 << (ha->function_number * 4));
1885 + val = (1 << (ha->pci_function_number * 4));
1819 1886 } else {
1820 - val |= (1 << (ha->function_number * 4));
1887 + val |= (1 << (ha->pci_function_number * 4));
1821 1888 }
1822 1889 ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1823 1890
1824 1891 ql_8021_hw_unlock(ha);
1825 1892 }
1826 1893
1827 1894 void
1828 1895 ql_8021_clr_drv_active(ql_adapter_state_t *ha)
1829 1896 {
1830 1897 uint32_t val;
1831 1898
1832 1899 if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1833 1900 return;
1834 1901 }
1835 1902
1836 1903 ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1837 - val &= ~(1 << (ha->function_number * 4));
1904 + val &= ~(1 << (ha->pci_function_number * 4));
1838 1905 ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1839 1906
1840 1907 ql_8021_hw_unlock(ha);
1841 1908 }
1842 1909
1843 1910 static void
1844 1911 ql_8021_need_reset_handler(ql_adapter_state_t *ha)
1845 1912 {
1846 - uint32_t drv_state, drv_active;
1847 - clock_t timer;
1913 + uint32_t drv_state, drv_active, cnt;
1848 1914
1849 - (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1850 -
1851 1915 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1852 - drv_state |= (1 << (ha->function_number * 4));
1916 + if (drv_state == 0xffffffff) {
1917 + drv_state = 0;
1918 + }
1919 + if (!(ha->ql_dump_state & QL_DUMPING)) {
1920 + drv_state |= (1 << (ha->pci_function_number * 4));
1921 + }
1853 1922 ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1854 1923
1855 - ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1856 -
1857 - ql_8021_hw_unlock(ha);
1858 -
1859 - for (timer = 30; timer && drv_state != drv_active; timer--) {
1924 + for (cnt = 60; cnt; cnt--) {
1925 + ql_8021_hw_unlock(ha);
1860 1926 delay(100);
1861 -
1862 1927 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1928 +
1863 1929 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1864 1930 ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1865 - ql_8021_hw_unlock(ha);
1931 + if (ha->ql_dump_state & QL_DUMPING) {
1932 + drv_state |= (1 << (ha->pci_function_number * 4));
1933 + }
1934 + if (drv_state == drv_active) {
1935 + if (ha->ql_dump_state & QL_DUMPING) {
1936 + ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1937 + }
1938 + break;
1939 + }
1866 1940 }
1867 1941 }
1868 1942
1869 -uint32_t
1870 -ql_8021_idc_handler(ql_adapter_state_t *ha)
1943 +int
1944 +ql_8021_fw_reload(ql_adapter_state_t *ha)
1871 1945 {
1872 - uint32_t dev_state, drv_state, rval;
1873 - clock_t timer;
1946 + int rval;
1947 +
1948 + (void) ql_stall_driver(ha, BIT_0);
1949 +
1950 + (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1951 + ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
1952 + ql_8021_hw_unlock(ha);
1953 +
1954 + rval = ql_8021_load_fw(ha) == 0 ? NX_DEV_READY : NX_DEV_FAILED;
1955 +
1956 + (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1957 + ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
1958 + ql_8021_hw_unlock(ha);
1959 +
1960 + TASK_DAEMON_LOCK(ha);
1961 + ha->task_daemon_flags &= ~(TASK_DAEMON_STALLED_FLG | DRIVER_STALL);
1962 + TASK_DAEMON_UNLOCK(ha);
1963 +
1964 + if (rval != NX_DEV_READY) {
1965 + EL(ha, "status=%xh\n", QL_FUNCTION_FAILED);
1966 + return (QL_FUNCTION_FAILED);
1967 + }
1968 + return (QL_SUCCESS);
1969 +}
1970 +
1971 +void
1972 +ql_8021_idc_poll(ql_adapter_state_t *ha)
1973 +{
1974 + uint32_t new_state;
1975 +
1976 + if (ha->ql_dump_state & QL_DUMPING) {
1977 + return;
1978 + }
1979 + new_state = ql_8021_check_fw_alive(ha);
1980 +
1981 + if (new_state == NX_DEV_NEED_RESET &&
1982 + !(ha->ql_dump_state & QL_DUMPING ||
1983 + (ha->ql_dump_state & QL_DUMP_VALID &&
1984 + !(ha->ql_dump_state & QL_DUMP_UPLOADED)))) {
1985 + (void) ql_dump_firmware(ha);
1986 + } else {
1987 + (void) ql_8021_idc_handler(ha, new_state);
1988 + }
1989 +}
1990 +
1991 +int
1992 +ql_8021_idc_handler(ql_adapter_state_t *ha, uint32_t new_state)
1993 +{
1994 + int rval;
1995 + uint32_t dev_state, drv_state, loop;
1874 1996 ql_mbx_data_t mr;
1875 - boolean_t stalled = B_FALSE, lock = B_FALSE;
1997 + boolean_t stalled = B_FALSE, reset_needed = B_FALSE;
1998 + boolean_t force_load = B_FALSE;
1876 1999
1877 - /* wait for 30 seconds for device to go ready */
1878 - timer = 30;
1879 - while (timer) {
1880 - if (lock == B_FALSE) {
1881 - (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1882 - lock = B_TRUE;
2000 + (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2001 +
2002 + /* wait for 180 seconds for device to go ready */
2003 + for (loop = 180; loop; loop--) {
2004 + if (new_state != NX_DEV_POLL) {
2005 + ql_8021_wr_32(ha, CRB_DEV_STATE, new_state);
2006 + dev_state = new_state;
2007 + new_state = NX_DEV_POLL;
2008 + } else {
2009 + ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
1883 2010 }
1884 - ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
1885 2011
1886 2012 switch (dev_state) {
1887 2013 case 0xffffffff:
1888 2014 case NX_DEV_COLD:
1889 - EL(ha, "dev_state=NX_DEV_COLD\n");
2015 + if (ha->dev_state != dev_state) {
2016 + EL(ha, "dev_state=NX_DEV_COLD\n");
2017 + }
1890 2018 rval = NX_DEV_COLD;
1891 2019 ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
1892 2020 ql_8021_wr_32(ha, CRB_DRV_IDC_VERSION, NX_IDC_VERSION);
1893 - (void) ql_8021_hw_unlock(ha);
1894 - if (ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&
2021 + ql_8021_hw_unlock(ha);
2022 + if (!force_load &&
2023 + ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&
1895 2024 (mr.mb[1] | mr.mb[2] | mr.mb[3])) {
1896 2025 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR,
1897 2026 &ha->fw_major_version);
1898 2027 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR,
1899 2028 &ha->fw_minor_version);
1900 2029 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB,
1901 2030 &ha->fw_subminor_version);
1902 2031 rval = NX_DEV_READY;
1903 - } else if (ql_8021_load_risc(ha) == QL_SUCCESS) {
1904 - rval = NX_DEV_READY;
2032 + } else {
2033 + if (!stalled) {
2034 + TASK_DAEMON_LOCK(ha);
2035 + ha->task_daemon_flags |=
2036 + TASK_DAEMON_STALLED_FLG;
2037 + TASK_DAEMON_UNLOCK(ha);
2038 + ql_abort_queues(ha);
2039 + stalled = B_TRUE;
2040 + }
2041 + if (ha->ql_dump_state & QL_DUMPING) {
2042 + (void) ql_8021_get_fw_dump(ha);
2043 + }
2044 + rval = ql_8021_load_fw(ha) == 0 ?
2045 + NX_DEV_READY : NX_DEV_FAILED;
1905 2046 }
1906 2047 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1907 2048 ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
1908 2049 break;
1909 2050 case NX_DEV_READY:
2051 + if (ha->dev_state != dev_state) {
2052 + EL(ha, "dev_state=NX_DEV_READY\n");
2053 + }
1910 2054 rval = NX_DEV_READY;
1911 - timer = 0;
2055 + loop = 1;
1912 2056 break;
1913 2057 case NX_DEV_FAILED:
1914 - EL(ha, "dev_state=NX_DEV_FAILED\n");
2058 + if (ha->dev_state != dev_state) {
2059 + EL(ha, "dev_state=NX_DEV_FAILED\n");
2060 + }
1915 2061 rval = NX_DEV_FAILED;
1916 - timer = 0;
2062 + loop = 1;
1917 2063 break;
1918 -
1919 2064 case NX_DEV_NEED_RESET:
1920 - EL(ha, "dev_state=NX_DEV_NEED_RESET\n");
2065 + if (ha->dev_state != dev_state) {
2066 + EL(ha, "dev_state=NX_DEV_NEED_RESET\n");
2067 + }
1921 2068 rval = NX_DEV_NEED_RESET;
1922 - (void) ql_8021_hw_unlock(ha);
1923 - lock = B_FALSE;
1924 - if (ql_stall_driver(ha, 0) == QL_SUCCESS) {
1925 - stalled = B_TRUE;
1926 - ql_8021_need_reset_handler(ha);
2069 + ql_8021_need_reset_handler(ha);
2070 + /*
2071 + * Force to DEV_COLD unless someone else is starting
2072 + * a reset
2073 + */
2074 + ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
2075 + if (dev_state == NX_DEV_NEED_RESET) {
2076 + EL(ha, "HW State: COLD/RE-INIT\n");
2077 + ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_COLD);
2078 + force_load = B_TRUE;
1927 2079 }
2080 + reset_needed = B_TRUE;
1928 2081 break;
1929 -
1930 2082 case NX_DEV_NEED_QUIESCENT:
1931 - EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
1932 - (void) ql_8021_hw_unlock(ha);
1933 - lock = B_FALSE;
1934 - rval = ql_stall_driver(ha, 0);
1935 - if (rval == QL_SUCCESS) {
2083 + if (ha->dev_state != dev_state) {
2084 + EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
2085 + }
2086 + ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
2087 + drv_state |= (2 << (ha->pci_function_number * 4));
2088 + ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
2089 + ql_8021_hw_unlock(ha);
2090 + if (!stalled) {
2091 + TASK_DAEMON_LOCK(ha);
2092 + ha->task_daemon_flags |=
2093 + TASK_DAEMON_STALLED_FLG;
2094 + TASK_DAEMON_UNLOCK(ha);
2095 + (void) ql_stall_driver(ha, BIT_0);
1936 2096 stalled = B_TRUE;
1937 - (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1938 - lock = B_TRUE;
1939 - ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1940 - drv_state |=
1941 - (2 << (ha->function_number * 4));
1942 - ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1943 2097 }
2098 + (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1944 2099 break;
1945 -
1946 2100 case NX_DEV_INITIALIZING:
1947 - EL(ha, "dev_state=NX_DEV_INITIALIZING\n");
2101 + if (ha->dev_state != dev_state) {
2102 + EL(ha, "dev_state=NX_DEV_INITIALIZING\n");
2103 + }
2104 + ql_8021_hw_unlock(ha);
2105 + if (!stalled) {
2106 + TASK_DAEMON_LOCK(ha);
2107 + ha->task_daemon_flags |=
2108 + TASK_DAEMON_STALLED_FLG;
2109 + TASK_DAEMON_UNLOCK(ha);
2110 + ql_awaken_task_daemon(ha, NULL,
2111 + DRIVER_STALL, 0);
2112 + stalled = B_TRUE;
2113 + ql_requeue_all_cmds(ha);
2114 + ADAPTER_STATE_LOCK(ha);
2115 + ha->flags &= ~INTERRUPTS_ENABLED;
2116 + ADAPTER_STATE_UNLOCK(ha);
2117 + }
2118 + delay(100);
2119 + (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2120 + reset_needed = B_TRUE;
1948 2121 break;
1949 2122 case NX_DEV_QUIESCENT:
1950 - EL(ha, "dev_state=NX_DEV_QUIESCENT\n");
2123 + if (ha->dev_state != dev_state) {
2124 + EL(ha, "dev_state=NX_DEV_QUIESCENT\n");
2125 + }
2126 + ql_8021_hw_unlock(ha);
2127 + delay(100);
2128 + (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1951 2129 break;
1952 2130 default:
1953 - EL(ha, "dev_state=%x, default\n", dev_state);
2131 + if (ha->dev_state != dev_state) {
2132 + EL(ha, "dev_state=%x, default\n", dev_state);
2133 + }
2134 + ql_8021_hw_unlock(ha);
2135 + delay(100);
2136 + (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1954 2137 break;
1955 2138 }
1956 - if (lock == B_TRUE) {
1957 - (void) ql_8021_hw_unlock(ha);
1958 - lock = B_FALSE;
2139 + ha->dev_state = dev_state;
2140 + }
2141 +
2142 + /* Clear reset ready and quiescent flags. */
2143 + ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
2144 + drv_state &= ~(1 << (ha->pci_function_number * 4));
2145 + drv_state &= ~(2 << (ha->pci_function_number * 4));
2146 + ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
2147 +
2148 + ql_8021_hw_unlock(ha);
2149 + if (reset_needed && ha->flags & ONLINE &&
2150 + !(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
2151 + delay(100);
2152 + ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0);
2153 + }
2154 + if (stalled) {
2155 + TASK_DAEMON_LOCK(ha);
2156 + ha->task_daemon_flags &= ~TASK_DAEMON_STALLED_FLG;
2157 + TASK_DAEMON_UNLOCK(ha);
2158 + ql_restart_driver(ha);
2159 + }
2160 + return (rval);
2161 +}
2162 +
2163 +void
2164 +ql_8021_wr_req_in(ql_adapter_state_t *ha, uint32_t index)
2165 +{
2166 + index = index << 16 | ha->pci_function_number << 5 | 4;
2167 +
2168 + if (NX_IS_REVISION_P3PLUS_B0(ha->rev_id)) {
2169 + uint64_t addr;
2170 +
2171 + addr = ha->function_number ? (uint64_t)CRB_PORT_1_REQIN :
2172 + (uint64_t)CRB_PORT_0_REQIN;
2173 + ql_8021_wr_32(ha, addr, index);
2174 + } else {
2175 + do {
2176 + ddi_put32(ha->db_dev_handle, ha->nx_req_in, index);
2177 + } while (RD_REG_DWORD(ha, ha->db_read) != index);
2178 + }
2179 +}
2180 +
2181 +/* Called every 2 seconds */
2182 +static uint32_t
2183 +ql_8021_check_fw_alive(ql_adapter_state_t *ha)
2184 +{
2185 + uint32_t dev_state, fw_heartbeat_counter, cnt, data[7];
2186 + uint32_t new_state = NX_DEV_POLL;
2187 +
2188 + ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
2189 + if (dev_state != NX_DEV_READY) {
2190 + return (new_state);
2191 + }
2192 +
2193 + ql_8021_rd_32(ha, UNM_PEG_ALIVE_COUNTER, &fw_heartbeat_counter);
2194 +
2195 + if (ha->fw_heartbeat_counter == fw_heartbeat_counter) {
2196 + ha->seconds_since_last_heartbeat++;
2197 + /* FW not alive after 6 seconds */
2198 + if (ha->seconds_since_last_heartbeat == 3) {
2199 + ha->seconds_since_last_heartbeat = 0;
2200 + /* FW not alive after 5 milliseconds */
2201 + for (cnt = 5; cnt; cnt--) {
2202 + ql_8021_rd_32(ha, UNM_PEG_ALIVE_COUNTER,
2203 + &fw_heartbeat_counter);
2204 + if (ha->fw_heartbeat_counter !=
2205 + fw_heartbeat_counter) {
2206 + break;
2207 + }
2208 + drv_usecwait(1000);
2209 + }
2210 + if (ha->fw_heartbeat_counter == fw_heartbeat_counter) {
2211 + EL(ha, "nx_dev_need_reset\n");
2212 + ql_8021_rd_32(ha, UNM_PEG_HALT_STATUS1,
2213 + &data[0]);
2214 + ql_8021_rd_32(ha, UNM_PEG_HALT_STATUS2,
2215 + &data[1]);
2216 + ql_8021_rd_32(ha, UNM_CRB_PEG_NET_0 + 0x3C,
2217 + &data[2]);
2218 + ql_8021_rd_32(ha, UNM_CRB_PEG_NET_1 + 0x3C,
2219 + &data[3]);
2220 + ql_8021_rd_32(ha, UNM_CRB_PEG_NET_2 + 0x3C,
2221 + &data[4]);
2222 + ql_8021_rd_32(ha, UNM_CRB_PEG_NET_3 + 0x3C,
2223 + &data[5]);
2224 + ql_8021_rd_32(ha, UNM_CRB_PEG_NET_4 + 0x3C,
2225 + &data[6]);
2226 + EL(ha, "halt_status1=%xh, halt_status2=%xh,\n"
2227 + "peg_pc0=%xh, peg_pc1=%xh, peg_pc2=%xh, "
2228 + "peg_pc3=%xh, peg_pc4=%xh\n", data[0],
2229 + data[1], data[2], data[3], data[4],
2230 + data[5], data[6]);
2231 + new_state = NX_DEV_NEED_RESET;
2232 + }
1959 2233 }
2234 + } else {
2235 + ha->seconds_since_last_heartbeat = 0;
2236 + }
1960 2237
1961 - if (timer) {
1962 - delay(100);
1963 - timer--;
2238 + ha->fw_heartbeat_counter = fw_heartbeat_counter;
2239 + return (new_state);
2240 +}
2241 +
2242 +int
2243 +ql_8021_reset_fw(ql_adapter_state_t *ha)
2244 +{
2245 + return (ql_8021_idc_handler(ha, NX_DEV_NEED_RESET));
2246 +}
2247 +
2248 +int
2249 +ql_8021_fw_chk(ql_adapter_state_t *ha)
2250 +{
2251 + uint32_t dev_state, new_state = NX_DEV_POLL;
2252 + int rval;
2253 + ql_mbx_data_t mr;
2254 +
2255 + ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
2256 + switch (dev_state) {
2257 + case 0xffffffff:
2258 + case NX_DEV_COLD:
2259 + case NX_DEV_NEED_RESET:
2260 + case NX_DEV_NEED_QUIESCENT:
2261 + case NX_DEV_INITIALIZING:
2262 + case NX_DEV_QUIESCENT:
2263 + case NX_DEV_BADOBADO:
2264 + break;
2265 + case NX_DEV_READY:
2266 + if (ql_get_fw_version(ha, &mr, 2) != QL_SUCCESS ||
2267 + (mr.mb[1] | mr.mb[2] | mr.mb[3]) == 0) {
2268 + EL(ha, "version check needs reset\n", dev_state);
2269 + new_state = NX_DEV_NEED_RESET;
1964 2270 }
2271 + break;
2272 + case NX_DEV_FAILED:
2273 + EL(ha, "device needs reset\n");
2274 + new_state = NX_DEV_NEED_RESET;
2275 + break;
2276 + default:
2277 + EL(ha, "state=%xh needs reset\n", dev_state);
2278 + new_state = NX_DEV_COLD;
2279 + break;
1965 2280 }
1966 2281
1967 - if (stalled) {
1968 - ql_restart_driver(ha);
2282 + /* Test for firmware running. */
2283 + rval = ql_8021_idc_handler(ha, new_state) == NX_DEV_READY ?
2284 + QL_SUCCESS : QL_FUNCTION_FAILED;
2285 +
2286 + return (rval);
2287 +}
2288 +
2289 +/* ****************************************************************** */
2290 +/* ***************** NetXen MiniDump Functions ********************** */
2291 +/* ****************************************************************** */
2292 +
2293 +/*
2294 + * ql_8021_get_fw_dump
2295 + *
2296 + * Input:
2297 + * pi: FC port info pointer.
2298 + *
2299 + * Returns:
2300 + * qla driver local function return status codes
2301 + *
2302 + * Context:
2303 + * Interrupt or Kernel context, no mailbox commands allowed.
2304 + */
2305 +static int
2306 +ql_8021_get_fw_dump(ql_adapter_state_t *ha)
2307 +{
2308 + uint32_t tsize, cnt, *dp, *bp;
2309 +
2310 + QL_PRINT_10(ha, "started\n");
2311 +
2312 + tsize = ha->dmp_template.size;
2313 + cnt = (uint32_t)(tsize / sizeof (uint32_t));
2314 + dp = (uint32_t *)ha->ql_dump_ptr;
2315 + bp = (uint32_t *)ha->dmp_template.bp;
2316 + while (cnt--) {
2317 + *dp++ = ddi_get32(ha->dmp_template.acc_handle, bp++);
1969 2318 }
2319 + ql_8021_md_parse_template(ha, ha->ql_dump_ptr, (caddr_t)dp,
2320 + ha->md_capture_size - tsize, ha->md_capture_mask);
2321 +
2322 +#ifdef _BIG_ENDIAN
2323 + cnt = (uint32_t)(ha->ql_dump_size / sizeof (uint32_t));
2324 + dp = (uint32_t *)ha->ql_dump_ptr;
2325 + while (cnt--) {
2326 + ql_chg_endian((uint8_t *)dp, 4);
2327 + dp++;
2328 + }
2329 +#endif
2330 + QL_PRINT_10(ha, "done\n");
2331 + return (QL_SUCCESS);
2332 +}
2333 +
2334 +/*
2335 + * ql_8021_get_md_template
2336 + * Get mini-dump template
2337 + *
2338 + * Input:
2339 + * ha: adapter state pointer.
2340 + *
2341 + * Returns:
2342 + * ql local function return status code.
2343 + *
2344 + * Context:
2345 + * Kernel context.
2346 + */
2347 +int
2348 +ql_8021_get_md_template(ql_adapter_state_t *ha)
2349 +{
2350 + ql_mbx_data_t mr;
2351 + uint32_t tsize, chksum;
2352 + int rval;
2353 +
2354 + rval = ql_get_md_template(ha, NULL, &mr, 0, GTO_TEMPLATE_SIZE);
2355 + if (rval != QL_SUCCESS ||
2356 + (tsize = SHORT_TO_LONG(mr.mb[2], mr.mb[3])) == 0) {
2357 + EL(ha, "size=%xh status=%xh\n", tsize, rval);
2358 + ha->md_capture_size = 0;
2359 + ql_free_phys(ha, &ha->dmp_template);
2360 + return (rval);
2361 + }
2362 + if (ha->dmp_template.dma_handle && ha->dmp_template.size != tsize) {
2363 + ql_free_phys(ha, &ha->dmp_template);
2364 + }
2365 + ha->md_capture_mask = 0x1f;
2366 + ha->md_capture_size = SHORT_TO_LONG(mr.mb[4], mr.mb[5]) +
2367 + SHORT_TO_LONG(mr.mb[6], mr.mb[7]) +
2368 + SHORT_TO_LONG(mr.mb[8], mr.mb[9]) +
2369 + SHORT_TO_LONG(mr.mb[10], mr.mb[11]) + tsize;
2370 + /*
2371 + * Determine ascii dump file size
2372 + * 2 ascii bytes per binary byte + a space and
2373 + * a newline every 16 binary bytes
2374 + */
2375 + ha->risc_dump_size = ha->md_capture_size << 1;
2376 + ha->risc_dump_size += ha->md_capture_size;
2377 + ha->risc_dump_size += ha->md_capture_size / 16 + 1;
2378 +
2379 + /* Allocate template buffer. */
2380 + if (ha->dmp_template.dma_handle == NULL) {
2381 + rval = ql_get_dma_mem(ha, &ha->dmp_template, tsize,
2382 + LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN);
2383 + if (rval != QL_SUCCESS) {
2384 + EL(ha, "unable to allocate template buffer, "
2385 + "status=%xh\n", rval);
2386 + ha->md_capture_size = 0;
2387 + ql_free_phys(ha, &ha->dmp_template);
2388 + return (rval);
2389 + }
2390 + }
2391 + rval = ql_get_md_template(ha, &ha->dmp_template, &mr, 0, GTO_TEMPLATE);
2392 + if (rval != QL_SUCCESS ||
2393 + (chksum = ql_8021_md_template_checksum(ha))) {
2394 + EL(ha, "status=%xh, chksum=%xh\n", rval, chksum);
2395 + if (rval == QL_SUCCESS) {
2396 + rval = QL_FUNCTION_FAILED;
2397 + }
2398 + ql_free_phys(ha, &ha->dmp_template);
2399 + ha->md_capture_size = 0;
2400 + }
2401 +
1970 2402 return (rval);
2403 +}
2404 +
2405 +static void
2406 +ql_8021_md_parse_template(ql_adapter_state_t *ha, caddr_t template_buff,
2407 + caddr_t dump_buff, uint32_t buff_size, uint32_t capture_mask)
2408 +{
2409 + int e_cnt, buff_level, esize;
2410 + uint32_t num_of_entries;
2411 + time_t time;
2412 + caddr_t dbuff;
2413 + int sane_start = 0, sane_end = 0;
2414 + md_template_hdr_t *template_hdr;
2415 + md_entry_t *entry;
2416 +
2417 + if ((capture_mask & 0x3) != 0x3) {
2418 + EL(ha, "capture mask %02xh below minimum needed for valid "
2419 + "dump\n", capture_mask);
2420 + return;
2421 + }
2422 + /* Setup parameters */
2423 + template_hdr = (md_template_hdr_t *)template_buff;
2424 + if (template_hdr->entry_type == TLHDR) {
2425 + sane_start = 1;
2426 + }
2427 + (void) drv_getparm(TIME, &time);
2428 + template_hdr->driver_timestamp = LSD(time);
2429 + template_hdr->driver_capture_mask = capture_mask;
2430 + num_of_entries = template_hdr->num_of_entries;
2431 + entry = (md_entry_t *)((caddr_t)template_buff +
2432 + template_hdr->first_entry_offset);
2433 + for (buff_level = 0, e_cnt = 0; e_cnt < num_of_entries; e_cnt++) {
2434 + /*
2435 + * If the capture_mask of the entry does not match capture mask
2436 + * skip the entry after marking the driver_flags indicator.
2437 + */
2438 + if (!(entry->h.a.ecw.entry_capture_mask & capture_mask)) {
2439 + entry->h.a.ecw.driver_flags = (uint8_t)
2440 + (entry->h.a.ecw.driver_flags |
2441 + QL_DBG_SKIPPED_FLAG);
2442 + entry = (md_entry_t *)((char *)entry +
2443 + entry->h.entry_size);
2444 + continue;
2445 + }
2446 + /*
2447 + * This is ONLY needed in implementations where
2448 + * the capture buffer allocated is too small to capture
2449 + * all of the required entries for a given capture mask.
2450 + * We need to empty the buffer contents to a file
2451 + * if possible, before processing the next entry
2452 + * If the buff_full_flag is set, no further capture will
2453 + * happen and all remaining non-control entries will be
2454 + * skipped.
2455 + */
2456 + if (entry->h.entry_capture_size != 0) {
2457 + if ((buff_level + entry->h.entry_capture_size) >
2458 + buff_size) {
2459 + entry = (md_entry_t *)((char *)entry +
2460 + entry->h.entry_size);
2461 + continue;
2462 + }
2463 + }
2464 + /*
2465 + * Decode the entry type and process it accordingly
2466 + */
2467 + switch (entry->h.entry_type) {
2468 + case RDNOP:
2469 + break;
2470 + case RDEND:
2471 + sane_end += 1;
2472 + break;
2473 + case RDCRB:
2474 + dbuff = dump_buff + buff_level;
2475 + esize = ql_8021_md_rdcrb(ha, (void *)entry,
2476 + (void *)dbuff);
2477 + ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2478 + buff_level += esize;
2479 + break;
2480 + case L2ITG:
2481 + case L2DTG:
2482 + case L2DAT:
2483 + case L2INS:
2484 + dbuff = dump_buff + buff_level;
2485 + esize = ql_8021_md_L2Cache(ha, (void *)entry,
2486 + (void *)dbuff);
2487 + if (esize == -1) {
2488 + entry->h.a.ecw.driver_flags = (uint8_t)
2489 + (entry->h.a.ecw.driver_flags |
2490 + QL_DBG_SKIPPED_FLAG);
2491 + } else {
2492 + ql_8021_md_entry_err_chk(ha, entry, esize,
2493 + e_cnt);
2494 + buff_level += esize;
2495 + }
2496 + break;
2497 + case L1DAT:
2498 + case L1INS:
2499 + dbuff = dump_buff + buff_level;
2500 + esize = ql_8021_md_L1Cache(ha, (void *)entry,
2501 + (void *)dbuff);
2502 + ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2503 + buff_level += esize;
2504 + break;
2505 + case RDOCM:
2506 + dbuff = dump_buff + buff_level;
2507 + esize = ql_8021_md_rdocm(ha, (void *)entry,
2508 + (void *)dbuff);
2509 + ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2510 + buff_level += esize;
2511 + break;
2512 + case RDMEM:
2513 + dbuff = dump_buff + buff_level;
2514 + esize = ql_8021_md_rdmem(ha, (void *)entry,
2515 + (void *)dbuff);
2516 + ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2517 + buff_level += esize;
2518 + break;
2519 + case BOARD:
2520 + case RDROM:
2521 + dbuff = dump_buff + buff_level;
2522 + esize = ql_8021_md_rdrom(ha, (void *)entry,
2523 + (void *)dbuff);
2524 + ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2525 + buff_level += esize;
2526 + break;
2527 + case RDMUX:
2528 + dbuff = dump_buff + buff_level;
2529 + esize = ql_8021_md_rdmux(ha, (void *)entry,
2530 + (void *)dbuff);
2531 + ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2532 + buff_level += esize;
2533 + break;
2534 + case QUEUE:
2535 + dbuff = dump_buff + buff_level;
2536 + esize = ql_8021_md_rdqueue(ha, (void *)entry,
2537 + (void *)dbuff);
2538 + ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2539 + buff_level += esize;
2540 + break;
2541 + case CNTRL:
2542 + if (ql_8021_md_cntrl(ha, template_hdr,
2543 + (void *)entry)) {
2544 + entry->h.a.ecw.driver_flags = (uint8_t)
2545 + (entry->h.a.ecw.driver_flags |
2546 + QL_DBG_SKIPPED_FLAG);
2547 + EL(ha, "Entry ID=%d, entry_type=%d non zero "
2548 + "status\n", e_cnt, entry->h.entry_type);
2549 + }
2550 + break;
2551 + default:
2552 + entry->h.a.ecw.driver_flags = (uint8_t)
2553 + (entry->h.a.ecw.driver_flags |
2554 + QL_DBG_SKIPPED_FLAG);
2555 + EL(ha, "Entry ID=%d, entry_type=%d unknown\n", e_cnt,
2556 + entry->h.entry_type);
2557 + break;
2558 + }
2559 + /* next entry in the template */
2560 + entry = (md_entry_t *)((caddr_t)entry + entry->h.entry_size);
2561 + }
2562 + if (!sane_start || (sane_end > 1)) {
2563 + EL(ha, "Template configuration error. Check Template\n");
2564 + }
2565 + QL_PRINT_10(ha, "Minidump num of entries=%d\n",
2566 + template_hdr->num_of_entries);
2567 +}
2568 +
2569 +/*
2570 + * Read CRB operation.
2571 + */
2572 +static int
2573 +ql_8021_md_rdcrb(ql_adapter_state_t *ha, md_entry_rdcrb_t *crbEntry,
2574 + uint32_t *data_buff)
2575 +{
2576 + uint32_t loop_cnt, op_count, addr, stride, value;
2577 + int i;
2578 +
2579 + addr = crbEntry->addr;
2580 + op_count = crbEntry->op_count;
2581 + stride = crbEntry->a.ac.addr_stride;
2582 +
2583 + for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
2584 + value = ql_8021_read_reg(ha, addr);
2585 + *data_buff++ = addr;
2586 + *data_buff++ = value;
2587 + addr = addr + stride;
2588 + }
2589 +
2590 + /*
2591 + * for testing purpose we return amount of data written
2592 + */
2593 + i = (int)(loop_cnt * (2 * sizeof (uint32_t)));
2594 +
2595 + return (i);
2596 +}
2597 +
2598 +/*
2599 + * Handle L2 Cache.
2600 + */
2601 +static int
2602 +ql_8021_md_L2Cache(ql_adapter_state_t *ha, md_entry_cache_t *cacheEntry,
2603 + uint32_t *data_buff)
2604 +{
2605 + int i, k, tflag;
2606 + uint32_t read_value, loop_cnt, read_cnt;
2607 + uint32_t addr, read_addr, cntrl_addr, tag_reg_addr;
2608 + uint32_t cntl_value_w, tag_value, tag_value_stride;
2609 + volatile uint8_t cntl_value_r;
2610 + clock_t timeout, elapsed;
2611 +
2612 + read_addr = cacheEntry->read_addr;
2613 + loop_cnt = cacheEntry->op_count;
2614 + cntrl_addr = cacheEntry->control_addr;
2615 + cntl_value_w = CHAR_TO_SHORT(cacheEntry->b.cv.write_value[0],
2616 + cacheEntry->b.cv.write_value[1]);
2617 + tag_reg_addr = cacheEntry->tag_reg_addr;
2618 + tag_value = CHAR_TO_SHORT(cacheEntry->a.sac.init_tag_value[0],
2619 + cacheEntry->a.sac.init_tag_value[1]);
2620 + tag_value_stride = CHAR_TO_SHORT(cacheEntry->a.sac.tag_value_stride[0],
2621 + cacheEntry->a.sac.tag_value_stride[1]);
2622 + read_cnt = cacheEntry->c.rac.read_addr_cnt;
2623 +
2624 + for (i = 0; i < loop_cnt; i++) {
2625 + ql_8021_write_reg(ha, tag_value, tag_reg_addr);
2626 + if (cntl_value_w) {
2627 + ql_8021_write_reg(ha, cntl_value_w, cntrl_addr);
2628 + }
2629 + if (cacheEntry->b.cv.poll_wait) {
2630 + (void) drv_getparm(LBOLT, &timeout);
2631 + timeout += drv_usectohz(cacheEntry->b.cv.poll_wait *
2632 + 1000) + 1;
2633 + cntl_value_r = (uint8_t)ql_8021_read_reg(ha,
2634 + cntrl_addr);
2635 + tflag = 0;
2636 + while (!tflag && ((cntl_value_r &
2637 + cacheEntry->b.cv.poll_mask) != 0)) {
2638 + (void) drv_getparm(LBOLT, &elapsed);
2639 + if (elapsed > timeout) {
2640 + tflag = 1;
2641 + }
2642 + cntl_value_r = (uint8_t)ql_8021_read_reg(ha,
2643 + cntrl_addr);
2644 + }
2645 + if (tflag) {
2646 + /*
2647 + * Report timeout error. core dump capture
2648 + * failed
2649 + * Skip remaining entries. Write buffer out
2650 + * to file
2651 + * Use driver specific fields in template
2652 + * header
2653 + * to report this error.
2654 + */
2655 + EL(ha, "timeout\n");
2656 + return (-1);
2657 + }
2658 + }
2659 + addr = read_addr;
2660 + for (k = 0; k < read_cnt; k++) {
2661 + read_value = ql_8021_read_reg(ha, addr);
2662 + *data_buff++ = read_value;
2663 + addr += cacheEntry->c.rac.read_addr_stride;
2664 + }
2665 + tag_value += tag_value_stride;
2666 + }
2667 + i = (int)(read_cnt * loop_cnt * sizeof (uint32_t));
2668 +
2669 + return (i);
2670 +}
2671 +
2672 +/*
2673 + * Handle L1 Cache.
2674 + */
2675 +static int
2676 +ql_8021_md_L1Cache(ql_adapter_state_t *ha, md_entry_cache_t *cacheEntry,
2677 + uint32_t *data_buff)
2678 +{
2679 + int i, k;
2680 + uint32_t read_value, tag_value, tag_value_stride;
2681 + uint32_t read_cnt, loop_cnt;
2682 + uint32_t addr, read_addr, cntrl_addr, tag_reg_addr;
2683 + volatile uint32_t cntl_value_w;
2684 +
2685 + read_addr = cacheEntry->read_addr;
2686 + loop_cnt = cacheEntry->op_count;
2687 + cntrl_addr = cacheEntry->control_addr;
2688 + cntl_value_w = CHAR_TO_SHORT(cacheEntry->b.cv.write_value[0],
2689 + cacheEntry->b.cv.write_value[1]);
2690 + tag_reg_addr = cacheEntry->tag_reg_addr;
2691 + tag_value = CHAR_TO_SHORT(cacheEntry->a.sac.init_tag_value[0],
2692 + cacheEntry->a.sac.init_tag_value[1]);
2693 + tag_value_stride = CHAR_TO_SHORT(cacheEntry->a.sac.tag_value_stride[0],
2694 + cacheEntry->a.sac.tag_value_stride[1]);
2695 + read_cnt = cacheEntry->c.rac.read_addr_cnt;
2696 +
2697 + for (i = 0; i < loop_cnt; i++) {
2698 + ql_8021_write_reg(ha, tag_value, tag_reg_addr);
2699 + ql_8021_write_reg(ha, cntl_value_w, cntrl_addr);
2700 + addr = read_addr;
2701 + for (k = 0; k < read_cnt; k++) {
2702 + read_value = ql_8021_read_reg(ha, addr);
2703 + *data_buff++ = read_value;
2704 + addr += cacheEntry->c.rac.read_addr_stride;
2705 + }
2706 + tag_value += tag_value_stride;
2707 + }
2708 + i = (int)(read_cnt * loop_cnt * sizeof (uint32_t));
2709 +
2710 + return (i);
2711 +}
2712 +
2713 +/*
2714 + * Reading OCM memory
2715 + */
2716 +static int
2717 +ql_8021_md_rdocm(ql_adapter_state_t *ha, md_entry_rdocm_t *ocmEntry,
2718 + uint32_t *data_buff)
2719 +{
2720 + int i;
2721 + uint32_t addr, value, loop_cnt;
2722 +
2723 + addr = ocmEntry->read_addr;
2724 + loop_cnt = ocmEntry->op_count;
2725 +
2726 + for (i = 0; i < loop_cnt; i++) {
2727 + value = ql_8021_read_ocm(ha, addr);
2728 + *data_buff++ = value;
2729 + addr += ocmEntry->read_addr_stride;
2730 + }
2731 + i = (int)(loop_cnt * sizeof (value));
2732 +
2733 + return (i);
2734 +}
2735 +
2736 +/*
2737 + * Read memory
2738 + */
2739 +static int
2740 +ql_8021_md_rdmem(ql_adapter_state_t *ha, md_entry_rdmem_t *memEntry,
2741 + uint32_t *data_buff)
2742 +{
2743 + int i, k;
2744 + uint32_t addr, value, loop_cnt;
2745 +
2746 + addr = memEntry->read_addr;
2747 + loop_cnt = (uint32_t)(memEntry->read_data_size /
2748 + (sizeof (uint32_t) * 4)); /* size in bytes / 16 */
2749 +
2750 + ql_8021_write_reg(ha, 0, MD_MIU_TEST_AGT_ADDR_HI);
2751 + for (i = 0; i < loop_cnt; i++) {
2752 + /*
2753 + * Write address
2754 + */
2755 + ql_8021_write_reg(ha, addr, MD_MIU_TEST_AGT_ADDR_LO);
2756 + ql_8021_write_reg(ha, MD_TA_CTL_ENABLE,
2757 + MD_MIU_TEST_AGT_CTRL);
2758 + ql_8021_write_reg(ha, (MD_TA_CTL_START | MD_TA_CTL_ENABLE),
2759 + MD_MIU_TEST_AGT_CTRL);
2760 + /*
2761 + * Check busy bit.
2762 + */
2763 + for (k = 0; k < MD_TA_CTL_CHECK; k++) {
2764 + value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_CTRL);
2765 + if ((value & MD_TA_CTL_BUSY) == 0) {
2766 + break;
2767 + }
2768 + }
2769 + if (k == MD_TA_CTL_CHECK) {
2770 + i = (int)((uint_t)i * (sizeof (uint32_t) * 4));
2771 + EL(ha, "failed to read=xh\n", i);
2772 + return (i);
2773 + }
2774 + /*
2775 + * Read data
2776 + */
2777 + value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_0_31);
2778 + *data_buff++ = value;
2779 + value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_32_63);
2780 + *data_buff++ = value;
2781 + value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_64_95);
2782 + *data_buff++ = value;
2783 + value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_96_127);
2784 + *data_buff++ = value;
2785 + /*
2786 + * next address to read
2787 + */
2788 + addr = (uint32_t)(addr + (sizeof (uint32_t) * 4));
2789 + }
2790 + i = (int)(loop_cnt * (sizeof (uint32_t) * 4));
2791 +
2792 + return (i);
2793 +}
2794 +
2795 +/*
2796 + * Read Rom
2797 + */
2798 +static int
2799 +ql_8021_md_rdrom(ql_adapter_state_t *ha, md_entry_rdrom_t *romEntry,
2800 + uint32_t *data_buff)
2801 +{
2802 + int i;
2803 + uint32_t addr, waddr, raddr, value, loop_cnt;
2804 +
2805 + addr = romEntry->read_addr;
2806 + loop_cnt = romEntry->read_data_size; /* This is size in bytes */
2807 + loop_cnt = (uint32_t)(loop_cnt / sizeof (value));
2808 +
2809 + for (i = 0; i < loop_cnt; i++) {
2810 + waddr = addr & 0xFFFF0000;
2811 + (void) ql_8021_rom_lock(ha);
2812 + ql_8021_write_reg(ha, waddr, MD_DIRECT_ROM_WINDOW);
2813 + raddr = MD_DIRECT_ROM_READ_BASE + (addr & 0x0000FFFF);
2814 + value = ql_8021_read_reg(ha, raddr);
2815 + ql_8021_rom_unlock(ha);
2816 + *data_buff++ = value;
2817 + addr = (uint32_t)(addr + sizeof (value));
2818 + }
2819 + i = (int)(loop_cnt * sizeof (value));
2820 +
2821 + return (i);
2822 +}
2823 +
2824 +/*
2825 + * Read MUX data
2826 + */
2827 +static int
2828 +ql_8021_md_rdmux(ql_adapter_state_t *ha, md_entry_mux_t *muxEntry,
2829 + uint32_t *data_buff)
2830 +{
2831 + uint32_t read_value, sel_value, loop_cnt;
2832 + uint32_t read_addr, select_addr;
2833 + int i;
2834 +
2835 + select_addr = muxEntry->select_addr;
2836 + sel_value = muxEntry->select_value;
2837 + read_addr = muxEntry->read_addr;
2838 +
2839 + for (loop_cnt = 0; loop_cnt < muxEntry->op_count; loop_cnt++) {
2840 + ql_8021_write_reg(ha, sel_value, select_addr);
2841 + read_value = ql_8021_read_reg(ha, read_addr);
2842 + *data_buff++ = sel_value;
2843 + *data_buff++ = read_value;
2844 + sel_value += muxEntry->select_value_stride;
2845 + }
2846 + i = (int)(loop_cnt * (2 * sizeof (uint32_t)));
2847 +
2848 + return (i);
2849 +}
2850 +
2851 +/*
2852 + * Handling Queue State Reads.
2853 + */
2854 +static int
2855 +ql_8021_md_rdqueue(ql_adapter_state_t *ha, md_entry_queue_t *queueEntry,
2856 + uint32_t *data_buff)
2857 +{
2858 + int k;
2859 + uint32_t read_value, read_addr, read_stride, select_addr;
2860 + uint32_t queue_id, loop_cnt, read_cnt;
2861 +
2862 + read_cnt = queueEntry->b.rac.read_addr_cnt;
2863 + read_stride = queueEntry->b.rac.read_addr_stride;
2864 + select_addr = queueEntry->select_addr;
2865 +
2866 + for (loop_cnt = 0, queue_id = 0; loop_cnt < queueEntry->op_count;
2867 + loop_cnt++) {
2868 + ql_8021_write_reg(ha, queue_id, select_addr);
2869 + read_addr = queueEntry->read_addr;
2870 + for (k = 0; k < read_cnt; k++) {
2871 + read_value = ql_8021_read_reg(ha, read_addr);
2872 + *data_buff++ = read_value;
2873 + read_addr += read_stride;
2874 + }
2875 + queue_id += CHAR_TO_SHORT(queueEntry->a.sac.queue_id_stride[0],
2876 + queueEntry->a.sac.queue_id_stride[1]);
2877 + }
2878 + k = (int)(loop_cnt * (read_cnt * sizeof (uint32_t)));
2879 +
2880 + return (k);
2881 +}
2882 +
2883 +/*
2884 + * Handling control entries.
2885 + */
2886 +static int
2887 +ql_8021_md_cntrl(ql_adapter_state_t *ha, md_template_hdr_t *template_hdr,
2888 + md_entry_cntrl_t *crbEntry)
2889 +{
2890 + int tflag;
2891 + uint32_t opcode, read_value, addr, entry_addr, loop_cnt;
2892 + clock_t timeout, elapsed;
2893 +
2894 + entry_addr = crbEntry->addr;
2895 +
2896 + for (loop_cnt = 0; loop_cnt < crbEntry->op_count; loop_cnt++) {
2897 + opcode = crbEntry->b.cv.opcode;
2898 + if (opcode & QL_DBG_OPCODE_WR) {
2899 + ql_8021_write_reg(ha, crbEntry->value_1, entry_addr);
2900 + opcode &= ~QL_DBG_OPCODE_WR;
2901 + }
2902 + if (opcode & QL_DBG_OPCODE_RW) {
2903 + read_value = ql_8021_read_reg(ha, entry_addr);
2904 + ql_8021_write_reg(ha, read_value, entry_addr);
2905 + opcode &= ~QL_DBG_OPCODE_RW;
2906 + }
2907 + if (opcode & QL_DBG_OPCODE_AND) {
2908 + read_value = ql_8021_read_reg(ha, entry_addr);
2909 + read_value &= crbEntry->value_2;
2910 + opcode &= ~QL_DBG_OPCODE_AND;
2911 +
2912 + /* Checking for OR here to avoid extra register write */
2913 + if (opcode & QL_DBG_OPCODE_OR) {
2914 + read_value |= crbEntry->value_3;
2915 + opcode &= ~QL_DBG_OPCODE_OR;
2916 + }
2917 + ql_8021_write_reg(ha, read_value, entry_addr);
2918 + }
2919 + if (opcode & QL_DBG_OPCODE_OR) {
2920 + read_value = ql_8021_read_reg(ha, entry_addr);
2921 + read_value |= crbEntry->value_3;
2922 + ql_8021_write_reg(ha, read_value, entry_addr);
2923 + opcode &= ~QL_DBG_OPCODE_OR;
2924 + }
2925 + if (opcode & QL_DBG_OPCODE_POLL) {
2926 + opcode &= ~QL_DBG_OPCODE_POLL;
2927 + (void) drv_getparm(LBOLT, &timeout);
2928 + timeout += drv_usectohz(
2929 + CHAR_TO_SHORT(crbEntry->a.ac.poll_timeout[0],
2930 + crbEntry->a.ac.poll_timeout[1]) * 1000) + 1;
2931 + addr = entry_addr;
2932 + read_value = ql_8021_read_reg(ha, addr);
2933 + tflag = 0;
2934 + while (!tflag && ((read_value & crbEntry->value_2) !=
2935 + crbEntry->value_1)) {
2936 + (void) drv_getparm(LBOLT, &elapsed);
2937 + if (elapsed > timeout) {
2938 + tflag = 1;
2939 + }
2940 + read_value = ql_8021_read_reg(ha, addr);
2941 + }
2942 + if (tflag) {
2943 + /*
2944 + * Report timeout error. core dump capture
2945 + * failed Skip remaining entries. Write buffer
2946 + * out to file Use driver specific fields in
2947 + * template header to report this error.
2948 + */
2949 + EL(ha, "timeout\n");
2950 + return (-1);
2951 + }
2952 + }
2953 + if (opcode & QL_DBG_OPCODE_RDSTATE) {
2954 + /*
2955 + * decide which address to use.
2956 + */
2957 + if (crbEntry->a.ac.state_index_a) {
2958 + addr = template_hdr->saved_state_array[
2959 + crbEntry->a.ac.state_index_a];
2960 + } else {
2961 + addr = entry_addr;
2962 + }
2963 + read_value = ql_8021_read_reg(ha, addr);
2964 + template_hdr->saved_state_array[
2965 + crbEntry->b.cv.state_index_v] = read_value;
2966 + opcode &= ~QL_DBG_OPCODE_RDSTATE;
2967 + }
2968 + if (opcode & QL_DBG_OPCODE_WRSTATE) {
2969 + /*
2970 + * decide which value to use.
2971 + */
2972 + if (crbEntry->b.cv.state_index_v) {
2973 + read_value = template_hdr->saved_state_array[
2974 + crbEntry->b.cv.state_index_v];
2975 + } else {
2976 + read_value = crbEntry->value_1;
2977 + }
2978 + /*
2979 + * decide which address to use.
2980 + */
2981 + if (crbEntry->a.ac.state_index_a) {
2982 + addr = template_hdr->saved_state_array[
2983 + crbEntry->a.ac.state_index_a];
2984 + } else {
2985 + addr = entry_addr;
2986 + }
2987 + ql_8021_write_reg(ha, read_value, addr);
2988 + opcode &= ~QL_DBG_OPCODE_WRSTATE;
2989 + }
2990 + if (opcode & QL_DBG_OPCODE_MDSTATE) {
2991 + /* Read value from saved state using index */
2992 + read_value = template_hdr->saved_state_array[
2993 + crbEntry->b.cv.state_index_v];
2994 + /* Shift left operation */
2995 + read_value <<= crbEntry->b.cv.shl;
2996 + /* Shift right operation */
2997 + read_value >>= crbEntry->b.cv.shr;
2998 + /* check if AND mask is provided */
2999 + if (crbEntry->value_2) {
3000 + read_value &= crbEntry->value_2;
3001 + }
3002 + read_value |= crbEntry->value_3; /* OR operation */
3003 + read_value += crbEntry->value_1; /* inc operation */
3004 + /* Write value back to state area. */
3005 + template_hdr->saved_state_array[
3006 + crbEntry->b.cv.state_index_v] = read_value;
3007 + opcode &= ~QL_DBG_OPCODE_MDSTATE;
3008 + }
3009 + entry_addr += crbEntry->a.ac.addr_stride;
3010 + }
3011 +
3012 + return (0);
3013 +}
3014 +
3015 +/*
3016 + * Error Checking routines for template consistency.
3017 + *
3018 + * We catch an error where driver does not read
3019 + * as much data as we expect from the entry.
3020 + */
3021 +static void
3022 +ql_8021_md_entry_err_chk(ql_adapter_state_t *ha, md_entry_t *entry,
3023 + uint32_t esize, int e_cnt)
3024 +{
3025 + if (esize != entry->h.entry_capture_size) {
3026 + EL(ha, "%d %04x Dump write count = %d did not match entry "
3027 + "capture size = %d entry_count = %d\n", entry->h.entry_type,
3028 + entry->h.a.ecw.entry_capture_mask, esize,
3029 + entry->h.entry_capture_size, e_cnt);
3030 + entry->h.entry_capture_size = esize;
3031 + entry->h.a.ecw.driver_flags = (uint8_t)
3032 + (entry->h.a.ecw.driver_flags | QL_DBG_SKIPPED_FLAG);
3033 + }
3034 +}
3035 +
3036 +static uint32_t
3037 +ql_8021_md_template_checksum(ql_adapter_state_t *ha)
3038 +{
3039 + uint64_t sum = 0;
3040 + uint32_t cnt, *bp;
3041 +
3042 + cnt = (uint32_t)(ha->dmp_template.size / sizeof (uint32_t));
3043 + bp = ha->dmp_template.bp;
3044 + while (cnt-- > 0) {
3045 + sum += ddi_get32(ha->dmp_template.acc_handle, bp++);
3046 + }
3047 + while (sum >> 32) {
3048 + sum = (sum & 0xFFFFFFFF) + (sum >> 32);
3049 + }
3050 + cnt = (uint32_t)~sum;
3051 +
3052 + return (cnt);
3053 +}
3054 +
3055 +static uint32_t
3056 +ql_8021_read_reg(ql_adapter_state_t *ha, uint32_t addr)
3057 +{
3058 + uint32_t addr0, addr1, value;
3059 +
3060 + (void) ql_8021_crb_win_lock(ha);
3061 +
3062 + addr0 = addr & 0xFFFF0000;
3063 + WRT_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060), addr0);
3064 + /* PCI posting read */
3065 + (void) RD_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060));
3066 + addr1 = addr & 0x0000FFFF;
3067 + value = RD_REG_DWORD(ha, (ha->nx_pcibase + 0x001E0000 + addr1));
3068 +
3069 + ql_8021_crb_win_unlock(ha);
3070 +
3071 + return (value);
3072 +}
3073 +
3074 +static void
3075 +ql_8021_write_reg(ql_adapter_state_t *ha, uint32_t value, uint32_t addr)
3076 +{
3077 + uint32_t addr0, addr1;
3078 +
3079 + (void) ql_8021_crb_win_lock(ha);
3080 +
3081 + addr0 = addr & 0xFFFF0000;
3082 + WRT_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060), addr0);
3083 + /* PCI posting read */
3084 + (void) RD_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060));
3085 + addr1 = addr & 0x0000FFFF;
3086 + WRT_REG_DWORD(ha, (ha->nx_pcibase + 0x001E0000 + addr1), value);
3087 + /* PCI posting read */
3088 + (void) RD_REG_DWORD(ha, (ha->nx_pcibase + 0x001E0000 + addr1));
3089 +
3090 + ql_8021_crb_win_unlock(ha);
3091 +}
3092 +
3093 +static uint32_t
3094 +ql_8021_read_ocm(ql_adapter_state_t *ha, uint32_t addr)
3095 +{
3096 + uint32_t value;
3097 +
3098 + value = RD_REG_DWORD(ha, (ha->nx_pcibase + addr));
3099 +
3100 + return (value);
1971 3101 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX