Print this page
XXXX introduce drv_sectohz
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c
+++ new/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.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 2010 QLogic Corporation. All rights reserved.
24 24 */
25 25
26 26 #include <qlge.h>
27 27
28 28 static int ql_async_event_parser(qlge_t *, mbx_data_t *);
29 29
30 30 /*
31 31 * Wait upto timeout seconds for Processor Interrupt
32 32 * if timeout is 0, then wait for default waittime
33 33 */
34 34 static int
35 35 ql_poll_processor_intr(qlge_t *qlge, uint8_t timeout)
36 36 {
37 37 int rtn_val = DDI_SUCCESS;
38 38
39 39 if (ql_wait_reg_bit(qlge, REG_STATUS, STS_PI, BIT_SET, timeout)
40 40 != DDI_SUCCESS) {
41 41 cmn_err(CE_WARN, "Polling for processor interrupt failed.");
42 42 rtn_val = DDI_FAILURE;
43 43 }
44 44 return (rtn_val);
45 45 }
46 46
47 47 /*
48 48 * Wait for mailbox Processor Register Ready
49 49 */
50 50 static int
51 51 ql_wait_processor_addr_reg_ready(qlge_t *qlge)
52 52 {
53 53 int rtn_val = DDI_SUCCESS;
54 54
55 55 if (ql_wait_reg_bit(qlge, REG_PROCESSOR_ADDR,
56 56 PROCESSOR_ADDRESS_RDY, BIT_SET, 0) != DDI_SUCCESS) {
57 57 cmn_err(CE_WARN,
58 58 "Wait for processor address register ready timeout.");
59 59 rtn_val = DDI_FAILURE;
60 60 }
61 61 return (rtn_val);
62 62 }
63 63
64 64 /*
65 65 * Read and write MPI registers using the indirect register interface
66 66 * Assume all the locks&semaphore have been acquired
67 67 */
68 68 int
69 69 ql_write_processor_data(qlge_t *qlge, uint32_t addr, uint32_t data)
70 70 {
71 71 int rtn_val = DDI_FAILURE;
72 72
73 73 /* wait for processor address register ready */
74 74 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
75 75 goto out;
76 76 /* write the data to the data reg */
77 77 ql_write_reg(qlge, REG_PROCESSOR_DATA, data);
78 78 /* trigger the write */
79 79 ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
80 80 /* wait for register to come ready */
81 81 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
82 82 goto out;
83 83
84 84 rtn_val = DDI_SUCCESS;
85 85
86 86 out:
87 87 return (rtn_val);
88 88
89 89 }
90 90
91 91 /*
92 92 * Read from processor register
93 93 */
94 94 int
95 95 ql_read_processor_data(qlge_t *qlge, uint32_t addr, uint32_t *data)
96 96 {
97 97 int rtn_val = DDI_FAILURE;
98 98
99 99 /* enable read operation */
100 100 addr |= PROCESSOR_ADDRESS_READ;
101 101 /* wait for processor address register ready */
102 102 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
103 103 goto out;
104 104
105 105 /* Write read address, wait for data ready in Data register */
106 106 ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
107 107 /* wait for data ready */
108 108 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
109 109 goto out;
110 110 /* read data */
111 111 *data = ql_read_reg(qlge, REG_PROCESSOR_DATA);
112 112
113 113 rtn_val = DDI_SUCCESS;
114 114
115 115 out:
116 116 return (rtn_val);
117 117
118 118 }
119 119
120 120 /*
121 121 * Read "count" number of outgoing Mailbox register starting
122 122 * from mailbox #0 if count is 0 then read all mailboxes
123 123 */
124 124 static int
125 125 ql_read_mailbox_cmd(qlge_t *qlge, mbx_data_t *mbx_buf, uint32_t count)
126 126 {
127 127 int rtn_val = DDI_FAILURE;
128 128 uint32_t reg_status;
129 129 uint32_t addr;
130 130 int i;
131 131
132 132 if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
133 133 cmn_err(CE_WARN,
134 134 "%s(%d) get QL_PROCESSOR_SEM_MASK time out error",
135 135 __func__, qlge->instance);
136 136 return (DDI_FAILURE);
137 137 }
138 138
139 139 if (qlge->func_number == qlge->fn0_net)
140 140 addr = FUNC_0_OUT_MAILBOX_0_REG_OFFSET;
141 141 else
142 142 addr = FUNC_1_OUT_MAILBOX_0_REG_OFFSET;
143 143
144 144 if (count == 0)
145 145 count = NUM_MAILBOX_REGS;
146 146 for (i = 0; i < count; i++) {
147 147 if (ql_read_processor_data(qlge, addr, ®_status)
148 148 == DDI_FAILURE)
149 149 goto out;
150 150 QL_PRINT(DBG_MBX, ("%s(%d) mailbox %d value 0x%x\n",
151 151 __func__, qlge->instance, i, reg_status));
152 152 mbx_buf->mb[i] = reg_status;
153 153 addr ++;
154 154 }
155 155
156 156 rtn_val = DDI_SUCCESS;
157 157
158 158 out:
159 159 ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
160 160
161 161 return (rtn_val);
162 162
163 163 }
164 164
165 165 /*
166 166 * Write mail box command (upto 16) to MPI Firmware
167 167 */
168 168 int
169 169 ql_issue_mailbox_cmd(qlge_t *qlge, mbx_cmd_t *mbx_cmd)
170 170 {
171 171 int rtn_val = DDI_FAILURE;
172 172 uint32_t addr;
173 173 int i;
174 174 /*
175 175 * Get semaphore to access Processor Address and
176 176 * Processor Data Registers
177 177 */
178 178 if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
179 179 return (DDI_FAILURE);
180 180 }
181 181 /* ensure no overwriting current command */
182 182 if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS,
183 183 HOST_TO_MPI_INTR_NOT_DONE, BIT_RESET, 0) != DDI_SUCCESS) {
184 184 goto out;
185 185 }
186 186
187 187 if (qlge->func_number == qlge->fn0_net)
188 188 addr = FUNC_0_IN_MAILBOX_0_REG_OFFSET;
189 189 else
190 190 addr = FUNC_1_IN_MAILBOX_0_REG_OFFSET;
191 191
192 192 /* wait for mailbox registers to be ready to access */
193 193 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
194 194 goto out;
195 195
196 196 /* issue mailbox command one by one */
197 197 for (i = 0; i < NUM_MAILBOX_REGS; i++) {
198 198 /* write sending cmd to mailbox data register */
199 199 ql_write_reg(qlge, REG_PROCESSOR_DATA, mbx_cmd->mb[i]);
200 200 /* write mailbox address to address register */
201 201 ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
202 202 QL_PRINT(DBG_MBX, ("%s(%d) write %x to mailbox(%x) addr %x \n",
203 203 __func__, qlge->instance, mbx_cmd->mb[i], i, addr));
204 204 addr++;
205 205 /*
206 206 * wait for mailbox cmd to be written before
207 207 * next write can start
208 208 */
209 209 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
210 210 goto out;
211 211 }
212 212 /* inform MPI that new mailbox commands are available */
213 213 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_INTR);
214 214 rtn_val = DDI_SUCCESS;
215 215 out:
216 216 ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
217 217 return (rtn_val);
218 218 }
219 219
220 220 /*
221 221 * Send mail box command (upto 16) to MPI Firmware
222 222 * and polling for MPI mailbox completion response when
223 223 * interrupt is not enabled.
224 224 * The MBX_LOCK mutexe should have been held and released
225 225 * externally
226 226 */
227 227 int
228 228 ql_issue_mailbox_cmd_and_poll_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd,
229 229 mbx_data_t *p_results)
230 230 {
231 231 int rtn_val = DDI_FAILURE;
232 232 boolean_t done;
233 233 int max_wait;
234 234
235 235 if (mbx_cmd == NULL)
236 236 goto err;
237 237
238 238 rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd);
239 239 if (rtn_val != DDI_SUCCESS) {
240 240 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed",
241 241 __func__, qlge->instance);
242 242 goto err;
243 243 }
244 244 done = B_FALSE;
245 245 max_wait = 5; /* wait upto 5 PI interrupt */
246 246 /* delay for the processor interrupt is received */
247 247 while ((done != B_TRUE) && (max_wait--)) {
248 248 /* wait up to 5s for PI interrupt */
249 249 if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmd->timeout)
250 250 == DDI_SUCCESS) {
251 251 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
252 252 __func__, qlge->instance));
253 253 (void) ql_read_mailbox_cmd(qlge, p_results, 0);
254 254 /*
255 255 * Sometimes, the incoming messages is not what we are
256 256 * waiting for, ie. async events, then, continue to
257 257 * wait. If it is the result * of previous mailbox
258 258 * command, then Done. No matter what, send
259 259 * HOST_CMD_CLEAR_RISC_TO_HOST_INTR to clear each
260 260 * PI interrupt
261 261 */
262 262 if (ql_async_event_parser(qlge, p_results) == B_FALSE) {
263 263 /*
264 264 * we get what we are waiting for,
265 265 * clear the interrupt
266 266 */
267 267 rtn_val = DDI_SUCCESS;
268 268 done = B_TRUE;
269 269 } else {
270 270 /*EMPTY*/
271 271 QL_PRINT(DBG_MBX,
272 272 ("%s(%d) result ignored, not we wait for\n",
273 273 __func__, qlge->instance));
274 274 }
275 275 ql_write_reg(qlge, REG_HOST_CMD_STATUS,
276 276 HOST_CMD_CLEAR_RISC_TO_HOST_INTR);
277 277 } else { /* timeout */
278 278 done = B_TRUE;
279 279 }
280 280 rtn_val = DDI_SUCCESS;
281 281 }
282 282 err:
283 283 return (rtn_val);
284 284 }
285 285 /*
286 286 * Send mail box command (upto 16) to MPI Firmware
287 287 * and wait for MPI mailbox completion response which
288 288 * is saved in interrupt. Thus, this function can only
289 289 * be used after interrupt is enabled.
290 290 * Must hold MBX mutex before calling this function
291 291 */
292 292 static int
293 293 ql_issue_mailbox_cmd_and_wait_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd)
294 294 {
295 295 int rtn_val = DDI_FAILURE;
296 296 clock_t timer;
297 297 int i;
298 298 int done = 0;
299 299
300 300 if (mbx_cmd == NULL)
301 301 goto err;
302 302
303 303 ASSERT(mutex_owned(&qlge->mbx_mutex));
304 304
305 305 /* if interrupts are not enabled, poll when results are available */
306 306 if (!(qlge->flags & INTERRUPTS_ENABLED)) {
307 307 rtn_val = ql_issue_mailbox_cmd_and_poll_rsp(qlge, mbx_cmd,
308 308 &qlge->received_mbx_cmds);
309 309 if (rtn_val == DDI_SUCCESS) {
310 310 for (i = 0; i < NUM_MAILBOX_REGS; i++)
311 311 mbx_cmd->mb[i] = qlge->received_mbx_cmds.mb[i];
312 312 }
313 313 } else {
314 314 rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd);
↓ open down ↓ |
314 lines elided |
↑ open up ↑ |
315 315 if (rtn_val != DDI_SUCCESS) {
316 316 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed",
317 317 __func__, qlge->instance);
318 318 goto err;
319 319 }
320 320 qlge->mbx_wait_completion = 1;
321 321 while (!done && qlge->mbx_wait_completion && !ddi_in_panic()) {
322 322 /* default 5 seconds from now to timeout */
323 323 timer = ddi_get_lbolt();
324 324 if (mbx_cmd->timeout) {
325 - timer +=
326 - mbx_cmd->timeout * drv_usectohz(1000000);
325 + timer += drv_sectohz(mbx_cmd->timeout);
327 326 } else {
328 - timer += 5 * drv_usectohz(1000000);
327 + timer += drv_sectohz(5);
329 328 }
330 329 if (cv_timedwait(&qlge->cv_mbx_intr, &qlge->mbx_mutex,
331 330 timer) == -1) {
332 331 /*
333 332 * The timeout time 'timer' was
334 333 * reached or expired without the condition
335 334 * being signaled.
336 335 */
337 336 cmn_err(CE_WARN, "%s(%d) Wait for Mailbox cmd "
338 337 "complete timeout.",
339 338 __func__, qlge->instance);
340 339 rtn_val = DDI_FAILURE;
341 340 done = 1;
342 341 } else {
343 342 QL_PRINT(DBG_MBX,
344 343 ("%s(%d) mailbox completion signal received"
345 344 " \n", __func__, qlge->instance));
346 345 for (i = 0; i < NUM_MAILBOX_REGS; i++) {
347 346 mbx_cmd->mb[i] =
348 347 qlge->received_mbx_cmds.mb[i];
349 348 }
350 349 rtn_val = DDI_SUCCESS;
351 350 done = 1;
352 351 }
353 352 }
354 353 }
355 354 err:
356 355 return (rtn_val);
357 356 }
358 357
359 358 /*
360 359 * Inteprete incoming asynchronous events
361 360 */
362 361 static int
363 362 ql_async_event_parser(qlge_t *qlge, mbx_data_t *mbx_cmds)
364 363 {
365 364 uint32_t link_status, cmd;
366 365 uint8_t link_speed;
367 366 uint8_t link_type;
368 367 boolean_t proc_done = B_TRUE;
369 368 mbx_cmd_t reply_cmd = {0};
370 369 boolean_t fatal_error = B_FALSE;
371 370
372 371 switch (mbx_cmds->mb[0]) {
373 372 case MBA_IDC_INTERMEDIATE_COMPLETE /* 1000h */:
374 373 QL_PRINT(DBG_MBX, ("%s(%d):"
375 374 "MBA_IDC_INTERMEDIATE_COMPLETE received\n",
376 375 __func__, qlge->instance));
377 376 break;
378 377 case MBA_SYSTEM_ERR /* 8002h */:
379 378 cmn_err(CE_WARN, "%s(%d): MBA_SYSTEM_ERR received",
380 379 __func__, qlge->instance);
381 380 cmn_err(CE_WARN, "%s(%d): File id %x, Line # %x,"
382 381 "Firmware Ver# %x",
383 382 __func__, qlge->instance, mbx_cmds->mb[1],
384 383 mbx_cmds->mb[2], mbx_cmds->mb[3]);
385 384 fatal_error = B_TRUE;
386 385 (void) ql_8xxx_binary_core_dump(qlge, &qlge->ql_mpi_coredump);
387 386 break;
388 387 case MBA_LINK_UP /* 8011h */:
389 388 QL_PRINT(DBG_MBX, ("%s(%d): MBA_LINK_UP received\n",
390 389 __func__, qlge->instance));
391 390 link_status = mbx_cmds->mb[1];
392 391 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n",
393 392 __func__, qlge->instance, link_status));
394 393 link_speed = (uint8_t)((link_status >> 3) & 0x07);
395 394
396 395 if (link_speed == 0) {
397 396 qlge->speed = SPEED_100;
398 397 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 100M\n",
399 398 __func__, qlge->instance));
400 399 } else if (link_speed == 1) {
401 400 qlge->speed = SPEED_1000;
402 401 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 1G\n",
403 402 __func__, qlge->instance));
404 403 } else if (link_speed == 2) {
405 404 qlge->speed = SPEED_10G;
406 405 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 10G\n",
407 406 __func__, qlge->instance));
408 407 }
409 408
410 409 qlge->link_type = link_type = (uint8_t)(link_status & 0x07);
411 410
412 411 if (link_type == XFI_NETWORK_INTERFACE) {
413 412 /* EMPTY */
414 413 QL_PRINT(DBG_MBX,
415 414 ("%s(%d):Link type XFI_NETWORK_INTERFACE\n",
416 415 __func__, qlge->instance));
417 416 } else if (link_type == XAUI_NETWORK_INTERFACE) {
418 417 /* EMPTY */
419 418 QL_PRINT(DBG_MBX, ("%s(%d):Link type"
420 419 "XAUI_NETWORK_INTERFACE\n",
421 420 __func__, qlge->instance));
422 421 } else if (link_type == XFI_BACKPLANE_INTERFACE) {
423 422 /* EMPTY */
424 423 QL_PRINT(DBG_MBX, ("%s(%d):Link type"
425 424 "XFI_BACKPLANE_INTERFACE\n",
426 425 __func__, qlge->instance));
427 426 } else if (link_type == XAUI_BACKPLANE_INTERFACE) {
428 427 /* EMPTY */
429 428 QL_PRINT(DBG_MBX, ("%s(%d):Link type "
430 429 "XAUI_BACKPLANE_INTERFACE\n",
431 430 __func__, qlge->instance));
432 431 } else if (link_type == EXT_10GBASE_T_PHY) {
433 432 /* EMPTY */
434 433 QL_PRINT(DBG_MBX,
435 434 ("%s(%d):Link type EXT_10GBASE_T_PHY\n",
436 435 __func__, qlge->instance));
437 436 } else if (link_type == EXT_EXT_EDC_PHY) {
438 437 /* EMPTY */
439 438 QL_PRINT(DBG_MBX,
440 439 ("%s(%d):Link type EXT_EXT_EDC_PHY\n",
441 440 __func__, qlge->instance));
442 441 } else {
443 442 /* EMPTY */
444 443 QL_PRINT(DBG_MBX,
445 444 ("%s(%d):unknown Link type \n",
446 445 __func__, qlge->instance));
447 446 }
448 447 cmn_err(CE_NOTE, "qlge(%d) mpi link up! speed %dMbps\n",
449 448 qlge->instance, qlge->speed);
450 449 /*
451 450 * start timer if not started to delay some time then
452 451 * check if link is really up or down
453 452 */
454 453 ql_restart_timer(qlge);
455 454
456 455 break;
457 456 case MBA_LINK_DOWN /* 8012h */:
458 457 QL_PRINT(DBG_MBX,
459 458 ("%s(%d): MBA_LINK_DOWN received\n",
460 459 __func__, qlge->instance));
461 460
462 461 link_status = mbx_cmds->mb[1];
463 462
464 463 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n",
465 464 __func__, qlge->instance, link_status));
466 465 if (link_status & 0x1) {
467 466 /* EMPTY */
468 467 QL_PRINT(DBG_MBX, ("%s(%d): Loss of signal \n",
469 468 __func__, qlge->instance));
470 469 }
471 470 if (link_status & 0x2) {
472 471 /* EMPTY */
473 472 QL_PRINT(DBG_MBX,
474 473 ("%s(%d): Auto-Negotiation Failed \n",
475 474 __func__, qlge->instance));
476 475 }
477 476 if (link_status & 0x4) {
478 477 /* EMPTY */
479 478 QL_PRINT(DBG_MBX,
480 479 ("%s(%d): XTI-Training Failed \n",
481 480 __func__, qlge->instance));
482 481 }
483 482
484 483 cmn_err(CE_NOTE, "qlge(%d) mpi link down!\n", qlge->instance);
485 484 ql_restart_timer(qlge);
486 485 break;
487 486 case MBA_IDC_COMPLETE /* 8100h */:
488 487
489 488 QL_PRINT(DBG_MBX,
490 489 ("%s(%d): MBA_IDC_COMPLETE received\n",
491 490 __func__, qlge->instance));
492 491 cmd = mbx_cmds->mb[1];
493 492 if (cmd == MBC_STOP_FIRMWARE) {
494 493 /* EMPTY */
495 494 QL_PRINT(DBG_MBX,
496 495 ("%s(%d): STOP_FIRMWARE event completed\n",
497 496 __func__, qlge->instance));
498 497 } else if (cmd == MBC_IDC_REQUEST) {
499 498 /* EMPTY */
500 499 QL_PRINT(DBG_MBX,
501 500 ("%s(%d): IDC_REQUEST event completed\n",
502 501 __func__, qlge->instance));
503 502 } else if (cmd == MBC_PORT_RESET) {
504 503 /* EMPTY */
505 504 QL_PRINT(DBG_MBX,
506 505 ("%s(%d): PORT_RESET event completed\n",
507 506 __func__, qlge->instance));
508 507 } else if (cmd == MBC_SET_PORT_CONFIG) {
509 508 /* EMPTY */
510 509 QL_PRINT(DBG_MBX,
511 510 ("%s(%d): SET_PORT_CONFIG event "
512 511 "completed\n", __func__, qlge->instance));
513 512 } else {
514 513 /* EMPTY */
515 514 QL_PRINT(DBG_MBX,
516 515 ("%s(%d): unknown IDC completion request"
517 516 " event %x %x\n", __func__, qlge->instance,
518 517 mbx_cmds->mb[1], mbx_cmds->mb[2]));
519 518 }
520 519 proc_done = B_FALSE;
521 520 break;
522 521
523 522 case MBA_IDC_REQUEST_NOTIFICATION /* 8101h */:
524 523 QL_PRINT(DBG_MBX,
525 524 ("%s(%d): MBA_IDC_REQUEST_NOTIFICATION "
526 525 "received\n", __func__, qlge->instance));
527 526 cmd = mbx_cmds->mb[1];
528 527 if (cmd == MBC_STOP_FIRMWARE) {
529 528 /* EMPTY */
530 529 QL_PRINT(DBG_MBX,
531 530 ("%s(%d): STOP_FIRMWARE notification"
532 531 " received\n", __func__, qlge->instance));
533 532 } else if (cmd == MBC_IDC_REQUEST) {
534 533 /* EMPTY */
535 534 QL_PRINT(DBG_MBX,
536 535 ("%s(%d): IDC_REQUEST notification "
537 536 "received\n", __func__, qlge->instance));
538 537 } else if (cmd == MBC_PORT_RESET) {
539 538 /* EMPTY */
540 539 QL_PRINT(DBG_MBX, ("%s(%d): PORT_RESET "
541 540 "notification received\n",
542 541 __func__, qlge->instance));
543 542 } else if (cmd == MBC_SET_PORT_CONFIG) {
544 543 /* EMPTY */
545 544 QL_PRINT(DBG_MBX,
546 545 ("%s(%d): SET_PORT_CONFIG notification "
547 546 "received\n", __func__, qlge->instance));
548 547 } else {
549 548 /* EMPTY */
550 549 QL_PRINT(DBG_MBX, ("%s(%d): "
551 550 "unknown request received %x %x\n",
552 551 __func__, qlge->instance, mbx_cmds->mb[1],
553 552 mbx_cmds->mb[2]));
554 553 }
555 554 reply_cmd.mb[0] = MBC_IDC_ACK;
556 555 reply_cmd.mb[1] = mbx_cmds->mb[1];
557 556 reply_cmd.mb[2] = mbx_cmds->mb[2];
558 557 reply_cmd.mb[3] = mbx_cmds->mb[3];
559 558 reply_cmd.mb[4] = mbx_cmds->mb[4];
560 559 if (ql_issue_mailbox_cmd(qlge, &reply_cmd)
561 560 != DDI_SUCCESS) {
562 561 cmn_err(CE_WARN,
563 562 "%s(%d) send IDC Ack failed.",
564 563 __func__, qlge->instance);
565 564 }
566 565 /*
567 566 * verify if the incoming outbound mailbox value is what
568 567 * we just sent
569 568 */
570 569 if (mbx_cmds->mb[0] == MBS_COMMAND_COMPLETE) {
571 570 /* 0x4000 */
572 571 /* EMPTY */
573 572 QL_PRINT(DBG_MBX,
574 573 ("%s(%d): IDC Ack sent success.\n",
575 574 __func__, qlge->instance));
576 575 } else {
577 576 /* EMPTY */
578 577 QL_PRINT(DBG_MBX,
579 578 ("%s(%d): IDC Ack reply error %x %x %x.\n",
580 579 __func__, qlge->instance, mbx_cmds->mb[0],
581 580 mbx_cmds->mb[1], mbx_cmds->mb[2]));
582 581 }
583 582 break;
584 583 case MBA_IDC_TIME_EXTENDED /* 8102 */:
585 584 QL_PRINT(DBG_MBX,
586 585 ("%s(%d): MBA_IDC_TIME_EXTENDED received\n",
587 586 __func__, qlge->instance));
588 587 break;
589 588 case MBA_DCBX_CONFIG_CHANGE /* 8110 */:
590 589 QL_PRINT(DBG_MBX,
591 590 ("%s(%d): MBA_DCBX_CONFIG_CHANGE received\n",
592 591 __func__, qlge->instance));
593 592 break;
594 593 case MBA_NOTIFICATION_LOST /* 8120 */:
595 594 QL_PRINT(DBG_MBX,
596 595 ("%s(%d): MBA_NOTIFICATION_LOST received\n",
597 596 __func__, qlge->instance));
598 597 break;
599 598 case MBA_SFT_TRANSCEIVER_INSERTION /* 8130 */:
600 599 QL_PRINT(DBG_MBX,
601 600 ("%s(%d): MBA_SFT_TRANSCEIVER_INSERTION "
602 601 "received\n", __func__, qlge->instance));
603 602 break;
604 603 case MBA_SFT_TRANSCEIVER_REMOVAL /* 8140 */:
605 604 QL_PRINT(DBG_MBX,
606 605 ("%s(%d): MBA_SFT_TRANSCEIVER_REMOVAL "
607 606 "received\n", __func__, qlge->instance));
608 607 break;
609 608 case MBA_FIRMWARE_INIT_COMPLETE /* 8400 */:
610 609 QL_PRINT(DBG_MBX,
611 610 ("%s(%d): MBA_FIRMWARE_INIT_COMPLETE "
612 611 "received\n", __func__, qlge->instance));
613 612 QL_PRINT(DBG_MBX,
614 613 ("%s(%d): mbx[1] %x, mbx[2] %x\n", __func__,
615 614 qlge->instance, mbx_cmds->mb[1], mbx_cmds->mb[2]));
616 615 qlge->fw_init_complete = B_TRUE;
617 616 qlge->fw_version_info.major_version =
618 617 LSB(MSW(mbx_cmds->mb[1]));
619 618 qlge->fw_version_info.minor_version =
620 619 MSB(LSW(mbx_cmds->mb[1]));
621 620 qlge->fw_version_info.sub_minor_version =
622 621 LSB(LSW(mbx_cmds->mb[1]));
623 622 qlge->phy_version_info.major_version =
624 623 LSB(MSW(mbx_cmds->mb[2]));
625 624 qlge->phy_version_info.minor_version =
626 625 MSB(LSW(mbx_cmds->mb[2]));
627 626 qlge->phy_version_info.sub_minor_version =
628 627 LSB(LSW(mbx_cmds->mb[2]));
629 628 break;
630 629 case MBA_FIRMWARE_INIT_FAILED /* 8401 */:
631 630 cmn_err(CE_WARN, "%s(%d):"
632 631 "ASYNC_EVENT_FIRMWARE_INIT_FAILURE "
633 632 "received: mbx[1] %x, mbx[2] %x",
634 633 __func__, qlge->instance,
635 634 mbx_cmds->mb[1], mbx_cmds->mb[2]);
636 635 fatal_error = B_TRUE;
637 636 break;
638 637 default:
639 638 if (mbx_cmds->mb[0] > 0x8000) {
640 639 cmn_err(CE_WARN, "%s(%d): "
641 640 "Unknown Async event received: mbx[0] %x ,"
642 641 "mbx[1] %x; mbx[2] %x",
643 642 __func__, qlge->instance,
644 643 mbx_cmds->mb[0], mbx_cmds->mb[1],
645 644 mbx_cmds->mb[2]);
646 645 proc_done = B_TRUE;
647 646 } else {
648 647 proc_done = B_FALSE;
649 648 }
650 649 break;
651 650 }
652 651 if (fatal_error) {
653 652 if (qlge->fm_enable) {
654 653 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
655 654 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST);
656 655 atomic_or_32(&qlge->flags, ADAPTER_ERROR);
657 656 }
658 657 }
659 658 return (proc_done);
660 659 }
661 660
662 661
663 662 /*
664 663 * MPI Interrupt handler
665 664 * Caller must have MBX_LOCK
666 665 */
667 666 void
668 667 ql_do_mpi_intr(qlge_t *qlge)
669 668 {
670 669 /*
671 670 * we just need to read first few mailboxes that this adapter's MPI
672 671 * will write response to.
673 672 */
674 673 mutex_enter(&qlge->mbx_mutex);
675 674
676 675 (void) ql_read_mailbox_cmd(qlge, &qlge->received_mbx_cmds,
677 676 qlge->max_read_mbx);
678 677
679 678 /*
680 679 * process PI interrupt as async events, if not done,
681 680 * then pass to mailbox processing
682 681 */
683 682 if (ql_async_event_parser(qlge, &qlge->received_mbx_cmds) == B_FALSE) {
684 683 QL_PRINT(DBG_MBX, ("%s(%d) mailbox completion interrupt\n",
685 684 __func__, qlge->instance));
686 685 /*
687 686 * If another thread is waiting for the mail box
688 687 * completion event to occur
689 688 */
690 689 if (qlge->mbx_wait_completion == 1) {
691 690 qlge->mbx_wait_completion = 0;
692 691 cv_broadcast(&qlge->cv_mbx_intr);
693 692 QL_PRINT(DBG_MBX,
694 693 ("%s(%d) mailbox completion signaled \n",
695 694 __func__, qlge->instance));
696 695 }
697 696 }
698 697 /* inform MPI Firmware to clear the interrupt */
699 698 ql_write_reg(qlge, REG_HOST_CMD_STATUS,
700 699 HOST_CMD_CLEAR_RISC_TO_HOST_INTR /* 0x0A */);
701 700 mutex_exit(&qlge->mbx_mutex);
702 701 ql_enable_completion_interrupt(qlge, 0); /* MPI is on irq 0 */
703 702 }
704 703
705 704 /*
706 705 * Test if mailbox communication works
707 706 * This is used when Interrupt is not enabled
708 707 */
709 708 int
710 709 ql_mbx_test(qlge_t *qlge)
711 710 {
712 711 mbx_cmd_t mbx_cmds;
713 712 mbx_data_t mbx_results;
714 713 int i, test_ok = 1;
715 714 int rtn_val = DDI_FAILURE;
716 715
717 716 for (i = 0; i < NUM_MAILBOX_REGS; i++)
718 717 mbx_cmds.mb[i] = i;
719 718
720 719 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */
721 720 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) {
722 721 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.",
723 722 __func__, qlge->instance);
724 723 goto out;
725 724 }
726 725
727 726 /* delay for the processor interrupt is received */
728 727 if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmds.timeout)
729 728 == DDI_SUCCESS) {
730 729 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
731 730 __func__, qlge->instance));
732 731 (void) ql_read_mailbox_cmd(qlge, &mbx_results, 0);
733 732
734 733 ql_write_reg(qlge, REG_HOST_CMD_STATUS,
735 734 HOST_CMD_CLEAR_RISC_TO_HOST_INTR);
736 735
737 736 if (mbx_results.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
738 737 test_ok = 0;
739 738 } else {
740 739 for (i = 1; i < NUM_MAILBOX_REGS; i++) {
741 740 if (mbx_results.mb[i] != i) {
742 741 test_ok = 0;
743 742 break;
744 743 }
745 744 }
746 745 }
747 746 if (test_ok) {
748 747 rtn_val = DDI_SUCCESS;
749 748 } else {
750 749 cmn_err(CE_WARN, "%s(%d) mailbox test failed!",
751 750 __func__, qlge->instance);
752 751 }
753 752 } else {
754 753 cmn_err(CE_WARN, "%s(%d) mailbox testing error: "
755 754 "PI Intr not received ", __func__, qlge->instance);
756 755 }
757 756 out:
758 757 return (rtn_val);
759 758 }
760 759
761 760 /*
762 761 * ql_mbx_test2
763 762 * Test if mailbox communication works
764 763 * This is used when Interrupt is enabled
765 764 * mailbox cmd:0x06h
766 765 */
767 766 int
768 767 ql_mbx_test2(qlge_t *qlge)
769 768 {
770 769 mbx_cmd_t mbx_cmds = {0};
771 770 int i, test_ok = 1;
772 771 int rtn_val = DDI_FAILURE;
773 772
774 773 for (i = 0; i < NUM_MAILBOX_REGS; i++)
775 774 mbx_cmds.mb[i] = i;
776 775
777 776 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */
778 777 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
779 778 cmn_err(CE_WARN,
780 779 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
781 780 __func__, qlge->instance);
782 781 goto out;
783 782 }
784 783
785 784 /* verify if the incoming outbound mailbox value is what we just sent */
786 785 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
787 786 test_ok = 0;
788 787 } else {
789 788 for (i = 1; i < qlge->max_read_mbx; i++) {
790 789 if (mbx_cmds.mb[i] != i) {
791 790 test_ok = 0;
792 791 break;
793 792 }
794 793 }
795 794 }
796 795 if (test_ok) {
797 796 rtn_val = DDI_SUCCESS;
798 797 } else {
799 798 cmn_err(CE_WARN, "%s(%d) mailbox test failed!",
800 799 __func__, qlge->instance);
801 800 }
802 801 out:
803 802 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
804 803 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
805 804 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
806 805 }
807 806 return (rtn_val);
808 807 }
809 808
810 809 /*
811 810 * ql_get_fw_state
812 811 * Get fw state.
813 812 * mailbox cmd:0x69h
814 813 */
815 814 int
816 815 ql_get_fw_state(qlge_t *qlge, uint32_t *fw_state_ptr)
817 816 {
818 817 int rtn_val = DDI_FAILURE;
819 818 mbx_cmd_t mbx_cmds = {0};
820 819
821 820 mbx_cmds.mb[0] = MBC_GET_FIRMWARE_STATE;
822 821
823 822 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
824 823 != DDI_SUCCESS) {
825 824 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
826 825 " failed.", __func__, qlge->instance);
827 826 goto out;
828 827 }
829 828 /* verify if the transaction is completed successful */
830 829 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
831 830 cmn_err(CE_WARN, "%s(%d) failed, 0x%x",
832 831 __func__, qlge->instance, mbx_cmds.mb[0]);
833 832 } else {
834 833 /* EMPTY */
835 834 QL_PRINT(DBG_MBX, ("firmware state: 0x%x\n", mbx_cmds.mb[1]));
836 835 }
837 836 if (fw_state_ptr != NULL)
838 837 *fw_state_ptr = mbx_cmds.mb[1];
839 838 rtn_val = DDI_SUCCESS;
840 839 out:
841 840 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
842 841 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
843 842 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
844 843 }
845 844 return (rtn_val);
846 845 }
847 846
848 847 /*
849 848 * ql_set_IDC_Req
850 849 * Send a IDC Request to firmware to notify all functions
851 850 * or any specific functions on the same port
852 851 * mailbox cmd:0x100h
853 852 */
854 853 int
855 854 ql_set_IDC_Req(qlge_t *qlge, uint8_t dest_functions, uint8_t timeout)
856 855 {
857 856 int rtn_val = DDI_FAILURE;
858 857 mbx_cmd_t mbx_cmds = {0};
859 858
860 859 mbx_cmds.mb[0] = MBC_IDC_REQUEST /* 0x100 */;
861 860 mbx_cmds.mb[1] = (timeout<<8) | qlge->func_number;
862 861
863 862 switch (dest_functions) {
864 863 case IDC_REQ_DEST_FUNC_ALL:
865 864 mbx_cmds.mb[1] |= IDC_REQ_ALL_DEST_FUNC_MASK;
866 865 mbx_cmds.mb[2] = 0;
867 866 break;
868 867 case IDC_REQ_DEST_FUNC_0:
869 868 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_0_MASK;
870 869 break;
871 870 case IDC_REQ_DEST_FUNC_1:
872 871 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_1_MASK;
873 872 break;
874 873 case IDC_REQ_DEST_FUNC_2:
875 874 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_2_MASK;
876 875 break;
877 876 case IDC_REQ_DEST_FUNC_3:
878 877 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_3_MASK;
879 878 break;
880 879 default:
881 880 cmn_err(CE_WARN, "Wrong dest functions %x",
882 881 dest_functions);
883 882 }
884 883
885 884 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
886 885 cmn_err(CE_WARN,
887 886 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
888 887 __func__, qlge->instance);
889 888 goto out;
890 889 }
891 890 /* verify if the transaction is completed successful */
892 891 if (mbx_cmds.mb[0] == MBA_IDC_INTERMEDIATE_COMPLETE /* 0x1000 */) {
893 892 QL_PRINT(DBG_MBX, ("%s(%d) mbx1: 0x%x, mbx2: 0x%x\n",
894 893 __func__, qlge->instance, mbx_cmds.mb[1], mbx_cmds.mb[2]));
895 894 rtn_val = DDI_SUCCESS;
896 895 } else if (mbx_cmds.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) {
897 896 QL_PRINT(DBG_MBX, ("%s(%d) cmd sent succesfully 0x%x\n",
898 897 __func__, qlge->instance));
899 898 rtn_val = DDI_SUCCESS;
900 899 } else if (mbx_cmds.mb[0] == MBS_COMMAND_ERROR /* 0x4005 */) {
901 900 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_ERROR",
902 901 __func__, qlge->instance);
903 902 } else if (mbx_cmds.mb[0] == MBS_COMMAND_PARAMETER_ERROR /* 0x4006 */) {
904 903 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_PARAMETER_ERROR",
905 904 __func__, qlge->instance);
906 905 } else {
907 906 cmn_err(CE_WARN, "%s(%d) unknow result: mbx[0]: 0x%x; mbx[1]:"
908 907 " 0x%x; mbx[2]: 0x%x", __func__, qlge->instance,
909 908 mbx_cmds.mb[0], mbx_cmds.mb[1], mbx_cmds.mb[2]);
910 909 }
911 910
912 911 out:
913 912 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
914 913 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
915 914 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
916 915 }
917 916 return (rtn_val);
918 917 }
919 918
920 919 /*
921 920 * ql_set_mpi_port_config
922 921 * Send new port configuration.to mpi
923 922 * mailbox cmd:0x122h
924 923 */
925 924 int
926 925 ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg)
927 926 {
928 927 int rtn_val = DDI_FAILURE;
929 928 mbx_cmd_t mbx_cmds = {0};
930 929
931 930 mbx_cmds.mb[0] = MBC_SET_PORT_CONFIG /* 0x122 */;
932 931 mbx_cmds.mb[1] = new_cfg.link_cfg;
933 932 mbx_cmds.mb[2] = new_cfg.max_frame_size;
934 933
935 934 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
936 935 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
937 936 " failed.", __func__, qlge->instance);
938 937 goto out;
939 938 }
940 939 /* verify if the transaction is completed successful */
941 940 if ((mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) &&
942 941 (mbx_cmds.mb[0] != MBA_IDC_COMPLETE /* 0x8100 */)) {
943 942 cmn_err(CE_WARN, "set port config (%d) failed, 0x%x",
944 943 qlge->instance, mbx_cmds.mb[0]);
945 944 } else
946 945 rtn_val = DDI_SUCCESS;
947 946 out:
948 947 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
949 948 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
950 949 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
951 950 }
952 951 return (rtn_val);
953 952 }
954 953
955 954 int
956 955 ql_set_pause_mode(qlge_t *qlge)
957 956 {
958 957 uint32_t pause_bit_mask = 0x60; /* bit 5-6 */
959 958
960 959 /* clear pause bits */
961 960 qlge->port_cfg_info.link_cfg &= ~pause_bit_mask;
962 961
963 962 /* set new pause mode */
964 963 if (qlge->pause == PAUSE_MODE_STANDARD)
965 964 qlge->port_cfg_info.link_cfg |= STD_PAUSE;
966 965 else if (qlge->pause == PAUSE_MODE_PER_PRIORITY)
967 966 qlge->port_cfg_info.link_cfg |= PP_PAUSE;
968 967
969 968 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info));
970 969 }
971 970
972 971 int
973 972 ql_set_loop_back_mode(qlge_t *qlge)
974 973 {
975 974 uint32_t loop_back_bit_mask = 0x0e; /* bit 1-3 */
976 975
977 976 /* clear loop back bits */
978 977 qlge->port_cfg_info.link_cfg &= ~loop_back_bit_mask;
979 978 /* loop back cfg: bit1-3 */
980 979 if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_PARALLEL)
981 980 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL;
982 981 else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL)
983 982 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL;
984 983 else if (qlge->loop_back_mode == QLGE_LOOP_EXTERNAL_PHY)
985 984 qlge->port_cfg_info.link_cfg |= LOOP_EXTERNAL_PHY;
986 985
987 986 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info));
988 987
989 988 }
990 989 /*
991 990 * ql_get_port_cfg
992 991 * Get port configuration.
993 992 * mailbox cmd:0x123h
994 993 */
995 994 int
996 995 ql_get_port_cfg(qlge_t *qlge)
997 996 {
998 997 int rtn_val = DDI_FAILURE;
999 998 mbx_cmd_t mbx_cmds = {0};
1000 999
1001 1000 mbx_cmds.mb[0] = MBC_GET_PORT_CONFIG /* 0x123 */;
1002 1001 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
1003 1002 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
1004 1003 " failed.", __func__, qlge->instance);
1005 1004 goto out;
1006 1005 }
1007 1006 /* verify if the transaction is completed successfully */
1008 1007 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
1009 1008 cmn_err(CE_WARN, "get port config (%d) failed, 0x%x",
1010 1009 qlge->instance, mbx_cmds.mb[0]);
1011 1010 } else { /* verify frame size */
1012 1011 if ((mbx_cmds.mb[2] == NORMAL_FRAME_SIZE) ||
1013 1012 (mbx_cmds.mb[2] == JUMBO_FRAME_SIZE)) {
1014 1013 qlge->port_cfg_info.link_cfg = mbx_cmds.mb[1];
1015 1014 qlge->port_cfg_info.max_frame_size = mbx_cmds.mb[2];
1016 1015 QL_PRINT(DBG_MBX, ("link_cfg: 0x%x, max_frame_size:"
1017 1016 " %d bytes\n", mbx_cmds.mb[1], mbx_cmds.mb[2]));
1018 1017 rtn_val = DDI_SUCCESS;
1019 1018 } else {
1020 1019 cmn_err(CE_WARN, "bad link_cfg: 0x%x, max_frame_size:"
1021 1020 " %d bytes", mbx_cmds.mb[1], mbx_cmds.mb[2]);
1022 1021 }
1023 1022 }
1024 1023 out:
1025 1024 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
1026 1025 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1027 1026 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
1028 1027 }
1029 1028 return (rtn_val);
1030 1029 }
1031 1030
1032 1031 /*
1033 1032 * qlge_get_link_status
1034 1033 * Get link status.
1035 1034 * mailbox cmd:0x124h
1036 1035 */
1037 1036 int
1038 1037 qlge_get_link_status(qlge_t *qlge,
1039 1038 struct qlnic_link_status_info *link_status_ptr)
1040 1039 {
1041 1040 int rtn_val = DDI_FAILURE;
1042 1041 mbx_cmd_t mbx_cmds = {0};
1043 1042
1044 1043 mbx_cmds.mb[0] = MBC_GET_LINK_STATUS /* 0x124 */;
1045 1044
1046 1045 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
1047 1046 != DDI_SUCCESS) {
1048 1047 cmn_err(CE_WARN,
1049 1048 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
1050 1049 __func__, qlge->instance);
1051 1050 goto out;
1052 1051 }
1053 1052 /* verify if the transaction is completed successful */
1054 1053 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
1055 1054 cmn_err(CE_WARN, "get link status(%d) failed, 0x%x",
1056 1055 qlge->instance, mbx_cmds.mb[0]);
1057 1056 } else {
1058 1057 /* EMPTY */
1059 1058 QL_PRINT(DBG_MBX,
1060 1059 ("link status: status1 : 0x%x, status2 : 0x%x, "
1061 1060 "status3 : 0x%x\n",
1062 1061 mbx_cmds.mb[1], mbx_cmds.mb[2], mbx_cmds.mb[3]));
1063 1062 }
1064 1063 if (link_status_ptr != NULL) {
1065 1064 link_status_ptr->link_status_info = mbx_cmds.mb[1];
1066 1065 link_status_ptr->additional_info = mbx_cmds.mb[2];
1067 1066 link_status_ptr->network_hw_info = mbx_cmds.mb[3];
1068 1067 link_status_ptr->dcbx_frame_counters_info = mbx_cmds.mb[4];
1069 1068 link_status_ptr->change_counters_info = mbx_cmds.mb[5];
1070 1069 }
1071 1070 rtn_val = DDI_SUCCESS;
1072 1071 out:
1073 1072 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
1074 1073 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1075 1074 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
1076 1075 }
1077 1076 return (rtn_val);
1078 1077 }
1079 1078
1080 1079 /*
1081 1080 * ql_get_firmware_version
1082 1081 * Get firmware version.
1083 1082 */
1084 1083 int
1085 1084 ql_get_firmware_version(qlge_t *qlge,
1086 1085 struct qlnic_mpi_version_info *mpi_version_ptr)
1087 1086 {
1088 1087 int rtn_val = DDI_FAILURE;
1089 1088 mbx_cmd_t mbx_cmds = {0};
1090 1089
1091 1090 mbx_cmds.mb[0] = MBC_ABOUT_FIRMWARE /* 0x08 */;
1092 1091
1093 1092 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
1094 1093 != DDI_SUCCESS) {
1095 1094 cmn_err(CE_WARN,
1096 1095 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
1097 1096 __func__, qlge->instance);
1098 1097 goto out;
1099 1098 }
1100 1099
1101 1100 /* verify if the transaction is completed successful */
1102 1101 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
1103 1102 cmn_err(CE_WARN, "get firmware version(%d) failed, 0x%x",
1104 1103 qlge->instance, mbx_cmds.mb[0]);
1105 1104 } else {
1106 1105 qlge->fw_version_info.major_version =
1107 1106 LSB(MSW(mbx_cmds.mb[1]));
1108 1107 qlge->fw_version_info.minor_version =
1109 1108 MSB(LSW(mbx_cmds.mb[1]));
1110 1109 qlge->fw_version_info.sub_minor_version =
1111 1110 LSB(LSW(mbx_cmds.mb[1]));
1112 1111 qlge->phy_version_info.major_version =
1113 1112 LSB(MSW(mbx_cmds.mb[2]));
1114 1113 qlge->phy_version_info.minor_version =
1115 1114 MSB(LSW(mbx_cmds.mb[2]));
1116 1115 qlge->phy_version_info.sub_minor_version =
1117 1116 LSB(LSW(mbx_cmds.mb[2]));
1118 1117 #ifdef QLGE_LOAD_UNLOAD
1119 1118 cmn_err(CE_NOTE, "firmware version: %d.%d.%d\n",
1120 1119 qlge->fw_version_info.major_version,
1121 1120 qlge->fw_version_info.minor_version,
1122 1121 qlge->fw_version_info.sub_minor_version);
1123 1122 #endif
1124 1123 if (mpi_version_ptr != NULL) {
1125 1124 mpi_version_ptr->fw_version =
1126 1125 (qlge->fw_version_info.major_version<<16)
1127 1126 |(qlge->fw_version_info.minor_version<<8)
1128 1127 |(qlge->fw_version_info.sub_minor_version);
1129 1128 mpi_version_ptr->phy_version =
1130 1129 (qlge->phy_version_info.major_version<<16)
1131 1130 |(qlge->phy_version_info.minor_version<<8)
1132 1131 |(qlge->phy_version_info.sub_minor_version);
1133 1132 }
1134 1133 }
1135 1134 rtn_val = DDI_SUCCESS;
1136 1135 out:
1137 1136 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
1138 1137 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1139 1138 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
1140 1139 }
1141 1140 return (rtn_val);
1142 1141 }
1143 1142
1144 1143 /*
1145 1144 * Trigger a system error event
1146 1145 */
1147 1146 int
1148 1147 ql_trigger_system_error_event(qlge_t *qlge)
1149 1148 {
1150 1149 mbx_cmd_t mbx_cmds = {0};
1151 1150 int rtn_val = DDI_FAILURE;
1152 1151
1153 1152 mbx_cmds.mb[0] = MBC_GENERATE_SYS_ERROR; /* 0x2A */
1154 1153 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) {
1155 1154 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.",
1156 1155 __func__, qlge->instance);
1157 1156 goto out;
1158 1157 }
1159 1158 rtn_val = DDI_SUCCESS;
1160 1159 out:
1161 1160 return (rtn_val);
1162 1161 }
1163 1162
1164 1163 /*
1165 1164 * Reset the MPI RISC Processor
1166 1165 */
1167 1166 int
1168 1167 ql_reset_mpi_risc(qlge_t *qlge)
1169 1168 {
1170 1169 int rtn_val = DDI_FAILURE;
1171 1170
1172 1171 /* Reset the MPI Processor */
1173 1172 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_RESET);
1174 1173 if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, RISC_RESET,
1175 1174 BIT_SET, 0) != DDI_SUCCESS) {
1176 1175 (void) ql_read_reg(qlge, REG_HOST_CMD_STATUS);
1177 1176 goto out;
1178 1177 }
1179 1178 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_CLEAR_RISC_RESET);
1180 1179 rtn_val = DDI_SUCCESS;
1181 1180 out:
1182 1181 return (rtn_val);
1183 1182 }
1184 1183
1185 1184 int
1186 1185 ql_read_risc_ram(qlge_t *qlge, uint32_t risc_address, uint64_t bp,
1187 1186 uint32_t word_count)
1188 1187 {
1189 1188 int rval = DDI_FAILURE;
1190 1189 mbx_cmd_t mc = {0};
1191 1190 mbx_cmd_t *mcp = &mc;
1192 1191 mbx_data_t mbx_results;
1193 1192
1194 1193 QL_PRINT(DBG_MBX, ("%s(%d): read risc addr:0x%x,"
1195 1194 "phys_addr %x,%x words\n", __func__, qlge->instance,
1196 1195 risc_address, bp, word_count));
1197 1196 if (CFG_IST(qlge, CFG_CHIP_8100)) {
1198 1197 mcp->mb[0] = MBC_DUMP_RISC_RAM /* 0x0C */;
1199 1198 mcp->mb[1] = LSW(risc_address);
1200 1199 mcp->mb[2] = MSW(LSD(bp));
1201 1200 mcp->mb[3] = LSW(LSD(bp));
1202 1201 mcp->mb[4] = MSW(word_count);
1203 1202 mcp->mb[5] = LSW(word_count);
1204 1203 mcp->mb[6] = MSW(MSD(bp));
1205 1204 mcp->mb[7] = LSW(MSD(bp));
1206 1205 mcp->mb[8] = MSW(risc_address);
1207 1206 }
1208 1207 mcp->timeout = 10 /* MAILBOX_TOV */;
1209 1208
1210 1209 if (ql_issue_mailbox_cmd_and_poll_rsp(qlge, mcp, &mbx_results)
1211 1210 != DDI_SUCCESS) {
1212 1211 goto out;
1213 1212 } else {
1214 1213 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
1215 1214 __func__, qlge->instance));
1216 1215 if (mbx_results.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) {
1217 1216 QL_PRINT(DBG_MBX, ("%s(%d): success\n",
1218 1217 __func__, qlge->instance));
1219 1218 rval = DDI_SUCCESS;
1220 1219 } else {
1221 1220 cmn_err(CE_WARN, "read_risc_ram(%d): failed, status %x",
1222 1221 qlge->instance, mbx_results.mb[0]);
1223 1222 }
1224 1223 }
1225 1224 out:
1226 1225 return (rval);
1227 1226 }
↓ open down ↓ |
889 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX