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_main.c
+++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_main.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 the driver entry points
27 31 * and related helper functions
28 32 */
29 33
30 34 #include <oce_impl.h>
31 35 #include <oce_stat.h>
32 36 #include <oce_ioctl.h>
33 37
34 -#define ATTACH_DEV_INIT 0x1
35 -#define ATTACH_FM_INIT 0x2
36 -#define ATTACH_PCI_CFG 0x4
37 -#define ATTACH_LOCK_INIT 0x8
38 -#define ATTACH_PCI_INIT 0x10
39 -#define ATTACH_HW_INIT 0x20
40 -#define ATTACH_SETUP_TXRX 0x40
41 -#define ATTACH_SETUP_ADAP 0x80
42 -#define ATTACH_SETUP_INTR 0x100
43 -#define ATTACH_STAT_INIT 0x200
44 -#define ATTACH_MAC_REG 0x400
45 -
46 38 /* ---[ globals and externs ]-------------------------------------------- */
47 39 const char oce_ident_string[] = OCE_IDENT_STRING;
48 40 const char oce_mod_name[] = OCE_MOD_NAME;
49 -struct oce_dev *oce_dev_list[MAX_DEVS + 1]; /* Last entry is invalid */
50 41
51 42 /* driver properties */
43 +static const char tx_reclaim[] = "tx_reclaim";
52 44 static const char flow_control[] = "flow_control";
53 45 static const char mtu_prop_name[] = "oce_default_mtu";
54 46 static const char tx_ring_size_name[] = "tx_ring_size";
55 47 static const char tx_bcopy_limit_name[] = "tx_bcopy_limit";
56 48 static const char rx_bcopy_limit_name[] = "rx_bcopy_limit";
57 49 static const char rx_frag_size_name[] = "rx_frag_size";
58 50 static const char rx_max_bufs_name[] = "rx_max_bufs";
59 51 static const char fm_cap_name[] = "oce_fm_capability";
60 52 static const char log_level_name[] = "oce_log_level";
61 53 static const char lso_capable_name[] = "lso_capable";
62 54 static const char rx_pkt_per_intr_name[] = "rx_pkts_per_intr";
63 55 static const char tx_reclaim_threshold_name[] = "tx_reclaim_threshold";
64 -static const char rx_rings_name[] = "max_rx_rings";
65 -static const char tx_rings_name[] = "max_tx_rings";
56 +static const char rx_rings_name[] = "max_rx_rings";
57 +static const char rx_group_name[] = "max_rx_rings_per_group";
58 +static const char tx_rings_name[] = "max_tx_rings";
66 59
67 60 /* --[ static function prototypes here ]------------------------------- */
68 61 static int oce_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd);
69 62 static int oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
70 63 static int oce_quiesce(dev_info_t *dip);
71 64 static int oce_suspend(dev_info_t *dip);
72 65 static int oce_resume(dev_info_t *dip);
73 66 static void oce_unconfigure(struct oce_dev *dev);
74 67 static void oce_init_locks(struct oce_dev *dev);
75 68 static void oce_destroy_locks(struct oce_dev *dev);
76 69 static void oce_get_params(struct oce_dev *dev);
77 70 static int oce_get_prop(struct oce_dev *dev, char *propname, int minval,
78 71 int maxval, int defval, uint32_t *values);
72 +static void oce_reset_wd_timer(struct oce_dev *dev);
73 +static void oce_wd_timer(void *arg);
74 +static void oce_set_wd_timer(struct oce_dev *dev);
75 +int oce_alloc_queues(struct oce_dev *dev);
76 +void oce_free_queues(struct oce_dev *dev);
79 77
80 78 static struct cb_ops oce_cb_ops = {
81 79 nulldev, /* cb_open */
82 80 nulldev, /* cb_close */
83 81 nodev, /* cb_strategy */
84 82 nodev, /* cb_print */
85 83 nodev, /* cb_dump */
86 84 nodev, /* cb_read */
87 85 nodev, /* cb_write */
88 86 nodev, /* cb_ioctl */
89 87 nodev, /* cb_devmap */
90 88 nodev, /* cb_mmap */
91 89 nodev, /* cb_segmap */
92 90 nochpoll, /* cb_chpoll */
93 91 ddi_prop_op, /* cb_prop_op */
94 92 NULL, /* cb_stream */
95 93 D_MP, /* cb_flag */
96 94 CB_REV, /* cb_rev */
97 95 nodev, /* cb_aread */
98 96 nodev /* cb_awrite */
99 97 };
100 98
101 99 static struct dev_ops oce_dev_ops = {
102 100 DEVO_REV, /* devo_rev */
103 101 0, /* devo_refcnt */
104 102 NULL, /* devo_getinfo */
105 103 NULL, /* devo_identify */
106 104 nulldev, /* devo_probe */
107 105 oce_attach, /* devo_attach */
108 106 oce_detach, /* devo_detach */
109 107 nodev, /* devo_reset */
110 108 &oce_cb_ops, /* devo_cb_ops */
111 109 NULL, /* devo_bus_ops */
112 110 nodev, /* devo_power */
113 111 oce_quiesce /* devo_quiesce */
114 112 };
115 113
|
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
116 114 static struct modldrv oce_drv = {
117 115 &mod_driverops, /* Type of module. This one is a driver */
118 116 (char *)oce_ident_string, /* Description string */
119 117 &oce_dev_ops, /* driver ops */
120 118 };
121 119
122 120 static struct modlinkage oce_mod_linkage = {
123 121 MODREV_1, &oce_drv, NULL
124 122 };
125 123
126 -#define OCE_M_CB_FLAGS (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | \
127 - MC_PROPINFO)
124 +#define OCE_M_CB_FLAGS (MC_IOCTL | MC_GETCAPAB | MC_PROPERTIES)
128 125 static mac_callbacks_t oce_mac_cb = {
129 126 OCE_M_CB_FLAGS, /* mc_callbacks */
130 127 oce_m_stat, /* mc_getstat */
131 128 oce_m_start, /* mc_start */
132 129 oce_m_stop, /* mc_stop */
133 130 oce_m_promiscuous, /* mc_setpromisc */
134 131 oce_m_multicast, /* mc_multicast */
135 - oce_m_unicast, /* mc_unicast */
136 - oce_m_send, /* mc_tx */
132 + NULL, /* mc_unicast */
133 + NULL, /* mc_tx */
137 134 NULL, /* mc_reserve */
138 135 oce_m_ioctl, /* mc_ioctl */
139 136 oce_m_getcap, /* mc_getcapab */
140 137 NULL, /* open */
141 138 NULL, /* close */
142 139 oce_m_setprop, /* set properties */
143 140 oce_m_getprop, /* get properties */
144 141 oce_m_propinfo /* properties info */
145 142 };
146 143
147 -extern char *oce_priv_props[];
148 144
145 +/* array of properties supported by this driver */
146 +char *oce_priv_props[] = {
147 + "_tx_rings",
148 + "_tx_ring_size",
149 + "_tx_bcopy_limit",
150 + "_tx_reclaim_threshold",
151 + "_rx_rings",
152 + "_rx_rings_per_group",
153 + "_rx_ring_size",
154 + "_rx_bcopy_limit",
155 + "_rx_pkts_per_intr",
156 + "_log_level",
157 + NULL
158 +};
159 +
160 +int oce_irm_enable = -1;
161 +
162 +extern int oce_cbfunc(dev_info_t *dip, ddi_cb_action_t cbaction, void *cbarg,
163 + void *arg1, void *arg2);
164 +
149 165 /* Module Init */
150 166 int
151 167 _info(struct modinfo *modinfop)
152 168 {
153 169 return (mod_info(&oce_mod_linkage, modinfop));
154 170 } /* _info */
155 171
156 172 int
157 173 _init(void)
158 174 {
159 175 int ret = 0;
160 176
161 177 /* install the module */
162 - mac_init_ops(&oce_dev_ops, "oce");
178 + mac_init_ops(&oce_dev_ops, OCE_MOD_NAME);
163 179
164 180 ret = mod_install(&oce_mod_linkage);
165 181 if (ret) {
166 182 cmn_err(CE_WARN, "mod_install failed rval=%x", ret);
167 183 }
168 184
169 185 return (ret);
170 186 } /* _init */
171 187
172 188
173 189 int
174 190 _fini(void)
175 191 {
176 192 int ret = 0;
193 +
177 194 /* remove the module */
178 195 ret = mod_remove(&oce_mod_linkage);
179 196 if (ret != 0) {
180 197 return (ret);
181 198 }
182 199
183 200 mac_fini_ops(&oce_dev_ops);
184 201
185 202 return (ret);
186 203 } /* _fini */
187 204
188 205
189 206 static int
190 207 oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
191 208 {
192 209 int ret = 0;
193 210 struct oce_dev *dev = NULL;
194 211 mac_register_t *mac;
195 - uint8_t dev_index = 0;
196 212
197 213 switch (cmd) {
198 214 case DDI_RESUME:
199 215 return (oce_resume(dip));
200 216 default:
201 217 return (DDI_FAILURE);
202 218
203 219 case DDI_ATTACH:
204 220 break;
205 221 }
206 222
207 223 /* allocate dev */
208 224 dev = kmem_zalloc(sizeof (struct oce_dev), KM_SLEEP);
209 225
210 226 /* populate the dev structure */
211 227 dev->dip = dip;
212 228 dev->dev_id = ddi_get_instance(dip);
213 229 dev->suspended = B_FALSE;
214 230
215 - dev->dev_list_index = MAX_DEVS;
216 - while (dev_index < MAX_DEVS) {
217 - (void) atomic_cas_ptr(&oce_dev_list[dev_index], NULL, dev);
218 - if (oce_dev_list[dev_index] == dev) {
219 - break;
220 - }
221 - dev_index++;
222 - }
223 - if (dev_index == MAX_DEVS) {
224 - oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
225 - "Too many oce devices on the system. Failed to attach.");
226 - goto attach_fail;
227 - }
228 - dev->dev_list_index = dev_index;
229 -
230 231 /* get the parameters */
231 232 oce_get_params(dev);
232 233
233 234 /*
234 235 * set the ddi driver private data pointer. This is
235 236 * sent to all mac callback entry points
236 237 */
237 238 ddi_set_driver_private(dip, dev);
238 239
239 240 dev->attach_state |= ATTACH_DEV_INIT;
240 241
241 242 oce_fm_init(dev);
242 243 dev->attach_state |= ATTACH_FM_INIT;
243 244
244 245 ret = pci_config_setup(dev->dip, &dev->pci_cfg_handle);
245 246 if (ret != DDI_SUCCESS) {
246 247 oce_log(dev, CE_WARN, MOD_CONFIG,
247 248 "Map PCI config failed with %d", ret);
248 249 goto attach_fail;
249 250 }
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
250 251 dev->attach_state |= ATTACH_PCI_CFG;
251 252
252 253 ret = oce_identify_hw(dev);
253 254
254 255 if (ret != DDI_SUCCESS) {
255 256 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
256 257 "Device Unknown");
257 258 goto attach_fail;
258 259 }
259 260
260 - ret = oce_get_bdf(dev);
261 - if (ret != DDI_SUCCESS) {
262 - oce_log(dev, CE_WARN, MOD_CONFIG,
263 - "Failed to read BDF, status = 0x%x", ret);
264 - goto attach_fail;
265 - }
266 - /* Update the dev->rss */
267 - oce_dev_rss_ready(dev);
268 -
269 261 /* setup PCI bars */
270 262 ret = oce_pci_init(dev);
271 263 if (ret != DDI_SUCCESS) {
272 264 oce_log(dev, CE_WARN, MOD_CONFIG,
273 265 "PCI initialization failed with %d", ret);
274 266 goto attach_fail;
275 267 }
276 268 dev->attach_state |= ATTACH_PCI_INIT;
277 269
278 - ret = oce_setup_intr(dev);
279 - if (ret != DDI_SUCCESS) {
280 - oce_log(dev, CE_WARN, MOD_CONFIG,
281 - "Interrupt setup failed with %d", ret);
282 - goto attach_fail;
283 -
284 - }
285 - dev->attach_state |= ATTACH_SETUP_INTR;
286 -
287 270 /* initialize locks */
288 271 oce_init_locks(dev);
289 272 dev->attach_state |= ATTACH_LOCK_INIT;
290 273
291 -
292 274 /* HW init */
293 275 ret = oce_hw_init(dev);
294 276 if (ret != DDI_SUCCESS) {
295 277 oce_log(dev, CE_WARN, MOD_CONFIG,
296 278 "HW initialization failed with %d", ret);
297 279 goto attach_fail;
298 280 }
299 281 dev->attach_state |= ATTACH_HW_INIT;
300 282
301 - ret = oce_init_txrx(dev);
302 - if (ret != DDI_SUCCESS) {
303 - oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
304 - "Failed to init rings");
305 - goto attach_fail;
283 + /* Register IRM callback handler */
284 + if (oce_irm_enable != 0) {
285 + ret = ddi_cb_register(dev->dip, DDI_CB_FLAG_INTR, oce_cbfunc,
286 + dev, NULL, &dev->cb_handle);
287 + if (ret != 0) {
288 + oce_log(dev, CE_NOTE, MOD_CONFIG,
289 + "Unable to register IRM callback: 0x%x", ret);
290 + oce_irm_enable = 0;
291 + } else {
292 + dev->attach_state |= ATTACH_CB_REG;
293 + oce_irm_enable = 1;
294 + }
306 295 }
307 - dev->attach_state |= ATTACH_SETUP_TXRX;
308 296
309 - ret = oce_setup_adapter(dev);
297 + /* Adjusting number of groups and rings */
298 + oce_group_rings(dev);
299 +
300 + ret = oce_setup_intr(dev);
310 301 if (ret != DDI_SUCCESS) {
302 + oce_log(dev, CE_WARN, MOD_CONFIG,
303 + "Interrupt setup failed with %d", ret);
304 + goto attach_fail;
305 + }
306 + dev->attach_state |= ATTACH_SETUP_INTR;
307 +
308 + if (oce_alloc_queues(dev) != DDI_SUCCESS) {
311 309 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
312 - "Failed to setup adapter");
310 + "Failed to allocate rings");
313 311 goto attach_fail;
314 312 }
315 - dev->attach_state |= ATTACH_SETUP_ADAP;
313 + dev->attach_state |= ATTACH_ALLOC_QUEUES;
316 314
317 -
318 315 ret = oce_stat_init(dev);
319 316 if (ret != DDI_SUCCESS) {
320 317 oce_log(dev, CE_WARN, MOD_CONFIG,
321 318 "kstat setup Failed with %d", ret);
322 319 goto attach_fail;
323 320 }
324 321 dev->attach_state |= ATTACH_STAT_INIT;
325 322
323 + if (oce_setup_handlers(dev) != DDI_SUCCESS) {
324 + oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
325 + "Failed to Setup handlers");
326 + goto attach_fail;
327 + }
328 + dev->attach_state |= ATTACH_REG_INTR_HANDLE;
329 +
326 330 /* mac_register_t */
327 331 oce_log(dev, CE_NOTE, MOD_CONFIG,
328 332 "MAC_VERSION = 0x%x", MAC_VERSION);
329 333 mac = mac_alloc(MAC_VERSION);
330 334 if (mac == NULL) {
331 335 oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
332 336 "MAC allocation Failed");
333 337 goto attach_fail;
334 338 }
335 339 /*
336 340 * fill the mac structure before calling mac_register
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
337 341 */
338 342 mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
339 343 mac->m_driver = dev;
340 344 mac->m_dip = dip;
341 345 mac->m_src_addr = dev->mac_addr;
342 346 mac->m_callbacks = &oce_mac_cb;
343 347 mac->m_min_sdu = 0;
344 348 mac->m_max_sdu = dev->mtu;
345 349 mac->m_margin = VTAG_SIZE;
346 350 mac->m_priv_props = oce_priv_props;
351 + mac->m_v12n = MAC_VIRT_LEVEL1;
347 352
348 353 oce_log(dev, CE_NOTE, MOD_CONFIG,
349 354 "Driver Private structure = 0x%p", (void *)dev);
350 355
351 356 /* now register with GLDv3 */
352 357 ret = mac_register(mac, (mac_handle_t *)&dev->mac_handle);
353 358 /* regardless of the status, free mac_register */
354 359 mac_free(mac);
355 360 mac = NULL;
356 361 if (ret != DDI_SUCCESS) {
357 362 oce_log(dev, CE_WARN, MOD_CONFIG,
358 363 "MAC registration failed :0x%x", ret);
359 364 goto attach_fail;
360 -
361 365 }
362 366
363 367 /* correct link status only after start */
364 368 dev->link_status = LINK_STATE_UNKNOWN;
365 369 mac_link_update(dev->mac_handle, dev->link_status);
366 370
367 371 dev->attach_state |= ATTACH_MAC_REG;
368 - dev->state |= STATE_INIT;
369 372
370 373 oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
371 374 "ATTACH SUCCESS");
372 375
373 376 return (DDI_SUCCESS);
374 377
375 378 attach_fail:
376 379 oce_unconfigure(dev);
377 380 return (DDI_FAILURE);
378 381 } /* oce_attach */
379 382
380 383 static int
381 384 oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
382 385 {
383 386 struct oce_dev *dev;
384 - int pcnt = 0;
385 - int qid;
387 + int ret = DDI_SUCCESS;
386 388
387 389 dev = ddi_get_driver_private(dip);
388 390 if (dev == NULL) {
389 391 return (DDI_FAILURE);
390 392 }
391 - oce_log(dev, CE_NOTE, MOD_CONFIG,
392 - "Detaching driver: cmd = 0x%x", cmd);
393 393
394 394 switch (cmd) {
395 395 default:
396 396 return (DDI_FAILURE);
397 397 case DDI_SUSPEND:
398 398 return (oce_suspend(dip));
399 399 case DDI_DETACH:
400 400 break;
401 401 } /* switch cmd */
402 402
403 - /* Fail detach if MAC unregister is unsuccessfule */
404 - if (mac_unregister(dev->mac_handle) != 0) {
405 - oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
406 - "Failed to unregister MAC ");
407 - }
408 - dev->attach_state &= ~ATTACH_MAC_REG;
409 -
410 403 /* check if the detach is called with out stopping */
411 404 DEV_LOCK(dev);
412 405 if (dev->state & STATE_MAC_STARTED) {
413 406 dev->state &= ~STATE_MAC_STARTED;
414 407 oce_stop(dev);
415 408 DEV_UNLOCK(dev);
416 409 } else
417 410 DEV_UNLOCK(dev);
418 411
419 - /*
420 - * Wait for Packets sent up to be freed
421 - */
422 - for (qid = 0; qid < dev->rx_rings; qid++) {
423 - pcnt = oce_rx_pending(dev, dev->rq[qid], DEFAULT_DRAIN_TIME);
424 - if (pcnt != 0) {
425 - oce_log(dev, CE_WARN, MOD_CONFIG,
426 - "%d Pending Buffers Detach failed", pcnt);
427 - return (DDI_FAILURE);
428 - }
429 - }
430 412 oce_unconfigure(dev);
431 -
432 - return (DDI_SUCCESS);
413 + return (ret);
433 414 } /* oce_detach */
434 415
435 416 static int
436 417 oce_quiesce(dev_info_t *dip)
437 418 {
438 419 int ret = DDI_SUCCESS;
439 420 struct oce_dev *dev = ddi_get_driver_private(dip);
440 421
441 422 if (dev == NULL) {
442 423 return (DDI_FAILURE);
443 424 }
444 425 if (dev->suspended) {
445 426 return (DDI_SUCCESS);
446 427 }
447 428
448 - oce_chip_di(dev);
429 + if (!LANCER_CHIP(dev)) {
430 + oce_chip_di(dev);
449 431
450 - ret = oce_reset_fun(dev);
432 + ret = oce_reset_fun(dev);
433 + } else {
434 + LANCER_IP_RESET;
435 + }
451 436
452 437 return (ret);
453 438 }
454 439
455 440 static int
456 441 oce_suspend(dev_info_t *dip)
457 442 {
458 443 struct oce_dev *dev = ddi_get_driver_private(dip);
444 + int i;
459 445
460 446 mutex_enter(&dev->dev_lock);
461 447 /* Suspend the card */
448 + if (dev->suspended || (!(dev->state & STATE_MAC_STARTED))) {
449 + mutex_exit(&dev->dev_lock);
450 + return (DDI_SUCCESS);
451 + }
462 452 dev->suspended = B_TRUE;
463 - /* stop the adapter */
464 - if (dev->state & STATE_MAC_STARTED) {
465 - oce_stop(dev);
466 - oce_unsetup_adapter(dev);
453 +
454 + /* stop the groups */
455 + for (i = 0; i < dev->num_rx_groups; i++) {
456 + mutex_enter(&dev->rx_group[i].grp_lock);
457 + oce_suspend_group_rings(&dev->rx_group[i]);
458 + oce_stop_group(&dev->rx_group[i], B_FALSE);
459 + mutex_exit(&dev->rx_group[i].grp_lock);
467 460 }
468 - dev->state &= ~STATE_MAC_STARTED;
461 +
462 + /* stop the adapter */
463 + oce_stop(dev);
464 +
469 465 mutex_exit(&dev->dev_lock);
466 + oce_disable_wd_timer(dev);
470 467 return (DDI_SUCCESS);
471 468 } /* oce_suspend */
472 469
473 470 static int
474 471 oce_resume(dev_info_t *dip)
475 472 {
476 473 struct oce_dev *dev;
477 - int ret;
474 + int i, ret = DDI_SUCCESS;
478 475
479 476 /* get the dev pointer from dip */
480 477 dev = ddi_get_driver_private(dip);
478 + if (dev == NULL) {
479 + return (DDI_FAILURE);
480 + }
481 481 mutex_enter(&dev->dev_lock);
482 482 if (!dev->suspended) {
483 483 mutex_exit(&dev->dev_lock);
484 484 return (DDI_SUCCESS);
485 485 }
486 - if (!(dev->state & STATE_MAC_STARTED)) {
487 - ret = oce_setup_adapter(dev);
488 - if (ret != DDI_SUCCESS) {
489 - mutex_exit(&dev->dev_lock);
490 - return (DDI_FAILURE);
486 + if (dev->state & STATE_MAC_STARTED) {
487 + if ((ret = oce_start(dev)) != DDI_SUCCESS) {
488 + goto resume_finish;
491 489 }
492 - ret = oce_start(dev);
493 - if (ret != DDI_SUCCESS) {
494 - mutex_exit(&dev->dev_lock);
495 - return (DDI_FAILURE);
490 +
491 + /* re-start the groups */
492 + for (i = 0; i < dev->num_rx_groups; i++) {
493 + mutex_enter(&dev->rx_group[i].grp_lock);
494 + ret = oce_start_group(&dev->rx_group[i], B_FALSE);
495 + if (ret == DDI_SUCCESS) {
496 + ret = oce_resume_group_rings(&dev->rx_group[i]);
497 + }
498 + mutex_exit(&dev->rx_group[i].grp_lock);
499 + if (ret != DDI_SUCCESS)
500 + goto resume_finish;
496 501 }
502 + oce_enable_wd_timer(dev);
497 503 }
498 504 dev->suspended = B_FALSE;
499 - dev->state |= STATE_MAC_STARTED;
505 +
506 +resume_finish:
500 507 mutex_exit(&dev->dev_lock);
501 508 return (ret);
502 509 } /* oce_resume */
503 510
504 511 static void
505 512 oce_init_locks(struct oce_dev *dev)
506 513 {
507 514 /* initialize locks */
508 515 mutex_init(&dev->dev_lock, NULL, MUTEX_DRIVER,
509 516 DDI_INTR_PRI(dev->intr_pri));
510 517 mutex_init(&dev->bmbx_lock, NULL, MUTEX_DRIVER,
511 518 DDI_INTR_PRI(dev->intr_pri));
519 + mutex_init(&dev->wd_lock, NULL, MUTEX_DRIVER,
520 + DDI_INTR_PRI(dev->intr_pri));
521 + mutex_init(&dev->stat_lock, NULL, MUTEX_DRIVER,
522 + DDI_INTR_PRI(dev->intr_pri));
512 523 } /* oce_init_locks */
513 524
514 525 static void
515 526 oce_destroy_locks(struct oce_dev *dev)
516 527 {
517 528 mutex_destroy(&dev->dev_lock);
518 529 mutex_destroy(&dev->bmbx_lock);
530 + mutex_destroy(&dev->wd_lock);
531 + mutex_destroy(&dev->stat_lock);
519 532 } /* oce_destroy_locks */
520 533
521 534 static void
522 535 oce_unconfigure(struct oce_dev *dev)
523 536 {
524 537 uint32_t state = dev->attach_state;
525 538
526 539 if (state & ATTACH_MAC_REG) {
527 540 (void) mac_unregister(dev->mac_handle);
528 541 }
542 + if (state & ATTACH_REG_INTR_HANDLE) {
543 + oce_remove_handler(dev);
544 + }
529 545 if (state & ATTACH_STAT_INIT) {
530 546 oce_stat_fini(dev);
531 547 }
532 - if (state & ATTACH_SETUP_ADAP) {
533 - oce_unsetup_adapter(dev);
548 + if (state & ATTACH_CB_REG) {
549 + (void) ddi_cb_unregister(dev->cb_handle);
534 550 }
535 - if (state & ATTACH_SETUP_TXRX) {
536 - oce_fini_txrx(dev);
551 + if (state & ATTACH_SETUP_INTR) {
552 + (void) oce_teardown_intr(dev);
537 553 }
554 + if (state & ATTACH_ALLOC_QUEUES) {
555 + oce_free_queues(dev);
556 + }
538 557 if (state & ATTACH_HW_INIT) {
539 558 oce_hw_fini(dev);
540 559 }
541 560 if (state & ATTACH_LOCK_INIT) {
542 561 oce_destroy_locks(dev);
543 562 }
544 - if (state & ATTACH_SETUP_INTR) {
545 - (void) oce_teardown_intr(dev);
546 - }
547 563 if (state & ATTACH_PCI_INIT) {
548 564 oce_pci_fini(dev);
549 565 }
550 566 if (state & ATTACH_PCI_CFG) {
551 567 pci_config_teardown(&dev->pci_cfg_handle);
552 568 }
553 569 if (state & ATTACH_FM_INIT) {
554 570 oce_fm_fini(dev);
555 571 }
556 572 if (state & ATTACH_DEV_INIT) {
557 573 ddi_set_driver_private(dev->dip, NULL);
558 - oce_dev_list[dev->dev_list_index] = NULL;
559 574 kmem_free(dev, sizeof (struct oce_dev));
560 575 }
561 576 } /* oce_unconfigure */
562 577
563 578 static void
564 579 oce_get_params(struct oce_dev *dev)
565 580 {
566 581 uint32_t log_level;
567 582 uint16_t mod_mask;
568 583 uint16_t severity;
569 584 /*
570 585 * Allowed values for the driver parameters. If all values in a range
571 586 * is allowed, the the array has only one value.
572 587 */
573 588 uint32_t fc_values[] = {OCE_FC_NONE, OCE_FC_TX, OCE_FC_RX,
574 589 OCE_DEFAULT_FLOW_CONTROL, END};
575 590 uint32_t mtu_values[] = {OCE_MIN_MTU, OCE_MAX_MTU, END};
576 591 uint32_t tx_rs_values[] = {SIZE_256, SIZE_512, SIZE_1K, SIZE_2K, END};
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
577 592 uint32_t tx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K,
578 593 SIZE_2K, END};
579 594 uint32_t rx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K,
580 595 SIZE_2K, END};
581 596 uint32_t rq_fs_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END};
582 597 uint32_t rq_mb_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END};
583 598 uint32_t lso_capable_values[] = {0, 1, END};
584 599 uint32_t fm_caps_values[] = {DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY,
585 600 END};
586 601 uint32_t tx_rt_values[] = {END};
602 + uint32_t tx_reclaim_values[] = {END};
587 603 uint32_t rx_ppi_values[] = {END};
588 604 uint32_t rx_rings_values[] = {END};
605 + uint32_t rx_group_values[] = {END};
589 606 uint32_t tx_rings_values[] = {END};
590 607 uint32_t log_level_values[] = {END};
591 608
592 609 /* non tunables */
593 610 dev->rx_ring_size = OCE_DEFAULT_RX_RING_SIZE;
594 611
595 612 /* configurable parameters */
596 613 dev->flow_control = oce_get_prop(dev, (char *)flow_control, OCE_FC_NONE,
597 614 OCE_DEFAULT_FLOW_CONTROL, OCE_DEFAULT_FLOW_CONTROL, fc_values);
598 615
599 616 dev->mtu = oce_get_prop(dev, (char *)mtu_prop_name, OCE_MIN_MTU,
600 617 OCE_MAX_MTU, OCE_MIN_MTU, mtu_values);
601 618
602 619 dev->tx_ring_size = oce_get_prop(dev, (char *)tx_ring_size_name,
603 620 SIZE_256, SIZE_2K, OCE_DEFAULT_TX_RING_SIZE, tx_rs_values);
604 621
605 622 dev->tx_bcopy_limit = oce_get_prop(dev, (char *)tx_bcopy_limit_name,
606 623 SIZE_128, SIZE_2K, OCE_DEFAULT_TX_BCOPY_LIMIT, tx_bcl_values);
607 624
608 625 dev->rx_bcopy_limit = oce_get_prop(dev, (char *)rx_bcopy_limit_name,
609 626 SIZE_128, SIZE_2K, OCE_DEFAULT_RX_BCOPY_LIMIT, rx_bcl_values);
610 627
611 628 dev->rq_frag_size = oce_get_prop(dev, (char *)rx_frag_size_name,
612 629 SIZE_2K, SIZE_8K, OCE_RQ_BUF_SIZE, rq_fs_values);
613 630
614 631 dev->rq_max_bufs = oce_get_prop(dev, (char *)rx_max_bufs_name, SIZE_2K,
615 632 SIZE_8K, OCE_RQ_NUM_BUFFERS, rq_mb_values);
616 633
617 634 dev->lso_capable = oce_get_prop(dev, (char *)lso_capable_name, 0,
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
618 635 1, 1, lso_capable_values);
619 636
620 637 dev->fm_caps = oce_get_prop(dev, (char *)fm_cap_name,
621 638 DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY, OCE_FM_CAPABILITY,
622 639 fm_caps_values);
623 640
624 641 dev->tx_reclaim_threshold = oce_get_prop(dev,
625 642 (char *)tx_reclaim_threshold_name, 0, dev->tx_ring_size/2,
626 643 OCE_DEFAULT_TX_RECLAIM_THRESHOLD, tx_rt_values);
627 644
645 + dev->tx_reclaim = oce_get_prop(dev, (char *)tx_reclaim, 1,
646 + dev->tx_reclaim_threshold, dev->tx_reclaim_threshold,
647 + tx_reclaim_values);
648 +
628 649 dev->rx_pkt_per_intr = oce_get_prop(dev, (char *)rx_pkt_per_intr_name,
629 - 0, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKT_PER_INTR, rx_ppi_values);
650 + 1, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKTS_PER_INTR,
651 + rx_ppi_values);
630 652
631 653 dev->rx_rings = oce_get_prop(dev, (char *)rx_rings_name,
632 654 OCE_MIN_RQ, OCE_MAX_RQ, OCE_DEFAULT_RQS, rx_rings_values);
633 655
656 + dev->rx_rings_per_group = oce_get_prop(dev, (char *)rx_group_name,
657 + OCE_MIN_RING_PER_GROUP, OCE_MAX_RING_PER_GROUP,
658 + OCE_DEF_RING_PER_GROUP, rx_group_values);
659 +
634 660 dev->tx_rings = oce_get_prop(dev, (char *)tx_rings_name,
635 - OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, tx_rings_values);
661 + OCE_MIN_WQ, OCE_MAX_WQ, OCE_DEFAULT_WQS, tx_rings_values);
636 662
637 663 log_level = oce_get_prop(dev, (char *)log_level_name, 0,
638 664 OCE_MAX_LOG_SETTINGS, OCE_DEFAULT_LOG_SETTINGS, log_level_values);
639 665
640 666 severity = (uint16_t)(log_level & 0xffff);
641 667 mod_mask = (uint16_t)(log_level >> 16);
642 668 if (mod_mask > MOD_ISR) {
643 669 mod_mask = 0;
644 670 }
645 671 if (severity > CE_IGNORE) {
646 672 severity = 0;
647 673 }
648 674
649 675 dev->mod_mask = mod_mask;
650 676 dev->severity = severity;
651 677 } /* oce_get_params */
652 678
653 679 static int
654 680 oce_get_prop(struct oce_dev *dev, char *propname, int minval, int maxval,
655 681 int defval, uint32_t *values)
656 682 {
657 683 int value = 0;
658 684 int i = 0;
659 685
660 686 value = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
661 687 DDI_PROP_DONTPASS, propname, defval);
662 688
663 689 if (value > maxval)
664 690 value = maxval;
665 691
666 692 if (value < minval)
667 693 value = minval;
668 694
669 695 while (values[i] != 0xdeadface) {
670 696 if (values[i] == value) {
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
671 697 break;
672 698 }
673 699 i++;
674 700 }
675 701
676 702 if ((i != 0) && (values[i] == 0xdeadface)) {
677 703 value = defval;
678 704 }
679 705
680 706 return (value);
707 +}
708 +
709 +
710 +static void oce_reset_wd_timer(struct oce_dev *dev)
711 +{
712 + mutex_enter(&dev->wd_lock);
713 + if (dev->wd_enable) {
714 + oce_set_wd_timer(dev);
715 + }
716 + mutex_exit(&dev->wd_lock);
717 +}
718 +
719 +static void oce_wd_timer(void *arg)
720 +{
721 + struct oce_dev *dev = (struct oce_dev *)arg;
722 +
723 + if (!LANCER_CHIP(dev)) {
724 + if (oce_check_ue(dev)) {
725 + /* disable the watchdog and clean-up the interrupts */
726 + oce_disable_wd_timer(dev);
727 + mutex_enter(&dev->dev_lock);
728 + (void) oce_di(dev);
729 + ddi_fm_service_impact(dev->dip, DDI_SERVICE_LOST);
730 + mutex_exit(&dev->dev_lock);
731 + return;
732 + }
733 + }
734 +
735 + if (oce_tx_stall_check(dev)) {
736 + oce_log(dev, CE_NOTE, MOD_CONFIG, "Tx Stall Detected at %lu",
737 + ddi_get_lbolt());
738 + }
739 + /* restart the watch dog timer */
740 + oce_reset_wd_timer(dev);
741 +}
742 +
743 +static void
744 +oce_set_wd_timer(struct oce_dev *dev)
745 +{
746 + dev->wd_id =
747 + timeout(oce_wd_timer, (void *) dev, drv_usectohz(1000000));
748 +}
749 +
750 +void
751 +oce_enable_wd_timer(struct oce_dev *dev)
752 +{
753 +
754 + mutex_enter(&dev->wd_lock);
755 + if (!dev->wd_enable) {
756 + dev->wd_enable = B_TRUE;
757 + oce_set_wd_timer(dev);
758 + }
759 + mutex_exit(&dev->wd_lock);
760 +}
761 +
762 +void
763 +oce_disable_wd_timer(struct oce_dev *dev)
764 +{
765 + timeout_id_t wd_id;
766 + mutex_enter(&dev->wd_lock);
767 + dev->wd_enable = B_FALSE;
768 + wd_id = dev->wd_id;
769 + mutex_exit(&dev->wd_lock);
770 + if (wd_id != 0) {
771 + (void) untimeout(wd_id);
772 + dev->wd_id = 0;
773 + }
681 774 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX