1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* Copyright © 2003-2011 Emulex. All rights reserved. */ 23 24 25 /* 26 * Source file containing the implementation of the driver entry points 27 * and related helper functions 28 */ 29 30 #include <oce_impl.h> 31 #include <oce_stat.h> 32 #include <oce_ioctl.h> 33 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 /* ---[ globals and externs ]-------------------------------------------- */ 47 const char oce_ident_string[] = OCE_IDENT_STRING; 48 const char oce_mod_name[] = OCE_MOD_NAME; 49 struct oce_dev *oce_dev_list[MAX_DEVS + 1]; /* Last entry is invalid */ 50 51 /* driver properties */ 52 static const char flow_control[] = "flow_control"; 53 static const char mtu_prop_name[] = "oce_default_mtu"; 54 static const char tx_ring_size_name[] = "tx_ring_size"; 55 static const char tx_bcopy_limit_name[] = "tx_bcopy_limit"; 56 static const char rx_bcopy_limit_name[] = "rx_bcopy_limit"; 57 static const char rx_frag_size_name[] = "rx_frag_size"; 58 static const char rx_max_bufs_name[] = "rx_max_bufs"; 59 static const char fm_cap_name[] = "oce_fm_capability"; 60 static const char log_level_name[] = "oce_log_level"; 61 static const char lso_capable_name[] = "lso_capable"; 62 static const char rx_pkt_per_intr_name[] = "rx_pkts_per_intr"; 63 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"; 66 67 /* --[ static function prototypes here ]------------------------------- */ 68 static int oce_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd); 69 static int oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 70 static int oce_quiesce(dev_info_t *dip); 71 static int oce_suspend(dev_info_t *dip); 72 static int oce_resume(dev_info_t *dip); 73 static void oce_unconfigure(struct oce_dev *dev); 74 static void oce_init_locks(struct oce_dev *dev); 75 static void oce_destroy_locks(struct oce_dev *dev); 76 static void oce_get_params(struct oce_dev *dev); 77 static int oce_get_prop(struct oce_dev *dev, char *propname, int minval, 78 int maxval, int defval, uint32_t *values); 79 80 static struct cb_ops oce_cb_ops = { 81 nulldev, /* cb_open */ 82 nulldev, /* cb_close */ 83 nodev, /* cb_strategy */ 84 nodev, /* cb_print */ 85 nodev, /* cb_dump */ 86 nodev, /* cb_read */ 87 nodev, /* cb_write */ 88 nodev, /* cb_ioctl */ 89 nodev, /* cb_devmap */ 90 nodev, /* cb_mmap */ 91 nodev, /* cb_segmap */ 92 nochpoll, /* cb_chpoll */ 93 ddi_prop_op, /* cb_prop_op */ 94 NULL, /* cb_stream */ 95 D_MP, /* cb_flag */ 96 CB_REV, /* cb_rev */ 97 nodev, /* cb_aread */ 98 nodev /* cb_awrite */ 99 }; 100 101 static struct dev_ops oce_dev_ops = { 102 DEVO_REV, /* devo_rev */ 103 0, /* devo_refcnt */ 104 NULL, /* devo_getinfo */ 105 NULL, /* devo_identify */ 106 nulldev, /* devo_probe */ 107 oce_attach, /* devo_attach */ 108 oce_detach, /* devo_detach */ 109 nodev, /* devo_reset */ 110 &oce_cb_ops, /* devo_cb_ops */ 111 NULL, /* devo_bus_ops */ 112 nodev, /* devo_power */ 113 oce_quiesce /* devo_quiesce */ 114 }; 115 116 static struct modldrv oce_drv = { 117 &mod_driverops, /* Type of module. This one is a driver */ 118 (char *)oce_ident_string, /* Description string */ 119 &oce_dev_ops, /* driver ops */ 120 }; 121 122 static struct modlinkage oce_mod_linkage = { 123 MODREV_1, &oce_drv, NULL 124 }; 125 126 #define OCE_M_CB_FLAGS (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | \ 127 MC_PROPINFO) 128 static mac_callbacks_t oce_mac_cb = { 129 OCE_M_CB_FLAGS, /* mc_callbacks */ 130 oce_m_stat, /* mc_getstat */ 131 oce_m_start, /* mc_start */ 132 oce_m_stop, /* mc_stop */ 133 oce_m_promiscuous, /* mc_setpromisc */ 134 oce_m_multicast, /* mc_multicast */ 135 oce_m_unicast, /* mc_unicast */ 136 oce_m_send, /* mc_tx */ 137 NULL, /* mc_reserve */ 138 oce_m_ioctl, /* mc_ioctl */ 139 oce_m_getcap, /* mc_getcapab */ 140 NULL, /* open */ 141 NULL, /* close */ 142 oce_m_setprop, /* set properties */ 143 oce_m_getprop, /* get properties */ 144 oce_m_propinfo /* properties info */ 145 }; 146 147 extern char *oce_priv_props[]; 148 149 /* Module Init */ 150 int 151 _info(struct modinfo *modinfop) 152 { 153 return (mod_info(&oce_mod_linkage, modinfop)); 154 } /* _info */ 155 156 int 157 _init(void) 158 { 159 int ret = 0; 160 161 /* install the module */ 162 mac_init_ops(&oce_dev_ops, "oce"); 163 164 ret = mod_install(&oce_mod_linkage); 165 if (ret) { 166 cmn_err(CE_WARN, "mod_install failed rval=%x", ret); 167 } 168 169 return (ret); 170 } /* _init */ 171 172 173 int 174 _fini(void) 175 { 176 int ret = 0; 177 /* remove the module */ 178 ret = mod_remove(&oce_mod_linkage); 179 if (ret != 0) { 180 return (ret); 181 } 182 183 mac_fini_ops(&oce_dev_ops); 184 185 return (ret); 186 } /* _fini */ 187 188 189 static int 190 oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 191 { 192 int ret = 0; 193 struct oce_dev *dev = NULL; 194 mac_register_t *mac; 195 uint8_t dev_index = 0; 196 197 switch (cmd) { 198 case DDI_RESUME: 199 return (oce_resume(dip)); 200 default: 201 return (DDI_FAILURE); 202 203 case DDI_ATTACH: 204 break; 205 } 206 207 /* allocate dev */ 208 dev = kmem_zalloc(sizeof (struct oce_dev), KM_SLEEP); 209 210 /* populate the dev structure */ 211 dev->dip = dip; 212 dev->dev_id = ddi_get_instance(dip); 213 dev->suspended = B_FALSE; 214 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 /* get the parameters */ 231 oce_get_params(dev); 232 233 /* 234 * set the ddi driver private data pointer. This is 235 * sent to all mac callback entry points 236 */ 237 ddi_set_driver_private(dip, dev); 238 239 dev->attach_state |= ATTACH_DEV_INIT; 240 241 oce_fm_init(dev); 242 dev->attach_state |= ATTACH_FM_INIT; 243 244 ret = pci_config_setup(dev->dip, &dev->pci_cfg_handle); 245 if (ret != DDI_SUCCESS) { 246 oce_log(dev, CE_WARN, MOD_CONFIG, 247 "Map PCI config failed with %d", ret); 248 goto attach_fail; 249 } 250 dev->attach_state |= ATTACH_PCI_CFG; 251 252 ret = oce_identify_hw(dev); 253 254 if (ret != DDI_SUCCESS) { 255 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 256 "Device Unknown"); 257 goto attach_fail; 258 } 259 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 /* setup PCI bars */ 270 ret = oce_pci_init(dev); 271 if (ret != DDI_SUCCESS) { 272 oce_log(dev, CE_WARN, MOD_CONFIG, 273 "PCI initialization failed with %d", ret); 274 goto attach_fail; 275 } 276 dev->attach_state |= ATTACH_PCI_INIT; 277 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 /* initialize locks */ 288 oce_init_locks(dev); 289 dev->attach_state |= ATTACH_LOCK_INIT; 290 291 292 /* HW init */ 293 ret = oce_hw_init(dev); 294 if (ret != DDI_SUCCESS) { 295 oce_log(dev, CE_WARN, MOD_CONFIG, 296 "HW initialization failed with %d", ret); 297 goto attach_fail; 298 } 299 dev->attach_state |= ATTACH_HW_INIT; 300 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; 306 } 307 dev->attach_state |= ATTACH_SETUP_TXRX; 308 309 ret = oce_setup_adapter(dev); 310 if (ret != DDI_SUCCESS) { 311 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 312 "Failed to setup adapter"); 313 goto attach_fail; 314 } 315 dev->attach_state |= ATTACH_SETUP_ADAP; 316 317 318 ret = oce_stat_init(dev); 319 if (ret != DDI_SUCCESS) { 320 oce_log(dev, CE_WARN, MOD_CONFIG, 321 "kstat setup Failed with %d", ret); 322 goto attach_fail; 323 } 324 dev->attach_state |= ATTACH_STAT_INIT; 325 326 /* mac_register_t */ 327 oce_log(dev, CE_NOTE, MOD_CONFIG, 328 "MAC_VERSION = 0x%x", MAC_VERSION); 329 mac = mac_alloc(MAC_VERSION); 330 if (mac == NULL) { 331 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 332 "MAC allocation Failed"); 333 goto attach_fail; 334 } 335 /* 336 * fill the mac structure before calling mac_register 337 */ 338 mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 339 mac->m_driver = dev; 340 mac->m_dip = dip; 341 mac->m_src_addr = dev->mac_addr; 342 mac->m_callbacks = &oce_mac_cb; 343 mac->m_min_sdu = 0; 344 mac->m_max_sdu = dev->mtu; 345 mac->m_margin = VTAG_SIZE; 346 mac->m_priv_props = oce_priv_props; 347 348 oce_log(dev, CE_NOTE, MOD_CONFIG, 349 "Driver Private structure = 0x%p", (void *)dev); 350 351 /* now register with GLDv3 */ 352 ret = mac_register(mac, (mac_handle_t *)&dev->mac_handle); 353 /* regardless of the status, free mac_register */ 354 mac_free(mac); 355 mac = NULL; 356 if (ret != DDI_SUCCESS) { 357 oce_log(dev, CE_WARN, MOD_CONFIG, 358 "MAC registration failed :0x%x", ret); 359 goto attach_fail; 360 361 } 362 363 /* correct link status only after start */ 364 dev->link_status = LINK_STATE_UNKNOWN; 365 mac_link_update(dev->mac_handle, dev->link_status); 366 367 dev->attach_state |= ATTACH_MAC_REG; 368 dev->state |= STATE_INIT; 369 370 oce_log(dev, CE_NOTE, MOD_CONFIG, "%s", 371 "ATTACH SUCCESS"); 372 373 return (DDI_SUCCESS); 374 375 attach_fail: 376 oce_unconfigure(dev); 377 return (DDI_FAILURE); 378 } /* oce_attach */ 379 380 static int 381 oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 382 { 383 struct oce_dev *dev; 384 int pcnt = 0; 385 int qid; 386 387 dev = ddi_get_driver_private(dip); 388 if (dev == NULL) { 389 return (DDI_FAILURE); 390 } 391 oce_log(dev, CE_NOTE, MOD_CONFIG, 392 "Detaching driver: cmd = 0x%x", cmd); 393 394 switch (cmd) { 395 default: 396 return (DDI_FAILURE); 397 case DDI_SUSPEND: 398 return (oce_suspend(dip)); 399 case DDI_DETACH: 400 break; 401 } /* switch cmd */ 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 /* check if the detach is called with out stopping */ 411 DEV_LOCK(dev); 412 if (dev->state & STATE_MAC_STARTED) { 413 dev->state &= ~STATE_MAC_STARTED; 414 oce_stop(dev); 415 DEV_UNLOCK(dev); 416 } else 417 DEV_UNLOCK(dev); 418 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 oce_unconfigure(dev); 431 432 return (DDI_SUCCESS); 433 } /* oce_detach */ 434 435 static int 436 oce_quiesce(dev_info_t *dip) 437 { 438 int ret = DDI_SUCCESS; 439 struct oce_dev *dev = ddi_get_driver_private(dip); 440 441 if (dev == NULL) { 442 return (DDI_FAILURE); 443 } 444 if (dev->suspended) { 445 return (DDI_SUCCESS); 446 } 447 448 oce_chip_di(dev); 449 450 ret = oce_reset_fun(dev); 451 452 return (ret); 453 } 454 455 static int 456 oce_suspend(dev_info_t *dip) 457 { 458 struct oce_dev *dev = ddi_get_driver_private(dip); 459 460 mutex_enter(&dev->dev_lock); 461 /* Suspend the card */ 462 dev->suspended = B_TRUE; 463 /* stop the adapter */ 464 if (dev->state & STATE_MAC_STARTED) { 465 oce_stop(dev); 466 oce_unsetup_adapter(dev); 467 } 468 dev->state &= ~STATE_MAC_STARTED; 469 mutex_exit(&dev->dev_lock); 470 return (DDI_SUCCESS); 471 } /* oce_suspend */ 472 473 static int 474 oce_resume(dev_info_t *dip) 475 { 476 struct oce_dev *dev; 477 int ret; 478 479 /* get the dev pointer from dip */ 480 dev = ddi_get_driver_private(dip); 481 mutex_enter(&dev->dev_lock); 482 if (!dev->suspended) { 483 mutex_exit(&dev->dev_lock); 484 return (DDI_SUCCESS); 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); 491 } 492 ret = oce_start(dev); 493 if (ret != DDI_SUCCESS) { 494 mutex_exit(&dev->dev_lock); 495 return (DDI_FAILURE); 496 } 497 } 498 dev->suspended = B_FALSE; 499 dev->state |= STATE_MAC_STARTED; 500 mutex_exit(&dev->dev_lock); 501 return (ret); 502 } /* oce_resume */ 503 504 static void 505 oce_init_locks(struct oce_dev *dev) 506 { 507 /* initialize locks */ 508 mutex_init(&dev->dev_lock, NULL, MUTEX_DRIVER, 509 DDI_INTR_PRI(dev->intr_pri)); 510 mutex_init(&dev->bmbx_lock, NULL, MUTEX_DRIVER, 511 DDI_INTR_PRI(dev->intr_pri)); 512 } /* oce_init_locks */ 513 514 static void 515 oce_destroy_locks(struct oce_dev *dev) 516 { 517 mutex_destroy(&dev->dev_lock); 518 mutex_destroy(&dev->bmbx_lock); 519 } /* oce_destroy_locks */ 520 521 static void 522 oce_unconfigure(struct oce_dev *dev) 523 { 524 uint32_t state = dev->attach_state; 525 526 if (state & ATTACH_MAC_REG) { 527 (void) mac_unregister(dev->mac_handle); 528 } 529 if (state & ATTACH_STAT_INIT) { 530 oce_stat_fini(dev); 531 } 532 if (state & ATTACH_SETUP_ADAP) { 533 oce_unsetup_adapter(dev); 534 } 535 if (state & ATTACH_SETUP_TXRX) { 536 oce_fini_txrx(dev); 537 } 538 if (state & ATTACH_HW_INIT) { 539 oce_hw_fini(dev); 540 } 541 if (state & ATTACH_LOCK_INIT) { 542 oce_destroy_locks(dev); 543 } 544 if (state & ATTACH_SETUP_INTR) { 545 (void) oce_teardown_intr(dev); 546 } 547 if (state & ATTACH_PCI_INIT) { 548 oce_pci_fini(dev); 549 } 550 if (state & ATTACH_PCI_CFG) { 551 pci_config_teardown(&dev->pci_cfg_handle); 552 } 553 if (state & ATTACH_FM_INIT) { 554 oce_fm_fini(dev); 555 } 556 if (state & ATTACH_DEV_INIT) { 557 ddi_set_driver_private(dev->dip, NULL); 558 oce_dev_list[dev->dev_list_index] = NULL; 559 kmem_free(dev, sizeof (struct oce_dev)); 560 } 561 } /* oce_unconfigure */ 562 563 static void 564 oce_get_params(struct oce_dev *dev) 565 { 566 uint32_t log_level; 567 uint16_t mod_mask; 568 uint16_t severity; 569 /* 570 * Allowed values for the driver parameters. If all values in a range 571 * is allowed, the the array has only one value. 572 */ 573 uint32_t fc_values[] = {OCE_FC_NONE, OCE_FC_TX, OCE_FC_RX, 574 OCE_DEFAULT_FLOW_CONTROL, END}; 575 uint32_t mtu_values[] = {OCE_MIN_MTU, OCE_MAX_MTU, END}; 576 uint32_t tx_rs_values[] = {SIZE_256, SIZE_512, SIZE_1K, SIZE_2K, END}; 577 uint32_t tx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K, 578 SIZE_2K, END}; 579 uint32_t rx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K, 580 SIZE_2K, END}; 581 uint32_t rq_fs_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END}; 582 uint32_t rq_mb_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END}; 583 uint32_t lso_capable_values[] = {0, 1, END}; 584 uint32_t fm_caps_values[] = {DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY, 585 END}; 586 uint32_t tx_rt_values[] = {END}; 587 uint32_t rx_ppi_values[] = {END}; 588 uint32_t rx_rings_values[] = {END}; 589 uint32_t tx_rings_values[] = {END}; 590 uint32_t log_level_values[] = {END}; 591 592 /* non tunables */ 593 dev->rx_ring_size = OCE_DEFAULT_RX_RING_SIZE; 594 595 /* configurable parameters */ 596 dev->flow_control = oce_get_prop(dev, (char *)flow_control, OCE_FC_NONE, 597 OCE_DEFAULT_FLOW_CONTROL, OCE_DEFAULT_FLOW_CONTROL, fc_values); 598 599 dev->mtu = oce_get_prop(dev, (char *)mtu_prop_name, OCE_MIN_MTU, 600 OCE_MAX_MTU, OCE_MIN_MTU, mtu_values); 601 602 dev->tx_ring_size = oce_get_prop(dev, (char *)tx_ring_size_name, 603 SIZE_256, SIZE_2K, OCE_DEFAULT_TX_RING_SIZE, tx_rs_values); 604 605 dev->tx_bcopy_limit = oce_get_prop(dev, (char *)tx_bcopy_limit_name, 606 SIZE_128, SIZE_2K, OCE_DEFAULT_TX_BCOPY_LIMIT, tx_bcl_values); 607 608 dev->rx_bcopy_limit = oce_get_prop(dev, (char *)rx_bcopy_limit_name, 609 SIZE_128, SIZE_2K, OCE_DEFAULT_RX_BCOPY_LIMIT, rx_bcl_values); 610 611 dev->rq_frag_size = oce_get_prop(dev, (char *)rx_frag_size_name, 612 SIZE_2K, SIZE_8K, OCE_RQ_BUF_SIZE, rq_fs_values); 613 614 dev->rq_max_bufs = oce_get_prop(dev, (char *)rx_max_bufs_name, SIZE_2K, 615 SIZE_8K, OCE_RQ_NUM_BUFFERS, rq_mb_values); 616 617 dev->lso_capable = oce_get_prop(dev, (char *)lso_capable_name, 0, 618 1, 1, lso_capable_values); 619 620 dev->fm_caps = oce_get_prop(dev, (char *)fm_cap_name, 621 DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY, OCE_FM_CAPABILITY, 622 fm_caps_values); 623 624 dev->tx_reclaim_threshold = oce_get_prop(dev, 625 (char *)tx_reclaim_threshold_name, 0, dev->tx_ring_size/2, 626 OCE_DEFAULT_TX_RECLAIM_THRESHOLD, tx_rt_values); 627 628 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); 630 631 dev->rx_rings = oce_get_prop(dev, (char *)rx_rings_name, 632 OCE_MIN_RQ, OCE_MAX_RQ, OCE_DEFAULT_RQS, rx_rings_values); 633 634 dev->tx_rings = oce_get_prop(dev, (char *)tx_rings_name, 635 OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, tx_rings_values); 636 637 log_level = oce_get_prop(dev, (char *)log_level_name, 0, 638 OCE_MAX_LOG_SETTINGS, OCE_DEFAULT_LOG_SETTINGS, log_level_values); 639 640 severity = (uint16_t)(log_level & 0xffff); 641 mod_mask = (uint16_t)(log_level >> 16); 642 if (mod_mask > MOD_ISR) { 643 mod_mask = 0; 644 } 645 if (severity > CE_IGNORE) { 646 severity = 0; 647 } 648 649 dev->mod_mask = mod_mask; 650 dev->severity = severity; 651 } /* oce_get_params */ 652 653 static int 654 oce_get_prop(struct oce_dev *dev, char *propname, int minval, int maxval, 655 int defval, uint32_t *values) 656 { 657 int value = 0; 658 int i = 0; 659 660 value = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 661 DDI_PROP_DONTPASS, propname, defval); 662 663 if (value > maxval) 664 value = maxval; 665 666 if (value < minval) 667 value = minval; 668 669 while (values[i] != 0xdeadface) { 670 if (values[i] == value) { 671 break; 672 } 673 i++; 674 } 675 676 if ((i != 0) && (values[i] == 0xdeadface)) { 677 value = defval; 678 } 679 680 return (value); 681 }