Print this page
8368 remove warlock leftovers from usr/src/uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/adapters/hermon/hermon_ioctl.c
+++ new/usr/src/uts/common/io/ib/adapters/hermon/hermon_ioctl.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 *
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 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * hermon_ioctl.c
28 28 * Hemron IOCTL Routines
29 29 *
30 30 * Implements all ioctl access into the driver. This includes all routines
31 31 * necessary for updating firmware, accessing the hermon flash device, and
32 32 * providing interfaces for VTS.
33 33 */
34 34
35 35 #include <sys/types.h>
36 36 #include <sys/conf.h>
37 37 #include <sys/ddi.h>
38 38 #include <sys/sunddi.h>
39 39 #include <sys/modctl.h>
40 40 #include <sys/file.h>
41 41
42 42 #include <sys/ib/adapters/hermon/hermon.h>
43 43
44 44 /* Hemron HCA state pointer (extern) */
45 45 extern void *hermon_statep;
46 46 extern int hermon_verbose;
47 47
48 48 #define DO_WRCONF 1
49 49 static int do_bar0 = 1;
50 50
51 51 /*
52 52 * The ioctl declarations (for firmware flash burning, register read/write
53 53 * (DEBUG-only), and VTS interfaces)
54 54 */
55 55 static int hermon_ioctl_flash_read(hermon_state_t *state, dev_t dev,
56 56 intptr_t arg, int mode);
57 57 static int hermon_ioctl_flash_write(hermon_state_t *state, dev_t dev,
58 58 intptr_t arg, int mode);
59 59 static int hermon_ioctl_flash_erase(hermon_state_t *state, dev_t dev,
60 60 intptr_t arg, int mode);
61 61 static int hermon_ioctl_flash_init(hermon_state_t *state, dev_t dev,
62 62 intptr_t arg, int mode);
63 63 static int hermon_ioctl_flash_fini(hermon_state_t *state, dev_t dev);
64 64 static int hermon_ioctl_flash_cleanup(hermon_state_t *state);
65 65 static int hermon_ioctl_flash_cleanup_nolock(hermon_state_t *state);
66 66 #ifdef DEBUG
67 67 static int hermon_ioctl_reg_write(hermon_state_t *state, intptr_t arg,
68 68 int mode);
69 69 static int hermon_ioctl_reg_read(hermon_state_t *state, intptr_t arg,
70 70 int mode);
71 71 #endif /* DEBUG */
72 72 static int hermon_ioctl_write_boot_addr(hermon_state_t *state, dev_t dev,
73 73 intptr_t arg, int mode);
74 74 static int hermon_ioctl_info(hermon_state_t *state, dev_t dev,
75 75 intptr_t arg, int mode);
76 76 static int hermon_ioctl_ports(hermon_state_t *state, intptr_t arg,
77 77 int mode);
78 78 static int hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg,
79 79 int mode);
80 80
81 81 /* Hemron Flash Functions */
82 82 static void hermon_flash_spi_exec_command(hermon_state_t *state,
83 83 ddi_acc_handle_t hdl, uint32_t cmd);
84 84 static int hermon_flash_read_sector(hermon_state_t *state,
85 85 uint32_t sector_num);
86 86 static int hermon_flash_read_quadlet(hermon_state_t *state, uint32_t *data,
87 87 uint32_t addr);
88 88 static int hermon_flash_write_sector(hermon_state_t *state,
89 89 uint32_t sector_num);
90 90 static int hermon_flash_spi_write_dword(hermon_state_t *state,
91 91 uint32_t addr, uint32_t data);
92 92 static int hermon_flash_write_byte(hermon_state_t *state, uint32_t addr,
93 93 uchar_t data);
94 94 static int hermon_flash_erase_sector(hermon_state_t *state,
95 95 uint32_t sector_num);
96 96 static int hermon_flash_erase_chip(hermon_state_t *state);
97 97 static int hermon_flash_bank(hermon_state_t *state, uint32_t addr);
98 98 static uint32_t hermon_flash_read(hermon_state_t *state, uint32_t addr,
99 99 int *err);
100 100 static void hermon_flash_write(hermon_state_t *state, uint32_t addr,
101 101 uchar_t data, int *err);
102 102 static int hermon_flash_spi_wait_wip(hermon_state_t *state);
103 103 static void hermon_flash_spi_write_enable(hermon_state_t *state);
104 104 static int hermon_flash_init(hermon_state_t *state);
105 105 static int hermon_flash_cfi_init(hermon_state_t *state, uint32_t *cfi_info,
106 106 int *intel_xcmd);
107 107 static int hermon_flash_fini(hermon_state_t *state);
108 108 static int hermon_flash_reset(hermon_state_t *state);
109 109 static uint32_t hermon_flash_read_cfg(hermon_state_t *state,
110 110 ddi_acc_handle_t pci_config_hdl, uint32_t addr);
111 111 #ifdef DO_WRCONF
112 112 static void hermon_flash_write_cfg(hermon_state_t *state,
113 113 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data);
114 114 static void hermon_flash_write_cfg_helper(hermon_state_t *state,
115 115 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data);
116 116 static void hermon_flash_write_confirm(hermon_state_t *state,
117 117 ddi_acc_handle_t pci_config_hdl);
118 118 #endif
119 119 static void hermon_flash_cfi_byte(uint8_t *ch, uint32_t dword, int i);
120 120 static void hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i);
121 121
122 122 /* Hemron loopback test functions */
123 123 static void hermon_loopback_free_qps(hermon_loopback_state_t *lstate);
124 124 static void hermon_loopback_free_state(hermon_loopback_state_t *lstate);
125 125 static int hermon_loopback_init(hermon_state_t *state,
126 126 hermon_loopback_state_t *lstate);
127 127 static void hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
128 128 hermon_loopback_comm_t *comm);
129 129 static int hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
130 130 hermon_loopback_comm_t *comm, int sz);
131 131 static int hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
132 132 hermon_loopback_comm_t *comm);
133 133 static int hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
134 134 hermon_loopback_comm_t *comm, uint_t qp_num);
135 135 static int hermon_loopback_copyout(hermon_loopback_ioctl_t *lb,
136 136 intptr_t arg, int mode);
137 137 static int hermon_loopback_post_send(hermon_loopback_state_t *lstate,
138 138 hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx);
139 139 static int hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
140 140 hermon_loopback_comm_t *comm);
141 141
142 142 /* Patchable timeout values for flash operations */
143 143 int hermon_hw_flash_timeout_gpio_sema = HERMON_HW_FLASH_TIMEOUT_GPIO_SEMA;
144 144 int hermon_hw_flash_timeout_config = HERMON_HW_FLASH_TIMEOUT_CONFIG;
145 145 int hermon_hw_flash_timeout_write = HERMON_HW_FLASH_TIMEOUT_WRITE;
146 146 int hermon_hw_flash_timeout_erase = HERMON_HW_FLASH_TIMEOUT_ERASE;
147 147
148 148 /*
149 149 * hermon_ioctl()
150 150 */
151 151 /* ARGSUSED */
152 152 int
153 153 hermon_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
154 154 int *rvalp)
155 155 {
156 156 hermon_state_t *state;
157 157 minor_t instance;
158 158 int status;
159 159
160 160 if (drv_priv(credp) != 0) {
161 161 return (EPERM);
162 162 }
163 163
164 164 instance = HERMON_DEV_INSTANCE(dev);
165 165 if (instance == (minor_t)-1) {
166 166 return (EBADF);
167 167 }
168 168
169 169 state = ddi_get_soft_state(hermon_statep, instance);
170 170 if (state == NULL) {
171 171 return (EBADF);
172 172 }
173 173
174 174 status = 0;
175 175
176 176 switch (cmd) {
177 177 case HERMON_IOCTL_FLASH_READ:
178 178 status = hermon_ioctl_flash_read(state, dev, arg, mode);
179 179 break;
180 180
181 181 case HERMON_IOCTL_FLASH_WRITE:
182 182 status = hermon_ioctl_flash_write(state, dev, arg, mode);
183 183 break;
184 184
185 185 case HERMON_IOCTL_FLASH_ERASE:
186 186 status = hermon_ioctl_flash_erase(state, dev, arg, mode);
187 187 break;
188 188
189 189 case HERMON_IOCTL_FLASH_INIT:
190 190 status = hermon_ioctl_flash_init(state, dev, arg, mode);
191 191 break;
192 192
193 193 case HERMON_IOCTL_FLASH_FINI:
194 194 status = hermon_ioctl_flash_fini(state, dev);
195 195 break;
196 196
197 197 case HERMON_IOCTL_INFO:
198 198 status = hermon_ioctl_info(state, dev, arg, mode);
199 199 break;
200 200
201 201 case HERMON_IOCTL_PORTS:
202 202 status = hermon_ioctl_ports(state, arg, mode);
203 203 break;
204 204
205 205 case HERMON_IOCTL_LOOPBACK:
206 206 status = hermon_ioctl_loopback(state, arg, mode);
207 207 break;
208 208
209 209 #ifdef DEBUG
210 210 case HERMON_IOCTL_REG_WRITE:
211 211 status = hermon_ioctl_reg_write(state, arg, mode);
212 212 break;
213 213
214 214 case HERMON_IOCTL_REG_READ:
215 215 status = hermon_ioctl_reg_read(state, arg, mode);
216 216 break;
217 217 #endif /* DEBUG */
218 218
219 219 case HERMON_IOCTL_DDR_READ:
220 220 /* XXX guard until the ioctl header is cleaned up */
221 221 status = ENODEV;
222 222 break;
223 223
224 224 case HERMON_IOCTL_WRITE_BOOT_ADDR:
225 225 status = hermon_ioctl_write_boot_addr(state, dev, arg, mode);
226 226 break;
227 227
228 228 default:
229 229 status = ENOTTY;
230 230 break;
231 231 }
232 232 *rvalp = status;
233 233
234 234 return (status);
235 235 }
236 236
237 237 /*
238 238 * hermon_ioctl_flash_read()
239 239 */
240 240 static int
241 241 hermon_ioctl_flash_read(hermon_state_t *state, dev_t dev, intptr_t arg,
242 242 int mode)
243 243 {
244 244 hermon_flash_ioctl_t ioctl_info;
245 245 int status = 0;
246 246
247 247 /*
248 248 * Check that flash init ioctl has been called first. And check
249 249 * that the same dev_t that called init is the one calling read now.
250 250 */
251 251 mutex_enter(&state->hs_fw_flashlock);
252 252 if ((state->hs_fw_flashdev != dev) ||
253 253 (state->hs_fw_flashstarted == 0)) {
254 254 mutex_exit(&state->hs_fw_flashlock);
255 255 return (EIO);
256 256 }
257 257
258 258 /* copy user struct to kernel */
259 259 #ifdef _MULTI_DATAMODEL
260 260 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
261 261 hermon_flash_ioctl32_t info32;
262 262
263 263 if (ddi_copyin((void *)arg, &info32,
264 264 sizeof (hermon_flash_ioctl32_t), mode) != 0) {
265 265 mutex_exit(&state->hs_fw_flashlock);
266 266 return (EFAULT);
267 267 }
268 268 ioctl_info.af_type = info32.af_type;
269 269 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
270 270 ioctl_info.af_sector_num = info32.af_sector_num;
271 271 ioctl_info.af_addr = info32.af_addr;
272 272 } else
273 273 #endif /* _MULTI_DATAMODEL */
274 274 if (ddi_copyin((void *)arg, &ioctl_info, sizeof (hermon_flash_ioctl_t),
275 275 mode) != 0) {
276 276 mutex_exit(&state->hs_fw_flashlock);
277 277 return (EFAULT);
278 278 }
279 279
280 280 /*
281 281 * Determine type of READ ioctl
282 282 */
283 283 switch (ioctl_info.af_type) {
284 284 case HERMON_FLASH_READ_SECTOR:
285 285 /* Check if sector num is too large for flash device */
286 286 if (ioctl_info.af_sector_num >=
287 287 (state->hs_fw_device_sz >> state->hs_fw_log_sector_sz)) {
288 288 mutex_exit(&state->hs_fw_flashlock);
289 289 return (EFAULT);
290 290 }
291 291
292 292 /* Perform the Sector Read */
293 293 if ((status = hermon_flash_reset(state)) != 0 ||
294 294 (status = hermon_flash_read_sector(state,
295 295 ioctl_info.af_sector_num)) != 0) {
296 296 mutex_exit(&state->hs_fw_flashlock);
297 297 return (status);
298 298 }
299 299
300 300 /* copyout the firmware sector image data */
301 301 if (ddi_copyout(&state->hs_fw_sector[0],
302 302 &ioctl_info.af_sector[0], 1 << state->hs_fw_log_sector_sz,
303 303 mode) != 0) {
304 304 mutex_exit(&state->hs_fw_flashlock);
305 305 return (EFAULT);
306 306 }
307 307 break;
308 308
309 309 case HERMON_FLASH_READ_QUADLET:
310 310 /* Check if addr is too large for flash device */
311 311 if (ioctl_info.af_addr >= state->hs_fw_device_sz) {
312 312 mutex_exit(&state->hs_fw_flashlock);
313 313 return (EFAULT);
314 314 }
315 315
316 316 /* Perform the Quadlet Read */
317 317 if ((status = hermon_flash_reset(state)) != 0 ||
318 318 (status = hermon_flash_read_quadlet(state,
319 319 &ioctl_info.af_quadlet, ioctl_info.af_addr)) != 0) {
320 320 mutex_exit(&state->hs_fw_flashlock);
321 321 return (status);
322 322 }
323 323 break;
324 324
325 325 default:
326 326 mutex_exit(&state->hs_fw_flashlock);
327 327 return (EINVAL);
328 328 }
329 329
330 330 /* copy results back to userland */
331 331 #ifdef _MULTI_DATAMODEL
332 332 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
333 333 hermon_flash_ioctl32_t info32;
334 334
335 335 info32.af_quadlet = ioctl_info.af_quadlet;
336 336 info32.af_type = ioctl_info.af_type;
337 337 info32.af_sector_num = ioctl_info.af_sector_num;
338 338 info32.af_sector = (caddr32_t)(uintptr_t)ioctl_info.af_sector;
339 339 info32.af_addr = ioctl_info.af_addr;
340 340
341 341 if (ddi_copyout(&info32, (void *)arg,
342 342 sizeof (hermon_flash_ioctl32_t), mode) != 0) {
343 343 mutex_exit(&state->hs_fw_flashlock);
344 344 return (EFAULT);
345 345 }
346 346 } else
347 347 #endif /* _MULTI_DATAMODEL */
348 348 if (ddi_copyout(&ioctl_info, (void *)arg,
349 349 sizeof (hermon_flash_ioctl_t), mode) != 0) {
350 350 mutex_exit(&state->hs_fw_flashlock);
351 351 return (EFAULT);
352 352 }
353 353
354 354 mutex_exit(&state->hs_fw_flashlock);
355 355 return (status);
356 356 }
357 357
358 358 /*
359 359 * hermon_ioctl_flash_write()
360 360 */
361 361 static int
362 362 hermon_ioctl_flash_write(hermon_state_t *state, dev_t dev, intptr_t arg,
363 363 int mode)
364 364 {
365 365 hermon_flash_ioctl_t ioctl_info;
366 366 int status = 0;
367 367
368 368 /*
369 369 * Check that flash init ioctl has been called first. And check
370 370 * that the same dev_t that called init is the one calling write now.
371 371 */
372 372 mutex_enter(&state->hs_fw_flashlock);
373 373 if ((state->hs_fw_flashdev != dev) ||
374 374 (state->hs_fw_flashstarted == 0)) {
375 375 mutex_exit(&state->hs_fw_flashlock);
376 376 return (EIO);
377 377 }
378 378
379 379 /* copy user struct to kernel */
380 380 #ifdef _MULTI_DATAMODEL
381 381 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
382 382 hermon_flash_ioctl32_t info32;
383 383
384 384 if (ddi_copyin((void *)arg, &info32,
385 385 sizeof (hermon_flash_ioctl32_t), mode) != 0) {
386 386 mutex_exit(&state->hs_fw_flashlock);
387 387 return (EFAULT);
388 388 }
389 389 ioctl_info.af_type = info32.af_type;
390 390 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
391 391 ioctl_info.af_sector_num = info32.af_sector_num;
392 392 ioctl_info.af_addr = info32.af_addr;
393 393 ioctl_info.af_byte = info32.af_byte;
394 394 } else
395 395 #endif /* _MULTI_DATAMODEL */
396 396 if (ddi_copyin((void *)arg, &ioctl_info,
397 397 sizeof (hermon_flash_ioctl_t), mode) != 0) {
398 398 mutex_exit(&state->hs_fw_flashlock);
399 399 return (EFAULT);
400 400 }
401 401
402 402 /*
403 403 * Determine type of WRITE ioctl
404 404 */
405 405 switch (ioctl_info.af_type) {
406 406 case HERMON_FLASH_WRITE_SECTOR:
407 407 /* Check if sector num is too large for flash device */
408 408 if (ioctl_info.af_sector_num >=
409 409 (state->hs_fw_device_sz >> state->hs_fw_log_sector_sz)) {
410 410 mutex_exit(&state->hs_fw_flashlock);
411 411 return (EFAULT);
412 412 }
413 413
414 414 /* copy in fw sector image data */
415 415 if (ddi_copyin(&ioctl_info.af_sector[0],
416 416 &state->hs_fw_sector[0], 1 << state->hs_fw_log_sector_sz,
417 417 mode) != 0) {
418 418 mutex_exit(&state->hs_fw_flashlock);
419 419 return (EFAULT);
420 420 }
421 421
422 422 /* Perform Write Sector */
423 423 status = hermon_flash_write_sector(state,
424 424 ioctl_info.af_sector_num);
425 425 break;
426 426
427 427 case HERMON_FLASH_WRITE_BYTE:
428 428 /* Check if addr is too large for flash device */
429 429 if (ioctl_info.af_addr >= state->hs_fw_device_sz) {
430 430 mutex_exit(&state->hs_fw_flashlock);
431 431 return (EFAULT);
432 432 }
433 433
434 434 /* Perform Write Byte */
435 435 /*
436 436 * CMJ -- is a reset really needed before and after writing
437 437 * each byte? This code came from arbel, but we should look
438 438 * into this. Also, for SPI, no reset is actually performed.
439 439 */
440 440 if ((status = hermon_flash_bank(state,
441 441 ioctl_info.af_addr)) != 0 ||
442 442 (status = hermon_flash_reset(state)) != 0 ||
443 443 (status = hermon_flash_write_byte(state,
444 444 ioctl_info.af_addr, ioctl_info.af_byte)) != 0 ||
445 445 (status = hermon_flash_reset(state)) != 0) {
446 446 mutex_exit(&state->hs_fw_flashlock);
447 447 return (status);
448 448 }
449 449 break;
450 450
451 451 default:
452 452 status = EINVAL;
453 453 break;
454 454 }
455 455
456 456 mutex_exit(&state->hs_fw_flashlock);
457 457 return (status);
458 458 }
459 459
460 460 /*
461 461 * hermon_ioctl_flash_erase()
462 462 */
463 463 static int
464 464 hermon_ioctl_flash_erase(hermon_state_t *state, dev_t dev, intptr_t arg,
465 465 int mode)
466 466 {
467 467 hermon_flash_ioctl_t ioctl_info;
468 468 int status = 0;
469 469
470 470 /*
471 471 * Check that flash init ioctl has been called first. And check
472 472 * that the same dev_t that called init is the one calling erase now.
473 473 */
474 474 mutex_enter(&state->hs_fw_flashlock);
475 475 if ((state->hs_fw_flashdev != dev) ||
476 476 (state->hs_fw_flashstarted == 0)) {
477 477 mutex_exit(&state->hs_fw_flashlock);
478 478 return (EIO);
479 479 }
480 480
481 481 /* copy user struct to kernel */
482 482 #ifdef _MULTI_DATAMODEL
483 483 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
484 484 hermon_flash_ioctl32_t info32;
485 485
486 486 if (ddi_copyin((void *)arg, &info32,
487 487 sizeof (hermon_flash_ioctl32_t), mode) != 0) {
488 488 mutex_exit(&state->hs_fw_flashlock);
489 489 return (EFAULT);
490 490 }
491 491 ioctl_info.af_type = info32.af_type;
492 492 ioctl_info.af_sector_num = info32.af_sector_num;
493 493 } else
494 494 #endif /* _MULTI_DATAMODEL */
495 495 if (ddi_copyin((void *)arg, &ioctl_info, sizeof (hermon_flash_ioctl_t),
496 496 mode) != 0) {
497 497 mutex_exit(&state->hs_fw_flashlock);
498 498 return (EFAULT);
499 499 }
500 500
501 501 /*
502 502 * Determine type of ERASE ioctl
503 503 */
504 504 switch (ioctl_info.af_type) {
505 505 case HERMON_FLASH_ERASE_SECTOR:
506 506 /* Check if sector num is too large for flash device */
507 507 if (ioctl_info.af_sector_num >=
508 508 (state->hs_fw_device_sz >> state->hs_fw_log_sector_sz)) {
509 509 mutex_exit(&state->hs_fw_flashlock);
510 510 return (EFAULT);
511 511 }
512 512
513 513 /* Perform Sector Erase */
514 514 status = hermon_flash_erase_sector(state,
515 515 ioctl_info.af_sector_num);
516 516 break;
517 517
518 518 case HERMON_FLASH_ERASE_CHIP:
519 519 /* Perform Chip Erase */
520 520 status = hermon_flash_erase_chip(state);
521 521 break;
522 522
523 523 default:
524 524 status = EINVAL;
525 525 break;
526 526 }
527 527
528 528 mutex_exit(&state->hs_fw_flashlock);
529 529 return (status);
530 530 }
531 531
532 532 /*
533 533 * hermon_ioctl_flash_init()
534 534 */
535 535 static int
536 536 hermon_ioctl_flash_init(hermon_state_t *state, dev_t dev, intptr_t arg,
537 537 int mode)
538 538 {
539 539 hermon_flash_init_ioctl_t init_info;
540 540 int ret;
541 541 int intel_xcmd = 0;
542 542 ddi_acc_handle_t pci_hdl = hermon_get_pcihdl(state);
543 543
544 544 /* initialize the FMA retry loop */
545 545 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
546 546
547 547 state->hs_fw_sector = NULL;
548 548
549 549 /*
550 550 * init cannot be called more than once. If we have already init'd the
551 551 * flash, return directly.
552 552 */
553 553 mutex_enter(&state->hs_fw_flashlock);
554 554 if (state->hs_fw_flashstarted == 1) {
555 555 mutex_exit(&state->hs_fw_flashlock);
556 556 return (EINVAL);
557 557 }
558 558
559 559 /* copyin the user struct to kernel */
560 560 if (ddi_copyin((void *)arg, &init_info,
561 561 sizeof (hermon_flash_init_ioctl_t), mode) != 0) {
562 562 mutex_exit(&state->hs_fw_flashlock);
563 563 return (EFAULT);
564 564 }
565 565
566 566 /* Init Flash */
567 567 if ((ret = hermon_flash_init(state)) != 0) {
568 568 if (ret == EIO) {
569 569 goto pio_error;
570 570 }
571 571 mutex_exit(&state->hs_fw_flashlock);
572 572 return (ret);
573 573 }
574 574
575 575 /* Read CFI info */
576 576 if ((ret = hermon_flash_cfi_init(state, &init_info.af_cfi_info[0],
577 577 &intel_xcmd)) != 0) {
578 578 if (ret == EIO) {
579 579 goto pio_error;
580 580 }
581 581 mutex_exit(&state->hs_fw_flashlock);
582 582 return (ret);
583 583 }
584 584
585 585 /*
586 586 * Return error if the command set is unknown.
587 587 */
588 588 if (state->hs_fw_cmdset == HERMON_FLASH_UNKNOWN_CMDSET) {
589 589 if ((ret = hermon_ioctl_flash_cleanup_nolock(state)) != 0) {
590 590 if (ret == EIO) {
591 591 goto pio_error;
592 592 }
593 593 mutex_exit(&state->hs_fw_flashlock);
594 594 return (ret);
595 595 }
596 596 mutex_exit(&state->hs_fw_flashlock);
597 597 return (EFAULT);
598 598 }
599 599
600 600 /* the FMA retry loop starts. */
601 601 hermon_pio_start(state, pci_hdl, pio_error,
602 602 fm_loop_cnt, fm_status, fm_test);
603 603
604 604 /* Read HWREV - least significant 8 bits is revision ID */
605 605 init_info.af_hwrev = pci_config_get32(pci_hdl,
606 606 HERMON_HW_FLASH_CFG_HWREV) & 0xFF;
607 607
608 608 /* the FMA retry loop ends. */
609 609 hermon_pio_end(state, pci_hdl, pio_error, fm_loop_cnt,
610 610 fm_status, fm_test);
611 611
612 612 /* Fill in the firmwate revision numbers */
613 613 init_info.af_fwrev.afi_maj = state->hs_fw.fw_rev_major;
614 614 init_info.af_fwrev.afi_min = state->hs_fw.fw_rev_minor;
615 615 init_info.af_fwrev.afi_sub = state->hs_fw.fw_rev_subminor;
616 616
617 617 /* Alloc flash mem for one sector size */
618 618 state->hs_fw_sector = (uint32_t *)kmem_zalloc(1 <<
619 619 state->hs_fw_log_sector_sz, KM_SLEEP);
620 620
621 621 /* Set HW part number and length */
622 622 init_info.af_pn_len = state->hs_hca_pn_len;
623 623 if (state->hs_hca_pn_len != 0) {
624 624 (void) memcpy(init_info.af_hwpn, state->hs_hca_pn,
625 625 state->hs_hca_pn_len);
626 626 }
627 627
628 628 /* Copy ioctl results back to userland */
629 629 if (ddi_copyout(&init_info, (void *)arg,
630 630 sizeof (hermon_flash_init_ioctl_t), mode) != 0) {
631 631 if ((ret = hermon_ioctl_flash_cleanup_nolock(state)) != 0) {
632 632 if (ret == EIO) {
633 633 goto pio_error;
634 634 }
635 635 mutex_exit(&state->hs_fw_flashlock);
636 636 return (ret);
637 637 }
638 638 mutex_exit(&state->hs_fw_flashlock);
639 639 return (EFAULT);
640 640 }
641 641
642 642 /* Set flash state to started */
643 643 state->hs_fw_flashstarted = 1;
644 644 state->hs_fw_flashdev = dev;
645 645
646 646 mutex_exit(&state->hs_fw_flashlock);
647 647
648 648 /*
649 649 * If "flash init" is successful, add an "on close" callback to the
650 650 * current dev node to ensure that "flash fini" gets called later
651 651 * even if the userland process prematurely exits.
652 652 */
653 653 ret = hermon_umap_db_set_onclose_cb(dev,
654 654 HERMON_ONCLOSE_FLASH_INPROGRESS,
655 655 (int (*)(void *))hermon_ioctl_flash_cleanup, state);
656 656 if (ret != DDI_SUCCESS) {
657 657 int status = hermon_ioctl_flash_fini(state, dev);
658 658 if (status != 0) {
659 659 if (status == EIO) {
660 660 hermon_fm_ereport(state, HCA_SYS_ERR,
661 661 HCA_ERR_IOCTL);
662 662 return (EIO);
663 663 }
664 664 return (status);
665 665 }
666 666 }
667 667 return (0);
668 668
669 669 pio_error:
670 670 mutex_exit(&state->hs_fw_flashlock);
671 671 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
672 672 return (EIO);
673 673 }
674 674
675 675 /*
676 676 * hermon_ioctl_flash_fini()
677 677 */
678 678 static int
679 679 hermon_ioctl_flash_fini(hermon_state_t *state, dev_t dev)
680 680 {
681 681 int ret;
682 682
683 683 /*
684 684 * Check that flash init ioctl has been called first. And check
685 685 * that the same dev_t that called init is the one calling fini now.
686 686 */
687 687 mutex_enter(&state->hs_fw_flashlock);
688 688 if ((state->hs_fw_flashdev != dev) ||
689 689 (state->hs_fw_flashstarted == 0)) {
690 690 mutex_exit(&state->hs_fw_flashlock);
691 691 return (EINVAL);
692 692 }
693 693
694 694 if ((ret = hermon_ioctl_flash_cleanup_nolock(state)) != 0) {
695 695 mutex_exit(&state->hs_fw_flashlock);
696 696 if (ret == EIO) {
697 697 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
698 698 }
699 699 return (ret);
700 700 }
701 701 mutex_exit(&state->hs_fw_flashlock);
702 702
703 703 /*
704 704 * If "flash fini" is successful, remove the "on close" callback
705 705 * that was setup during "flash init".
706 706 */
707 707 ret = hermon_umap_db_clear_onclose_cb(dev,
708 708 HERMON_ONCLOSE_FLASH_INPROGRESS);
709 709 if (ret != DDI_SUCCESS) {
710 710 return (EFAULT);
711 711 }
712 712 return (0);
713 713 }
714 714
715 715
716 716 /*
717 717 * hermon_ioctl_flash_cleanup()
718 718 */
719 719 static int
720 720 hermon_ioctl_flash_cleanup(hermon_state_t *state)
721 721 {
722 722 int status;
723 723
724 724 mutex_enter(&state->hs_fw_flashlock);
725 725 status = hermon_ioctl_flash_cleanup_nolock(state);
726 726 mutex_exit(&state->hs_fw_flashlock);
727 727
728 728 return (status);
729 729 }
730 730
731 731
732 732 /*
733 733 * hermon_ioctl_flash_cleanup_nolock()
734 734 */
735 735 static int
736 736 hermon_ioctl_flash_cleanup_nolock(hermon_state_t *state)
737 737 {
738 738 int status;
739 739 ASSERT(MUTEX_HELD(&state->hs_fw_flashlock));
740 740
741 741 /* free flash mem */
742 742 if (state->hs_fw_sector) {
743 743 kmem_free(state->hs_fw_sector, 1 << state->hs_fw_log_sector_sz);
744 744 }
745 745
746 746 /* Fini the Flash */
747 747 if ((status = hermon_flash_fini(state)) != 0)
748 748 return (status);
749 749
750 750 /* Set flash state to fini */
751 751 state->hs_fw_flashstarted = 0;
752 752 state->hs_fw_flashdev = 0;
753 753 return (0);
754 754 }
755 755
756 756
757 757 /*
758 758 * hermon_ioctl_info()
759 759 */
760 760 static int
761 761 hermon_ioctl_info(hermon_state_t *state, dev_t dev, intptr_t arg, int mode)
762 762 {
763 763 hermon_info_ioctl_t info;
764 764 hermon_flash_init_ioctl_t init_info;
765 765
766 766 /*
767 767 * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
768 768 */
769 769 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
770 770 return (EFAULT);
771 771 }
772 772
773 773 /* copyin the user struct to kernel */
774 774 if (ddi_copyin((void *)arg, &info, sizeof (hermon_info_ioctl_t),
775 775 mode) != 0) {
776 776 return (EFAULT);
777 777 }
778 778
779 779 /*
780 780 * Check ioctl revision
781 781 */
782 782 if (info.ai_revision != HERMON_VTS_IOCTL_REVISION) {
783 783 return (EINVAL);
784 784 }
785 785
786 786 /*
787 787 * If the 'fw_device_sz' has not been initialized yet, we initialize it
788 788 * here. This is done by leveraging the
789 789 * hermon_ioctl_flash_init()/fini() calls. We also hold our own mutex
790 790 * around this operation in case we have multiple VTS threads in
791 791 * process at the same time.
792 792 */
793 793 mutex_enter(&state->hs_info_lock);
794 794 if (state->hs_fw_device_sz == 0) {
795 795 if (hermon_ioctl_flash_init(state, dev, (intptr_t)&init_info,
796 796 (FKIOCTL | mode)) != 0) {
797 797 mutex_exit(&state->hs_info_lock);
798 798 return (EFAULT);
799 799 }
800 800 (void) hermon_ioctl_flash_fini(state, dev);
801 801 }
802 802 mutex_exit(&state->hs_info_lock);
803 803
804 804 info.ai_hw_rev = state->hs_revision_id;
805 805 info.ai_flash_sz = state->hs_fw_device_sz;
806 806 info.ai_fw_rev.afi_maj = state->hs_fw.fw_rev_major;
807 807 info.ai_fw_rev.afi_min = state->hs_fw.fw_rev_minor;
808 808 info.ai_fw_rev.afi_sub = state->hs_fw.fw_rev_subminor;
809 809
810 810 /* Copy ioctl results back to user struct */
811 811 if (ddi_copyout(&info, (void *)arg, sizeof (hermon_info_ioctl_t),
812 812 mode) != 0) {
813 813 return (EFAULT);
814 814 }
815 815
816 816 return (0);
817 817 }
818 818
819 819 /*
820 820 * hermon_ioctl_ports()
821 821 */
822 822 static int
823 823 hermon_ioctl_ports(hermon_state_t *state, intptr_t arg, int mode)
824 824 {
825 825 hermon_ports_ioctl_t info;
826 826 hermon_stat_port_ioctl_t portstat;
827 827 ibt_hca_portinfo_t pi;
828 828 uint_t tbl_size;
829 829 ib_gid_t *sgid_tbl;
830 830 ib_pkey_t *pkey_tbl;
831 831 int i;
832 832
833 833 /*
834 834 * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
835 835 */
836 836 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
837 837 return (EFAULT);
838 838 }
839 839
840 840 /* copyin the user struct to kernel */
841 841 #ifdef _MULTI_DATAMODEL
842 842 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
843 843 hermon_ports_ioctl32_t info32;
844 844
845 845 if (ddi_copyin((void *)arg, &info32,
846 846 sizeof (hermon_ports_ioctl32_t), mode) != 0) {
847 847 return (EFAULT);
848 848 }
849 849 info.ap_revision = info32.ap_revision;
850 850 info.ap_ports =
851 851 (hermon_stat_port_ioctl_t *)(uintptr_t)info32.ap_ports;
852 852 info.ap_num_ports = info32.ap_num_ports;
853 853
854 854 } else
855 855 #endif /* _MULTI_DATAMODEL */
856 856 if (ddi_copyin((void *)arg, &info, sizeof (hermon_ports_ioctl_t),
857 857 mode) != 0) {
858 858 return (EFAULT);
859 859 }
860 860
861 861 /*
862 862 * Check ioctl revision
863 863 */
864 864 if (info.ap_revision != HERMON_VTS_IOCTL_REVISION) {
865 865 return (EINVAL);
↓ open down ↓ |
865 lines elided |
↑ open up ↑ |
866 866 }
867 867
868 868 /* Allocate space for temporary GID table/PKey table */
869 869 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
870 870 sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
871 871 KM_SLEEP);
872 872 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
873 873 pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
874 874 KM_SLEEP);
875 875
876 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sgid_tbl, *pkey_tbl))
877 -
878 876 /*
879 877 * Setup the number of ports, then loop through all ports and
880 878 * query properties of each.
881 879 */
882 880 info.ap_num_ports = (uint8_t)state->hs_cfg_profile->cp_num_ports;
883 881 for (i = 0; i < info.ap_num_ports; i++) {
884 882 /*
885 883 * Get portstate information from the device. If
886 884 * hermon_port_query() fails, leave zeroes in user
887 885 * struct port entry and continue.
888 886 */
889 887 bzero(&pi, sizeof (ibt_hca_portinfo_t));
890 888 pi.p_sgid_tbl = sgid_tbl;
891 889 pi.p_pkey_tbl = pkey_tbl;
892 890 (void) hermon_port_query(state, i + 1, &pi);
893 891
894 892 portstat.asp_port_num = pi.p_port_num;
895 893 portstat.asp_state = pi.p_linkstate;
896 894 portstat.asp_guid = pi.p_sgid_tbl[0].gid_guid;
897 895
898 896 /*
899 897 * Copy queried port results back to user struct. If
900 898 * this fails, then break out of loop, attempt to copy
901 899 * out remaining info to user struct, and return (without
902 900 * error).
903 901 */
904 902 if (ddi_copyout(&portstat,
905 903 &(((hermon_stat_port_ioctl_t *)info.ap_ports)[i]),
906 904 sizeof (hermon_stat_port_ioctl_t), mode) != 0) {
907 905 break;
908 906 }
909 907 }
910 908
911 909 /* Free the temporary space used for GID table/PKey table */
912 910 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
913 911 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
914 912 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
915 913 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
916 914
917 915 /* Copy ioctl results back to user struct */
918 916 #ifdef _MULTI_DATAMODEL
919 917 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
920 918 hermon_ports_ioctl32_t info32;
921 919
922 920 info32.ap_revision = info.ap_revision;
923 921 info32.ap_ports = (caddr32_t)(uintptr_t)info.ap_ports;
924 922 info32.ap_num_ports = info.ap_num_ports;
925 923
926 924 if (ddi_copyout(&info32, (void *)arg,
927 925 sizeof (hermon_ports_ioctl32_t), mode) != 0) {
928 926 return (EFAULT);
929 927 }
930 928 } else
931 929 #endif /* _MULTI_DATAMODEL */
932 930 if (ddi_copyout(&info, (void *)arg, sizeof (hermon_ports_ioctl_t),
933 931 mode) != 0) {
934 932 return (EFAULT);
935 933 }
936 934
937 935 return (0);
938 936 }
939 937
940 938 /*
941 939 * hermon_ioctl_loopback()
942 940 */
943 941 static int
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
944 942 hermon_ioctl_loopback(hermon_state_t *state, intptr_t arg, int mode)
945 943 {
946 944 hermon_loopback_ioctl_t lb;
947 945 hermon_loopback_state_t lstate;
948 946 ibt_hca_portinfo_t pi;
949 947 uint_t tbl_size, loopmax, max_usec;
950 948 ib_gid_t *sgid_tbl;
951 949 ib_pkey_t *pkey_tbl;
952 950 int j, iter, ret;
953 951
954 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(lstate))
955 -
956 952 /*
957 953 * Access to Hemron VTS ioctls is not allowed in "maintenance mode".
958 954 */
959 955 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
960 956 return (EFAULT);
961 957 }
962 958
963 959 /* copyin the user struct to kernel */
964 960 #ifdef _MULTI_DATAMODEL
965 961 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
966 962 hermon_loopback_ioctl32_t lb32;
967 963
968 964 if (ddi_copyin((void *)arg, &lb32,
969 965 sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
970 966 return (EFAULT);
971 967 }
972 968 lb.alb_revision = lb32.alb_revision;
973 969 lb.alb_send_buf = (caddr_t)(uintptr_t)lb32.alb_send_buf;
974 970 lb.alb_fail_buf = (caddr_t)(uintptr_t)lb32.alb_fail_buf;
975 971 lb.alb_buf_sz = lb32.alb_buf_sz;
976 972 lb.alb_num_iter = lb32.alb_num_iter;
977 973 lb.alb_pass_done = lb32.alb_pass_done;
978 974 lb.alb_timeout = lb32.alb_timeout;
979 975 lb.alb_error_type = lb32.alb_error_type;
980 976 lb.alb_port_num = lb32.alb_port_num;
981 977 lb.alb_num_retry = lb32.alb_num_retry;
982 978 } else
983 979 #endif /* _MULTI_DATAMODEL */
984 980 if (ddi_copyin((void *)arg, &lb, sizeof (hermon_loopback_ioctl_t),
985 981 mode) != 0) {
986 982 return (EFAULT);
987 983 }
988 984
989 985 /* Initialize the internal loopback test state structure */
990 986 bzero(&lstate, sizeof (hermon_loopback_state_t));
991 987
992 988 /*
993 989 * Check ioctl revision
994 990 */
995 991 if (lb.alb_revision != HERMON_VTS_IOCTL_REVISION) {
996 992 lb.alb_error_type = HERMON_LOOPBACK_INVALID_REVISION;
997 993 (void) hermon_loopback_copyout(&lb, arg, mode);
998 994 return (EINVAL);
999 995 }
1000 996
1001 997 /* Validate that specified port number is legal */
1002 998 if (!hermon_portnum_is_valid(state, lb.alb_port_num)) {
1003 999 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1004 1000 (void) hermon_loopback_copyout(&lb, arg, mode);
1005 1001 return (EINVAL);
1006 1002 }
1007 1003
1008 1004 /* Allocate space for temporary GID table/PKey table */
1009 1005 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1010 1006 sgid_tbl = (ib_gid_t *)kmem_zalloc(tbl_size * sizeof (ib_gid_t),
1011 1007 KM_SLEEP);
1012 1008 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1013 1009 pkey_tbl = (ib_pkey_t *)kmem_zalloc(tbl_size * sizeof (ib_pkey_t),
1014 1010 KM_SLEEP);
1015 1011
1016 1012 /*
1017 1013 * Get portstate information from specific port on device
1018 1014 */
1019 1015 bzero(&pi, sizeof (ibt_hca_portinfo_t));
1020 1016 pi.p_sgid_tbl = sgid_tbl;
1021 1017 pi.p_pkey_tbl = pkey_tbl;
1022 1018 if (hermon_port_query(state, lb.alb_port_num, &pi) != 0) {
1023 1019 /* Free the temporary space used for GID table/PKey table */
1024 1020 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1025 1021 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1026 1022 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1027 1023 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1028 1024
1029 1025 lb.alb_error_type = HERMON_LOOPBACK_INVALID_PORT;
1030 1026 (void) hermon_loopback_copyout(&lb, arg, mode);
1031 1027 hermon_loopback_free_state(&lstate);
1032 1028 return (EINVAL);
1033 1029 }
1034 1030
1035 1031 lstate.hls_port = pi.p_port_num;
1036 1032 lstate.hls_lid = pi.p_base_lid;
1037 1033 lstate.hls_pkey_ix = (pi.p_linkstate == HERMON_PORT_LINK_ACTIVE) ?
1038 1034 1 : 0; /* XXX bogus assumption of a SUN subnet manager */
1039 1035 lstate.hls_state = state;
1040 1036 lstate.hls_retry = lb.alb_num_retry;
1041 1037
1042 1038 /* Free the temporary space used for GID table/PKey table */
1043 1039 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_gidtbl);
1044 1040 kmem_free(sgid_tbl, tbl_size * sizeof (ib_gid_t));
1045 1041 tbl_size = (1 << state->hs_cfg_profile->cp_log_max_pkeytbl);
1046 1042 kmem_free(pkey_tbl, tbl_size * sizeof (ib_pkey_t));
1047 1043
1048 1044 /*
1049 1045 * Compute the timeout duration in usec per the formula:
1050 1046 * to_usec_per_retry = 4.096us * (2 ^ supplied_timeout)
1051 1047 * (plus we add a little fudge-factor here too)
1052 1048 */
1053 1049 lstate.hls_timeout = lb.alb_timeout;
1054 1050 max_usec = (4096 * (1 << lstate.hls_timeout)) / 1000;
1055 1051 max_usec = max_usec * (lstate.hls_retry + 1);
1056 1052 max_usec = max_usec + 10000;
1057 1053
1058 1054 /*
1059 1055 * Determine how many times we should loop before declaring a
1060 1056 * timeout failure.
1061 1057 */
1062 1058 loopmax = max_usec/HERMON_VTS_LOOPBACK_MIN_WAIT_DUR;
1063 1059 if ((max_usec % HERMON_VTS_LOOPBACK_MIN_WAIT_DUR) != 0) {
1064 1060 loopmax++;
1065 1061 }
1066 1062
1067 1063 if (lb.alb_send_buf == NULL || lb.alb_buf_sz == 0) {
1068 1064 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_INVALID;
1069 1065 (void) hermon_loopback_copyout(&lb, arg, mode);
1070 1066 hermon_loopback_free_state(&lstate);
1071 1067 return (EINVAL);
1072 1068 }
1073 1069
1074 1070 /* Allocate protection domain (PD) */
1075 1071 if (hermon_loopback_init(state, &lstate) != 0) {
1076 1072 lb.alb_error_type = lstate.hls_err;
1077 1073 (void) hermon_loopback_copyout(&lb, arg, mode);
1078 1074 hermon_loopback_free_state(&lstate);
1079 1075 return (EFAULT);
1080 1076 }
1081 1077
1082 1078 /* Allocate and register a TX buffer */
1083 1079 if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_tx,
1084 1080 lb.alb_buf_sz) != 0) {
1085 1081 lb.alb_error_type =
1086 1082 HERMON_LOOPBACK_SEND_BUF_MEM_REGION_ALLOC_FAIL;
1087 1083 (void) hermon_loopback_copyout(&lb, arg, mode);
1088 1084 hermon_loopback_free_state(&lstate);
1089 1085 return (EFAULT);
1090 1086 }
1091 1087
1092 1088 /* Allocate and register an RX buffer */
1093 1089 if (hermon_loopback_alloc_mem(&lstate, &lstate.hls_rx,
1094 1090 lb.alb_buf_sz) != 0) {
1095 1091 lb.alb_error_type =
1096 1092 HERMON_LOOPBACK_RECV_BUF_MEM_REGION_ALLOC_FAIL;
1097 1093 (void) hermon_loopback_copyout(&lb, arg, mode);
1098 1094 hermon_loopback_free_state(&lstate);
1099 1095 return (EFAULT);
1100 1096 }
1101 1097
1102 1098 /* Copy in the transmit buffer data */
1103 1099 if (ddi_copyin((void *)lb.alb_send_buf, lstate.hls_tx.hlc_buf,
1104 1100 lb.alb_buf_sz, mode) != 0) {
1105 1101 lb.alb_error_type = HERMON_LOOPBACK_SEND_BUF_COPY_FAIL;
1106 1102 (void) hermon_loopback_copyout(&lb, arg, mode);
1107 1103 hermon_loopback_free_state(&lstate);
1108 1104 return (EFAULT);
1109 1105 }
1110 1106
1111 1107 /* Allocate the transmit QP and CQs */
1112 1108 lstate.hls_err = HERMON_LOOPBACK_XMIT_SEND_CQ_ALLOC_FAIL;
1113 1109 if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_tx) != 0) {
1114 1110 lb.alb_error_type = lstate.hls_err;
1115 1111 (void) hermon_loopback_copyout(&lb, arg, mode);
1116 1112 hermon_loopback_free_state(&lstate);
1117 1113 return (EFAULT);
1118 1114 }
1119 1115
1120 1116 /* Allocate the receive QP and CQs */
1121 1117 lstate.hls_err = HERMON_LOOPBACK_RECV_SEND_CQ_ALLOC_FAIL;
1122 1118 if (hermon_loopback_alloc_qps(&lstate, &lstate.hls_rx) != 0) {
1123 1119 lb.alb_error_type = lstate.hls_err;
1124 1120 (void) hermon_loopback_copyout(&lb, arg, mode);
1125 1121 hermon_loopback_free_state(&lstate);
1126 1122 return (EFAULT);
1127 1123 }
1128 1124
1129 1125 /* Activate the TX QP (connect to RX QP) */
1130 1126 lstate.hls_err = HERMON_LOOPBACK_XMIT_QP_INIT_FAIL;
1131 1127 if (hermon_loopback_modify_qp(&lstate, &lstate.hls_tx,
1132 1128 lstate.hls_rx.hlc_qp_num) != 0) {
1133 1129 lb.alb_error_type = lstate.hls_err;
1134 1130 (void) hermon_loopback_copyout(&lb, arg, mode);
1135 1131 hermon_loopback_free_state(&lstate);
1136 1132 return (EFAULT);
1137 1133 }
1138 1134
1139 1135 /* Activate the RX QP (connect to TX QP) */
1140 1136 lstate.hls_err = HERMON_LOOPBACK_RECV_QP_INIT_FAIL;
1141 1137 if (hermon_loopback_modify_qp(&lstate, &lstate.hls_rx,
1142 1138 lstate.hls_tx.hlc_qp_num) != 0) {
1143 1139 lb.alb_error_type = lstate.hls_err;
1144 1140 (void) hermon_loopback_copyout(&lb, arg, mode);
1145 1141 hermon_loopback_free_state(&lstate);
1146 1142 return (EFAULT);
1147 1143 }
1148 1144
1149 1145 /* Run the loopback test (for specified number of iterations) */
1150 1146 lb.alb_pass_done = 0;
1151 1147 for (iter = 0; iter < lb.alb_num_iter; iter++) {
1152 1148 lstate.hls_err = 0;
1153 1149 bzero(lstate.hls_rx.hlc_buf, lb.alb_buf_sz);
1154 1150
1155 1151 /* Post RDMA Write work request */
1156 1152 if (hermon_loopback_post_send(&lstate, &lstate.hls_tx,
1157 1153 &lstate.hls_rx) != IBT_SUCCESS) {
1158 1154 lb.alb_error_type = HERMON_LOOPBACK_WQE_POST_FAIL;
1159 1155 (void) hermon_loopback_copyout(&lb, arg, mode);
1160 1156 hermon_loopback_free_state(&lstate);
1161 1157 return (EFAULT);
1162 1158 }
1163 1159
1164 1160 /* Poll the TX CQ for a completion every few ticks */
1165 1161 for (j = 0; j < loopmax; j++) {
1166 1162 delay(drv_usectohz(HERMON_VTS_LOOPBACK_MIN_WAIT_DUR));
1167 1163
1168 1164 ret = hermon_loopback_poll_cq(&lstate, &lstate.hls_tx);
1169 1165 if (((ret != IBT_SUCCESS) && (ret != IBT_CQ_EMPTY)) ||
1170 1166 ((ret == IBT_CQ_EMPTY) && (j == loopmax - 1))) {
1171 1167 lb.alb_error_type =
1172 1168 HERMON_LOOPBACK_CQ_POLL_FAIL;
1173 1169 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1174 1170 lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1175 1171 mode) != 0) {
1176 1172 return (EFAULT);
1177 1173 }
1178 1174 (void) hermon_loopback_copyout(&lb, arg, mode);
1179 1175 hermon_loopback_free_state(&lstate);
1180 1176 return (EFAULT);
1181 1177 } else if (ret == IBT_CQ_EMPTY) {
1182 1178 continue;
1183 1179 }
1184 1180
1185 1181 /* Compare the data buffers */
1186 1182 if (bcmp(lstate.hls_tx.hlc_buf, lstate.hls_rx.hlc_buf,
1187 1183 lb.alb_buf_sz) == 0) {
1188 1184 break;
1189 1185 } else {
1190 1186 lb.alb_error_type =
1191 1187 HERMON_LOOPBACK_SEND_RECV_COMPARE_FAIL;
1192 1188 if (ddi_copyout(lstate.hls_rx.hlc_buf,
1193 1189 lb.alb_fail_buf, lstate.hls_tx.hlc_buf_sz,
1194 1190 mode) != 0) {
1195 1191 return (EFAULT);
1196 1192 }
1197 1193 (void) hermon_loopback_copyout(&lb, arg, mode);
1198 1194 hermon_loopback_free_state(&lstate);
1199 1195 return (EFAULT);
1200 1196 }
1201 1197 }
1202 1198
1203 1199 lstate.hls_err = HERMON_LOOPBACK_SUCCESS;
1204 1200 lb.alb_pass_done = iter + 1;
1205 1201 }
1206 1202
1207 1203 lb.alb_error_type = HERMON_LOOPBACK_SUCCESS;
1208 1204
1209 1205 /* Copy ioctl results back to user struct */
1210 1206 ret = hermon_loopback_copyout(&lb, arg, mode);
1211 1207
1212 1208 /* Free up everything and release all consumed resources */
1213 1209 hermon_loopback_free_state(&lstate);
1214 1210
1215 1211 return (ret);
1216 1212 }
1217 1213
1218 1214 #ifdef DEBUG
1219 1215 /*
1220 1216 * hermon_ioctl_reg_read()
1221 1217 */
1222 1218 static int
1223 1219 hermon_ioctl_reg_read(hermon_state_t *state, intptr_t arg, int mode)
1224 1220 {
1225 1221 hermon_reg_ioctl_t rdreg;
1226 1222 uint32_t *addr;
1227 1223 uintptr_t baseaddr;
1228 1224 int status;
1229 1225 ddi_acc_handle_t handle;
1230 1226
1231 1227 /* initialize the FMA retry loop */
1232 1228 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1233 1229
1234 1230 /*
1235 1231 * Access to Hemron registers is not allowed in "maintenance mode".
1236 1232 * This is primarily because the device may not have BARs to access
1237 1233 */
1238 1234 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1239 1235 return (EFAULT);
1240 1236 }
1241 1237
1242 1238 /* Copy in the hermon_reg_ioctl_t structure */
1243 1239 status = ddi_copyin((void *)arg, &rdreg, sizeof (hermon_reg_ioctl_t),
1244 1240 mode);
1245 1241 if (status != 0) {
1246 1242 return (EFAULT);
1247 1243 }
1248 1244
1249 1245 /* Determine base address for requested register set */
1250 1246 switch (rdreg.arg_reg_set) {
1251 1247 case HERMON_CMD_BAR:
1252 1248 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1253 1249 handle = hermon_get_cmdhdl(state);
1254 1250 break;
1255 1251
1256 1252 case HERMON_UAR_BAR:
1257 1253 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1258 1254 handle = hermon_get_uarhdl(state);
1259 1255 break;
1260 1256
1261 1257
1262 1258 default:
1263 1259 return (EINVAL);
1264 1260 }
1265 1261
1266 1262 /* Ensure that address is properly-aligned */
1267 1263 addr = (uint32_t *)((baseaddr + rdreg.arg_offset) & ~0x3);
1268 1264
1269 1265 /* the FMA retry loop starts. */
1270 1266 hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1271 1267 fm_status, fm_test);
1272 1268
1273 1269 /* Read the register pointed to by addr */
1274 1270 rdreg.arg_data = ddi_get32(handle, addr);
1275 1271
1276 1272 /* the FMA retry loop ends. */
1277 1273 hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1278 1274 fm_test);
1279 1275
1280 1276 /* Copy in the result into the hermon_reg_ioctl_t structure */
1281 1277 status = ddi_copyout(&rdreg, (void *)arg, sizeof (hermon_reg_ioctl_t),
1282 1278 mode);
1283 1279 if (status != 0) {
1284 1280 return (EFAULT);
1285 1281 }
1286 1282 return (0);
1287 1283
1288 1284 pio_error:
1289 1285 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1290 1286 return (EIO);
1291 1287 }
1292 1288
1293 1289
1294 1290 /*
1295 1291 * hermon_ioctl_reg_write()
1296 1292 */
1297 1293 static int
1298 1294 hermon_ioctl_reg_write(hermon_state_t *state, intptr_t arg, int mode)
1299 1295 {
1300 1296 hermon_reg_ioctl_t wrreg;
1301 1297 uint32_t *addr;
1302 1298 uintptr_t baseaddr;
1303 1299 int status;
1304 1300 ddi_acc_handle_t handle;
1305 1301
1306 1302 /* initialize the FMA retry loop */
1307 1303 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1308 1304
1309 1305 /*
1310 1306 * Access to Hermon registers is not allowed in "maintenance mode".
1311 1307 * This is primarily because the device may not have BARs to access
1312 1308 */
1313 1309 if (state->hs_operational_mode == HERMON_MAINTENANCE_MODE) {
1314 1310 return (EFAULT);
1315 1311 }
1316 1312
1317 1313 /* Copy in the hermon_reg_ioctl_t structure */
1318 1314 status = ddi_copyin((void *)arg, &wrreg, sizeof (hermon_reg_ioctl_t),
1319 1315 mode);
1320 1316 if (status != 0) {
1321 1317 return (EFAULT);
1322 1318 }
1323 1319
1324 1320 /* Determine base address for requested register set */
1325 1321 switch (wrreg.arg_reg_set) {
1326 1322 case HERMON_CMD_BAR:
1327 1323 baseaddr = (uintptr_t)state->hs_reg_cmd_baseaddr;
1328 1324 handle = hermon_get_cmdhdl(state);
1329 1325 break;
1330 1326
1331 1327 case HERMON_UAR_BAR:
1332 1328 baseaddr = (uintptr_t)state->hs_reg_uar_baseaddr;
1333 1329 handle = hermon_get_uarhdl(state);
1334 1330 break;
1335 1331
1336 1332 default:
1337 1333 return (EINVAL);
1338 1334 }
1339 1335
1340 1336 /* Ensure that address is properly-aligned */
1341 1337 addr = (uint32_t *)((baseaddr + wrreg.arg_offset) & ~0x3);
1342 1338
1343 1339 /* the FMA retry loop starts. */
1344 1340 hermon_pio_start(state, handle, pio_error, fm_loop_cnt,
1345 1341 fm_status, fm_test);
1346 1342
1347 1343 /* Write the data to the register pointed to by addr */
1348 1344 ddi_put32(handle, addr, wrreg.arg_data);
1349 1345
1350 1346 /* the FMA retry loop ends. */
1351 1347 hermon_pio_end(state, handle, pio_error, fm_loop_cnt, fm_status,
1352 1348 fm_test);
1353 1349 return (0);
1354 1350
1355 1351 pio_error:
1356 1352 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1357 1353 return (EIO);
1358 1354 }
1359 1355 #endif /* DEBUG */
1360 1356
1361 1357 static int
1362 1358 hermon_ioctl_write_boot_addr(hermon_state_t *state, dev_t dev, intptr_t arg,
1363 1359 int mode)
1364 1360 {
1365 1361 hermon_flash_ioctl_t ioctl_info;
1366 1362
1367 1363 /* initialize the FMA retry loop */
1368 1364 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1369 1365
1370 1366 /*
1371 1367 * Check that flash init ioctl has been called first. And check
1372 1368 * that the same dev_t that called init is the one calling write now.
1373 1369 */
1374 1370 mutex_enter(&state->hs_fw_flashlock);
1375 1371 if ((state->hs_fw_flashdev != dev) ||
1376 1372 (state->hs_fw_flashstarted == 0)) {
1377 1373 mutex_exit(&state->hs_fw_flashlock);
1378 1374 return (EIO);
1379 1375 }
1380 1376
1381 1377 /* copy user struct to kernel */
1382 1378 #ifdef _MULTI_DATAMODEL
1383 1379 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
1384 1380 hermon_flash_ioctl32_t info32;
1385 1381
1386 1382 if (ddi_copyin((void *)arg, &info32,
1387 1383 sizeof (hermon_flash_ioctl32_t), mode) != 0) {
1388 1384 mutex_exit(&state->hs_fw_flashlock);
1389 1385 return (EFAULT);
1390 1386 }
1391 1387 ioctl_info.af_type = info32.af_type;
1392 1388 ioctl_info.af_sector = (caddr_t)(uintptr_t)info32.af_sector;
1393 1389 ioctl_info.af_sector_num = info32.af_sector_num;
1394 1390 ioctl_info.af_addr = info32.af_addr;
1395 1391 ioctl_info.af_byte = info32.af_byte;
1396 1392 } else
1397 1393 #endif /* _MULTI_DATAMODEL */
1398 1394 if (ddi_copyin((void *)arg, &ioctl_info,
1399 1395 sizeof (hermon_flash_ioctl_t), mode) != 0) {
1400 1396 mutex_exit(&state->hs_fw_flashlock);
1401 1397 return (EFAULT);
1402 1398 }
1403 1399
1404 1400 switch (state->hs_fw_cmdset) {
1405 1401 case HERMON_FLASH_AMD_CMDSET:
1406 1402 case HERMON_FLASH_INTEL_CMDSET:
1407 1403 break;
1408 1404
1409 1405 case HERMON_FLASH_SPI_CMDSET:
1410 1406 {
1411 1407 ddi_acc_handle_t pci_hdl = hermon_get_pcihdl(state);
1412 1408
1413 1409 /* the FMA retry loop starts. */
1414 1410 hermon_pio_start(state, pci_hdl, pio_error,
1415 1411 fm_loop_cnt, fm_status, fm_test);
1416 1412
1417 1413 hermon_flash_write_cfg(state, pci_hdl,
1418 1414 HERMON_HW_FLASH_SPI_BOOT_ADDR_REG,
1419 1415 (ioctl_info.af_addr << 8) | 0x06);
1420 1416
1421 1417 /* the FMA retry loop ends. */
1422 1418 hermon_pio_end(state, pci_hdl, pio_error,
1423 1419 fm_loop_cnt, fm_status, fm_test);
1424 1420 break;
1425 1421 }
1426 1422
1427 1423 case HERMON_FLASH_UNKNOWN_CMDSET:
1428 1424 default:
1429 1425 mutex_exit(&state->hs_fw_flashlock);
1430 1426 return (EINVAL);
1431 1427 }
1432 1428 mutex_exit(&state->hs_fw_flashlock);
1433 1429 return (0);
1434 1430
1435 1431 pio_error:
1436 1432 mutex_exit(&state->hs_fw_flashlock);
1437 1433 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1438 1434 return (EIO);
1439 1435 }
1440 1436
1441 1437 /*
1442 1438 * hermon_flash_reset()
1443 1439 */
1444 1440 static int
1445 1441 hermon_flash_reset(hermon_state_t *state)
1446 1442 {
1447 1443 int status;
1448 1444
1449 1445 /*
1450 1446 * Performs a reset to the flash device. After a reset the flash will
1451 1447 * be operating in normal mode (capable of read/write, etc.).
1452 1448 */
1453 1449 switch (state->hs_fw_cmdset) {
1454 1450 case HERMON_FLASH_AMD_CMDSET:
1455 1451 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_AMD,
1456 1452 &status);
1457 1453 if (status != 0) {
1458 1454 return (status);
1459 1455 }
1460 1456 break;
1461 1457
1462 1458 case HERMON_FLASH_INTEL_CMDSET:
1463 1459 hermon_flash_write(state, 0x555, HERMON_HW_FLASH_RESET_INTEL,
1464 1460 &status);
1465 1461 if (status != 0) {
1466 1462 return (status);
1467 1463 }
1468 1464 break;
1469 1465
1470 1466 /* It appears no reset is needed for SPI */
1471 1467 case HERMON_FLASH_SPI_CMDSET:
1472 1468 status = 0;
1473 1469 break;
1474 1470
1475 1471 case HERMON_FLASH_UNKNOWN_CMDSET:
1476 1472 default:
1477 1473 status = EINVAL;
1478 1474 break;
1479 1475 }
1480 1476 return (status);
1481 1477 }
1482 1478
1483 1479 /*
1484 1480 * hermon_flash_read_sector()
1485 1481 */
1486 1482 static int
1487 1483 hermon_flash_read_sector(hermon_state_t *state, uint32_t sector_num)
1488 1484 {
1489 1485 uint32_t addr;
1490 1486 uint32_t end_addr;
1491 1487 uint32_t *image;
1492 1488 int i, status;
1493 1489
1494 1490 image = (uint32_t *)&state->hs_fw_sector[0];
1495 1491
1496 1492 /*
1497 1493 * Calculate the start and end address of the sector, based on the
1498 1494 * sector number passed in.
1499 1495 */
1500 1496 addr = sector_num << state->hs_fw_log_sector_sz;
1501 1497 end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1502 1498
1503 1499 /* Set the flash bank correctly for the given address */
1504 1500 if ((status = hermon_flash_bank(state, addr)) != 0)
1505 1501 return (status);
1506 1502
1507 1503 /* Read the entire sector, one quadlet at a time */
1508 1504 for (i = 0; addr < end_addr; i++, addr += 4) {
1509 1505 image[i] = hermon_flash_read(state, addr, &status);
1510 1506 if (status != 0) {
1511 1507 return (status);
1512 1508 }
1513 1509 }
1514 1510 return (0);
1515 1511 }
1516 1512
1517 1513 /*
1518 1514 * hermon_flash_read_quadlet()
1519 1515 */
1520 1516 static int
1521 1517 hermon_flash_read_quadlet(hermon_state_t *state, uint32_t *data,
1522 1518 uint32_t addr)
1523 1519 {
1524 1520 int status;
1525 1521
1526 1522 /* Set the flash bank correctly for the given address */
1527 1523 if ((status = hermon_flash_bank(state, addr)) != 0) {
1528 1524 return (status);
1529 1525 }
1530 1526
1531 1527 /* Read one quadlet of data */
1532 1528 *data = hermon_flash_read(state, addr, &status);
1533 1529 if (status != 0) {
1534 1530 return (EIO);
1535 1531 }
1536 1532
1537 1533 return (0);
1538 1534 }
1539 1535
1540 1536 /*
1541 1537 * hermon_flash_write_sector()
1542 1538 */
1543 1539 static int
1544 1540 hermon_flash_write_sector(hermon_state_t *state, uint32_t sector_num)
1545 1541 {
1546 1542 uint32_t addr;
1547 1543 uint32_t end_addr;
1548 1544 uint32_t *databuf;
1549 1545 uchar_t *sector;
1550 1546 int status = 0;
1551 1547 int i;
1552 1548
1553 1549 sector = (uchar_t *)&state->hs_fw_sector[0];
1554 1550
1555 1551 /*
1556 1552 * Calculate the start and end address of the sector, based on the
1557 1553 * sector number passed in.
1558 1554 */
1559 1555 addr = sector_num << state->hs_fw_log_sector_sz;
1560 1556 end_addr = addr + (1 << state->hs_fw_log_sector_sz);
1561 1557
1562 1558 /* Set the flash bank correctly for the given address */
1563 1559 if ((status = hermon_flash_bank(state, addr)) != 0 ||
1564 1560 (status = hermon_flash_reset(state)) != 0) {
1565 1561 return (status);
1566 1562 }
1567 1563
1568 1564 /* Erase the sector before writing */
1569 1565 status = hermon_flash_erase_sector(state, sector_num);
1570 1566 if (status != 0) {
1571 1567 return (status);
1572 1568 }
1573 1569
1574 1570 switch (state->hs_fw_cmdset) {
1575 1571 case HERMON_FLASH_SPI_CMDSET:
1576 1572 databuf = (uint32_t *)(void *)sector;
1577 1573 /* Write the sector, one dword at a time */
1578 1574 for (i = 0; addr < end_addr; i++, addr += 4) {
1579 1575 if ((status = hermon_flash_spi_write_dword(state, addr,
1580 1576 htonl(databuf[i]))) != 0) {
1581 1577 return (status);
1582 1578 }
1583 1579 }
1584 1580 status = hermon_flash_reset(state);
1585 1581 break;
1586 1582
1587 1583 case HERMON_FLASH_INTEL_CMDSET:
1588 1584 case HERMON_FLASH_AMD_CMDSET:
1589 1585 /* Write the sector, one byte at a time */
1590 1586 for (i = 0; addr < end_addr; i++, addr++) {
1591 1587 status = hermon_flash_write_byte(state, addr,
1592 1588 sector[i]);
1593 1589 if (status != 0) {
1594 1590 break;
1595 1591 }
1596 1592 }
1597 1593 status = hermon_flash_reset(state);
1598 1594 break;
1599 1595
1600 1596 case HERMON_FLASH_UNKNOWN_CMDSET:
1601 1597 default:
1602 1598 status = EINVAL;
1603 1599 break;
1604 1600 }
1605 1601
1606 1602 return (status);
1607 1603 }
1608 1604
1609 1605 /*
1610 1606 * hermon_flash_spi_write_dword()
1611 1607 *
1612 1608 * NOTE: This function assumes that "data" is in network byte order.
1613 1609 *
1614 1610 */
1615 1611 static int
1616 1612 hermon_flash_spi_write_dword(hermon_state_t *state, uint32_t addr,
1617 1613 uint32_t data)
1618 1614 {
1619 1615 int status;
1620 1616 ddi_acc_handle_t hdl;
1621 1617
1622 1618 /* initialize the FMA retry loop */
1623 1619 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1624 1620
1625 1621 hdl = hermon_get_pcihdl(state);
1626 1622
1627 1623 /* the FMA retry loop starts. */
1628 1624 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1629 1625 fm_test);
1630 1626
1631 1627 /* Issue Write Enable */
1632 1628 hermon_flash_spi_write_enable(state);
1633 1629
1634 1630 /* Set the Address */
1635 1631 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1636 1632 addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1637 1633
1638 1634 /* Set the Data */
1639 1635 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_DATA, data);
1640 1636
1641 1637 /* Set the Page Program and execute */
1642 1638 hermon_flash_spi_exec_command(state, hdl,
1643 1639 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1644 1640 HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1645 1641 HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
1646 1642 HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
1647 1643 (HERMON_HW_FLASH_SPI_PAGE_PROGRAM <<
1648 1644 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1649 1645
1650 1646 /* Wait for write to complete */
1651 1647 if ((status = hermon_flash_spi_wait_wip(state)) != 0) {
1652 1648 return (status);
1653 1649 }
1654 1650
1655 1651 /* the FMA retry loop ends. */
1656 1652 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
1657 1653 return (0);
1658 1654
1659 1655 pio_error:
1660 1656 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1661 1657 return (EIO);
1662 1658 }
1663 1659
1664 1660 /*
1665 1661 * hermon_flash_write_byte()
1666 1662 */
1667 1663 static int
1668 1664 hermon_flash_write_byte(hermon_state_t *state, uint32_t addr, uchar_t data)
1669 1665 {
1670 1666 uint32_t stat;
1671 1667 int status = 0;
1672 1668 int dword_addr;
1673 1669 int byte_offset;
1674 1670 int i;
1675 1671 union {
1676 1672 uint8_t bytes[4];
1677 1673 uint32_t dword;
1678 1674 } dword;
1679 1675
1680 1676 switch (state->hs_fw_cmdset) {
1681 1677 case HERMON_FLASH_AMD_CMDSET:
1682 1678 /* Issue Flash Byte program command */
1683 1679 hermon_flash_write(state, addr, 0xAA, &status);
1684 1680 if (status != 0) {
1685 1681 return (status);
1686 1682 }
1687 1683
1688 1684 hermon_flash_write(state, addr, 0x55, &status);
1689 1685 if (status != 0) {
1690 1686 return (status);
1691 1687 }
1692 1688
1693 1689 hermon_flash_write(state, addr, 0xA0, &status);
1694 1690 if (status != 0) {
1695 1691 return (status);
1696 1692 }
1697 1693
1698 1694 hermon_flash_write(state, addr, data, &status);
1699 1695 if (status != 0) {
1700 1696 return (status);
1701 1697 }
1702 1698
1703 1699 /* Wait for Write Byte to Complete */
1704 1700 i = 0;
1705 1701 do {
1706 1702 drv_usecwait(1);
1707 1703 stat = hermon_flash_read(state, addr & ~3, &status);
1708 1704 if (status != 0) {
1709 1705 return (status);
1710 1706 }
1711 1707
1712 1708 if (i == hermon_hw_flash_timeout_write) {
1713 1709 cmn_err(CE_WARN,
1714 1710 "hermon_flash_write_byte: ACS write "
1715 1711 "timeout: addr: 0x%x, data: 0x%x\n",
1716 1712 addr, data);
1717 1713 hermon_fm_ereport(state, HCA_SYS_ERR,
1718 1714 HCA_ERR_IOCTL);
1719 1715 return (EIO);
1720 1716 }
1721 1717 i++;
1722 1718 } while (data != ((stat >> ((3 - (addr & 3)) << 3)) & 0xFF));
1723 1719
1724 1720 break;
1725 1721
1726 1722 case HERMON_FLASH_INTEL_CMDSET:
1727 1723 /* Issue Flash Byte program command */
1728 1724 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_WRITE,
1729 1725 &status);
1730 1726 if (status != 0) {
1731 1727 return (status);
1732 1728 }
1733 1729 hermon_flash_write(state, addr, data, &status);
1734 1730 if (status != 0) {
1735 1731 return (status);
1736 1732 }
1737 1733
1738 1734 /* Wait for Write Byte to Complete */
1739 1735 i = 0;
1740 1736 do {
1741 1737 drv_usecwait(1);
1742 1738 stat = hermon_flash_read(state, addr & ~3, &status);
1743 1739 if (status != 0) {
1744 1740 return (status);
1745 1741 }
1746 1742
1747 1743 if (i == hermon_hw_flash_timeout_write) {
1748 1744 cmn_err(CE_WARN,
1749 1745 "hermon_flash_write_byte: ICS write "
1750 1746 "timeout: addr: %x, data: %x\n",
1751 1747 addr, data);
1752 1748 hermon_fm_ereport(state, HCA_SYS_ERR,
1753 1749 HCA_ERR_IOCTL);
1754 1750 return (EIO);
1755 1751 }
1756 1752 i++;
1757 1753 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1758 1754
1759 1755 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1760 1756 cmn_err(CE_WARN,
1761 1757 "hermon_flash_write_byte: ICS write cmd error: "
1762 1758 "addr: %x, data: %x\n",
1763 1759 addr, data);
1764 1760 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1765 1761 return (EIO);
1766 1762 }
1767 1763 break;
1768 1764
1769 1765 case HERMON_FLASH_SPI_CMDSET:
1770 1766 /*
1771 1767 * Our lowest write granularity on SPI is a dword.
1772 1768 * To support this ioctl option, we can read in the
1773 1769 * dword that contains this byte, modify this byte,
1774 1770 * and write the dword back out.
1775 1771 */
1776 1772
1777 1773 /* Determine dword offset and byte offset within the dword */
1778 1774 byte_offset = addr & 3;
1779 1775 dword_addr = addr - byte_offset;
1780 1776 #ifdef _LITTLE_ENDIAN
1781 1777 byte_offset = 3 - byte_offset;
1782 1778 #endif
1783 1779
1784 1780 /* Read in dword */
1785 1781 if ((status = hermon_flash_read_quadlet(state, &dword.dword,
1786 1782 dword_addr)) != 0)
1787 1783 break;
1788 1784
1789 1785 /* Set "data" to the appopriate byte */
1790 1786 dword.bytes[byte_offset] = data;
1791 1787
1792 1788 /* Write modified dword back out */
1793 1789 status = hermon_flash_spi_write_dword(state, dword_addr,
1794 1790 dword.dword);
1795 1791
1796 1792 break;
1797 1793
1798 1794 case HERMON_FLASH_UNKNOWN_CMDSET:
1799 1795 default:
1800 1796 cmn_err(CE_WARN,
1801 1797 "hermon_flash_write_byte: unknown cmd set: 0x%x\n",
1802 1798 state->hs_fw_cmdset);
1803 1799 status = EINVAL;
1804 1800 break;
1805 1801 }
1806 1802
1807 1803 return (status);
1808 1804 }
1809 1805
1810 1806 /*
1811 1807 * hermon_flash_erase_sector()
1812 1808 */
1813 1809 static int
1814 1810 hermon_flash_erase_sector(hermon_state_t *state, uint32_t sector_num)
1815 1811 {
1816 1812 ddi_acc_handle_t hdl;
1817 1813 uint32_t addr;
1818 1814 uint32_t stat;
1819 1815 int status = 0;
1820 1816 int i;
1821 1817
1822 1818 /* initialize the FMA retry loop */
1823 1819 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
1824 1820
1825 1821 /* Get address from sector num */
1826 1822 addr = sector_num << state->hs_fw_log_sector_sz;
1827 1823
1828 1824 switch (state->hs_fw_cmdset) {
1829 1825 case HERMON_FLASH_AMD_CMDSET:
1830 1826 /* Issue Flash Sector Erase Command */
1831 1827 hermon_flash_write(state, addr, 0xAA, &status);
1832 1828 if (status != 0) {
1833 1829 return (status);
1834 1830 }
1835 1831
1836 1832 hermon_flash_write(state, addr, 0x55, &status);
1837 1833 if (status != 0) {
1838 1834 return (status);
1839 1835 }
1840 1836
1841 1837 hermon_flash_write(state, addr, 0x80, &status);
1842 1838 if (status != 0) {
1843 1839 return (status);
1844 1840 }
1845 1841
1846 1842 hermon_flash_write(state, addr, 0xAA, &status);
1847 1843 if (status != 0) {
1848 1844 return (status);
1849 1845 }
1850 1846
1851 1847 hermon_flash_write(state, addr, 0x55, &status);
1852 1848 if (status != 0) {
1853 1849 return (status);
1854 1850 }
1855 1851
1856 1852 hermon_flash_write(state, addr, 0x30, &status);
1857 1853 if (status != 0) {
1858 1854 return (status);
1859 1855 }
1860 1856
1861 1857 /* Wait for Sector Erase to complete */
1862 1858 i = 0;
1863 1859 do {
1864 1860 drv_usecwait(1);
1865 1861 stat = hermon_flash_read(state, addr, &status);
1866 1862 if (status != 0) {
1867 1863 return (status);
1868 1864 }
1869 1865
1870 1866 if (i == hermon_hw_flash_timeout_erase) {
1871 1867 cmn_err(CE_WARN,
1872 1868 "hermon_flash_erase_sector: "
1873 1869 "ACS erase timeout\n");
1874 1870 hermon_fm_ereport(state, HCA_SYS_ERR,
1875 1871 HCA_ERR_IOCTL);
1876 1872 return (EIO);
1877 1873 }
1878 1874 i++;
1879 1875 } while (stat != 0xFFFFFFFF);
1880 1876 break;
1881 1877
1882 1878 case HERMON_FLASH_INTEL_CMDSET:
1883 1879 /* Issue Flash Sector Erase Command */
1884 1880 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_ERASE,
1885 1881 &status);
1886 1882 if (status != 0) {
1887 1883 return (status);
1888 1884 }
1889 1885
1890 1886 hermon_flash_write(state, addr, HERMON_HW_FLASH_ICS_CONFIRM,
1891 1887 &status);
1892 1888 if (status != 0) {
1893 1889 return (status);
1894 1890 }
1895 1891
1896 1892 /* Wait for Sector Erase to complete */
1897 1893 i = 0;
1898 1894 do {
1899 1895 drv_usecwait(1);
1900 1896 stat = hermon_flash_read(state, addr & ~3, &status);
1901 1897 if (status != 0) {
1902 1898 return (status);
1903 1899 }
1904 1900
1905 1901 if (i == hermon_hw_flash_timeout_erase) {
1906 1902 cmn_err(CE_WARN,
1907 1903 "hermon_flash_erase_sector: "
1908 1904 "ICS erase timeout\n");
1909 1905 hermon_fm_ereport(state, HCA_SYS_ERR,
1910 1906 HCA_ERR_IOCTL);
1911 1907 return (EIO);
1912 1908 }
1913 1909 i++;
1914 1910 } while ((stat & HERMON_HW_FLASH_ICS_READY) == 0);
1915 1911
1916 1912 if (stat & HERMON_HW_FLASH_ICS_ERROR) {
1917 1913 cmn_err(CE_WARN,
1918 1914 "hermon_flash_erase_sector: "
1919 1915 "ICS erase cmd error\n");
1920 1916 hermon_fm_ereport(state, HCA_SYS_ERR,
1921 1917 HCA_ERR_IOCTL);
1922 1918 return (EIO);
1923 1919 }
1924 1920 break;
1925 1921
1926 1922 case HERMON_FLASH_SPI_CMDSET:
1927 1923 hdl = hermon_get_pcihdl(state);
1928 1924
1929 1925 /* the FMA retry loop starts. */
1930 1926 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
1931 1927 fm_test);
1932 1928
1933 1929 /* Issue Write Enable */
1934 1930 hermon_flash_spi_write_enable(state);
1935 1931
1936 1932 /* Set the Address */
1937 1933 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
1938 1934 addr & HERMON_HW_FLASH_SPI_ADDR_MASK);
1939 1935
1940 1936 /* Issue Flash Sector Erase */
1941 1937 hermon_flash_spi_exec_command(state, hdl,
1942 1938 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
1943 1939 HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
1944 1940 ((uint32_t)(HERMON_HW_FLASH_SPI_SECTOR_ERASE) <<
1945 1941 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
1946 1942
1947 1943 /* the FMA retry loop ends. */
1948 1944 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status,
1949 1945 fm_test);
1950 1946
1951 1947 /* Wait for Sector Erase to complete */
1952 1948 status = hermon_flash_spi_wait_wip(state);
1953 1949 break;
1954 1950
1955 1951 case HERMON_FLASH_UNKNOWN_CMDSET:
1956 1952 default:
1957 1953 cmn_err(CE_WARN,
1958 1954 "hermon_flash_erase_sector: unknown cmd set: 0x%x\n",
1959 1955 state->hs_fw_cmdset);
1960 1956 status = EINVAL;
1961 1957 break;
1962 1958 }
1963 1959
1964 1960 /* Reset the flash device */
1965 1961 if (status == 0) {
1966 1962 status = hermon_flash_reset(state);
1967 1963 }
1968 1964 return (status);
1969 1965
1970 1966 pio_error:
1971 1967 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
1972 1968 return (EIO);
1973 1969 }
1974 1970
1975 1971 /*
1976 1972 * hermon_flash_erase_chip()
1977 1973 */
1978 1974 static int
1979 1975 hermon_flash_erase_chip(hermon_state_t *state)
1980 1976 {
1981 1977 uint32_t stat;
1982 1978 uint_t size;
1983 1979 int status = 0;
1984 1980 int i;
1985 1981 int num_sect;
1986 1982
1987 1983 switch (state->hs_fw_cmdset) {
1988 1984 case HERMON_FLASH_AMD_CMDSET:
1989 1985 /* Issue Flash Chip Erase Command */
1990 1986 hermon_flash_write(state, 0, 0xAA, &status);
1991 1987 if (status != 0) {
1992 1988 return (status);
1993 1989 }
1994 1990
1995 1991 hermon_flash_write(state, 0, 0x55, &status);
1996 1992 if (status != 0) {
1997 1993 return (status);
1998 1994 }
1999 1995
2000 1996 hermon_flash_write(state, 0, 0x80, &status);
2001 1997 if (status != 0) {
2002 1998 return (status);
2003 1999 }
2004 2000
2005 2001 hermon_flash_write(state, 0, 0xAA, &status);
2006 2002 if (status != 0) {
2007 2003 return (status);
2008 2004 }
2009 2005
2010 2006 hermon_flash_write(state, 0, 0x55, &status);
2011 2007 if (status != 0) {
2012 2008 return (status);
2013 2009 }
2014 2010
2015 2011 hermon_flash_write(state, 0, 0x10, &status);
2016 2012 if (status != 0) {
2017 2013 return (status);
2018 2014 }
2019 2015
2020 2016 /* Wait for Chip Erase to Complete */
2021 2017 i = 0;
2022 2018 do {
2023 2019 drv_usecwait(1);
2024 2020 stat = hermon_flash_read(state, 0, &status);
2025 2021 if (status != 0) {
2026 2022 return (status);
2027 2023 }
2028 2024
2029 2025 if (i == hermon_hw_flash_timeout_erase) {
2030 2026 cmn_err(CE_WARN,
2031 2027 "hermon_flash_erase_chip: erase timeout\n");
2032 2028 hermon_fm_ereport(state, HCA_SYS_ERR,
2033 2029 HCA_ERR_IOCTL);
2034 2030 return (EIO);
2035 2031 }
2036 2032 i++;
2037 2033 } while (stat != 0xFFFFFFFF);
2038 2034 break;
2039 2035
2040 2036 case HERMON_FLASH_INTEL_CMDSET:
2041 2037 case HERMON_FLASH_SPI_CMDSET:
2042 2038 /*
2043 2039 * These chips don't have a chip erase command, so erase
2044 2040 * all blocks one at a time.
2045 2041 */
2046 2042 size = (0x1 << state->hs_fw_log_sector_sz);
2047 2043 num_sect = state->hs_fw_device_sz / size;
2048 2044
2049 2045 for (i = 0; i < num_sect; i++) {
2050 2046 status = hermon_flash_erase_sector(state, i);
2051 2047 if (status != 0) {
2052 2048 cmn_err(CE_WARN,
2053 2049 "hermon_flash_erase_chip: "
2054 2050 "sector %d erase error\n", i);
2055 2051 return (status);
2056 2052 }
2057 2053 }
2058 2054 break;
2059 2055
2060 2056 case HERMON_FLASH_UNKNOWN_CMDSET:
2061 2057 default:
2062 2058 cmn_err(CE_WARN, "hermon_flash_erase_chip: "
2063 2059 "unknown cmd set: 0x%x\n", state->hs_fw_cmdset);
2064 2060 status = EINVAL;
2065 2061 break;
2066 2062 }
2067 2063
2068 2064 return (status);
2069 2065 }
2070 2066
2071 2067 /*
2072 2068 * hermon_flash_spi_write_enable()
2073 2069 */
2074 2070 static void
2075 2071 hermon_flash_spi_write_enable(hermon_state_t *state)
2076 2072 {
2077 2073 ddi_acc_handle_t hdl;
2078 2074
2079 2075 hdl = hermon_get_pcihdl(state);
2080 2076
2081 2077 hermon_flash_spi_exec_command(state, hdl,
2082 2078 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2083 2079 (HERMON_HW_FLASH_SPI_WRITE_ENABLE <<
2084 2080 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2085 2081 }
2086 2082
2087 2083 /*
2088 2084 * hermon_flash_spi_wait_wip()
2089 2085 */
2090 2086 static int
2091 2087 hermon_flash_spi_wait_wip(hermon_state_t *state)
2092 2088 {
2093 2089 ddi_acc_handle_t hdl;
2094 2090 uint32_t status;
2095 2091
2096 2092 /* initialize the FMA retry loop */
2097 2093 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2098 2094
2099 2095 hdl = hermon_get_pcihdl(state);
2100 2096
2101 2097 /* the FMA retry loop starts. */
2102 2098 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2103 2099 fm_test);
2104 2100
2105 2101 /* wait on the gateway to clear busy */
2106 2102 do {
2107 2103 status = hermon_flash_read_cfg(state, hdl,
2108 2104 HERMON_HW_FLASH_SPI_GW);
2109 2105 } while (status & HERMON_HW_FLASH_SPI_BUSY);
2110 2106
2111 2107 /* now, get the status and check for WIP to clear */
2112 2108 do {
2113 2109 hermon_flash_spi_exec_command(state, hdl,
2114 2110 HERMON_HW_FLASH_SPI_READ_OP |
2115 2111 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2116 2112 HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2117 2113 HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2118 2114 (HERMON_HW_FLASH_SPI_READ_STATUS_REG <<
2119 2115 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2120 2116
2121 2117 status = hermon_flash_read_cfg(state, hdl,
2122 2118 HERMON_HW_FLASH_SPI_DATA);
2123 2119 } while (status & HERMON_HW_FLASH_SPI_WIP);
2124 2120
2125 2121 /* the FMA retry loop ends. */
2126 2122 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2127 2123 return (0);
2128 2124
2129 2125 pio_error:
2130 2126 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2131 2127 return (EIO);
2132 2128 }
2133 2129
2134 2130 /*
2135 2131 * hermon_flash_bank()
2136 2132 */
2137 2133 static int
2138 2134 hermon_flash_bank(hermon_state_t *state, uint32_t addr)
2139 2135 {
2140 2136 ddi_acc_handle_t hdl;
2141 2137 uint32_t bank;
↓ open down ↓ |
1176 lines elided |
↑ open up ↑ |
2142 2138
2143 2139 /* initialize the FMA retry loop */
2144 2140 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2145 2141
2146 2142 /* Set handle */
2147 2143 hdl = hermon_get_pcihdl(state);
2148 2144
2149 2145 /* Determine the bank setting from the address */
2150 2146 bank = addr & HERMON_HW_FLASH_BANK_MASK;
2151 2147
2152 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(state->hs_fw_flashbank))
2153 -
2154 2148 /*
2155 2149 * If the bank is different from the currently set bank, we need to
2156 2150 * change it. Also, if an 'addr' of 0 is given, this allows the
2157 2151 * capability to force the flash bank to 0. This is useful at init
2158 2152 * time to initially set the bank value
2159 2153 */
2160 2154 if (state->hs_fw_flashbank != bank || addr == 0) {
2161 2155 switch (state->hs_fw_cmdset) {
2162 2156 case HERMON_FLASH_SPI_CMDSET:
2163 2157 /* CMJ: not needed for hermon */
2164 2158 break;
2165 2159
2166 2160 case HERMON_FLASH_INTEL_CMDSET:
2167 2161 case HERMON_FLASH_AMD_CMDSET:
2168 2162 /* the FMA retry loop starts. */
2169 2163 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt,
2170 2164 fm_status, fm_test);
2171 2165
2172 2166 hermon_flash_write_cfg(state, hdl,
2173 2167 HERMON_HW_FLASH_GPIO_DATACLEAR, 0x70);
2174 2168 hermon_flash_write_cfg(state, hdl,
2175 2169 HERMON_HW_FLASH_GPIO_DATASET, (bank >> 15) & 0x70);
2176 2170
2177 2171 /* the FMA retry loop ends. */
2178 2172 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt,
2179 2173 fm_status, fm_test);
2180 2174 break;
2181 2175
2182 2176 case HERMON_FLASH_UNKNOWN_CMDSET:
2183 2177 default:
2184 2178 return (EINVAL);
2185 2179 }
2186 2180
2187 2181 state->hs_fw_flashbank = bank;
2188 2182 }
2189 2183 return (0);
2190 2184
2191 2185 pio_error:
2192 2186 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2193 2187 return (EIO);
2194 2188 }
2195 2189
2196 2190 /*
2197 2191 * hermon_flash_spi_exec_command()
2198 2192 */
2199 2193 static void
2200 2194 hermon_flash_spi_exec_command(hermon_state_t *state, ddi_acc_handle_t hdl,
2201 2195 uint32_t cmd)
2202 2196 {
2203 2197 uint32_t data;
2204 2198 int timeout = 0;
2205 2199
2206 2200 cmd |= HERMON_HW_FLASH_SPI_BUSY | HERMON_HW_FLASH_SPI_ENABLE_OFF;
2207 2201
2208 2202 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_GW, cmd);
2209 2203
2210 2204 do {
2211 2205 data = hermon_flash_read_cfg(state, hdl,
2212 2206 HERMON_HW_FLASH_SPI_GW);
2213 2207 timeout++;
2214 2208 } while ((data & HERMON_HW_FLASH_SPI_BUSY) &&
2215 2209 (timeout < hermon_hw_flash_timeout_config));
2216 2210 }
2217 2211
2218 2212 /*
2219 2213 * hermon_flash_read()
2220 2214 */
2221 2215 static uint32_t
2222 2216 hermon_flash_read(hermon_state_t *state, uint32_t addr, int *err)
2223 2217 {
2224 2218 ddi_acc_handle_t hdl;
2225 2219 uint32_t data = 0;
2226 2220 int timeout, status = 0;
2227 2221
2228 2222 /* initialize the FMA retry loop */
2229 2223 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2230 2224
2231 2225 hdl = hermon_get_pcihdl(state);
2232 2226
2233 2227 /* the FMA retry loop starts. */
2234 2228 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2235 2229 fm_test);
2236 2230
2237 2231 switch (state->hs_fw_cmdset) {
2238 2232 case HERMON_FLASH_SPI_CMDSET:
2239 2233 /* Set the transaction address */
2240 2234 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_SPI_ADDR,
2241 2235 (addr & HERMON_HW_FLASH_SPI_ADDR_MASK));
2242 2236
2243 2237 hermon_flash_spi_exec_command(state, hdl,
2244 2238 HERMON_HW_FLASH_SPI_READ_OP |
2245 2239 HERMON_HW_FLASH_SPI_INSTR_PHASE_OFF |
2246 2240 HERMON_HW_FLASH_SPI_ADDR_PHASE_OFF |
2247 2241 HERMON_HW_FLASH_SPI_DATA_PHASE_OFF |
2248 2242 HERMON_HW_FLASH_SPI_TRANS_SZ_4B |
2249 2243 (HERMON_HW_FLASH_SPI_READ <<
2250 2244 HERMON_HW_FLASH_SPI_INSTR_SHIFT));
2251 2245
2252 2246 data = hermon_flash_read_cfg(state, hdl,
2253 2247 HERMON_HW_FLASH_SPI_DATA);
2254 2248 break;
2255 2249
2256 2250 case HERMON_FLASH_INTEL_CMDSET:
2257 2251 case HERMON_FLASH_AMD_CMDSET:
2258 2252 /*
2259 2253 * The Read operation does the following:
2260 2254 * 1) Write the masked address to the HERMON_FLASH_ADDR
2261 2255 * register. Only the least significant 19 bits are valid.
2262 2256 * 2) Read back the register until the command has completed.
2263 2257 * 3) Read the data retrieved from the address at the
2264 2258 * HERMON_FLASH_DATA register.
2265 2259 */
2266 2260 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2267 2261 (addr & HERMON_HW_FLASH_ADDR_MASK) | (1 << 29));
2268 2262
2269 2263 timeout = 0;
2270 2264 do {
2271 2265 data = hermon_flash_read_cfg(state, hdl,
2272 2266 HERMON_HW_FLASH_ADDR);
2273 2267 timeout++;
2274 2268 } while ((data & HERMON_HW_FLASH_CMD_MASK) &&
2275 2269 (timeout < hermon_hw_flash_timeout_config));
2276 2270
2277 2271 if (timeout == hermon_hw_flash_timeout_config) {
2278 2272 cmn_err(CE_WARN, "hermon_flash_read: command timed "
2279 2273 "out.\n");
2280 2274 *err = EIO;
2281 2275 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2282 2276 return (data);
2283 2277 }
2284 2278
2285 2279 data = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_DATA);
2286 2280 break;
2287 2281
2288 2282 case HERMON_FLASH_UNKNOWN_CMDSET:
2289 2283 default:
2290 2284 cmn_err(CE_CONT, "hermon_flash_read: unknown cmdset: 0x%x\n",
2291 2285 state->hs_fw_cmdset);
2292 2286 status = EINVAL;
2293 2287 break;
2294 2288 }
2295 2289
2296 2290
2297 2291 /* the FMA retry loop ends. */
2298 2292 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2299 2293 *err = status;
2300 2294 return (data);
2301 2295
2302 2296 pio_error:
2303 2297 *err = EIO;
2304 2298 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2305 2299 return (data);
2306 2300 }
2307 2301
2308 2302 /*
2309 2303 * hermon_flash_write()
2310 2304 */
2311 2305 static void
2312 2306 hermon_flash_write(hermon_state_t *state, uint32_t addr, uchar_t data, int *err)
2313 2307 {
2314 2308 ddi_acc_handle_t hdl;
2315 2309 int cmd;
2316 2310 int timeout;
2317 2311
2318 2312 /* initialize the FMA retry loop */
2319 2313 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2320 2314
2321 2315 hdl = hermon_get_pcihdl(state);
2322 2316
2323 2317 /* the FMA retry loop starts. */
2324 2318 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2325 2319 fm_test);
2326 2320
2327 2321 /*
2328 2322 * The Write operation does the following:
2329 2323 * 1) Write the data to be written to the HERMON_FLASH_DATA offset.
2330 2324 * 2) Write the address to write the data to to the HERMON_FLASH_ADDR
2331 2325 * offset.
2332 2326 * 3) Wait until the write completes.
2333 2327 */
2334 2328
2335 2329 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_DATA, data << 24);
2336 2330 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_ADDR,
2337 2331 (addr & 0x7FFFF) | (2 << 29));
2338 2332
2339 2333 timeout = 0;
2340 2334 do {
2341 2335 cmd = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_ADDR);
2342 2336 timeout++;
2343 2337 } while ((cmd & HERMON_HW_FLASH_CMD_MASK) &&
2344 2338 (timeout < hermon_hw_flash_timeout_config));
2345 2339
2346 2340 if (timeout == hermon_hw_flash_timeout_config) {
2347 2341 cmn_err(CE_WARN, "hermon_flash_write: config cmd timeout.\n");
2348 2342 *err = EIO;
2349 2343 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2350 2344 return;
2351 2345 }
2352 2346
2353 2347 /* the FMA retry loop ends. */
2354 2348 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2355 2349 *err = 0;
2356 2350 return;
2357 2351
2358 2352 pio_error:
2359 2353 *err = EIO;
2360 2354 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2361 2355 }
2362 2356
2363 2357 /*
2364 2358 * hermon_flash_init()
2365 2359 */
2366 2360 static int
2367 2361 hermon_flash_init(hermon_state_t *state)
2368 2362 {
2369 2363 uint32_t word;
2370 2364 ddi_acc_handle_t hdl;
2371 2365 int sema_cnt;
2372 2366 int gpio;
2373 2367
2374 2368 /* initialize the FMA retry loop */
2375 2369 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2376 2370
2377 2371 /* Set handle */
2378 2372 hdl = hermon_get_pcihdl(state);
2379 2373
2380 2374 /* the FMA retry loop starts. */
2381 2375 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2382 2376 fm_test);
2383 2377
2384 2378 /* Init the flash */
2385 2379
2386 2380 #ifdef DO_WRCONF
2387 2381 /*
2388 2382 * Grab the WRCONF semaphore.
2389 2383 */
2390 2384 word = hermon_flash_read_cfg(state, hdl, HERMON_HW_FLASH_WRCONF_SEMA);
2391 2385 #endif
2392 2386
2393 2387 /*
2394 2388 * Grab the GPIO semaphore. This allows us exclusive access to the
2395 2389 * GPIO settings on the Hermon for the duration of the flash burning
2396 2390 * procedure.
2397 2391 */
2398 2392 sema_cnt = 0;
2399 2393 do {
2400 2394 word = hermon_flash_read_cfg(state, hdl,
2401 2395 HERMON_HW_FLASH_GPIO_SEMA);
2402 2396 if (word == 0) {
2403 2397 break;
2404 2398 }
2405 2399
2406 2400 sema_cnt++;
2407 2401 drv_usecwait(1);
2408 2402
2409 2403 } while (sema_cnt < hermon_hw_flash_timeout_gpio_sema);
2410 2404
2411 2405 /*
2412 2406 * Determine if we timed out trying to grab the GPIO semaphore
2413 2407 */
2414 2408 if (sema_cnt == hermon_hw_flash_timeout_gpio_sema) {
2415 2409 cmn_err(CE_WARN, "hermon_flash_init: GPIO SEMA timeout\n");
2416 2410 cmn_err(CE_WARN, "GPIO_SEMA value: 0x%x\n", word);
2417 2411 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2418 2412 return (EIO);
2419 2413 }
2420 2414
2421 2415 /* Save away original GPIO Values */
2422 2416 state->hs_fw_gpio[0] = hermon_flash_read_cfg(state, hdl,
2423 2417 HERMON_HW_FLASH_GPIO_DATA);
2424 2418
2425 2419 /* Set new GPIO value */
2426 2420 gpio = state->hs_fw_gpio[0] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2427 2421 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA, gpio);
2428 2422
2429 2423 /* Save away original GPIO Values */
2430 2424 state->hs_fw_gpio[1] = hermon_flash_read_cfg(state, hdl,
2431 2425 HERMON_HW_FLASH_GPIO_MOD0);
2432 2426 state->hs_fw_gpio[2] = hermon_flash_read_cfg(state, hdl,
2433 2427 HERMON_HW_FLASH_GPIO_MOD1);
2434 2428
2435 2429 /* unlock GPIO */
2436 2430 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2437 2431 HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2438 2432
2439 2433 /*
2440 2434 * Set new GPIO values
2441 2435 */
2442 2436 gpio = state->hs_fw_gpio[1] | HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2443 2437 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0, gpio);
2444 2438
2445 2439 gpio = state->hs_fw_gpio[2] & ~HERMON_HW_FLASH_GPIO_PIN_ENABLE;
2446 2440 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1, gpio);
2447 2441
2448 2442 /* re-lock GPIO */
2449 2443 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2450 2444
2451 2445 /* Set CPUMODE to enable hermon to access the flash device */
2452 2446 /* CMJ This code came from arbel. Hermon doesn't seem to need it. */
2453 2447 /*
2454 2448 * hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_CPUMODE,
2455 2449 * 1 << HERMON_HW_FLASH_CPU_SHIFT);
2456 2450 */
2457 2451
2458 2452 /* the FMA retry loop ends. */
2459 2453 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2460 2454 return (0);
2461 2455
2462 2456 pio_error:
2463 2457 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2464 2458 return (EIO);
2465 2459 }
2466 2460
2467 2461 /*
2468 2462 * hermon_flash_cfi_init
2469 2463 * Implements access to the CFI (Common Flash Interface) data
2470 2464 */
2471 2465 static int
2472 2466 hermon_flash_cfi_init(hermon_state_t *state, uint32_t *cfi_info,
2473 2467 int *intel_xcmd)
2474 2468 {
2475 2469 uint32_t data;
2476 2470 uint32_t sector_sz_bytes;
2477 2471 uint32_t bit_count;
2478 2472 uint8_t cfi_ch_info[HERMON_CFI_INFO_SIZE];
2479 2473 uint32_t cfi_dw_info[HERMON_CFI_INFO_QSIZE];
2480 2474 int i;
2481 2475 int status;
2482 2476
2483 2477 /* Right now, all hermon cards use SPI. */
2484 2478 if (hermon_device_mode(state)) {
2485 2479 /*
2486 2480 * Don't use CFI for SPI part. Just fill in what we need
2487 2481 * and return.
2488 2482 */
2489 2483 state->hs_fw_cmdset = HERMON_FLASH_SPI_CMDSET;
2490 2484 state->hs_fw_log_sector_sz = HERMON_FLASH_SPI_LOG_SECTOR_SIZE;
2491 2485 state->hs_fw_device_sz = HERMON_FLASH_SPI_DEVICE_SIZE;
2492 2486
2493 2487 /*
2494 2488 * set this to inform caller of cmdset type.
2495 2489 */
2496 2490 cfi_ch_info[0x13] = HERMON_FLASH_SPI_CMDSET;
2497 2491 hermon_flash_cfi_dword(&cfi_info[4], cfi_ch_info, 0x10);
2498 2492 return (0);
2499 2493 }
2500 2494
2501 2495 /*
2502 2496 * Determine if the user command supports the Intel Extended
2503 2497 * Command Set. The query string is contained in the fourth
2504 2498 * quad word.
2505 2499 */
2506 2500 hermon_flash_cfi_byte(cfi_ch_info, cfi_info[0x04], 0x10);
2507 2501 if (cfi_ch_info[0x10] == 'M' &&
2508 2502 cfi_ch_info[0x11] == 'X' &&
2509 2503 cfi_ch_info[0x12] == '2') {
2510 2504 *intel_xcmd = 1; /* support is there */
2511 2505 if (hermon_verbose) {
2512 2506 IBTF_DPRINTF_L2("hermon",
2513 2507 "Support for Intel X is present\n");
2514 2508 }
2515 2509 }
2516 2510
2517 2511 /* CFI QUERY */
2518 2512 hermon_flash_write(state, 0x55, HERMON_FLASH_CFI_INIT, &status);
2519 2513 if (status != 0) {
2520 2514 return (status);
2521 2515 }
2522 2516
2523 2517 /* temporarily set the cmdset in order to do the initial read */
2524 2518 state->hs_fw_cmdset = HERMON_FLASH_INTEL_CMDSET;
2525 2519
2526 2520 /* Read in CFI data */
2527 2521 for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 4) {
2528 2522 data = hermon_flash_read(state, i, &status);
2529 2523 if (status != 0) {
2530 2524 return (status);
2531 2525 }
2532 2526 cfi_dw_info[i >> 2] = data;
2533 2527 hermon_flash_cfi_byte(cfi_ch_info, data, i);
2534 2528 }
2535 2529
2536 2530 /* Determine chip set */
2537 2531 state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2538 2532 if (cfi_ch_info[0x20] == 'Q' &&
2539 2533 cfi_ch_info[0x22] == 'R' &&
2540 2534 cfi_ch_info[0x24] == 'Y') {
2541 2535 /*
2542 2536 * Mode: x16 working in x8 mode (Intel).
2543 2537 * Pack data - skip spacing bytes.
2544 2538 */
2545 2539 if (hermon_verbose) {
2546 2540 IBTF_DPRINTF_L2("hermon",
2547 2541 "x16 working in x8 mode (Intel)\n");
2548 2542 }
2549 2543 for (i = 0; i < HERMON_CFI_INFO_SIZE; i += 2) {
2550 2544 cfi_ch_info[i/2] = cfi_ch_info[i];
2551 2545 }
2552 2546 }
2553 2547 state->hs_fw_cmdset = cfi_ch_info[0x13];
2554 2548
2555 2549 if (state->hs_fw_cmdset != HERMON_FLASH_INTEL_CMDSET &&
2556 2550 state->hs_fw_cmdset != HERMON_FLASH_AMD_CMDSET) {
2557 2551 cmn_err(CE_WARN,
2558 2552 "hermon_flash_cfi_init: UNKNOWN chip cmd set 0x%04x\n",
2559 2553 state->hs_fw_cmdset);
2560 2554 state->hs_fw_cmdset = HERMON_FLASH_UNKNOWN_CMDSET;
2561 2555 return (0);
2562 2556 }
2563 2557
2564 2558 /* Determine total bytes in one sector size */
2565 2559 sector_sz_bytes = ((cfi_ch_info[0x30] << 8) | cfi_ch_info[0x2F]) << 8;
2566 2560
2567 2561 /* Calculate equivalent of log2 (n) */
2568 2562 for (bit_count = 0; sector_sz_bytes > 1; bit_count++) {
2569 2563 sector_sz_bytes >>= 1;
2570 2564 }
2571 2565
2572 2566 /* Set sector size */
2573 2567 state->hs_fw_log_sector_sz = bit_count;
2574 2568
2575 2569 /* Set flash size */
2576 2570 state->hs_fw_device_sz = 0x1 << cfi_ch_info[0x27];
2577 2571
2578 2572 /* Reset to turn off CFI mode */
2579 2573 if ((status = hermon_flash_reset(state)) != 0)
2580 2574 goto out;
2581 2575
2582 2576 /* Pass CFI data back to user command. */
2583 2577 for (i = 0; i < HERMON_FLASH_CFI_SIZE_QUADLET; i++) {
2584 2578 hermon_flash_cfi_dword(&cfi_info[i], cfi_ch_info, i << 2);
2585 2579 }
2586 2580
2587 2581 if (*intel_xcmd == 1) {
2588 2582 /*
2589 2583 * Inform the user cmd that this driver does support the
2590 2584 * Intel Extended Command Set.
2591 2585 */
2592 2586 cfi_ch_info[0x10] = 'M';
2593 2587 cfi_ch_info[0x11] = 'X';
2594 2588 cfi_ch_info[0x12] = '2';
2595 2589 } else {
2596 2590 cfi_ch_info[0x10] = 'Q';
2597 2591 cfi_ch_info[0x11] = 'R';
2598 2592 cfi_ch_info[0x12] = 'Y';
2599 2593 }
2600 2594 cfi_ch_info[0x13] = state->hs_fw_cmdset;
2601 2595 hermon_flash_cfi_dword(&cfi_info[0x4], cfi_ch_info, 0x10);
2602 2596 out:
2603 2597 return (status);
2604 2598 }
2605 2599
2606 2600 /*
2607 2601 * hermon_flash_fini()
2608 2602 */
2609 2603 static int
2610 2604 hermon_flash_fini(hermon_state_t *state)
2611 2605 {
2612 2606 int status;
2613 2607 ddi_acc_handle_t hdl;
2614 2608
2615 2609 /* initialize the FMA retry loop */
2616 2610 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
2617 2611
2618 2612 /* Set handle */
2619 2613 hdl = hermon_get_pcihdl(state);
2620 2614
2621 2615 if ((status = hermon_flash_bank(state, 0)) != 0)
2622 2616 return (status);
2623 2617
2624 2618 /* the FMA retry loop starts. */
2625 2619 hermon_pio_start(state, hdl, pio_error, fm_loop_cnt, fm_status,
2626 2620 fm_test);
2627 2621
2628 2622 /*
2629 2623 * Restore original GPIO Values
2630 2624 */
2631 2625 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_DATA,
2632 2626 state->hs_fw_gpio[0]);
2633 2627
2634 2628 /* unlock GPIOs */
2635 2629 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK,
2636 2630 HERMON_HW_FLASH_GPIO_UNLOCK_VAL);
2637 2631
2638 2632 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD0,
2639 2633 state->hs_fw_gpio[1]);
2640 2634 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_MOD1,
2641 2635 state->hs_fw_gpio[2]);
2642 2636
2643 2637 /* re-lock GPIOs */
2644 2638 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_LOCK, 0);
2645 2639
2646 2640 /* Give up gpio semaphore */
2647 2641 hermon_flash_write_cfg(state, hdl, HERMON_HW_FLASH_GPIO_SEMA, 0);
2648 2642
2649 2643 /* the FMA retry loop ends. */
2650 2644 hermon_pio_end(state, hdl, pio_error, fm_loop_cnt, fm_status, fm_test);
2651 2645 return (0);
2652 2646
2653 2647 pio_error:
2654 2648 hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_IOCTL);
2655 2649 return (EIO);
2656 2650 }
2657 2651
2658 2652 /*
2659 2653 * hermon_flash_read_cfg
2660 2654 */
2661 2655 static uint32_t
2662 2656 hermon_flash_read_cfg(hermon_state_t *state, ddi_acc_handle_t pci_config_hdl,
2663 2657 uint32_t addr)
2664 2658 {
2665 2659 uint32_t read;
2666 2660
2667 2661 if (do_bar0) {
2668 2662 read = ddi_get32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2669 2663 (state->hs_reg_cmd_baseaddr + addr));
2670 2664 } else {
2671 2665 /*
2672 2666 * Perform flash read operation:
2673 2667 * 1) Place addr to read from on the HERMON_HW_FLASH_CFG_ADDR
2674 2668 * register
2675 2669 * 2) Read data at that addr from the HERMON_HW_FLASH_CFG_DATA
2676 2670 * register
2677 2671 */
2678 2672 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2679 2673 addr);
2680 2674 read = pci_config_get32(pci_config_hdl,
2681 2675 HERMON_HW_FLASH_CFG_DATA);
2682 2676 }
2683 2677
2684 2678 return (read);
2685 2679 }
2686 2680
2687 2681 #ifdef DO_WRCONF
2688 2682 static void
2689 2683 hermon_flash_write_cfg(hermon_state_t *state,
2690 2684 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2691 2685 {
2692 2686 hermon_flash_write_cfg_helper(state, pci_config_hdl, addr, data);
2693 2687 hermon_flash_write_confirm(state, pci_config_hdl);
2694 2688 }
2695 2689
2696 2690 static void
2697 2691 hermon_flash_write_confirm(hermon_state_t *state,
2698 2692 ddi_acc_handle_t pci_config_hdl)
2699 2693 {
2700 2694 uint32_t sem_value = 1;
2701 2695
2702 2696 hermon_flash_write_cfg_helper(state, pci_config_hdl,
2703 2697 HERMON_HW_FLASH_WRCONF_SEMA, 0);
2704 2698 while (sem_value) {
2705 2699 sem_value = hermon_flash_read_cfg(state, pci_config_hdl,
2706 2700 HERMON_HW_FLASH_WRCONF_SEMA);
2707 2701 }
2708 2702 }
2709 2703 #endif
2710 2704
2711 2705 /*
2712 2706 * hermon_flash_write_cfg
2713 2707 */
2714 2708 static void
2715 2709 #ifdef DO_WRCONF
2716 2710 hermon_flash_write_cfg_helper(hermon_state_t *state,
2717 2711 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2718 2712 #else
2719 2713 hermon_flash_write_cfg(hermon_state_t *state,
2720 2714 ddi_acc_handle_t pci_config_hdl, uint32_t addr, uint32_t data)
2721 2715 #endif
2722 2716 {
2723 2717 if (do_bar0) {
2724 2718 ddi_put32(hermon_get_cmdhdl(state), (uint32_t *)(void *)
2725 2719 (state->hs_reg_cmd_baseaddr + addr), data);
2726 2720
2727 2721 } else {
2728 2722
2729 2723 /*
2730 2724 * Perform flash write operation:
2731 2725 * 1) Place addr to write to on the HERMON_HW_FLASH_CFG_ADDR
2732 2726 * register
2733 2727 * 2) Place data to write on to the HERMON_HW_FLASH_CFG_DATA
2734 2728 * register
2735 2729 */
2736 2730 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_ADDR,
2737 2731 addr);
2738 2732 pci_config_put32(pci_config_hdl, HERMON_HW_FLASH_CFG_DATA,
2739 2733 data);
2740 2734 }
2741 2735 }
2742 2736
2743 2737 /*
2744 2738 * Support routines to convert Common Flash Interface (CFI) data
2745 2739 * from a 32 bit word to a char array, and from a char array to
2746 2740 * a 32 bit word.
2747 2741 */
2748 2742 static void
2749 2743 hermon_flash_cfi_byte(uint8_t *ch, uint32_t dword, int i)
2750 2744 {
2751 2745 ch[i] = (uint8_t)((dword & 0xFF000000) >> 24);
2752 2746 ch[i+1] = (uint8_t)((dword & 0x00FF0000) >> 16);
2753 2747 ch[i+2] = (uint8_t)((dword & 0x0000FF00) >> 8);
2754 2748 ch[i+3] = (uint8_t)((dword & 0x000000FF));
2755 2749 }
2756 2750
2757 2751 static void
2758 2752 hermon_flash_cfi_dword(uint32_t *dword, uint8_t *ch, int i)
2759 2753 {
2760 2754 *dword = (uint32_t)
2761 2755 ((uint32_t)ch[i] << 24 |
2762 2756 (uint32_t)ch[i+1] << 16 |
2763 2757 (uint32_t)ch[i+2] << 8 |
2764 2758 (uint32_t)ch[i+3]);
↓ open down ↓ |
601 lines elided |
↑ open up ↑ |
2765 2759 }
2766 2760
2767 2761 /*
2768 2762 * hermon_loopback_free_qps
2769 2763 */
2770 2764 static void
2771 2765 hermon_loopback_free_qps(hermon_loopback_state_t *lstate)
2772 2766 {
2773 2767 int i;
2774 2768
2775 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2776 -
2777 2769 if (lstate->hls_tx.hlc_qp_hdl != NULL) {
2778 2770 (void) hermon_qp_free(lstate->hls_state,
2779 2771 &lstate->hls_tx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2780 2772 HERMON_NOSLEEP);
2781 2773 }
2782 2774 if (lstate->hls_rx.hlc_qp_hdl != NULL) {
2783 2775 (void) hermon_qp_free(lstate->hls_state,
2784 2776 &lstate->hls_rx.hlc_qp_hdl, IBC_FREE_QP_AND_QPN, NULL,
2785 2777 HERMON_NOSLEEP);
2786 2778 }
2787 2779 lstate->hls_tx.hlc_qp_hdl = NULL;
2788 2780 lstate->hls_rx.hlc_qp_hdl = NULL;
2789 2781 for (i = 0; i < 2; i++) {
2790 2782 if (lstate->hls_tx.hlc_cqhdl[i] != NULL) {
2791 2783 (void) hermon_cq_free(lstate->hls_state,
2792 2784 &lstate->hls_tx.hlc_cqhdl[i], HERMON_NOSLEEP);
2793 2785 }
2794 2786 if (lstate->hls_rx.hlc_cqhdl[i] != NULL) {
2795 2787 (void) hermon_cq_free(lstate->hls_state,
2796 2788 &lstate->hls_rx.hlc_cqhdl[i], HERMON_NOSLEEP);
2797 2789 }
2798 2790 lstate->hls_tx.hlc_cqhdl[i] = NULL;
2799 2791 lstate->hls_rx.hlc_cqhdl[i] = NULL;
2800 2792 }
2801 2793 }
2802 2794
2803 2795 /*
2804 2796 * hermon_loopback_free_state
2805 2797 */
2806 2798 static void
2807 2799 hermon_loopback_free_state(hermon_loopback_state_t *lstate)
2808 2800 {
2809 2801 hermon_loopback_free_qps(lstate);
2810 2802 if (lstate->hls_tx.hlc_mrhdl != NULL) {
2811 2803 (void) hermon_mr_deregister(lstate->hls_state,
2812 2804 &lstate->hls_tx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2813 2805 HERMON_NOSLEEP);
2814 2806 }
2815 2807 if (lstate->hls_rx.hlc_mrhdl != NULL) {
2816 2808 (void) hermon_mr_deregister(lstate->hls_state,
2817 2809 &lstate->hls_rx.hlc_mrhdl, HERMON_MR_DEREG_ALL,
2818 2810 HERMON_NOSLEEP);
2819 2811 }
2820 2812 if (lstate->hls_pd_hdl != NULL) {
2821 2813 (void) hermon_pd_free(lstate->hls_state, &lstate->hls_pd_hdl);
2822 2814 }
2823 2815 if (lstate->hls_tx.hlc_buf != NULL) {
2824 2816 kmem_free(lstate->hls_tx.hlc_buf, lstate->hls_tx.hlc_buf_sz);
2825 2817 }
2826 2818 if (lstate->hls_rx.hlc_buf != NULL) {
2827 2819 kmem_free(lstate->hls_rx.hlc_buf, lstate->hls_rx.hlc_buf_sz);
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
2828 2820 }
2829 2821 bzero(lstate, sizeof (hermon_loopback_state_t));
2830 2822 }
2831 2823
2832 2824 /*
2833 2825 * hermon_loopback_init
2834 2826 */
2835 2827 static int
2836 2828 hermon_loopback_init(hermon_state_t *state, hermon_loopback_state_t *lstate)
2837 2829 {
2838 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2839 -
2840 2830 lstate->hls_hca_hdl = (ibc_hca_hdl_t)state;
2841 2831 lstate->hls_status = hermon_pd_alloc(lstate->hls_state,
2842 2832 &lstate->hls_pd_hdl, HERMON_NOSLEEP);
2843 2833 if (lstate->hls_status != IBT_SUCCESS) {
2844 2834 lstate->hls_err = HERMON_LOOPBACK_PROT_DOMAIN_ALLOC_FAIL;
2845 2835 return (EFAULT);
2846 2836 }
2847 2837
2848 2838 return (0);
2849 2839 }
2850 2840
2851 2841 /*
2852 2842 * hermon_loopback_init_qp_info
2853 2843 */
2854 2844 static void
2855 2845 hermon_loopback_init_qp_info(hermon_loopback_state_t *lstate,
2856 2846 hermon_loopback_comm_t *comm)
2857 2847 {
2858 2848 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2859 2849 bzero(&comm->hlc_qp_attr, sizeof (ibt_qp_alloc_attr_t));
2860 2850 bzero(&comm->hlc_qp_info, sizeof (ibt_qp_info_t));
2861 2851
2862 2852 comm->hlc_wrid = 1;
2863 2853 comm->hlc_cq_attr.cq_size = 128;
2864 2854 comm->hlc_qp_attr.qp_sizes.cs_sq_sgl = 3;
2865 2855 comm->hlc_qp_attr.qp_sizes.cs_rq_sgl = 3;
2866 2856 comm->hlc_qp_attr.qp_sizes.cs_sq = 16;
2867 2857 comm->hlc_qp_attr.qp_sizes.cs_rq = 16;
2868 2858 comm->hlc_qp_attr.qp_flags = IBT_WR_SIGNALED;
2869 2859
2870 2860 comm->hlc_qp_info.qp_state = IBT_STATE_RESET;
2871 2861 comm->hlc_qp_info.qp_trans = IBT_RC_SRV;
2872 2862 comm->hlc_qp_info.qp_flags = IBT_CEP_RDMA_RD | IBT_CEP_RDMA_WR;
2873 2863 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
2874 2864 lstate->hls_port;
2875 2865 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_pkey_ix =
2876 2866 lstate->hls_pkey_ix;
2877 2867 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_timeout =
2878 2868 lstate->hls_timeout;
2879 2869 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srvl = 0;
2880 2870 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_srate =
2881 2871 IBT_SRATE_4X;
2882 2872 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_send_grh = 0;
2883 2873 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid =
2884 2874 lstate->hls_lid;
2885 2875 comm->hlc_qp_info.qp_transport.rc.rc_retry_cnt = lstate->hls_retry;
2886 2876 comm->hlc_qp_info.qp_transport.rc.rc_sq_psn = 0;
2887 2877 comm->hlc_qp_info.qp_transport.rc.rc_rq_psn = 0;
2888 2878 comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_in = 4;
2889 2879 comm->hlc_qp_info.qp_transport.rc.rc_rdma_ra_out = 4;
2890 2880 comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = 0;
2891 2881 comm->hlc_qp_info.qp_transport.rc.rc_min_rnr_nak = IBT_RNR_NAK_655ms;
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
2892 2882 comm->hlc_qp_info.qp_transport.rc.rc_path_mtu = IB_MTU_1K;
2893 2883 }
2894 2884
2895 2885 /*
2896 2886 * hermon_loopback_alloc_mem
2897 2887 */
2898 2888 static int
2899 2889 hermon_loopback_alloc_mem(hermon_loopback_state_t *lstate,
2900 2890 hermon_loopback_comm_t *comm, int sz)
2901 2891 {
2902 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2903 -
2904 2892 /* Allocate buffer of specified size */
2905 2893 comm->hlc_buf_sz = sz;
2906 2894 comm->hlc_buf = kmem_zalloc(sz, KM_NOSLEEP);
2907 2895 if (comm->hlc_buf == NULL) {
2908 2896 return (EFAULT);
2909 2897 }
2910 2898
2911 2899 /* Register the buffer as a memory region */
2912 2900 comm->hlc_memattr.mr_vaddr = (uint64_t)(uintptr_t)comm->hlc_buf;
2913 2901 comm->hlc_memattr.mr_len = (ib_msglen_t)sz;
2914 2902 comm->hlc_memattr.mr_as = NULL;
2915 2903 comm->hlc_memattr.mr_flags = IBT_MR_NOSLEEP |
2916 2904 IBT_MR_ENABLE_REMOTE_WRITE | IBT_MR_ENABLE_LOCAL_WRITE;
2917 2905
2918 2906 comm->hlc_status = hermon_mr_register(lstate->hls_state,
2919 2907 lstate->hls_pd_hdl, &comm->hlc_memattr, &comm->hlc_mrhdl,
2920 2908 NULL, HERMON_MPT_DMPT);
2921 2909
2922 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm->hlc_mrhdl))
2923 -
2924 2910 comm->hlc_mrdesc.md_vaddr = comm->hlc_mrhdl->mr_bindinfo.bi_addr;
2925 2911 comm->hlc_mrdesc.md_lkey = comm->hlc_mrhdl->mr_lkey;
2926 2912 comm->hlc_mrdesc.md_rkey = comm->hlc_mrhdl->mr_rkey;
2927 2913 if (comm->hlc_status != IBT_SUCCESS) {
2928 2914 return (EFAULT);
2929 2915 }
2930 2916 return (0);
2931 2917 }
2932 2918
2933 2919 /*
2934 2920 * hermon_loopback_alloc_qps
2935 2921 */
2936 2922 static int
2937 2923 hermon_loopback_alloc_qps(hermon_loopback_state_t *lstate,
2938 2924 hermon_loopback_comm_t *comm)
2939 2925 {
2940 2926 uint32_t i, real_size;
2941 2927 hermon_qp_info_t qpinfo;
2942 2928
2943 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2944 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2945 -
2946 2929 /* Allocate send and recv CQs */
2947 2930 for (i = 0; i < 2; i++) {
2948 2931 bzero(&comm->hlc_cq_attr, sizeof (ibt_cq_attr_t));
2949 2932 comm->hlc_cq_attr.cq_size = 128;
2950 2933 comm->hlc_status = hermon_cq_alloc(lstate->hls_state,
2951 2934 (ibt_cq_hdl_t)NULL, &comm->hlc_cq_attr, &real_size,
2952 2935 &comm->hlc_cqhdl[i], HERMON_NOSLEEP);
2953 2936 if (comm->hlc_status != IBT_SUCCESS) {
2954 2937 lstate->hls_err += i;
2955 2938 return (EFAULT);
2956 2939 }
2957 2940 }
2958 2941
2959 2942 /* Allocate the QP */
2960 2943 hermon_loopback_init_qp_info(lstate, comm);
2961 2944 comm->hlc_qp_attr.qp_pd_hdl = (ibt_pd_hdl_t)lstate->hls_pd_hdl;
2962 2945 comm->hlc_qp_attr.qp_scq_hdl = (ibt_cq_hdl_t)comm->hlc_cqhdl[0];
2963 2946 comm->hlc_qp_attr.qp_rcq_hdl = (ibt_cq_hdl_t)comm->hlc_cqhdl[1];
2964 2947 comm->hlc_qp_attr.qp_ibc_scq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[0];
2965 2948 comm->hlc_qp_attr.qp_ibc_rcq_hdl = (ibt_opaque1_t)comm->hlc_cqhdl[1];
2966 2949 qpinfo.qpi_attrp = &comm->hlc_qp_attr;
2967 2950 qpinfo.qpi_type = IBT_RC_RQP;
2968 2951 qpinfo.qpi_ibt_qphdl = NULL;
2969 2952 qpinfo.qpi_queueszp = &comm->hlc_chan_sizes;
2970 2953 qpinfo.qpi_qpn = &comm->hlc_qp_num;
2971 2954 comm->hlc_status = hermon_qp_alloc(lstate->hls_state, &qpinfo,
2972 2955 HERMON_NOSLEEP);
2973 2956 if (comm->hlc_status == DDI_SUCCESS) {
2974 2957 comm->hlc_qp_hdl = qpinfo.qpi_qphdl;
2975 2958 }
2976 2959
2977 2960 if (comm->hlc_status != IBT_SUCCESS) {
2978 2961 lstate->hls_err += 2;
2979 2962 return (EFAULT);
2980 2963 }
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
2981 2964 return (0);
2982 2965 }
2983 2966
2984 2967 /*
2985 2968 * hermon_loopback_modify_qp
2986 2969 */
2987 2970 static int
2988 2971 hermon_loopback_modify_qp(hermon_loopback_state_t *lstate,
2989 2972 hermon_loopback_comm_t *comm, uint_t qp_num)
2990 2973 {
2991 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
2992 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lstate))
2993 -
2994 2974 /* Modify QP to INIT */
2995 2975 hermon_loopback_init_qp_info(lstate, comm);
2996 2976 comm->hlc_qp_info.qp_state = IBT_STATE_INIT;
2997 2977 comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
2998 2978 IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
2999 2979 if (comm->hlc_status != IBT_SUCCESS) {
3000 2980 return (EFAULT);
3001 2981 }
3002 2982
3003 2983 /*
3004 2984 * Modify QP to RTR (set destination LID and QP number to local
3005 2985 * LID and QP number)
3006 2986 */
3007 2987 comm->hlc_qp_info.qp_state = IBT_STATE_RTR;
3008 2988 comm->hlc_qp_info.qp_transport.rc.rc_path.cep_adds_vect.av_dlid
3009 2989 = lstate->hls_lid;
3010 2990 comm->hlc_qp_info.qp_transport.rc.rc_dst_qpn = qp_num;
3011 2991 comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3012 2992 IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3013 2993 if (comm->hlc_status != IBT_SUCCESS) {
3014 2994 lstate->hls_err += 1;
3015 2995 return (EFAULT);
3016 2996 }
3017 2997
3018 2998 /* Modify QP to RTS */
3019 2999 comm->hlc_qp_info.qp_current_state = IBT_STATE_RTR;
3020 3000 comm->hlc_qp_info.qp_state = IBT_STATE_RTS;
3021 3001 comm->hlc_status = hermon_qp_modify(lstate->hls_state, comm->hlc_qp_hdl,
3022 3002 IBT_CEP_SET_STATE, &comm->hlc_qp_info, &comm->hlc_queue_sizes);
3023 3003 if (comm->hlc_status != IBT_SUCCESS) {
3024 3004 lstate->hls_err += 2;
3025 3005 return (EFAULT);
3026 3006 }
3027 3007 return (0);
3028 3008 }
3029 3009
3030 3010 /*
3031 3011 * hermon_loopback_copyout
3032 3012 */
3033 3013 static int
3034 3014 hermon_loopback_copyout(hermon_loopback_ioctl_t *lb, intptr_t arg, int mode)
3035 3015 {
3036 3016 #ifdef _MULTI_DATAMODEL
3037 3017 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
3038 3018 hermon_loopback_ioctl32_t lb32;
3039 3019
3040 3020 lb32.alb_revision = lb->alb_revision;
3041 3021 lb32.alb_send_buf =
3042 3022 (caddr32_t)(uintptr_t)lb->alb_send_buf;
3043 3023 lb32.alb_fail_buf =
3044 3024 (caddr32_t)(uintptr_t)lb->alb_fail_buf;
3045 3025 lb32.alb_buf_sz = lb->alb_buf_sz;
3046 3026 lb32.alb_num_iter = lb->alb_num_iter;
3047 3027 lb32.alb_pass_done = lb->alb_pass_done;
3048 3028 lb32.alb_timeout = lb->alb_timeout;
3049 3029 lb32.alb_error_type = lb->alb_error_type;
3050 3030 lb32.alb_port_num = lb->alb_port_num;
3051 3031 lb32.alb_num_retry = lb->alb_num_retry;
3052 3032
3053 3033 if (ddi_copyout(&lb32, (void *)arg,
3054 3034 sizeof (hermon_loopback_ioctl32_t), mode) != 0) {
3055 3035 return (EFAULT);
3056 3036 }
3057 3037 } else
3058 3038 #endif /* _MULTI_DATAMODEL */
3059 3039 if (ddi_copyout(lb, (void *)arg, sizeof (hermon_loopback_ioctl_t),
3060 3040 mode) != 0) {
3061 3041 return (EFAULT);
3062 3042 }
3063 3043 return (0);
3064 3044 }
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
3065 3045
3066 3046 /*
3067 3047 * hermon_loopback_post_send
3068 3048 */
3069 3049 static int
3070 3050 hermon_loopback_post_send(hermon_loopback_state_t *lstate,
3071 3051 hermon_loopback_comm_t *tx, hermon_loopback_comm_t *rx)
3072 3052 {
3073 3053 int ret;
3074 3054
3075 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tx))
3076 -
3077 3055 bzero(&tx->hlc_sgl, sizeof (ibt_wr_ds_t));
3078 3056 bzero(&tx->hlc_wr, sizeof (ibt_send_wr_t));
3079 3057
3080 3058 /* Initialize local address for TX buffer */
3081 3059 tx->hlc_sgl.ds_va = tx->hlc_mrdesc.md_vaddr;
3082 3060 tx->hlc_sgl.ds_key = tx->hlc_mrdesc.md_lkey;
3083 3061 tx->hlc_sgl.ds_len = tx->hlc_buf_sz;
3084 3062
3085 3063 /* Initialize the remaining details of the work request */
3086 3064 tx->hlc_wr.wr_id = tx->hlc_wrid++;
3087 3065 tx->hlc_wr.wr_flags = IBT_WR_SEND_SIGNAL;
3088 3066 tx->hlc_wr.wr_nds = 1;
3089 3067 tx->hlc_wr.wr_sgl = &tx->hlc_sgl;
3090 3068 tx->hlc_wr.wr_opcode = IBT_WRC_RDMAW;
3091 3069 tx->hlc_wr.wr_trans = IBT_RC_SRV;
3092 3070
3093 3071 /* Initialize the remote address for RX buffer */
3094 3072 tx->hlc_wr.wr.rc.rcwr.rdma.rdma_raddr = rx->hlc_mrdesc.md_vaddr;
3095 3073 tx->hlc_wr.wr.rc.rcwr.rdma.rdma_rkey = rx->hlc_mrdesc.md_rkey;
3096 3074 tx->hlc_complete = 0;
3097 3075 ret = hermon_post_send(lstate->hls_state, tx->hlc_qp_hdl, &tx->hlc_wr,
3098 3076 1, NULL);
3099 3077 if (ret != IBT_SUCCESS) {
3100 3078 return (EFAULT);
3101 3079 }
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
3102 3080 return (0);
3103 3081 }
3104 3082
3105 3083 /*
3106 3084 * hermon_loopback_poll_cq
3107 3085 */
3108 3086 static int
3109 3087 hermon_loopback_poll_cq(hermon_loopback_state_t *lstate,
3110 3088 hermon_loopback_comm_t *comm)
3111 3089 {
3112 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*comm))
3113 -
3114 3090 comm->hlc_wc.wc_status = 0;
3115 3091 comm->hlc_num_polled = 0;
3116 3092 comm->hlc_status = hermon_cq_poll(lstate->hls_state,
3117 3093 comm->hlc_cqhdl[0], &comm->hlc_wc, 1, &comm->hlc_num_polled);
3118 3094 if ((comm->hlc_status == IBT_SUCCESS) &&
3119 3095 (comm->hlc_wc.wc_status != IBT_WC_SUCCESS)) {
3120 3096 comm->hlc_status = ibc_get_ci_failure(0);
3121 3097 }
3122 3098 return (comm->hlc_status);
3123 3099 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX