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_hw.c
+++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.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
27 +
28 +
24 29 /*
25 30 * Source file containing the implementation of the Hardware specific
26 31 * functions
27 32 */
28 33
29 34 #include <oce_impl.h>
30 35 #include <oce_stat.h>
31 36 #include <oce_ioctl.h>
32 37
33 38 static ddi_device_acc_attr_t reg_accattr = {
34 39 DDI_DEVICE_ATTR_V1,
35 40 DDI_STRUCTURE_LE_ACC,
36 41 DDI_STRICTORDER_ACC,
37 42 DDI_FLAGERR_ACC
38 43 };
39 44
40 45 extern int oce_destroy_q(struct oce_dev *dev, struct oce_mbx *mbx,
41 - size_t req_size, enum qtype qtype);
46 + size_t req_size, enum qtype qtype, uint32_t mode);
42 47
43 48 static int
44 49 oce_map_regs(struct oce_dev *dev)
45 50 {
46 51 int ret = 0;
47 52 off_t bar_size = 0;
48 53
49 54 ASSERT(NULL != dev);
50 55 ASSERT(NULL != dev->dip);
51 56
52 57 /* get number of supported bars */
53 58 ret = ddi_dev_nregs(dev->dip, &dev->num_bars);
54 59 if (ret != DDI_SUCCESS) {
55 60 oce_log(dev, CE_WARN, MOD_CONFIG,
56 - "%d: could not retrieve num_bars", MOD_CONFIG);
61 + "Could not retrieve num_bars, ret =0x%x", ret);
57 62 return (DDI_FAILURE);
58 63 }
59 64
65 + if (LANCER_CHIP(dev)) {
66 + /* Doorbells */
67 + ret = ddi_dev_regsize(dev->dip, OCE_PCI_LANCER_DB_BAR,
68 + &bar_size);
69 + if (ret != DDI_SUCCESS) {
70 + oce_log(dev, CE_WARN, MOD_CONFIG,
71 + "%d Could not get sizeof BAR %d",
72 + ret, OCE_PCI_LANCER_DB_BAR);
73 + return (DDI_FAILURE);
74 + }
75 +
76 + ret = ddi_regs_map_setup(dev->dip, OCE_PCI_LANCER_DB_BAR,
77 + &dev->db_addr, 0, 0, ®_accattr, &dev->db_handle);
78 + if (ret != DDI_SUCCESS) {
79 + oce_log(dev, CE_WARN, MOD_CONFIG,
80 + "Could not map bar %d", OCE_PCI_LANCER_DB_BAR);
81 + return (DDI_FAILURE);
82 + }
83 + return (DDI_SUCCESS);
84 + }
85 +
60 86 /* verify each bar and map it accordingly */
61 87 /* PCI CFG */
62 88 ret = ddi_dev_regsize(dev->dip, OCE_DEV_CFG_BAR, &bar_size);
63 89 if (ret != DDI_SUCCESS) {
64 90 oce_log(dev, CE_WARN, MOD_CONFIG,
65 91 "Could not get sizeof BAR %d",
66 92 OCE_DEV_CFG_BAR);
67 93 return (DDI_FAILURE);
68 94 }
69 95
70 96 ret = ddi_regs_map_setup(dev->dip, OCE_DEV_CFG_BAR, &dev->dev_cfg_addr,
71 97 0, bar_size, ®_accattr, &dev->dev_cfg_handle);
72 98
73 99 if (ret != DDI_SUCCESS) {
74 100 oce_log(dev, CE_WARN, MOD_CONFIG,
75 101 "Could not map bar %d",
76 102 OCE_DEV_CFG_BAR);
77 103 return (DDI_FAILURE);
78 104 }
79 105
80 106 /* CSR */
81 107 ret = ddi_dev_regsize(dev->dip, OCE_PCI_CSR_BAR, &bar_size);
82 108
83 109 if (ret != DDI_SUCCESS) {
84 110 oce_log(dev, CE_WARN, MOD_CONFIG,
85 111 "Could not get sizeof BAR %d",
86 112 OCE_PCI_CSR_BAR);
87 113 return (DDI_FAILURE);
88 114 }
89 115
90 116 ret = ddi_regs_map_setup(dev->dip, OCE_PCI_CSR_BAR, &dev->csr_addr,
91 117 0, bar_size, ®_accattr, &dev->csr_handle);
92 118 if (ret != DDI_SUCCESS) {
93 119 oce_log(dev, CE_WARN, MOD_CONFIG,
94 120 "Could not map bar %d",
95 121 OCE_PCI_CSR_BAR);
96 122 ddi_regs_map_free(&dev->dev_cfg_handle);
97 123 return (DDI_FAILURE);
98 124 }
99 125
100 126 /* Doorbells */
101 127 ret = ddi_dev_regsize(dev->dip, OCE_PCI_DB_BAR, &bar_size);
102 128 if (ret != DDI_SUCCESS) {
103 129 oce_log(dev, CE_WARN, MOD_CONFIG,
104 130 "%d Could not get sizeof BAR %d",
105 131 ret, OCE_PCI_DB_BAR);
106 132 ddi_regs_map_free(&dev->csr_handle);
107 133 ddi_regs_map_free(&dev->dev_cfg_handle);
108 134 return (DDI_FAILURE);
109 135 }
110 136
111 137 ret = ddi_regs_map_setup(dev->dip, OCE_PCI_DB_BAR, &dev->db_addr,
112 138 0, 0, ®_accattr, &dev->db_handle);
113 139 if (ret != DDI_SUCCESS) {
114 140 oce_log(dev, CE_WARN, MOD_CONFIG,
115 141 "Could not map bar %d", OCE_PCI_DB_BAR);
116 142 ddi_regs_map_free(&dev->csr_handle);
117 143 ddi_regs_map_free(&dev->dev_cfg_handle);
118 144 return (DDI_FAILURE);
119 145 }
|
↓ open down ↓ |
50 lines elided |
↑ open up ↑ |
120 146 return (DDI_SUCCESS);
121 147 }
122 148 static void
123 149 oce_unmap_regs(struct oce_dev *dev)
124 150 {
125 151
126 152 ASSERT(NULL != dev);
127 153 ASSERT(NULL != dev->dip);
128 154
129 155 ddi_regs_map_free(&dev->db_handle);
130 - ddi_regs_map_free(&dev->csr_handle);
131 - ddi_regs_map_free(&dev->dev_cfg_handle);
156 + if (!LANCER_CHIP(dev)) {
157 + ddi_regs_map_free(&dev->csr_handle);
158 + ddi_regs_map_free(&dev->dev_cfg_handle);
159 + }
132 160
133 161 }
134 162
135 163
164 +static void
165 +oce_check_slot(struct oce_dev *dev)
166 +{
167 + uint32_t curr = 0;
168 + uint32_t max = 0;
169 + uint32_t width = 0;
170 + uint32_t max_width = 0;
171 + uint32_t speed = 0;
172 + uint32_t max_speed = 0;
136 173
174 + curr = OCE_CFG_READ32(dev, PCICFG_PCIE_LINK_STATUS_OFFSET);
137 175
176 + width = (curr >> PCIE_LINK_STATUS_NEG_WIDTH_SHIFT) &
177 + PCIE_LINK_STATUS_NEG_WIDTH_MASK;
178 + speed = (curr >> PCIE_LINK_STATUS_SPEED_SHIFT) &
179 + PCIE_LINK_STATUS_SPEED_MASK;
138 180
181 + oce_log(dev, CE_NOTE, MOD_CONFIG, "Reg value %x"
182 + " width %d speed %d\n", curr, width, speed);
183 + max = OCE_CFG_READ32(dev, PCICFG_PCIE_LINK_CAP_OFFSET);
184 +
185 + max_width = (max >> PCIE_LINK_CAP_MAX_WIDTH_SHIFT) &
186 + PCIE_LINK_CAP_MAX_WIDTH_MASK;
187 + max_speed = (max >> PCIE_LINK_CAP_MAX_SPEED_SHIFT) &
188 + PCIE_LINK_CAP_MAX_SPEED_MASK;
189 + oce_log(dev, CE_NOTE, MOD_CONFIG, "Reg value %x"
190 + " max_width %d max_speed %d\n",
191 + max, max_width, max_speed);
192 +
193 + if (width < max_width || speed < max_speed) {
194 + oce_log(dev, CE_NOTE, MOD_CONFIG,
195 + "Found CNA device in a Gen%s x%d PCIe Slot."
196 + "It is recommended to be in a Gen2 x%d slot"
197 + "for best performance\n",
198 + speed < max_speed ? "1" : "2",
199 + width, max_width);
200 + }
201 +}
202 +
203 +
139 204 /*
140 205 * function to map the device memory
141 206 *
142 207 * dev - handle to device private data structure
143 208 *
144 209 */
145 210 int
146 211 oce_pci_init(struct oce_dev *dev)
147 212 {
148 213 int ret = 0;
149 214
150 215 ret = oce_map_regs(dev);
151 216
152 217 if (ret != DDI_SUCCESS) {
153 218 return (DDI_FAILURE);
154 219 }
155 - dev->fn = OCE_PCI_FUNC(dev);
156 - if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) != DDI_FM_OK) {
157 - ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
220 +
221 + if (!LANCER_CHIP(dev)) {
222 + dev->fn = OCE_PCI_FUNC(dev);
223 + if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) !=
224 + DDI_FM_OK) {
225 + ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
226 + }
158 227 }
159 228
160 229 if (ret != DDI_FM_OK) {
161 230 oce_pci_fini(dev);
162 231 return (DDI_FAILURE);
163 232 }
164 233
234 + if (!LANCER_CHIP(dev))
235 + oce_check_slot(dev);
236 +
165 237 return (DDI_SUCCESS);
166 238 } /* oce_pci_init */
167 239
168 240 /*
169 241 * function to free device memory mapping mapped using
170 242 * oce_pci_init
171 243 *
172 244 * dev - handle to device private data
173 245 */
174 246 void
175 247 oce_pci_fini(struct oce_dev *dev)
176 248 {
177 249 oce_unmap_regs(dev);
178 250 } /* oce_pci_fini */
179 251
180 -/*
181 - * function to read the PCI Bus, Device, and function numbers for the
182 - * device instance.
183 - *
184 - * dev - handle to device private data
185 - */
186 -int
187 -oce_get_bdf(struct oce_dev *dev)
188 -{
189 - pci_regspec_t *pci_rp;
190 - uint32_t length;
191 - int rc;
192 252
193 - /* Get "reg" property */
194 - rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dev->dip,
195 - 0, "reg", (int **)&pci_rp, (uint_t *)&length);
196 -
197 - if ((rc != DDI_SUCCESS) ||
198 - (length < (sizeof (pci_regspec_t) / sizeof (int)))) {
199 - oce_log(dev, CE_WARN, MOD_CONFIG,
200 - "Failed to read \"reg\" property, Status = 0x%x", rc);
201 - return (rc);
202 - }
203 -
204 - dev->pci_bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
205 - dev->pci_device = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
206 - dev->pci_function = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
207 -
208 - oce_log(dev, CE_NOTE, MOD_CONFIG,
209 - "\"reg\" property num=%d, Bus=%d, Device=%d, Function=%d",
210 - length, dev->pci_bus, dev->pci_device, dev->pci_function);
211 -
212 - /* Free the memory allocated by ddi_prop_lookup_int_array() */
213 - ddi_prop_free(pci_rp);
214 - return (rc);
215 -}
216 -
217 253 int
218 254 oce_identify_hw(struct oce_dev *dev)
219 255 {
220 256 int ret = DDI_SUCCESS;
257 + uint32_t if_type = 0, sli_intf = 0;
221 258
222 259 dev->vendor_id = pci_config_get16(dev->pci_cfg_handle,
223 260 PCI_CONF_VENID);
224 261 dev->device_id = pci_config_get16(dev->pci_cfg_handle,
225 262 PCI_CONF_DEVID);
226 263 dev->subsys_id = pci_config_get16(dev->pci_cfg_handle,
227 264 PCI_CONF_SUBSYSID);
228 265 dev->subvendor_id = pci_config_get16(dev->pci_cfg_handle,
229 266 PCI_CONF_SUBVENID);
230 267
231 268 switch (dev->device_id) {
232 269
233 270 case DEVID_TIGERSHARK:
234 271 dev->chip_rev = OC_CNA_GEN2;
272 + /* BE2 hardware properly supports single tx ring */
273 + dev->tx_rings = 1;
235 274 break;
236 275 case DEVID_TOMCAT:
237 276 dev->chip_rev = OC_CNA_GEN3;
238 277 break;
278 + case DEVID_LANCER:
279 + sli_intf = pci_config_get32(dev->pci_cfg_handle,
280 + SLI_INTF_REG_OFFSET);
281 +
282 + if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
283 + SLI_INTF_IF_TYPE_SHIFT;
284 +
285 + if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) ||
286 + if_type != 0x02) {
287 + oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
288 + "SLI I/F not Valid or different interface type\n");
289 + ret = DDI_FAILURE;
290 + break;
291 + }
292 + dev->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
293 + SLI_INTF_FAMILY_SHIFT);
294 +
295 + dev->chip_rev = 0;
296 + break;
297 +
239 298 default:
240 299 dev->chip_rev = 0;
241 300 ret = DDI_FAILURE;
242 301 break;
243 302 }
244 303 return (ret);
245 304 }
246 305
247 306
248 307 /*
249 308 * function to check if a reset is required
250 309 *
251 310 * dev - software handle to the device
252 311 *
253 312 */
254 313 boolean_t
255 314 oce_is_reset_pci(struct oce_dev *dev)
256 315 {
257 316 mpu_ep_semaphore_t post_status;
258 317
259 318 ASSERT(dev != NULL);
260 319 ASSERT(dev->dip != NULL);
261 320
262 321 post_status.dw0 = 0;
263 322 post_status.dw0 = OCE_CSR_READ32(dev, MPU_EP_SEMAPHORE);
264 323
265 324 if (post_status.bits.stage == POST_STAGE_ARMFW_READY) {
266 325 return (B_FALSE);
267 326 }
268 327 return (B_TRUE);
269 328 } /* oce_is_reset_pci */
270 329
271 330 /*
272 331 * function to do a soft reset on the device
273 332 *
274 333 * dev - software handle to the device
275 334 *
276 335 */
277 336 int
278 337 oce_pci_soft_reset(struct oce_dev *dev)
279 338 {
280 339 pcicfg_soft_reset_t soft_rst;
281 340 /* struct mpu_ep_control ep_control; */
282 341 /* struct pcicfg_online1 online1; */
283 342 clock_t tmo;
284 343 clock_t earlier = ddi_get_lbolt();
285 344
286 345 ASSERT(dev != NULL);
287 346
288 347 /* issue soft reset */
289 348 soft_rst.dw0 = OCE_CFG_READ32(dev, PCICFG_SOFT_RESET);
290 349 soft_rst.bits.soft_reset = 0x01;
291 350 OCE_CFG_WRITE32(dev, PCICFG_SOFT_RESET, soft_rst.dw0);
292 351
293 352 /* wait till soft reset bit deasserts */
294 353 tmo = drv_usectohz(60000000); /* 1.0min */
295 354 do {
296 355 if ((ddi_get_lbolt() - earlier) > tmo) {
297 356 tmo = 0;
298 357 break;
299 358 }
300 359
301 360 soft_rst.dw0 = OCE_CFG_READ32(dev, PCICFG_SOFT_RESET);
302 361 if (soft_rst.bits.soft_reset)
303 362 drv_usecwait(100);
304 363 } while (soft_rst.bits.soft_reset);
305 364
|
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
306 365 if (soft_rst.bits.soft_reset) {
307 366 oce_log(dev, CE_WARN, MOD_CONFIG,
308 367 "0x%x soft_reset"
309 368 "bit asserted[1]. Reset failed",
310 369 soft_rst.dw0);
311 370 return (DDI_FAILURE);
312 371 }
313 372
314 373 return (oce_POST(dev));
315 374 } /* oce_pci_soft_reset */
375 +
376 +
377 +static int lancer_wait_ready(struct oce_dev *dev)
378 +{
379 + uint32_t sliport_status;
380 + int status = 0, i;
381 +
382 + for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
383 + sliport_status = OCE_DB_READ32(dev, SLIPORT_STATUS_OFFSET);
384 + if (oce_fm_check_acc_handle(dev, dev->db_handle) !=
385 + DDI_FM_OK) {
386 + ddi_fm_service_impact(dev->dip,
387 + DDI_SERVICE_DEGRADED);
388 + return (EIO);
389 + }
390 + if (sliport_status & SLIPORT_STATUS_RDY_MASK)
391 + break;
392 + drv_usecwait(20000);
393 + }
394 +
395 + if (i == SLIPORT_READY_TIMEOUT)
396 + status = DDI_FAILURE;
397 +
398 + return (status);
399 +}
400 +
401 +static int lancer_test_and_set_rdy_state(struct oce_dev *dev)
402 +{
403 + int status;
404 + uint32_t sliport_status, err, reset_needed;
405 + status = lancer_wait_ready(dev);
406 + if (!status) {
407 + sliport_status = OCE_DB_READ32(dev, SLIPORT_STATUS_OFFSET);
408 + if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
409 + ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
410 + return (EIO);
411 + }
412 + err = sliport_status & SLIPORT_STATUS_ERR_MASK;
413 + reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK;
414 + if (err && reset_needed) {
415 + OCE_DB_WRITE32(dev, SLIPORT_CONTROL_OFFSET,
416 + SLI_PORT_CONTROL_IP_MASK);
417 + if (oce_fm_check_acc_handle(dev, dev->db_handle) !=
418 + DDI_FM_OK) {
419 + ddi_fm_service_impact(dev->dip,
420 + DDI_SERVICE_DEGRADED);
421 + return (EIO);
422 + }
423 + /* check adapter has corrected the error */
424 + status = lancer_wait_ready(dev);
425 + sliport_status = OCE_DB_READ32(dev,
426 + SLIPORT_STATUS_OFFSET);
427 + if (oce_fm_check_acc_handle(dev, dev->db_handle) !=
428 + DDI_FM_OK) {
429 + ddi_fm_service_impact(dev->dip,
430 + DDI_SERVICE_DEGRADED);
431 + return (EIO);
432 + }
433 + sliport_status &= (SLIPORT_STATUS_ERR_MASK |
434 + SLIPORT_STATUS_RN_MASK);
435 + if (status || sliport_status)
436 + status = -1;
437 + } else if (err || reset_needed) {
438 + status = DDI_FAILURE;
439 + }
440 + }
441 + return (status);
442 +}
443 +
316 444 /*
317 - * function to trigger a POST on the device
445 + * function to trigger a POST on the Lancer device
318 446 *
319 447 * dev - software handle to the device
320 448 *
321 449 */
322 450 int
323 -oce_POST(struct oce_dev *dev)
451 +oce_lancer_POST(struct oce_dev *dev)
324 452 {
453 + int status = 0;
454 + int sem = 0;
455 + int stage = 0;
456 + int timeout = 0;
457 +
458 + status = lancer_test_and_set_rdy_state(dev);
459 + if (status != 0)
460 + return (DDI_FAILURE);
461 +
462 + do {
463 + sem = OCE_DB_READ32(dev, MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET);
464 + if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
465 + ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
466 + return (EIO);
467 + }
468 + stage = sem & EP_SEMAPHORE_POST_STAGE_MASK;
469 +
470 + if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) &
471 + EP_SEMAPHORE_POST_ERR_MASK) {
472 + oce_log(dev, CE_WARN, MOD_CONFIG,
473 + "POST error; stage=0x%x\n", stage);
474 + return (DDI_FAILURE);
475 + } else if (stage != POST_STAGE_ARMFW_READY) {
476 + drv_usecwait(1000);
477 + } else {
478 + return (0);
479 + }
480 + } while (timeout++ < 1000);
481 + oce_log(dev, CE_WARN, MOD_CONFIG,
482 + "POST timeout; stage=0x%x\n", stage);
483 + return (DDI_FAILURE);
484 +
485 +} /* oce_lancer_POST */
486 +
487 +/*
488 + * function to trigger a POST on the BE device
489 + *
490 + * dev - software handle to the device
491 + *
492 + */
493 +int
494 +oce_be_POST(struct oce_dev *dev)
495 +{
325 496 mpu_ep_semaphore_t post_status;
326 497 clock_t tmo;
327 498 clock_t earlier = ddi_get_lbolt();
328 499
329 500 /* read semaphore CSR */
330 501 post_status.dw0 = OCE_CSR_READ32(dev, MPU_EP_SEMAPHORE);
331 502 if (oce_fm_check_acc_handle(dev, dev->csr_handle) != DDI_FM_OK) {
332 503 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
333 504 return (DDI_FAILURE);
334 505 }
335 506 /* if host is ready then wait for fw ready else send POST */
336 507 if (post_status.bits.stage <= POST_STAGE_AWAITING_HOST_RDY) {
337 508 post_status.bits.stage = POST_STAGE_CHIP_RESET;
338 509 OCE_CSR_WRITE32(dev, MPU_EP_SEMAPHORE, post_status.dw0);
339 510 if (oce_fm_check_acc_handle(dev, dev->csr_handle) !=
340 511 DDI_FM_OK) {
341 512 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
342 513 return (DDI_FAILURE);
343 514 }
344 515 }
345 516
346 517 /* wait for FW ready */
347 518 tmo = drv_usectohz(60000000); /* 1.0min */
348 519 for (;;) {
349 520 if ((ddi_get_lbolt() - earlier) > tmo) {
350 521 tmo = 0;
351 522 break;
352 523 }
353 524
354 525 post_status.dw0 = OCE_CSR_READ32(dev, MPU_EP_SEMAPHORE);
355 526 if (oce_fm_check_acc_handle(dev, dev->csr_handle) !=
356 527 DDI_FM_OK) {
357 528 ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
358 529 return (DDI_FAILURE);
359 530 }
360 531 if (post_status.bits.error) {
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
361 532 oce_log(dev, CE_WARN, MOD_CONFIG,
362 533 "0x%x POST ERROR!!", post_status.dw0);
363 534 return (DDI_FAILURE);
364 535 }
365 536 if (post_status.bits.stage == POST_STAGE_ARMFW_READY)
366 537 return (DDI_SUCCESS);
367 538
368 539 drv_usecwait(100);
369 540 }
370 541 return (DDI_FAILURE);
371 -} /* oce_POST */
542 +} /* oce_be_POST */
543 +
372 544 /*
545 + * function to trigger a POST on the device
546 + *
547 + * dev - software handle to the device
548 + *
549 + */
550 +int
551 +oce_POST(struct oce_dev *dev)
552 +{
553 + int ret = 0;
554 +
555 + if (LANCER_CHIP(dev)) {
556 + ret = oce_lancer_POST(dev);
557 + } else {
558 + ret = oce_be_POST(dev);
559 + }
560 +
561 + return (ret);
562 +}
563 +
564 +/*
373 565 * function to modify register access attributes corresponding to the
374 566 * FM capabilities configured by the user
375 567 *
376 568 * fm_caps - fm capability configured by the user and accepted by the driver
377 569 */
378 570 void
379 571 oce_set_reg_fma_flags(int fm_caps)
380 572 {
381 573 if (fm_caps == DDI_FM_NOT_CAPABLE) {
382 574 return;
383 575 }
384 576 if (DDI_FM_ACC_ERR_CAP(fm_caps)) {
385 577 reg_accattr.devacc_attr_access = DDI_FLAGERR_ACC;
386 578 } else {
387 579 reg_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
388 580 }
389 581 } /* oce_set_fma_flags */
390 582
391 583
392 584 int
393 -oce_create_nw_interface(struct oce_dev *dev)
585 +oce_create_nw_interface(struct oce_dev *dev, oce_group_t *grp, uint32_t mode)
394 586 {
395 587 int ret;
396 - uint32_t capab_flags = OCE_CAPAB_FLAGS;
397 - uint32_t capab_en_flags = OCE_CAPAB_ENABLE;
588 + uint32_t cap_flags, en_flags;
398 589
399 - if (dev->rss_enable) {
400 - capab_flags |= MBX_RX_IFACE_FLAGS_RSS;
401 - capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;
590 + cap_flags = MBX_RX_IFACE_FLAGS_UNTAGGED;
591 + en_flags = MBX_RX_IFACE_FLAGS_UNTAGGED;
592 +
593 + /* first/default group receives broadcast and mcast pkts */
594 + if (grp->grp_num == 0) {
595 + cap_flags |= MBX_RX_IFACE_FLAGS_BROADCAST |
596 + MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS |
597 + MBX_RX_IFACE_FLAGS_PROMISCUOUS |
598 + MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS |
599 + MBX_RX_IFACE_FLAGS_MCAST;
600 +
601 + en_flags |= MBX_RX_IFACE_FLAGS_BROADCAST |
602 + MBX_RX_IFACE_FLAGS_MCAST;
603 +
604 +
605 + cap_flags |= MBX_RX_IFACE_FLAGS_PASS_L3L4;
606 + en_flags |= MBX_RX_IFACE_FLAGS_PASS_L3L4;
607 + if (grp->rss_enable) {
608 + cap_flags |= MBX_RX_IFACE_FLAGS_RSS;
609 + en_flags |= MBX_RX_IFACE_FLAGS_RSS;
610 + }
402 611 }
403 612
404 - /* create an interface for the device with out mac */
405 - ret = oce_if_create(dev, capab_flags, capab_en_flags,
406 - 0, &dev->mac_addr[0], (uint32_t *)&dev->if_id);
613 + if (grp->grp_num == 0) {
614 + ret = oce_if_create(dev, cap_flags, en_flags,
615 + 0, NULL,
616 + (uint32_t *)&grp->if_id, mode);
617 + /* copy default if_id into dev */
618 + dev->if_id = grp->if_id;
619 +
620 + } else {
621 + ret = oce_if_create(dev, cap_flags, en_flags,
622 + 0, NULL, (uint32_t *)&grp->if_id, mode);
623 + }
407 624 if (ret != 0) {
408 625 oce_log(dev, CE_WARN, MOD_CONFIG,
409 - "Interface creation failed: 0x%x", ret);
626 + "Interface creation failed for group "
627 + "instance %d: 0x%x", grp->grp_num, ret);
410 628 return (ret);
411 629 }
412 - atomic_inc_32(&dev->nifs);
413 630
414 - dev->if_cap_flags = capab_en_flags;
415 -
416 631 /* Enable VLAN Promisc on HW */
417 - ret = oce_config_vlan(dev, (uint8_t)dev->if_id, NULL, 0,
418 - B_TRUE, B_TRUE);
632 + ret = oce_config_vlan(dev, (uint8_t)grp->if_id,
633 + NULL, 0, B_TRUE, B_TRUE, mode);
419 634 if (ret != 0) {
420 635 oce_log(dev, CE_WARN, MOD_CONFIG,
421 - "Config vlan failed: %d", ret);
422 - oce_delete_nw_interface(dev);
636 + "Config vlan failed: 0x%x", ret);
637 + oce_delete_nw_interface(dev, grp, mode);
423 638 return (ret);
424 -
425 639 }
426 -
427 - /* set default flow control */
428 - ret = oce_set_flow_control(dev, dev->flow_control);
429 - if (ret != 0) {
430 - oce_log(dev, CE_NOTE, MOD_CONFIG,
431 - "Set flow control failed: %d", ret);
432 - }
433 - ret = oce_set_promiscuous(dev, dev->promisc);
434 -
435 - if (ret != 0) {
436 - oce_log(dev, CE_NOTE, MOD_CONFIG,
437 - "Set Promisc failed: %d", ret);
438 - }
439 -
440 640 return (0);
441 641 }
442 642
443 643 void
444 -oce_delete_nw_interface(struct oce_dev *dev) {
445 -
446 - /* currently only single interface is implmeneted */
447 - if (dev->nifs > 0) {
448 - (void) oce_if_del(dev, dev->if_id);
449 - atomic_dec_32(&dev->nifs);
450 - }
451 -}
452 -
453 -static void
454 -oce_create_itbl(struct oce_dev *dev, char *itbl)
644 +oce_delete_nw_interface(struct oce_dev *dev, oce_group_t *grp, uint32_t mode)
455 645 {
456 - int i;
457 - struct oce_rq **rss_queuep = &dev->rq[1];
458 - int nrss = dev->nrqs - 1;
459 - /* fill the indirection table rq 0 is default queue */
460 - for (i = 0; i < OCE_ITBL_SIZE; i++) {
461 - itbl[i] = rss_queuep[i % nrss]->rss_cpuid;
462 - }
463 -}
646 + char itbl[OCE_ITBL_SIZE] = {0};
647 + char hkey[OCE_HKEY_SIZE] = {0};
648 + int ret = 0;
464 649
465 -int
466 -oce_setup_adapter(struct oce_dev *dev)
467 -{
468 - int ret;
469 - char itbl[OCE_ITBL_SIZE];
470 - char hkey[OCE_HKEY_SIZE];
650 + if (grp->rss_enable) {
651 + ret = oce_config_rss(dev, grp->if_id, hkey,
652 + itbl, OCE_ITBL_SIZE, RSS_ENABLE_NONE, B_FALSE, mode);
471 653
472 - /* disable the interrupts here and enable in start */
473 - oce_chip_di(dev);
474 -
475 - ret = oce_create_nw_interface(dev);
476 - if (ret != DDI_SUCCESS) {
477 - return (DDI_FAILURE);
478 - }
479 - ret = oce_create_queues(dev);
480 - if (ret != DDI_SUCCESS) {
481 - oce_delete_nw_interface(dev);
482 - return (DDI_FAILURE);
483 - }
484 - if (dev->rss_enable) {
485 - (void) oce_create_itbl(dev, itbl);
486 - (void) oce_gen_hkey(hkey, OCE_HKEY_SIZE);
487 - ret = oce_config_rss(dev, dev->if_id, hkey, itbl, OCE_ITBL_SIZE,
488 - OCE_DEFAULT_RSS_TYPE, B_TRUE);
489 654 if (ret != DDI_SUCCESS) {
490 - oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
491 - "Failed to Configure RSS");
492 - oce_delete_queues(dev);
493 - oce_delete_nw_interface(dev);
494 - return (ret);
655 + oce_log(dev, CE_NOTE, MOD_CONFIG,
656 + "Failed to Disable RSS if_id=%d, ret=0x%x",
657 + grp->if_id, ret);
495 658 }
496 659 }
497 - ret = oce_setup_handlers(dev);
498 - if (ret != DDI_SUCCESS) {
499 - oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
500 - "Failed to Setup handlers");
501 - oce_delete_queues(dev);
502 - oce_delete_nw_interface(dev);
503 - return (ret);
504 - }
505 - return (DDI_SUCCESS);
660 + ret = oce_if_del(dev, (uint8_t)grp->if_id, mode);
661 + if (ret != DDI_SUCCESS)
662 + oce_log(dev, CE_NOTE, MOD_CONFIG,
663 + "Failed to delete nw i/f gidx =%d if_id = 0x%x ret=0x%x",
664 + grp->grp_num, grp->if_id, ret);
506 665 }
507 666
508 667 void
509 -oce_unsetup_adapter(struct oce_dev *dev)
668 +oce_group_create_itbl(oce_group_t *grp, char *itbl)
510 669 {
511 - oce_remove_handler(dev);
512 - if (dev->rss_enable) {
513 - char itbl[OCE_ITBL_SIZE] = {0};
514 - char hkey[OCE_HKEY_SIZE] = {0};
515 - int ret = 0;
516 -
517 - ret = oce_config_rss(dev, dev->if_id, hkey, itbl, OCE_ITBL_SIZE,
518 - RSS_ENABLE_NONE, B_TRUE);
519 -
520 - if (ret != DDI_SUCCESS) {
521 - oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
522 - "Failed to Disable RSS");
523 - }
670 + int i;
671 + oce_ring_t *rss_queuep = &grp->ring[1];
672 + /* fill the indirection table rq 0 is default queue */
673 + for (i = 0; i < OCE_ITBL_SIZE; i++) {
674 + itbl[i] = rss_queuep[i % (grp->num_rings - 1)].rx->rss_cpuid;
524 675 }
525 - oce_delete_queues(dev);
526 - oce_delete_nw_interface(dev);
527 676 }
528 677
678 +
529 679 int
530 680 oce_hw_init(struct oce_dev *dev)
531 681 {
532 682 int ret;
533 683 struct mac_address_format mac_addr;
534 684
535 685 ret = oce_POST(dev);
536 686 if (ret != DDI_SUCCESS) {
537 687 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
538 688 "!!!HW POST1 FAILED");
539 689 /* ADD FM FAULT */
540 690 return (DDI_FAILURE);
541 691 }
542 692 /* create bootstrap mailbox */
543 - dev->bmbx = oce_alloc_dma_buffer(dev,
544 - sizeof (struct oce_bmbx), NULL, DDI_DMA_CONSISTENT);
545 - if (dev->bmbx == NULL) {
693 + ret = oce_alloc_dma_buffer(dev, &dev->bmbx,
694 + sizeof (struct oce_bmbx), NULL, DDI_DMA_CONSISTENT|DDI_DMA_RDWR);
695 + if (ret != DDI_SUCCESS) {
546 696 oce_log(dev, CE_WARN, MOD_CONFIG,
547 - "Failed to allocate bmbx: size = %u",
548 - (uint32_t)sizeof (struct oce_bmbx));
697 + "Failed to allocate bmbx: 0x%x", ret);
549 698 return (DDI_FAILURE);
550 699 }
551 700
552 701 ret = oce_reset_fun(dev);
553 702 if (ret != 0) {
554 703 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
555 704 "!!!FUNCTION RESET FAILED");
556 705 goto init_fail;
557 706 }
558 707
559 708 /* reset the Endianess of BMBX */
560 709 ret = oce_mbox_init(dev);
561 710 if (ret != 0) {
562 711 oce_log(dev, CE_WARN, MOD_CONFIG,
563 - "Mailbox initialization2 Failed with %d", ret);
712 + "Mailbox initialization failed with 0x%x", ret);
564 713 goto init_fail;
565 714 }
566 715
567 716 /* read the firmware version */
568 - ret = oce_get_fw_version(dev);
717 + ret = oce_get_fw_version(dev, MBX_BOOTSTRAP);
569 718 if (ret != 0) {
570 719 oce_log(dev, CE_WARN, MOD_CONFIG,
571 - "Firmaware version read failed with %d", ret);
720 + "Firmaware version read failed with 0x%x", ret);
572 721 goto init_fail;
573 722 }
574 723
575 724 /* read the fw config */
576 - ret = oce_get_fw_config(dev);
725 + ret = oce_get_fw_config(dev, MBX_BOOTSTRAP);
577 726 if (ret != 0) {
578 727 oce_log(dev, CE_WARN, MOD_CONFIG,
579 728 "Firmware configuration read failed with %d", ret);
580 729 goto init_fail;
581 730 }
582 731
583 732 /* read the Factory MAC address */
584 733 ret = oce_read_mac_addr(dev, 0, 1,
585 - MAC_ADDRESS_TYPE_NETWORK, &mac_addr);
734 + MAC_ADDRESS_TYPE_NETWORK, &mac_addr, MBX_BOOTSTRAP);
586 735 if (ret != 0) {
587 736 oce_log(dev, CE_WARN, MOD_CONFIG,
588 - "MAC address read failed with %d", ret);
737 + "MAC address read failed with 0x%x", ret);
589 738 goto init_fail;
590 739 }
591 740 bcopy(&mac_addr.mac_addr[0], &dev->mac_addr[0], ETHERADDRL);
741 +
742 + if (!LANCER_CHIP(dev)) {
743 + /* cache the ue mask registers for ue detection */
744 + dev->ue_mask_lo = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_LO_MASK);
745 + dev->ue_mask_hi = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_HI_MASK);
746 + }
747 +
592 748 return (DDI_SUCCESS);
593 749 init_fail:
594 750 oce_hw_fini(dev);
595 751 return (DDI_FAILURE);
596 752 }
597 753 void
598 754 oce_hw_fini(struct oce_dev *dev)
599 755 {
600 - if (dev->bmbx != NULL) {
601 - oce_free_dma_buffer(dev, dev->bmbx);
602 - dev->bmbx = NULL;
756 + (void) oce_mbox_fini(dev);
757 + oce_free_dma_buffer(dev, &dev->bmbx);
758 +}
759 +
760 +boolean_t
761 +oce_check_ue(struct oce_dev *dev)
762 +{
763 + uint32_t ue_lo;
764 + uint32_t ue_hi;
765 +
766 + /* check for the Hardware unexpected error */
767 + ue_lo = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_LO);
768 + ue_hi = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_HI);
769 +
770 + if ((~dev->ue_mask_lo & ue_lo) ||
771 + (~dev->ue_mask_hi & ue_hi)) {
772 + /* Unrecoverable error detected */
773 + oce_log(dev, CE_WARN, MOD_CONFIG,
774 + "Hardware UE Detected: "
775 + "UE_LOW:%08x"
776 + "UE_HI:%08x "
777 + "UE_MASK_LO:%08x "
778 + "UE_MASK_HI:%08x",
779 + ue_lo, ue_hi,
780 + dev->ue_mask_lo,
781 + dev->ue_mask_hi);
782 + return (B_TRUE);
603 783 }
784 + return (B_FALSE);
604 785 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX