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
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 (c) 2004-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <emlxs.h>
28
29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30 EMLXS_MSG_DEF(EMLXS_MBOX_C);
31
32
33 emlxs_table_t emlxs_mb_status_table[] = {
34 {MBX_SUCCESS, "SUCCESS"},
35 {MBX_FAILURE, "FAILURE"},
36 {MBXERR_NUM_IOCBS, "NUM_IOCBS"},
37 {MBXERR_IOCBS_EXCEEDED, "IOCBS_EXCEEDED"},
38 {MBXERR_BAD_RING_NUMBER, "BAD_RING_NUMBER"},
39 {MBXERR_MASK_ENTRIES_RANGE, "MASK_ENTRIES_RANGE"},
40 {MBXERR_MASKS_EXCEEDED, "MASKS_EXCEEDED"},
41 {MBXERR_BAD_PROFILE, "BAD_PROFILE"},
42 {MBXERR_BAD_DEF_CLASS, "BAD_DEF_CLASS"},
43 {MBXERR_BAD_MAX_RESPONDER, "BAD_MAX_RESPONDER"},
44 {MBXERR_BAD_MAX_ORIGINATOR, "BAD_MAX_ORIGINATOR"},
45 {MBXERR_RPI_REGISTERED, "RPI_REGISTERED"},
46 {MBXERR_RPI_FULL, "RPI_FULL"},
47 {MBXERR_NO_RESOURCES, "NO_RESOURCES"},
48 {MBXERR_BAD_RCV_LENGTH, "BAD_RCV_LENGTH"},
49 {MBXERR_DMA_ERROR, "DMA_ERROR"},
50 {MBXERR_NOT_SUPPORTED, "NOT_SUPPORTED"},
51 {MBXERR_UNSUPPORTED_FEATURE, "UNSUPPORTED_FEATURE"},
52 {MBXERR_UNKNOWN_COMMAND, "UNKNOWN_COMMAND"},
53 {MBXERR_BAD_IP_BIT, "BAD_IP_BIT"},
54 {MBXERR_BAD_PCB_ALIGN, "BAD_PCB_ALIGN"},
55 {MBXERR_BAD_HBQ_ID, "BAD_HBQ_ID"},
56 {MBXERR_BAD_HBQ_STATE, "BAD_HBQ_STATE"},
57 {MBXERR_BAD_HBQ_MASK_NUM, "BAD_HBQ_MASK_NUM"},
58 {MBXERR_BAD_HBQ_MASK_SUBSET, "BAD_HBQ_MASK_SUBSET"},
59 {MBXERR_HBQ_CREATE_FAIL, "HBQ_CREATE_FAIL"},
60 {MBXERR_HBQ_EXISTING, "HBQ_EXISTING"},
61 {MBXERR_HBQ_RSPRING_FULL, "HBQ_RSPRING_FULL"},
62 {MBXERR_HBQ_DUP_MASK, "HBQ_DUP_MASK"},
63 {MBXERR_HBQ_INVAL_GET_PTR, "HBQ_INVAL_GET_PTR"},
64 {MBXERR_BAD_HBQ_SIZE, "BAD_HBQ_SIZE"},
65 {MBXERR_BAD_HBQ_ORDER, "BAD_HBQ_ORDER"},
66 {MBXERR_INVALID_ID, "INVALID_ID"},
67 {MBXERR_INVALID_VFI, "INVALID_VFI"},
68 {MBXERR_FLASH_WRITE_FAILED, "FLASH_WRITE_FAILED"},
69 {MBXERR_INVALID_LINKSPEED, "INVALID_LINKSPEED"},
70 {MBXERR_BAD_REDIRECT, "BAD_REDIRECT"},
71 {MBXERR_RING_ALREADY_CONFIG, "RING_ALREADY_CONFIG"},
72 {MBXERR_RING_INACTIVE, "RING_INACTIVE"},
73 {MBXERR_RPI_INACTIVE, "RPI_INACTIVE"},
74 {MBXERR_NO_ACTIVE_XRI, "NO_ACTIVE_XRI"},
75 {MBXERR_XRI_NOT_ACTIVE, "XRI_NOT_ACTIVE"},
76 {MBXERR_RPI_INUSE, "RPI_INUSE"},
77 {MBXERR_NO_LINK_ATTENTION, "NO_LINK_ATTENTION"},
78 {MBXERR_INVALID_SLI_MODE, "INVALID_SLI_MODE"},
79 {MBXERR_INVALID_HOST_PTR, "INVALID_HOST_PTR"},
80 {MBXERR_CANT_CFG_SLI_MODE, "CANT_CFG_SLI_MODE"},
81 {MBXERR_BAD_OVERLAY, "BAD_OVERLAY"},
82 {MBXERR_INVALID_FEAT_REQ, "INVALID_FEAT_REQ"},
83 {MBXERR_CONFIG_CANT_COMPLETE, "CONFIG_CANT_COMPLETE"},
84 {MBXERR_DID_ALREADY_REGISTERED, "DID_ALREADY_REGISTERED"},
85 {MBXERR_DID_INCONSISTENT, "DID_INCONSISTENT"},
86 {MBXERR_VPI_TOO_LARGE, "VPI_TOO_LARGE"},
87 {MBXERR_STILL_ASSOCIATED, "STILL_ASSOCIATED"},
88 {MBXERR_INVALID_VF_STATE, "INVALID_VF_STATE"},
89 {MBXERR_VFI_ALREADY_REGISTERED, "VFI_ALREADY_REGISTERED"},
90 {MBXERR_VFI_TOO_LARGE, "VFI_TOO_LARGE"},
91 {MBXERR_LOAD_FW_FAILED, "LOAD_FW_FAILED"},
92 {MBXERR_FIND_FW_FAILED, "FIND_FW_FAILED"},
93 };
94
95 emlxs_table_t emlxs_mb_cmd_table[] = {
96 {MBX_SHUTDOWN, "SHUTDOWN"},
97 {MBX_LOAD_SM, "LOAD_SM"},
98 {MBX_READ_NV, "READ_NV"},
99 {MBX_WRITE_NV, "WRITE_NV"},
100 {MBX_RUN_BIU_DIAG, "RUN_BIU_DIAG"},
101 {MBX_INIT_LINK, "INIT_LINK"},
102 {MBX_DOWN_LINK, "DOWN_LINK"},
103 {MBX_CONFIG_LINK, "CONFIG_LINK"},
104 {MBX_PART_SLIM, "PART_SLIM"},
105 {MBX_CONFIG_RING, "CONFIG_RING"},
106 {MBX_RESET_RING, "RESET_RING"},
107 {MBX_READ_CONFIG, "READ_CONFIG"},
108 {MBX_READ_RCONFIG, "READ_RCONFIG"},
109 {MBX_READ_SPARM, "READ_SPARM"},
110 {MBX_READ_STATUS, "READ_STATUS"},
111 {MBX_READ_RPI, "READ_RPI"},
112 {MBX_READ_XRI, "READ_XRI"},
113 {MBX_READ_REV, "READ_REV"},
114 {MBX_READ_LNK_STAT, "READ_LNK_STAT"},
115 {MBX_REG_LOGIN, "REG_LOGIN"},
116 {MBX_UNREG_LOGIN, "UNREG_RPI"},
117 {MBX_READ_LA, "READ_LA"},
118 {MBX_CLEAR_LA, "CLEAR_LA"},
119 {MBX_DUMP_MEMORY, "DUMP_MEMORY"},
120 {MBX_DUMP_CONTEXT, "DUMP_CONTEXT"},
121 {MBX_RUN_DIAGS, "RUN_DIAGS"},
122 {MBX_RESTART, "RESTART"},
123 {MBX_UPDATE_CFG, "UPDATE_CFG"},
124 {MBX_DOWN_LOAD, "DOWN_LOAD"},
125 {MBX_DEL_LD_ENTRY, "DEL_LD_ENTRY"},
126 {MBX_RUN_PROGRAM, "RUN_PROGRAM"},
127 {MBX_SET_MASK, "SET_MASK"},
128 {MBX_SET_VARIABLE, "SET_VARIABLE"},
129 {MBX_UNREG_D_ID, "UNREG_D_ID"},
130 {MBX_KILL_BOARD, "KILL_BOARD"},
131 {MBX_CONFIG_FARP, "CONFIG_FARP"},
132 {MBX_LOAD_AREA, "LOAD_AREA"},
133 {MBX_RUN_BIU_DIAG64, "RUN_BIU_DIAG64"},
134 {MBX_CONFIG_PORT, "CONFIG_PORT"},
135 {MBX_READ_SPARM64, "READ_SPARM64"},
136 {MBX_READ_RPI64, "READ_RPI64"},
137 {MBX_CONFIG_MSI, "CONFIG_MSI"},
138 {MBX_CONFIG_MSIX, "CONFIG_MSIX"},
139 {MBX_REG_LOGIN64, "REG_RPI"},
140 {MBX_READ_LA64, "READ_LA64"},
141 {MBX_FLASH_WR_ULA, "FLASH_WR_ULA"},
142 {MBX_SET_DEBUG, "SET_DEBUG"},
143 {MBX_GET_DEBUG, "GET_DEBUG"},
144 {MBX_LOAD_EXP_ROM, "LOAD_EXP_ROM"},
145 {MBX_BEACON, "BEACON"},
146 {MBX_CONFIG_HBQ, "CONFIG_HBQ"}, /* SLI3 */
147 {MBX_REG_VPI, "REG_VPI"}, /* NPIV */
148 {MBX_UNREG_VPI, "UNREG_VPI"}, /* NPIV */
149 {MBX_ASYNC_EVENT, "ASYNC_EVENT"},
150 {MBX_HEARTBEAT, "HEARTBEAT"},
151 {MBX_READ_EVENT_LOG_STATUS, "READ_EVENT_LOG_STATUS"},
152 {MBX_READ_EVENT_LOG, "READ_EVENT_LOG"},
153 {MBX_WRITE_EVENT_LOG, "WRITE_EVENT_LOG"},
154 {MBX_NV_LOG, "NV_LOG"},
155 {MBX_PORT_CAPABILITIES, "PORT_CAPABILITIES"},
156 {MBX_IOV_CONTROL, "IOV_CONTROL"},
157 {MBX_IOV_MBX, "IOV_MBX"},
158 {MBX_SLI_CONFIG, "SLI_CONFIG"},
159 {MBX_REQUEST_FEATURES, "REQUEST_FEATURES"},
160 {MBX_RESUME_RPI, "RESUME_RPI"},
161 {MBX_REG_VFI, "REG_VFI"},
162 {MBX_REG_FCFI, "REG_FCFI"},
163 {MBX_UNREG_VFI, "UNREG_VFI"},
164 {MBX_UNREG_FCFI, "UNREG_FCFI"},
165 {MBX_INIT_VFI, "INIT_VFI"},
166 {MBX_INIT_VPI, "INIT_VPI"},
167 {MBX_WRITE_VPARMS, "WRITE_VPARMS"},
168 {MBX_ACCESS_VDATA, "ACCESS_VDATA"}
169 }; /* emlxs_mb_cmd_table */
170
171
172 emlxs_table_t emlxs_request_feature_table[] = {
173 {SLI4_FEATURE_INHIBIT_AUTO_ABTS, "IAA "}, /* Bit 0 */
174 {SLI4_FEATURE_NPIV, "NPIV "}, /* Bit 1 */
175 {SLI4_FEATURE_DIF, "DIF "}, /* Bit 2 */
176 {SLI4_FEATURE_VIRTUAL_FABRICS, "VF "}, /* Bit 3 */
177 {SLI4_FEATURE_FCP_INITIATOR, "FCPI "}, /* Bit 4 */
178 {SLI4_FEATURE_FCP_TARGET, "FCPT "}, /* Bit 5 */
179 {SLI4_FEATURE_FCP_COMBO, "FCPC "}, /* Bit 6 */
180 {SLI4_FEATURE_RSVD1, "RSVD1 "}, /* Bit 7 */
181 {SLI4_FEATURE_RQD, "RQD "}, /* Bit 8 */
182 {SLI4_FEATURE_INHIBIT_AUTO_ABTS_R, "IAAR "}, /* Bit 9 */
183 {SLI4_FEATURE_HIGH_LOGIN_MODE, "HLM "}, /* Bit 10 */
184 {SLI4_FEATURE_PERF_HINT, "PERFH "} /* Bit 11 */
185 }; /* emlxs_request_feature_table */
186
187
188 extern char *
emlxs_mb_xlate_status(uint32_t status)189 emlxs_mb_xlate_status(uint32_t status)
190 {
191 static char buffer[32];
192 uint32_t i;
193 uint32_t count;
194
195 count = sizeof (emlxs_mb_status_table) / sizeof (emlxs_table_t);
196 for (i = 0; i < count; i++) {
197 if (status == emlxs_mb_status_table[i].code) {
198 return (emlxs_mb_status_table[i].string);
199 }
200 }
201
202 (void) snprintf(buffer, sizeof (buffer), "status=%x", status);
203 return (buffer);
204
205 } /* emlxs_mb_xlate_status() */
206
207
208 /* SLI4 */
209 /*ARGSUSED*/
210 extern void
emlxs_mb_resetport(emlxs_hba_t * hba,MAILBOXQ * mbq)211 emlxs_mb_resetport(emlxs_hba_t *hba, MAILBOXQ *mbq)
212 {
213 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
214
215 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
216 mbq->nonembed = NULL;
217 mbq->mbox_cmpl = NULL; /* no cmpl needed */
218 mbq->port = (void *)&PPORT;
219
220 /*
221 * Signifies an embedded command
222 */
223 mb4->un.varSLIConfig.be.embedded = 1;
224
225 mb4->mbxCommand = MBX_SLI_CONFIG;
226 mb4->mbxOwner = OWN_HOST;
227 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
228 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
229 IOCTL_SUBSYSTEM_COMMON;
230 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_RESET;
231 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
232 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0;
233
234 return;
235
236 } /* emlxs_mb_resetport() */
237
238
239 /* SLI4 */
240 /*ARGSUSED*/
241 extern void
emlxs_mb_request_features(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t mask)242 emlxs_mb_request_features(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t mask)
243 {
244 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
245
246 hba->flag &= ~FC_NPIV_ENABLED;
247 hba->sli.sli4.flag &= ~(EMLXS_SLI4_PHON | EMLXS_SLI4_PHWQ);
248
249 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
250 mbq->nonembed = NULL;
251 mbq->mbox_cmpl = NULL; /* no cmpl needed */
252 mbq->port = (void *)&PPORT;
253
254 mb4->mbxCommand = MBX_REQUEST_FEATURES;
255 mb4->mbxOwner = OWN_HOST;
256
257 mb4->un.varReqFeatures.featuresRequested = mask;
258 return;
259
260 } /* emlxs_mb_request_features() */
261
262
263 /* SLI4 */
264 /*ARGSUSED*/
265 extern void
emlxs_mb_noop(emlxs_hba_t * hba,MAILBOXQ * mbq)266 emlxs_mb_noop(emlxs_hba_t *hba, MAILBOXQ *mbq)
267 {
268 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
269 IOCTL_COMMON_NOP *nop;
270
271 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
272 mbq->nonembed = NULL;
273 mbq->mbox_cmpl = NULL; /* no cmpl needed */
274 mbq->port = (void *)&PPORT;
275
276 /*
277 * Signifies an embedded command
278 */
279 mb4->un.varSLIConfig.be.embedded = 1;
280
281 mb4->mbxCommand = MBX_SLI_CONFIG;
282 mb4->mbxOwner = OWN_HOST;
283 mb4->un.varSLIConfig.be.payload_length = sizeof (IOCTL_COMMON_NOP) +
284 IOCTL_HEADER_SZ;
285 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
286 IOCTL_SUBSYSTEM_COMMON;
287 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_NOP;
288 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
289 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
290 sizeof (IOCTL_COMMON_NOP);
291 nop = (IOCTL_COMMON_NOP *)&mb4->un.varSLIConfig.payload;
292 nop->params.request.context = -1;
293
294 return;
295
296 } /* emlxs_mb_noop() */
297
298
299 /* SLI4 */
300 /*ARGSUSED*/
301 extern int
emlxs_mbext_noop(emlxs_hba_t * hba,MAILBOXQ * mbq)302 emlxs_mbext_noop(emlxs_hba_t *hba, MAILBOXQ *mbq)
303 {
304 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
305 IOCTL_COMMON_NOP *nop;
306 MATCHMAP *mp;
307 mbox_req_hdr_t *hdr_req;
308
309 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
310
311 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
312 return (1);
313 }
314 /*
315 * Save address for completion
316 * Signifies a non-embedded command
317 */
318 mb4->un.varSLIConfig.be.embedded = 0;
319 mbq->nonembed = (void *)mp;
320 mbq->mbox_cmpl = NULL; /* no cmpl needed */
321 mbq->port = (void *)&PPORT;
322
323 mb4->mbxCommand = MBX_SLI_CONFIG;
324 mb4->mbxOwner = OWN_HOST;
325
326 hdr_req = (mbox_req_hdr_t *)mp->virt;
327 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
328 hdr_req->opcode = COMMON_OPCODE_NOP;
329 hdr_req->timeout = 0;
330 hdr_req->req_length = sizeof (IOCTL_COMMON_NOP);
331 nop = (IOCTL_COMMON_NOP *)(hdr_req + 1);
332 nop->params.request.context = -1;
333
334 return (0);
335
336 } /* emlxs_mbext_noop() */
337
338
339 /* SLI4 */
340 /*ARGSUSED*/
341 extern void
emlxs_mb_eq_create(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t num)342 emlxs_mb_eq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
343 {
344 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
345 IOCTL_COMMON_EQ_CREATE *qp;
346 uint64_t addr;
347
348 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
349 mbq->nonembed = NULL;
350 mbq->mbox_cmpl = NULL; /* no cmpl needed */
351 mbq->port = (void *)&PPORT;
352
353 /*
354 * Signifies an embedded command
355 */
356 mb4->un.varSLIConfig.be.embedded = 1;
357
358 mb4->mbxCommand = MBX_SLI_CONFIG;
359 mb4->mbxOwner = OWN_HOST;
360 mb4->un.varSLIConfig.be.payload_length =
361 sizeof (IOCTL_COMMON_EQ_CREATE) + IOCTL_HEADER_SZ;
362 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
363 IOCTL_SUBSYSTEM_COMMON;
364 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_EQ_CREATE;
365 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
366 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
367 sizeof (IOCTL_COMMON_EQ_CREATE);
368 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0;
369
370 qp = (IOCTL_COMMON_EQ_CREATE *)&mb4->un.varSLIConfig.payload;
371
372 /* 1024 * 4 bytes = 4K */
373 qp->params.request.EQContext.Count = EQ_ELEMENT_COUNT_1024;
374 qp->params.request.EQContext.Valid = 1;
375 qp->params.request.EQContext.DelayMult = EQ_DELAY_MULT;
376
377 addr = hba->sli.sli4.eq[num].addr.phys;
378 qp->params.request.NumPages = 1;
379 qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
380 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
381
382 return;
383
384 } /* emlxs_mb_eq_create() */
385
386
387 /* SLI4 */
388 /*ARGSUSED*/
389 extern void
emlxs_mb_cq_create(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t num)390 emlxs_mb_cq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
391 {
392 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
393 IOCTL_COMMON_CQ_CREATE *qp;
394 IOCTL_COMMON_CQ_CREATE_V2 *qp2;
395 uint64_t addr;
396 uint32_t i;
397
398 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
399 mbq->nonembed = NULL;
400 mbq->mbox_cmpl = NULL; /* no cmpl needed */
401 mbq->port = (void *)&PPORT;
402
403 /*
404 * Signifies an embedded command
405 */
406 mb4->un.varSLIConfig.be.embedded = 1;
407
408 mb4->mbxCommand = MBX_SLI_CONFIG;
409 mb4->mbxOwner = OWN_HOST;
410
411 switch (hba->sli.sli4.param.CQV) {
412 case 0:
413 mb4->un.varSLIConfig.be.payload_length =
414 sizeof (IOCTL_COMMON_CQ_CREATE) + IOCTL_HEADER_SZ;
415 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
416 IOCTL_SUBSYSTEM_COMMON;
417 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
418 COMMON_OPCODE_CQ_CREATE;
419 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
420 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
421 sizeof (IOCTL_COMMON_CQ_CREATE);
422 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0;
423
424 qp = (IOCTL_COMMON_CQ_CREATE *)
425 &mb4->un.varSLIConfig.payload;
426
427 /* 256 * 16 bytes = 4K */
428 qp->params.request.CQContext.Count = CQ_ELEMENT_COUNT_256;
429 qp->params.request.CQContext.EQId =
430 (uint8_t)hba->sli.sli4.cq[num].eqid;
431 qp->params.request.CQContext.Valid = 1;
432 qp->params.request.CQContext.Eventable = 1;
433 qp->params.request.CQContext.NoDelay = 0;
434 qp->params.request.CQContext.CoalesceWM = 0;
435
436 addr = hba->sli.sli4.cq[num].addr.phys;
437 qp->params.request.NumPages = 1;
438 qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
439 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
440
441 break;
442
443 case 2:
444 default:
445 mb4->un.varSLIConfig.be.payload_length =
446 sizeof (IOCTL_COMMON_CQ_CREATE_V2) + IOCTL_HEADER_SZ;
447 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
448 IOCTL_SUBSYSTEM_COMMON;
449 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
450 COMMON_OPCODE_CQ_CREATE;
451 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
452 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
453 sizeof (IOCTL_COMMON_CQ_CREATE_V2);
454 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 2;
455
456 qp2 = (IOCTL_COMMON_CQ_CREATE_V2 *)
457 &mb4->un.varSLIConfig.payload;
458
459 qp2->params.request.CQContext.CqeCnt = CQ_ELEMENT_COUNT_1024;
460 qp2->params.request.CQContext.CqeSize = CQE_SIZE_16_BYTES;
461 qp2->params.request.CQContext.EQId = hba->sli.sli4.cq[num].eqid;
462 qp2->params.request.CQContext.Valid = 1;
463 qp2->params.request.CQContext.AutoValid = 0;
464 qp2->params.request.CQContext.Eventable = 1;
465 qp2->params.request.CQContext.NoDelay = 0;
466 qp2->params.request.CQContext.Count1 = 0;
467 qp2->params.request.CQContext.CoalesceWM = 0;
468
469 addr = hba->sli.sli4.cq[num].addr.phys;
470 qp2->params.request.PageSize = CQ_PAGE_SIZE_4K;
471 qp2->params.request.NumPages = EMLXS_NUM_CQ_PAGES_V2;
472
473 for (i = 0; i < EMLXS_NUM_CQ_PAGES_V2; i++) {
474 qp2->params.request.Pages[i].addrLow = PADDR_LO(addr);
475 qp2->params.request.Pages[i].addrHigh = PADDR_HI(addr);
476 addr += 4096;
477 }
478
479 break;
480 }
481 return;
482
483 } /* emlxs_mb_cq_create() */
484
485
486 /* SLI4 */
487 /*ARGSUSED*/
488 extern void
emlxs_mb_get_port_name(emlxs_hba_t * hba,MAILBOXQ * mbq)489 emlxs_mb_get_port_name(emlxs_hba_t *hba, MAILBOXQ *mbq)
490 {
491 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
492
493 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
494 mbq->nonembed = NULL;
495 mbq->mbox_cmpl = NULL; /* no cmpl needed */
496 mbq->port = (void *)&PPORT;
497
498 mb4->un.varSLIConfig.be.embedded = 1;
499 mb4->mbxCommand = MBX_SLI_CONFIG;
500 mb4->mbxOwner = OWN_HOST;
501
502 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
503 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
504 IOCTL_SUBSYSTEM_COMMON;
505 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
506 COMMON_OPCODE_GET_PORT_NAME;
507 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
508 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0;
509
510 if (hba->model_info.chip & EMLXS_BE_CHIPS) {
511 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; /* V0 */
512 } else {
513 IOCTL_COMMON_GET_PORT_NAME_V1 *pn;
514
515 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1; /* V1 */
516
517 pn = (IOCTL_COMMON_GET_PORT_NAME_V1 *)
518 &mb4->un.varSLIConfig.payload;
519 pn->params.request.pt = PORT_TYPE_FC;
520 }
521
522 return;
523
524 } /* emlxs_mb_get_port_name() */
525
526
527 /* SLI4 */
528 /*ARGSUSED*/
529 extern void
emlxs_mb_get_sli4_params(emlxs_hba_t * hba,MAILBOXQ * mbq)530 emlxs_mb_get_sli4_params(emlxs_hba_t *hba, MAILBOXQ *mbq)
531 {
532 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
533
534 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
535 mbq->nonembed = NULL;
536 mbq->mbox_cmpl = NULL; /* no cmpl needed */
537 mbq->port = (void *)&PPORT;
538
539 mb4->un.varSLIConfig.be.embedded = 1;
540 mb4->mbxCommand = MBX_SLI_CONFIG;
541 mb4->mbxOwner = OWN_HOST;
542
543 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
544 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
545 IOCTL_SUBSYSTEM_COMMON;
546 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
547 COMMON_OPCODE_GET_SLI4_PARAMS;
548 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
549 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0;
550 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; /* V0 */
551
552 return;
553
554 } /* emlxs_mb_get_sli4_params() */
555
556
557 /* SLI4 */
558 /*ARGSUSED*/
559 extern void
emlxs_mb_get_extents_info(emlxs_hba_t * hba,MAILBOXQ * mbq,uint16_t type)560 emlxs_mb_get_extents_info(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type)
561 {
562 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
563 IOCTL_COMMON_EXTENTS *ep;
564
565 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
566 mbq->nonembed = NULL;
567 mbq->mbox_cmpl = NULL; /* no cmpl needed */
568 mbq->port = (void *)&PPORT;
569
570 mb4->un.varSLIConfig.be.embedded = 1;
571 mb4->mbxCommand = MBX_SLI_CONFIG;
572 mb4->mbxOwner = OWN_HOST;
573
574 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
575 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem =
576 IOCTL_SUBSYSTEM_COMMON;
577 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode =
578 COMMON_OPCODE_GET_EXTENTS_INFO;
579 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0;
580 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length =
581 sizeof (IOCTL_COMMON_EXTENTS);
582 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0;
583 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0;
584 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0;
585
586 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */
587
588 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload;
589 ep->params.request.RscType = type;
590
591 return;
592
593 } /* emlxs_mb_get_extents_info() */
594
595
596 /* SLI4 */
597 /*ARGSUSED*/
598 extern void
emlxs_mb_get_extents(emlxs_hba_t * hba,MAILBOXQ * mbq,uint16_t type)599 emlxs_mb_get_extents(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type)
600 {
601 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
602 IOCTL_COMMON_EXTENTS *ep;
603
604 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
605 mbq->nonembed = NULL;
606 mbq->mbox_cmpl = NULL; /* no cmpl needed */
607 mbq->port = (void *)&PPORT;
608
609 mb4->un.varSLIConfig.be.embedded = 1;
610 mb4->mbxCommand = MBX_SLI_CONFIG;
611 mb4->mbxOwner = OWN_HOST;
612
613 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
614 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem =
615 IOCTL_SUBSYSTEM_COMMON;
616 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode =
617 COMMON_OPCODE_GET_EXTENTS;
618 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0;
619 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length =
620 sizeof (IOCTL_COMMON_EXTENTS);
621 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0;
622 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0;
623 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0;
624
625 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */
626
627 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload;
628 ep->params.request.RscType = type;
629
630 return;
631
632 } /* emlxs_mb_get_extents() */
633
634
635 /* SLI4 */
636 /*ARGSUSED*/
637 extern void
emlxs_mb_alloc_extents(emlxs_hba_t * hba,MAILBOXQ * mbq,uint16_t type,uint16_t count)638 emlxs_mb_alloc_extents(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type,
639 uint16_t count)
640 {
641 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
642 IOCTL_COMMON_EXTENTS *ep;
643
644 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
645 mbq->nonembed = NULL;
646 mbq->mbox_cmpl = NULL; /* no cmpl needed */
647 mbq->port = (void *)&PPORT;
648
649 mb4->un.varSLIConfig.be.embedded = 1;
650 mb4->mbxCommand = MBX_SLI_CONFIG;
651 mb4->mbxOwner = OWN_HOST;
652
653 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
654 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem =
655 IOCTL_SUBSYSTEM_COMMON;
656 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode =
657 COMMON_OPCODE_ALLOC_EXTENTS;
658 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0;
659 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length =
660 sizeof (IOCTL_COMMON_EXTENTS);
661 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0;
662 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0;
663 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0;
664
665 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */
666
667 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload;
668 ep->params.request.RscType = type;
669
670 count = min(count, MAX_EXTENTS);
671 ep->params.request.RscCnt = count;
672
673 return;
674
675 } /* emlxs_mb_alloc_extents() */
676
677
678 /* SLI4 */
679 /*ARGSUSED*/
680 extern void
emlxs_mb_dealloc_extents(emlxs_hba_t * hba,MAILBOXQ * mbq,uint16_t type)681 emlxs_mb_dealloc_extents(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type)
682 {
683 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
684 IOCTL_COMMON_EXTENTS *ep;
685
686 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
687 mbq->nonembed = NULL;
688 mbq->mbox_cmpl = NULL; /* no cmpl needed */
689 mbq->port = (void *)&PPORT;
690
691 mb4->un.varSLIConfig.be.embedded = 1;
692 mb4->mbxCommand = MBX_SLI_CONFIG;
693 mb4->mbxOwner = OWN_HOST;
694
695 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
696 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem =
697 IOCTL_SUBSYSTEM_COMMON;
698 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode =
699 COMMON_OPCODE_DEALLOC_EXTENTS;
700 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0;
701 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length =
702 sizeof (IOCTL_COMMON_EXTENTS);
703 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0;
704 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0;
705 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0;
706
707 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */
708
709 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload;
710 ep->params.request.RscType = type;
711
712 return;
713
714 } /* emlxs_mb_dealloc_extents() */
715
716
717 /* SLI4 */
718 /*ARGSUSED*/
719 extern void
emlxs_mb_wq_create(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t num)720 emlxs_mb_wq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
721 {
722 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
723 IOCTL_FCOE_WQ_CREATE *qp;
724 IOCTL_FCOE_WQ_CREATE_V1 *qp1;
725 uint64_t addr;
726 int i;
727
728 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
729 mbq->nonembed = NULL;
730 mbq->mbox_cmpl = NULL; /* no cmpl needed */
731 mbq->port = (void *)&PPORT;
732
733 /*
734 * Signifies an embedded command
735 */
736 mb4->un.varSLIConfig.be.embedded = 1;
737
738 mb4->mbxCommand = MBX_SLI_CONFIG;
739 mb4->mbxOwner = OWN_HOST;
740
741 switch (hba->sli.sli4.param.WQV) {
742 case 0:
743 mb4->un.varSLIConfig.be.payload_length =
744 sizeof (IOCTL_FCOE_WQ_CREATE) + IOCTL_HEADER_SZ;
745 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
746 IOCTL_SUBSYSTEM_FCOE;
747 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
748 FCOE_OPCODE_WQ_CREATE;
749 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
750 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
751 sizeof (IOCTL_FCOE_WQ_CREATE);
752 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0;
753
754 addr = hba->sli.sli4.wq[num].addr.phys;
755 qp = (IOCTL_FCOE_WQ_CREATE *)&mb4->un.varSLIConfig.payload;
756
757 qp->params.request.CQId = hba->sli.sli4.wq[num].cqid;
758
759 qp->params.request.NumPages = EMLXS_NUM_WQ_PAGES;
760 for (i = 0; i < EMLXS_NUM_WQ_PAGES; i++) {
761 qp->params.request.Pages[i].addrLow = PADDR_LO(addr);
762 qp->params.request.Pages[i].addrHigh = PADDR_HI(addr);
763 addr += 4096;
764 }
765
766 break;
767
768 case 1:
769 default:
770 mb4->un.varSLIConfig.be.payload_length =
771 sizeof (IOCTL_FCOE_WQ_CREATE_V1) + IOCTL_HEADER_SZ;
772 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
773 IOCTL_SUBSYSTEM_FCOE;
774 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
775 FCOE_OPCODE_WQ_CREATE;
776 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
777 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
778 sizeof (IOCTL_FCOE_WQ_CREATE_V1);
779 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1;
780
781 addr = hba->sli.sli4.wq[num].addr.phys;
782 qp1 = (IOCTL_FCOE_WQ_CREATE_V1 *)&mb4->un.varSLIConfig.payload;
783
784 qp1->params.request.CQId = hba->sli.sli4.wq[num].cqid;
785 qp1->params.request.NumPages = EMLXS_NUM_WQ_PAGES;
786
787 qp1->params.request.WqeCnt = WQ_DEPTH;
788 qp1->params.request.WqeSize = WQE_SIZE_64_BYTES;
789 qp1->params.request.PageSize = WQ_PAGE_SIZE_4K;
790
791 for (i = 0; i < EMLXS_NUM_WQ_PAGES; i++) {
792 qp1->params.request.Pages[i].addrLow = PADDR_LO(addr);
793 qp1->params.request.Pages[i].addrHigh = PADDR_HI(addr);
794 addr += 4096;
795 }
796
797 break;
798 }
799
800 return;
801
802 } /* emlxs_mb_wq_create() */
803
804
805 /* SLI4 */
806 /*ARGSUSED*/
807 extern void
emlxs_mb_rq_create(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t num)808 emlxs_mb_rq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
809 {
810 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
811 IOCTL_FCOE_RQ_CREATE *qp;
812 IOCTL_FCOE_RQ_CREATE_V1 *qp1;
813 uint64_t addr;
814
815 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
816 mbq->nonembed = NULL;
817 mbq->mbox_cmpl = NULL; /* no cmpl needed */
818 mbq->port = (void *)&PPORT;
819
820 /*
821 * Signifies an embedded command
822 */
823 mb4->un.varSLIConfig.be.embedded = 1;
824
825 mb4->mbxCommand = MBX_SLI_CONFIG;
826 mb4->mbxOwner = OWN_HOST;
827
828 switch (hba->sli.sli4.param.RQV) {
829 case 0:
830 mb4->un.varSLIConfig.be.payload_length =
831 sizeof (IOCTL_FCOE_RQ_CREATE) + IOCTL_HEADER_SZ;
832 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
833 IOCTL_SUBSYSTEM_FCOE;
834 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
835 FCOE_OPCODE_RQ_CREATE;
836 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
837 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
838 sizeof (IOCTL_FCOE_RQ_CREATE);
839 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0;
840
841 addr = hba->sli.sli4.rq[num].addr.phys;
842
843 qp = (IOCTL_FCOE_RQ_CREATE *)&mb4->un.varSLIConfig.payload;
844
845 qp->params.request.RQContext.RqeCnt = RQ_DEPTH_EXPONENT;
846 qp->params.request.RQContext.BufferSize = RQB_DATA_SIZE;
847 qp->params.request.RQContext.CQId =
848 hba->sli.sli4.rq[num].cqid;
849
850 qp->params.request.NumPages = 1;
851 qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
852 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
853
854 break;
855
856 case 1:
857 default:
858 mb4->un.varSLIConfig.be.payload_length =
859 sizeof (IOCTL_FCOE_RQ_CREATE_V1) + IOCTL_HEADER_SZ;
860 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
861 IOCTL_SUBSYSTEM_FCOE;
862 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
863 FCOE_OPCODE_RQ_CREATE;
864 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
865 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
866 sizeof (IOCTL_FCOE_RQ_CREATE_V1);
867 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1;
868
869 addr = hba->sli.sli4.rq[num].addr.phys;
870
871 qp1 = (IOCTL_FCOE_RQ_CREATE_V1 *)&mb4->un.varSLIConfig.payload;
872
873 qp1->params.request.RQContext.RqeCnt = RQ_DEPTH;
874 qp1->params.request.RQContext.RqeSize = RQE_SIZE_8_BYTES;
875 qp1->params.request.RQContext.PageSize = RQ_PAGE_SIZE_4K;
876
877 qp1->params.request.RQContext.BufferSize = RQB_DATA_SIZE;
878 qp1->params.request.RQContext.CQId =
879 hba->sli.sli4.rq[num].cqid;
880
881 qp1->params.request.NumPages = 1;
882 qp1->params.request.Pages[0].addrLow = PADDR_LO(addr);
883 qp1->params.request.Pages[0].addrHigh = PADDR_HI(addr);
884
885 break;
886 }
887
888 return;
889
890 } /* emlxs_mb_rq_create() */
891
892
893 /* SLI4 */
894 /*ARGSUSED*/
895 extern void
emlxs_mb_mq_create(emlxs_hba_t * hba,MAILBOXQ * mbq)896 emlxs_mb_mq_create(emlxs_hba_t *hba, MAILBOXQ *mbq)
897 {
898 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
899 IOCTL_COMMON_MQ_CREATE *qp;
900 uint64_t addr;
901
902 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
903 mbq->nonembed = NULL;
904 mbq->mbox_cmpl = NULL; /* no cmpl needed */
905 mbq->port = (void *)&PPORT;
906
907 /*
908 * Signifies an embedded command
909 */
910 mb4->un.varSLIConfig.be.embedded = 1;
911
912 mb4->mbxCommand = MBX_SLI_CONFIG;
913 mb4->mbxOwner = OWN_HOST;
914 mb4->un.varSLIConfig.be.payload_length =
915 sizeof (IOCTL_COMMON_MQ_CREATE) + IOCTL_HEADER_SZ;
916 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
917 IOCTL_SUBSYSTEM_COMMON;
918 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_MQ_CREATE;
919 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
920 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
921 sizeof (IOCTL_COMMON_MQ_CREATE);
922
923 addr = hba->sli.sli4.mq.addr.phys;
924 qp = (IOCTL_COMMON_MQ_CREATE *)&mb4->un.varSLIConfig.payload;
925
926 qp->params.request.MQContext.Size = MQ_ELEMENT_COUNT_16;
927 qp->params.request.MQContext.Valid = 1;
928 qp->params.request.MQContext.CQId = hba->sli.sli4.mq.cqid;
929
930 qp->params.request.NumPages = 1;
931 qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
932 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
933
934 return;
935
936 } /* emlxs_mb_mq_create() */
937
938
939 /* SLI4 */
940 /*ARGSUSED*/
941 extern void
emlxs_mb_mq_create_ext(emlxs_hba_t * hba,MAILBOXQ * mbq)942 emlxs_mb_mq_create_ext(emlxs_hba_t *hba, MAILBOXQ *mbq)
943 {
944 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
945 IOCTL_COMMON_MQ_CREATE_EXT *qp;
946 IOCTL_COMMON_MQ_CREATE_EXT_V1 *qp1;
947 uint64_t addr;
948
949 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
950 mbq->nonembed = NULL;
951 mbq->mbox_cmpl = NULL; /* no cmpl needed */
952 mbq->port = (void *)&PPORT;
953
954 /*
955 * Signifies an embedded command
956 */
957 mb4->un.varSLIConfig.be.embedded = 1;
958
959 mb4->mbxCommand = MBX_SLI_CONFIG;
960 mb4->mbxOwner = OWN_HOST;
961
962 switch (hba->sli.sli4.param.MQV) {
963 case 0:
964 mb4->un.varSLIConfig.be.payload_length =
965 sizeof (IOCTL_COMMON_MQ_CREATE_EXT) + IOCTL_HEADER_SZ;
966 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
967 IOCTL_SUBSYSTEM_COMMON;
968 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
969 COMMON_OPCODE_MQ_CREATE_EXT;
970 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
971 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
972 sizeof (IOCTL_COMMON_MQ_CREATE_EXT);
973 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0;
974
975 addr = hba->sli.sli4.mq.addr.phys;
976 qp = (IOCTL_COMMON_MQ_CREATE_EXT *)
977 &mb4->un.varSLIConfig.payload;
978
979 qp->params.request.num_pages = 1;
980 qp->params.request.async_event_bitmap =
981 ASYNC_LINK_EVENT | ASYNC_FCF_EVENT | ASYNC_GROUP5_EVENT;
982 qp->params.request.context.Size = MQ_ELEMENT_COUNT_16;
983 qp->params.request.context.Valid = 1;
984 qp->params.request.context.CQId = hba->sli.sli4.mq.cqid;
985
986 qp->params.request.pages[0].addrLow = PADDR_LO(addr);
987 qp->params.request.pages[0].addrHigh = PADDR_HI(addr);
988
989 break;
990
991 case 1:
992 default:
993 mb4->un.varSLIConfig.be.payload_length =
994 sizeof (IOCTL_COMMON_MQ_CREATE) + IOCTL_HEADER_SZ;
995 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
996 IOCTL_SUBSYSTEM_COMMON;
997 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
998 COMMON_OPCODE_MQ_CREATE_EXT;
999 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
1000 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
1001 sizeof (IOCTL_COMMON_MQ_CREATE_EXT_V1);
1002 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1;
1003
1004 addr = hba->sli.sli4.mq.addr.phys;
1005 qp1 = (IOCTL_COMMON_MQ_CREATE_EXT_V1 *)
1006 &mb4->un.varSLIConfig.payload;
1007
1008 qp1->params.request.num_pages = 1;
1009 qp1->params.request.async_event_bitmap =
1010 ASYNC_LINK_EVENT | ASYNC_FCF_EVENT | ASYNC_GROUP5_EVENT |
1011 ASYNC_FC_EVENT | ASYNC_PORT_EVENT;
1012 qp1->params.request.context.Size = MQ_ELEMENT_COUNT_16;
1013 qp1->params.request.context.Valid = 1;
1014 qp1->params.request.CQId = hba->sli.sli4.mq.cqid;
1015
1016 qp1->params.request.pages[0].addrLow = PADDR_LO(addr);
1017 qp1->params.request.pages[0].addrHigh = PADDR_HI(addr);
1018
1019 break;
1020 }
1021
1022 return;
1023
1024 } /* emlxs_mb_mq_create_ext() */
1025
1026
1027 /*ARGSUSED*/
1028 extern void
emlxs_mb_async_event(emlxs_hba_t * hba,MAILBOXQ * mbq)1029 emlxs_mb_async_event(emlxs_hba_t *hba, MAILBOXQ *mbq)
1030 {
1031 MAILBOX *mb = (MAILBOX *)mbq;
1032
1033 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1034
1035 mb->mbxCommand = MBX_ASYNC_EVENT;
1036 mb->mbxOwner = OWN_HOST;
1037 mb->un.varWords[0] = hba->channel_els;
1038 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1039 mbq->port = (void *)&PPORT;
1040
1041 return;
1042
1043 } /* emlxs_mb_async_event() */
1044
1045
1046 /*ARGSUSED*/
1047 extern void
emlxs_mb_heartbeat(emlxs_hba_t * hba,MAILBOXQ * mbq)1048 emlxs_mb_heartbeat(emlxs_hba_t *hba, MAILBOXQ *mbq)
1049 {
1050 MAILBOX *mb = (MAILBOX *)mbq;
1051
1052 bzero((void *) mb, MAILBOX_CMD_BSIZE);
1053
1054 mb->mbxCommand = MBX_HEARTBEAT;
1055 mb->mbxOwner = OWN_HOST;
1056 mbq->mbox_cmpl = NULL; /* no cmpl needed for hbeat */
1057 mbq->port = (void *)&PPORT;
1058
1059 return;
1060
1061 } /* emlxs_mb_heartbeat() */
1062
1063
1064 #ifdef MSI_SUPPORT
1065
1066 /*ARGSUSED*/
1067 extern void
emlxs_mb_config_msi(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t * intr_map,uint32_t intr_count)1068 emlxs_mb_config_msi(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map,
1069 uint32_t intr_count)
1070 {
1071 MAILBOX *mb = (MAILBOX *)mbq;
1072 uint16_t i;
1073 uint32_t mask;
1074
1075 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1076
1077 mb->mbxCommand = MBX_CONFIG_MSI;
1078
1079 /* Set the default message id to zero */
1080 mb->un.varCfgMSI.defaultPresent = 1;
1081 mb->un.varCfgMSI.defaultMessageNumber = 0;
1082
1083 for (i = 1; i < intr_count; i++) {
1084 mask = intr_map[i];
1085
1086 mb->un.varCfgMSI.attConditions |= mask;
1087
1088 #ifdef EMLXS_BIG_ENDIAN
1089 if (mask & HA_R0ATT) {
1090 mb->un.varCfgMSI.messageNumberByHA[3] = i;
1091 }
1092 if (mask & HA_R1ATT) {
1093 mb->un.varCfgMSI.messageNumberByHA[7] = i;
1094 }
1095 if (mask & HA_R2ATT) {
1096 mb->un.varCfgMSI.messageNumberByHA[11] = i;
1097 }
1098 if (mask & HA_R3ATT) {
1099 mb->un.varCfgMSI.messageNumberByHA[15] = i;
1100 }
1101 if (mask & HA_LATT) {
1102 mb->un.varCfgMSI.messageNumberByHA[29] = i;
1103 }
1104 if (mask & HA_MBATT) {
1105 mb->un.varCfgMSI.messageNumberByHA[30] = i;
1106 }
1107 if (mask & HA_ERATT) {
1108 mb->un.varCfgMSI.messageNumberByHA[31] = i;
1109 }
1110 #endif /* EMLXS_BIG_ENDIAN */
1111
1112 #ifdef EMLXS_LITTLE_ENDIAN
1113 /* Accounts for half word swap of LE architecture */
1114 if (mask & HA_R0ATT) {
1115 mb->un.varCfgMSI.messageNumberByHA[2] = i;
1116 }
1117 if (mask & HA_R1ATT) {
1118 mb->un.varCfgMSI.messageNumberByHA[6] = i;
1119 }
1120 if (mask & HA_R2ATT) {
1121 mb->un.varCfgMSI.messageNumberByHA[10] = i;
1122 }
1123 if (mask & HA_R3ATT) {
1124 mb->un.varCfgMSI.messageNumberByHA[14] = i;
1125 }
1126 if (mask & HA_LATT) {
1127 mb->un.varCfgMSI.messageNumberByHA[28] = i;
1128 }
1129 if (mask & HA_MBATT) {
1130 mb->un.varCfgMSI.messageNumberByHA[31] = i;
1131 }
1132 if (mask & HA_ERATT) {
1133 mb->un.varCfgMSI.messageNumberByHA[30] = i;
1134 }
1135 #endif /* EMLXS_LITTLE_ENDIAN */
1136 }
1137
1138 mb->mbxOwner = OWN_HOST;
1139 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1140 mbq->port = (void *)&PPORT;
1141
1142 return;
1143
1144 } /* emlxs_mb_config_msi() */
1145
1146
1147 /*ARGSUSED*/
1148 extern void
emlxs_mb_config_msix(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t * intr_map,uint32_t intr_count)1149 emlxs_mb_config_msix(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map,
1150 uint32_t intr_count)
1151 {
1152 MAILBOX *mb = (MAILBOX *)mbq;
1153 uint8_t i;
1154 uint32_t mask;
1155
1156 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1157
1158 mb->mbxCommand = MBX_CONFIG_MSIX;
1159
1160 /* Set the default message id to zero */
1161 mb->un.varCfgMSIX.defaultPresent = 1;
1162 mb->un.varCfgMSIX.defaultMessageNumber = 0;
1163
1164 for (i = 1; i < intr_count; i++) {
1165 mask = intr_map[i];
1166
1167 mb->un.varCfgMSIX.attConditions1 |= mask;
1168
1169 #ifdef EMLXS_BIG_ENDIAN
1170 if (mask & HA_R0ATT) {
1171 mb->un.varCfgMSIX.messageNumberByHA[3] = i;
1172 }
1173 if (mask & HA_R1ATT) {
1174 mb->un.varCfgMSIX.messageNumberByHA[7] = i;
1175 }
1176 if (mask & HA_R2ATT) {
1177 mb->un.varCfgMSIX.messageNumberByHA[11] = i;
1178 }
1179 if (mask & HA_R3ATT) {
1180 mb->un.varCfgMSIX.messageNumberByHA[15] = i;
1181 }
1182 if (mask & HA_LATT) {
1183 mb->un.varCfgMSIX.messageNumberByHA[29] = i;
1184 }
1185 if (mask & HA_MBATT) {
1186 mb->un.varCfgMSIX.messageNumberByHA[30] = i;
1187 }
1188 if (mask & HA_ERATT) {
1189 mb->un.varCfgMSIX.messageNumberByHA[31] = i;
1190 }
1191 #endif /* EMLXS_BIG_ENDIAN */
1192
1193 #ifdef EMLXS_LITTLE_ENDIAN
1194 /* Accounts for word swap of LE architecture */
1195 if (mask & HA_R0ATT) {
1196 mb->un.varCfgMSIX.messageNumberByHA[0] = i;
1197 }
1198 if (mask & HA_R1ATT) {
1199 mb->un.varCfgMSIX.messageNumberByHA[4] = i;
1200 }
1201 if (mask & HA_R2ATT) {
1202 mb->un.varCfgMSIX.messageNumberByHA[8] = i;
1203 }
1204 if (mask & HA_R3ATT) {
1205 mb->un.varCfgMSIX.messageNumberByHA[12] = i;
1206 }
1207 if (mask & HA_LATT) {
1208 mb->un.varCfgMSIX.messageNumberByHA[30] = i;
1209 }
1210 if (mask & HA_MBATT) {
1211 mb->un.varCfgMSIX.messageNumberByHA[29] = i;
1212 }
1213 if (mask & HA_ERATT) {
1214 mb->un.varCfgMSIX.messageNumberByHA[28] = i;
1215 }
1216 #endif /* EMLXS_LITTLE_ENDIAN */
1217 }
1218
1219 mb->mbxOwner = OWN_HOST;
1220 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1221 mbq->port = (void *)&PPORT;
1222
1223 return;
1224
1225 } /* emlxs_mb_config_msix() */
1226
1227
1228 #endif /* MSI_SUPPORT */
1229
1230
1231 /*ARGSUSED*/
1232 extern void
emlxs_mb_reset_ring(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t ringno)1233 emlxs_mb_reset_ring(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t ringno)
1234 {
1235 MAILBOX *mb = (MAILBOX *)mbq;
1236
1237 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1238
1239 mb->mbxCommand = MBX_RESET_RING;
1240 mb->un.varRstRing.ring_no = ringno;
1241 mb->mbxOwner = OWN_HOST;
1242 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1243 mbq->port = (void *)&PPORT;
1244
1245 return;
1246
1247 } /* emlxs_mb_reset_ring() */
1248
1249
1250 /*ARGSUSED*/
1251 extern void
emlxs_mb_dump_vpd(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t offset)1252 emlxs_mb_dump_vpd(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset)
1253 {
1254
1255 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1256 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
1257
1258 /* Clear the local dump_region */
1259 bzero(hba->sli.sli4.dump_region.virt,
1260 hba->sli.sli4.dump_region.size);
1261
1262 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
1263
1264 mb4->mbxCommand = MBX_DUMP_MEMORY;
1265 mb4->un.varDmp4.type = DMP_NV_PARAMS;
1266 mb4->un.varDmp4.entry_index = offset;
1267 mb4->un.varDmp4.region_id = DMP_VPD_REGION;
1268
1269 mb4->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size;
1270 mb4->un.varDmp4.addrHigh =
1271 PADDR_HI(hba->sli.sli4.dump_region.phys);
1272 mb4->un.varDmp4.addrLow =
1273 PADDR_LO(hba->sli.sli4.dump_region.phys);
1274 mb4->un.varDmp4.rsp_cnt = 0;
1275
1276 mb4->mbxOwner = OWN_HOST;
1277
1278 } else {
1279 MAILBOX *mb = (MAILBOX *)mbq;
1280
1281 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1282
1283 mb->mbxCommand = MBX_DUMP_MEMORY;
1284 mb->un.varDmp.cv = 1;
1285 mb->un.varDmp.type = DMP_NV_PARAMS;
1286 mb->un.varDmp.entry_index = offset;
1287 mb->un.varDmp.region_id = DMP_VPD_REGION;
1288
1289 /* limited by mailbox size */
1290 mb->un.varDmp.word_cnt = DMP_VPD_DUMP_WCOUNT;
1291
1292 mb->un.varDmp.co = 0;
1293 mb->un.varDmp.resp_offset = 0;
1294 mb->mbxOwner = OWN_HOST;
1295 }
1296
1297 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1298 mbq->port = (void *)&PPORT;
1299
1300 } /* emlxs_mb_dump_vpd() */
1301
1302
1303 /* SLI4 */
1304 /*ARGSUSED*/
1305 extern void
emlxs_mb_dump_fcoe(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t offset)1306 emlxs_mb_dump_fcoe(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset)
1307 {
1308 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
1309
1310 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
1311 return;
1312 }
1313
1314 /* Clear the local dump_region */
1315 bzero(hba->sli.sli4.dump_region.virt,
1316 hba->sli.sli4.dump_region.size);
1317
1318 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
1319
1320 mb4->mbxCommand = MBX_DUMP_MEMORY;
1321 mb4->un.varDmp4.type = DMP_NV_PARAMS;
1322 mb4->un.varDmp4.entry_index = offset;
1323 mb4->un.varDmp4.region_id = DMP_FCOE_REGION;
1324
1325 mb4->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size;
1326 mb4->un.varDmp4.addrHigh =
1327 PADDR_HI(hba->sli.sli4.dump_region.phys);
1328 mb4->un.varDmp4.addrLow =
1329 PADDR_LO(hba->sli.sli4.dump_region.phys);
1330 mb4->un.varDmp4.rsp_cnt = 0;
1331
1332 mb4->mbxOwner = OWN_HOST;
1333
1334 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1335 mbq->port = (void *)&PPORT;
1336
1337 } /* emlxs_mb_dump_fcoe() */
1338
1339
1340 /*ARGSUSED*/
1341 extern void
emlxs_mb_dump(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t offset,uint32_t words)1342 emlxs_mb_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset, uint32_t words)
1343 {
1344
1345 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1346 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
1347
1348 /* Clear the local dump_region */
1349 bzero(hba->sli.sli4.dump_region.virt,
1350 hba->sli.sli4.dump_region.size);
1351
1352 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
1353
1354 mb4->mbxCommand = MBX_DUMP_MEMORY;
1355 mb4->un.varDmp4.type = DMP_MEM_REG;
1356 mb4->un.varDmp4.entry_index = offset;
1357 mb4->un.varDmp4.region_id = 0;
1358
1359 mb4->un.varDmp4.available_cnt = min((words*4),
1360 hba->sli.sli4.dump_region.size);
1361 mb4->un.varDmp4.addrHigh =
1362 PADDR_HI(hba->sli.sli4.dump_region.phys);
1363 mb4->un.varDmp4.addrLow =
1364 PADDR_LO(hba->sli.sli4.dump_region.phys);
1365 mb4->un.varDmp4.rsp_cnt = 0;
1366
1367 mb4->mbxOwner = OWN_HOST;
1368
1369 } else {
1370
1371 MAILBOX *mb = (MAILBOX *)mbq;
1372
1373 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1374
1375 mb->mbxCommand = MBX_DUMP_MEMORY;
1376 mb->un.varDmp.type = DMP_MEM_REG;
1377 mb->un.varDmp.word_cnt = words;
1378 mb->un.varDmp.base_adr = offset;
1379
1380 mb->un.varDmp.co = 0;
1381 mb->un.varDmp.resp_offset = 0;
1382 mb->mbxOwner = OWN_HOST;
1383 }
1384
1385 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1386 mbq->port = (void *)&PPORT;
1387
1388 return;
1389
1390 } /* emlxs_mb_dump() */
1391
1392
1393 /*
1394 * emlxs_mb_read_nv Issue a READ NVPARAM mailbox command
1395 */
1396 /*ARGSUSED*/
1397 extern void
emlxs_mb_read_nv(emlxs_hba_t * hba,MAILBOXQ * mbq)1398 emlxs_mb_read_nv(emlxs_hba_t *hba, MAILBOXQ *mbq)
1399 {
1400 MAILBOX *mb = (MAILBOX *)mbq;
1401
1402 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1403
1404 mb->mbxCommand = MBX_READ_NV;
1405 mb->mbxOwner = OWN_HOST;
1406 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1407 mbq->port = (void *)&PPORT;
1408
1409 } /* emlxs_mb_read_nv() */
1410
1411
1412 /*
1413 * emlxs_mb_read_rev Issue a READ REV mailbox command
1414 */
1415 /*ARGSUSED*/
1416 extern void
emlxs_mb_read_rev(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t v3)1417 emlxs_mb_read_rev(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t v3)
1418 {
1419 MAILBOX *mb = (MAILBOX *)mbq;
1420
1421 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1422 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1423 mbq->nonembed = NULL;
1424 } else {
1425 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1426
1427 mb->un.varRdRev.cv = 1;
1428
1429 if (v3) {
1430 mb->un.varRdRev.cv3 = 1;
1431 }
1432 }
1433
1434 mb->mbxCommand = MBX_READ_REV;
1435 mb->mbxOwner = OWN_HOST;
1436 mbq->mbox_cmpl = NULL;
1437 mbq->port = (void *)&PPORT;
1438
1439 } /* emlxs_mb_read_rev() */
1440
1441
1442 /*
1443 * emlxs_mb_run_biu_diag Issue a RUN_BIU_DIAG mailbox command
1444 */
1445 /*ARGSUSED*/
1446 extern uint32_t
emlxs_mb_run_biu_diag(emlxs_hba_t * hba,MAILBOXQ * mbq,uint64_t out,uint64_t in)1447 emlxs_mb_run_biu_diag(emlxs_hba_t *hba, MAILBOXQ *mbq, uint64_t out,
1448 uint64_t in)
1449 {
1450 MAILBOX *mb = (MAILBOX *)mbq;
1451
1452 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1453
1454 mb->mbxCommand = MBX_RUN_BIU_DIAG64;
1455 mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
1456 mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = PADDR_HI(out);
1457 mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = PADDR_LO(out);
1458 mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
1459 mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = PADDR_HI(in);
1460 mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = PADDR_LO(in);
1461 mb->mbxOwner = OWN_HOST;
1462 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1463 mbq->port = (void *)&PPORT;
1464
1465 return (0);
1466 } /* emlxs_mb_run_biu_diag() */
1467
1468
1469 /* This should only be called with active MBX_NOWAIT mailboxes */
1470 void
emlxs_mb_retry(emlxs_hba_t * hba,MAILBOXQ * mbq)1471 emlxs_mb_retry(emlxs_hba_t *hba, MAILBOXQ *mbq)
1472 {
1473 MAILBOX *mb;
1474 MAILBOX *mbox;
1475 int rc;
1476
1477 mbox = (MAILBOX *)emlxs_mem_get(hba, MEM_MBOX);
1478 if (!mbox) {
1479 return;
1480 }
1481 mb = (MAILBOX *)mbq;
1482 bcopy((uint8_t *)mb, (uint8_t *)mbox, MAILBOX_CMD_BSIZE);
1483 mbox->mbxOwner = OWN_HOST;
1484 mbox->mbxStatus = 0;
1485
1486 mutex_enter(&EMLXS_PORT_LOCK);
1487
1488 HBASTATS.MboxCompleted++;
1489
1490 if (mb->mbxStatus != 0) {
1491 HBASTATS.MboxError++;
1492 } else {
1493 HBASTATS.MboxGood++;
1494 }
1495
1496 hba->mbox_mbq = NULL;
1497 hba->mbox_queue_flag = 0;
1498
1499 mutex_exit(&EMLXS_PORT_LOCK);
1500
1501 rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0);
1502 if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
1503 emlxs_mem_put(hba, MEM_MBOX, (void *)mbox);
1504 }
1505 return;
1506
1507 } /* emlxs_mb_retry() */
1508
1509
1510 /* SLI3 */
1511 static uint32_t
emlxs_read_la_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)1512 emlxs_read_la_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
1513 {
1514 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
1515 MAILBOX *mb;
1516 MAILBOXQ *mbox;
1517 MATCHMAP *mp;
1518 READ_LA_VAR la;
1519 int i;
1520 uint32_t control;
1521
1522 mb = (MAILBOX *)mbq;
1523 if (mb->mbxStatus) {
1524 if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
1525 control = mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize;
1526 if (control == 0) {
1527 (void) emlxs_mb_read_la(hba, mbq);
1528 }
1529 emlxs_mb_retry(hba, mbq);
1530 return (1);
1531 }
1532 /* Enable Link Attention interrupts */
1533 mutex_enter(&EMLXS_PORT_LOCK);
1534
1535 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
1536 hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
1537 WRITE_CSR_REG(hba, FC_HC_REG(hba),
1538 hba->sli.sli3.hc_copy);
1539 #ifdef FMA_SUPPORT
1540 /* Access handle validation */
1541 EMLXS_CHK_ACC_HANDLE(hba,
1542 hba->sli.sli3.csr_acc_handle);
1543 #endif /* FMA_SUPPORT */
1544 }
1545
1546 mutex_exit(&EMLXS_PORT_LOCK);
1547 return (0);
1548 }
1549 bcopy((void *)&mb->un.varReadLA, (void *)&la, sizeof (READ_LA_VAR));
1550
1551 mp = (MATCHMAP *)mbq->bp;
1552 if (mp) {
1553 bcopy((caddr_t)mp->virt, (caddr_t)port->alpa_map, 128);
1554 } else {
1555 bzero((caddr_t)port->alpa_map, 128);
1556 }
1557
1558 if (la.attType == AT_LINK_UP) {
1559 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkup_atten_msg,
1560 "tag=%d -> %d ALPA=%x",
1561 (uint32_t)hba->link_event_tag,
1562 (uint32_t)la.eventTag,
1563 (uint32_t)la.granted_AL_PA);
1564 } else {
1565 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkdown_atten_msg,
1566 "tag=%d -> %d ALPA=%x",
1567 (uint32_t)hba->link_event_tag,
1568 (uint32_t)la.eventTag,
1569 (uint32_t)la.granted_AL_PA);
1570 }
1571
1572 if (la.pb) {
1573 hba->flag |= FC_BYPASSED_MODE;
1574 } else {
1575 hba->flag &= ~FC_BYPASSED_MODE;
1576 }
1577
1578 if (hba->link_event_tag == la.eventTag) {
1579 HBASTATS.LinkMultiEvent++;
1580 } else if (hba->link_event_tag + 1 < la.eventTag) {
1581 HBASTATS.LinkMultiEvent++;
1582
1583 /* Make sure link is declared down */
1584 emlxs_linkdown(hba);
1585 }
1586
1587 hba->link_event_tag = la.eventTag;
1588 port->lip_type = 0;
1589
1590 /* If link not already up then declare it up now */
1591 if ((la.attType == AT_LINK_UP) && (hba->state < FC_LINK_UP)) {
1592
1593 #ifdef MENLO_SUPPORT
1594 if ((hba->model_info.device_id == PCI_DEVICE_ID_HORNET) &&
1595 (hba->flag & (FC_ILB_MODE | FC_ELB_MODE))) {
1596 la.topology = TOPOLOGY_LOOP;
1597 la.granted_AL_PA = 0;
1598 port->alpa_map[0] = 1;
1599 port->alpa_map[1] = 0;
1600 la.lipType = LT_PORT_INIT;
1601 }
1602 #endif /* MENLO_SUPPORT */
1603 /* Save the linkspeed */
1604 hba->linkspeed = la.UlnkSpeed;
1605
1606 /* Check for old model adapters that only */
1607 /* supported 1Gb */
1608 if ((hba->linkspeed == 0) &&
1609 (hba->model_info.chip & EMLXS_DRAGONFLY_CHIP)) {
1610 hba->linkspeed = LA_1GHZ_LINK;
1611 }
1612
1613 if ((hba->topology = la.topology) == TOPOLOGY_LOOP) {
1614 port->granted_alpa = la.granted_AL_PA;
1615 port->did = port->granted_alpa;
1616 port->lip_type = la.lipType;
1617 if (hba->flag & FC_SLIM2_MODE) {
1618 i = la.un.lilpBde64.tus.f.bdeSize;
1619 } else {
1620 i = la.un.lilpBde.bdeSize;
1621 }
1622
1623 if (i == 0) {
1624 port->alpa_map[0] = 0;
1625 } else {
1626 uint8_t *alpa_map;
1627 uint32_t j;
1628
1629 /* Check number of devices in map */
1630 if (port->alpa_map[0] > 127) {
1631 port->alpa_map[0] = 127;
1632 }
1633
1634 alpa_map = (uint8_t *)port->alpa_map;
1635
1636 EMLXS_MSGF(EMLXS_CONTEXT,
1637 &emlxs_link_atten_msg,
1638 "alpa_map: %d device(s): "
1639 "%02x %02x %02x %02x %02x %02x "
1640 "%02x", alpa_map[0], alpa_map[1],
1641 alpa_map[2], alpa_map[3],
1642 alpa_map[4], alpa_map[5],
1643 alpa_map[6], alpa_map[7]);
1644
1645 for (j = 8; j <= alpa_map[0]; j += 8) {
1646 EMLXS_MSGF(EMLXS_CONTEXT,
1647 &emlxs_link_atten_msg,
1648 "alpa_map: "
1649 "%02x %02x %02x %02x %02x "
1650 "%02x %02x %02x",
1651 alpa_map[j],
1652 alpa_map[j + 1],
1653 alpa_map[j + 2],
1654 alpa_map[j + 3],
1655 alpa_map[j + 4],
1656 alpa_map[j + 5],
1657 alpa_map[j + 6],
1658 alpa_map[j + 7]);
1659 }
1660 }
1661 }
1662 #ifdef MENLO_SUPPORT
1663 /* Check if Menlo maintenance mode is enabled */
1664 if (hba->model_info.device_id ==
1665 PCI_DEVICE_ID_HORNET) {
1666 if (la.mm == 1) {
1667 EMLXS_MSGF(EMLXS_CONTEXT,
1668 &emlxs_link_atten_msg,
1669 "Maintenance Mode enabled.");
1670
1671 mutex_enter(&EMLXS_PORT_LOCK);
1672 hba->flag |= FC_MENLO_MODE;
1673 mutex_exit(&EMLXS_PORT_LOCK);
1674
1675 mutex_enter(&EMLXS_LINKUP_LOCK);
1676 cv_broadcast(&EMLXS_LINKUP_CV);
1677 mutex_exit(&EMLXS_LINKUP_LOCK);
1678 } else {
1679 EMLXS_MSGF(EMLXS_CONTEXT,
1680 &emlxs_link_atten_msg,
1681 "Maintenance Mode disabled.");
1682 }
1683
1684 /* Check FCoE attention bit */
1685 if (la.fa == 1) {
1686 emlxs_thread_spawn(hba,
1687 emlxs_fcoe_attention_thread,
1688 0, 0);
1689 }
1690 }
1691 #endif /* MENLO_SUPPORT */
1692
1693 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1694 MEM_MBOX))) {
1695 /* This should turn on DELAYED ABTS for */
1696 /* ELS timeouts */
1697 emlxs_mb_set_var(hba, mbox, 0x00052198, 0x1);
1698
1699 emlxs_mb_put(hba, mbox);
1700 }
1701
1702 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1703 MEM_MBOX))) {
1704 /* If link not already down then */
1705 /* declare it down now */
1706 if (emlxs_mb_read_sparam(hba, mbox) == 0) {
1707 emlxs_mb_put(hba, mbox);
1708 } else {
1709 emlxs_mem_put(hba, MEM_MBOX,
1710 (void *)mbox);
1711 }
1712 }
1713
1714 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1715 MEM_MBOX))) {
1716 emlxs_mb_config_link(hba, mbox);
1717
1718 emlxs_mb_put(hba, mbox);
1719 }
1720
1721 /* Declare the linkup here */
1722 emlxs_linkup(hba);
1723 }
1724
1725 /* If link not already down then declare it down now */
1726 else if (la.attType == AT_LINK_DOWN) {
1727 /* Make sure link is declared down */
1728 emlxs_linkdown(hba);
1729 }
1730
1731 /* Enable Link attention interrupt */
1732 mutex_enter(&EMLXS_PORT_LOCK);
1733
1734 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
1735 hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
1736 WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
1737 #ifdef FMA_SUPPORT
1738 /* Access handle validation */
1739 EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
1740 #endif /* FMA_SUPPORT */
1741 }
1742
1743 mutex_exit(&EMLXS_PORT_LOCK);
1744
1745 return (0);
1746
1747 } /* emlxs_read_la_mbcmpl() */
1748
1749
1750 extern uint32_t
emlxs_mb_read_la(emlxs_hba_t * hba,MAILBOXQ * mbq)1751 emlxs_mb_read_la(emlxs_hba_t *hba, MAILBOXQ *mbq)
1752 {
1753 MAILBOX *mb = (MAILBOX *)mbq;
1754 MATCHMAP *mp;
1755
1756 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1757
1758 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
1759 mb->mbxCommand = MBX_READ_LA64;
1760
1761 return (1);
1762 }
1763
1764 mb->mbxCommand = MBX_READ_LA64;
1765 mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
1766 mb->un.varReadLA.un.lilpBde64.addrHigh = PADDR_HI(mp->phys);
1767 mb->un.varReadLA.un.lilpBde64.addrLow = PADDR_LO(mp->phys);
1768 mb->mbxOwner = OWN_HOST;
1769 mbq->mbox_cmpl = emlxs_read_la_mbcmpl;
1770 mbq->port = (void *)&PPORT;
1771
1772 /*
1773 * save address for completion
1774 */
1775 mbq->bp = (void *)mp;
1776
1777 return (0);
1778
1779 } /* emlxs_mb_read_la() */
1780
1781
1782 /* SLI3 */
1783 static uint32_t
emlxs_clear_la_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)1784 emlxs_clear_la_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
1785 {
1786 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
1787 MAILBOX *mb;
1788 MAILBOXQ *mbox;
1789 emlxs_port_t *vport;
1790 uint32_t la_enable;
1791 int i, rc;
1792
1793 mb = (MAILBOX *)mbq;
1794 if (mb->mbxStatus) {
1795 la_enable = 1;
1796
1797 if (mb->mbxStatus == 0x1601) {
1798 /* Get a buffer which will be used for */
1799 /* mailbox commands */
1800 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1801 MEM_MBOX))) {
1802 /* Get link attention message */
1803 if (emlxs_mb_read_la(hba, mbox) == 0) {
1804 rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba,
1805 (MAILBOX *)mbox, MBX_NOWAIT, 0);
1806 if ((rc != MBX_BUSY) &&
1807 (rc != MBX_SUCCESS)) {
1808 emlxs_mem_put(hba,
1809 MEM_MBOX, (void *)mbox);
1810 }
1811 la_enable = 0;
1812 } else {
1813 emlxs_mem_put(hba, MEM_MBOX,
1814 (void *)mbox);
1815 }
1816 }
1817 }
1818
1819 mutex_enter(&EMLXS_PORT_LOCK);
1820 if (la_enable) {
1821 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
1822 /* Enable Link Attention interrupts */
1823 hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
1824 WRITE_CSR_REG(hba, FC_HC_REG(hba),
1825 hba->sli.sli3.hc_copy);
1826 #ifdef FMA_SUPPORT
1827 /* Access handle validation */
1828 EMLXS_CHK_ACC_HANDLE(hba,
1829 hba->sli.sli3.csr_acc_handle);
1830 #endif /* FMA_SUPPORT */
1831 }
1832 } else {
1833 if (hba->sli.sli3.hc_copy & HC_LAINT_ENA) {
1834 /* Disable Link Attention interrupts */
1835 hba->sli.sli3.hc_copy &= ~HC_LAINT_ENA;
1836 WRITE_CSR_REG(hba, FC_HC_REG(hba),
1837 hba->sli.sli3.hc_copy);
1838 #ifdef FMA_SUPPORT
1839 /* Access handle validation */
1840 EMLXS_CHK_ACC_HANDLE(hba,
1841 hba->sli.sli3.csr_acc_handle);
1842 #endif /* FMA_SUPPORT */
1843 }
1844 }
1845 mutex_exit(&EMLXS_PORT_LOCK);
1846
1847 return (0);
1848 }
1849 /* Enable on Link Attention interrupts */
1850 mutex_enter(&EMLXS_PORT_LOCK);
1851
1852 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
1853 hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
1854 WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
1855 #ifdef FMA_SUPPORT
1856 /* Access handle validation */
1857 EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
1858 #endif /* FMA_SUPPORT */
1859 }
1860
1861 if (hba->state >= FC_LINK_UP) {
1862 EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY);
1863 }
1864
1865 mutex_exit(&EMLXS_PORT_LOCK);
1866
1867 /* Adapter is now ready for FCP traffic */
1868 if (hba->state == FC_READY) {
1869
1870 /* Register vpi's for all ports that have did's */
1871 for (i = 0; i < MAX_VPORTS; i++) {
1872 vport = &VPORT(i);
1873
1874 if (!(vport->flag & EMLXS_PORT_BOUND) ||
1875 !(vport->did)) {
1876 continue;
1877 }
1878
1879 (void) emlxs_mb_reg_vpi(vport, NULL);
1880 }
1881
1882 /* Attempt to send any pending IO */
1883 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[hba->channel_fcp], 0);
1884 }
1885 return (0);
1886
1887 } /* emlxs_clear_la_mbcmpl() */
1888
1889
1890 /* SLI3 */
1891 extern void
emlxs_mb_clear_la(emlxs_hba_t * hba,MAILBOXQ * mbq)1892 emlxs_mb_clear_la(emlxs_hba_t *hba, MAILBOXQ *mbq)
1893 {
1894 MAILBOX *mb = (MAILBOX *)mbq;
1895
1896 #ifdef FC_RPI_CHECK
1897 emlxs_rpi_check(hba);
1898 #endif /* FC_RPI_CHECK */
1899
1900 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1901
1902 mb->un.varClearLA.eventTag = hba->link_event_tag;
1903 mb->mbxCommand = MBX_CLEAR_LA;
1904 mb->mbxOwner = OWN_HOST;
1905 mbq->mbox_cmpl = emlxs_clear_la_mbcmpl;
1906 mbq->port = (void *)&PPORT;
1907
1908 return;
1909
1910 } /* emlxs_mb_clear_la() */
1911
1912
1913 /*
1914 * emlxs_mb_read_status Issue a READ STATUS mailbox command
1915 */
1916 /*ARGSUSED*/
1917 extern void
emlxs_mb_read_status(emlxs_hba_t * hba,MAILBOXQ * mbq)1918 emlxs_mb_read_status(emlxs_hba_t *hba, MAILBOXQ *mbq)
1919 {
1920 MAILBOX *mb = (MAILBOX *)mbq;
1921
1922 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1923
1924 mb->mbxCommand = MBX_READ_STATUS;
1925 mb->mbxOwner = OWN_HOST;
1926 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1927 mbq->port = (void *)&PPORT;
1928
1929 } /* fc_read_status() */
1930
1931
1932 /*
1933 * emlxs_mb_read_lnk_stat Issue a LINK STATUS mailbox command
1934 */
1935 /*ARGSUSED*/
1936 extern void
emlxs_mb_read_lnk_stat(emlxs_hba_t * hba,MAILBOXQ * mbq)1937 emlxs_mb_read_lnk_stat(emlxs_hba_t *hba, MAILBOXQ *mbq)
1938 {
1939 MAILBOX *mb = (MAILBOX *)mbq;
1940
1941 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1942
1943 mb->mbxCommand = MBX_READ_LNK_STAT;
1944 mb->mbxOwner = OWN_HOST;
1945 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1946 mbq->port = (void *)&PPORT;
1947
1948 } /* emlxs_mb_read_lnk_stat() */
1949
1950
1951
1952
1953
1954
1955 /*
1956 * emlxs_mb_config_ring Issue a CONFIG RING mailbox command
1957 */
1958 extern void
emlxs_mb_config_ring(emlxs_hba_t * hba,int32_t ring,MAILBOXQ * mbq)1959 emlxs_mb_config_ring(emlxs_hba_t *hba, int32_t ring, MAILBOXQ *mbq)
1960 {
1961 MAILBOX *mb = (MAILBOX *)mbq;
1962 int32_t i;
1963 int32_t j;
1964
1965 bzero((void *)mb, MAILBOX_CMD_BSIZE);
1966
1967 j = 0;
1968 for (i = 0; i < ring; i++) {
1969 j += hba->sli.sli3.ring_masks[i];
1970 }
1971
1972 for (i = 0; i < hba->sli.sli3.ring_masks[ring]; i++) {
1973 if ((j + i) >= 6) {
1974 break;
1975 }
1976
1977 mb->un.varCfgRing.rrRegs[i].rval =
1978 hba->sli.sli3.ring_rval[j + i];
1979 mb->un.varCfgRing.rrRegs[i].rmask =
1980 hba->sli.sli3.ring_rmask[j + i];
1981 mb->un.varCfgRing.rrRegs[i].tval =
1982 hba->sli.sli3.ring_tval[j + i];
1983 mb->un.varCfgRing.rrRegs[i].tmask =
1984 hba->sli.sli3.ring_tmask[j + i];
1985 }
1986
1987 mb->un.varCfgRing.ring = ring;
1988 mb->un.varCfgRing.profile = 0;
1989 mb->un.varCfgRing.maxOrigXchg = 0;
1990 mb->un.varCfgRing.maxRespXchg = 0;
1991 mb->un.varCfgRing.recvNotify = 1;
1992 mb->un.varCfgRing.numMask = hba->sli.sli3.ring_masks[ring];
1993 mb->mbxCommand = MBX_CONFIG_RING;
1994 mb->mbxOwner = OWN_HOST;
1995 mbq->mbox_cmpl = NULL; /* no cmpl needed */
1996 mbq->port = (void *)&PPORT;
1997
1998 return;
1999
2000 } /* emlxs_mb_config_ring() */
2001
2002
2003 /*
2004 * emlxs_mb_config_link Issue a CONFIG LINK mailbox command
2005 */
2006 extern void
emlxs_mb_config_link(emlxs_hba_t * hba,MAILBOXQ * mbq)2007 emlxs_mb_config_link(emlxs_hba_t *hba, MAILBOXQ *mbq)
2008 {
2009 MAILBOX *mb = (MAILBOX *)mbq;
2010 emlxs_port_t *port = &PPORT;
2011 emlxs_config_t *cfg = &CFG;
2012
2013 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2014
2015 /*
2016 * NEW_FEATURE SLI-2, Coalescing Response Feature.
2017 */
2018 if (cfg[CFG_CR_DELAY].current) {
2019 mb->un.varCfgLnk.cr = 1;
2020 mb->un.varCfgLnk.ci = 1;
2021 mb->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current;
2022 mb->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current;
2023 }
2024
2025 if (cfg[CFG_ACK0].current) {
2026 mb->un.varCfgLnk.ack0_enable = 1;
2027 }
2028
2029 mb->un.varCfgLnk.myId = port->did;
2030 mb->un.varCfgLnk.edtov = hba->fc_edtov;
2031 mb->un.varCfgLnk.arbtov = hba->fc_arbtov;
2032 mb->un.varCfgLnk.ratov = hba->fc_ratov;
2033 mb->un.varCfgLnk.rttov = hba->fc_rttov;
2034 mb->un.varCfgLnk.altov = hba->fc_altov;
2035 mb->un.varCfgLnk.crtov = hba->fc_crtov;
2036 mb->un.varCfgLnk.citov = hba->fc_citov;
2037 mb->mbxCommand = MBX_CONFIG_LINK;
2038 mb->mbxOwner = OWN_HOST;
2039 mbq->mbox_cmpl = NULL;
2040 mbq->port = (void *)port;
2041
2042 return;
2043
2044 } /* emlxs_mb_config_link() */
2045
2046
2047 static uint32_t
emlxs_init_link_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)2048 emlxs_init_link_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
2049 {
2050 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
2051 emlxs_config_t *cfg = &CFG;
2052 MAILBOX *mb;
2053
2054 mb = (MAILBOX *)mbq;
2055 if (mb->mbxStatus) {
2056 if ((hba->flag & FC_SLIM2_MODE) &&
2057 (hba->mbox_queue_flag == MBX_NOWAIT)) {
2058 /* Retry only MBX_NOWAIT requests */
2059
2060 if ((cfg[CFG_LINK_SPEED].current > 0) &&
2061 ((mb->mbxStatus == 0x0011) ||
2062 (mb->mbxStatus == 0x0500))) {
2063
2064 EMLXS_MSGF(EMLXS_CONTEXT,
2065 &emlxs_mbox_event_msg,
2066 "Retrying. %s: status=%x. Auto-speed set.",
2067 emlxs_mb_cmd_xlate(mb->mbxCommand),
2068 (uint32_t)mb->mbxStatus);
2069
2070 mb->un.varInitLnk.link_flags &=
2071 ~FLAGS_LINK_SPEED;
2072 mb->un.varInitLnk.link_speed = 0;
2073
2074 emlxs_mb_retry(hba, mbq);
2075 return (1);
2076 }
2077 }
2078 }
2079 return (0);
2080
2081 } /* emlxs_init_link_mbcmpl() */
2082
2083
2084 /*
2085 * emlxs_mb_init_link Issue an INIT LINK mailbox command
2086 */
2087 extern void
emlxs_mb_init_link(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t topology,uint32_t linkspeed)2088 emlxs_mb_init_link(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t topology,
2089 uint32_t linkspeed)
2090 {
2091 MAILBOX *mb = (MAILBOX *)mbq;
2092 emlxs_vpd_t *vpd = &VPD;
2093 emlxs_config_t *cfg = &CFG;
2094
2095 if ((hba->sli_mode == EMLXS_HBA_SLI4_MODE) &&
2096 (SLI4_FCOE_MODE)) {
2097 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
2098 mbq->nonembed = NULL;
2099 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2100 mbq->port = (void *)&PPORT;
2101
2102 mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
2103 mb->mbxOwner = OWN_HOST;
2104 return;
2105 }
2106
2107 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2108
2109 switch (topology) {
2110 case FLAGS_LOCAL_LB:
2111 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
2112 mb->un.varInitLnk.link_flags |= FLAGS_LOCAL_LB;
2113 break;
2114 case FLAGS_TOPOLOGY_MODE_LOOP_PT:
2115 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
2116 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
2117 break;
2118 case FLAGS_TOPOLOGY_MODE_PT_PT:
2119 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
2120 break;
2121 case FLAGS_TOPOLOGY_MODE_LOOP:
2122 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
2123 break;
2124 case FLAGS_TOPOLOGY_MODE_PT_LOOP:
2125 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
2126 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
2127 break;
2128 }
2129
2130 if (cfg[CFG_LILP_ENABLE].current == 0) {
2131 /* Disable LIRP/LILP support */
2132 mb->un.varInitLnk.link_flags |= FLAGS_LIRP_LILP;
2133 }
2134
2135 /*
2136 * Setting up the link speed
2137 */
2138 switch (linkspeed) {
2139 case 0:
2140 break;
2141
2142 case 1:
2143 if (!(vpd->link_speed & LMT_1GB_CAPABLE)) {
2144 linkspeed = 0;
2145 }
2146 break;
2147
2148 case 2:
2149 if (!(vpd->link_speed & LMT_2GB_CAPABLE)) {
2150 linkspeed = 0;
2151 }
2152 break;
2153
2154 case 4:
2155 if (!(vpd->link_speed & LMT_4GB_CAPABLE)) {
2156 linkspeed = 0;
2157 }
2158 break;
2159
2160 case 8:
2161 if (!(vpd->link_speed & LMT_8GB_CAPABLE)) {
2162 linkspeed = 0;
2163 }
2164 break;
2165
2166 case 10:
2167 if (!(vpd->link_speed & LMT_10GB_CAPABLE)) {
2168 linkspeed = 0;
2169 }
2170 break;
2171
2172 case 16:
2173 if (!(vpd->link_speed & LMT_16GB_CAPABLE)) {
2174 linkspeed = 0;
2175 }
2176 break;
2177
2178 default:
2179 linkspeed = 0;
2180 break;
2181
2182 }
2183
2184 if ((linkspeed > 0) && (vpd->feaLevelHigh >= 0x02)) {
2185 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
2186 mb->un.varInitLnk.link_speed = linkspeed;
2187 }
2188
2189 mb->un.varInitLnk.link_flags |= FLAGS_PREABORT_RETURN;
2190
2191 mb->un.varInitLnk.fabric_AL_PA =
2192 (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
2193 mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
2194 mb->mbxOwner = OWN_HOST;
2195 mbq->mbox_cmpl = emlxs_init_link_mbcmpl;
2196 mbq->port = (void *)&PPORT;
2197
2198
2199 return;
2200
2201 } /* emlxs_mb_init_link() */
2202
2203
2204 /*
2205 * emlxs_mb_down_link Issue a DOWN LINK mailbox command
2206 */
2207 /*ARGSUSED*/
2208 extern void
emlxs_mb_down_link(emlxs_hba_t * hba,MAILBOXQ * mbq)2209 emlxs_mb_down_link(emlxs_hba_t *hba, MAILBOXQ *mbq)
2210 {
2211 MAILBOX *mb = (MAILBOX *)mbq;
2212
2213 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2214
2215 mb->mbxCommand = MBX_DOWN_LINK;
2216 mb->mbxOwner = OWN_HOST;
2217 mbq->mbox_cmpl = NULL;
2218 mbq->port = (void *)&PPORT;
2219
2220 return;
2221
2222 } /* emlxs_mb_down_link() */
2223
2224
2225 static uint32_t
emlxs_read_sparam_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)2226 emlxs_read_sparam_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
2227 {
2228 emlxs_port_t *port = &PPORT;
2229 MAILBOX *mb;
2230 MATCHMAP *mp;
2231 emlxs_port_t *vport;
2232 int32_t i;
2233 uint32_t control;
2234 uint8_t null_wwn[8];
2235
2236 mb = (MAILBOX *)mbq;
2237 if (mb->mbxStatus) {
2238 if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
2239 control = mb->un.varRdSparm.un.sp64.tus.f.bdeSize;
2240 if (control == 0) {
2241 (void) emlxs_mb_read_sparam(hba, mbq);
2242 }
2243 emlxs_mb_retry(hba, mbq);
2244 return (1);
2245 }
2246 return (0);
2247 }
2248 mp = (MATCHMAP *)mbq->bp;
2249 if (!mp) {
2250 return (0);
2251 }
2252
2253 bcopy((caddr_t)mp->virt, (caddr_t)&hba->sparam, sizeof (SERV_PARM));
2254
2255 /* Initialize the node name and port name only once */
2256 bzero(null_wwn, 8);
2257 if ((bcmp((caddr_t)&hba->wwnn, (caddr_t)null_wwn, 8) == 0) &&
2258 (bcmp((caddr_t)&hba->wwpn, (caddr_t)null_wwn, 8) == 0)) {
2259 bcopy((caddr_t)&hba->sparam.nodeName,
2260 (caddr_t)&hba->wwnn, sizeof (NAME_TYPE));
2261
2262 bcopy((caddr_t)&hba->sparam.portName,
2263 (caddr_t)&hba->wwpn, sizeof (NAME_TYPE));
2264 } else {
2265 bcopy((caddr_t)&hba->wwnn,
2266 (caddr_t)&hba->sparam.nodeName, sizeof (NAME_TYPE));
2267
2268 bcopy((caddr_t)&hba->wwpn,
2269 (caddr_t)&hba->sparam.portName, sizeof (NAME_TYPE));
2270 }
2271
2272 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2273 "SPARAM: EDTOV hba=%x mbox_csp=%x BBC=%x",
2274 hba->fc_edtov, hba->sparam.cmn.e_d_tov,
2275 hba->sparam.cmn.bbCreditlsb);
2276
2277 /* Initialize the physical port */
2278 bcopy((caddr_t)&hba->sparam, (caddr_t)&port->sparam,
2279 sizeof (SERV_PARM));
2280 bcopy((caddr_t)&hba->wwpn, (caddr_t)&port->wwpn,
2281 sizeof (NAME_TYPE));
2282 bcopy((caddr_t)&hba->wwnn, (caddr_t)&port->wwnn,
2283 sizeof (NAME_TYPE));
2284
2285 /* Initialize the virtual ports */
2286 for (i = 1; i < MAX_VPORTS; i++) {
2287 vport = &VPORT(i);
2288 if (! (vport->flag & EMLXS_PORT_BOUND)) {
2289 continue;
2290 }
2291
2292 bcopy((caddr_t)&hba->sparam,
2293 (caddr_t)&vport->sparam,
2294 sizeof (SERV_PARM));
2295
2296 bcopy((caddr_t)&vport->wwnn,
2297 (caddr_t)&vport->sparam.nodeName,
2298 sizeof (NAME_TYPE));
2299
2300 bcopy((caddr_t)&vport->wwpn,
2301 (caddr_t)&vport->sparam.portName,
2302 sizeof (NAME_TYPE));
2303 }
2304
2305 return (0);
2306
2307 } /* emlxs_read_sparam_mbcmpl() */
2308
2309
2310 /*
2311 * emlxs_mb_read_sparam Issue a READ SPARAM mailbox command
2312 */
2313 extern uint32_t
emlxs_mb_read_sparam(emlxs_hba_t * hba,MAILBOXQ * mbq)2314 emlxs_mb_read_sparam(emlxs_hba_t *hba, MAILBOXQ *mbq)
2315 {
2316 MAILBOX *mb = (MAILBOX *)mbq;
2317 MATCHMAP *mp;
2318
2319 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2320
2321 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
2322 mb->mbxCommand = MBX_READ_SPARM64;
2323
2324 return (1);
2325 }
2326
2327 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
2328 mb->un.varRdSparm.un.sp64.addrHigh = PADDR_HI(mp->phys);
2329 mb->un.varRdSparm.un.sp64.addrLow = PADDR_LO(mp->phys);
2330 mb->mbxCommand = MBX_READ_SPARM64;
2331 mb->mbxOwner = OWN_HOST;
2332 mbq->mbox_cmpl = emlxs_read_sparam_mbcmpl;
2333 mbq->port = (void *)&PPORT;
2334
2335 /*
2336 * save address for completion
2337 */
2338 mbq->bp = (void *)mp;
2339
2340 return (0);
2341
2342 } /* emlxs_mb_read_sparam() */
2343
2344
2345 /*
2346 * emlxs_mb_read_rpi Issue a READ RPI mailbox command
2347 */
2348 /*ARGSUSED*/
2349 extern uint32_t
emlxs_mb_read_rpi(emlxs_hba_t * hba,uint32_t rpi,MAILBOXQ * mbq,uint32_t flag)2350 emlxs_mb_read_rpi(emlxs_hba_t *hba, uint32_t rpi, MAILBOXQ *mbq,
2351 uint32_t flag)
2352 {
2353 MAILBOX *mb = (MAILBOX *)mbq;
2354
2355 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2356
2357 /*
2358 * Set flag to issue action on cmpl
2359 */
2360 mb->un.varWords[30] = flag;
2361 mb->un.varRdRPI.reqRpi = (volatile uint16_t) rpi;
2362 mb->mbxCommand = MBX_READ_RPI64;
2363 mb->mbxOwner = OWN_HOST;
2364 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2365 mbq->port = (void *)&PPORT;
2366
2367 return (0);
2368 } /* emlxs_mb_read_rpi() */
2369
2370
2371 /*
2372 * emlxs_mb_read_xri Issue a READ XRI mailbox command
2373 */
2374 /*ARGSUSED*/
2375 extern uint32_t
emlxs_mb_read_xri(emlxs_hba_t * hba,uint32_t xri,MAILBOXQ * mbq,uint32_t flag)2376 emlxs_mb_read_xri(emlxs_hba_t *hba, uint32_t xri, MAILBOXQ *mbq,
2377 uint32_t flag)
2378 {
2379 MAILBOX *mb = (MAILBOX *)mbq;
2380
2381 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2382
2383 /*
2384 * Set flag to issue action on cmpl
2385 */
2386 mb->un.varWords[30] = flag;
2387 mb->un.varRdXRI.reqXri = (volatile uint16_t)xri;
2388 mb->mbxCommand = MBX_READ_XRI;
2389 mb->mbxOwner = OWN_HOST;
2390 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2391 mbq->port = (void *)&PPORT;
2392
2393 return (0);
2394 } /* emlxs_mb_read_xri() */
2395
2396
2397 /*ARGSUSED*/
2398 extern int32_t
emlxs_mb_check_sparm(emlxs_hba_t * hba,SERV_PARM * nsp)2399 emlxs_mb_check_sparm(emlxs_hba_t *hba, SERV_PARM *nsp)
2400 {
2401 uint32_t nsp_value;
2402 uint32_t *iptr;
2403
2404 if (nsp->cmn.fPort) {
2405 return (0);
2406 }
2407
2408 /* Validate the service parameters */
2409 iptr = (uint32_t *)&nsp->portName;
2410 if (iptr[0] == 0 && iptr[1] == 0) {
2411 return (1);
2412 }
2413
2414 iptr = (uint32_t *)&nsp->nodeName;
2415 if (iptr[0] == 0 && iptr[1] == 0) {
2416 return (2);
2417 }
2418
2419 if (nsp->cls2.classValid) {
2420 nsp_value =
2421 ((nsp->cls2.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls2.
2422 rcvDataSizeLsb;
2423
2424 /* If the receive data length is zero then set it to */
2425 /* the CSP value */
2426 if (!nsp_value) {
2427 nsp->cls2.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
2428 nsp->cls2.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
2429 return (0);
2430 }
2431 }
2432
2433 if (nsp->cls3.classValid) {
2434 nsp_value =
2435 ((nsp->cls3.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls3.
2436 rcvDataSizeLsb;
2437
2438 /* If the receive data length is zero then set it to */
2439 /* the CSP value */
2440 if (!nsp_value) {
2441 nsp->cls3.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
2442 nsp->cls3.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
2443 return (0);
2444 }
2445 }
2446
2447 return (0);
2448
2449 } /* emlxs_mb_check_sparm() */
2450
2451
2452
2453
2454 /*
2455 * emlxs_mb_set_var Issue a special debug mbox command to write slim
2456 */
2457 /*ARGSUSED*/
2458 extern void
emlxs_mb_set_var(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t addr,uint32_t value)2459 emlxs_mb_set_var(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t addr,
2460 uint32_t value)
2461 {
2462 MAILBOX *mb = (MAILBOX *)mbq;
2463
2464 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2465
2466 /* addr = 0x090597 is AUTO ABTS disable for ELS commands */
2467 /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */
2468 /* addr = 0x100506 is for setting PCI MAX READ value */
2469
2470 /*
2471 * Always turn on DELAYED ABTS for ELS timeouts
2472 */
2473 if ((addr == 0x052198) && (value == 0)) {
2474 value = 1;
2475 }
2476
2477 mb->un.varWords[0] = addr;
2478 mb->un.varWords[1] = value;
2479 mb->mbxCommand = MBX_SET_VARIABLE;
2480 mb->mbxOwner = OWN_HOST;
2481 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2482 mbq->port = (void *)&PPORT;
2483
2484 } /* emlxs_mb_set_var() */
2485
2486
2487 /*
2488 * Disable Traffic Cop
2489 */
2490 /*ARGSUSED*/
2491 extern void
emlxs_disable_tc(emlxs_hba_t * hba,MAILBOXQ * mbq)2492 emlxs_disable_tc(emlxs_hba_t *hba, MAILBOXQ *mbq)
2493 {
2494 MAILBOX *mb = (MAILBOX *)mbq;
2495
2496 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2497
2498 mb->un.varWords[0] = 0x50797;
2499 mb->un.varWords[1] = 0;
2500 mb->un.varWords[2] = 0xfffffffe;
2501 mb->mbxCommand = MBX_SET_VARIABLE;
2502 mb->mbxOwner = OWN_HOST;
2503 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2504 mbq->port = (void *)&PPORT;
2505
2506 } /* emlxs_disable_tc() */
2507
2508
2509 extern void
emlxs_mb_config_hbq(emlxs_hba_t * hba,MAILBOXQ * mbq,int hbq_id)2510 emlxs_mb_config_hbq(emlxs_hba_t *hba, MAILBOXQ *mbq, int hbq_id)
2511 {
2512 HBQ_INIT_t *hbq;
2513 MAILBOX *mb = (MAILBOX *)mbq;
2514 int i;
2515
2516 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2517
2518 hbq = &hba->sli.sli3.hbq_table[hbq_id];
2519
2520 mb->un.varCfgHbq.hbqId = hbq_id;
2521 mb->un.varCfgHbq.numEntries = hbq->HBQ_numEntries;
2522 mb->un.varCfgHbq.recvNotify = hbq->HBQ_recvNotify;
2523 mb->un.varCfgHbq.numMask = hbq->HBQ_num_mask;
2524 mb->un.varCfgHbq.profile = hbq->HBQ_profile;
2525 mb->un.varCfgHbq.ringMask = hbq->HBQ_ringMask;
2526 mb->un.varCfgHbq.headerLen = hbq->HBQ_headerLen;
2527 mb->un.varCfgHbq.logEntry = hbq->HBQ_logEntry;
2528 mb->un.varCfgHbq.hbqaddrLow = PADDR_LO(hbq->HBQ_host_buf.phys);
2529 mb->un.varCfgHbq.hbqaddrHigh = PADDR_HI(hbq->HBQ_host_buf.phys);
2530 mb->mbxCommand = MBX_CONFIG_HBQ;
2531 mb->mbxOwner = OWN_HOST;
2532 mbq->mbox_cmpl = NULL;
2533 mbq->port = (void *)&PPORT;
2534
2535 /* Copy info for profiles 2,3,5. Other profiles this area is reserved */
2536 if ((hbq->HBQ_profile == 2) || (hbq->HBQ_profile == 3) ||
2537 (hbq->HBQ_profile == 5)) {
2538 bcopy(&hbq->profiles.allprofiles,
2539 &mb->un.varCfgHbq.profiles.allprofiles,
2540 sizeof (hbq->profiles));
2541 }
2542
2543 /* Return if no rctl / type masks for this HBQ */
2544 if (!hbq->HBQ_num_mask) {
2545 return;
2546 }
2547
2548 /* Otherwise we setup specific rctl / type masks for this HBQ */
2549 for (i = 0; i < hbq->HBQ_num_mask; i++) {
2550 mb->un.varCfgHbq.hbqMasks[i].tmatch =
2551 hbq->HBQ_Masks[i].tmatch;
2552 mb->un.varCfgHbq.hbqMasks[i].tmask = hbq->HBQ_Masks[i].tmask;
2553 mb->un.varCfgHbq.hbqMasks[i].rctlmatch =
2554 hbq->HBQ_Masks[i].rctlmatch;
2555 mb->un.varCfgHbq.hbqMasks[i].rctlmask =
2556 hbq->HBQ_Masks[i].rctlmask;
2557 }
2558
2559 return;
2560
2561 } /* emlxs_mb_config_hbq() */
2562
2563
2564 /* SLI3 */
2565 static uint32_t
emlxs_reg_vpi_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)2566 emlxs_reg_vpi_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
2567 {
2568 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
2569 MAILBOX *mb;
2570
2571 mb = (MAILBOX *)mbq;
2572
2573 mutex_enter(&EMLXS_PORT_LOCK);
2574
2575 if (mb->mbxStatus != MBX_SUCCESS) {
2576 port->flag &= ~EMLXS_PORT_REG_VPI;
2577 mutex_exit(&EMLXS_PORT_LOCK);
2578
2579 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2580 "cmpl_reg_vpi:%d failed. status=%x",
2581 port->vpi, mb->mbxStatus);
2582 return (0);
2583 }
2584
2585 port->flag |= EMLXS_PORT_REG_VPI_CMPL;
2586
2587 mutex_exit(&EMLXS_PORT_LOCK);
2588
2589 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2590 "cmpl_reg_vpi:%d ",
2591 port->vpi);
2592
2593 return (0);
2594
2595 } /* emlxs_reg_vpi_mbcmpl */
2596
2597
2598 /* SLI3 */
2599 extern uint32_t
emlxs_mb_reg_vpi(emlxs_port_t * port,emlxs_buf_t * sbp)2600 emlxs_mb_reg_vpi(emlxs_port_t *port, emlxs_buf_t *sbp)
2601 {
2602 emlxs_hba_t *hba = HBA;
2603 MAILBOXQ *mbq;
2604 MAILBOX *mb;
2605 int rval;
2606
2607 if (hba->sli_mode > EMLXS_HBA_SLI3_MODE) {
2608 return (1);
2609 }
2610
2611 if (!(hba->flag & FC_NPIV_ENABLED)) {
2612 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2613 "reg_vpi:%d failed. NPIV disabled.",
2614 port->vpi);
2615 return (1);
2616 }
2617
2618 if (port->flag & EMLXS_PORT_REG_VPI) {
2619 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2620 "reg_vpi:%d failed. Already registered.",
2621 port->vpi);
2622 return (0);
2623 }
2624
2625 mutex_enter(&EMLXS_PORT_LOCK);
2626
2627 /* Can't reg vpi until ClearLA is sent */
2628 if (hba->state != FC_READY) {
2629 mutex_exit(&EMLXS_PORT_LOCK);
2630
2631 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2632 "reg_vpi:%d failed. HBA state not READY",
2633 port->vpi);
2634 return (1);
2635 }
2636
2637 /* Must have port id */
2638 if (!port->did) {
2639 mutex_exit(&EMLXS_PORT_LOCK);
2640
2641 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2642 "reg_vpi:%d failed. Port did=0",
2643 port->vpi);
2644 return (1);
2645 }
2646
2647 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
2648 mutex_exit(&EMLXS_PORT_LOCK);
2649
2650 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2651 "reg_vpi:%d failed. Unable to allocate mbox.",
2652 port->vpi);
2653 return (1);
2654 }
2655
2656 port->flag |= EMLXS_PORT_REG_VPI;
2657
2658 mutex_exit(&EMLXS_PORT_LOCK);
2659
2660 mb = (MAILBOX *)mbq->mbox;
2661 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2662
2663 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2664 "reg_vpi:%d", port->vpi);
2665
2666 mb->un.varRegVpi.vpi = port->vpi;
2667 mb->un.varRegVpi.sid = port->did;
2668 mb->mbxCommand = MBX_REG_VPI;
2669 mb->mbxOwner = OWN_HOST;
2670
2671 mbq->sbp = (void *)sbp;
2672 mbq->mbox_cmpl = emlxs_reg_vpi_mbcmpl;
2673 mbq->context = NULL;
2674 mbq->port = (void *)port;
2675
2676 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
2677 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
2678 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2679 "reg_vpi:%d failed. Unable to send request.",
2680 port->vpi);
2681
2682 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2683 return (1);
2684 }
2685
2686 return (0);
2687
2688 } /* emlxs_mb_reg_vpi() */
2689
2690
2691 /* SLI3 */
2692 static uint32_t
emlxs_unreg_vpi_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)2693 emlxs_unreg_vpi_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
2694 {
2695 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
2696 MAILBOX *mb;
2697
2698 mb = (MAILBOX *)mbq->mbox;
2699
2700 if (mb->mbxStatus != MBX_SUCCESS) {
2701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2702 "unreg_vpi_mbcmpl:%d failed. status=%x",
2703 port->vpi, mb->mbxStatus);
2704 return (0);
2705 }
2706
2707 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2708 "unreg_vpi_mbcmpl:%d", port->vpi);
2709
2710 mutex_enter(&EMLXS_PORT_LOCK);
2711 port->flag &= ~EMLXS_PORT_REG_VPI_CMPL;
2712 mutex_exit(&EMLXS_PORT_LOCK);
2713
2714 return (0);
2715
2716 } /* emlxs_unreg_vpi_mbcmpl() */
2717
2718
2719 /* SLI3 */
2720 extern uint32_t
emlxs_mb_unreg_vpi(emlxs_port_t * port)2721 emlxs_mb_unreg_vpi(emlxs_port_t *port)
2722 {
2723 emlxs_hba_t *hba = HBA;
2724 MAILBOXQ *mbq;
2725 MAILBOX *mb;
2726 int rval;
2727
2728 if (hba->sli_mode > EMLXS_HBA_SLI3_MODE) {
2729 return (1);
2730 }
2731
2732 mutex_enter(&EMLXS_PORT_LOCK);
2733
2734 if (!(port->flag & EMLXS_PORT_REG_VPI) ||
2735 !(port->flag & EMLXS_PORT_REG_VPI_CMPL)) {
2736
2737 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2738 "unreg_vpi:%d failed. Not registered. flag=%x",
2739 port->vpi, port->flag);
2740
2741 mutex_exit(&EMLXS_PORT_LOCK);
2742 return (0);
2743 }
2744
2745 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
2746 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2747 "unreg_vpi:%d failed. Unable to allocate mbox.",
2748 port->vpi);
2749
2750 mutex_exit(&EMLXS_PORT_LOCK);
2751 return (1);
2752 }
2753
2754 port->flag &= ~EMLXS_PORT_REG_VPI;
2755
2756 mutex_exit(&EMLXS_PORT_LOCK);
2757
2758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2759 "unreg_vpi:%d", port->vpi);
2760
2761 mb = (MAILBOX *)mbq->mbox;
2762 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2763 mb->un.varUnregVpi.vpi = port->vpi;
2764 mb->mbxCommand = MBX_UNREG_VPI;
2765 mb->mbxOwner = OWN_HOST;
2766
2767 mbq->mbox_cmpl = emlxs_unreg_vpi_mbcmpl;
2768 mbq->context = NULL;
2769 mbq->port = (void *)port;
2770
2771 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
2772 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
2773 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2774 "unreg_vpi:%d failed. Unable to send request.",
2775 port->vpi);
2776
2777 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2778 return (1);
2779 }
2780
2781 return (0);
2782
2783 } /* emlxs_mb_unreg_vpi() */
2784
2785
2786 /*
2787 * emlxs_mb_config_farp Issue a CONFIG FARP mailbox command
2788 */
2789 extern void
emlxs_mb_config_farp(emlxs_hba_t * hba,MAILBOXQ * mbq)2790 emlxs_mb_config_farp(emlxs_hba_t *hba, MAILBOXQ *mbq)
2791 {
2792 MAILBOX *mb = (MAILBOX *)mbq;
2793
2794 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2795
2796 bcopy((uint8_t *)&hba->wwpn,
2797 (uint8_t *)&mb->un.varCfgFarp.portname, sizeof (NAME_TYPE));
2798
2799 bcopy((uint8_t *)&hba->wwpn,
2800 (uint8_t *)&mb->un.varCfgFarp.nodename, sizeof (NAME_TYPE));
2801
2802 mb->un.varCfgFarp.filterEnable = 1;
2803 mb->un.varCfgFarp.portName = 1;
2804 mb->un.varCfgFarp.nodeName = 1;
2805 mb->mbxCommand = MBX_CONFIG_FARP;
2806 mb->mbxOwner = OWN_HOST;
2807 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2808 mbq->port = (void *)&PPORT;
2809
2810 } /* emlxs_mb_config_farp() */
2811
2812
2813 /*
2814 * emlxs_mb_read_nv Issue a READ CONFIG mailbox command
2815 */
2816 /*ARGSUSED*/
2817 extern void
emlxs_mb_read_config(emlxs_hba_t * hba,MAILBOXQ * mbq)2818 emlxs_mb_read_config(emlxs_hba_t *hba, MAILBOXQ *mbq)
2819 {
2820 MAILBOX *mb = (MAILBOX *)mbq;
2821
2822 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2823 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
2824 mbq->nonembed = NULL;
2825 } else {
2826 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2827 }
2828
2829 mb->mbxCommand = MBX_READ_CONFIG;
2830 mb->mbxOwner = OWN_HOST;
2831 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2832 mbq->port = (void *)&PPORT;
2833
2834 } /* emlxs_mb_read_config() */
2835
2836
2837 /*
2838 * NAME: emlxs_mb_put
2839 *
2840 * FUNCTION: put mailbox cmd onto the mailbox queue.
2841 *
2842 * EXECUTION ENVIRONMENT: process and interrupt level.
2843 *
2844 * NOTES:
2845 *
2846 * CALLED FROM: EMLXS_SLI_ISSUE_MBOX_CMD
2847 *
2848 * INPUT: hba - pointer to the device info area
2849 * mbp - pointer to mailbox queue entry of mailbox cmd
2850 *
2851 * RETURNS: NULL - command queued
2852 */
2853 extern void
emlxs_mb_put(emlxs_hba_t * hba,MAILBOXQ * mbq)2854 emlxs_mb_put(emlxs_hba_t *hba, MAILBOXQ *mbq)
2855 {
2856
2857 mutex_enter(&EMLXS_MBOX_LOCK);
2858
2859 if (hba->mbox_queue.q_first) {
2860
2861 /*
2862 * queue command to end of list
2863 */
2864 ((MAILBOXQ *)hba->mbox_queue.q_last)->next = mbq;
2865 hba->mbox_queue.q_last = (uint8_t *)mbq;
2866 hba->mbox_queue.q_cnt++;
2867 } else {
2868
2869 /*
2870 * add command to empty list
2871 */
2872 hba->mbox_queue.q_first = (uint8_t *)mbq;
2873 hba->mbox_queue.q_last = (uint8_t *)mbq;
2874 hba->mbox_queue.q_cnt = 1;
2875 }
2876
2877 mbq->next = NULL;
2878
2879 mutex_exit(&EMLXS_MBOX_LOCK);
2880 } /* emlxs_mb_put() */
2881
2882
2883 /*
2884 * NAME: emlxs_mb_get
2885 *
2886 * FUNCTION: get a mailbox command from mailbox command queue
2887 *
2888 * EXECUTION ENVIRONMENT: interrupt level.
2889 *
2890 * NOTES:
2891 *
2892 * CALLED FROM: emlxs_handle_mb_event
2893 *
2894 * INPUT: hba - pointer to the device info area
2895 *
2896 * RETURNS: NULL - no match found mb pointer - pointer to a mailbox command
2897 */
2898 extern MAILBOXQ *
emlxs_mb_get(emlxs_hba_t * hba)2899 emlxs_mb_get(emlxs_hba_t *hba)
2900 {
2901 MAILBOXQ *p_first = NULL;
2902
2903 mutex_enter(&EMLXS_MBOX_LOCK);
2904
2905 if (hba->mbox_queue.q_first) {
2906 p_first = (MAILBOXQ *)hba->mbox_queue.q_first;
2907 hba->mbox_queue.q_first = (uint8_t *)p_first->next;
2908
2909 if (hba->mbox_queue.q_first == NULL) {
2910 hba->mbox_queue.q_last = NULL;
2911 hba->mbox_queue.q_cnt = 0;
2912 } else {
2913 hba->mbox_queue.q_cnt--;
2914 }
2915
2916 p_first->next = NULL;
2917 }
2918
2919 mutex_exit(&EMLXS_MBOX_LOCK);
2920
2921 return (p_first);
2922
2923 } /* emlxs_mb_get() */
2924
2925
2926 /* EMLXS_PORT_LOCK must be held when calling this */
2927 void
emlxs_mb_init(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t flag,uint32_t tmo)2928 emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo)
2929 {
2930 MATCHMAP *mp;
2931
2932 HBASTATS.MboxIssued++;
2933 hba->mbox_queue_flag = flag;
2934
2935 /* Set the Mailbox timer */
2936 if (hba->timer_tics) {
2937 hba->mbox_timer = hba->timer_tics + tmo;
2938 } else {
2939 hba->mbox_timer = DRV_TIME + tmo;
2940 }
2941
2942 /* Initialize mailbox */
2943 mbq->flag &= MBQ_INIT_MASK;
2944 mbq->next = 0;
2945
2946 mutex_enter(&EMLXS_MBOX_LOCK);
2947 hba->mbox_mbq = (void *)mbq;
2948 mutex_exit(&EMLXS_MBOX_LOCK);
2949
2950 if (mbq->nonembed) {
2951 mp = (MATCHMAP *) mbq->nonembed;
2952 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
2953 DDI_DMA_SYNC_FORDEV);
2954 }
2955
2956 if (mbq->bp) {
2957 mp = (MATCHMAP *) mbq->bp;
2958 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
2959 DDI_DMA_SYNC_FORDEV);
2960 }
2961 return;
2962
2963 } /* emlxs_mb_init() */
2964
2965
2966 extern void
emlxs_mb_fini(emlxs_hba_t * hba,MAILBOX * mb,uint32_t mbxStatus)2967 emlxs_mb_fini(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mbxStatus)
2968 {
2969 emlxs_port_t *port = &PPORT;
2970 MATCHMAP *mbox_nonembed;
2971 MATCHMAP *mbox_bp;
2972 emlxs_buf_t *mbox_sbp;
2973 fc_unsol_buf_t *mbox_ubp;
2974 IOCBQ *mbox_iocbq;
2975 MAILBOXQ *mbox_mbq;
2976 MAILBOX *mbox;
2977 uint32_t mbox_queue_flag;
2978
2979 mutex_enter(&EMLXS_PORT_LOCK);
2980
2981 if (hba->mbox_queue_flag) {
2982 HBASTATS.MboxCompleted++;
2983
2984 if (mbxStatus != MBX_SUCCESS) {
2985 HBASTATS.MboxError++;
2986 } else {
2987 HBASTATS.MboxGood++;
2988 }
2989 }
2990
2991 mutex_enter(&EMLXS_MBOX_LOCK);
2992 mbox_queue_flag = hba->mbox_queue_flag;
2993 mbox_mbq = (MAILBOXQ *)hba->mbox_mbq;
2994
2995 if (mbox_mbq) {
2996 mbox_nonembed = (MATCHMAP *)mbox_mbq->nonembed;
2997 mbox_bp = (MATCHMAP *)mbox_mbq->bp;
2998 mbox_sbp = (emlxs_buf_t *)mbox_mbq->sbp;
2999 mbox_ubp = (fc_unsol_buf_t *)mbox_mbq->ubp;
3000 mbox_iocbq = (IOCBQ *)mbox_mbq->iocbq;
3001 } else {
3002 mbox_nonembed = NULL;
3003 mbox_bp = NULL;
3004 mbox_sbp = NULL;
3005 mbox_ubp = NULL;
3006 mbox_iocbq = NULL;
3007 }
3008
3009 hba->mbox_mbq = NULL;
3010 hba->mbox_queue_flag = 0;
3011 hba->mbox_timer = 0;
3012 mutex_exit(&EMLXS_MBOX_LOCK);
3013
3014 mutex_exit(&EMLXS_PORT_LOCK);
3015
3016 #ifdef SFCT_SUPPORT
3017 if (mb && mbox_sbp && mbox_sbp->fct_cmd) {
3018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3019 "FCT mailbox: %s: status=%x",
3020 emlxs_mb_cmd_xlate(mb->mbxCommand),
3021 mb->mbxStatus);
3022 }
3023 #endif /* SFCT_SUPPORT */
3024
3025 if (mbox_queue_flag == MBX_NOWAIT) {
3026 /* Check for deferred MBUF cleanup */
3027 if (mbox_bp) {
3028 emlxs_mem_put(hba, MEM_BUF, (void *)mbox_bp);
3029 }
3030 if (mbox_nonembed) {
3031 emlxs_mem_put(hba, MEM_BUF,
3032 (void *)mbox_nonembed);
3033 }
3034 if (mbox_mbq) {
3035 emlxs_mem_put(hba, MEM_MBOX,
3036 (void *)mbox_mbq);
3037 }
3038 } else { /* MBX_WAIT */
3039 if (mbox_mbq) {
3040 if (mb) {
3041 /* Copy the local mailbox provided back into */
3042 /* the original mailbox */
3043 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3044 bcopy((uint32_t *)mb,
3045 (uint32_t *)mbox_mbq,
3046 MAILBOX_CMD_SLI4_BSIZE);
3047 } else {
3048 bcopy((uint32_t *)mb,
3049 (uint32_t *)mbox_mbq,
3050 MAILBOX_CMD_BSIZE);
3051 }
3052 }
3053
3054 mbox = (MAILBOX *)mbox_mbq;
3055 mbox->mbxStatus = (uint16_t)mbxStatus;
3056
3057 /* Mark mailbox complete */
3058 mbox_mbq->flag |= MBQ_COMPLETED;
3059 }
3060
3061 /* Wake up the sleeping thread */
3062 if (mbox_queue_flag == MBX_SLEEP) {
3063 mutex_enter(&EMLXS_MBOX_LOCK);
3064 cv_broadcast(&EMLXS_MBOX_CV);
3065 mutex_exit(&EMLXS_MBOX_LOCK);
3066 }
3067 }
3068
3069 emlxs_mb_deferred_cmpl(port, mbxStatus, mbox_sbp, mbox_ubp, mbox_iocbq);
3070
3071 return;
3072
3073 } /* emlxs_mb_fini() */
3074
3075
3076 extern void
emlxs_mb_deferred_cmpl(emlxs_port_t * port,uint32_t mbxStatus,emlxs_buf_t * sbp,fc_unsol_buf_t * ubp,IOCBQ * iocbq)3077 emlxs_mb_deferred_cmpl(emlxs_port_t *port, uint32_t mbxStatus, emlxs_buf_t *sbp,
3078 fc_unsol_buf_t *ubp, IOCBQ *iocbq)
3079 {
3080 emlxs_hba_t *hba = HBA;
3081 emlxs_ub_priv_t *ub_priv;
3082
3083 #ifdef SFCT_SUPPORT
3084 if (sbp && sbp->fct_cmd && (sbp->fct_state == EMLXS_FCT_REG_PENDING)) {
3085 mutex_enter(&EMLXS_PKT_LOCK);
3086 sbp->fct_flags |= EMLXS_FCT_REGISTERED;
3087 cv_broadcast(&EMLXS_PKT_CV);
3088 mutex_exit(&EMLXS_PKT_LOCK);
3089
3090 sbp = NULL;
3091 }
3092 #endif /* SFCT_SUPPORT */
3093
3094 /* Check for deferred pkt completion */
3095 if (sbp) {
3096 if (mbxStatus != MBX_SUCCESS) {
3097 /* Set error status */
3098 sbp->pkt_flags &= ~PACKET_STATE_VALID;
3099 emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT,
3100 IOERR_NO_RESOURCES, 1);
3101 }
3102
3103 emlxs_pkt_complete(sbp, -1, 0, 1);
3104 }
3105
3106 /* Check for deferred ub completion */
3107 if (ubp) {
3108 ub_priv = ubp->ub_fca_private;
3109
3110 if (mbxStatus == MBX_SUCCESS) {
3111 emlxs_ub_callback(ub_priv->port, ubp);
3112 } else {
3113 (void) emlxs_fca_ub_release(ub_priv->port, 1,
3114 &ubp->ub_token);
3115 }
3116 }
3117
3118 /* Special handling for restricted login */
3119 if (iocbq == (IOCBQ *)1) {
3120 iocbq = NULL;
3121 }
3122
3123 /* Check for deferred iocb tx */
3124 if (iocbq) {
3125 /* Check for driver special codes */
3126 /* These indicate the mailbox is being flushed */
3127 if (mbxStatus >= MBX_DRIVER_RESERVED) {
3128 /* Set the error status and return it */
3129 iocbq->iocb.ULPSTATUS = IOSTAT_LOCAL_REJECT;
3130 iocbq->iocb.un.grsp.perr.statLocalError =
3131 IOERR_ABORT_REQUESTED;
3132
3133 emlxs_proc_channel_event(hba, iocbq->channel,
3134 iocbq);
3135 } else {
3136 EMLXS_SLI_ISSUE_IOCB_CMD(hba, iocbq->channel,
3137 iocbq);
3138 }
3139 }
3140
3141 return;
3142
3143 } /* emlxs_mb_deferred_cmpl() */
3144
3145
3146 extern void
emlxs_mb_flush(emlxs_hba_t * hba)3147 emlxs_mb_flush(emlxs_hba_t *hba)
3148 {
3149 MAILBOXQ *mbq;
3150 uint32_t mbxStatus;
3151
3152 mbxStatus = (hba->flag & FC_HARDWARE_ERROR) ?
3153 MBX_HARDWARE_ERROR : MBX_NOT_FINISHED;
3154
3155 /* Flush out the active mbox command */
3156 emlxs_mb_fini(hba, NULL, mbxStatus);
3157
3158 /* Flush out the queued mbox commands */
3159 while (mbq = (MAILBOXQ *)emlxs_mb_get(hba)) {
3160 mutex_enter(&EMLXS_MBOX_LOCK);
3161 hba->mbox_queue_flag = MBX_NOWAIT;
3162 hba->mbox_mbq = (void *)mbq;
3163 mutex_exit(&EMLXS_MBOX_LOCK);
3164
3165 emlxs_mb_fini(hba, NULL, mbxStatus);
3166 }
3167
3168 return;
3169
3170 } /* emlxs_mb_flush */
3171
3172
3173 extern char *
emlxs_mb_cmd_xlate(uint8_t cmd)3174 emlxs_mb_cmd_xlate(uint8_t cmd)
3175 {
3176 static char buffer[32];
3177 uint32_t i;
3178 uint32_t count;
3179
3180 count = sizeof (emlxs_mb_cmd_table) / sizeof (emlxs_table_t);
3181 for (i = 0; i < count; i++) {
3182 if (cmd == emlxs_mb_cmd_table[i].code) {
3183 return (emlxs_mb_cmd_table[i].string);
3184 }
3185 }
3186
3187 (void) snprintf(buffer, sizeof (buffer), "Cmd=0x%x", cmd);
3188 return (buffer);
3189
3190 } /* emlxs_mb_cmd_xlate() */
3191
3192 extern char *
emlxs_request_feature_xlate(uint32_t mask)3193 emlxs_request_feature_xlate(uint32_t mask)
3194 {
3195 static char buffer[64];
3196 uint32_t i;
3197
3198 bzero((char *)&buffer[0], 64);
3199 for (i = 0; i < 12; i++) {
3200 if (mask & (1<<i)) {
3201 (void) strlcat(buffer,
3202 emlxs_request_feature_table[i].string,
3203 sizeof (buffer));
3204 }
3205 }
3206 return (buffer);
3207 }
3208