emlxs_mbox.c (728bdc9b) emlxs_mbox.c (291a2b48)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Emulex. All rights reserved.
23 * Copyright 2009 Emulex. All rights reserved.
24 * Use is subject to License terms.
25 */
26
24 * Use is subject to License terms.
25 */
26
27#include <emlxs.h>
27
28
28#include "emlxs.h"
29
30/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31EMLXS_MSG_DEF(EMLXS_MBOX_C);
32
29/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30EMLXS_MSG_DEF(EMLXS_MBOX_C);
31
33static void emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOX *mb,
34 uint32_t hbainit);
35static void emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mask,
36 uint32_t ringno);
37static void emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOX *mb, uint32_t word0,
38 uint32_t word1, uint32_t word2);
39static int32_t emlxs_mb_handle_cmd(emlxs_hba_t *hba, MAILBOX *mb);
40static void emlxs_mb_write_nv(emlxs_hba_t *hba, MAILBOX *mb);
32static void emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOX *mb,
33 uint32_t hbainit);
34static void emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mask,
35 uint32_t ringno);
36static void emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOX *mb,
37 uint32_t word0, uint32_t word1, uint32_t word2);
38static int32_t emlxs_mb_handle_cmd(emlxs_hba_t *hba, MAILBOX *mb);
39static void emlxs_mb_write_nv(emlxs_hba_t *hba, MAILBOX *mb);
41
40
42static void emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag,
43 uint32_t tmo);
44static void emlxs_mb_retry(emlxs_hba_t *hba, MAILBOX *mb);
45
41
46
47emlxs_table_t emlxs_mb_cmd_table[] =
48{
42emlxs_table_t emlxs_mb_cmd_table[] = {
49 {MBX_SHUTDOWN, "SHUTDOWN"},
50 {MBX_LOAD_SM, "LOAD_SM"},
51 {MBX_READ_NV, "READ_NV"},
52 {MBX_WRITE_NV, "WRITE_NV"},
53 {MBX_RUN_BIU_DIAG, "RUN_BIU_DIAG"},
54 {MBX_INIT_LINK, "INIT_LINK"},
55 {MBX_DOWN_LINK, "DOWN_LINK"},
56 {MBX_CONFIG_LINK, "CONFIG_LINK"},

--- 41 unchanged lines hidden (view full) ---

98 {MBX_BEACON, "BEACON"},
99 {MBX_CONFIG_HBQ, "CONFIG_HBQ"}, /* SLI3 */
100 {MBX_REG_VPI, "REG_VPI"}, /* NPIV */
101 {MBX_ASYNC_EVENT, "ASYNC_EVENT"},
102 {MBX_HEARTBEAT, "HEARTBEAT"},
103 {MBX_READ_EVENT_LOG_STATUS, "READ_EVENT_LOG_STATUS"},
104 {MBX_READ_EVENT_LOG, "READ_EVENT_LOG"},
105 {MBX_WRITE_EVENT_LOG, "WRITE_EVENT_LOG"},
43 {MBX_SHUTDOWN, "SHUTDOWN"},
44 {MBX_LOAD_SM, "LOAD_SM"},
45 {MBX_READ_NV, "READ_NV"},
46 {MBX_WRITE_NV, "WRITE_NV"},
47 {MBX_RUN_BIU_DIAG, "RUN_BIU_DIAG"},
48 {MBX_INIT_LINK, "INIT_LINK"},
49 {MBX_DOWN_LINK, "DOWN_LINK"},
50 {MBX_CONFIG_LINK, "CONFIG_LINK"},

--- 41 unchanged lines hidden (view full) ---

92 {MBX_BEACON, "BEACON"},
93 {MBX_CONFIG_HBQ, "CONFIG_HBQ"}, /* SLI3 */
94 {MBX_REG_VPI, "REG_VPI"}, /* NPIV */
95 {MBX_ASYNC_EVENT, "ASYNC_EVENT"},
96 {MBX_HEARTBEAT, "HEARTBEAT"},
97 {MBX_READ_EVENT_LOG_STATUS, "READ_EVENT_LOG_STATUS"},
98 {MBX_READ_EVENT_LOG, "READ_EVENT_LOG"},
99 {MBX_WRITE_EVENT_LOG, "WRITE_EVENT_LOG"},
106 {MBX_NV_LOG, "NV_LOG"}
107
100 {MBX_NV_LOG, "NV_LOG"},
101 {MBX_PORT_CAPABILITIES, "PORT_CAPABILITIES"},
102 {MBX_IOV_CONTROL, "IOV_CONTROL"},
103 {MBX_IOV_MBX, "IOV_MBX"}
108}; /* emlxs_mb_cmd_table */
109
110
104}; /* emlxs_mb_cmd_table */
105
106
111/* ARGSUSED */
107/*ARGSUSED*/
112extern void
113emlxs_mb_async_event(emlxs_hba_t *hba, MAILBOX *mb)
114{
115 bzero((void *) mb, MAILBOX_CMD_BSIZE);
116
117 mb->mbxCommand = MBX_ASYNC_EVENT;
118 mb->mbxOwner = OWN_HOST;
119 mb->un.varWords[0] = FC_ELS_RING;
120
121 return;
122
123} /* emlxs_mb_async_event() */
124
125
108extern void
109emlxs_mb_async_event(emlxs_hba_t *hba, MAILBOX *mb)
110{
111 bzero((void *) mb, MAILBOX_CMD_BSIZE);
112
113 mb->mbxCommand = MBX_ASYNC_EVENT;
114 mb->mbxOwner = OWN_HOST;
115 mb->un.varWords[0] = FC_ELS_RING;
116
117 return;
118
119} /* emlxs_mb_async_event() */
120
121
126/* ARGSUSED */
122/*ARGSUSED*/
127extern void
128emlxs_mb_heartbeat(emlxs_hba_t *hba, MAILBOX *mb)
129{
130 bzero((void *) mb, MAILBOX_CMD_BSIZE);
131
132 mb->mbxCommand = MBX_HEARTBEAT;
133 mb->mbxOwner = OWN_HOST;
134
135 return;
136
137} /* emlxs_mb_heartbeat() */
138
139
140#ifdef MSI_SUPPORT
141
123extern void
124emlxs_mb_heartbeat(emlxs_hba_t *hba, MAILBOX *mb)
125{
126 bzero((void *) mb, MAILBOX_CMD_BSIZE);
127
128 mb->mbxCommand = MBX_HEARTBEAT;
129 mb->mbxOwner = OWN_HOST;
130
131 return;
132
133} /* emlxs_mb_heartbeat() */
134
135
136#ifdef MSI_SUPPORT
137
142/* ARGSUSED */
138/*ARGSUSED*/
143extern void
144emlxs_mb_config_msi(emlxs_hba_t *hba, MAILBOX *mb, uint32_t *intr_map,
145 uint32_t intr_count)
146{
147 uint32_t i;
148 uint32_t mask;
149
139extern void
140emlxs_mb_config_msi(emlxs_hba_t *hba, MAILBOX *mb, uint32_t *intr_map,
141 uint32_t intr_count)
142{
143 uint32_t i;
144 uint32_t mask;
145
150 bzero((void *) mb, MAILBOX_CMD_BSIZE);
146 bzero((void *)mb, MAILBOX_CMD_BSIZE);
151
152 mb->mbxCommand = MBX_CONFIG_MSI;
153
154 /* Set the default message id to zero */
155 mb->un.varCfgMSI.defaultPresent = 1;
156 mb->un.varCfgMSI.defaultMessageNumber = 0;
157
158 for (i = 1; i < intr_count; i++) {

--- 53 unchanged lines hidden (view full) ---

212
213 mb->mbxOwner = OWN_HOST;
214
215 return;
216
217} /* emlxs_mb_config_msi() */
218
219
147
148 mb->mbxCommand = MBX_CONFIG_MSI;
149
150 /* Set the default message id to zero */
151 mb->un.varCfgMSI.defaultPresent = 1;
152 mb->un.varCfgMSI.defaultMessageNumber = 0;
153
154 for (i = 1; i < intr_count; i++) {

--- 53 unchanged lines hidden (view full) ---

208
209 mb->mbxOwner = OWN_HOST;
210
211 return;
212
213} /* emlxs_mb_config_msi() */
214
215
220/* ARGSUSED */
216/*ARGSUSED*/
221extern void
222emlxs_mb_config_msix(emlxs_hba_t *hba, MAILBOX *mb, uint32_t *intr_map,
223 uint32_t intr_count)
224{
225 uint32_t i;
226 uint32_t mask;
227
217extern void
218emlxs_mb_config_msix(emlxs_hba_t *hba, MAILBOX *mb, uint32_t *intr_map,
219 uint32_t intr_count)
220{
221 uint32_t i;
222 uint32_t mask;
223
228 bzero((void *) mb, MAILBOX_CMD_BSIZE);
224 bzero((void *)mb, MAILBOX_CMD_BSIZE);
229
230 mb->mbxCommand = MBX_CONFIG_MSIX;
231
232 /* Set the default message id to zero */
233 mb->un.varCfgMSIX.defaultPresent = 1;
234 mb->un.varCfgMSIX.defaultMessageNumber = 0;
235
236 for (i = 1; i < intr_count; i++) {

--- 55 unchanged lines hidden (view full) ---

292
293 return;
294
295} /* emlxs_mb_config_msix() */
296
297
298#endif /* MSI_SUPPORT */
299
225
226 mb->mbxCommand = MBX_CONFIG_MSIX;
227
228 /* Set the default message id to zero */
229 mb->un.varCfgMSIX.defaultPresent = 1;
230 mb->un.varCfgMSIX.defaultMessageNumber = 0;
231
232 for (i = 1; i < intr_count; i++) {

--- 55 unchanged lines hidden (view full) ---

288
289 return;
290
291} /* emlxs_mb_config_msix() */
292
293
294#endif /* MSI_SUPPORT */
295
300/* ARGSUSED */
296
297/*ARGSUSED*/
301extern void
302emlxs_mb_reset_ring(emlxs_hba_t *hba, MAILBOX *mb, uint32_t ringno)
303{
298extern void
299emlxs_mb_reset_ring(emlxs_hba_t *hba, MAILBOX *mb, uint32_t ringno)
300{
304 bzero((void *) mb, MAILBOX_CMD_BSIZE);
301 bzero((void *)mb, MAILBOX_CMD_BSIZE);
305
306 mb->mbxCommand = MBX_RESET_RING;
307 mb->un.varRstRing.ring_no = ringno;
308 mb->mbxOwner = OWN_HOST;
309
310 return;
311
312} /* emlxs_mb_reset_ring() */
313
314
315
316/*
302
303 mb->mbxCommand = MBX_RESET_RING;
304 mb->un.varRstRing.ring_no = ringno;
305 mb->mbxOwner = OWN_HOST;
306
307 return;
308
309} /* emlxs_mb_reset_ring() */
310
311
312
313/*
317 * emlxs_mb_dump_vpd Issue a DUMP MEMORY
318 * mailbox command
314 * emlxs_mb_dump_vpd Issue a DUMP MEMORY mailbox command
319 */
315 */
320/* ARGSUSED */
316/*ARGSUSED*/
321extern void
322emlxs_mb_dump_vpd(emlxs_hba_t *hba, MAILBOX *mb, uint32_t offset)
323{
317extern void
318emlxs_mb_dump_vpd(emlxs_hba_t *hba, MAILBOX *mb, uint32_t offset)
319{
324 bzero((void *) mb, MAILBOX_CMD_BSIZE);
320 bzero((void *)mb, MAILBOX_CMD_BSIZE);
325
326 /*
327 * Setup to dump VPD region
328 */
329 mb->mbxCommand = MBX_DUMP_MEMORY;
330 mb->un.varDmp.cv = 1;
331 mb->un.varDmp.type = DMP_NV_PARAMS;
332 mb->un.varDmp.entry_index = offset;
333 mb->un.varDmp.region_id = DMP_VPD_REGION;
321
322 /*
323 * Setup to dump VPD region
324 */
325 mb->mbxCommand = MBX_DUMP_MEMORY;
326 mb->un.varDmp.cv = 1;
327 mb->un.varDmp.type = DMP_NV_PARAMS;
328 mb->un.varDmp.entry_index = offset;
329 mb->un.varDmp.region_id = DMP_VPD_REGION;
334 mb->un.varDmp.word_cnt = DMP_VPD_DUMP_WCOUNT; /* limited by */
335 /* mailbox size */
336
330
331 /* limited by mailbox size */
332 mb->un.varDmp.word_cnt = DMP_VPD_DUMP_WCOUNT;
333
337 mb->un.varDmp.co = 0;
338 mb->un.varDmp.resp_offset = 0;
339 mb->mbxOwner = OWN_HOST;
334 mb->un.varDmp.co = 0;
335 mb->un.varDmp.resp_offset = 0;
336 mb->mbxOwner = OWN_HOST;
337
340} /* emlxs_mb_dump_vpd() */
341
342
338} /* emlxs_mb_dump_vpd() */
339
340
341/*ARGSUSED*/
342extern void
343emlxs_mb_dump(emlxs_hba_t *hba, MAILBOX *mb, uint32_t offset, uint32_t words)
344{
345 bzero((void *)mb, MAILBOX_CMD_BSIZE);
346
347 mb->mbxCommand = MBX_DUMP_MEMORY;
348 mb->un.varDmp.type = DMP_MEM_REG;
349 mb->un.varDmp.word_cnt = words;
350 mb->un.varDmp.base_adr = offset;
351
352 mb->un.varDmp.co = 0;
353 mb->un.varDmp.resp_offset = 0;
354 mb->mbxOwner = OWN_HOST;
355
356 return;
357
358} /* emlxs_mb_dump() */
359
360
361
343/*
362/*
344 * emlxs_mb_read_nv Issue a READ NVPARAM
345 * mailbox command
363 * emlxs_mb_read_nv Issue a READ NVPARAM mailbox command
346 */
364 */
347/* ARGSUSED */
365/*ARGSUSED*/
348extern void
349emlxs_mb_read_nv(emlxs_hba_t *hba, MAILBOX *mb)
350{
366extern void
367emlxs_mb_read_nv(emlxs_hba_t *hba, MAILBOX *mb)
368{
351 bzero((void *) mb, MAILBOX_CMD_BSIZE);
369 bzero((void *)mb, MAILBOX_CMD_BSIZE);
352
353 mb->mbxCommand = MBX_READ_NV;
354 mb->mbxOwner = OWN_HOST;
370
371 mb->mbxCommand = MBX_READ_NV;
372 mb->mbxOwner = OWN_HOST;
355
356} /* End emlxs_mb_read_nv */
357
358
359/*
373} /* End emlxs_mb_read_nv */
374
375
376/*
360 * emlxs_mb_read_rev Issue a READ REV
361 * mailbox command
377 * emlxs_mb_read_rev Issue a READ REV mailbox command
362 */
378 */
363/* ARGSUSED */
379/*ARGSUSED*/
364extern void
365emlxs_mb_read_rev(emlxs_hba_t *hba, MAILBOX *mb, uint32_t v3)
366{
380extern void
381emlxs_mb_read_rev(emlxs_hba_t *hba, MAILBOX *mb, uint32_t v3)
382{
367 bzero((void *) mb, MAILBOX_CMD_BSIZE);
383 bzero((void *)mb, MAILBOX_CMD_BSIZE);
368
369 mb->un.varRdRev.cv = 1;
370
371 if (v3) {
372 mb->un.varRdRev.cv3 = 1;
373 }
374
375 mb->mbxCommand = MBX_READ_REV;
376 mb->mbxOwner = OWN_HOST;
384
385 mb->un.varRdRev.cv = 1;
386
387 if (v3) {
388 mb->un.varRdRev.cv3 = 1;
389 }
390
391 mb->mbxCommand = MBX_READ_REV;
392 mb->mbxOwner = OWN_HOST;
377
378} /* End emlxs_mb_read_rev */
379
380
381/*
393} /* End emlxs_mb_read_rev */
394
395
396/*
382 * emlxs_mb_run_biu_diag Issue a RUN_BIU_DIAG
383 * mailbox command
397 * emlxs_mb_run_biu_diag Issue a RUN_BIU_DIAG mailbox command
384 */
398 */
385/* ARGSUSED */
399/*ARGSUSED*/
386extern uint32_t
387emlxs_mb_run_biu_diag(emlxs_hba_t *hba, MAILBOX *mb, uint64_t out,
388 uint64_t in)
389{
400extern uint32_t
401emlxs_mb_run_biu_diag(emlxs_hba_t *hba, MAILBOX *mb, uint64_t out,
402 uint64_t in)
403{
390 bzero((void *) mb, MAILBOX_CMD_BSIZE);
404 bzero((void *)mb, MAILBOX_CMD_BSIZE);
391
392 mb->mbxCommand = MBX_RUN_BIU_DIAG64;
393 mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
405
406 mb->mbxCommand = MBX_RUN_BIU_DIAG64;
407 mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
394 mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh =
395 (uint32_t)putPaddrHigh(out);
396 mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow =
397 (uint32_t)putPaddrLow(out);
408 mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = putPaddrHigh(out);
409 mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = putPaddrLow(out);
398 mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
410 mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
399 mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh =
400 (uint32_t)putPaddrHigh(in);
401 mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = (uint32_t)putPaddrLow(in);
411 mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = putPaddrHigh(in);
412 mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = putPaddrLow(in);
402 mb->mbxOwner = OWN_HOST;
403
404 return (0);
413 mb->mbxOwner = OWN_HOST;
414
415 return (0);
405
406} /* End emlxs_mb_run_biu_diag */
407
408
409/*
416} /* End emlxs_mb_run_biu_diag */
417
418
419/*
410 * emlxs_mb_read_la Issue a READ LA
411 * mailbox command
420 * emlxs_mb_read_la Issue a READ LA mailbox command
412 */
413extern uint32_t
414emlxs_mb_read_la(emlxs_hba_t *hba, MAILBOX *mb)
415{
416 MATCHMAP *mp;
417
421 */
422extern uint32_t
423emlxs_mb_read_la(emlxs_hba_t *hba, MAILBOX *mb)
424{
425 MATCHMAP *mp;
426
418 bzero((void *) mb, MAILBOX_CMD_BSIZE);
427 bzero((void *)mb, MAILBOX_CMD_BSIZE);
419
428
420 if ((mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BUF)) == 0) {
429 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
421 mb->mbxCommand = MBX_READ_LA64;
422
423 return (1);
424 }
430 mb->mbxCommand = MBX_READ_LA64;
431
432 return (1);
433 }
434
425 mb->mbxCommand = MBX_READ_LA64;
426 mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
435 mb->mbxCommand = MBX_READ_LA64;
436 mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
427 mb->un.varReadLA.un.lilpBde64.addrHigh =
428 (uint32_t)putPaddrHigh(mp->phys);
429 mb->un.varReadLA.un.lilpBde64.addrLow =
430 (uint32_t)putPaddrLow(mp->phys);
437 mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
438 mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys);
431 mb->mbxOwner = OWN_HOST;
432
433 /*
434 * save address for completion
435 */
436 ((MAILBOXQ *)mb)->bp = (uint8_t *)mp;
437
438 return (0);
439
440} /* emlxs_mb_read_la() */
441
442
443/*
439 mb->mbxOwner = OWN_HOST;
440
441 /*
442 * save address for completion
443 */
444 ((MAILBOXQ *)mb)->bp = (uint8_t *)mp;
445
446 return (0);
447
448} /* emlxs_mb_read_la() */
449
450
451/*
444 * emlxs_mb_clear_la Issue a CLEAR LA
445 * mailbox command
452 * emlxs_mb_clear_la Issue a CLEAR LA mailbox command
446 */
447extern void
448emlxs_mb_clear_la(emlxs_hba_t *hba, MAILBOX *mb)
449{
450#ifdef FC_RPI_CHECK
451 emlxs_rpi_check(hba);
452#endif /* FC_RPI_CHECK */
453
453 */
454extern void
455emlxs_mb_clear_la(emlxs_hba_t *hba, MAILBOX *mb)
456{
457#ifdef FC_RPI_CHECK
458 emlxs_rpi_check(hba);
459#endif /* FC_RPI_CHECK */
460
454 bzero((void *) mb, MAILBOX_CMD_BSIZE);
461 bzero((void *)mb, MAILBOX_CMD_BSIZE);
455
456 mb->un.varClearLA.eventTag = hba->link_event_tag;
457 mb->mbxCommand = MBX_CLEAR_LA;
458 mb->mbxOwner = OWN_HOST;
459
460 return;
461
462} /* End emlxs_mb_clear_la */
463
464
465/*
462
463 mb->un.varClearLA.eventTag = hba->link_event_tag;
464 mb->mbxCommand = MBX_CLEAR_LA;
465 mb->mbxOwner = OWN_HOST;
466
467 return;
468
469} /* End emlxs_mb_clear_la */
470
471
472/*
466 * emlxs_mb_read_status Issue a READ STATUS
467 * mailbox command
473 * emlxs_mb_read_status Issue a READ STATUS mailbox command
468 */
474 */
469/* ARGSUSED */
475/*ARGSUSED*/
470extern void
471emlxs_mb_read_status(emlxs_hba_t *hba, MAILBOX *mb)
472{
476extern void
477emlxs_mb_read_status(emlxs_hba_t *hba, MAILBOX *mb)
478{
473 bzero((void *) mb, MAILBOX_CMD_BSIZE);
479 bzero((void *)mb, MAILBOX_CMD_BSIZE);
474
475 mb->mbxCommand = MBX_READ_STATUS;
476 mb->mbxOwner = OWN_HOST;
480
481 mb->mbxCommand = MBX_READ_STATUS;
482 mb->mbxOwner = OWN_HOST;
477
478} /* End fc_read_status */
479
483} /* End fc_read_status */
484
480
481/*
485/*
482 * emlxs_mb_read_lnk_stat Issue a LINK STATUS
483 * mailbox command
486 * emlxs_mb_read_lnk_stat Issue a LINK STATUS mailbox command
484 */
487 */
485/* ARGSUSED */
488/*ARGSUSED*/
486extern void
487emlxs_mb_read_lnk_stat(emlxs_hba_t *hba, MAILBOX *mb)
488{
489extern void
490emlxs_mb_read_lnk_stat(emlxs_hba_t *hba, MAILBOX *mb)
491{
489 bzero((void *) mb, MAILBOX_CMD_BSIZE);
492 bzero((void *)mb, MAILBOX_CMD_BSIZE);
490
491 mb->mbxCommand = MBX_READ_LNK_STAT;
492 mb->mbxOwner = OWN_HOST;
493
494 mb->mbxCommand = MBX_READ_LNK_STAT;
495 mb->mbxOwner = OWN_HOST;
493
494} /* End emlxs_mb_read_lnk_stat */
495
496
497/*
496} /* End emlxs_mb_read_lnk_stat */
497
498
499/*
498 * emlxs_mb_write_nv Issue a WRITE NVPARAM
499 * mailbox command
500 * emlxs_mb_write_nv Issue a WRITE NVPARAM mailbox command
500 */
501static void
502emlxs_emb_mb_write_nv(emlxs_hba_t *hba, MAILBOX *mb)
503{
501 */
502static void
503emlxs_emb_mb_write_nv(emlxs_hba_t *hba, MAILBOX *mb)
504{
504 int32_t i;
505 emlxs_config_t *cfg = &CFG;
505 int32_t i;
506 emlxs_config_t *cfg = &CFG;
506
507
507 bzero((void *) mb, MAILBOX_CMD_BSIZE);
508 bzero((void *)mb, MAILBOX_CMD_BSIZE);
508
509
509 bcopy((void *) &hba->wwnn,
510 (void *) mb->un.varWTnvp.nodename,
511 sizeof (NAME_TYPE));
510 bcopy((void *)&hba->wwnn,
511 (void *)mb->un.varWTnvp.nodename, sizeof (NAME_TYPE));
512
512
513 bcopy((void *) &hba->wwpn,
514 (void *) mb->un.varWTnvp.portname,
515 sizeof (NAME_TYPE));
513 bcopy((void *)&hba->wwpn,
514 (void *)mb->un.varWTnvp.portname, sizeof (NAME_TYPE));
516
517 mb->un.varWTnvp.pref_DID = 0;
518 mb->un.varWTnvp.hardAL_PA = (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
519 mb->un.varWTnvp.rsvd1[0] = 0xffffffff;
520 mb->un.varWTnvp.rsvd1[1] = 0xffffffff;
521 mb->un.varWTnvp.rsvd1[2] = 0xffffffff;
522 for (i = 0; i < 21; i++) {
523 mb->un.varWTnvp.rsvd3[i] = 0xffffffff;
524 }
525
526 mb->mbxCommand = MBX_WRITE_NV;
527 mb->mbxOwner = OWN_HOST;
528} /* End emlxs_mb_write_nv */
529
530
531/*
515
516 mb->un.varWTnvp.pref_DID = 0;
517 mb->un.varWTnvp.hardAL_PA = (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
518 mb->un.varWTnvp.rsvd1[0] = 0xffffffff;
519 mb->un.varWTnvp.rsvd1[1] = 0xffffffff;
520 mb->un.varWTnvp.rsvd1[2] = 0xffffffff;
521 for (i = 0; i < 21; i++) {
522 mb->un.varWTnvp.rsvd3[i] = 0xffffffff;
523 }
524
525 mb->mbxCommand = MBX_WRITE_NV;
526 mb->mbxOwner = OWN_HOST;
527} /* End emlxs_mb_write_nv */
528
529
530/*
532 * emlxs_mb_part_slim Issue a PARTITION SLIM
533 * mailbox command
531 * emlxs_mb_part_slim Issue a PARTITION SLIM mailbox command
534 */
535static void
536emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOX *mb, uint32_t hbainit)
537{
532 */
533static void
534emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOX *mb, uint32_t hbainit)
535{
538 bzero((void *) mb, MAILBOX_CMD_BSIZE);
536 bzero((void *)mb, MAILBOX_CMD_BSIZE);
539
540
541 mb->un.varSlim.numRing = hba->ring_count;
542 mb->un.varSlim.hbainit = hbainit;
543 mb->mbxCommand = MBX_PART_SLIM;
544 mb->mbxOwner = OWN_HOST;
537
538
539 mb->un.varSlim.numRing = hba->ring_count;
540 mb->un.varSlim.hbainit = hbainit;
541 mb->mbxCommand = MBX_PART_SLIM;
542 mb->mbxOwner = OWN_HOST;
545
546} /* End emlxs_mb_part_slim */
547
548
549/*
543} /* End emlxs_mb_part_slim */
544
545
546/*
550 * emlxs_mb_config_ring Issue a CONFIG RING
551 * mailbox command
547 * emlxs_mb_config_ring Issue a CONFIG RING mailbox command
552 */
553extern void
554emlxs_mb_config_ring(emlxs_hba_t *hba, int32_t ring, MAILBOX *mb)
555{
556 int32_t i;
557 int32_t j;
558
548 */
549extern void
550emlxs_mb_config_ring(emlxs_hba_t *hba, int32_t ring, MAILBOX *mb)
551{
552 int32_t i;
553 int32_t j;
554
559 bzero((void *) mb, MAILBOX_CMD_BSIZE);
555 bzero((void *)mb, MAILBOX_CMD_BSIZE);
560
561 j = 0;
562 for (i = 0; i < ring; i++) {
563 j += hba->ring_masks[i];
564 }
565
566 for (i = 0; i < hba->ring_masks[ring]; i++) {
567 if ((j + i) >= 6) {
568 break;
569 }
556
557 j = 0;
558 for (i = 0; i < ring; i++) {
559 j += hba->ring_masks[i];
560 }
561
562 for (i = 0; i < hba->ring_masks[ring]; i++) {
563 if ((j + i) >= 6) {
564 break;
565 }
570 mb->un.varCfgRing.rrRegs[i].rval = hba->ring_rval[j + i];
566
567 mb->un.varCfgRing.rrRegs[i].rval = hba->ring_rval[j + i];
571 mb->un.varCfgRing.rrRegs[i].rmask = hba->ring_rmask[j + i];
572
568 mb->un.varCfgRing.rrRegs[i].rmask = hba->ring_rmask[j + i];
569
573 mb->un.varCfgRing.rrRegs[i].tval = hba->ring_tval[j + i];
570 mb->un.varCfgRing.rrRegs[i].tval = hba->ring_tval[j + i];
574 mb->un.varCfgRing.rrRegs[i].tmask = hba->ring_tmask[j + i];
575 }
576
577 mb->un.varCfgRing.ring = ring;
578 mb->un.varCfgRing.profile = 0;
579 mb->un.varCfgRing.maxOrigXchg = 0;
580 mb->un.varCfgRing.maxRespXchg = 0;
581 mb->un.varCfgRing.recvNotify = 1;
582 mb->un.varCfgRing.numMask = hba->ring_masks[ring];
583 mb->mbxCommand = MBX_CONFIG_RING;
584 mb->mbxOwner = OWN_HOST;
585
586 return;
587
588} /* End emlxs_mb_config_ring */
589
590
591/*
571 mb->un.varCfgRing.rrRegs[i].tmask = hba->ring_tmask[j + i];
572 }
573
574 mb->un.varCfgRing.ring = ring;
575 mb->un.varCfgRing.profile = 0;
576 mb->un.varCfgRing.maxOrigXchg = 0;
577 mb->un.varCfgRing.maxRespXchg = 0;
578 mb->un.varCfgRing.recvNotify = 1;
579 mb->un.varCfgRing.numMask = hba->ring_masks[ring];
580 mb->mbxCommand = MBX_CONFIG_RING;
581 mb->mbxOwner = OWN_HOST;
582
583 return;
584
585} /* End emlxs_mb_config_ring */
586
587
588/*
592 * emlxs_mb_config_link Issue a CONFIG LINK
593 * mailbox command
589 * emlxs_mb_config_link Issue a CONFIG LINK mailbox command
594 */
595extern void
596emlxs_mb_config_link(emlxs_hba_t *hba, MAILBOX *mb)
597{
590 */
591extern void
592emlxs_mb_config_link(emlxs_hba_t *hba, MAILBOX *mb)
593{
598 emlxs_port_t *port = &PPORT;
594 emlxs_port_t *port = &PPORT;
599 emlxs_config_t *cfg = &CFG;
600
595 emlxs_config_t *cfg = &CFG;
596
601 bzero((void *) mb, MAILBOX_CMD_BSIZE);
597 bzero((void *)mb, MAILBOX_CMD_BSIZE);
602
603 /*
604 * NEW_FEATURE SLI-2, Coalescing Response Feature.
605 */
606 if (cfg[CFG_CR_DELAY].current) {
607 mb->un.varCfgLnk.cr = 1;
608 mb->un.varCfgLnk.ci = 1;
609 mb->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current;
610 mb->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current;
611 }
598
599 /*
600 * NEW_FEATURE SLI-2, Coalescing Response Feature.
601 */
602 if (cfg[CFG_CR_DELAY].current) {
603 mb->un.varCfgLnk.cr = 1;
604 mb->un.varCfgLnk.ci = 1;
605 mb->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current;
606 mb->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current;
607 }
608
612 if (cfg[CFG_ACK0].current)
613 mb->un.varCfgLnk.ack0_enable = 1;
614
615 mb->un.varCfgLnk.myId = port->did;
616 mb->un.varCfgLnk.edtov = hba->fc_edtov;
617 mb->un.varCfgLnk.arbtov = hba->fc_arbtov;
618 mb->un.varCfgLnk.ratov = hba->fc_ratov;
619 mb->un.varCfgLnk.rttov = hba->fc_rttov;

--- 4 unchanged lines hidden (view full) ---

624 mb->mbxOwner = OWN_HOST;
625
626 return;
627
628} /* emlxs_mb_config_link() */
629
630
631/*
609 if (cfg[CFG_ACK0].current)
610 mb->un.varCfgLnk.ack0_enable = 1;
611
612 mb->un.varCfgLnk.myId = port->did;
613 mb->un.varCfgLnk.edtov = hba->fc_edtov;
614 mb->un.varCfgLnk.arbtov = hba->fc_arbtov;
615 mb->un.varCfgLnk.ratov = hba->fc_ratov;
616 mb->un.varCfgLnk.rttov = hba->fc_rttov;

--- 4 unchanged lines hidden (view full) ---

621 mb->mbxOwner = OWN_HOST;
622
623 return;
624
625} /* emlxs_mb_config_link() */
626
627
628/*
632 * emlxs_mb_init_link Issue an INIT LINK
633 * mailbox command
629 * emlxs_mb_init_link Issue an INIT LINK mailbox command
634 */
635extern void
636emlxs_mb_init_link(emlxs_hba_t *hba, MAILBOX *mb, uint32_t topology,
637 uint32_t linkspeed)
638{
630 */
631extern void
632emlxs_mb_init_link(emlxs_hba_t *hba, MAILBOX *mb, uint32_t topology,
633 uint32_t linkspeed)
634{
639 emlxs_vpd_t *vpd = &VPD;
640 emlxs_config_t *cfg = &CFG;
635 emlxs_vpd_t *vpd = &VPD;
636 emlxs_config_t *cfg = &CFG;
641
637
642 bzero((void *) mb, MAILBOX_CMD_BSIZE);
638 bzero((void *)mb, MAILBOX_CMD_BSIZE);
643
644 switch (topology) {
645 case FLAGS_LOCAL_LB:
646 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
647 mb->un.varInitLnk.link_flags |= FLAGS_LOCAL_LB;
648 break;
649 case FLAGS_TOPOLOGY_MODE_LOOP_PT:
650 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;

--- 10 unchanged lines hidden (view full) ---

661 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
662 break;
663 }
664
665 if (cfg[CFG_LILP_ENABLE].current == 0) {
666 /* Disable LIRP/LILP support */
667 mb->un.varInitLnk.link_flags |= FLAGS_LIRP_LILP;
668 }
639
640 switch (topology) {
641 case FLAGS_LOCAL_LB:
642 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
643 mb->un.varInitLnk.link_flags |= FLAGS_LOCAL_LB;
644 break;
645 case FLAGS_TOPOLOGY_MODE_LOOP_PT:
646 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;

--- 10 unchanged lines hidden (view full) ---

657 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
658 break;
659 }
660
661 if (cfg[CFG_LILP_ENABLE].current == 0) {
662 /* Disable LIRP/LILP support */
663 mb->un.varInitLnk.link_flags |= FLAGS_LIRP_LILP;
664 }
665
669 /*
670 * Setting up the link speed
671 */
672 switch (linkspeed) {
673 case 0:
674 break;
675
676 case 1:

--- 31 unchanged lines hidden (view full) ---

708 break;
709
710 }
711
712 if ((linkspeed > 0) && (vpd->feaLevelHigh >= 0x02)) {
713 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
714 mb->un.varInitLnk.link_speed = linkspeed;
715 }
666 /*
667 * Setting up the link speed
668 */
669 switch (linkspeed) {
670 case 0:
671 break;
672
673 case 1:

--- 31 unchanged lines hidden (view full) ---

705 break;
706
707 }
708
709 if ((linkspeed > 0) && (vpd->feaLevelHigh >= 0x02)) {
710 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
711 mb->un.varInitLnk.link_speed = linkspeed;
712 }
713
716 mb->un.varInitLnk.link_flags |= FLAGS_PREABORT_RETURN;
717
714 mb->un.varInitLnk.link_flags |= FLAGS_PREABORT_RETURN;
715
718 mb->un.varInitLnk.fabric_AL_PA = (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
716 mb->un.varInitLnk.fabric_AL_PA =
717 (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
719 mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
720 mb->mbxOwner = OWN_HOST;
721
722
723 return;
724
725} /* emlxs_mb_init_link() */
726
727
728/*
718 mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
719 mb->mbxOwner = OWN_HOST;
720
721
722 return;
723
724} /* emlxs_mb_init_link() */
725
726
727/*
729 * emlxs_mb_down_link Issue a DOWN LINK
730 * mailbox command
728 * emlxs_mb_down_link Issue a DOWN LINK mailbox command
731 */
729 */
732/* ARGSUSED */
730/*ARGSUSED*/
733extern void
734emlxs_mb_down_link(emlxs_hba_t *hba, MAILBOX *mb)
735{
731extern void
732emlxs_mb_down_link(emlxs_hba_t *hba, MAILBOX *mb)
733{
736 bzero((void *) mb, MAILBOX_CMD_BSIZE);
734 bzero((void *)mb, MAILBOX_CMD_BSIZE);
737
738 mb->mbxCommand = MBX_DOWN_LINK;
739 mb->mbxOwner = OWN_HOST;
740
741 return;
742
743} /* emlxs_mb_down_link() */
744
745
746/*
735
736 mb->mbxCommand = MBX_DOWN_LINK;
737 mb->mbxOwner = OWN_HOST;
738
739 return;
740
741} /* emlxs_mb_down_link() */
742
743
744/*
747 * emlxs_mb_read_sparam Issue a READ SPARAM
748 * mailbox command
745 * emlxs_mb_read_sparam Issue a READ SPARAM mailbox command
749 */
750extern uint32_t
751emlxs_mb_read_sparam(emlxs_hba_t *hba, MAILBOX *mb)
752{
753 MATCHMAP *mp;
754
746 */
747extern uint32_t
748emlxs_mb_read_sparam(emlxs_hba_t *hba, MAILBOX *mb)
749{
750 MATCHMAP *mp;
751
755 bzero((void *) mb, MAILBOX_CMD_BSIZE);
752 bzero((void *)mb, MAILBOX_CMD_BSIZE);
756
753
757 if ((mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BUF)) == 0) {
754 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
758 mb->mbxCommand = MBX_READ_SPARM64;
759
760 return (1);
761 }
755 mb->mbxCommand = MBX_READ_SPARM64;
756
757 return (1);
758 }
759
762 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
760 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
763 mb->un.varRdSparm.un.sp64.addrHigh = (uint32_t)putPaddrHigh(mp->phys);
764 mb->un.varRdSparm.un.sp64.addrLow = (uint32_t)putPaddrLow(mp->phys);
761 mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
762 mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
765 mb->mbxCommand = MBX_READ_SPARM64;
766 mb->mbxOwner = OWN_HOST;
767
768 /*
769 * save address for completion
770 */
771 ((MAILBOXQ *)mb)->bp = (uint8_t *)mp;
772
773 return (0);
774
775} /* emlxs_mb_read_sparam() */
776
777
778/*
763 mb->mbxCommand = MBX_READ_SPARM64;
764 mb->mbxOwner = OWN_HOST;
765
766 /*
767 * save address for completion
768 */
769 ((MAILBOXQ *)mb)->bp = (uint8_t *)mp;
770
771 return (0);
772
773} /* emlxs_mb_read_sparam() */
774
775
776/*
779 * emlxs_mb_read_rpi Issue a READ RPI
780 * mailbox command
777 * emlxs_mb_read_rpi Issue a READ RPI mailbox command
781 */
778 */
782/* ARGSUSED */
779/*ARGSUSED*/
783extern uint32_t
780extern uint32_t
784emlxs_mb_read_rpi(emlxs_hba_t *hba, uint32_t rpi, MAILBOX *mb, uint32_t flag)
781emlxs_mb_read_rpi(emlxs_hba_t *hba, uint32_t rpi, MAILBOX *mb,
782 uint32_t flag)
785{
783{
786 bzero((void *) mb, MAILBOX_CMD_BSIZE);
784 bzero((void *)mb, MAILBOX_CMD_BSIZE);
787
788 /*
789 * Set flag to issue action on cmpl
790 */
791 mb->un.varWords[30] = flag;
792 mb->un.varRdRPI.reqRpi = (volatile uint16_t) rpi;
793 mb->mbxCommand = MBX_READ_RPI64;
794 mb->mbxOwner = OWN_HOST;
795
796 return (0);
785
786 /*
787 * Set flag to issue action on cmpl
788 */
789 mb->un.varWords[30] = flag;
790 mb->un.varRdRPI.reqRpi = (volatile uint16_t) rpi;
791 mb->mbxCommand = MBX_READ_RPI64;
792 mb->mbxOwner = OWN_HOST;
793
794 return (0);
797
798} /* End emlxs_mb_read_rpi */
799
800
801/*
795} /* End emlxs_mb_read_rpi */
796
797
798/*
802 * emlxs_mb_read_xri Issue a READ XRI
803 * mailbox command
799 * emlxs_mb_read_xri Issue a READ XRI mailbox command
804 */
800 */
805/* ARGSUSED */
801/*ARGSUSED*/
806extern uint32_t
802extern uint32_t
807emlxs_mb_read_xri(emlxs_hba_t *hba, uint32_t xri, MAILBOX *mb, uint32_t flag)
803emlxs_mb_read_xri(emlxs_hba_t *hba, uint32_t xri, MAILBOX *mb,
804 uint32_t flag)
808{
805{
809 bzero((void *) mb, MAILBOX_CMD_BSIZE);
806 bzero((void *)mb, MAILBOX_CMD_BSIZE);
810
811 /*
812 * Set flag to issue action on cmpl
813 */
814 mb->un.varWords[30] = flag;
807
808 /*
809 * Set flag to issue action on cmpl
810 */
811 mb->un.varWords[30] = flag;
815 mb->un.varRdXRI.reqXri = (volatile uint16_t) xri;
812 mb->un.varRdXRI.reqXri = (volatile uint16_t)xri;
816 mb->mbxCommand = MBX_READ_XRI;
817 mb->mbxOwner = OWN_HOST;
818
819 return (0);
813 mb->mbxCommand = MBX_READ_XRI;
814 mb->mbxOwner = OWN_HOST;
815
816 return (0);
820
821} /* End emlxs_mb_read_xri */
822
823
817} /* End emlxs_mb_read_xri */
818
819
824/* ARGSUSED */
820/*ARGSUSED*/
825extern int32_t
826emlxs_mb_check_sparm(emlxs_hba_t *hba, SERV_PARM *nsp)
827{
828 uint32_t nsp_value;
829 uint32_t *iptr;
830
831 if (nsp->cmn.fPort) {
832 return (0);
833 }
821extern int32_t
822emlxs_mb_check_sparm(emlxs_hba_t *hba, SERV_PARM *nsp)
823{
824 uint32_t nsp_value;
825 uint32_t *iptr;
826
827 if (nsp->cmn.fPort) {
828 return (0);
829 }
830
834 /* Validate the service parameters */
831 /* Validate the service parameters */
835 iptr = (uint32_t *)& nsp->portName;
832 iptr = (uint32_t *)&nsp->portName;
836 if (iptr[0] == 0 && iptr[1] == 0) {
837 return (1);
838 }
833 if (iptr[0] == 0 && iptr[1] == 0) {
834 return (1);
835 }
839 iptr = (uint32_t *)& nsp->nodeName;
836
837 iptr = (uint32_t *)&nsp->nodeName;
840 if (iptr[0] == 0 && iptr[1] == 0) {
841 return (2);
842 }
838 if (iptr[0] == 0 && iptr[1] == 0) {
839 return (2);
840 }
841
843 if (nsp->cls2.classValid) {
842 if (nsp->cls2.classValid) {
844 nsp_value = ((nsp->cls2.rcvDataSizeMsb & 0x0f) << 8) |
845 nsp->cls2.rcvDataSizeLsb;
843 nsp_value =
844 ((nsp->cls2.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls2.
845 rcvDataSizeLsb;
846
846
847 /*
848 * If the receive data length is zero then set it to the CSP
849 * value
850 */
847 /* If the receive data length is zero then set it to */
848 /* the CSP value */
851 if (!nsp_value) {
852 nsp->cls2.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
853 nsp->cls2.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
854 return (0);
855 }
856 }
849 if (!nsp_value) {
850 nsp->cls2.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
851 nsp->cls2.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
852 return (0);
853 }
854 }
855
857 if (nsp->cls3.classValid) {
856 if (nsp->cls3.classValid) {
858 nsp_value = ((nsp->cls3.rcvDataSizeMsb & 0x0f) << 8) |
859 nsp->cls3.rcvDataSizeLsb;
857 nsp_value =
858 ((nsp->cls3.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls3.
859 rcvDataSizeLsb;
860
860
861 /*
862 * If the receive data length is zero then set it to the CSP
863 * value
864 */
865 /* This prevents a Emulex adapter bug from occurring */
861 /* If the receive data length is zero then set it to */
862 /* the CSP value */
866 if (!nsp_value) {
867 nsp->cls3.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
868 nsp->cls3.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
869 return (0);
870 }
871 }
863 if (!nsp_value) {
864 nsp->cls3.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
865 nsp->cls3.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
866 return (0);
867 }
868 }
869
872 return (0);
873
874} /* emlxs_mb_check_sparm() */
875
876
877/*
870 return (0);
871
872} /* emlxs_mb_check_sparm() */
873
874
875/*
878 * emlxs_mb_reg_did Issue a REG_LOGIN
879 * mailbox command
876 * emlxs_mb_reg_did Issue a REG_LOGIN mailbox command
880 */
881extern uint32_t
882emlxs_mb_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param,
883 emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq)
884{
877 */
878extern uint32_t
879emlxs_mb_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param,
880 emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq)
881{
885 emlxs_hba_t *hba = HBA;
886 MATCHMAP *mp;
887 MAILBOXQ *mbq;
888 MAILBOX *mb;
889 uint32_t rval;
882 emlxs_hba_t *hba = HBA;
883 MATCHMAP *mp;
884 MAILBOXQ *mbq;
885 MAILBOX *mb;
886 uint32_t rval;
890
891 /* Check for invalid node ids to register */
887
888 /* Check for invalid node ids to register */
892 if (did == 0 || (did & 0xff000000)) {
889 if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) {
893 return (1);
894 }
890 return (1);
891 }
892
893 if (did & 0xff000000) {
894 return (1);
895 }
896
895 if ((rval = emlxs_mb_check_sparm(hba, param))) {
896 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
897 if ((rval = emlxs_mb_check_sparm(hba, param))) {
898 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
897 "Invalid service parameters. did=%06x rval=%d", did, rval);
899 "Invalid service parameters. did=%06x rval=%d", did,
900 rval);
898
899 return (1);
900 }
901
902 return (1);
903 }
904
901 /* Check if the node limit has been reached */
902 if (port->node_count >= hba->max_nodes) {
903 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
905 /* Check if the node limit has been reached */
906 if (port->node_count >= hba->max_nodes) {
907 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
904 "Limit reached. did=%06x count=%d", did, port->node_count);
908 "Limit reached. did=%06x count=%d", did,
909 port->node_count);
905
906 return (1);
907 }
910
911 return (1);
912 }
908 if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
913
914 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
909 return (1);
910 }
915 return (1);
916 }
917
911 /* Build login request */
918 /* Build login request */
912 if ((mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BUF | MEM_PRI)) == 0) {
919 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF | MEM_PRI)) == 0) {
913 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
914 return (1);
915 }
920 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
921 return (1);
922 }
916 bcopy((void *) param, (void *) mp->virt, sizeof (SERV_PARM));
917
923
918 mb = (MAILBOX *) mbq->mbox;
924 bcopy((void *)param, (void *)mp->virt, sizeof (SERV_PARM));
925
926 mb = (MAILBOX *)mbq->mbox;
919 mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
927 mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
920 mb->un.varRegLogin.un.sp64.addrHigh = (uint32_t)putPaddrHigh(mp->phys);
921 mb->un.varRegLogin.un.sp64.addrLow = (uint32_t)putPaddrLow(mp->phys);
928 mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
929 mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
922 mb->un.varRegLogin.rpi = 0;
923 mb->un.varRegLogin.did = did;
924 mb->un.varWords[30] = 0; /* flags */
925 mb->mbxCommand = MBX_REG_LOGIN64;
926 mb->mbxOwner = OWN_HOST;
927
928#ifdef SLI3_SUPPORT
930 mb->un.varRegLogin.rpi = 0;
931 mb->un.varRegLogin.did = did;
932 mb->un.varWords[30] = 0; /* flags */
933 mb->mbxCommand = MBX_REG_LOGIN64;
934 mb->mbxOwner = OWN_HOST;
935
936#ifdef SLI3_SUPPORT
929 mb->un.varRegLogin.vpi =
930 port->vpi;
937 mb->un.varRegLogin.vpi = port->vpi;
931#endif /* SLI3_SUPPORT */
932
933 mbq->sbp = (uint8_t *)sbp;
934 mbq->ubp = (uint8_t *)ubp;
935 mbq->iocbq = (uint8_t *)iocbq;
936 mbq->bp = (uint8_t *)mp;
937
938#endif /* SLI3_SUPPORT */
939
940 mbq->sbp = (uint8_t *)sbp;
941 mbq->ubp = (uint8_t *)ubp;
942 mbq->iocbq = (uint8_t *)iocbq;
943 mbq->bp = (uint8_t *)mp;
944
938 if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
945 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
939 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
940 }
946 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
947 }
948
941 return (0);
942
943} /* emlxs_mb_reg_did() */
944
945/*
949 return (0);
950
951} /* emlxs_mb_reg_did() */
952
953/*
946 * emlxs_mb_unreg_rpi Issue a UNREG_LOGIN
947 * mailbox command
954 * emlxs_mb_unreg_rpi Issue a UNREG_LOGIN mailbox command
948 */
949extern uint32_t
950emlxs_mb_unreg_rpi(emlxs_port_t *port, uint32_t rpi, emlxs_buf_t *sbp,
951 fc_unsol_buf_t *ubp, IOCBQ *iocbq)
952{
955 */
956extern uint32_t
957emlxs_mb_unreg_rpi(emlxs_port_t *port, uint32_t rpi, emlxs_buf_t *sbp,
958 fc_unsol_buf_t *ubp, IOCBQ *iocbq)
959{
953 emlxs_hba_t *hba = HBA;
954 MAILBOXQ *mbq;
955 MAILBOX *mb;
956 NODELIST *ndlp;
960 emlxs_hba_t *hba = HBA;
961 MAILBOXQ *mbq;
962 MAILBOX *mb;
963 NODELIST *ndlp;
957
958 if (rpi != 0xffff) {
959 /* Make sure the node does already exist */
960 ndlp = emlxs_node_find_rpi(port, rpi);
961
962
963 if (ndlp) {
964 /*
964
965 if (rpi != 0xffff) {
966 /* Make sure the node does already exist */
967 ndlp = emlxs_node_find_rpi(port, rpi);
968
969
970 if (ndlp) {
971 /*
965 * If we just unregistered the host node then clear
966 * the host DID
972 * If we just unregistered the host node then
973 * clear the host DID
967 */
968 if (ndlp->nlp_DID == port->did) {
969 port->did = 0;
970 }
974 */
975 if (ndlp->nlp_DID == port->did) {
976 port->did = 0;
977 }
978
971 /* remove it */
972 emlxs_node_rm(port, ndlp);
973
974 } else {
975 return (1);
976 }
977 } else { /* Unreg all */
979 /* remove it */
980 emlxs_node_rm(port, ndlp);
981
982 } else {
983 return (1);
984 }
985 } else { /* Unreg all */
986
978 emlxs_node_destroy_all(port);
979 }
980
987 emlxs_node_destroy_all(port);
988 }
989
981 if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
990 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
982 return (1);
983 }
991 return (1);
992 }
984 mb = (MAILBOX *) mbq->mbox;
993
994 mb = (MAILBOX *)mbq->mbox;
985 mb->un.varUnregLogin.rpi = (uint16_t)rpi;
986
987#ifdef SLI3_SUPPORT
988 mb->un.varUnregLogin.vpi = port->vpi;
995 mb->un.varUnregLogin.rpi = (uint16_t)rpi;
996
997#ifdef SLI3_SUPPORT
998 mb->un.varUnregLogin.vpi = port->vpi;
989#endif /* SLI3_SUPPORT */
999#endif /* SLI3_SUPPORT */
990
991 mb->mbxCommand = MBX_UNREG_LOGIN;
992 mb->mbxOwner = OWN_HOST;
993 mbq->sbp = (uint8_t *)sbp;
994 mbq->ubp = (uint8_t *)ubp;
995 mbq->iocbq = (uint8_t *)iocbq;
996
1000
1001 mb->mbxCommand = MBX_UNREG_LOGIN;
1002 mb->mbxOwner = OWN_HOST;
1003 mbq->sbp = (uint8_t *)sbp;
1004 mbq->ubp = (uint8_t *)ubp;
1005 mbq->iocbq = (uint8_t *)iocbq;
1006
997 if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
1007 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
998 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
999 }
1008 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1009 }
1010
1000 return (0);
1001} /* emlxs_mb_unreg_rpi() */
1002
1003/*
1011 return (0);
1012} /* emlxs_mb_unreg_rpi() */
1013
1014/*
1004 * emlxs_mb_unreg_did Issue a UNREG_DID
1005 * mailbox command
1015 * emlxs_mb_unreg_did Issue a UNREG_DID mailbox command
1006 */
1007extern uint32_t
1008emlxs_mb_unreg_did(emlxs_port_t *port, uint32_t did, emlxs_buf_t *sbp,
1009 fc_unsol_buf_t *ubp, IOCBQ *iocbq)
1010{
1016 */
1017extern uint32_t
1018emlxs_mb_unreg_did(emlxs_port_t *port, uint32_t did, emlxs_buf_t *sbp,
1019 fc_unsol_buf_t *ubp, IOCBQ *iocbq)
1020{
1011 emlxs_hba_t *hba = HBA;
1012 NODELIST *ndlp;
1013 MAILBOXQ *mbq;
1014 MAILBOX *mb;
1021 emlxs_hba_t *hba = HBA;
1022 NODELIST *ndlp;
1023 MAILBOXQ *mbq;
1024 MAILBOX *mb;
1015
1016 /*
1017 * Unregister all default RPIs if did == 0xffffffff
1018 */
1019 if (did != 0xffffffff) {
1020 /* Check for base node */
1021 if (did == Bcast_DID) {
1022 /* just flush base node */
1023 (void) emlxs_tx_node_flush(port, &port->node_base,
1024 0, 0, 0);
1025
1026 /*
1027 * Unregister all default RPIs if did == 0xffffffff
1028 */
1029 if (did != 0xffffffff) {
1030 /* Check for base node */
1031 if (did == Bcast_DID) {
1032 /* just flush base node */
1033 (void) emlxs_tx_node_flush(port, &port->node_base,
1034 0, 0, 0);
1025 (void) emlxs_chipq_node_flush(port, 0, &port->node_base,
1026 0);
1035 (void) emlxs_chipq_node_flush(port, 0,
1036 &port->node_base, 0);
1027
1028 /* Return now */
1029 return (1);
1030 }
1037
1038 /* Return now */
1039 return (1);
1040 }
1041
1042
1031 /*
1032 * A zero DID means that we are trying to unreg the host node
1033 * after a link bounce
1034 */
1035
1036 /*
1037 * If the prev_did == 0 then the adapter has been reset and
1038 * there is no need in unregistering
1039 */
1040
1041 /*
1043 /*
1044 * A zero DID means that we are trying to unreg the host node
1045 * after a link bounce
1046 */
1047
1048 /*
1049 * If the prev_did == 0 then the adapter has been reset and
1050 * there is no need in unregistering
1051 */
1052
1053 /*
1042 * If the prev_did != 0 then we can look for the hosts last
1043 * known DID node
1054 * If the prev_did != 0 then we can look for the hosts
1055 * last known DID node
1044 */
1045
1046 if (did == 0) {
1047 if (port->prev_did == 0) {
1048 return (1);
1049 }
1056 */
1057
1058 if (did == 0) {
1059 if (port->prev_did == 0) {
1060 return (1);
1061 }
1062
1050 did = port->prev_did;
1051 }
1063 did = port->prev_did;
1064 }
1065
1052 /* Make sure the node does already exist */
1053 ndlp = emlxs_node_find_did(port, did);
1054
1055
1056 if (ndlp) {
1057 /* remove it */
1058 emlxs_node_rm(port, ndlp);
1059
1060 /*
1066 /* Make sure the node does already exist */
1067 ndlp = emlxs_node_find_did(port, did);
1068
1069
1070 if (ndlp) {
1071 /* remove it */
1072 emlxs_node_rm(port, ndlp);
1073
1074 /*
1061 * If we just unregistered the host node then clear
1062 * the host DID
1075 * If we just unregistered the host node then
1076 * clear the host DID
1063 */
1064 if (did == port->did) {
1065 port->did = 0;
1066 }
1077 */
1078 if (did == port->did) {
1079 port->did = 0;
1080 }
1081
1067 } else {
1068 return (1);
1069 }
1070 }
1082 } else {
1083 return (1);
1084 }
1085 }
1071 if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
1086
1087 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
1072 return (1);
1073 }
1088 return (1);
1089 }
1074 mb = (MAILBOX *) mbq->mbox;
1090
1091 mb = (MAILBOX *)mbq->mbox;
1075 mb->un.varUnregDID.did = did;
1076
1077#ifdef SLI3_SUPPORT
1078 mb->un.varUnregDID.vpi = port->vpi;
1079#endif /* SLI3_SUPPORT */
1080
1081 mb->mbxCommand = MBX_UNREG_D_ID;
1082 mb->mbxOwner = OWN_HOST;
1083 mbq->sbp = (uint8_t *)sbp;
1084 mbq->ubp = (uint8_t *)ubp;
1085 mbq->iocbq = (uint8_t *)iocbq;
1086
1092 mb->un.varUnregDID.did = did;
1093
1094#ifdef SLI3_SUPPORT
1095 mb->un.varUnregDID.vpi = port->vpi;
1096#endif /* SLI3_SUPPORT */
1097
1098 mb->mbxCommand = MBX_UNREG_D_ID;
1099 mb->mbxOwner = OWN_HOST;
1100 mbq->sbp = (uint8_t *)sbp;
1101 mbq->ubp = (uint8_t *)ubp;
1102 mbq->iocbq = (uint8_t *)iocbq;
1103
1087 if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
1104 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
1088 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1089 }
1105 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1106 }
1107
1090 return (0);
1091
1092} /* End emlxs_mb_unreg_did */
1093
1094
1095/*
1108 return (0);
1109
1110} /* End emlxs_mb_unreg_did */
1111
1112
1113/*
1096 * emlxs_mb_set_mask Issue a SET MASK
1097 * mailbox command
1114 * emlxs_mb_set_mask Issue a SET MASK mailbox command
1098 */
1115 */
1099/* ARGSUSED */
1116/*ARGSUSED*/
1100static void
1101emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mask,
1102 uint32_t ringno)
1103{
1117static void
1118emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mask,
1119 uint32_t ringno)
1120{
1104 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1121 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1105
1106 mb->un.varWords[0] = 0x11223344; /* set passwd */
1107 mb->un.varWords[1] = mask; /* set mask */
1108 mb->un.varWords[2] = ringno; /* set ringno */
1109 mb->mbxCommand = MBX_SET_MASK;
1110 mb->mbxOwner = OWN_HOST;
1122
1123 mb->un.varWords[0] = 0x11223344; /* set passwd */
1124 mb->un.varWords[1] = mask; /* set mask */
1125 mb->un.varWords[2] = ringno; /* set ringno */
1126 mb->mbxCommand = MBX_SET_MASK;
1127 mb->mbxOwner = OWN_HOST;
1111
1112} /* End emlxs_mb_set_mask */
1113
1114
1115/*
1128} /* End emlxs_mb_set_mask */
1129
1130
1131/*
1116 * emlxs_mb_set_debug Issue a special debug
1117 * mailbox command
1132 * emlxs_mb_set_debug Issue a special debug mailbox command
1118 */
1133 */
1119/* ARGSUSED */
1134/*ARGSUSED*/
1120static void
1121emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOX *mb, uint32_t word0,
1122 uint32_t word1, uint32_t word2)
1123{
1135static void
1136emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOX *mb, uint32_t word0,
1137 uint32_t word1, uint32_t word2)
1138{
1124 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1139 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1125
1126 mb->un.varWords[0] = word0;
1127 mb->un.varWords[1] = word1;
1128 mb->un.varWords[2] = word2;
1129 mb->mbxCommand = MBX_SET_DEBUG;
1130 mb->mbxOwner = OWN_HOST;
1140
1141 mb->un.varWords[0] = word0;
1142 mb->un.varWords[1] = word1;
1143 mb->un.varWords[2] = word2;
1144 mb->mbxCommand = MBX_SET_DEBUG;
1145 mb->mbxOwner = OWN_HOST;
1131
1132} /* End emlxs_mb_set_debug */
1133
1134
1135/*
1146} /* End emlxs_mb_set_debug */
1147
1148
1149/*
1136 * emlxs_mb_set_var Issue a special debug mbox
1137 * command to write slim
1150 * emlxs_mb_set_var Issue a special debug mbox command to write slim
1138 */
1151 */
1139/* ARGSUSED */
1152/*ARGSUSED*/
1140extern void
1153extern void
1141emlxs_mb_set_var(emlxs_hba_t *hba, MAILBOX *mb, uint32_t addr, uint32_t value)
1154emlxs_mb_set_var(emlxs_hba_t *hba, MAILBOX *mb, uint32_t addr,
1155 uint32_t value)
1142{
1156{
1143 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1157 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1144
1145 /* addr = 0x090597 is AUTO ABTS disable for ELS commands */
1146 /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */
1147 /* addr = 0x100506 is for setting PCI MAX READ value */
1148
1149 /*
1150 * Always turn on DELAYED ABTS for ELS timeouts
1151 */
1152 if ((addr == 0x052198) && (value == 0)) {
1153 value = 1;
1154 }
1158
1159 /* addr = 0x090597 is AUTO ABTS disable for ELS commands */
1160 /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */
1161 /* addr = 0x100506 is for setting PCI MAX READ value */
1162
1163 /*
1164 * Always turn on DELAYED ABTS for ELS timeouts
1165 */
1166 if ((addr == 0x052198) && (value == 0)) {
1167 value = 1;
1168 }
1169
1155 mb->un.varWords[0] = addr;
1156 mb->un.varWords[1] = value;
1157 mb->mbxCommand = MBX_SET_VARIABLE;
1158 mb->mbxOwner = OWN_HOST;
1170 mb->un.varWords[0] = addr;
1171 mb->un.varWords[1] = value;
1172 mb->mbxCommand = MBX_SET_VARIABLE;
1173 mb->mbxOwner = OWN_HOST;
1159
1160} /* End emlxs_mb_set_var */
1161
1162
1163/*
1164 * Disable Traffic Cop
1165 */
1174} /* End emlxs_mb_set_var */
1175
1176
1177/*
1178 * Disable Traffic Cop
1179 */
1166/* ARGSUSED */
1180/*ARGSUSED*/
1167extern void
1168emlxs_disable_tc(emlxs_hba_t *hba, MAILBOX *mb)
1169{
1181extern void
1182emlxs_disable_tc(emlxs_hba_t *hba, MAILBOX *mb)
1183{
1170 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1184 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1171
1172 mb->un.varWords[0] = 0x50797;
1173 mb->un.varWords[1] = 0;
1174 mb->un.varWords[2] = 0xfffffffe;
1175 mb->mbxCommand = MBX_SET_VARIABLE;
1176 mb->mbxOwner = OWN_HOST;
1177
1178} /* End emlxs_disable_tc */
1179
1180
1185
1186 mb->un.varWords[0] = 0x50797;
1187 mb->un.varWords[1] = 0;
1188 mb->un.varWords[2] = 0xfffffffe;
1189 mb->mbxCommand = MBX_SET_VARIABLE;
1190 mb->mbxOwner = OWN_HOST;
1191
1192} /* End emlxs_disable_tc */
1193
1194
1181/*
1182 * emlxs_mb_config_port Issue a CONFIG_PORT
1183 * mailbox command
1184 */
1185extern uint32_t
1186emlxs_mb_config_port(emlxs_hba_t *hba, MAILBOX *mb, uint32_t sli_mode,
1187 uint32_t hbainit)
1188{
1189 emlxs_vpd_t *vpd = &VPD;
1190 emlxs_port_t *port = &PPORT;
1191 emlxs_config_t *cfg;
1192 RING *rp;
1193 uint64_t pcb;
1194 uint64_t mbx;
1195 uint64_t hgp;
1196 uint64_t pgp;
1197 uint64_t rgp;
1198 MAILBOX *mbox;
1199 SLIM2 *slim;
1200 SLI2_RDSC *rdsc;
1201 uint64_t offset;
1202 uint32_t Laddr;
1203 uint32_t i;
1204
1195
1205 cfg = &CFG;
1206 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1207 mbox = NULL;
1208 slim = NULL;
1209
1210 mb->mbxCommand = MBX_CONFIG_PORT;
1211 mb->mbxOwner = OWN_HOST;
1212
1213 mb->un.varCfgPort.pcbLen = sizeof (PCB);
1214
1215#ifdef SLI3_SUPPORT
1196#ifdef SLI3_SUPPORT
1216 mb->un.varCfgPort.hbainit[0] = hbainit;
1217#else /* SLI3_SUPPORT */
1218 mb->un.varCfgPort.hbainit = hbainit;
1219#endif /* SLI3_SUPPORT */
1220
1221 pcb = hba->slim2.phys + (uint64_t)(unsigned long)& (slim->pcb);
1222 mb->un.varCfgPort.pcbLow = (uint32_t)putPaddrLow(pcb);
1223 mb->un.varCfgPort.pcbHigh = (uint32_t)putPaddrHigh(pcb);
1224
1225 /* Set Host pointers in SLIM flag */
1226 mb->un.varCfgPort.hps = 1;
1227
1228 /* Initialize hba structure for assumed default SLI2 mode */
1229 /* If config port succeeds, then we will update it then */
1230 hba->sli_mode = 2;
1231 hba->vpi_max = 1;
1232 hba->flag &= ~FC_NPIV_ENABLED;
1233
1234#ifdef SLI3_SUPPORT
1235 if (sli_mode >= 3) {
1236 mb->un.varCfgPort.sli_mode = 3;
1237 mb->un.varCfgPort.cerbm = 1;
1238 mb->un.varCfgPort.max_hbq = EMLXS_NUM_HBQ;
1239
1240#ifdef NPIV_SUPPORT
1241 if (cfg[CFG_NPIV_ENABLE].current) {
1242 if (vpd->feaLevelHigh >= 0x09) {
1243 if (hba->model_info.chip >= EMLXS_SATURN_CHIP) {
1244 mb->un.varCfgPort.vpi_max =
1245 MAX_VPORTS - 1;
1246 } else {
1247 mb->un.varCfgPort.vpi_max =
1248 MAX_VPORTS_LIMITED - 1;
1249 }
1250
1251 mb->un.varCfgPort.cmv = 1;
1252 } else {
1253 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1254 "CFGPORT: Firmware does not support NPIV. "
1255 "level=%d", vpd->feaLevelHigh);
1256 }
1257
1258 }
1259#endif /* NPIV_SUPPORT */
1260 }
1261#endif /* SLI3_SUPPORT */
1262
1263 /*
1264 * Now setup pcb
1265 */
1266 ((SLIM2 *) hba->slim2.virt)->pcb.type = TYPE_NATIVE_SLI2;
1267 ((SLIM2 *) hba->slim2.virt)->pcb.feature = FEATURE_INITIAL_SLI2;
1268 ((SLIM2 *) hba->slim2.virt)->pcb.maxRing = (hba->ring_count - 1);
1269 ((SLIM2 *) hba->slim2.virt)->pcb.mailBoxSize = sizeof (MAILBOX) +
1270 MBOX_EXTENSION_SIZE;
1271
1272 mbx = hba->slim2.phys + (uint64_t)(unsigned long)& (slim->mbx);
1273 ((SLIM2 *)hba->slim2.virt)->pcb.mbAddrHigh =
1274 (uint32_t)putPaddrHigh(mbx);
1275 ((SLIM2 *)hba->slim2.virt)->pcb.mbAddrLow = (uint32_t)putPaddrLow(mbx);
1276
1277
1278 /*
1279 * Set up HGP - Port Memory
1280 *
1281 * CR0Put - SLI2(no HBQs) = 0xc0, With HBQs = 0x80
1282 * RR0Get 0xc4 0x84
1283 * CR1Put 0xc8 0x88
1284 * RR1Get 0xcc 0x8c
1285 * CR2Put 0xd0 0x90
1286 * RR2Get 0xd4 0x94
1287 * CR3Put 0xd8 0x98
1288 * RR3Get 0xdc 0x9c
1289 *
1290 * Reserved 0xa0-0xbf
1291 *
1292 * If HBQs configured:
1293 * HBQ 0 Put ptr 0xc0
1294 * HBQ 1 Put ptr 0xc4
1295 * HBQ 2 Put ptr 0xc8
1296 * ......
1297 * HBQ(M-1)Put Pointer 0xc0+(M-1)*4
1298 */
1299
1300#ifdef SLI3_SUPPORT
1301 if (sli_mode >= 3) {
1302 /* ERBM is enabled */
1303 hba->hgp_ring_offset = 0x80;
1304 hba->hgp_hbq_offset = 0xC0;
1305
1306 hba->iocb_cmd_size = SLI3_IOCB_CMD_SIZE;
1307 hba->iocb_rsp_size = SLI3_IOCB_RSP_SIZE;
1308
1309 } else /* SLI2 */
1310#endif /* SLI3_SUPPORT */
1311 {
1312 /* ERBM is disabled */
1313 hba->hgp_ring_offset = 0xC0;
1314 hba->hgp_hbq_offset = 0;
1315
1316 hba->iocb_cmd_size = SLI2_IOCB_CMD_SIZE;
1317 hba->iocb_rsp_size = SLI2_IOCB_RSP_SIZE;
1318 }
1319
1320 /* The Sbus card uses Host Memory. The PCI card uses SLIM POINTER */
1321 if (hba->bus_type == SBUS_FC) {
1322 hgp = hba->slim2.phys +
1323 (uint64_t)(unsigned long)& (mbox->us.s2.host);
1324 ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrHigh =
1325 (uint32_t)putPaddrHigh(hgp);
1326 ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrLow =
1327 (uint32_t)putPaddrLow(hgp);
1328 } else {
1329 ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrHigh =
1330 (uint32_t)ddi_get32(hba->pci_acc_handle,
1331 (uint32_t *)(hba->pci_addr + PCI_BAR_1_REGISTER));
1332
1333 Laddr = ddi_get32(hba->pci_acc_handle,
1334 (uint32_t *)(hba->pci_addr + PCI_BAR_0_REGISTER));
1335 Laddr &= ~0x4;
1336 ((SLIM2 *)hba->slim2.virt)->pcb.hgpAddrLow =
1337 (uint32_t)(Laddr + hba->hgp_ring_offset);
1338
1339 }
1340
1341 pgp = hba->slim2.phys + (uint64_t)(unsigned long)& (mbox->us.s2.port);
1342 ((SLIM2 *)hba->slim2.virt)->pcb.pgpAddrHigh =
1343 (uint32_t)putPaddrHigh(pgp);
1344 ((SLIM2 *)hba->slim2.virt)->pcb.pgpAddrLow = (uint32_t)putPaddrLow(pgp);
1345
1346 offset = 0;
1347 for (i = 0; i < 4; i++) {
1348 rp = &hba->ring[i];
1349 rdsc = &((SLIM2 *) hba->slim2.virt)->pcb.rdsc[i];
1350
1351 /* Setup command ring */
1352 rgp = hba->slim2.phys +
1353 (uint64_t)(unsigned long)& (slim->IOCBs[offset]);
1354 rdsc->cmdAddrHigh = (uint32_t)putPaddrHigh(rgp);
1355 rdsc->cmdAddrLow = (uint32_t)putPaddrLow(rgp);
1356 rdsc->cmdEntries = rp->fc_numCiocb;
1357
1358 rp->fc_cmdringaddr = (void *) &((SLIM2 *) hba->slim2.virt)->
1359 IOCBs[offset];
1360 offset += rdsc->cmdEntries * hba->iocb_cmd_size;
1361
1362 /* Setup response ring */
1363 rgp = hba->slim2.phys +
1364 (uint64_t)(unsigned long)& (slim->IOCBs[offset]);
1365 rdsc->rspAddrHigh = (uint32_t)putPaddrHigh(rgp);
1366 rdsc->rspAddrLow = (uint32_t)putPaddrLow(rgp);
1367 rdsc->rspEntries = rp->fc_numRiocb;
1368
1369 rp->fc_rspringaddr = (void *) &((SLIM2 *) hba->slim2.virt)->
1370 IOCBs[offset];
1371 offset += rdsc->rspEntries * hba->iocb_rsp_size;
1372 }
1373
1374 emlxs_pcimem_bcopy((uint32_t *)(&((SLIM2 *) hba->slim2.virt)->pcb),
1375 (uint32_t *)(&((SLIM2 *) hba->slim2.virt)->pcb), sizeof (PCB));
1376
1377 offset =
1378 ((uint64_t)(unsigned long)& (((SLIM2 *) hba->slim2.virt)->pcb) -
1379 (uint64_t)(unsigned long)hba->slim2.virt);
1380 emlxs_mpdata_sync(hba->slim2.dma_handle, (off_t)offset, sizeof (PCB),
1381 DDI_DMA_SYNC_FORDEV);
1382
1383 return (0);
1384
1385} /* emlxs_mb_config_port() */
1386
1387
1388#ifdef SLI3_SUPPORT
1389extern void
1390emlxs_mb_config_hbq(emlxs_hba_t *hba, MAILBOX *mb, int hbq_id)
1391{
1197extern void
1198emlxs_mb_config_hbq(emlxs_hba_t *hba, MAILBOX *mb, int hbq_id)
1199{
1392 HBQ_INIT_t *hbq;
1393 int i;
1200 HBQ_INIT_t *hbq;
1201 int i;
1394
1202
1395 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1203 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1396
1397 hbq = &hba->hbq_table[hbq_id];
1398
1399 mb->un.varCfgHbq.hbqId = hbq_id;
1400 mb->un.varCfgHbq.numEntries = hbq->HBQ_numEntries;
1401 mb->un.varCfgHbq.recvNotify = hbq->HBQ_recvNotify;
1402 mb->un.varCfgHbq.numMask = hbq->HBQ_num_mask;
1403 mb->un.varCfgHbq.profile = hbq->HBQ_profile;

--- 7 unchanged lines hidden (view full) ---

1411
1412 /* Copy info for profiles 2,3,5. Other profiles this area is reserved */
1413 if ((hbq->HBQ_profile == 2) || (hbq->HBQ_profile == 3) ||
1414 (hbq->HBQ_profile == 5)) {
1415 bcopy(&hbq->profiles.allprofiles,
1416 &mb->un.varCfgHbq.profiles.allprofiles,
1417 sizeof (hbq->profiles));
1418 }
1204
1205 hbq = &hba->hbq_table[hbq_id];
1206
1207 mb->un.varCfgHbq.hbqId = hbq_id;
1208 mb->un.varCfgHbq.numEntries = hbq->HBQ_numEntries;
1209 mb->un.varCfgHbq.recvNotify = hbq->HBQ_recvNotify;
1210 mb->un.varCfgHbq.numMask = hbq->HBQ_num_mask;
1211 mb->un.varCfgHbq.profile = hbq->HBQ_profile;

--- 7 unchanged lines hidden (view full) ---

1219
1220 /* Copy info for profiles 2,3,5. Other profiles this area is reserved */
1221 if ((hbq->HBQ_profile == 2) || (hbq->HBQ_profile == 3) ||
1222 (hbq->HBQ_profile == 5)) {
1223 bcopy(&hbq->profiles.allprofiles,
1224 &mb->un.varCfgHbq.profiles.allprofiles,
1225 sizeof (hbq->profiles));
1226 }
1227
1419 /* Return if no rctl / type masks for this HBQ */
1420 if (!hbq->HBQ_num_mask) {
1421 return;
1422 }
1228 /* Return if no rctl / type masks for this HBQ */
1229 if (!hbq->HBQ_num_mask) {
1230 return;
1231 }
1232
1423 /* Otherwise we setup specific rctl / type masks for this HBQ */
1424 for (i = 0; i < hbq->HBQ_num_mask; i++) {
1233 /* Otherwise we setup specific rctl / type masks for this HBQ */
1234 for (i = 0; i < hbq->HBQ_num_mask; i++) {
1425 mb->un.varCfgHbq.hbqMasks[i].tmatch = hbq->HBQ_Masks[i].tmatch;
1235 mb->un.varCfgHbq.hbqMasks[i].tmatch =
1236 hbq->HBQ_Masks[i].tmatch;
1426 mb->un.varCfgHbq.hbqMasks[i].tmask = hbq->HBQ_Masks[i].tmask;
1427 mb->un.varCfgHbq.hbqMasks[i].rctlmatch =
1428 hbq->HBQ_Masks[i].rctlmatch;
1429 mb->un.varCfgHbq.hbqMasks[i].rctlmask =
1430 hbq->HBQ_Masks[i].rctlmask;
1431 }
1432
1433 return;
1434
1435} /* emlxs_mb_config_hbq() */
1436
1437#endif /* SLI3_SUPPORT */
1438
1439
1440extern uint32_t
1441emlxs_mb_reg_vpi(emlxs_port_t *port)
1442{
1237 mb->un.varCfgHbq.hbqMasks[i].tmask = hbq->HBQ_Masks[i].tmask;
1238 mb->un.varCfgHbq.hbqMasks[i].rctlmatch =
1239 hbq->HBQ_Masks[i].rctlmatch;
1240 mb->un.varCfgHbq.hbqMasks[i].rctlmask =
1241 hbq->HBQ_Masks[i].rctlmask;
1242 }
1243
1244 return;
1245
1246} /* emlxs_mb_config_hbq() */
1247
1248#endif /* SLI3_SUPPORT */
1249
1250
1251extern uint32_t
1252emlxs_mb_reg_vpi(emlxs_port_t *port)
1253{
1443 emlxs_hba_t *hba = HBA;
1444 MAILBOXQ *mbq;
1445 MAILBOX *mb;
1254 emlxs_hba_t *hba = HBA;
1255 MAILBOXQ *mbq;
1256 MAILBOX *mb;
1446
1447 if (!(hba->flag & FC_NPIV_ENABLED)) {
1448 return (0);
1449 }
1257
1258 if (!(hba->flag & FC_NPIV_ENABLED)) {
1259 return (0);
1260 }
1261
1450 mutex_enter(&EMLXS_PORT_LOCK);
1451
1452 /* Can't reg vpi until ClearLA is sent */
1453 if (hba->state != FC_READY) {
1454 mutex_exit(&EMLXS_PORT_LOCK);
1455
1456 return (1);
1457 }
1262 mutex_enter(&EMLXS_PORT_LOCK);
1263
1264 /* Can't reg vpi until ClearLA is sent */
1265 if (hba->state != FC_READY) {
1266 mutex_exit(&EMLXS_PORT_LOCK);
1267
1268 return (1);
1269 }
1270
1458 /* Must have port id */
1459 if (!port->did) {
1460 mutex_exit(&EMLXS_PORT_LOCK);
1461
1462 return (1);
1463 }
1271 /* Must have port id */
1272 if (!port->did) {
1273 mutex_exit(&EMLXS_PORT_LOCK);
1274
1275 return (1);
1276 }
1464 if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
1277
1278 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
1465 mutex_exit(&EMLXS_PORT_LOCK);
1466
1467 return (1);
1468 }
1279 mutex_exit(&EMLXS_PORT_LOCK);
1280
1281 return (1);
1282 }
1283
1469 port->flag |= EMLXS_PORT_REGISTERED;
1470
1471 mutex_exit(&EMLXS_PORT_LOCK);
1472
1284 port->flag |= EMLXS_PORT_REGISTERED;
1285
1286 mutex_exit(&EMLXS_PORT_LOCK);
1287
1473 mb = (MAILBOX *) mbq->mbox;
1474 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1288 mb = (MAILBOX *)mbq->mbox;
1289 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1475 mb->un.varRegVpi.vpi = port->vpi;
1476 mb->un.varRegVpi.sid = port->did;
1477 mb->mbxCommand = MBX_REG_VPI;
1478 mb->mbxOwner = OWN_HOST;
1479
1290 mb->un.varRegVpi.vpi = port->vpi;
1291 mb->un.varRegVpi.sid = port->did;
1292 mb->mbxCommand = MBX_REG_VPI;
1293 mb->mbxOwner = OWN_HOST;
1294
1480 if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
1295 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
1481 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1482 }
1296 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1297 }
1298
1483 return (0);
1484
1485} /* emlxs_mb_reg_vpi() */
1486
1487
1488extern uint32_t
1489emlxs_mb_unreg_vpi(emlxs_port_t *port)
1490{
1299 return (0);
1300
1301} /* emlxs_mb_reg_vpi() */
1302
1303
1304extern uint32_t
1305emlxs_mb_unreg_vpi(emlxs_port_t *port)
1306{
1491 emlxs_hba_t *hba = HBA;
1492 MAILBOXQ *mbq;
1493 MAILBOX *mb;
1307 emlxs_hba_t *hba = HBA;
1308 MAILBOXQ *mbq;
1309 MAILBOX *mb;
1494
1495 mutex_enter(&EMLXS_PORT_LOCK);
1496
1497 if (!(port->flag & EMLXS_PORT_REGISTERED)) {
1498 mutex_exit(&EMLXS_PORT_LOCK);
1499
1500 return (0);
1501 }
1310
1311 mutex_enter(&EMLXS_PORT_LOCK);
1312
1313 if (!(port->flag & EMLXS_PORT_REGISTERED)) {
1314 mutex_exit(&EMLXS_PORT_LOCK);
1315
1316 return (0);
1317 }
1502 if (!(mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
1318
1319 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX | MEM_PRI))) {
1503 mutex_exit(&EMLXS_PORT_LOCK);
1504
1505 return (1);
1506 }
1320 mutex_exit(&EMLXS_PORT_LOCK);
1321
1322 return (1);
1323 }
1324
1507 port->flag &= ~EMLXS_PORT_REGISTERED;
1508
1509 mutex_exit(&EMLXS_PORT_LOCK);
1510
1325 port->flag &= ~EMLXS_PORT_REGISTERED;
1326
1327 mutex_exit(&EMLXS_PORT_LOCK);
1328
1511 mb = (MAILBOX *) mbq->mbox;
1512 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1329 mb = (MAILBOX *)mbq->mbox;
1330 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1513 mb->un.varUnregVpi.vpi = port->vpi;
1514 mb->mbxCommand = MBX_UNREG_VPI;
1515 mb->mbxOwner = OWN_HOST;
1516
1331 mb->un.varUnregVpi.vpi = port->vpi;
1332 mb->mbxCommand = MBX_UNREG_VPI;
1333 mb->mbxOwner = OWN_HOST;
1334
1517 if (emlxs_mb_issue_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
1335 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_NOWAIT, 0) != MBX_BUSY) {
1518 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1519 }
1336 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1337 }
1338
1520 return (0);
1521
1522} /* emlxs_mb_unreg_vpi() */
1523
1524
1525/*
1339 return (0);
1340
1341} /* emlxs_mb_unreg_vpi() */
1342
1343
1344/*
1526 * emlxs_mb_config_farp Issue a CONFIG FARP
1527 * mailbox command
1345 * emlxs_mb_config_farp Issue a CONFIG FARP mailbox command
1528 */
1529extern void
1530emlxs_mb_config_farp(emlxs_hba_t *hba, MAILBOX *mb)
1531{
1346 */
1347extern void
1348emlxs_mb_config_farp(emlxs_hba_t *hba, MAILBOX *mb)
1349{
1532 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1350 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1533
1351
1534 bcopy((uint8_t *)& hba->wwpn,
1535 (uint8_t *)& mb->un.varCfgFarp.portname,
1536 sizeof (NAME_TYPE));
1352 bcopy((uint8_t *)&hba->wwpn,
1353 (uint8_t *)&mb->un.varCfgFarp.portname, sizeof (NAME_TYPE));
1537
1354
1538 bcopy((uint8_t *)& hba->wwpn,
1539 (uint8_t *)& mb->un.varCfgFarp.nodename,
1540 sizeof (NAME_TYPE));
1355 bcopy((uint8_t *)&hba->wwpn,
1356 (uint8_t *)&mb->un.varCfgFarp.nodename, sizeof (NAME_TYPE));
1541
1542 mb->un.varCfgFarp.filterEnable = 1;
1543 mb->un.varCfgFarp.portName = 1;
1544 mb->un.varCfgFarp.nodeName = 1;
1545 mb->mbxCommand = MBX_CONFIG_FARP;
1546 mb->mbxOwner = OWN_HOST;
1547} /* emlxs_mb_config_farp() */
1548
1549
1550/*
1357
1358 mb->un.varCfgFarp.filterEnable = 1;
1359 mb->un.varCfgFarp.portName = 1;
1360 mb->un.varCfgFarp.nodeName = 1;
1361 mb->mbxCommand = MBX_CONFIG_FARP;
1362 mb->mbxOwner = OWN_HOST;
1363} /* emlxs_mb_config_farp() */
1364
1365
1366/*
1551 * emlxs_mb_read_nv Issue a READ CONFIG
1552 * mailbox command
1367 * emlxs_mb_read_nv Issue a READ CONFIG mailbox command
1553 */
1368 */
1554/* ARGSUSED */
1369/*ARGSUSED*/
1555extern void
1556emlxs_mb_read_config(emlxs_hba_t *hba, MAILBOX *mb)
1557{
1370extern void
1371emlxs_mb_read_config(emlxs_hba_t *hba, MAILBOX *mb)
1372{
1558 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1373 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1559
1560 mb->mbxCommand = MBX_READ_CONFIG;
1561 mb->mbxOwner = OWN_HOST;
1374
1375 mb->mbxCommand = MBX_READ_CONFIG;
1376 mb->mbxOwner = OWN_HOST;
1562
1563} /* emlxs_mb_read_config() */
1564
1565
1566
1567/*
1568 * NAME: emlxs_mb_put
1569 *
1570 * FUNCTION: put mailbox cmd onto the mailbox queue.
1571 *
1572 * EXECUTION ENVIRONMENT: process and interrupt level.
1573 *
1574 * NOTES:
1575 *
1377} /* emlxs_mb_read_config() */
1378
1379
1380
1381/*
1382 * NAME: emlxs_mb_put
1383 *
1384 * FUNCTION: put mailbox cmd onto the mailbox queue.
1385 *
1386 * EXECUTION ENVIRONMENT: process and interrupt level.
1387 *
1388 * NOTES:
1389 *
1576 * CALLED FROM: emlxs_mb_issue_cmd
1390 * CALLED FROM: emlxs_sli_issue_mbox_cmd
1577 *
1391 *
1578 * INPUT: hba - pointer to the device info area mbp
1579 * - pointer to mailbox queue entry of mailbox cmd
1392 * INPUT: hba - pointer to the device info area
1393 * mbp - pointer to mailbox queue entry of mailbox cmd
1580 *
1581 * RETURNS: NULL - command queued
1582 */
1583extern void
1584emlxs_mb_put(emlxs_hba_t *hba, MAILBOXQ *mbq)
1585{
1586
1587 mutex_enter(&EMLXS_MBOX_LOCK);
1588
1589 if (hba->mbox_queue.q_first) {
1590
1591 /*
1592 * queue command to end of list
1593 */
1394 *
1395 * RETURNS: NULL - command queued
1396 */
1397extern void
1398emlxs_mb_put(emlxs_hba_t *hba, MAILBOXQ *mbq)
1399{
1400
1401 mutex_enter(&EMLXS_MBOX_LOCK);
1402
1403 if (hba->mbox_queue.q_first) {
1404
1405 /*
1406 * queue command to end of list
1407 */
1594 ((MAILBOXQ *) hba->mbox_queue.q_last)->next = mbq;
1408 ((MAILBOXQ *)hba->mbox_queue.q_last)->next = mbq;
1595 hba->mbox_queue.q_last = (uint8_t *)mbq;
1596 hba->mbox_queue.q_cnt++;
1597 } else {
1598
1599 /*
1600 * add command to empty list
1601 */
1602 hba->mbox_queue.q_first = (uint8_t *)mbq;

--- 20 unchanged lines hidden (view full) ---

1623 *
1624 * INPUT: hba - pointer to the device info area
1625 *
1626 * RETURNS: NULL - no match found mb pointer - pointer to a mailbox command
1627 */
1628extern MAILBOXQ *
1629emlxs_mb_get(emlxs_hba_t *hba)
1630{
1409 hba->mbox_queue.q_last = (uint8_t *)mbq;
1410 hba->mbox_queue.q_cnt++;
1411 } else {
1412
1413 /*
1414 * add command to empty list
1415 */
1416 hba->mbox_queue.q_first = (uint8_t *)mbq;

--- 20 unchanged lines hidden (view full) ---

1437 *
1438 * INPUT: hba - pointer to the device info area
1439 *
1440 * RETURNS: NULL - no match found mb pointer - pointer to a mailbox command
1441 */
1442extern MAILBOXQ *
1443emlxs_mb_get(emlxs_hba_t *hba)
1444{
1631 MAILBOXQ *p_first = NULL;
1445 MAILBOXQ *p_first = NULL;
1632
1633 mutex_enter(&EMLXS_MBOX_LOCK);
1634
1635 if (hba->mbox_queue.q_first) {
1446
1447 mutex_enter(&EMLXS_MBOX_LOCK);
1448
1449 if (hba->mbox_queue.q_first) {
1636 p_first = (MAILBOXQ *) hba->mbox_queue.q_first;
1450 p_first = (MAILBOXQ *)hba->mbox_queue.q_first;
1637 hba->mbox_queue.q_first = (uint8_t *)p_first->next;
1638
1639 if (hba->mbox_queue.q_first == NULL) {
1640 hba->mbox_queue.q_last = NULL;
1641 hba->mbox_queue.q_cnt = 0;
1642 } else {
1643 hba->mbox_queue.q_cnt--;
1644 }
1645
1646 p_first->next = NULL;
1647 }
1451 hba->mbox_queue.q_first = (uint8_t *)p_first->next;
1452
1453 if (hba->mbox_queue.q_first == NULL) {
1454 hba->mbox_queue.q_last = NULL;
1455 hba->mbox_queue.q_cnt = 0;
1456 } else {
1457 hba->mbox_queue.q_cnt--;
1458 }
1459
1460 p_first->next = NULL;
1461 }
1462
1648 mutex_exit(&EMLXS_MBOX_LOCK);
1649
1650 return (p_first);
1651
1652} /* emlxs_mb_get() */
1653
1654
1655
1656/* EMLXS_PORT_LOCK must be held when calling this */
1463 mutex_exit(&EMLXS_MBOX_LOCK);
1464
1465 return (p_first);
1466
1467} /* emlxs_mb_get() */
1468
1469
1470
1471/* EMLXS_PORT_LOCK must be held when calling this */
1657static void
1472void
1658emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo)
1659{
1473emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo)
1474{
1660 MATCHMAP *mp;
1475#ifdef FMA_SUPPORT
1476 emlxs_port_t *port = &PPORT;
1477#endif /* FMA_SUPPORT */
1478 MATCHMAP *mp;
1661
1662 HBASTATS.MboxIssued++;
1663 hba->mbox_queue_flag = flag;
1664
1665 /* Set the Mailbox timer */
1666 hba->mbox_timer = hba->timer_tics + tmo;
1667
1668 /* Initialize mailbox */

--- 13 unchanged lines hidden (view full) ---

1682 if (mbq->bp) {
1683 mp = (MATCHMAP *) mbq->bp;
1684 emlxs_mpdata_sync(mp->dma_handle, 0, mp->size,
1685 DDI_DMA_SYNC_FORDEV);
1686
1687 hba->mbox_bp = mbq->bp;
1688 mbq->bp = 0;
1689 }
1479
1480 HBASTATS.MboxIssued++;
1481 hba->mbox_queue_flag = flag;
1482
1483 /* Set the Mailbox timer */
1484 hba->mbox_timer = hba->timer_tics + tmo;
1485
1486 /* Initialize mailbox */

--- 13 unchanged lines hidden (view full) ---

1500 if (mbq->bp) {
1501 mp = (MATCHMAP *) mbq->bp;
1502 emlxs_mpdata_sync(mp->dma_handle, 0, mp->size,
1503 DDI_DMA_SYNC_FORDEV);
1504
1505 hba->mbox_bp = mbq->bp;
1506 mbq->bp = 0;
1507 }
1508
1690 if (mbq->sbp) {
1691 hba->mbox_sbp = mbq->sbp;
1692 mbq->sbp = 0;
1693 }
1509 if (mbq->sbp) {
1510 hba->mbox_sbp = mbq->sbp;
1511 mbq->sbp = 0;
1512 }
1513
1694 if (mbq->ubp) {
1695 hba->mbox_ubp = mbq->ubp;
1696 mbq->ubp = 0;
1697 }
1514 if (mbq->ubp) {
1515 hba->mbox_ubp = mbq->ubp;
1516 mbq->ubp = 0;
1517 }
1518
1698 if (mbq->iocbq) {
1699 hba->mbox_iocbq = mbq->iocbq;
1700 mbq->iocbq = 0;
1701 }
1702#ifdef MBOX_EXT_SUPPORT
1703 if (mbq->extbuf && mbq->extsize) {
1704 hba->mbox_ext = mbq->extbuf;
1705 hba->mbox_ext_size = mbq->extsize;
1706 }
1519 if (mbq->iocbq) {
1520 hba->mbox_iocbq = mbq->iocbq;
1521 mbq->iocbq = 0;
1522 }
1523#ifdef MBOX_EXT_SUPPORT
1524 if (mbq->extbuf && mbq->extsize) {
1525 hba->mbox_ext = mbq->extbuf;
1526 hba->mbox_ext_size = mbq->extsize;
1527 }
1707#endif /* MBOX_EXT_SUPPORT */
1528#endif /* MBOX_EXT_SUPPORT */
1708
1709 return;
1710
1711} /* emlxs_mb_init() */
1712
1713
1714extern void
1715emlxs_mb_fini(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mbxStatus)
1716{
1529
1530 return;
1531
1532} /* emlxs_mb_init() */
1533
1534
1535extern void
1536emlxs_mb_fini(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mbxStatus)
1537{
1717 emlxs_port_t *port = &PPORT;
1718 MATCHMAP *mbox_bp;
1719 emlxs_buf_t *mbox_sbp;
1720 fc_unsol_buf_t *mbox_ubp;
1721 IOCBQ *mbox_iocbq;
1722 MAILBOXQ *mbox_mbq;
1723 MAILBOX *mbox;
1724 uint32_t mbox_queue_flag;
1725 emlxs_ub_priv_t *ub_priv;
1538 emlxs_port_t *port = &PPORT;
1539 MATCHMAP *mbox_bp;
1540 emlxs_buf_t *mbox_sbp;
1541 fc_unsol_buf_t *mbox_ubp;
1542 IOCBQ *mbox_iocbq;
1543 MAILBOXQ *mbox_mbq;
1544 MAILBOX *mbox;
1545 uint32_t mbox_queue_flag;
1546 emlxs_ub_priv_t *ub_priv;
1726
1727 mutex_enter(&EMLXS_PORT_LOCK);
1728
1729 if (hba->mbox_queue_flag) {
1730 HBASTATS.MboxCompleted++;
1731
1732 if (mbxStatus != MBX_SUCCESS) {
1733 HBASTATS.MboxError++;
1734 } else {
1735 HBASTATS.MboxGood++;
1736 }
1737 }
1547
1548 mutex_enter(&EMLXS_PORT_LOCK);
1549
1550 if (hba->mbox_queue_flag) {
1551 HBASTATS.MboxCompleted++;
1552
1553 if (mbxStatus != MBX_SUCCESS) {
1554 HBASTATS.MboxError++;
1555 } else {
1556 HBASTATS.MboxGood++;
1557 }
1558 }
1738 mbox_bp = (MATCHMAP *) hba->mbox_bp;
1559
1560 mbox_bp = (MATCHMAP *)hba->mbox_bp;
1739 mbox_sbp = (emlxs_buf_t *)hba->mbox_sbp;
1740 mbox_ubp = (fc_unsol_buf_t *)hba->mbox_ubp;
1561 mbox_sbp = (emlxs_buf_t *)hba->mbox_sbp;
1562 mbox_ubp = (fc_unsol_buf_t *)hba->mbox_ubp;
1741 mbox_iocbq = (IOCBQ *) hba->mbox_iocbq;
1742 mbox_mbq = (MAILBOXQ *) hba->mbox_mbq;
1563 mbox_iocbq = (IOCBQ *)hba->mbox_iocbq;
1564 mbox_mbq = (MAILBOXQ *)hba->mbox_mbq;
1743 mbox_queue_flag = hba->mbox_queue_flag;
1744
1745#ifdef MBOX_EXT_SUPPORT
1746 hba->mbox_ext = 0;
1747 hba->mbox_ext_size = 0;
1565 mbox_queue_flag = hba->mbox_queue_flag;
1566
1567#ifdef MBOX_EXT_SUPPORT
1568 hba->mbox_ext = 0;
1569 hba->mbox_ext_size = 0;
1748#endif /* MBOX_EXT_SUPPORT */
1570#endif /* MBOX_EXT_SUPPORT */
1749
1750 hba->mbox_bp = 0;
1751 hba->mbox_sbp = 0;
1752 hba->mbox_ubp = 0;
1753 hba->mbox_iocbq = 0;
1754 hba->mbox_mbqflag = 0;
1755 hba->mbox_mbq = 0;
1756 hba->mbox_timer = 0;
1757 hba->mbox_queue_flag = 0;
1758
1759 mutex_exit(&EMLXS_PORT_LOCK);
1760
1761 if (mbox_mbq) {
1762 if (mb) {
1571
1572 hba->mbox_bp = 0;
1573 hba->mbox_sbp = 0;
1574 hba->mbox_ubp = 0;
1575 hba->mbox_iocbq = 0;
1576 hba->mbox_mbqflag = 0;
1577 hba->mbox_mbq = 0;
1578 hba->mbox_timer = 0;
1579 hba->mbox_queue_flag = 0;
1580
1581 mutex_exit(&EMLXS_PORT_LOCK);
1582
1583 if (mbox_mbq) {
1584 if (mb) {
1763 /*
1764 * Copy the local mailbox provided back into the
1765 * original mailbox
1766 */
1585 /* Copy the local mailbox provided back into */
1586 /* the original mailbox */
1767 bcopy((uint32_t *)mb, (uint32_t *)mbox_mbq,
1768 MAILBOX_CMD_BSIZE);
1769 }
1587 bcopy((uint32_t *)mb, (uint32_t *)mbox_mbq,
1588 MAILBOX_CMD_BSIZE);
1589 }
1770 mbox = (MAILBOX *) mbox_mbq;
1590
1591 mbox = (MAILBOX *)mbox_mbq;
1771 mbox->mbxStatus = mbxStatus;
1772
1773 /* Mark mailbox complete */
1774 mbox_mbq->flag |= MBQ_COMPLETED;
1775
1776 /* Wake up the sleeping thread */
1777 if (mbox_queue_flag == MBX_SLEEP) {
1778 mutex_enter(&EMLXS_MBOX_LOCK);
1779 cv_broadcast(&EMLXS_MBOX_CV);
1780 mutex_exit(&EMLXS_MBOX_LOCK);
1781 }
1782 }
1592 mbox->mbxStatus = mbxStatus;
1593
1594 /* Mark mailbox complete */
1595 mbox_mbq->flag |= MBQ_COMPLETED;
1596
1597 /* Wake up the sleeping thread */
1598 if (mbox_queue_flag == MBX_SLEEP) {
1599 mutex_enter(&EMLXS_MBOX_LOCK);
1600 cv_broadcast(&EMLXS_MBOX_CV);
1601 mutex_exit(&EMLXS_MBOX_LOCK);
1602 }
1603 }
1604
1783 /* Check for deferred MBUF cleanup */
1784 if (mbox_bp && (mbox_queue_flag == MBX_NOWAIT)) {
1785 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mbox_bp);
1786 }
1787#ifdef SFCT_SUPPORT
1788 if (mbox_sbp && mbox_sbp->fct_cmd) {
1789 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1790 "FCT mailbox: %s: status=%x",
1791 emlxs_mb_cmd_xlate(mb->mbxCommand),
1792 (uint32_t)mb->mbxStatus);
1793 }
1605 /* Check for deferred MBUF cleanup */
1606 if (mbox_bp && (mbox_queue_flag == MBX_NOWAIT)) {
1607 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mbox_bp);
1608 }
1609#ifdef SFCT_SUPPORT
1610 if (mbox_sbp && mbox_sbp->fct_cmd) {
1611 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1612 "FCT mailbox: %s: status=%x",
1613 emlxs_mb_cmd_xlate(mb->mbxCommand),
1614 (uint32_t)mb->mbxStatus);
1615 }
1794#endif /* SFCT_SUPPORT */
1616#endif /* SFCT_SUPPORT */
1795
1796 /* Check for deferred pkt completion */
1797 if (mbox_sbp) {
1798 if (mbxStatus != MBX_SUCCESS) {
1799 /* Set error status */
1800 mbox_sbp->pkt_flags &= ~PACKET_STATE_VALID;
1801 emlxs_set_pkt_state(mbox_sbp, IOSTAT_LOCAL_REJECT,
1802 IOERR_NO_RESOURCES, 1);
1803 }
1617
1618 /* Check for deferred pkt completion */
1619 if (mbox_sbp) {
1620 if (mbxStatus != MBX_SUCCESS) {
1621 /* Set error status */
1622 mbox_sbp->pkt_flags &= ~PACKET_STATE_VALID;
1623 emlxs_set_pkt_state(mbox_sbp, IOSTAT_LOCAL_REJECT,
1624 IOERR_NO_RESOURCES, 1);
1625 }
1626
1804 emlxs_pkt_complete(mbox_sbp, -1, 0, 1);
1805 }
1627 emlxs_pkt_complete(mbox_sbp, -1, 0, 1);
1628 }
1629
1806 /* Check for deferred ub completion */
1807 if (mbox_ubp) {
1808 ub_priv = mbox_ubp->ub_fca_private;
1809 port = ub_priv->port;
1810
1811 emlxs_ub_callback(port, mbox_ubp);
1812 }
1630 /* Check for deferred ub completion */
1631 if (mbox_ubp) {
1632 ub_priv = mbox_ubp->ub_fca_private;
1633 port = ub_priv->port;
1634
1635 emlxs_ub_callback(port, mbox_ubp);
1636 }
1637
1813 /* Check for deferred iocb tx */
1814 if (mbox_iocbq) {
1638 /* Check for deferred iocb tx */
1639 if (mbox_iocbq) {
1815 emlxs_issue_iocb_cmd(hba, mbox_iocbq->ring, mbox_iocbq);
1640 emlxs_sli_issue_iocb_cmd(hba, mbox_iocbq->ring, mbox_iocbq);
1816 }
1641 }
1642
1817 return;
1818
1819} /* emlxs_mb_fini() */
1820
1821
1822
1823/* This should only be called with active MBX_NOWAIT mailboxes */
1643 return;
1644
1645} /* emlxs_mb_fini() */
1646
1647
1648
1649/* This should only be called with active MBX_NOWAIT mailboxes */
1824static void
1650void
1825emlxs_mb_retry(emlxs_hba_t *hba, MAILBOX *mb)
1826{
1651emlxs_mb_retry(emlxs_hba_t *hba, MAILBOX *mb)
1652{
1827 MAILBOXQ *mbq;
1653 MAILBOXQ *mbq;
1828
1829 mutex_enter(&EMLXS_PORT_LOCK);
1830
1831 HBASTATS.MboxCompleted++;
1832
1833 if (mb->mbxStatus != 0) {
1834 HBASTATS.MboxError++;
1835 } else {
1836 HBASTATS.MboxGood++;
1837 }
1838
1654
1655 mutex_enter(&EMLXS_PORT_LOCK);
1656
1657 HBASTATS.MboxCompleted++;
1658
1659 if (mb->mbxStatus != 0) {
1660 HBASTATS.MboxError++;
1661 } else {
1662 HBASTATS.MboxGood++;
1663 }
1664
1839 mbq = (MAILBOXQ *) mb;
1665 mbq = (MAILBOXQ *)mb;
1840 mbq->bp = (uint8_t *)hba->mbox_bp;
1841 mbq->sbp = (uint8_t *)hba->mbox_sbp;
1842 mbq->ubp = (uint8_t *)hba->mbox_ubp;
1843 mbq->iocbq = (uint8_t *)hba->mbox_iocbq;
1844
1845 hba->mbox_bp = 0;
1846 hba->mbox_sbp = 0;
1847 hba->mbox_ubp = 0;

--- 4 unchanged lines hidden (view full) ---

1852
1853 mutex_exit(&EMLXS_PORT_LOCK);
1854
1855 return;
1856
1857} /* emlxs_mb_retry() */
1858
1859
1666 mbq->bp = (uint8_t *)hba->mbox_bp;
1667 mbq->sbp = (uint8_t *)hba->mbox_sbp;
1668 mbq->ubp = (uint8_t *)hba->mbox_ubp;
1669 mbq->iocbq = (uint8_t *)hba->mbox_iocbq;
1670
1671 hba->mbox_bp = 0;
1672 hba->mbox_sbp = 0;
1673 hba->mbox_ubp = 0;

--- 4 unchanged lines hidden (view full) ---

1678
1679 mutex_exit(&EMLXS_PORT_LOCK);
1680
1681 return;
1682
1683} /* emlxs_mb_retry() */
1684
1685
1860
1861/*
1862 * emlxs_handle_mb_event
1863 *
1864 * Description: Process a Mailbox Attention.
1865 * Called from host_interrupt to process MBATT
1866 *
1867 * Returns:
1868 *
1869 */
1870extern uint32_t
1871emlxs_handle_mb_event(emlxs_hba_t *hba)
1872{
1873 emlxs_port_t *port = &PPORT;
1874 MAILBOX *mb;
1875 MAILBOX *swpmb;
1876 MAILBOX *mbox;
1877 MAILBOXQ *mbq;
1878 emlxs_config_t *cfg;
1879 uint32_t control;
1880 volatile uint32_t word0;
1881 MATCHMAP *mbox_bp;
1882 uint32_t la_enable;
1883 off_t offset;
1884 uint32_t i;
1885 MAILBOXQ mailbox;
1886
1887 cfg = &CFG;
1888 swpmb = (MAILBOX *) & word0;
1889 mb = (MAILBOX *) & mailbox;
1890
1891 switch (hba->mbox_queue_flag) {
1892 case 0:
1893 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg,
1894 "No mailbox active.");
1895 return (0);
1896
1897 case MBX_POLL:
1898
1899 /*
1900 * Mark mailbox complete, this should wake up any polling
1901 * threads
1902 */
1903 /*
1904 * This can happen if interrupts are enabled while a polled
1905 * mailbox command is outstanding
1906 */
1907 /*
1908 * If we don't set MBQ_COMPLETED here, the polling thread may
1909 * wait until timeout error occurs
1910 */
1911
1912 mutex_enter(&EMLXS_MBOX_LOCK);
1913 mbq = (MAILBOXQ *) hba->mbox_mbq;
1914 if (mbq) {
1915 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
1916 "Mailbox event. Completing Polled command.");
1917 mbq->flag |= MBQ_COMPLETED;
1918 }
1919 mutex_exit(&EMLXS_MBOX_LOCK);
1920
1921 return (0);
1922
1923 case MBX_SLEEP:
1924 case MBX_NOWAIT:
1925 break;
1926
1927 default:
1928 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg,
1929 "Invalid Mailbox flag (%x).");
1930 return (0);
1931 }
1932
1933 /* Get first word of mailbox */
1934 if (hba->flag & FC_SLIM2_MODE) {
1935 mbox = FC_SLIM2_MAILBOX(hba);
1936 offset = (off_t)((uint64_t)(unsigned long)mbox -
1937 (uint64_t)(unsigned long)hba->slim2.virt);
1938
1939 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
1940 sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
1941 word0 = *((volatile uint32_t *) mbox);
1942 word0 = PCIMEM_LONG(word0);
1943 } else {
1944 mbox = FC_SLIM1_MAILBOX(hba);
1945 word0 = READ_SLIM_ADDR(hba, ((volatile uint32_t *) mbox));
1946 }
1947
1948 i = 0;
1949 while (swpmb->mbxOwner == OWN_CHIP) {
1950 if (i++ > 10000) {
1951 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg,
1952 "OWN_CHIP: %s: status=%x",
1953 emlxs_mb_cmd_xlate(swpmb->mbxCommand),
1954 swpmb->mbxStatus);
1955
1956 return (1);
1957 }
1958 /* Get first word of mailbox */
1959 if (hba->flag & FC_SLIM2_MODE) {
1960 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
1961 sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
1962 word0 = *((volatile uint32_t *) mbox);
1963 word0 = PCIMEM_LONG(word0);
1964 } else {
1965 word0 = READ_SLIM_ADDR(hba,
1966 ((volatile uint32_t *) mbox));
1967 }
1968 }
1969
1970 /* Now that we are the owner, DMA Sync entire mailbox if needed */
1971 if (hba->flag & FC_SLIM2_MODE) {
1972 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
1973 MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL);
1974 emlxs_pcimem_bcopy((uint32_t *)mbox, (uint32_t *)mb,
1975 MAILBOX_CMD_BSIZE);
1976 } else {
1977 READ_SLIM_COPY(hba, (uint32_t *)mb, (uint32_t *)mbox,
1978 MAILBOX_CMD_WSIZE);
1979 }
1980
1981#ifdef MBOX_EXT_SUPPORT
1982 if (hba->mbox_ext) {
1983 uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox +
1984 MBOX_EXTENSION_OFFSET);
1985 off_t offset_ext = offset + MBOX_EXTENSION_OFFSET;
1986
1987 if (hba->flag & FC_SLIM2_MODE) {
1988 emlxs_mpdata_sync(hba->slim2.dma_handle, offset_ext,
1989 hba->mbox_ext_size, DDI_DMA_SYNC_FORKERNEL);
1990 emlxs_pcimem_bcopy(mbox_ext, (uint32_t *)hba->mbox_ext,
1991 hba->mbox_ext_size);
1992 } else {
1993 READ_SLIM_COPY(hba, (uint32_t *)hba->mbox_ext, mbox_ext,
1994 (hba->mbox_ext_size / 4));
1995 }
1996 }
1997#endif /* MBOX_EXT_SUPPORT */
1998
1999 /* Now sync the memory buffer if one was used */
2000 if (hba->mbox_bp) {
2001 mbox_bp = (MATCHMAP *) hba->mbox_bp;
2002 emlxs_mpdata_sync(mbox_bp->dma_handle, 0, mbox_bp->size,
2003 DDI_DMA_SYNC_FORKERNEL);
2004 }
2005 /* Mailbox has been completely received at this point */
2006
2007 if (mb->mbxCommand == MBX_HEARTBEAT) {
2008 hba->heartbeat_active = 0;
2009 goto done;
2010 }
2011 if (hba->mbox_queue_flag == MBX_SLEEP) {
2012 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
2013 "Received. %s: status=%x Sleep.",
2014 emlxs_mb_cmd_xlate(swpmb->mbxCommand), swpmb->mbxStatus);
2015 } else {
2016 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
2017 "Completed. %s: status=%x",
2018 emlxs_mb_cmd_xlate(swpmb->mbxCommand), swpmb->mbxStatus);
2019 }
2020
2021 /* Filter out passthru mailbox */
2022 if (hba->mbox_mbqflag & MBQ_PASSTHRU) {
2023 goto done;
2024 }
2025 /* If succesful, process the result */
2026 if (mb->mbxStatus == 0) {
2027 (void) emlxs_mb_handle_cmd(hba, mb);
2028 goto done;
2029 }
2030 /* ERROR RETURNED */
2031
2032 /* Check for no resources */
2033 if ((mb->mbxStatus == MBXERR_NO_RESOURCES) &&
2034 (hba->mbox_queue_flag == MBX_NOWAIT)) {
2035 /* Retry only MBX_NOWAIT requests */
2036
2037 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
2038 "Retrying. %s: status=%x",
2039 emlxs_mb_cmd_xlate(mb->mbxCommand),
2040 (uint32_t)mb->mbxStatus);
2041
2042 if ((mbox = (MAILBOX *) emlxs_mem_get(hba, MEM_MBOX))) {
2043 bcopy((uint8_t *)mb, (uint8_t *)mbox,
2044 MAILBOX_CMD_BSIZE);
2045
2046 switch (mbox->mbxCommand) {
2047 case MBX_READ_SPARM:
2048 control = mbox->un.varRdSparm.un.sp.bdeSize;
2049 if (control == 0) {
2050 (void) emlxs_mb_read_sparam(hba, mbox);
2051 }
2052 break;
2053
2054 case MBX_READ_SPARM64:
2055 control = mbox->un.varRdSparm.un.sp64.tus.f.
2056 bdeSize;
2057 if (control == 0) {
2058 (void) emlxs_mb_read_sparam(hba, mbox);
2059 }
2060 break;
2061
2062 case MBX_REG_LOGIN:
2063 control = mbox->un.varRegLogin.un.sp.bdeSize;
2064 if (control == 0) {
2065#ifdef NPIV_SUPPORT
2066 /* Special handle for vport PLOGI */
2067 if (hba->mbox_iocbq == (uint8_t *)1) {
2068 hba->mbox_iocbq = NULL;
2069 }
2070#endif /* NPIV_SUPPORT */
2071 goto done;
2072 }
2073 break;
2074
2075 case MBX_REG_LOGIN64:
2076 control = mbox->un.varRegLogin.un.sp64.tus.f.
2077 bdeSize;
2078 if (control == 0) {
2079#ifdef NPIV_SUPPORT
2080 /* Special handle for vport PLOGI */
2081 if (hba->mbox_iocbq == (uint8_t *)1) {
2082 hba->mbox_iocbq = NULL;
2083 }
2084#endif /* NPIV_SUPPORT */
2085 goto done;
2086 }
2087 break;
2088
2089 case MBX_READ_LA:
2090 control = mbox->un.varReadLA.un.lilpBde.bdeSize;
2091 if (control == 0) {
2092 (void) emlxs_mb_read_la(hba, mbox);
2093 }
2094 break;
2095
2096 case MBX_READ_LA64:
2097 control = mbox->un.varReadLA.un.lilpBde64.tus.f.
2098 bdeSize;
2099 if (control == 0) {
2100 (void) emlxs_mb_read_la(hba, mbox);
2101 }
2102 break;
2103 }
2104
2105 mbox->mbxOwner = OWN_HOST;
2106 mbox->mbxStatus = 0;
2107
2108 /* Refresh the mailbox area */
2109 emlxs_mb_retry(hba, mbox);
2110
2111 if (emlxs_mb_issue_cmd(hba, mbox, MBX_NOWAIT, 0) !=
2112 MBX_BUSY) {
2113 (void) emlxs_mem_put(hba, MEM_MBOX,
2114 (uint8_t *)mbox);
2115 }
2116 return (0);
2117 }
2118 }
2119 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg,
2120 "%s: status=0x%x", emlxs_mb_cmd_xlate(mb->mbxCommand),
2121 (uint32_t)mb->mbxStatus);
2122
2123 /*
2124 * ERROR: process mailbox command error
2125 */
2126 switch (mb->mbxCommand) {
2127 case MBX_REG_LOGIN:
2128 case MBX_REG_LOGIN64:
2129
2130 if (mb->mbxStatus == MBXERR_RPI_FULL) {
2131#ifdef SLI3_SUPPORT
2132 port = &VPORT(mb->un.varRegLogin.vpi);
2133#endif /* SLI3_SUPPORT */
2134
2135 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2136 "Limit reached. count=%d", port->node_count);
2137 }
2138#ifdef NPIV_SUPPORT
2139 /* Special handle for vport PLOGI */
2140 if (hba->mbox_iocbq == (uint8_t *)1) {
2141 hba->mbox_iocbq = NULL;
2142 }
2143#endif /* NPIV_SUPPORT */
2144 break;
2145
2146 case MBX_READ_LA:
2147 case MBX_READ_LA64:
2148
2149 /* Enable Link Attention interrupts */
2150 mutex_enter(&EMLXS_PORT_LOCK);
2151
2152 if (!(hba->hc_copy & HC_LAINT_ENA)) {
2153 /*
2154 * hba->hc_copy = READ_CSR_REG(hba, FC_HC_REG(hba,
2155 * hba->csr_addr));
2156 */
2157 hba->hc_copy |= HC_LAINT_ENA;
2158 WRITE_CSR_REG(hba, FC_HC_REG(hba, hba->csr_addr),
2159 hba->hc_copy);
2160 }
2161 mutex_exit(&EMLXS_PORT_LOCK);
2162
2163 break;
2164
2165
2166 case MBX_CLEAR_LA:
2167
2168 la_enable = 1;
2169
2170 if (mb->mbxStatus == 0x1601) {
2171 /*
2172 * Get a buffer which will be used for mailbox
2173 * commands
2174 */
2175 if ((mbox = (MAILBOX *) emlxs_mem_get(hba, MEM_MBOX |
2176 MEM_PRI))) {
2177 /* Get link attention message */
2178 if (emlxs_mb_read_la(hba, mbox) == 0) {
2179 if (emlxs_mb_issue_cmd(hba, mbox,
2180 MBX_NOWAIT, 0) != MBX_BUSY) {
2181 (void) emlxs_mem_put(hba,
2182 MEM_MBOX, (uint8_t *)mbox);
2183 }
2184 la_enable = 0;
2185 } else {
2186 (void) emlxs_mem_put(hba, MEM_MBOX,
2187 (uint8_t *)mbox);
2188 }
2189 }
2190 }
2191 mutex_enter(&EMLXS_PORT_LOCK);
2192 if (la_enable) {
2193 if (!(hba->hc_copy & HC_LAINT_ENA)) {
2194 /* Enable Link Attention interrupts */
2195 /*
2196 * hba->hc_copy = READ_CSR_REG(hba,
2197 * FC_HC_REG(hba, hba->csr_addr));
2198 */
2199 hba->hc_copy |= HC_LAINT_ENA;
2200 WRITE_CSR_REG(hba,
2201 FC_HC_REG(hba, hba->csr_addr),
2202 hba->hc_copy);
2203 }
2204 } else {
2205 if (hba->hc_copy & HC_LAINT_ENA) {
2206 /* Disable Link Attention interrupts */
2207 /*
2208 * hba->hc_copy = READ_CSR_REG(hba,
2209 * FC_HC_REG(hba, hba->csr_addr));
2210 */
2211 hba->hc_copy &= ~HC_LAINT_ENA;
2212 WRITE_CSR_REG(hba,
2213 FC_HC_REG(hba, hba->csr_addr),
2214 hba->hc_copy);
2215 }
2216 }
2217 mutex_exit(&EMLXS_PORT_LOCK);
2218
2219 break;
2220
2221 case MBX_INIT_LINK:
2222 if ((hba->flag & FC_SLIM2_MODE) &&
2223 (hba->mbox_queue_flag == MBX_NOWAIT)) {
2224 /* Retry only MBX_NOWAIT requests */
2225
2226 if ((cfg[CFG_LINK_SPEED].current > 0) &&
2227 ((mb->mbxStatus == 0x0011) ||
2228 (mb->mbxStatus == 0x0500))) {
2229 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
2230 "Retrying. %s: status=%x. Auto-speed set.",
2231 emlxs_mb_cmd_xlate(mb->mbxCommand),
2232 (uint32_t)mb->mbxStatus);
2233
2234 if ((mbox = (MAILBOX *) emlxs_mem_get(hba,
2235 MEM_MBOX))) {
2236 bcopy((uint8_t *)mb, (uint8_t *)mbox,
2237 MAILBOX_CMD_BSIZE);
2238
2239 mbox->un.varInitLnk.link_flags &=
2240 ~FLAGS_LINK_SPEED;
2241 mbox->un.varInitLnk.link_speed = 0;
2242 mbox->mbxOwner = OWN_HOST;
2243 mbox->mbxStatus = 0;
2244
2245 /* Refresh the mailbox area */
2246 emlxs_mb_retry(hba, mbox);
2247
2248 if (emlxs_mb_issue_cmd(hba, mbox,
2249 MBX_NOWAIT, 0) != MBX_BUSY) {
2250 (void) emlxs_mem_put(hba,
2251 MEM_MBOX, (uint8_t *)mbox);
2252 }
2253 return (0);
2254 }
2255 }
2256 }
2257 break;
2258 }
2259
2260done:
2261
2262 /* Clean up the mailbox area */
2263 emlxs_mb_fini(hba, mb, mb->mbxStatus);
2264
2265 /* Attempt to send pending mailboxes */
2266 if ((mbox = (MAILBOX *) emlxs_mb_get(hba))) {
2267 if (emlxs_mb_issue_cmd(hba, mbox, MBX_NOWAIT, 0) != MBX_BUSY) {
2268 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox);
2269 }
2270 }
2271 return (0);
2272
2273} /* emlxs_handle_mb_event() */
2274
2275
2276
2277/*
2278 * emlxs_mb_handle_cmd
2279 *
2280 * Description: Process a Mailbox Command.
2281 * Called from host_interrupt to process MBATT
2282 *
2283 * Returns:
2284 *
2285 */
2286static int
2287emlxs_mb_handle_cmd(emlxs_hba_t *hba, MAILBOX *mb)
2288{
2289 emlxs_port_t *port = &PPORT;
2290 emlxs_port_t *vport;
2291 MAILBOXQ *mbox;
2292 NODELIST *ndlp;
2293 volatile SERV_PARM *sp;
2294 int32_t i;
2295 uint32_t ldata;
2296 uint32_t ldid;
2297 uint16_t lrpi;
2298 uint16_t lvpi;
2299 MATCHMAP *mp;
2300 uint8_t *wwn;
2301 READ_LA_VAR la;
2302
2303 if (mb->mbxStatus != 0) {
2304 return (1);
2305 }
2306 mp = (MATCHMAP *) hba->mbox_bp;
2307
2308 /*
2309 * Mailbox command completed successfully, process completion
2310 */
2311 switch (mb->mbxCommand) {
2312 case MBX_SHUTDOWN:
2313 case MBX_LOAD_SM:
2314 case MBX_READ_NV:
2315 case MBX_WRITE_NV:
2316 case MBX_RUN_BIU_DIAG:
2317 case MBX_RUN_BIU_DIAG64:
2318 case MBX_INIT_LINK:
2319 case MBX_DOWN_LINK:
2320 case MBX_CONFIG_LINK:
2321 case MBX_PART_SLIM:
2322 case MBX_CONFIG_RING:
2323 case MBX_RESET_RING:
2324 case MBX_READ_CONFIG:
2325 case MBX_READ_RCONFIG:
2326 case MBX_READ_STATUS:
2327 case MBX_READ_XRI:
2328 case MBX_READ_REV:
2329 case MBX_READ_LNK_STAT:
2330 case MBX_UNREG_LOGIN:
2331 case MBX_DUMP_MEMORY:
2332 case MBX_DUMP_CONTEXT:
2333 case MBX_RUN_DIAGS:
2334 case MBX_RESTART:
2335 case MBX_UPDATE_CFG:
2336 case MBX_DOWN_LOAD:
2337 case MBX_DEL_LD_ENTRY:
2338 case MBX_RUN_PROGRAM:
2339 case MBX_SET_MASK:
2340 case MBX_SET_VARIABLE:
2341 case MBX_UNREG_D_ID:
2342 case MBX_KILL_BOARD:
2343 case MBX_CONFIG_FARP:
2344 case MBX_LOAD_AREA:
2345 case MBX_CONFIG_PORT:
2346 case MBX_CONFIG_MSI:
2347 case MBX_FLASH_WR_ULA:
2348 case MBX_SET_DEBUG:
2349 case MBX_GET_DEBUG:
2350 case MBX_LOAD_EXP_ROM:
2351 case MBX_BEACON:
2352 case MBX_READ_RPI:
2353 case MBX_READ_RPI64:
2354 case MBX_REG_VPI:
2355 case MBX_UNREG_VPI:
2356 case MBX_CONFIG_HBQ:
2357 case MBX_ASYNC_EVENT:
2358 case MBX_HEARTBEAT:
2359 break;
2360
2361 case MBX_CONFIG_MSIX:
2362 break;
2363
2364 case MBX_READ_SPARM: /* a READ SPARAM command completed */
2365 case MBX_READ_SPARM64: /* a READ SPARAM command completed */
2366 {
2367 if (mp) {
2368 bcopy((caddr_t)mp->virt, (caddr_t)& hba->sparam,
2369 sizeof (SERV_PARM));
2370
2371 bcopy((caddr_t)& hba->sparam.nodeName,
2372 (caddr_t)& hba->wwnn,
2373 sizeof (NAME_TYPE));
2374
2375 bcopy((caddr_t)& hba->sparam.portName,
2376 (caddr_t)& hba->wwpn,
2377 sizeof (NAME_TYPE));
2378
2379 /* Initialize the physical port */
2380 bcopy((caddr_t)& hba->sparam,
2381 (caddr_t)& port->sparam,
2382 sizeof (SERV_PARM));
2383 bcopy((caddr_t)& hba->wwpn,
2384 (caddr_t)& port->wwpn, sizeof (NAME_TYPE));
2385 bcopy((caddr_t)& hba->wwnn,
2386 (caddr_t)& port->wwnn, sizeof (NAME_TYPE));
2387
2388 /* Initialize the virtual ports */
2389 for (i = 1; i < MAX_VPORTS; i++) {
2390 vport = &VPORT(i);
2391 if (vport->flag & EMLXS_PORT_BOUND) {
2392 continue;
2393 }
2394 bcopy((caddr_t)& hba->sparam,
2395 (caddr_t)& vport->sparam,
2396 sizeof (SERV_PARM));
2397
2398 bcopy((caddr_t)& vport->wwnn,
2399 (caddr_t)& vport->sparam.nodeName,
2400 sizeof (NAME_TYPE));
2401
2402 bcopy((caddr_t)& vport->wwpn,
2403 (caddr_t)& vport->sparam.portName,
2404 sizeof (NAME_TYPE));
2405 }
2406
2407 }
2408 break;
2409 }
2410
2411
2412 case MBX_REG_LOGIN:
2413 case MBX_REG_LOGIN64:
2414
2415 if (!mp) {
2416 break;
2417 }
2418#ifdef SLI3_SUPPORT
2419 ldata = mb->un.varWords[5];
2420 lvpi = ldata & 0xffff;
2421 port = &VPORT(lvpi);
2422#endif /* SLI3_SUPPORT */
2423
2424 /* First copy command data */
2425 ldata = mb->un.varWords[0]; /* get rpi */
2426 lrpi = ldata & 0xffff;
2427
2428 ldata = mb->un.varWords[1]; /* get did */
2429 ldid = ldata & Mask_DID;
2430
2431 sp = (volatile SERV_PARM *) mp->virt;
2432 ndlp = emlxs_node_find_did(port, ldid);
2433
2434 if (!ndlp) {
2435 /* Attempt to create a node */
2436 if ((ndlp = (NODELIST *) emlxs_mem_get(hba, MEM_NLP))) {
2437 ndlp->nlp_Rpi = lrpi;
2438 ndlp->nlp_DID = ldid;
2439
2440 bcopy((uint8_t *)sp,
2441 (uint8_t *)& ndlp->sparm,
2442 sizeof (SERV_PARM));
2443
2444 bcopy((uint8_t *)& sp->nodeName,
2445 (uint8_t *)& ndlp->nlp_nodename,
2446 sizeof (NAME_TYPE));
2447
2448 bcopy((uint8_t *)& sp->portName,
2449 (uint8_t *)& ndlp->nlp_portname,
2450 sizeof (NAME_TYPE));
2451
2452 ndlp->nlp_active = 1;
2453 ndlp->nlp_flag[FC_CT_RING] |= NLP_CLOSED;
2454 ndlp->nlp_flag[FC_ELS_RING] |= NLP_CLOSED;
2455 ndlp->nlp_flag[FC_FCP_RING] |= NLP_CLOSED;
2456 ndlp->nlp_flag[FC_IP_RING] |= NLP_CLOSED;
2457
2458 /* Add the node */
2459 emlxs_node_add(port, ndlp);
2460
2461 /* Open the node */
2462 emlxs_node_open(port, ndlp, FC_CT_RING);
2463 emlxs_node_open(port, ndlp, FC_ELS_RING);
2464 emlxs_node_open(port, ndlp, FC_IP_RING);
2465 emlxs_node_open(port, ndlp, FC_FCP_RING);
2466 } else {
2467 wwn = (uint8_t *)& sp->portName;
2468 EMLXS_MSGF(EMLXS_CONTEXT,
2469 &emlxs_node_create_failed_msg,
2470 "Unable to allocate node. did=%06x rpi=%x "
2471 "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
2472 ldid, lrpi, wwn[0], wwn[1], wwn[2], wwn[3],
2473 wwn[4], wwn[5], wwn[6], wwn[7]);
2474
2475 break;
2476 }
2477 } else {
2478 mutex_enter(&EMLXS_PORT_LOCK);
2479
2480 ndlp->nlp_Rpi = lrpi;
2481 ndlp->nlp_DID = ldid;
2482
2483 bcopy((uint8_t *)sp,
2484 (uint8_t *)& ndlp->sparm,
2485 sizeof (SERV_PARM));
2486
2487 bcopy((uint8_t *)& sp->nodeName,
2488 (uint8_t *)& ndlp->nlp_nodename,
2489 sizeof (NAME_TYPE));
2490
2491 bcopy((uint8_t *)& sp->portName,
2492 (uint8_t *)& ndlp->nlp_portname,
2493 sizeof (NAME_TYPE));
2494
2495 wwn = (uint8_t *)& ndlp->nlp_portname;
2496 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg,
2497 "node=%p did=%06x rpi=%x wwpn="
2498 "%02x%02x%02x%02x%02x%02x%02x%02x",
2499 ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0], wwn[1],
2500 wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
2501
2502 mutex_exit(&EMLXS_PORT_LOCK);
2503
2504 /* Open the node */
2505 emlxs_node_open(port, ndlp, FC_CT_RING);
2506 emlxs_node_open(port, ndlp, FC_ELS_RING);
2507 emlxs_node_open(port, ndlp, FC_IP_RING);
2508 emlxs_node_open(port, ndlp, FC_FCP_RING);
2509 }
2510
2511 /* If this was a fabric login */
2512 if (ndlp->nlp_DID == Fabric_DID) {
2513 /*
2514 * If CLEAR_LA has been sent, then attempt to
2515 * register the vpi now
2516 */
2517 if (hba->state == FC_READY) {
2518 (void) emlxs_mb_reg_vpi(port);
2519 }
2520#ifdef SLI3_SUPPORT
2521 /*
2522 * If NPIV Fabric support has just been established
2523 * on the physical port, then notify the vports of
2524 * the link up
2525 */
2526 if ((lvpi == 0) &&
2527 (hba->flag & FC_NPIV_ENABLED) &&
2528 (hba->flag & FC_NPIV_SUPPORTED)) {
2529 /* Skip the physical port */
2530 for (i = 1; i < MAX_VPORTS; i++) {
2531 vport = &VPORT(i);
2532
2533 if (!(vport->flag & EMLXS_PORT_BOUND) ||
2534 !(vport->flag &
2535 EMLXS_PORT_ENABLE)) {
2536 continue;
2537 }
2538 emlxs_port_online(vport);
2539 }
2540 }
2541#endif /* SLI3_SUPPORT */
2542
2543 }
2544#ifdef NPIV_SUPPORT
2545 if (hba->mbox_iocbq == (uint8_t *)1) {
2546 hba->mbox_iocbq = NULL;
2547 (void) emlxs_mb_unreg_did(port, ldid, NULL, NULL, NULL);
2548 }
2549#endif /* NPIV_SUPPORT */
2550
2551#ifdef DHCHAP_SUPPORT
2552 if (hba->mbox_sbp || hba->mbox_ubp) {
2553 if (emlxs_dhc_auth_start(port, ndlp, hba->mbox_sbp,
2554 hba->mbox_ubp) == 0) {
2555 /*
2556 * Auth started - auth completion will handle
2557 * sbp and ubp now
2558 */
2559 hba->mbox_sbp = NULL;
2560 hba->mbox_ubp = NULL;
2561 }
2562 }
2563#endif /* DHCHAP_SUPPORT */
2564
2565#ifdef SFCT_SUPPORT
2566 if (hba->mbox_sbp && ((emlxs_buf_t *)hba->mbox_sbp)->fct_cmd) {
2567 emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)hba->mbox_sbp;
2568
2569 if (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) {
2570 hba->mbox_sbp = NULL;
2571
2572 mutex_enter(&EMLXS_PKT_LOCK);
2573 cmd_sbp->node = ndlp;
2574 cmd_sbp->fct_state = EMLXS_FCT_REG_COMPLETE;
2575 cv_broadcast(&EMLXS_PKT_CV);
2576 mutex_exit(&EMLXS_PKT_LOCK);
2577 }
2578 }
2579#endif /* SFCT_SUPPORT */
2580
2581 break;
2582
2583 case MBX_READ_LA:
2584 case MBX_READ_LA64:
2585 bcopy((uint32_t *)((char *)mb + sizeof (uint32_t)),
2586 (uint32_t *)& la, sizeof (READ_LA_VAR));
2587
2588 if (mp) {
2589 bcopy((caddr_t)mp->virt,
2590 (caddr_t)port->alpa_map, 128);
2591 } else {
2592 bzero((caddr_t)port->alpa_map, 128);
2593 }
2594
2595 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_atten_msg,
2596 "type=%s tag=%d -> %d ALPA=%x",
2597 ((la.attType == AT_LINK_UP) ?
2598 "LinkUp" : "LinkDown"),
2599 (uint32_t)hba->link_event_tag,
2600 (uint32_t)la.eventTag, (uint32_t)la.granted_AL_PA);
2601
2602 if (la.pb) {
2603 hba->flag |= FC_BYPASSED_MODE;
2604 } else {
2605 hba->flag &= ~FC_BYPASSED_MODE;
2606 }
2607
2608 if (hba->link_event_tag == la.eventTag) {
2609 HBASTATS.LinkMultiEvent++;
2610 } else if (hba->link_event_tag + 1 < la.eventTag) {
2611 HBASTATS.LinkMultiEvent++;
2612
2613 if (hba->state > FC_LINK_DOWN) {
2614 /* Declare link down here */
2615 emlxs_linkdown(hba);
2616 }
2617 }
2618 hba->link_event_tag = la.eventTag;
2619 port->lip_type = 0;
2620
2621 /* If link not already up then declare it up now */
2622 if ((la.attType == AT_LINK_UP) &&
2623 (hba->state < FC_LINK_UP)) {
2624
2625 /* Save the linkspeed */
2626 hba->linkspeed = la.UlnkSpeed;
2627
2628 /*
2629 * Check for old model adapters that only
2630 * supported 1Gb
2631 */
2632 if ((hba->linkspeed == 0) &&
2633 (hba->model_info.chip &
2634 EMLXS_DRAGONFLY_CHIP)) {
2635 hba->linkspeed = LA_1GHZ_LINK;
2636 }
2637 if ((hba->topology = la.topology) ==
2638 TOPOLOGY_LOOP) {
2639 port->did = la.granted_AL_PA;
2640 port->lip_type = la.lipType;
2641
2642 if (hba->flag & FC_SLIM2_MODE) {
2643 i = la.un.lilpBde64.tus.f.
2644 bdeSize;
2645 } else {
2646 i = la.un.lilpBde.bdeSize;
2647 }
2648
2649 if (i == 0) {
2650 port->alpa_map[0] = 0;
2651 } else {
2652 uint8_t *alpa_map;
2653 uint32_t j;
2654
2655 /*
2656 * Check number of devices in
2657 * map
2658 */
2659 if (port->alpa_map[0] > 127) {
2660 port->alpa_map[0] = 127;
2661 }
2662 alpa_map = (uint8_t *)port->alpa_map;
2663
2664 EMLXS_MSGF(EMLXS_CONTEXT,
2665 &emlxs_link_atten_msg,
2666 "alpa_map: %d device(s): %02x "
2667 "%02x %02x %02x %02x %02x %02x",
2668 alpa_map[0], alpa_map[1],
2669 alpa_map[2], alpa_map[3],
2670 alpa_map[4], alpa_map[5],
2671 alpa_map[6], alpa_map[7]);
2672
2673 for (j = 8; j <= alpa_map[0]; j += 8) {
2674 EMLXS_MSGF(EMLXS_CONTEXT,
2675 &emlxs_link_atten_msg,
2676 "alpa_map: %02x %02x %02x "
2677 "%02x %02x %02x %02x %02x",
2678 alpa_map[j],
2679 alpa_map[j + 1],
2680 alpa_map[j + 2],
2681 alpa_map[j + 3],
2682 alpa_map[j + 4],
2683 alpa_map[j + 5],
2684 alpa_map[j + 6],
2685 alpa_map[j + 7]);
2686 }
2687 }
2688 }
2689#ifdef MENLO_SUPPORT
2690 /* Check if Menlo maintenance mode is enabled */
2691 if (hba->model_info.device_id ==
2692 PCI_DEVICE_ID_LP21000_M) {
2693 if (la.mm == 1) {
2694 EMLXS_MSGF(EMLXS_CONTEXT,
2695 &emlxs_link_atten_msg,
2696 "Maintenance Mode enabled.");
2697
2698 mutex_enter(&EMLXS_PORT_LOCK);
2699 hba->flag |= FC_MENLO_MODE;
2700 mutex_exit(&EMLXS_PORT_LOCK);
2701
2702 mutex_enter(&EMLXS_LINKUP_LOCK);
2703 cv_broadcast(&EMLXS_LINKUP_CV);
2704 mutex_exit(&EMLXS_LINKUP_LOCK);
2705 } else {
2706 EMLXS_MSGF(EMLXS_CONTEXT,
2707 &emlxs_link_atten_msg,
2708 "Maintenance Mode disabled.");
2709 }
2710
2711 /* Check FCoE attention bit */
2712 if (la.fa == 1) {
2713 (void) thread_create(NULL, 0,
2714 emlxs_fcoe_attention_thread,
2715 (char *)hba, 0,
2716 &p0, TS_RUN,
2717 v.v_maxsyspri - 2);
2718 }
2719 }
2720#endif /* MENLO_SUPPORT */
2721
2722 if ((mbox = (MAILBOXQ *) emlxs_mem_get(hba,
2723 MEM_MBOX | MEM_PRI))) {
2724 /*
2725 * This should turn on DELAYED ABTS
2726 * for ELS timeouts
2727 */
2728 emlxs_mb_set_var(hba, (MAILBOX *) mbox,
2729 0x00052198, 0x1);
2730
2731 emlxs_mb_put(hba, mbox);
2732 }
2733 if ((mbox = (MAILBOXQ *) emlxs_mem_get(hba,
2734 MEM_MBOX | MEM_PRI))) {
2735 /*
2736 * If link not already down then
2737 * declare it down now
2738 */
2739 if (emlxs_mb_read_sparam(hba,
2740 (MAILBOX *) mbox) == 0) {
2741 emlxs_mb_put(hba, mbox);
2742 } else {
2743 (void) emlxs_mem_put(hba, MEM_MBOX,
2744 (uint8_t *)mbox);
2745 }
2746 }
2747 if ((mbox = (MAILBOXQ *) emlxs_mem_get(hba,
2748 MEM_MBOX | MEM_PRI))) {
2749 emlxs_mb_config_link(hba,
2750 (MAILBOX *) mbox);
2751
2752 emlxs_mb_put(hba, mbox);
2753 }
2754 /* Declare the linkup here */
2755 emlxs_linkup(hba);
2756 }
2757 /* If link not already down then declare it down now */
2758 else if ((la.attType == AT_LINK_DOWN) &&
2759 (hba->state > FC_LINK_DOWN)) {
2760 /* Declare link down here */
2761 emlxs_linkdown(hba);
2762 }
2763 /* Enable Link attention interrupt */
2764 mutex_enter(&EMLXS_PORT_LOCK);
2765
2766 if (!(hba->hc_copy & HC_LAINT_ENA)) {
2767 /*
2768 * hba->hc_copy = READ_CSR_REG(hba,
2769 * FC_HC_REG(hba, hba->csr_addr));
2770 */
2771 hba->hc_copy |= HC_LAINT_ENA;
2772 WRITE_CSR_REG(hba, FC_HC_REG(hba,
2773 hba->csr_addr), hba->hc_copy);
2774 }
2775 mutex_exit(&EMLXS_PORT_LOCK);
2776
2777 /* Log the link event */
2778 emlxs_log_link_event(port);
2779
2780 break;
2781
2782 case MBX_CLEAR_LA:
2783 /* Enable on Link Attention interrupts */
2784 mutex_enter(&EMLXS_PORT_LOCK);
2785
2786 if (!(hba->hc_copy & HC_LAINT_ENA)) {
2787 /*
2788 * hba->hc_copy = READ_CSR_REG(hba, FC_HC_REG(hba,
2789 * hba->csr_addr));
2790 */
2791 hba->hc_copy |= HC_LAINT_ENA;
2792 WRITE_CSR_REG(hba, FC_HC_REG(hba, hba->csr_addr),
2793 hba->hc_copy);
2794 }
2795 if (hba->state >= FC_LINK_UP) {
2796 emlxs_ffstate_change_locked(hba, FC_READY);
2797 }
2798 mutex_exit(&EMLXS_PORT_LOCK);
2799
2800 /* Adapter is now ready for FCP traffic */
2801 if (hba->state == FC_READY) {
2802 /* Register vpi's for all ports that have did's */
2803 for (i = 0; i < MAX_VPORTS; i++) {
2804 vport = &VPORT(i);
2805
2806 if (!(vport->flag & EMLXS_PORT_BOUND) ||
2807 !(vport->did)) {
2808 continue;
2809 }
2810 (void) emlxs_mb_reg_vpi(vport);
2811 }
2812
2813 /* Attempt to send any pending IO */
2814 emlxs_issue_iocb_cmd(hba, &hba->ring[FC_FCP_RING], 0);
2815 }
2816 break;
2817
2818 default:
2819 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg,
2820 "Unknown mailbox cmd: 0x%x", mb->mbxCommand);
2821 HBASTATS.MboxInvalid++;
2822 break;
2823 }
2824
2825 return (0);
2826
2827} /* emlxs_mb_handle_cmd() */
2828
2829
2830/* MBX_NOWAIT - returns MBX_BUSY or MBX_SUCCESS or MBX_HARDWARE_ERROR */
2831/* MBX_WAIT - returns MBX_TIMEOUT or mailbox_status */
2832/* MBX_SLEEP - returns MBX_TIMEOUT or mailbox_status */
2833/* MBX_POLL - returns MBX_TIMEOUT or mailbox_status */
2834
2835extern uint32_t
2836emlxs_mb_issue_cmd(emlxs_hba_t *hba, MAILBOX *mb, int32_t flag, uint32_t tmo)
2837{
2838 emlxs_port_t *port = &PPORT;
2839 MAILBOX *mbox;
2840 MAILBOXQ *mbq;
2841 volatile uint32_t word0;
2842 volatile uint32_t ldata;
2843 uint32_t ha_copy;
2844 off_t offset;
2845 MATCHMAP *mbox_bp;
2846 uint32_t tmo_local;
2847 MAILBOX *swpmb;
2848
2849 mbq = (MAILBOXQ *) mb;
2850 swpmb = (MAILBOX *) & word0;
2851
2852 mb->mbxStatus = MBX_SUCCESS;
2853
2854 /* Check for minimum timeouts */
2855 switch (mb->mbxCommand) {
2856 /* Mailbox commands that erase/write flash */
2857 case MBX_DOWN_LOAD:
2858 case MBX_UPDATE_CFG:
2859 case MBX_LOAD_AREA:
2860 case MBX_LOAD_EXP_ROM:
2861 case MBX_WRITE_NV:
2862 case MBX_FLASH_WR_ULA:
2863 case MBX_DEL_LD_ENTRY:
2864 case MBX_LOAD_SM:
2865 if (tmo < 300) {
2866 tmo = 300;
2867 }
2868 break;
2869
2870 default:
2871 if (tmo < 30) {
2872 tmo = 30;
2873 }
2874 break;
2875 }
2876
2877 /* Adjust wait flag */
2878 if (flag != MBX_NOWAIT) {
2879 /* If interrupt is enabled, use sleep, otherwise poll */
2880 if (hba->hc_copy & HC_MBINT_ENA) {
2881 flag = MBX_SLEEP;
2882 } else {
2883 flag = MBX_POLL;
2884 }
2885 }
2886 mutex_enter(&EMLXS_PORT_LOCK);
2887
2888 /* Check for hardware error */
2889 if (hba->flag & FC_HARDWARE_ERROR) {
2890 mb->mbxStatus = (hba->flag & FC_OVERTEMP_EVENT) ?
2891 MBX_OVERTEMP_ERROR : MBX_HARDWARE_ERROR;
2892
2893 mutex_exit(&EMLXS_PORT_LOCK);
2894
2895 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
2896 "Hardware error reported. %s failed. status=%x mb=%p",
2897 emlxs_mb_cmd_xlate(mb->mbxCommand), mb->mbxStatus, mb);
2898
2899 return (MBX_HARDWARE_ERROR);
2900 }
2901 if (hba->mbox_queue_flag) {
2902 /* If we are not polling, then queue it for later */
2903 if (flag == MBX_NOWAIT) {
2904 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
2905 "Busy. %s: mb=%p NoWait.",
2906 emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
2907
2908 emlxs_mb_put(hba, mbq);
2909
2910 HBASTATS.MboxBusy++;
2911
2912 mutex_exit(&EMLXS_PORT_LOCK);
2913
2914 return (MBX_BUSY);
2915 }
2916 tmo_local = tmo * 20; /* Convert tmo seconds to 50 */
2917 /* millisecond tics */
2918 while (hba->mbox_queue_flag) {
2919 mutex_exit(&EMLXS_PORT_LOCK);
2920
2921 if (tmo_local-- == 0) {
2922 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
2923 "Timeout. %s: mb=%p tmo=%d Waiting.",
2924 emlxs_mb_cmd_xlate(mb->mbxCommand), mb,
2925 tmo);
2926
2927 /* Non-lethalStatus mailbox timeout */
2928 /* Does not indicate a hardware error */
2929 mb->mbxStatus = MBX_TIMEOUT;
2930 return (MBX_TIMEOUT);
2931 }
2932 DELAYMS(50);
2933 mutex_enter(&EMLXS_PORT_LOCK);
2934 }
2935 }
2936 /* Initialize mailbox area */
2937 emlxs_mb_init(hba, mbq, flag, tmo);
2938
2939 switch (flag) {
2940 case MBX_NOWAIT:
2941
2942 if (mb->mbxCommand != MBX_HEARTBEAT) {
2943 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
2944 "Sending. %s: mb=%p NoWait.",
2945 emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
2946 }
2947 break;
2948
2949 case MBX_SLEEP:
2950 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
2951 "Sending. %s: mb=%p Sleep.",
2952 emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
2953
2954 break;
2955
2956 case MBX_POLL:
2957 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
2958 "Sending. %s: mb=%p Polled.",
2959 emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
2960 break;
2961 }
2962
2963 mb->mbxOwner = OWN_CHIP;
2964
2965 /* Clear the attention bit */
2966 WRITE_CSR_REG(hba, FC_HA_REG(hba, hba->csr_addr), HA_MBATT);
2967
2968 if (hba->flag & FC_SLIM2_MODE) {
2969 /* First copy command data */
2970 mbox = FC_SLIM2_MAILBOX(hba);
2971 offset = (off_t)((uint64_t)(unsigned long)mbox -
2972 (uint64_t)(unsigned long)hba->slim2.virt);
2973
2974#ifdef MBOX_EXT_SUPPORT
2975 if (hba->mbox_ext) {
2976 uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox +
2977 MBOX_EXTENSION_OFFSET);
2978 off_t offset_ext = offset + MBOX_EXTENSION_OFFSET;
2979
2980 emlxs_pcimem_bcopy((uint32_t *)hba->mbox_ext, mbox_ext,
2981 hba->mbox_ext_size);
2982 emlxs_mpdata_sync(hba->slim2.dma_handle, offset_ext,
2983 hba->mbox_ext_size, DDI_DMA_SYNC_FORDEV);
2984 }
2985#endif /* MBOX_EXT_SUPPORT */
2986
2987 emlxs_pcimem_bcopy((uint32_t *)mb, (uint32_t *)mbox,
2988 MAILBOX_CMD_BSIZE);
2989 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
2990 MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV);
2991 }
2992 /* Check for config port command */
2993 else if (mb->mbxCommand == MBX_CONFIG_PORT) {
2994 /* copy command data into host mbox for cmpl */
2995 mbox = FC_SLIM2_MAILBOX(hba);
2996 offset = (off_t)((uint64_t)(unsigned long)mbox -
2997 (uint64_t)(unsigned long)hba->slim2.virt);
2998
2999 emlxs_pcimem_bcopy((uint32_t *)mb, (uint32_t *)mbox,
3000 MAILBOX_CMD_BSIZE);
3001 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
3002 MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV);
3003
3004 /* First copy command data */
3005 mbox = FC_SLIM1_MAILBOX(hba);
3006 WRITE_SLIM_COPY(hba, &mb->un.varWords, &mbox->un.varWords,
3007 (MAILBOX_CMD_WSIZE - 1));
3008
3009 /* copy over last word, with mbxOwner set */
3010 ldata = *((volatile uint32_t *) mb);
3011 WRITE_SLIM_ADDR(hba, ((volatile uint32_t *) mbox), ldata);
3012
3013 /* switch over to host mailbox */
3014 /*
3015 * hba->mbox_queueaddr = (uint32_t *)&((SLIM2 *)
3016 * hba->slim2.virt)->mbx;
3017 */
3018 hba->flag |= FC_SLIM2_MODE;
3019 } else { /* SLIM 1 */
3020 mbox = FC_SLIM1_MAILBOX(hba);
3021
3022#ifdef MBOX_EXT_SUPPORT
3023 if (hba->mbox_ext) {
3024 uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox +
3025 MBOX_EXTENSION_OFFSET);
3026 WRITE_SLIM_COPY(hba, (uint32_t *)hba->mbox_ext,
3027 mbox_ext, (hba->mbox_ext_size / 4));
3028 }
3029#endif /* MBOX_EXT_SUPPORT */
3030
3031 /* First copy command data */
3032 WRITE_SLIM_COPY(hba, &mb->un.varWords, &mbox->un.varWords,
3033 (MAILBOX_CMD_WSIZE - 1));
3034
3035 /* copy over last word, with mbxOwner set */
3036 ldata = *((volatile uint32_t *) mb);
3037 WRITE_SLIM_ADDR(hba, ((volatile uint32_t *) mbox), ldata);
3038 }
3039
3040 /* Interrupt board to do it right away */
3041 WRITE_CSR_REG(hba, FC_CA_REG(hba, hba->csr_addr), CA_MBATT);
3042
3043 mutex_exit(&EMLXS_PORT_LOCK);
3044
3045 switch (flag) {
3046 case MBX_NOWAIT:
3047 return (MBX_SUCCESS);
3048
3049 case MBX_SLEEP:
3050
3051 /* Wait for completion */
3052 /* The driver clock is timing the mailbox. */
3053 /* emlxs_mb_fini() will be called externally. */
3054
3055 mutex_enter(&EMLXS_MBOX_LOCK);
3056 while (!(mbq->flag & MBQ_COMPLETED)) {
3057 cv_wait(&EMLXS_MBOX_CV, &EMLXS_MBOX_LOCK);
3058 }
3059 mutex_exit(&EMLXS_MBOX_LOCK);
3060
3061 if (mb->mbxStatus == MBX_TIMEOUT) {
3062 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
3063 "Timeout. %s: mb=%p tmo=%d. Sleep.",
3064 emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo);
3065 } else {
3066 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
3067 "Completed. %s: mb=%p status=%x Sleep.",
3068 emlxs_mb_cmd_xlate(mb->mbxCommand), mb,
3069 mb->mbxStatus);
3070 }
3071
3072 break;
3073
3074 case MBX_POLL:
3075
3076 tmo_local = tmo * 2000; /* Convert tmo seconds to 500 usec */
3077 /* tics */
3078
3079 if (hba->state >= FC_INIT_START) {
3080 ha_copy = READ_CSR_REG(hba, FC_HA_REG(hba,
3081 hba->csr_addr));
3082
3083 /* Wait for command to complete */
3084 while (!(ha_copy & HA_MBATT) &&
3085 !(mbq->flag & MBQ_COMPLETED)) {
3086 if (!hba->timer_id && (tmo_local-- == 0)) {
3087 /* self time */
3088 EMLXS_MSGF(EMLXS_CONTEXT,
3089 &emlxs_hardware_error_msg,
3090 "Mailbox Timeout: %s: mb=%p Polled",
3091 emlxs_mb_cmd_xlate(mb->mbxCommand),
3092 mb);
3093
3094 hba->flag |= FC_MBOX_TIMEOUT;
3095 emlxs_ffstate_change(hba, FC_ERROR);
3096 emlxs_mb_fini(hba, NULL, MBX_TIMEOUT);
3097
3098 break;
3099 }
3100 DELAYUS(500);
3101 ha_copy = READ_CSR_REG(hba,
3102 FC_HA_REG(hba, hba->csr_addr));
3103 }
3104
3105 if (mb->mbxStatus == MBX_TIMEOUT) {
3106 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
3107 "Timeout. %s: mb=%p tmo=%d. Polled.",
3108 emlxs_mb_cmd_xlate(mb->mbxCommand), mb,
3109 tmo);
3110
3111 break;
3112 }
3113 }
3114 /* Get first word of mailbox */
3115 if (hba->flag & FC_SLIM2_MODE) {
3116 mbox = FC_SLIM2_MAILBOX(hba);
3117 offset = (off_t)((uint64_t)(unsigned long)mbox -
3118 (uint64_t)(unsigned long)hba->slim2.virt);
3119
3120 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
3121 sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
3122 word0 = *((volatile uint32_t *) mbox);
3123 word0 = PCIMEM_LONG(word0);
3124 } else {
3125 mbox = FC_SLIM1_MAILBOX(hba);
3126 word0 = READ_SLIM_ADDR(hba,
3127 ((volatile uint32_t *) mbox));
3128 }
3129
3130 /* Wait for command to complete */
3131 while ((swpmb->mbxOwner == OWN_CHIP) &&
3132 !(mbq->flag & MBQ_COMPLETED)) {
3133 if (!hba->timer_id && (tmo_local-- == 0)) {
3134 /* self time */
3135 EMLXS_MSGF(EMLXS_CONTEXT,
3136 &emlxs_hardware_error_msg,
3137 "Mailbox Timeout: %s: mb=%p Polled.",
3138 emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
3139
3140 hba->flag |= FC_MBOX_TIMEOUT;
3141 emlxs_ffstate_change(hba, FC_ERROR);
3142 emlxs_mb_fini(hba, NULL, MBX_TIMEOUT);
3143
3144 break;
3145 }
3146 DELAYUS(500);
3147
3148 /* Get first word of mailbox */
3149 if (hba->flag & FC_SLIM2_MODE) {
3150 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
3151 sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
3152 word0 = *((volatile uint32_t *) mbox);
3153 word0 = PCIMEM_LONG(word0);
3154 } else {
3155 word0 = READ_SLIM_ADDR(hba,
3156 ((volatile uint32_t *) mbox));
3157 }
3158
3159 } /* while */
3160
3161 if (mb->mbxStatus == MBX_TIMEOUT) {
3162 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
3163 "Timeout. %s: mb=%p tmo=%d. Polled.",
3164 emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo);
3165
3166 break;
3167 }
3168 /* copy results back to user */
3169 if (hba->flag & FC_SLIM2_MODE) {
3170 emlxs_mpdata_sync(hba->slim2.dma_handle, offset,
3171 MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL);
3172 emlxs_pcimem_bcopy((uint32_t *)mbox, (uint32_t *)mb,
3173 MAILBOX_CMD_BSIZE);
3174 } else {
3175 READ_SLIM_COPY(hba, (uint32_t *)mb, (uint32_t *)mbox,
3176 MAILBOX_CMD_WSIZE);
3177 }
3178
3179#ifdef MBOX_EXT_SUPPORT
3180 if (hba->mbox_ext) {
3181 uint32_t *mbox_ext = (uint32_t *)((uint8_t *)mbox +
3182 MBOX_EXTENSION_OFFSET);
3183 off_t offset_ext = offset + MBOX_EXTENSION_OFFSET;
3184
3185 if (hba->flag & FC_SLIM2_MODE) {
3186 emlxs_mpdata_sync(hba->slim2.dma_handle,
3187 offset_ext, hba->mbox_ext_size,
3188 DDI_DMA_SYNC_FORKERNEL);
3189 emlxs_pcimem_bcopy(mbox_ext,
3190 (uint32_t *)hba->mbox_ext,
3191 hba->mbox_ext_size);
3192 } else {
3193 READ_SLIM_COPY(hba, (uint32_t *)hba->mbox_ext,
3194 mbox_ext, (hba->mbox_ext_size / 4));
3195 }
3196 }
3197#endif /* MBOX_EXT_SUPPORT */
3198
3199 /* Sync the memory buffer */
3200 if (hba->mbox_bp) {
3201 mbox_bp = (MATCHMAP *) hba->mbox_bp;
3202 emlxs_mpdata_sync(mbox_bp->dma_handle, 0, mbox_bp->size,
3203 DDI_DMA_SYNC_FORKERNEL);
3204 }
3205 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
3206 "Completed. %s: mb=%p status=%x Polled.",
3207 emlxs_mb_cmd_xlate(mb->mbxCommand), mb, mb->mbxStatus);
3208
3209 /* Process the result */
3210 if (!(mbq->flag & MBQ_PASSTHRU)) {
3211 (void) emlxs_mb_handle_cmd(hba, mb);
3212 }
3213 /* Clear the attention bit */
3214 WRITE_CSR_REG(hba, FC_HA_REG(hba, hba->csr_addr), HA_MBATT);
3215
3216 /* Clean up the mailbox area */
3217 emlxs_mb_fini(hba, NULL, mb->mbxStatus);
3218
3219 break;
3220
3221 } /* switch (flag) */
3222
3223 return (mb->mbxStatus);
3224
3225} /* emlxs_mb_issue_cmd() */
3226
3227
3228
3229extern char *
3230emlxs_mb_cmd_xlate(uint8_t cmd)
3231{
1686extern char *
1687emlxs_mb_cmd_xlate(uint8_t cmd)
1688{
3232 static char buffer[32];
3233 uint32_t i;
3234 uint32_t count;
1689 static char buffer[32];
1690 uint32_t i;
1691 uint32_t count;
3235
3236 count = sizeof (emlxs_mb_cmd_table) / sizeof (emlxs_table_t);
3237 for (i = 0; i < count; i++) {
3238 if (cmd == emlxs_mb_cmd_table[i].code) {
3239 return (emlxs_mb_cmd_table[i].string);
3240 }
3241 }
3242
3243 (void) sprintf(buffer, "Cmd=0x%x", cmd);
3244 return (buffer);
3245
3246} /* emlxs_mb_cmd_xlate() */
1692
1693 count = sizeof (emlxs_mb_cmd_table) / sizeof (emlxs_table_t);
1694 for (i = 0; i < count; i++) {
1695 if (cmd == emlxs_mb_cmd_table[i].code) {
1696 return (emlxs_mb_cmd_table[i].string);
1697 }
1698 }
1699
1700 (void) sprintf(buffer, "Cmd=0x%x", cmd);
1701 return (buffer);
1702
1703} /* emlxs_mb_cmd_xlate() */