Print this page
NEX-1890 update oce from source provided by Emulex
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c
+++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
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 -/* Copyright © 2003-2011 Emulex. All rights reserved. */
22 +/*
23 + * Copyright (c) 2009-2012 Emulex. All rights reserved.
24 + * Use is subject to license terms.
25 + */
23 26
24 27
28 +
25 29 /*
26 30 * Source file containing the implementation of MBOX
27 31 * and related helper functions
28 32 */
29 33
30 34 #include <oce_impl.h>
31 35
36 +extern int pow10[];
37 +
32 38 static ddi_dma_attr_t oce_sgl_dma_attr = {
33 39 DMA_ATTR_V0, /* version number */
34 40 0x0000000000000000ull, /* low address */
35 41 0xFFFFFFFFFFFFFFFFull, /* high address */
36 42 0x0000000000010000ull, /* dma counter max */
37 43 0x1000, /* alignment 4K for mbx bufs */
38 44 0x1, /* burst sizes */
39 45 0x00000004, /* minimum transfer size */
40 46 0x00000000FFFFFFFFull, /* maximum transfer size */
41 47 0xFFFFFFFFFFFFFFFFull, /* maximum segment size */
42 48 MAX_MBX_SGE, /* scatter/gather list length */
43 49 0x00000001, /* granularity */
44 50 0 /* DMA flags */
45 51 };
46 52
47 -static ddi_device_acc_attr_t oce_sgl_buf_accattr = {
48 - DDI_DEVICE_ATTR_V0,
49 - DDI_NEVERSWAP_ACC,
50 - DDI_STRICTORDER_ACC,
51 -};
53 +static int oce_mbox_issue_bootstrap(struct oce_dev *dev, struct oce_mbx *mbx,
54 + uint32_t tmo_sec);
55 +static uint32_t oce_enqueue_mq_mbox(struct oce_dev *dev, struct oce_mbx *mbx,
56 + uint32_t tmo_sec);
57 +static struct oce_mbx_ctx *oce_init_mq_ctx(struct oce_dev *dev,
58 + struct oce_mbx *mbx);
59 +static void oce_destroy_mq_ctx(struct oce_mbx_ctx *mbctx);
52 60
53 61 /*
54 62 * common inline function to fill an ioctl request header
55 63 *
56 64 * hdr - pointer to a buffer where the header will be initialized
57 65 * dom - domain
58 66 * port - port number
59 67 * opcode - command code for this MBX
60 68 * timeout - timeout in seconds
61 69 * pyld_len - length of the command buffer described by this header
62 70 *
63 71 * return none
64 72 */
65 73 void
66 74 mbx_common_req_hdr_init(struct mbx_hdr *hdr,
67 75 uint8_t dom, uint8_t port,
68 76 uint8_t subsys, uint8_t opcode,
69 - uint32_t timeout, uint32_t pyld_len)
77 + uint32_t timeout, uint32_t pyld_len, uint8_t version)
70 78 {
71 79 ASSERT(hdr != NULL);
72 80
73 81 hdr->u0.req.opcode = opcode;
74 82 hdr->u0.req.subsystem = subsys;
75 83 hdr->u0.req.port_number = port;
76 84 hdr->u0.req.domain = dom;
77 85
78 86 hdr->u0.req.timeout = timeout;
79 87 hdr->u0.req.request_length = pyld_len - sizeof (struct mbx_hdr);
80 - hdr->u0.req.rsvd0 = 0;
88 + hdr->u0.req.version = version;
81 89 } /* mbx_common_req_hdr_init */
82 90
83 91 /*
84 92 * function to initialize the hw with host endian information
85 93 *
86 94 * dev - software handle to the device
87 95 *
88 96 * return 0 on success, ETIMEDOUT on failure
89 97 */
90 98 int
91 99 oce_mbox_init(struct oce_dev *dev)
92 100 {
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
93 101 struct oce_bmbx *mbx;
94 102 uint8_t *ptr;
95 103 int ret = 0;
96 104
97 105 ASSERT(dev != NULL);
98 106
99 107 mbx = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
100 108 ptr = (uint8_t *)&mbx->mbx;
101 109
102 110 /* Endian Signature */
103 - *ptr++ = 0xff;
111 + *ptr++ = 0xFF;
104 112 *ptr++ = 0x12;
105 113 *ptr++ = 0x34;
106 - *ptr++ = 0xff;
107 - *ptr++ = 0xff;
114 + *ptr++ = 0xFF;
115 + *ptr++ = 0xFF;
108 116 *ptr++ = 0x56;
109 117 *ptr++ = 0x78;
110 - *ptr = 0xff;
118 + *ptr = 0xFF;
111 119
112 120 ret = oce_mbox_dispatch(dev, 0);
113 -
114 121 if (ret != 0)
115 122 oce_log(dev, CE_NOTE, MOD_CONFIG,
116 - "Failed to set endian %d", ret);
123 + "Failed to set endianess %d", ret);
117 124
118 125 return (ret);
119 126 } /* oce_mbox_init */
120 127
121 128 /*
129 + * function to reset the hw with host endian information
130 + *
131 + * dev - software handle to the device
132 + *
133 + * return 0 on success, ETIMEDOUT on failure
134 + */
135 +int
136 +oce_mbox_fini(struct oce_dev *dev)
137 +{
138 + struct oce_bmbx *mbx;
139 + uint8_t *ptr;
140 + int ret = 0;
141 +
142 + ASSERT(dev != NULL);
143 +
144 + mbx = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
145 + ptr = (uint8_t *)&mbx->mbx;
146 +
147 + /* Endian Signature */
148 + *ptr++ = 0xFF;
149 + *ptr++ = 0xAA;
150 + *ptr++ = 0xBB;
151 + *ptr++ = 0xFF;
152 + *ptr++ = 0xFF;
153 + *ptr++ = 0xCC;
154 + *ptr++ = 0xDD;
155 + *ptr = 0xFF;
156 +
157 + ret = oce_mbox_dispatch(dev, 0);
158 + if (ret != 0)
159 + oce_log(dev, CE_NOTE, MOD_CONFIG,
160 + "Failed to reset endianess %d", ret);
161 +
162 + return (ret);
163 +} /* oce_mbox_fini */
164 +
165 +/*
122 166 * function to wait till we get a mbox ready after writing to the
123 167 * mbox doorbell
124 168 *
125 169 * dev - software handle to the device
126 170 *
127 171 * return 0=ready, ETIMEDOUT=>not ready but timed out
128 172 */
129 173 int
130 174 oce_mbox_wait(struct oce_dev *dev, uint32_t tmo_sec)
131 175 {
132 176 clock_t tmo;
133 177 clock_t now, tstamp;
134 178 pd_mpu_mbox_db_t mbox_db;
135 179
136 180 tmo = (tmo_sec > 0) ? drv_usectohz(tmo_sec * 1000000) :
137 181 drv_usectohz(DEFAULT_MQ_MBOX_TIMEOUT);
138 182
139 183 /* Add the default timeout to wait for a mailbox to complete */
140 184 tmo += drv_usectohz(MBX_READY_TIMEOUT);
141 185
142 186 tstamp = ddi_get_lbolt();
143 187 for (;;) {
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
144 188 now = ddi_get_lbolt();
145 189 if ((now - tstamp) >= tmo) {
146 190 tmo = 0;
147 191 break;
148 192 }
149 193
150 194 mbox_db.dw0 = OCE_DB_READ32(dev, PD_MPU_MBOX_DB);
151 195 if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
152 196 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
153 197 oce_fm_ereport(dev, DDI_FM_DEVICE_INVAL_STATE);
198 + return (EIO);
154 199 }
155 200
156 201 if (mbox_db.bits.ready) {
157 202 return (0);
158 203 }
159 204 drv_usecwait(5);
160 205 }
161 206
162 207 return (ETIMEDOUT);
163 208 } /* oce_mbox_wait */
164 209
165 210 /*
166 211 * function to dispatch a mailbox command present in the mq mbox
167 212 *
168 213 * dev - software handle to the device
169 214 *
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
170 215 * return 0 on success, ETIMEDOUT on failure
171 216 */
172 217 int
173 218 oce_mbox_dispatch(struct oce_dev *dev, uint32_t tmo_sec)
174 219 {
175 220 pd_mpu_mbox_db_t mbox_db;
176 221 uint32_t pa;
177 222 int ret;
178 223
179 224 /* sync the bmbx */
180 - (void) DBUF_SYNC(dev->bmbx, DDI_DMA_SYNC_FORDEV);
225 + DBUF_SYNC(dev->bmbx, 0, 0, DDI_DMA_SYNC_FORDEV);
181 226
182 227 /* write 30 bits of address hi dword */
183 228 pa = (uint32_t)(DBUF_PA(dev->bmbx) >> 34);
184 229 bzero(&mbox_db, sizeof (pd_mpu_mbox_db_t));
185 230 mbox_db.bits.ready = 0;
186 231 mbox_db.bits.hi = 1;
187 232 mbox_db.bits.address = pa;
188 233
189 234 /* wait for mbox ready */
190 235 ret = oce_mbox_wait(dev, tmo_sec);
191 236 if (ret != 0) {
192 237 return (ret);
193 238 }
194 239
195 240 /* ring the doorbell */
196 241 OCE_DB_WRITE32(dev, PD_MPU_MBOX_DB, mbox_db.dw0);
197 242
198 243 if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
199 244 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
245 + return (EIO);
200 246 }
201 247
202 248 /* wait for mbox ready */
203 249 ret = oce_mbox_wait(dev, tmo_sec);
204 250 if (ret != 0) {
205 251 oce_log(dev, CE_NOTE, MOD_CONFIG,
206 252 "BMBX TIMED OUT PROGRAMMING HI ADDR: %d", ret);
207 253 /* if mbx times out, hw is in invalid state */
208 254 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
209 255 oce_fm_ereport(dev, DDI_FM_DEVICE_INVAL_STATE);
210 256 return (ret);
211 257 }
212 258
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
213 259 /* now write 30 bits of address lo dword */
214 260 pa = (uint32_t)(DBUF_PA(dev->bmbx) >> 4) & 0x3fffffff;
215 261 mbox_db.bits.ready = 0;
216 262 mbox_db.bits.hi = 0;
217 263 mbox_db.bits.address = pa;
218 264
219 265 /* ring the doorbell */
220 266 OCE_DB_WRITE32(dev, PD_MPU_MBOX_DB, mbox_db.dw0);
221 267 if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
222 268 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
269 + return (EIO);
223 270 }
224 271
225 272 /* wait for mbox ready */
226 273 ret = oce_mbox_wait(dev, tmo_sec);
274 +
275 + if (ret != 0) {
276 + oce_log(dev, CE_NOTE, MOD_CONFIG,
277 + "BMBX TIMED OUT PROGRAMMING LO ADDR: %d", ret);
278 + return (ret);
279 + }
280 +
227 281 /* sync */
228 - (void) ddi_dma_sync(DBUF_DHDL(dev->bmbx), 0, 0,
229 - DDI_DMA_SYNC_FORKERNEL);
282 + DBUF_SYNC(dev->bmbx, 0, 0, DDI_DMA_SYNC_FORKERNEL);
230 283 if (oce_fm_check_dma_handle(dev, DBUF_DHDL(dev->bmbx)) != DDI_FM_OK) {
231 284 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
232 285 return (EIO);
233 286 }
234 287 return (ret);
235 288 } /* oce_mbox_dispatch */
236 289
237 290 /*
238 - * function to post a MBX to the mbox
291 + * function to post a MBX to the bootstrap mbox
239 292 *
240 293 * dev - software handle to the device
241 294 * mbx - pointer to the MBX to send
242 - * mbxctx - pointer to the mbx context structure
295 + * tmo - timeout in seconds
243 296 *
244 297 * return 0 on success, ETIMEDOUT on failure
245 298 */
246 299 int
247 -oce_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx,
248 - struct oce_mbx_ctx *mbxctx)
300 +oce_mbox_issue_bootstrap(struct oce_dev *dev, struct oce_mbx *mbx,
301 + uint32_t tmo)
249 302 {
250 303 struct oce_mbx *mb_mbx = NULL;
251 304 struct oce_mq_cqe *mb_cqe = NULL;
252 305 struct oce_bmbx *mb = NULL;
253 306 int ret = 0;
254 - uint32_t tmo = 0;
307 + uint32_t status = 0;
255 308
256 309 mutex_enter(&dev->bmbx_lock);
257 -
258 310 mb = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
259 311 mb_mbx = &mb->mbx;
260 312
261 - /* get the tmo */
262 - tmo = mbx->tag[0];
263 - mbx->tag[0] = 0;
264 -
265 313 /* copy mbx into mbox */
266 314 bcopy(mbx, mb_mbx, sizeof (struct oce_mbx));
267 315
268 316 /* now dispatch */
269 317 ret = oce_mbox_dispatch(dev, tmo);
270 318 if (ret != 0) {
271 319 mutex_exit(&dev->bmbx_lock);
272 320 return (ret);
273 321 }
274 322
275 323 /* sync */
276 -
277 - (void) ddi_dma_sync(DBUF_DHDL(dev->bmbx), 0, 0,
278 - DDI_DMA_SYNC_FORKERNEL);
324 + DBUF_SYNC(dev->bmbx, 0, 0, DDI_DMA_SYNC_FORKERNEL);
279 325 ret = oce_fm_check_dma_handle(dev, DBUF_DHDL(dev->bmbx));
280 326 if (ret != DDI_FM_OK) {
281 327 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
282 328 mutex_exit(&dev->bmbx_lock);
283 329 return (EIO);
284 330 }
285 331
286 332 /*
287 333 * the command completed successfully. Now get the
288 334 * completion queue entry
289 335 */
290 336 mb_cqe = &mb->cqe;
291 337 DW_SWAP(u32ptr(&mb_cqe->u0.dw[0]), sizeof (struct oce_mq_cqe));
292 338
293 339 /* copy mbox mbx back */
294 340 bcopy(mb_mbx, mbx, sizeof (struct oce_mbx));
295 341
296 342 /* check mbox status */
297 - if (mb_cqe->u0.s.completion_status != 0) {
298 - oce_log(dev, CE_WARN, MOD_CONFIG,
299 - "MBOX Command Failed with Status: %d %d",
300 - mb_cqe->u0.s.completion_status,
301 - mb_cqe->u0.s.extended_status);
302 - mutex_exit(&dev->bmbx_lock);
303 - return (EIO);
304 - }
305 -
306 - /*
307 - * store the mbx context in the cqe tag section so that
308 - * the upper layer handling the cqe can associate the mbx
309 - * with the response
310 - */
311 - if (mbxctx) {
312 - /* save context */
313 - mbxctx->mbx = mb_mbx;
314 - bcopy(&mbxctx, mb_cqe->u0.s.mq_tag,
315 - sizeof (struct oce_mbx_ctx *));
316 - }
317 -
343 + status = mb_cqe->u0.s.completion_status << 16 |
344 + mb_cqe->u0.s.extended_status;
318 345 mutex_exit(&dev->bmbx_lock);
319 - return (0);
320 -} /* oce_mbox_post */
346 + return (status);
347 +} /* oce_mbox_issue_bootstrap */
321 348
322 349 /*
323 350 * function to get the firmware version
324 351 *
325 352 * dev - software handle to the device
326 353 *
327 354 * return 0 on success, EIO on failure
328 355 */
329 356 int
330 -oce_get_fw_version(struct oce_dev *dev)
357 +oce_get_fw_version(struct oce_dev *dev, uint32_t mode)
331 358 {
332 359 struct oce_mbx mbx;
333 360 struct mbx_get_common_fw_version *fwcmd;
334 361 int ret = 0;
335 362
336 363 bzero(&mbx, sizeof (struct oce_mbx));
337 364
338 365 /* initialize the ioctl header */
339 366 fwcmd = (struct mbx_get_common_fw_version *)&mbx.payload;
340 367 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
341 368 MBX_SUBSYSTEM_COMMON,
342 369 OPCODE_GET_COMMON_FW_VERSION,
343 370 MBX_TIMEOUT_SEC,
344 - sizeof (struct mbx_get_common_fw_version));
371 + sizeof (struct mbx_get_common_fw_version), 0);
345 372
346 373 /* fill rest of mbx */
347 374 mbx.u0.s.embedded = 1;
348 375 mbx.payload_length = sizeof (struct mbx_get_common_fw_version);
349 376 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
350 377
351 378 /* now post the command */
352 - ret = oce_mbox_post(dev, &mbx, NULL);
353 -
379 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
354 380 if (ret != 0) {
355 381 return (ret);
356 382 }
383 +
357 384 bcopy(fwcmd->params.rsp.fw_ver_str, dev->fw_version, 32);
358 385
359 386 oce_log(dev, CE_NOTE, MOD_CONFIG, "%s %s",
360 387 fwcmd->params.rsp.fw_ver_str,
361 388 fwcmd->params.rsp.fw_on_flash_ver_str);
362 389
363 390 return (0);
364 391 } /* oce_get_fw_version */
365 392
366 393 /*
367 394 * function to invoke f/w reset via. mailbox
368 395 * does not hold bootstap lock called by quiesce
369 396 *
370 397 * dev - software handle to the device
371 398 *
372 399 * return 0 on success, ETIMEDOUT on failure
373 400 *
374 401 */
375 402 int
376 403 oce_reset_fun(struct oce_dev *dev)
377 404 {
378 405 struct oce_mbx *mbx;
379 406 struct oce_bmbx *mb;
380 407 struct ioctl_common_function_reset *fwcmd;
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
381 408
382 409 mb = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
383 410 mbx = &mb->mbx;
384 411 bzero(mbx, sizeof (struct oce_mbx));
385 412 /* initialize the ioctl header */
386 413 fwcmd = (struct ioctl_common_function_reset *)&mbx->payload;
387 414 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
388 415 MBX_SUBSYSTEM_COMMON,
389 416 OPCODE_COMMON_FUNCTION_RESET,
390 417 MBX_TIMEOUT_SEC,
391 - sizeof (struct ioctl_common_function_reset));
418 + sizeof (struct ioctl_common_function_reset), 0);
392 419
393 420 /* fill rest of mbx */
394 421 mbx->u0.s.embedded = 1;
395 422 mbx->payload_length = sizeof (struct ioctl_common_function_reset);
396 423 DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ);
397 424
398 425 return (oce_mbox_dispatch(dev, 0));
399 426 } /* oce_reset_fun */
400 427
401 428 /*
402 429 * function to read the mac address associated with an interface
403 430 *
404 431 * dev - software handle to the device
405 432 * if_id - interface id to read the address from
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
406 433 * perm - set to 1 if reading the factory mac address. In this case
407 434 * if_id is ignored
408 435 * type - type of the mac address, whether network or storage
409 436 * mac - [OUTPUT] pointer to a buffer containing the mac address
410 437 * when the command succeeds
411 438 *
412 439 * return 0 on success, EIO on failure
413 440 */
414 441 int
415 442 oce_read_mac_addr(struct oce_dev *dev, uint32_t if_id, uint8_t perm,
416 - uint8_t type, struct mac_address_format *mac)
443 + uint8_t type, struct mac_address_format *mac, uint32_t mode)
417 444 {
418 445 struct oce_mbx mbx;
419 446 struct mbx_query_common_iface_mac *fwcmd;
420 447 int ret = 0;
421 448
422 449 bzero(&mbx, sizeof (struct oce_mbx));
423 450 /* initialize the ioctl header */
424 451 fwcmd = (struct mbx_query_common_iface_mac *)&mbx.payload;
425 452 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
426 453 MBX_SUBSYSTEM_COMMON,
427 454 OPCODE_QUERY_COMMON_IFACE_MAC,
428 455 MBX_TIMEOUT_SEC,
429 - sizeof (struct mbx_query_common_iface_mac));
456 + sizeof (struct mbx_query_common_iface_mac), 0);
430 457
431 458 /* fill the command */
432 459 fwcmd->params.req.permanent = perm;
433 460 if (perm)
434 461 fwcmd->params.req.if_id = (uint16_t)if_id;
435 462 else
436 463 fwcmd->params.req.if_id = 0;
437 464 fwcmd->params.req.type = type;
438 465
439 466 /* fill rest of mbx */
440 467 mbx.u0.s.embedded = 1;
441 468 mbx.payload_length = sizeof (struct mbx_query_common_iface_mac);
442 469 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
443 470
444 471 /* now post the command */
445 - ret = oce_mbox_post(dev, &mbx, NULL);
472 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
446 473 if (ret != 0) {
447 474 return (ret);
448 475 }
449 476
450 477 /* get the response */
451 478 oce_log(dev, CE_NOTE, MOD_CONFIG,
452 479 "MAC addr size = 0x%x",
453 480 LE_16(fwcmd->params.rsp.mac.size_of_struct));
454 481 oce_log(dev, CE_NOTE, MOD_CONFIG,
455 482 "MAC_ADDR:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x",
456 483 fwcmd->params.rsp.mac.mac_addr[0],
457 484 fwcmd->params.rsp.mac.mac_addr[1],
458 485 fwcmd->params.rsp.mac.mac_addr[2],
459 486 fwcmd->params.rsp.mac.mac_addr[3],
460 487 fwcmd->params.rsp.mac.mac_addr[4],
461 488 fwcmd->params.rsp.mac.mac_addr[5]);
462 489
463 490 /* copy the mac addres in the output parameter */
464 491 mac->size_of_struct = LE_16(fwcmd->params.rsp.mac.size_of_struct);
465 492 bcopy(&fwcmd->params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
466 493 mac->size_of_struct);
467 494
468 495 return (0);
469 496 } /* oce_read_mac_addr */
470 497
471 498 /*
472 499 * function to create an interface using the OPCODE_CREATE_COMMON_IFACE
473 500 * command
474 501 *
475 502 * dev - software handle to the device
476 503 * cap_flags - capability flags
477 504 * en_flags - enable capability flags
|
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
478 505 * vlan_tag - optional vlan tag to associate with the if
479 506 * mac_addr - pointer to a buffer containing the mac address
480 507 * if_id - [OUTPUT] pointer to an integer to hold the ID of the
481 508 * interface created
482 509 *
483 510 * return 0 on success, EIO on failure
484 511 */
485 512 int
486 513 oce_if_create(struct oce_dev *dev, uint32_t cap_flags, uint32_t en_flags,
487 514 uint16_t vlan_tag, uint8_t *mac_addr,
488 - uint32_t *if_id)
515 + uint32_t *if_id, uint32_t mode)
489 516 {
490 517 struct oce_mbx mbx;
491 518 struct mbx_create_common_iface *fwcmd;
492 519 int ret = 0;
493 520
494 521 bzero(&mbx, sizeof (struct oce_mbx));
495 522
496 523 /* initialize the ioctl header */
497 524 fwcmd = (struct mbx_create_common_iface *)&mbx.payload;
498 525 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
499 526 MBX_SUBSYSTEM_COMMON,
500 527 OPCODE_CREATE_COMMON_IFACE,
501 528 MBX_TIMEOUT_SEC,
502 - sizeof (struct mbx_create_common_iface));
529 + sizeof (struct mbx_create_common_iface), 0);
503 530 DW_SWAP(u32ptr(&fwcmd->hdr), sizeof (struct mbx_hdr));
504 531
505 532 /* fill the command */
506 533 fwcmd->params.req.version = 0;
507 534 fwcmd->params.req.cap_flags = LE_32(cap_flags);
508 535 fwcmd->params.req.enable_flags = LE_32(en_flags);
509 536 if (mac_addr != NULL) {
510 537 bcopy(mac_addr, &fwcmd->params.req.mac_addr[0],
511 538 ETHERADDRL);
512 539 fwcmd->params.req.vlan_tag.u0.normal.vtag = LE_16(vlan_tag);
513 540 fwcmd->params.req.mac_invalid = B_FALSE;
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
514 541 } else {
515 542 fwcmd->params.req.mac_invalid = B_TRUE;
516 543 }
517 544
518 545 /* fill rest of mbx */
519 546 mbx.u0.s.embedded = 1;
520 547 mbx.payload_length = sizeof (struct mbx_create_common_iface);
521 548 DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
522 549
523 550 /* now post the command */
524 - ret = oce_mbox_post(dev, &mbx, NULL);
551 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
525 552 if (ret != 0) {
526 553 return (ret);
527 554 }
528 555
529 -
530 -
531 556 /* get response */
532 557 *if_id = LE_32(fwcmd->params.rsp.if_id);
533 558 oce_log(dev, CE_NOTE, MOD_CONFIG,
534 559 "IF_ID = 0x%x", *if_id);
535 560
536 561 /* If asked to set mac addr save the pmac handle */
537 562 if (mac_addr != NULL) {
538 563 dev->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
539 564 oce_log(dev, CE_NOTE, MOD_CONFIG,
540 565 "PMAC_ID = 0x%x", dev->pmac_id);
541 566 }
542 567 return (0);
543 568 } /* oce_if_create */
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
544 569
545 570 /*
546 571 * function to delete an interface
547 572 *
548 573 * dev - software handle to the device
549 574 * if_id - ID of the interface to delete
550 575 *
551 576 * return 0 on success, EIO on failure
552 577 */
553 578 int
554 -oce_if_del(struct oce_dev *dev, uint32_t if_id)
579 +oce_if_del(struct oce_dev *dev, uint32_t if_id, uint32_t mode)
555 580 {
556 581 struct oce_mbx mbx;
557 582 struct mbx_destroy_common_iface *fwcmd;
558 583 int ret = 0;
559 584
560 585 bzero(&mbx, sizeof (struct oce_mbx));
561 586 /* initialize the ioctl header */
562 587 fwcmd = (struct mbx_destroy_common_iface *)&mbx.payload;
563 588 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
564 589 MBX_SUBSYSTEM_COMMON,
565 590 OPCODE_DESTROY_COMMON_IFACE,
566 591 MBX_TIMEOUT_SEC,
567 - sizeof (struct mbx_destroy_common_iface));
592 + sizeof (struct mbx_destroy_common_iface), 0);
568 593
569 594 /* fill the command */
570 595 fwcmd->params.req.if_id = if_id;
571 596
572 597 /* fill rest of mbx */
573 598 mbx.u0.s.embedded = 1;
574 599 mbx.payload_length = sizeof (struct mbx_destroy_common_iface);
575 600 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
576 601
577 602 /* post the command */
578 - ret = oce_mbox_post(dev, &mbx, NULL);
603 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
579 604 return (ret);
580 605 } /* oce_if_del */
581 606
582 607 /*
583 608 * function to query the link status from the hardware
584 609 *
585 610 * dev - software handle to the device
586 611 * link_status - [OUT] pointer to the structure returning the link attributes
587 612 *
588 613 * return 0 on success, EIO on failure
589 614 */
590 615 int
591 -oce_get_link_status(struct oce_dev *dev, struct link_status *link)
616 +oce_get_link_status(struct oce_dev *dev, link_state_t *link_status,
617 + int32_t *link_speed, uint8_t *link_duplex, uint8_t cmd_ver, uint32_t mode)
592 618 {
593 619 struct oce_mbx mbx;
594 620 struct mbx_query_common_link_status *fwcmd;
595 621 int ret = 0;
596 622
597 623 bzero(&mbx, sizeof (struct oce_mbx));
598 624
599 625 /* initialize the ioctl header */
600 626 fwcmd = (struct mbx_query_common_link_status *)&mbx.payload;
601 627 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
602 628 MBX_SUBSYSTEM_COMMON,
603 629 OPCODE_QUERY_COMMON_LINK_STATUS,
604 630 MBX_TIMEOUT_SEC,
605 - sizeof (struct mbx_query_common_link_status));
631 + sizeof (struct mbx_query_common_link_status), cmd_ver);
606 632
607 633 /* fill rest of mbx */
608 634 mbx.u0.s.embedded = 1;
609 635 mbx.payload_length = sizeof (struct mbx_query_common_link_status);
610 636 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
611 637
612 638 /* post the command */
613 - ret = oce_mbox_post(dev, &mbx, NULL);
614 -
639 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
615 640 if (ret != 0) {
641 + oce_log(dev, CE_NOTE, MOD_CONFIG,
642 + "Failed to query link status: 0x%x", ret);
616 643 return (ret);
617 644 }
618 645
619 646 /* interpret response */
620 - bcopy(&fwcmd->params.rsp, link, sizeof (struct link_status));
621 - link->logical_link_status = LE_32(link->logical_link_status);
622 - link->qos_link_speed = LE_16(link->qos_link_speed);
647 + *link_status = (LE_32(fwcmd->params.rsp.logical_link_status) ==
648 + NTWK_LOGICAL_LINK_UP) ? LINK_STATE_UP : LINK_STATE_DOWN;
649 + *link_speed = (fwcmd->params.rsp.qos_link_speed != 0) ?
650 + LE_16(fwcmd->params.rsp.qos_link_speed) * 10:
651 + pow10[fwcmd->params.rsp.mac_speed];
652 + *link_duplex = fwcmd->params.rsp.mac_duplex;
623 653
624 654 return (0);
625 655 } /* oce_get_link_status */
626 656
627 657 /*
628 658 * function to configure the rx filter on the interface
629 659 *
630 660 * dev - software handle to the device
631 661 * filter - mbx command containing the filter parameters
632 662 *
633 663 * return 0 on success, EIO on failure
634 664 */
635 665 int
636 666 oce_set_rx_filter(struct oce_dev *dev,
637 - struct mbx_set_common_ntwk_rx_filter *filter)
667 + struct mbx_set_common_ntwk_rx_filter *filter, uint32_t mode)
638 668 {
639 669 struct oce_mbx mbx;
640 670 struct mbx_set_common_ntwk_rx_filter *fwcmd;
641 671 int ret;
642 672
643 673 bzero(&mbx, sizeof (struct oce_mbx));
644 674 fwcmd = (struct mbx_set_common_ntwk_rx_filter *)&mbx.payload;
645 675 /* fill the command */
646 676 bcopy(filter, fwcmd, sizeof (struct mbx_set_common_ntwk_rx_filter));
647 677
648 678 /* initialize the ioctl header */
649 679 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
650 680 MBX_SUBSYSTEM_COMMON,
651 681 OPCODE_COMMON_NTWK_RX_FILTER,
652 682 MBX_TIMEOUT_SEC,
653 - sizeof (struct mbx_set_common_ntwk_rx_filter));
683 + sizeof (struct mbx_set_common_ntwk_rx_filter), 0);
654 684
655 685 /* fill rest of mbx */
656 686 mbx.u0.s.embedded = 1;
657 687 mbx.payload_length = sizeof (struct mbx_set_common_ntwk_rx_filter);
658 688 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
659 689
660 690 /* post the command */
661 - ret = oce_mbox_post(dev, &mbx, NULL);
691 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
692 + if (ret != 0) {
693 + oce_log(dev, CE_NOTE, MOD_CONFIG,
694 + "Set RX filter failed: 0x%x", ret);
695 + }
662 696
663 697 return (ret);
664 698 } /* oce_set_rx_filter */
665 699
666 700 /*
667 701 * function to send the mbx command to update the mcast table with fw
668 702 *
669 703 * dev - software handle to the device
670 704 * mca_table - array of mcast address to update
671 705 * mca_cnt - number of elements in mca_table
672 706 * enable_promisc - flag to enable/disable mcast-promiscuous mode
673 707 *
674 708 * return 0 on success, EIO on failure
675 709 */
676 710 int
677 711 oce_set_multicast_table(struct oce_dev *dev, uint32_t if_id,
678 -struct ether_addr *mca_table, uint16_t mca_cnt, boolean_t promisc)
712 + struct ether_addr *mca_table, uint16_t mca_cnt, boolean_t promisc,
713 + uint32_t mode)
679 714 {
680 715 struct oce_mbx mbx;
681 716 struct mbx_set_common_iface_multicast *fwcmd;
682 717 int ret;
683 718
684 719 bzero(&mbx, sizeof (struct oce_mbx));
685 720 fwcmd = (struct mbx_set_common_iface_multicast *)&mbx.payload;
686 721
687 722 /* initialize the ioctl header */
688 723 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
689 724 MBX_SUBSYSTEM_COMMON,
690 725 OPCODE_SET_COMMON_IFACE_MULTICAST,
691 726 MBX_TIMEOUT_SEC,
692 - sizeof (struct mbx_set_common_iface_multicast));
727 + sizeof (struct mbx_set_common_iface_multicast), 0);
693 728
694 729 /* fill the command */
695 730 fwcmd->params.req.if_id = (uint8_t)if_id;
696 731 if (mca_table != NULL) {
697 732 bcopy(mca_table, &fwcmd->params.req.mac[0],
698 733 mca_cnt * ETHERADDRL);
699 734 }
700 735 fwcmd->params.req.num_mac = LE_16(mca_cnt);
701 736 fwcmd->params.req.promiscuous = (uint8_t)promisc;
702 737
703 738 /* fill rest of mbx */
704 739 mbx.u0.s.embedded = B_TRUE;
705 740 mbx.payload_length = sizeof (struct mbx_set_common_iface_multicast);
706 741 /* Swap only MBX header + BOOTSTRAP HDR */
707 742 DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + OCE_MBX_RRHDR_SZ));
708 743
709 744 /* post the command */
710 - ret = oce_mbox_post(dev, &mbx, NULL);
745 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
711 746
712 747 return (ret);
713 748 } /* oce_set_multicast_table */
714 749
715 750 /*
716 751 * function to query the fw attributes from the hw
717 752 *
718 753 * dev - software handle to the device
719 754 *
720 755 * return 0 on success, EIO on failure
721 756 */
722 757 int
723 -oce_get_fw_config(struct oce_dev *dev)
758 +oce_get_fw_config(struct oce_dev *dev, uint32_t mode)
724 759 {
725 760 struct oce_mbx mbx;
726 761 struct mbx_common_query_fw_config *fwcmd;
762 + struct mbx_common_set_drvfn_capab *capab;
727 763 int ret = 0;
728 764
729 765 bzero(&mbx, sizeof (struct oce_mbx));
730 766 /* initialize the ioctl header */
731 767 fwcmd = (struct mbx_common_query_fw_config *)&mbx.payload;
732 768 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
733 769 MBX_SUBSYSTEM_COMMON,
734 770 OPCODE_QUERY_COMMON_FIRMWARE_CONFIG,
735 771 MBX_TIMEOUT_SEC,
736 - sizeof (struct mbx_common_query_fw_config));
772 + sizeof (struct mbx_common_query_fw_config), 0);
737 773
738 774 /* fill rest of mbx */
739 775 mbx.u0.s.embedded = 1;
740 776 mbx.payload_length = sizeof (struct mbx_common_query_fw_config);
741 777 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
742 778
743 779 /* now post the command */
744 - ret = oce_mbox_post(dev, &mbx, NULL);
780 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
745 781
746 782 if (ret != 0) {
783 + oce_log(dev, CE_WARN, MOD_CONFIG,
784 + "Failed to query fw config: 0x%x", ret);
747 785 return (ret);
748 786 }
749 787
750 788 /* swap and copy into buffer */
751 789 DW_SWAP(u32ptr(fwcmd), sizeof (struct mbx_common_query_fw_config));
752 790
753 791 dev->config_number = fwcmd->params.rsp.config_number;
754 792 dev->asic_revision = fwcmd->params.rsp.asic_revision;
755 793 dev->port_id = fwcmd->params.rsp.port_id;
756 794 dev->function_mode = fwcmd->params.rsp.function_mode;
757 795
758 796 /* get the max rings alloted for this function */
759 797 if (fwcmd->params.rsp.ulp[0].mode & ULP_NIC_MODE) {
760 798 dev->max_tx_rings = fwcmd->params.rsp.ulp[0].wq_count;
761 799 dev->max_rx_rings = fwcmd->params.rsp.ulp[0].rq_count;
762 800 } else {
763 801 dev->max_tx_rings = fwcmd->params.rsp.ulp[1].wq_count;
764 802 dev->max_rx_rings = fwcmd->params.rsp.ulp[1].rq_count;
765 803 }
766 804 dev->function_caps = fwcmd->params.rsp.function_caps;
805 +
806 + if (!LANCER_CHIP(dev)) {
807 + bzero(&mbx, sizeof (struct oce_mbx));
808 + /* initialize the ioctl header */
809 + capab = (struct mbx_common_set_drvfn_capab *)&mbx.payload;
810 + mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
811 + MBX_SUBSYSTEM_COMMON,
812 + OPCODE_COMMON_SET_DRIVER_FUNCTION_CAPABILITIES,
813 + MBX_TIMEOUT_SEC,
814 + sizeof (struct mbx_common_set_drvfn_capab), 0);
815 +
816 + /* fill rest of mbx */
817 + mbx.u0.s.embedded = 1;
818 + mbx.payload_length =
819 + sizeof (struct mbx_common_set_drvfn_capab);
820 +
821 + capab->params.request.valid_capability_flags =
822 + DRVFN_CAPAB_BE3_NATIVE;
823 + capab->params.request.capability_flags = DRVFN_CAPAB_BE3_NATIVE;
824 +
825 + DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
826 +
827 + /* now post the command */
828 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
829 +
830 + if (ret != 0) {
831 + if ((OCE_MBX_STATUS(fwcmd) ==
832 + MGMT_STATUS_ILLEGAL_REQUEST) &&
833 + OCE_MBX_ADDL_STATUS(fwcmd) ==
834 + MGMT_ADDI_STATUS_INVALID_OPCODE) {
835 + /*
836 + * run in legacy mode
837 + */
838 + dev->rx_rings_per_group =
839 + min(dev->rx_rings_per_group,
840 + MAX_RING_PER_GROUP_LEGACY);
841 + } else {
842 + return (ret);
843 + }
844 + } else {
845 + /* swap and copy into buffer */
846 + dev->drvfn_caps =
847 + LE_32(capab->params.response.capability_flags);
848 + }
849 +
850 + if (!(dev->drvfn_caps & DRVFN_CAPAB_BE3_NATIVE))
851 + dev->rx_rings_per_group = min(dev->rx_rings_per_group,
852 + MAX_RING_PER_GROUP_LEGACY);
853 + }
854 + oce_log(dev, CE_NOTE, MOD_CONFIG,
855 + "drvfn_caps = 0x%x, function_caps = 0x%x",
856 + dev->drvfn_caps, dev->function_caps);
857 +
767 858 return (0);
768 859 } /* oce_get_fw_config */
769 860
770 861 /*
771 862 * function to retrieve statistic counters from the hardware
772 863 *
773 864 * dev - software handle to the device
774 865 *
775 866 * return 0 on success, EIO on failure
776 867 */
777 868 int
778 -oce_get_hw_stats(struct oce_dev *dev)
869 +oce_get_hw_stats(struct oce_dev *dev, uint32_t mode)
779 870 {
780 871 struct oce_mbx mbx;
781 - struct mbx_get_nic_stats *fwcmd = dev->hw_stats;
872 + struct mbx_get_nic_stats *fwcmd =
873 + (struct mbx_get_nic_stats *)DBUF_VA(dev->stats_dbuf);
782 874 int ret = 0;
783 875
784 876 bzero(&mbx, sizeof (struct oce_mbx));
877 + bzero(fwcmd, sizeof (struct mbx_get_nic_stats));
878 +
785 879 /* initialize the ioctl header */
786 880 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
787 881 MBX_SUBSYSTEM_NIC,
788 882 OPCODE_GET_NIC_STATS,
789 883 MBX_TIMEOUT_SEC,
790 - sizeof (struct mbx_get_nic_stats));
884 + sizeof (struct mbx_get_nic_stats), 0);
885 +
886 + if (dev->chip_rev == OC_CNA_GEN3)
887 + fwcmd->hdr.u0.req.version = 1;
791 888 DW_SWAP(u32ptr(fwcmd), sizeof (struct mbx_get_nic_stats));
792 889
793 890 /* fill rest of mbx */
794 891 mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(DBUF_PA(dev->stats_dbuf));
795 892 mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(DBUF_PA(dev->stats_dbuf));
796 893 mbx.payload.u0.u1.sgl[0].length = sizeof (struct mbx_get_nic_stats);
797 894 mbx.payload_length = sizeof (struct mbx_get_nic_stats);
798 895
799 896 mbx.u0.s.embedded = 0;
800 897 mbx.u0.s.sge_count = 1;
801 898
802 899 DW_SWAP(u32ptr(&mbx), sizeof (struct oce_mq_sge) + OCE_BMBX_RHDR_SZ);
803 900
804 - bzero(&dev->hw_stats->params, sizeof (dev->hw_stats->params));
805 -
806 901 /* sync for device */
807 - (void) DBUF_SYNC(dev->stats_dbuf, DDI_DMA_SYNC_FORDEV);
902 + DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORDEV);
808 903
809 904 /* now post the command */
810 - ret = oce_mbox_post(dev, &mbx, NULL);
905 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
811 906 /* sync the stats */
812 - (void) DBUF_SYNC(dev->stats_dbuf, DDI_DMA_SYNC_FORKERNEL);
907 + DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORKERNEL);
813 908
814 909 /* Check the mailbox status and command completion status */
815 910 if (ret != 0) {
911 + oce_log(dev, CE_WARN, MOD_CONFIG,
912 + "Failed to get stats: 0x%x", ret);
816 913 return (ret);
817 914 }
818 915
819 - DW_SWAP(u32ptr(dev->hw_stats), sizeof (struct mbx_get_nic_stats));
916 + DW_SWAP(u32ptr(&fwcmd->params.rsp), sizeof (struct mbx_get_nic_stats));
820 917 return (0);
821 918 } /* oce_get_hw_stats */
822 919
823 920 /*
921 + * function to retrieve statistic counters from Lancer hardware
922 + *
923 + * dev - software handle to the device
924 + *
925 + * return 0 on success, EIO on failure
926 + */
927 +int
928 +oce_get_pport_stats(struct oce_dev *dev, uint32_t mode)
929 +{
930 + struct oce_mbx mbx;
931 + struct mbx_get_pport_stats *fwcmd;
932 + int ret = 0;
933 +
934 + bzero(&mbx, sizeof (struct oce_mbx));
935 + /* initialize the ioctl header */
936 +
937 + fwcmd = (struct mbx_get_pport_stats *)DBUF_VA(dev->stats_dbuf);
938 +
939 + bzero(&fwcmd->params, sizeof (fwcmd->params));
940 +
941 + mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
942 + MBX_SUBSYSTEM_NIC,
943 + OPCODE_NIC_GET_PPORT_STATS,
944 + MBX_TIMEOUT_SEC,
945 + sizeof (struct mbx_get_nic_stats), 0);
946 + fwcmd->params.req.arg.pport_num = dev->port_id;
947 + DW_SWAP(u32ptr(fwcmd), sizeof (struct mbx_get_pport_stats));
948 +
949 + /* fill rest of mbx */
950 + mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(DBUF_PA(dev->stats_dbuf));
951 + mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(DBUF_PA(dev->stats_dbuf));
952 + mbx.payload.u0.u1.sgl[0].length = sizeof (struct mbx_get_nic_stats);
953 + mbx.payload_length = sizeof (struct mbx_get_pport_stats);
954 +
955 + mbx.u0.s.embedded = 0;
956 + mbx.u0.s.sge_count = 1;
957 +
958 + DW_SWAP(u32ptr(&mbx), sizeof (struct oce_mq_sge) + OCE_BMBX_RHDR_SZ);
959 +
960 +
961 + /* sync for device */
962 + DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORDEV);
963 +
964 + /* now post the command */
965 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
966 + /* sync the stats */
967 + DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORKERNEL);
968 +
969 + /* Check the mailbox status and command completion status */
970 + if (ret != 0) {
971 + return (ret);
972 + }
973 +
974 + DW_SWAP(u32ptr(&fwcmd->params.rsp), sizeof (struct mbx_get_nic_stats));
975 + return (0);
976 +} /* oce_get_pport_stats */
977 +
978 +/*
824 979 * function to set the number of vectors with the cev
825 980 *
826 981 * dev - software handle to the device
827 982 * num_vectors - number of MSI messages
828 983 *
829 984 * return 0 on success, EIO on failure
830 985 */
831 986 int
832 -oce_num_intr_vectors_set(struct oce_dev *dev, uint32_t num_vectors)
987 +oce_num_intr_vectors_set(struct oce_dev *dev, uint32_t num_vectors,
988 + uint32_t mode)
833 989 {
834 990 struct oce_mbx mbx;
835 991 struct mbx_common_cev_modify_msi_messages *fwcmd;
836 992 int ret = 0;
837 993
838 994 bzero(&mbx, sizeof (struct oce_mbx));
839 995 /* initialize the ioctl header */
840 996 fwcmd = (struct mbx_common_cev_modify_msi_messages *)&mbx.payload;
841 997 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
842 998 MBX_SUBSYSTEM_COMMON,
843 999 OPCODE_COMMON_CEV_MODIFY_MSI_MESSAGES,
844 1000 MBX_TIMEOUT_SEC,
845 - sizeof (struct mbx_common_cev_modify_msi_messages));
1001 + sizeof (struct mbx_common_cev_modify_msi_messages), 0);
846 1002
847 1003 /* fill the command */
848 1004 fwcmd->params.req.num_msi_msgs = LE_32(num_vectors);
849 1005
850 1006 /* fill rest of mbx */
851 1007 mbx.u0.s.embedded = 1;
852 1008 mbx.payload_length =
853 1009 sizeof (struct mbx_common_cev_modify_msi_messages);
854 1010 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
855 1011
856 1012 /* post the command */
857 - ret = oce_mbox_post(dev, &mbx, NULL);
1013 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
858 1014
859 1015 return (ret);
860 1016 } /* oce_num_intr_vectors_set */
861 1017
862 1018 /*
863 1019 * function to set flow control capability in the hardware
864 1020 *
865 1021 * dev - software handle to the device
866 1022 * flow_control - flow control flags to set
867 1023 *
868 1024 * return 0 on success, EIO on failure
869 1025 */
870 1026 int
871 -oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control)
1027 +oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control, uint32_t mode)
872 1028 {
873 1029 struct oce_mbx mbx;
874 1030 struct mbx_common_get_set_flow_control *fwcmd =
875 1031 (struct mbx_common_get_set_flow_control *)&mbx.payload;
876 1032 int ret;
877 1033
878 1034 bzero(&mbx, sizeof (struct oce_mbx));
879 1035 /* initialize the ioctl header */
880 1036 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
881 1037 MBX_SUBSYSTEM_COMMON,
882 1038 OPCODE_SET_COMMON_FLOW_CONTROL,
883 1039 MBX_TIMEOUT_SEC,
884 - sizeof (struct mbx_common_get_set_flow_control));
1040 + sizeof (struct mbx_common_get_set_flow_control), 0);
885 1041
886 1042 /* fill command */
887 1043 if (flow_control & OCE_FC_TX)
888 1044 fwcmd->tx_flow_control = 1;
889 1045
890 1046 if (flow_control & OCE_FC_RX)
891 1047 fwcmd->rx_flow_control = 1;
892 1048
893 1049 /* fill rest of mbx */
894 1050 mbx.u0.s.embedded = 1;
895 1051 mbx.payload_length = sizeof (struct mbx_common_get_set_flow_control);
896 1052 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
897 1053
898 1054 /* post the command */
899 - ret = oce_mbox_post(dev, &mbx, NULL);
1055 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1056 + if (ret != 0) {
1057 + oce_log(dev, CE_NOTE, MOD_CONFIG,
1058 + "Set flow control failed: 0x%x", ret);
1059 + }
900 1060
901 1061 return (ret);
902 1062 } /* oce_set_flow_control */
903 1063
904 1064 /*
905 1065 * function to get the current flow control setting with the hardware
906 1066 *
907 1067 * dev - software handle to the device
908 1068 * flow_control - [OUT] pointer to location where flow_control setting
909 1069 * is returned
910 1070 *
911 1071 * return 0 on success, EIO on failure
912 1072 */
913 1073 int
914 -oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control)
1074 +oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control, uint32_t mode)
915 1075 {
916 1076 struct oce_mbx mbx;
917 1077 struct mbx_common_get_set_flow_control *fwcmd;
918 1078 int ret;
919 1079
920 1080 DEV_LOCK(dev);
921 1081 if (dev->suspended) {
922 1082 DEV_UNLOCK(dev);
923 1083 return (EIO);
924 1084 }
925 1085 DEV_UNLOCK(dev);
926 1086
927 1087 bzero(&mbx, sizeof (struct oce_mbx));
928 1088 fwcmd = (struct mbx_common_get_set_flow_control *)&mbx.payload;
929 1089
930 1090 /* initialize the ioctl header */
931 1091 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
932 1092 MBX_SUBSYSTEM_COMMON,
933 1093 OPCODE_GET_COMMON_FLOW_CONTROL,
934 1094 MBX_TIMEOUT_SEC,
935 - sizeof (struct mbx_common_get_set_flow_control));
1095 + sizeof (struct mbx_common_get_set_flow_control), 0);
936 1096
937 1097 /* fill rest of mbx */
938 1098 mbx.u0.s.embedded = 1;
939 1099 mbx.payload_length = sizeof (struct mbx_common_get_set_flow_control);
940 1100 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
941 1101
942 1102 /* post the command */
943 - ret = oce_mbox_post(dev, &mbx, NULL);
1103 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
944 1104
945 1105 if (ret != 0) {
946 1106 return (ret);
947 1107 }
948 1108
949 1109 /* get the flow control */
950 1110 DW_SWAP(u32ptr(fwcmd),
951 1111 sizeof (struct mbx_common_get_set_flow_control));
952 1112 *flow_control = 0;
953 1113 if (fwcmd->tx_flow_control)
954 1114 *flow_control |= OCE_FC_TX;
955 1115
956 1116 if (fwcmd->rx_flow_control)
957 1117 *flow_control |= OCE_FC_RX;
958 1118
959 1119 return (0);
960 1120 } /* oce_get_flow_control */
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
961 1121
962 1122 /*
963 1123 * function to enable/disable device promiscuous mode
964 1124 *
965 1125 * dev - software handle to the device
966 1126 * enable - enable/disable flag
967 1127 *
968 1128 * return 0 on success, EIO on failure
969 1129 */
970 1130 int
971 -oce_set_promiscuous(struct oce_dev *dev, boolean_t enable)
1131 +oce_set_promiscuous(struct oce_dev *dev, boolean_t enable, uint32_t mode)
972 1132 {
973 1133 struct oce_mbx mbx;
974 - struct mbx_config_nic_promiscuous *fwcmd;
975 - int ret;
1134 + struct mbx_set_common_iface_rx_filter *fwcmd;
1135 + int ret = 0;
976 1136
977 1137 bzero(&mbx, sizeof (struct oce_mbx));
978 1138
979 - fwcmd = (struct mbx_config_nic_promiscuous *)&mbx.payload;
1139 + fwcmd = (struct mbx_set_common_iface_rx_filter *)&mbx.payload;
980 1140
981 - if (dev->port_id == 0) {
982 - fwcmd->params.req.port0_promisc = (uint8_t)enable;
983 -
984 - } else {
985 - fwcmd->params.req.port1_promisc = (uint8_t)enable;
986 - }
987 -
988 1141 /* initialize the ioctl header */
989 1142 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
990 - MBX_SUBSYSTEM_NIC,
991 - OPCODE_CONFIG_NIC_PROMISCUOUS,
1143 + MBX_SUBSYSTEM_COMMON,
1144 + OPCODE_COMMON_NTWK_RX_FILTER,
992 1145 MBX_TIMEOUT_SEC,
993 - sizeof (struct mbx_config_nic_promiscuous));
1146 + sizeof (struct mbx_set_common_iface_rx_filter), 0);
994 1147 /* fill rest of mbx */
995 1148 mbx.u0.s.embedded = 1;
996 - mbx.payload_length = sizeof (struct mbx_config_nic_promiscuous);
1149 + mbx.payload_length = sizeof (struct mbx_set_common_iface_rx_filter);
1150 +
1151 + fwcmd->params.req.if_id = dev->if_id;
1152 + /*
1153 + * Not setting VLAN promiscuous as the
1154 + * interface is always in VLAN VLAN prmoiscuous
1155 + */
1156 + fwcmd->params.req.if_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
1157 + if (enable)
1158 + fwcmd->params.req.if_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
1159 +
997 1160 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
998 1161
999 1162 /* post the command */
1000 - ret = oce_mbox_post(dev, &mbx, NULL);
1163 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1001 1164
1002 1165 return (ret);
1003 1166 }
1004 1167
1005 1168 /*
1006 1169 * function to add a unicast address to an interface
1007 1170 *
1008 1171 * dev - software handle to the device
1009 1172 * mac - unicast address
1010 1173 *
1011 1174 * return 0 on success, EIO on failure
1012 1175 */
1013 1176 int
1014 1177 oce_add_mac(struct oce_dev *dev, uint32_t if_id,
1015 - const uint8_t *mac, uint32_t *pmac_id)
1178 + const uint8_t *mac, uint32_t *pmac_id, uint32_t mode)
1016 1179 {
1017 1180 struct oce_mbx mbx;
1018 1181 struct mbx_add_common_iface_mac *fwcmd;
1019 1182 int ret;
1020 1183
1021 1184 bzero(&mbx, sizeof (struct oce_mbx));
1022 1185 fwcmd = (struct mbx_add_common_iface_mac *)&mbx.payload;
1023 1186 fwcmd->params.req.if_id = LE_32(if_id);
1024 1187 bcopy(mac, &fwcmd->params.req.mac_address[0], ETHERADDRL);
1025 1188
1026 1189 /* initialize the ioctl header */
1027 1190 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1028 1191 MBX_SUBSYSTEM_COMMON,
1029 1192 OPCODE_ADD_COMMON_IFACE_MAC,
1030 1193 MBX_TIMEOUT_SEC,
1031 - sizeof (struct mbx_add_common_iface_mac));
1194 + sizeof (struct mbx_add_common_iface_mac), 0);
1032 1195
1033 1196 /* fill rest of mbx */
1034 1197 mbx.u0.s.embedded = 1;
1035 1198 mbx.payload_length = sizeof (struct mbx_add_common_iface_mac);
1036 1199 DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ + OCE_MBX_RRHDR_SZ);
1037 1200
1038 1201 /* post the command */
1039 - ret = oce_mbox_post(dev, &mbx, NULL);
1202 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1040 1203
1041 1204 if (ret != 0) {
1042 1205 return (ret);
1043 1206 }
1044 1207
1045 1208 *pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
1046 1209 return (0);
1047 1210 }
1048 1211
1049 1212 /*
1050 1213 * function to delete an unicast address associated with an interface
1051 1214 *
1052 1215 * dev - software handle to the device
1053 1216 * pmac_id - handle to the address added using ace_add_mac
1054 1217 *
1055 1218 * return 0 on success, EIO on failure
1056 1219 */
1057 1220 int
1058 -oce_del_mac(struct oce_dev *dev, uint32_t if_id, uint32_t *pmac_id)
1221 +oce_del_mac(struct oce_dev *dev, uint32_t if_id, uint32_t *pmac_id,
1222 + uint32_t mode)
1059 1223 {
1060 1224 struct oce_mbx mbx;
1061 1225 struct mbx_del_common_iface_mac *fwcmd;
1062 1226 int ret;
1063 1227
1064 1228 bzero(&mbx, sizeof (struct oce_mbx));
1065 1229 fwcmd = (struct mbx_del_common_iface_mac *)&mbx.payload;
1066 1230 fwcmd->params.req.if_id = if_id;
1067 1231 fwcmd->params.req.pmac_id = *pmac_id;
1068 1232
1069 1233 /* initialize the ioctl header */
1070 1234 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1071 1235 MBX_SUBSYSTEM_COMMON,
1072 1236 OPCODE_DEL_COMMON_IFACE_MAC,
1073 1237 MBX_TIMEOUT_SEC,
1074 - sizeof (struct mbx_add_common_iface_mac));
1238 + sizeof (struct mbx_add_common_iface_mac), 0);
1075 1239
1076 1240 /* fill rest of mbx */
1077 1241 mbx.u0.s.embedded = 1;
1078 1242 mbx.payload_length = sizeof (struct mbx_del_common_iface_mac);
1079 1243 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
1080 1244
1081 1245 /* post the command */
1082 - ret = oce_mbox_post(dev, &mbx, NULL);
1246 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1083 1247
1084 1248 return (ret);
1085 1249 }
1086 1250
1087 1251
1088 1252 /*
1089 1253 * function to send the mbx command to configure vlan
1090 1254 *
1091 1255 * dev - software handle to the device
1092 1256 * vtag_arr - array of vlan tags
1093 1257 * vtag_cnt - number of elements in array
1094 1258 * untagged - boolean TRUE/FLASE
1095 1259 * enable_promisc - flag to enable/disable VLAN promiscuous mode
1096 1260 *
1097 1261 * return 0 on success, EIO on failure
1098 1262 */
1099 1263 int
1100 1264 oce_config_vlan(struct oce_dev *dev, uint32_t if_id,
1101 1265 struct normal_vlan *vtag_arr, uint8_t vtag_cnt,
1102 - boolean_t untagged, boolean_t enable_promisc)
1266 + boolean_t untagged, boolean_t enable_promisc, uint32_t mode)
1103 1267 {
1104 1268 struct oce_mbx mbx;
1105 1269 struct mbx_common_config_vlan *fwcmd;
1106 1270 int ret;
1107 1271
1108 1272 bzero(&mbx, sizeof (struct oce_mbx));
1109 1273 fwcmd = (struct mbx_common_config_vlan *)&mbx.payload;
1110 1274
1111 1275 /* initialize the ioctl header */
1112 1276 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1113 1277 MBX_SUBSYSTEM_COMMON,
1114 - OPCODE_CONFIG_COMMON_IFACE_VLAN,
1278 + OPCODE_COMMON_NTWK_VLAN_CONFIG,
1115 1279 MBX_TIMEOUT_SEC,
1116 - sizeof (struct mbx_common_config_vlan));
1280 + sizeof (struct mbx_common_config_vlan), 0);
1117 1281
1118 1282 fwcmd->params.req.if_id = (uint8_t)if_id;
1119 1283 fwcmd->params.req.promisc = (uint8_t)enable_promisc;
1120 1284 fwcmd->params.req.untagged = (uint8_t)untagged;
1121 1285 fwcmd->params.req.num_vlans = vtag_cnt;
1122 1286
1123 1287 /* Set the vlan tag filter on hw */
1124 1288 if (!enable_promisc) {
1125 1289 bcopy(fwcmd->params.req.tags.normal_vlans, vtag_arr,
1126 1290 vtag_cnt * sizeof (struct normal_vlan));
1127 1291 }
1128 1292
1129 1293 /* fill rest of mbx */
1130 1294 mbx.u0.s.embedded = B_TRUE;
1131 1295 mbx.payload_length = sizeof (struct mbx_common_config_vlan);
1132 1296 DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
1133 1297
1134 1298 /* post the command */
1135 - ret = oce_mbox_post(dev, &mbx, NULL);
1299 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1136 1300
1137 1301 return (ret);
1138 1302 } /* oce_config_vlan */
1139 1303
1140 1304
1141 1305 /*
1142 1306 * function to enable or disable the link
1143 1307 *
1144 1308 * dev - software handle to the device
1145 1309 * mca_table - array of mcast address to update
1146 1310 * mca_cnt - number of elements in mca_table
1147 1311 * enable_promisc - flag to enable/disable mcast-promiscuous mode
1148 1312 *
1149 1313 * return 0 on success, EIO on failure
1150 1314 */
1151 1315 int
1152 -oce_config_link(struct oce_dev *dev, boolean_t enable)
1316 +oce_config_link(struct oce_dev *dev, boolean_t enable, uint32_t mode)
1153 1317 {
1154 1318 struct oce_mbx mbx;
1155 1319 struct mbx_common_func_link_cfg *fwcmd;
1156 1320 int ret;
1157 1321
1158 1322 bzero(&mbx, sizeof (struct oce_mbx));
1159 1323 fwcmd = (struct mbx_common_func_link_cfg *)&mbx.payload;
1160 1324
1161 1325 /* initialize the ioctl header */
1162 1326 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1163 1327 MBX_SUBSYSTEM_COMMON,
1164 1328 OPCODE_COMMON_FUNCTION_LINK_CONFIG,
1165 1329 MBX_TIMEOUT_SEC,
1166 - sizeof (struct mbx_common_config_vlan));
1330 + sizeof (struct mbx_common_func_link_cfg), 0);
1167 1331
1168 1332 fwcmd->params.req.enable = enable;
1169 1333
1170 1334 /* fill rest of mbx */
1171 1335 mbx.u0.s.embedded = B_TRUE;
1172 1336 mbx.payload_length = sizeof (struct mbx_common_func_link_cfg);
1173 1337 DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
1174 1338
1175 1339 /* post the command */
1176 - ret = oce_mbox_post(dev, &mbx, NULL);
1340 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1177 1341
1178 1342 return (ret);
1179 1343 } /* oce_config_link */
1180 1344
1181 1345 int
1182 1346 oce_config_rss(struct oce_dev *dev, uint16_t if_id, char *hkey, char *itbl,
1183 - int tbl_sz, uint16_t rss_type, uint8_t flush)
1347 + int tbl_sz, uint16_t rss_type, uint8_t flush, uint32_t mode)
1184 1348 {
1185 1349 struct oce_mbx mbx;
1186 1350 struct mbx_config_nic_rss *fwcmd;
1187 1351 int i;
1188 1352 int ret = 0;
1189 1353
1190 1354 bzero(&mbx, sizeof (struct oce_mbx));
1191 1355 fwcmd = (struct mbx_config_nic_rss *)&mbx.payload;
1192 1356
1193 1357 /* initialize the ioctl header */
1194 1358 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1195 1359 MBX_SUBSYSTEM_NIC,
1196 1360 OPCODE_CONFIG_NIC_RSS,
1197 1361 MBX_TIMEOUT_SEC,
1198 - sizeof (struct mbx_config_nic_rss));
1362 + sizeof (struct mbx_config_nic_rss), 0);
1199 1363 fwcmd->params.req.enable_rss = LE_16(rss_type);
1200 1364 fwcmd->params.req.flush = flush;
1201 1365 fwcmd->params.req.if_id = LE_32(if_id);
1202 1366
1203 1367 if (hkey != NULL) {
1204 1368 bcopy(hkey, fwcmd->params.req.hash, OCE_HKEY_SIZE);
1205 1369 }
1206 1370
1207 1371
1208 1372 /* Fill the indirection table */
1209 1373 for (i = 0; i < tbl_sz; i++) {
1210 1374 fwcmd->params.req.cputable[i] = itbl[i];
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
1211 1375 }
1212 1376
1213 1377 fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(tbl_sz));
1214 1378
1215 1379 /* fill rest of mbx */
1216 1380 mbx.u0.s.embedded = B_TRUE;
1217 1381 mbx.payload_length = sizeof (struct mbx_config_nic_rss);
1218 1382 DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + OCE_MBX_RRHDR_SZ));
1219 1383
1220 1384 /* post the command */
1221 - ret = oce_mbox_post(dev, &mbx, NULL);
1385 + ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1222 1386
1223 1387 return (ret);
1224 1388 }
1225 1389
1226 1390 /*
1391 + * function to post a MBX to the mbox
1392 + *
1393 + * dev - software handle to the device
1394 + * mbx - pointer to the MBX to send
1395 + *
1396 + * return 0 on success, error value on failure
1397 + */
1398 +int
1399 +oce_issue_mbox_cmd(struct oce_dev *dev, struct oce_mbx *mbx,
1400 + uint32_t tmo_sec, uint32_t flag)
1401 +{
1402 +
1403 + struct oce_mq *mq;
1404 + if (dev == NULL) {
1405 + oce_log(dev, CE_WARN, MOD_CONFIG,
1406 + "dev is null 0x%p", (void *)dev);
1407 + return (EINVAL);
1408 + }
1409 + mq = dev->mq;
1410 +
1411 + if ((dev->mq == NULL) || (mq->qstate != QCREATED) ||
1412 + !(dev->state & STATE_INTR_ENABLED)) {
1413 + /* Force bootstrap mode if MQ is not created or intr disabled */
1414 + if (flag == MBX_ASYNC_MQ) {
1415 + oce_log(dev, CE_NOTE, MOD_CONFIG,
1416 + "Forcing bootstrap mode DEV STATE %x\n",
1417 + dev->state);
1418 + flag = MBX_BOOTSTRAP;
1419 +
1420 + }
1421 + }
1422 + /* invoke appropriate functions depending on flag */
1423 + switch (flag) {
1424 + case MBX_BOOTSTRAP:
1425 + return (oce_mbox_issue_bootstrap(dev, mbx, tmo_sec));
1426 + case MBX_ASYNC_MQ:
1427 + return (oce_enqueue_mq_mbox(dev, mbx, tmo_sec));
1428 + default:
1429 + return (EINVAL);
1430 + }
1431 +
1432 +}
1433 +
1434 +static struct oce_mbx_ctx *
1435 +oce_init_mq_ctx(struct oce_dev *dev, struct oce_mbx *mbx)
1436 +{
1437 + struct oce_mbx_ctx *mbctx;
1438 + mbctx = kmem_zalloc(sizeof (struct oce_mbx_ctx), KM_SLEEP);
1439 +
1440 + mbctx->mbx = mbx;
1441 + cv_init(&mbctx->cond_var, NULL, CV_DRIVER, NULL);
1442 + mutex_init(&mbctx->cv_lock, NULL, MUTEX_DRIVER,
1443 + DDI_INTR_PRI(dev->intr_pri));
1444 + mbx->tag[0] = ADDR_LO((uintptr_t)mbctx);
1445 + mbx->tag[1] = ADDR_HI((uint64_t)(uintptr_t)mbctx);
1446 + return (mbctx);
1447 +}
1448 +
1449 +static void
1450 +oce_destroy_mq_ctx(struct oce_mbx_ctx *mbctx)
1451 +{
1452 + cv_destroy(&mbctx->cond_var);
1453 + mutex_destroy(&mbctx->cv_lock);
1454 + kmem_free(mbctx, sizeof (struct oce_mbx_ctx));
1455 +}
1456 +
1457 +static uint32_t
1458 +oce_enqueue_mq_mbox(struct oce_dev *dev, struct oce_mbx *mbx, uint32_t tmo_sec)
1459 +{
1460 + struct oce_mbx_ctx *mbctx;
1461 + uint32_t status;
1462 +
1463 + _NOTE(ARGUNUSED(tmo_sec));
1464 +
1465 + mbctx = oce_init_mq_ctx(dev, mbx);
1466 +
1467 + if (mbctx == NULL) {
1468 + return (EIO);
1469 + }
1470 + mutex_enter(&mbctx->cv_lock);
1471 + mbctx->mbx_status = MBX_BUSY;
1472 + if (oce_issue_mq_mbox(dev, mbx) != MBX_SUCCESS) {
1473 + mutex_exit(&mbctx->cv_lock);
1474 + oce_destroy_mq_ctx(mbctx);
1475 + return (EIO);
1476 + }
1477 + while (mbctx->mbx_status & MBX_BUSY) {
1478 + cv_wait(&mbctx->cond_var, &mbctx->cv_lock);
1479 + }
1480 + status = mbctx->compl_status;
1481 + mutex_exit(&mbctx->cv_lock);
1482 + oce_destroy_mq_ctx(mbctx);
1483 + return (status);
1484 +}
1485 +
1486 +/*
1227 1487 * function called from the gld ioctl entry point to send a mbx to fw
1228 1488 *
1229 1489 * dev - software handle to the device
1230 1490 * mp - mblk_t containing the user data
1231 1491 * payload_len = [OUT] pointer to return the length of the payload written
1232 1492 *
1233 1493 * return 0 on Success
1234 1494 */
1235 1495 int
1236 -oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
1237 - uint32_t *payload_len)
1496 +oce_issue_mbox_passthru(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
1497 + uint32_t *rsp_len)
1238 1498 {
1239 - int ret;
1499 + int ret = 0;
1240 1500 struct oce_mbx mbx;
1241 - struct mbx_hdr hdr;
1242 - ddi_dma_handle_t dma_handle;
1501 + struct mbx_hdr hdr = {0};
1502 + struct mbx_hdr *rsp_hdr = NULL;
1243 1503 boolean_t is_embedded = B_FALSE;
1244 - uint32_t payload_length;
1245 - int num_buf = 0;
1246 - int alloc_len;
1247 - caddr_t sg_va;
1248 - ddi_acc_handle_t acc_handle;
1249 - size_t actual_len;
1504 + int32_t payload_length = 0;
1505 + int offset = 0;
1506 + mblk_t *tmp = NULL;
1507 + uint32_t tmo;
1508 + oce_dma_buf_t dbuf = {0};
1250 1509
1251 1510 _NOTE(ARGUNUSED(wq));
1252 1511
1253 1512 bzero(&mbx, sizeof (struct oce_mbx));
1254 1513
1514 + /* initialize the response len */
1515 + *rsp_len = 0;
1516 +
1517 + /* copy and swap the request header */
1255 1518 bcopy(mp->b_cont->b_rptr, &hdr, sizeof (struct mbx_hdr));
1256 1519 DW_SWAP(u32ptr(&hdr), sizeof (struct mbx_hdr));
1257 1520
1258 1521 payload_length = hdr.u0.req.request_length +
1259 1522 sizeof (struct mbx_hdr);
1260 -
1261 1523 is_embedded = (payload_length <= sizeof (struct oce_mbx_payload));
1262 1524
1263 - alloc_len = msgdsize(mp->b_cont);
1264 -
1265 - oce_log(dev, CE_NOTE, MOD_CONFIG, "Mailbox: "
1266 - "DW[0] 0x%x DW[1] 0x%x DW[2]0x%x DW[3]0x%x,"
1267 - "MBLKL(%lu) ALLOCLEN(%d)",
1268 - hdr.u0.dw[0], hdr.u0.dw[1],
1269 - hdr.u0.dw[2], hdr.u0.dw[3],
1270 - MBLKL(mp->b_cont), alloc_len);
1271 -
1272 1525 /* get the timeout from the command header */
1273 - mbx.tag[0] = hdr.u0.req.timeout;
1526 + tmo = hdr.u0.req.timeout;
1274 1527
1275 - if (hdr.u0.req.opcode == OPCODE_WRITE_COMMON_FLASHROM) {
1276 - struct mbx_common_read_write_flashrom *fwcmd =
1277 - (struct mbx_common_read_write_flashrom *)
1278 - mp->b_cont->b_rptr;
1528 + oce_log(dev, CE_NOTE, MOD_CONFIG,
1529 + "Mailbox command: opcode=%d, subsystem=%d, timeout=%d",
1530 + hdr.u0.req.opcode, hdr.u0.req.subsystem, tmo);
1279 1531
1280 - if (dev->cookie != 0 && dev->cookie != hdr.u0.req.rsvd0)
1281 - return (EINVAL);
1282 -
1283 - if (dev->cookie == 0)
1284 - dev->cookie = hdr.u0.req.rsvd0;
1285 - hdr.u0.req.rsvd0 = 0;
1286 -
1287 - oce_log(dev, CE_NOTE, MOD_CONFIG, "Mailbox params:"
1288 - "OPCODE(%d) OPTYPE = %d SIZE = %d OFFSET = %d",
1289 - fwcmd->flash_op_code, fwcmd->flash_op_type,
1290 - fwcmd->data_buffer_size, fwcmd->data_offset);
1291 - }
1292 -
1293 1532 if (!is_embedded) {
1294 - mblk_t *tmp = NULL;
1295 1533 ddi_dma_cookie_t cookie;
1296 - uint32_t count = 0;
1297 - int offset = 0;
1534 + int alloc_len = 0;
1535 + int num_buf = 0;
1298 1536
1299 - /* allocate dma handle */
1300 - ret = ddi_dma_alloc_handle(dev->dip,
1301 - &oce_sgl_dma_attr, DDI_DMA_DONTWAIT, NULL,
1302 - &dma_handle);
1303 - if (ret != DDI_SUCCESS) {
1304 - oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
1305 - "Failed to alloc DMA handle");
1306 - ret = ENOMEM;
1307 - goto fail;
1308 - }
1537 + /* Calculate memory size to alloc */
1538 + alloc_len = msgdsize(mp->b_cont);
1309 1539
1310 - /* allocate the DMA-able memory */
1311 - ret = ddi_dma_mem_alloc(dma_handle, alloc_len,
1312 - &oce_sgl_buf_accattr,
1313 - DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1314 - DDI_DMA_DONTWAIT,
1315 - NULL, &sg_va, &actual_len, &acc_handle);
1540 + /* allocate the DMA memory */
1541 + ret = oce_alloc_dma_buffer(dev, &dbuf, alloc_len,
1542 + &oce_sgl_dma_attr, DDI_DMA_CONSISTENT|DDI_DMA_RDWR);
1316 1543 if (ret != DDI_SUCCESS) {
1317 - oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
1318 - "Failed to alloc DMA memory");
1319 - ret = ENOMEM;
1320 - goto dma_alloc_fail;
1544 + return (ENOMEM);
1321 1545 }
1322 1546
1323 1547 for (tmp = mp->b_cont; tmp != NULL; tmp = tmp->b_cont) {
1324 - bcopy((caddr_t)tmp->b_rptr, sg_va + offset, MBLKL(tmp));
1548 + bcopy((caddr_t)tmp->b_rptr, DBUF_VA(dbuf) + offset,
1549 + MBLKL(tmp));
1325 1550 offset += MBLKL(tmp);
1326 1551 }
1327 1552
1328 - /* bind mblk mem to handle */
1329 - ret = ddi_dma_addr_bind_handle(
1330 - dma_handle,
1331 - (struct as *)0, sg_va,
1332 - alloc_len,
1333 - DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1334 - DDI_DMA_DONTWAIT, NULL, &cookie, &count);
1335 - if (ret != DDI_DMA_MAPPED) {
1336 - ret = ENOMEM;
1337 - oce_log(dev, CE_NOTE, MOD_CONFIG,
1338 - "Failed to bind DMA handle ret code: %d",
1339 - ret);
1340 - goto dma_bind_fail;
1341 - }
1342 -
1343 - for (num_buf = 0; num_buf < count; num_buf++) {
1553 + cookie = dbuf.cookie;
1554 + for (num_buf = 0; num_buf < dbuf.ncookies; num_buf++) {
1344 1555 /* fill the mbx sglist */
1345 1556 mbx.payload.u0.u1.sgl[num_buf].pa_lo =
1346 - ADDR_LO(cookie.dmac_laddress);
1557 + LE_32(ADDR_LO(cookie.dmac_laddress));
1347 1558 mbx.payload.u0.u1.sgl[num_buf].pa_hi =
1348 - ADDR_HI(cookie.dmac_laddress);
1559 + LE_32(ADDR_HI(cookie.dmac_laddress));
1349 1560 mbx.payload.u0.u1.sgl[num_buf].length =
1350 - (uint32_t)cookie.dmac_size;
1351 - mbx.payload_length +=
1352 - mbx.payload.u0.u1.sgl[num_buf].length;
1353 - mbx.u0.s.sge_count++;
1561 + LE_32((uint32_t)cookie.dmac_size);
1354 1562
1355 - if (count > 1)
1356 - (void) ddi_dma_nextcookie(dma_handle, &cookie);
1563 + if (dbuf.ncookies > 1) {
1564 + (void) ddi_dma_nextcookie(DBUF_DHDL(dbuf),
1565 + &cookie);
1566 + }
1357 1567 }
1358 1568 mbx.u0.s.embedded = 0;
1569 + mbx.payload_length = alloc_len;
1570 + mbx.u0.s.sge_count = dbuf.ncookies;
1571 + oce_log(dev, CE_NOTE, MOD_CONFIG,
1572 + "sg count %d, payload_length = %d",
1573 + dbuf.ncookies, alloc_len);
1359 1574
1360 - DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ +
1361 - (sizeof (struct oce_mq_sge) * count));
1362 1575 } else {
1363 1576 /* fill rest of mbx */
1364 1577 mbx.u0.s.embedded = 1;
1365 1578 mbx.payload_length = payload_length;
1366 1579 bcopy(mp->b_cont->b_rptr, &mbx.payload, payload_length);
1367 -
1368 - DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
1369 1580 }
1370 1581
1582 + /* swap the bootstrap header only */
1583 + OCE_DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
1584 +
1371 1585 /* now post the command */
1372 - ret = oce_mbox_post(dev, &mbx, NULL);
1586 + ret = oce_issue_mbox_cmd(dev, &mbx, tmo, MBX_ASYNC_MQ);
1373 1587
1374 - bcopy(mp->b_cont->b_rptr, &hdr, sizeof (struct mbx_hdr));
1375 - DW_SWAP(u32ptr(&hdr), sizeof (struct mbx_hdr));
1376 -
1377 1588 if (ret != DDI_SUCCESS) {
1378 - oce_log(dev, CE_WARN, MOD_CONFIG,
1379 - "Failed to post the mailbox: %d", ret);
1380 -
1381 - *payload_len = hdr.u0.rsp.rsp_length +
1382 - sizeof (struct mbx_hdr);
1383 - if (is_embedded) {
1384 - bcopy(&mbx.payload, mp->b_cont->b_rptr,
1385 - MBLKL(mp->b_cont));
1386 - goto fail;
1387 - } else {
1388 - (void) ddi_dma_sync(dma_handle, 0, 0,
1389 - DDI_DMA_SYNC_FORKERNEL);
1390 -
1391 - if (oce_fm_check_dma_handle(dev, dma_handle) !=
1392 - DDI_FM_OK) {
1393 - ddi_fm_service_impact(dev->dip,
1394 - DDI_SERVICE_DEGRADED);
1395 - }
1396 - bcopy(sg_va, mp->b_cont->b_rptr,
1397 - sizeof (struct mbx_hdr));
1398 - goto post_fail;
1399 - }
1589 + goto fail;
1400 1590 }
1401 1591
1402 - if (hdr.u0.req.opcode == OPCODE_WRITE_COMMON_FLASHROM) {
1403 - struct mbx_common_read_write_flashrom *fwcmd =
1404 - (struct mbx_common_read_write_flashrom *)
1405 - mp->b_cont->b_rptr;
1406 -
1407 - if (LE_32(fwcmd->flash_op_code) == MGMT_FLASHROM_OPCODE_FLASH)
1408 - dev->cookie = 0;
1409 - }
1410 -
1411 - payload_length = hdr.u0.rsp.rsp_length + sizeof (struct mbx_hdr);
1412 -
1413 1592 /* Copy the response back only if this is an embedded mbx cmd */
1414 1593 if (is_embedded) {
1415 - bcopy(&mbx.payload, mp->b_cont->b_rptr,
1416 - min(payload_length, MBLKL(mp->b_cont)));
1594 + rsp_hdr = (struct mbx_hdr *)&mbx.payload;
1417 1595 } else {
1418 - mblk_t *tmp = NULL;
1419 - int offset = 0;
1420 1596 /* sync */
1421 - (void) ddi_dma_sync(dma_handle, 0, 0,
1597 + (void) ddi_dma_sync(DBUF_DHDL(dbuf), 0, 0,
1422 1598 DDI_DMA_SYNC_FORKERNEL);
1423 - if (oce_fm_check_dma_handle(dev, dma_handle) != DDI_FM_OK) {
1599 + if (oce_fm_check_dma_handle(dev, DBUF_DHDL(dbuf)) !=
1600 + DDI_FM_OK) {
1424 1601 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
1602 + ret = EIO;
1603 + goto fail;
1425 1604 }
1426 1605
1427 - /* copy back from kernel allocated buffer to user buffer */
1428 - for (tmp = mp->b_cont; tmp != NULL; tmp = tmp->b_cont) {
1429 - bcopy(sg_va + offset, tmp->b_rptr, MBLKL(tmp));
1430 - offset += MBLKL(tmp);
1431 - }
1432 -
1433 - /* unbind and free dma handles */
1434 - (void) ddi_dma_unbind_handle(dma_handle);
1435 - ddi_dma_mem_free(&acc_handle);
1436 - ddi_dma_free_handle(&dma_handle);
1606 + /* Get the mailbox header from SG list */
1607 + rsp_hdr = (struct mbx_hdr *)DBUF_VA(dbuf);
1437 1608 }
1609 + payload_length = LE_32(rsp_hdr->u0.rsp.actual_rsp_length)
1610 + + sizeof (struct mbx_hdr);
1611 + *rsp_len = payload_length;
1438 1612
1439 - *payload_len = payload_length;
1613 + oce_log(dev, CE_NOTE, MOD_CONFIG,
1614 + "Response Len %d status=0x%x, addnl_status=0x%x", payload_length,
1615 + rsp_hdr->u0.rsp.status, rsp_hdr->u0.rsp.additional_status);
1440 1616
1441 - return (0);
1442 -
1443 -post_fail:
1444 - (void) ddi_dma_unbind_handle(dma_handle);
1445 -
1446 -dma_bind_fail:
1447 - ddi_dma_mem_free(&acc_handle);
1448 -
1449 -dma_alloc_fail:
1450 - ddi_dma_free_handle(&dma_handle);
1451 -
1452 -fail:
1453 -alloc_err:
1454 - if (hdr.u0.req.opcode == OPCODE_WRITE_COMMON_FLASHROM) {
1455 - dev->cookie = 0;
1617 + for (tmp = mp->b_cont, offset = 0; tmp != NULL && payload_length > 0;
1618 + tmp = tmp->b_cont) {
1619 + bcopy((caddr_t)rsp_hdr + offset, tmp->b_rptr, MBLKL(tmp));
1620 + offset += MBLKL(tmp);
1621 + payload_length -= MBLKL(tmp);
1456 1622 }
1623 +fail:
1624 + oce_free_dma_buffer(dev, &dbuf);
1457 1625 return (ret);
1458 1626 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX