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