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 /* 23 * Copyright (c) 2010-2013, by Broadcom, Inc. 24 * All Rights Reserved. 25 */ 26 27 /* 28 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. 29 * All rights reserved. 30 */ 31 32 #include "bge_impl.h" 33 #include <sys/sdt.h> 34 #include <sys/mac_provider.h> 35 #include <sys/mac.h> 36 #include <sys/mac_flow.h> 37 38 39 #ifndef STRINGIFY 40 #define XSTRINGIFY(x) #x 41 #define STRINGIFY(x) XSTRINGIFY(x) 42 #endif 43 44 /* 45 * This is the string displayed by modinfo, etc. 46 */ 47 static char bge_ident[] = "Broadcom Gb Ethernet"; 48 49 /* 50 * Property names 51 */ 52 static char debug_propname[] = "bge-debug-flags"; 53 static char clsize_propname[] = "cache-line-size"; 54 static char latency_propname[] = "latency-timer"; 55 static char localmac_boolname[] = "local-mac-address?"; 56 static char localmac_propname[] = "local-mac-address"; 57 static char macaddr_propname[] = "mac-address"; 58 static char subdev_propname[] = "subsystem-id"; 59 static char subven_propname[] = "subsystem-vendor-id"; 60 static char rxrings_propname[] = "bge-rx-rings"; 61 static char txrings_propname[] = "bge-tx-rings"; 62 static char eee_propname[] = "bge-eee"; 63 static char fm_cap[] = "fm-capable"; 64 static char default_mtu[] = "default_mtu"; 65 66 static int bge_add_intrs(bge_t *, int); 67 static void bge_rem_intrs(bge_t *); 68 static int bge_unicst_set(void *, const uint8_t *, int); 69 static int bge_addmac(void *, const uint8_t *); 70 static int bge_remmac(void *, const uint8_t *); 71 72 /* 73 * Describes the chip's DMA engine 74 */ 75 static ddi_dma_attr_t dma_attr = { 76 DMA_ATTR_V0, /* dma_attr_version */ 77 0x0000000000000000ull, /* dma_attr_addr_lo */ 78 0xFFFFFFFFFFFFFFFFull, /* dma_attr_addr_hi */ 79 0x00000000FFFFFFFFull, /* dma_attr_count_max */ 80 0x0000000000000001ull, /* dma_attr_align */ 81 0x00000FFF, /* dma_attr_burstsizes */ 82 0x00000001, /* dma_attr_minxfer */ 83 0x000000000000FFFFull, /* dma_attr_maxxfer */ 84 0x00000000FFFFFFFFull, /* dma_attr_seg */ 85 1, /* dma_attr_sgllen */ 86 0x00000001, /* dma_attr_granular */ 87 DDI_DMA_FLAGERR /* dma_attr_flags */ 88 }; 89 90 /* 91 * PIO access attributes for registers 92 */ 93 static ddi_device_acc_attr_t bge_reg_accattr = { 94 DDI_DEVICE_ATTR_V1, 95 DDI_NEVERSWAP_ACC, 96 DDI_STRICTORDER_ACC, 97 DDI_FLAGERR_ACC 98 }; 99 100 /* 101 * DMA access attributes for descriptors: NOT to be byte swapped. 102 */ 103 static ddi_device_acc_attr_t bge_desc_accattr = { 104 DDI_DEVICE_ATTR_V0, 105 DDI_NEVERSWAP_ACC, 106 DDI_STRICTORDER_ACC 107 }; 108 109 /* 110 * DMA access attributes for data: NOT to be byte swapped. 111 */ 112 static ddi_device_acc_attr_t bge_data_accattr = { 113 DDI_DEVICE_ATTR_V0, 114 DDI_NEVERSWAP_ACC, 115 DDI_STRICTORDER_ACC 116 }; 117 118 static int bge_m_start(void *); 119 static void bge_m_stop(void *); 120 static int bge_m_promisc(void *, boolean_t); 121 static int bge_m_unicst(void * pArg, const uint8_t *); 122 static int bge_m_multicst(void *, boolean_t, const uint8_t *); 123 static void bge_m_resources(void * arg); 124 static void bge_m_ioctl(void *, queue_t *, mblk_t *); 125 static boolean_t bge_m_getcapab(void *, mac_capab_t, void *); 126 static int bge_unicst_set(void *, const uint8_t *, 127 int); 128 static int bge_m_setprop(void *, const char *, mac_prop_id_t, 129 uint_t, const void *); 130 static int bge_m_getprop(void *, const char *, mac_prop_id_t, 131 uint_t, void *); 132 static void bge_m_propinfo(void *, const char *, mac_prop_id_t, 133 mac_prop_info_handle_t); 134 static int bge_set_priv_prop(bge_t *, const char *, uint_t, 135 const void *); 136 static int bge_get_priv_prop(bge_t *, const char *, uint_t, 137 void *); 138 static void bge_priv_propinfo(const char *, 139 mac_prop_info_handle_t); 140 141 static mac_callbacks_t bge_m_callbacks = { 142 MC_IOCTL 143 #ifdef MC_RESOURCES 144 | MC_RESOURCES 145 #endif 146 #ifdef MC_SETPROP 147 | MC_SETPROP 148 #endif 149 #ifdef MC_GETPROP 150 | MC_GETPROP 151 #endif 152 #ifdef MC_PROPINFO 153 | MC_PROPINFO 154 #endif 155 | MC_GETCAPAB, 156 bge_m_stat, 157 bge_m_start, 158 bge_m_stop, 159 bge_m_promisc, 160 bge_m_multicst, 161 bge_m_unicst, 162 bge_m_tx, 163 #ifdef MC_RESOURCES 164 bge_m_resources, 165 #else 166 NULL, 167 #endif 168 bge_m_ioctl, 169 bge_m_getcapab, 170 #ifdef MC_OPEN 171 NULL, 172 NULL, 173 #endif 174 #ifdef MC_SETPROP 175 bge_m_setprop, 176 #endif 177 #ifdef MC_GETPROP 178 bge_m_getprop, 179 #endif 180 #ifdef MC_PROPINFO 181 bge_m_propinfo 182 #endif 183 }; 184 185 char *bge_priv_prop[] = { 186 "_adv_asym_pause_cap", 187 "_adv_pause_cap", 188 "_drain_max", 189 "_msi_cnt", 190 "_rx_intr_coalesce_blank_time", 191 "_tx_intr_coalesce_blank_time", 192 "_rx_intr_coalesce_pkt_cnt", 193 "_tx_intr_coalesce_pkt_cnt", 194 NULL 195 }; 196 197 uint8_t zero_addr[6] = {0, 0, 0, 0, 0, 0}; 198 /* 199 * ========== Transmit and receive ring reinitialisation ========== 200 */ 201 202 /* 203 * These <reinit> routines each reset the specified ring to an initial 204 * state, assuming that the corresponding <init> routine has already 205 * been called exactly once. 206 */ 207 208 static void 209 bge_reinit_send_ring(send_ring_t *srp) 210 { 211 bge_queue_t *txbuf_queue; 212 bge_queue_item_t *txbuf_head; 213 sw_txbuf_t *txbuf; 214 sw_sbd_t *ssbdp; 215 uint32_t slot; 216 217 /* 218 * Reinitialise control variables ... 219 */ 220 srp->tx_flow = 0; 221 srp->tx_next = 0; 222 srp->txfill_next = 0; 223 srp->tx_free = srp->desc.nslots; 224 ASSERT(mutex_owned(srp->tc_lock)); 225 srp->tc_next = 0; 226 srp->txpkt_next = 0; 227 srp->tx_block = 0; 228 srp->tx_nobd = 0; 229 srp->tx_nobuf = 0; 230 231 /* 232 * Initialize the tx buffer push queue 233 */ 234 mutex_enter(srp->freetxbuf_lock); 235 mutex_enter(srp->txbuf_lock); 236 txbuf_queue = &srp->freetxbuf_queue; 237 txbuf_queue->head = NULL; 238 txbuf_queue->count = 0; 239 txbuf_queue->lock = srp->freetxbuf_lock; 240 srp->txbuf_push_queue = txbuf_queue; 241 242 /* 243 * Initialize the tx buffer pop queue 244 */ 245 txbuf_queue = &srp->txbuf_queue; 246 txbuf_queue->head = NULL; 247 txbuf_queue->count = 0; 248 txbuf_queue->lock = srp->txbuf_lock; 249 srp->txbuf_pop_queue = txbuf_queue; 250 txbuf_head = srp->txbuf_head; 251 txbuf = srp->txbuf; 252 for (slot = 0; slot < srp->tx_buffers; ++slot) { 253 txbuf_head->item = txbuf; 254 txbuf_head->next = txbuf_queue->head; 255 txbuf_queue->head = txbuf_head; 256 txbuf_queue->count++; 257 txbuf++; 258 txbuf_head++; 259 } 260 mutex_exit(srp->txbuf_lock); 261 mutex_exit(srp->freetxbuf_lock); 262 263 /* 264 * Zero and sync all the h/w Send Buffer Descriptors 265 */ 266 DMA_ZERO(srp->desc); 267 DMA_SYNC(srp->desc, DDI_DMA_SYNC_FORDEV); 268 bzero(srp->pktp, BGE_SEND_BUF_MAX * sizeof (*srp->pktp)); 269 ssbdp = srp->sw_sbds; 270 for (slot = 0; slot < srp->desc.nslots; ++ssbdp, ++slot) 271 ssbdp->pbuf = NULL; 272 } 273 274 static void 275 bge_reinit_recv_ring(recv_ring_t *rrp) 276 { 277 /* 278 * Reinitialise control variables ... 279 */ 280 rrp->rx_next = 0; 281 } 282 283 static void 284 bge_reinit_buff_ring(buff_ring_t *brp, uint32_t ring) 285 { 286 bge_rbd_t *hw_rbd_p; 287 sw_rbd_t *srbdp; 288 uint32_t bufsize; 289 uint32_t nslots; 290 uint32_t slot; 291 292 static uint16_t ring_type_flag[BGE_BUFF_RINGS_MAX] = { 293 RBD_FLAG_STD_RING, 294 RBD_FLAG_JUMBO_RING, 295 RBD_FLAG_MINI_RING 296 }; 297 298 /* 299 * Zero, initialise and sync all the h/w Receive Buffer Descriptors 300 * Note: all the remaining fields (<type>, <flags>, <ip_cksum>, 301 * <tcp_udp_cksum>, <error_flag>, <vlan_tag>, and <reserved>) 302 * should be zeroed, and so don't need to be set up specifically 303 * once the whole area has been cleared. 304 */ 305 DMA_ZERO(brp->desc); 306 307 hw_rbd_p = DMA_VPTR(brp->desc); 308 nslots = brp->desc.nslots; 309 ASSERT(brp->buf[0].nslots == nslots/BGE_SPLIT); 310 bufsize = brp->buf[0].size; 311 srbdp = brp->sw_rbds; 312 for (slot = 0; slot < nslots; ++hw_rbd_p, ++srbdp, ++slot) { 313 hw_rbd_p->host_buf_addr = srbdp->pbuf.cookie.dmac_laddress; 314 hw_rbd_p->index = (uint16_t)slot; 315 hw_rbd_p->len = (uint16_t)bufsize; 316 hw_rbd_p->opaque = srbdp->pbuf.token; 317 hw_rbd_p->flags |= ring_type_flag[ring]; 318 } 319 320 DMA_SYNC(brp->desc, DDI_DMA_SYNC_FORDEV); 321 322 /* 323 * Finally, reinitialise the ring control variables ... 324 */ 325 brp->rf_next = (nslots != 0) ? (nslots-1) : 0; 326 } 327 328 /* 329 * Reinitialize all rings 330 */ 331 static void 332 bge_reinit_rings(bge_t *bgep) 333 { 334 uint32_t ring; 335 336 ASSERT(mutex_owned(bgep->genlock)); 337 338 /* 339 * Send Rings ... 340 */ 341 for (ring = 0; ring < bgep->chipid.tx_rings; ++ring) 342 bge_reinit_send_ring(&bgep->send[ring]); 343 344 /* 345 * Receive Return Rings ... 346 */ 347 for (ring = 0; ring < bgep->chipid.rx_rings; ++ring) 348 bge_reinit_recv_ring(&bgep->recv[ring]); 349 350 /* 351 * Receive Producer Rings ... 352 */ 353 for (ring = 0; ring < BGE_BUFF_RINGS_USED; ++ring) 354 bge_reinit_buff_ring(&bgep->buff[ring], ring); 355 } 356 357 /* 358 * ========== Internal state management entry points ========== 359 */ 360 361 #undef BGE_DBG 362 #define BGE_DBG BGE_DBG_NEMO /* debug flag for this code */ 363 364 /* 365 * These routines provide all the functionality required by the 366 * corresponding GLD entry points, but don't update the GLD state 367 * so they can be called internally without disturbing our record 368 * of what GLD thinks we should be doing ... 369 */ 370 371 /* 372 * bge_reset() -- reset h/w & rings to initial state 373 */ 374 static int 375 #ifdef BGE_IPMI_ASF 376 bge_reset(bge_t *bgep, uint_t asf_mode) 377 #else 378 bge_reset(bge_t *bgep) 379 #endif 380 { 381 uint32_t ring; 382 int retval; 383 384 BGE_TRACE(("bge_reset($%p)", (void *)bgep)); 385 386 ASSERT(mutex_owned(bgep->genlock)); 387 388 /* 389 * Grab all the other mutexes in the world (this should 390 * ensure no other threads are manipulating driver state) 391 */ 392 for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring) 393 mutex_enter(bgep->recv[ring].rx_lock); 394 for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring) 395 mutex_enter(bgep->buff[ring].rf_lock); 396 rw_enter(bgep->errlock, RW_WRITER); 397 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring) 398 mutex_enter(bgep->send[ring].tx_lock); 399 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring) 400 mutex_enter(bgep->send[ring].tc_lock); 401 402 #ifdef BGE_IPMI_ASF 403 retval = bge_chip_reset(bgep, B_TRUE, asf_mode); 404 #else 405 retval = bge_chip_reset(bgep, B_TRUE); 406 #endif 407 bge_reinit_rings(bgep); 408 409 /* 410 * Free the world ... 411 */ 412 for (ring = BGE_SEND_RINGS_MAX; ring-- > 0; ) 413 mutex_exit(bgep->send[ring].tc_lock); 414 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring) 415 mutex_exit(bgep->send[ring].tx_lock); 416 rw_exit(bgep->errlock); 417 for (ring = BGE_BUFF_RINGS_MAX; ring-- > 0; ) 418 mutex_exit(bgep->buff[ring].rf_lock); 419 for (ring = BGE_RECV_RINGS_MAX; ring-- > 0; ) 420 mutex_exit(bgep->recv[ring].rx_lock); 421 422 BGE_DEBUG(("bge_reset($%p) done", (void *)bgep)); 423 return (retval); 424 } 425 426 /* 427 * bge_stop() -- stop processing, don't reset h/w or rings 428 */ 429 static void 430 bge_stop(bge_t *bgep) 431 { 432 BGE_TRACE(("bge_stop($%p)", (void *)bgep)); 433 434 ASSERT(mutex_owned(bgep->genlock)); 435 436 #ifdef BGE_IPMI_ASF 437 if (bgep->asf_enabled) { 438 bgep->asf_pseudostop = B_TRUE; 439 } else { 440 #endif 441 bge_chip_stop(bgep, B_FALSE); 442 #ifdef BGE_IPMI_ASF 443 } 444 #endif 445 446 BGE_DEBUG(("bge_stop($%p) done", (void *)bgep)); 447 } 448 449 /* 450 * bge_start() -- start transmitting/receiving 451 */ 452 static int 453 bge_start(bge_t *bgep, boolean_t reset_phys) 454 { 455 int retval; 456 457 BGE_TRACE(("bge_start($%p, %d)", (void *)bgep, reset_phys)); 458 459 ASSERT(mutex_owned(bgep->genlock)); 460 461 /* 462 * Start chip processing, including enabling interrupts 463 */ 464 retval = bge_chip_start(bgep, reset_phys); 465 466 BGE_DEBUG(("bge_start($%p, %d) done", (void *)bgep, reset_phys)); 467 return (retval); 468 } 469 470 /* 471 * bge_restart - restart transmitting/receiving after error or suspend 472 */ 473 int 474 bge_restart(bge_t *bgep, boolean_t reset_phys) 475 { 476 int retval = DDI_SUCCESS; 477 ASSERT(mutex_owned(bgep->genlock)); 478 479 #ifdef BGE_IPMI_ASF 480 if (bgep->asf_enabled) { 481 if (bge_reset(bgep, ASF_MODE_POST_INIT) != DDI_SUCCESS) 482 retval = DDI_FAILURE; 483 } else 484 if (bge_reset(bgep, ASF_MODE_NONE) != DDI_SUCCESS) 485 retval = DDI_FAILURE; 486 #else 487 if (bge_reset(bgep) != DDI_SUCCESS) 488 retval = DDI_FAILURE; 489 #endif 490 if (bgep->bge_mac_state == BGE_MAC_STARTED) { 491 if (bge_start(bgep, reset_phys) != DDI_SUCCESS) 492 retval = DDI_FAILURE; 493 bgep->watchdog = 0; 494 ddi_trigger_softintr(bgep->drain_id); 495 } 496 497 BGE_DEBUG(("bge_restart($%p, %d) done", (void *)bgep, reset_phys)); 498 return (retval); 499 } 500 501 502 /* 503 * ========== Nemo-required management entry points ========== 504 */ 505 506 #undef BGE_DBG 507 #define BGE_DBG BGE_DBG_NEMO /* debug flag for this code */ 508 509 /* 510 * bge_m_stop() -- stop transmitting/receiving 511 */ 512 static void 513 bge_m_stop(void *arg) 514 { 515 bge_t *bgep = arg; /* private device info */ 516 send_ring_t *srp; 517 uint32_t ring; 518 519 BGE_TRACE(("bge_m_stop($%p)", arg)); 520 521 /* 522 * Just stop processing, then record new GLD state 523 */ 524 mutex_enter(bgep->genlock); 525 if (!(bgep->progress & PROGRESS_INTR)) { 526 /* can happen during autorecovery */ 527 bgep->bge_chip_state = BGE_CHIP_STOPPED; 528 } else 529 bge_stop(bgep); 530 531 bgep->link_state = LINK_STATE_UNKNOWN; 532 mac_link_update(bgep->mh, bgep->link_state); 533 534 /* 535 * Free the possible tx buffers allocated in tx process. 536 */ 537 #ifdef BGE_IPMI_ASF 538 if (!bgep->asf_pseudostop) 539 #endif 540 { 541 rw_enter(bgep->errlock, RW_WRITER); 542 for (ring = 0; ring < bgep->chipid.tx_rings; ++ring) { 543 srp = &bgep->send[ring]; 544 mutex_enter(srp->tx_lock); 545 if (srp->tx_array > 1) 546 bge_free_txbuf_arrays(srp); 547 mutex_exit(srp->tx_lock); 548 } 549 rw_exit(bgep->errlock); 550 } 551 bgep->bge_mac_state = BGE_MAC_STOPPED; 552 BGE_DEBUG(("bge_m_stop($%p) done", arg)); 553 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) 554 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); 555 mutex_exit(bgep->genlock); 556 } 557 558 /* 559 * bge_m_start() -- start transmitting/receiving 560 */ 561 static int 562 bge_m_start(void *arg) 563 { 564 bge_t *bgep = arg; /* private device info */ 565 566 BGE_TRACE(("bge_m_start($%p)", arg)); 567 568 /* 569 * Start processing and record new GLD state 570 */ 571 mutex_enter(bgep->genlock); 572 if (!(bgep->progress & PROGRESS_INTR)) { 573 /* can happen during autorecovery */ 574 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 575 mutex_exit(bgep->genlock); 576 return (EIO); 577 } 578 #ifdef BGE_IPMI_ASF 579 if (bgep->asf_enabled) { 580 if ((bgep->asf_status == ASF_STAT_RUN) && 581 (bgep->asf_pseudostop)) { 582 bgep->bge_mac_state = BGE_MAC_STARTED; 583 /* forcing a mac link update here */ 584 bge_phys_check(bgep); 585 bgep->link_state = (bgep->param_link_up) ? LINK_STATE_UP : 586 LINK_STATE_DOWN; 587 mac_link_update(bgep->mh, bgep->link_state); 588 mutex_exit(bgep->genlock); 589 return (0); 590 } 591 } 592 if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) { 593 #else 594 if (bge_reset(bgep) != DDI_SUCCESS) { 595 #endif 596 (void) bge_check_acc_handle(bgep, bgep->cfg_handle); 597 (void) bge_check_acc_handle(bgep, bgep->io_handle); 598 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 599 mutex_exit(bgep->genlock); 600 return (EIO); 601 } 602 if (bge_start(bgep, B_TRUE) != DDI_SUCCESS) { 603 (void) bge_check_acc_handle(bgep, bgep->cfg_handle); 604 (void) bge_check_acc_handle(bgep, bgep->io_handle); 605 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 606 mutex_exit(bgep->genlock); 607 return (EIO); 608 } 609 bgep->watchdog = 0; 610 bgep->bge_mac_state = BGE_MAC_STARTED; 611 BGE_DEBUG(("bge_m_start($%p) done", arg)); 612 613 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 614 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 615 mutex_exit(bgep->genlock); 616 return (EIO); 617 } 618 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 619 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 620 mutex_exit(bgep->genlock); 621 return (EIO); 622 } 623 #ifdef BGE_IPMI_ASF 624 if (bgep->asf_enabled) { 625 if (bgep->asf_status != ASF_STAT_RUN) { 626 /* start ASF heart beat */ 627 bgep->asf_timeout_id = timeout(bge_asf_heartbeat, 628 (void *)bgep, 629 drv_usectohz(BGE_ASF_HEARTBEAT_INTERVAL)); 630 bgep->asf_status = ASF_STAT_RUN; 631 } 632 } 633 #endif 634 mutex_exit(bgep->genlock); 635 636 return (0); 637 } 638 639 /* 640 * bge_unicst_set() -- set the physical network address 641 */ 642 static int 643 bge_unicst_set(void *arg, const uint8_t *macaddr, int slot) 644 { 645 bge_t *bgep = arg; /* private device info */ 646 647 BGE_TRACE(("bge_unicst_set($%p, %s)", arg, 648 ether_sprintf((void *)macaddr))); 649 /* 650 * Remember the new current address in the driver state 651 * Sync the chip's idea of the address too ... 652 */ 653 mutex_enter(bgep->genlock); 654 if (!(bgep->progress & PROGRESS_INTR)) { 655 /* can happen during autorecovery */ 656 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 657 mutex_exit(bgep->genlock); 658 return (EIO); 659 } 660 ethaddr_copy(macaddr, bgep->curr_addr[slot].addr); 661 #ifdef BGE_IPMI_ASF 662 if (bge_chip_sync(bgep, B_FALSE) == DDI_FAILURE) { 663 #else 664 if (bge_chip_sync(bgep) == DDI_FAILURE) { 665 #endif 666 (void) bge_check_acc_handle(bgep, bgep->cfg_handle); 667 (void) bge_check_acc_handle(bgep, bgep->io_handle); 668 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 669 mutex_exit(bgep->genlock); 670 return (EIO); 671 } 672 #ifdef BGE_IPMI_ASF 673 if (bgep->asf_enabled) { 674 /* 675 * The above bge_chip_sync() function wrote the ethernet MAC 676 * addresses registers which destroyed the IPMI/ASF sideband. 677 * Here, we have to reset chip to make IPMI/ASF sideband work. 678 */ 679 if (bgep->asf_status == ASF_STAT_RUN) { 680 /* 681 * We must stop ASF heart beat before bge_chip_stop(), 682 * otherwise some computers (ex. IBM HS20 blade server) 683 * may crash. 684 */ 685 bge_asf_update_status(bgep); 686 bge_asf_stop_timer(bgep); 687 bgep->asf_status = ASF_STAT_STOP; 688 689 bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET); 690 } 691 bge_chip_stop(bgep, B_FALSE); 692 693 if (bge_restart(bgep, B_FALSE) == DDI_FAILURE) { 694 (void) bge_check_acc_handle(bgep, bgep->cfg_handle); 695 (void) bge_check_acc_handle(bgep, bgep->io_handle); 696 ddi_fm_service_impact(bgep->devinfo, 697 DDI_SERVICE_DEGRADED); 698 mutex_exit(bgep->genlock); 699 return (EIO); 700 } 701 702 /* 703 * Start our ASF heartbeat counter as soon as possible. 704 */ 705 if (bgep->asf_status != ASF_STAT_RUN) { 706 /* start ASF heart beat */ 707 bgep->asf_timeout_id = timeout(bge_asf_heartbeat, 708 (void *)bgep, 709 drv_usectohz(BGE_ASF_HEARTBEAT_INTERVAL)); 710 bgep->asf_status = ASF_STAT_RUN; 711 } 712 } 713 #endif 714 BGE_DEBUG(("bge_unicst_set($%p) done", arg)); 715 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 716 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 717 mutex_exit(bgep->genlock); 718 return (EIO); 719 } 720 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 721 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 722 mutex_exit(bgep->genlock); 723 return (EIO); 724 } 725 mutex_exit(bgep->genlock); 726 727 return (0); 728 } 729 730 extern void bge_wake_factotum(bge_t *); 731 732 static boolean_t 733 bge_param_locked(mac_prop_id_t pr_num) 734 { 735 /* 736 * All adv_* parameters are locked (read-only) while 737 * the device is in any sort of loopback mode ... 738 */ 739 switch (pr_num) { 740 case MAC_PROP_ADV_1000FDX_CAP: 741 case MAC_PROP_EN_1000FDX_CAP: 742 case MAC_PROP_ADV_1000HDX_CAP: 743 case MAC_PROP_EN_1000HDX_CAP: 744 case MAC_PROP_ADV_100FDX_CAP: 745 case MAC_PROP_EN_100FDX_CAP: 746 case MAC_PROP_ADV_100HDX_CAP: 747 case MAC_PROP_EN_100HDX_CAP: 748 case MAC_PROP_ADV_10FDX_CAP: 749 case MAC_PROP_EN_10FDX_CAP: 750 case MAC_PROP_ADV_10HDX_CAP: 751 case MAC_PROP_EN_10HDX_CAP: 752 case MAC_PROP_AUTONEG: 753 case MAC_PROP_FLOWCTRL: 754 return (B_TRUE); 755 } 756 return (B_FALSE); 757 } 758 /* 759 * callback functions for set/get of properties 760 */ 761 static int 762 bge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 763 uint_t pr_valsize, const void *pr_val) 764 { 765 bge_t *bgep = barg; 766 int err = 0; 767 uint32_t cur_mtu, new_mtu; 768 link_flowctrl_t fl; 769 770 mutex_enter(bgep->genlock); 771 if (bgep->param_loop_mode != BGE_LOOP_NONE && 772 bge_param_locked(pr_num)) { 773 /* 774 * All adv_* parameters are locked (read-only) 775 * while the device is in any sort of loopback mode. 776 */ 777 mutex_exit(bgep->genlock); 778 return (EBUSY); 779 } 780 if ((bgep->chipid.flags & CHIP_FLAG_SERDES) && 781 ((pr_num == MAC_PROP_EN_100FDX_CAP) || 782 (pr_num == MAC_PROP_EN_100HDX_CAP) || 783 (pr_num == MAC_PROP_EN_10FDX_CAP) || 784 (pr_num == MAC_PROP_EN_10HDX_CAP))) { 785 /* 786 * these properties are read/write on copper, 787 * read-only and 0 on serdes 788 */ 789 mutex_exit(bgep->genlock); 790 return (ENOTSUP); 791 } 792 if (DEVICE_5906_SERIES_CHIPSETS(bgep) && 793 ((pr_num == MAC_PROP_EN_1000FDX_CAP) || 794 (pr_num == MAC_PROP_EN_1000HDX_CAP))) { 795 mutex_exit(bgep->genlock); 796 return (ENOTSUP); 797 } 798 799 switch (pr_num) { 800 case MAC_PROP_EN_1000FDX_CAP: 801 bgep->param_en_1000fdx = *(uint8_t *)pr_val; 802 bgep->param_adv_1000fdx = *(uint8_t *)pr_val; 803 goto reprogram; 804 case MAC_PROP_EN_1000HDX_CAP: 805 bgep->param_en_1000hdx = *(uint8_t *)pr_val; 806 bgep->param_adv_1000hdx = *(uint8_t *)pr_val; 807 goto reprogram; 808 case MAC_PROP_EN_100FDX_CAP: 809 bgep->param_en_100fdx = *(uint8_t *)pr_val; 810 bgep->param_adv_100fdx = *(uint8_t *)pr_val; 811 goto reprogram; 812 case MAC_PROP_EN_100HDX_CAP: 813 bgep->param_en_100hdx = *(uint8_t *)pr_val; 814 bgep->param_adv_100hdx = *(uint8_t *)pr_val; 815 goto reprogram; 816 case MAC_PROP_EN_10FDX_CAP: 817 bgep->param_en_10fdx = *(uint8_t *)pr_val; 818 bgep->param_adv_10fdx = *(uint8_t *)pr_val; 819 goto reprogram; 820 case MAC_PROP_EN_10HDX_CAP: 821 bgep->param_en_10hdx = *(uint8_t *)pr_val; 822 bgep->param_adv_10hdx = *(uint8_t *)pr_val; 823 reprogram: 824 if (err == 0 && bge_reprogram(bgep) == IOC_INVAL) 825 err = EINVAL; 826 break; 827 case MAC_PROP_ADV_1000FDX_CAP: 828 case MAC_PROP_ADV_1000HDX_CAP: 829 case MAC_PROP_ADV_100FDX_CAP: 830 case MAC_PROP_ADV_100HDX_CAP: 831 case MAC_PROP_ADV_10FDX_CAP: 832 case MAC_PROP_ADV_10HDX_CAP: 833 case MAC_PROP_STATUS: 834 case MAC_PROP_SPEED: 835 case MAC_PROP_DUPLEX: 836 err = ENOTSUP; /* read-only prop. Can't set this */ 837 break; 838 case MAC_PROP_AUTONEG: 839 bgep->param_adv_autoneg = *(uint8_t *)pr_val; 840 if (bge_reprogram(bgep) == IOC_INVAL) 841 err = EINVAL; 842 break; 843 case MAC_PROP_MTU: 844 cur_mtu = bgep->chipid.default_mtu; 845 bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 846 847 if (new_mtu == cur_mtu) { 848 err = 0; 849 break; 850 } 851 if (new_mtu < BGE_DEFAULT_MTU || 852 new_mtu > BGE_MAXIMUM_MTU) { 853 err = EINVAL; 854 break; 855 } 856 if ((new_mtu > BGE_DEFAULT_MTU) && 857 (bgep->chipid.flags & CHIP_FLAG_NO_JUMBO)) { 858 err = EINVAL; 859 break; 860 } 861 if (bgep->bge_mac_state == BGE_MAC_STARTED) { 862 err = EBUSY; 863 break; 864 } 865 bgep->chipid.default_mtu = new_mtu; 866 if (bge_chip_id_init(bgep)) { 867 err = EINVAL; 868 break; 869 } 870 bgep->bge_dma_error = B_TRUE; 871 bgep->manual_reset = B_TRUE; 872 bge_chip_stop(bgep, B_TRUE); 873 bge_wake_factotum(bgep); 874 err = 0; 875 break; 876 case MAC_PROP_FLOWCTRL: 877 bcopy(pr_val, &fl, sizeof (fl)); 878 switch (fl) { 879 default: 880 err = ENOTSUP; 881 break; 882 case LINK_FLOWCTRL_NONE: 883 bgep->param_adv_pause = 0; 884 bgep->param_adv_asym_pause = 0; 885 886 bgep->param_link_rx_pause = B_FALSE; 887 bgep->param_link_tx_pause = B_FALSE; 888 break; 889 case LINK_FLOWCTRL_RX: 890 bgep->param_adv_pause = 1; 891 bgep->param_adv_asym_pause = 1; 892 893 bgep->param_link_rx_pause = B_TRUE; 894 bgep->param_link_tx_pause = B_FALSE; 895 break; 896 case LINK_FLOWCTRL_TX: 897 bgep->param_adv_pause = 0; 898 bgep->param_adv_asym_pause = 1; 899 900 bgep->param_link_rx_pause = B_FALSE; 901 bgep->param_link_tx_pause = B_TRUE; 902 break; 903 case LINK_FLOWCTRL_BI: 904 bgep->param_adv_pause = 1; 905 bgep->param_adv_asym_pause = 0; 906 907 bgep->param_link_rx_pause = B_TRUE; 908 bgep->param_link_tx_pause = B_TRUE; 909 break; 910 } 911 912 if (err == 0) { 913 if (bge_reprogram(bgep) == IOC_INVAL) 914 err = EINVAL; 915 } 916 917 break; 918 case MAC_PROP_PRIVATE: 919 err = bge_set_priv_prop(bgep, pr_name, pr_valsize, 920 pr_val); 921 break; 922 default: 923 err = ENOTSUP; 924 break; 925 } 926 mutex_exit(bgep->genlock); 927 return (err); 928 } 929 930 /* ARGSUSED */ 931 static int 932 bge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 933 uint_t pr_valsize, void *pr_val) 934 { 935 bge_t *bgep = barg; 936 int err = 0; 937 938 switch (pr_num) { 939 case MAC_PROP_DUPLEX: 940 ASSERT(pr_valsize >= sizeof (link_duplex_t)); 941 bcopy(&bgep->param_link_duplex, pr_val, 942 sizeof (link_duplex_t)); 943 break; 944 case MAC_PROP_SPEED: { 945 uint64_t speed = bgep->param_link_speed * 1000000ull; 946 947 ASSERT(pr_valsize >= sizeof (speed)); 948 bcopy(&speed, pr_val, sizeof (speed)); 949 break; 950 } 951 case MAC_PROP_STATUS: 952 ASSERT(pr_valsize >= sizeof (link_state_t)); 953 bcopy(&bgep->link_state, pr_val, 954 sizeof (link_state_t)); 955 break; 956 case MAC_PROP_AUTONEG: 957 *(uint8_t *)pr_val = bgep->param_adv_autoneg; 958 break; 959 case MAC_PROP_FLOWCTRL: { 960 link_flowctrl_t fl; 961 962 ASSERT(pr_valsize >= sizeof (fl)); 963 964 if (bgep->param_link_rx_pause && 965 !bgep->param_link_tx_pause) 966 fl = LINK_FLOWCTRL_RX; 967 968 if (!bgep->param_link_rx_pause && 969 !bgep->param_link_tx_pause) 970 fl = LINK_FLOWCTRL_NONE; 971 972 if (!bgep->param_link_rx_pause && 973 bgep->param_link_tx_pause) 974 fl = LINK_FLOWCTRL_TX; 975 976 if (bgep->param_link_rx_pause && 977 bgep->param_link_tx_pause) 978 fl = LINK_FLOWCTRL_BI; 979 bcopy(&fl, pr_val, sizeof (fl)); 980 break; 981 } 982 case MAC_PROP_ADV_1000FDX_CAP: 983 *(uint8_t *)pr_val = bgep->param_adv_1000fdx; 984 break; 985 case MAC_PROP_EN_1000FDX_CAP: 986 *(uint8_t *)pr_val = bgep->param_en_1000fdx; 987 break; 988 case MAC_PROP_ADV_1000HDX_CAP: 989 *(uint8_t *)pr_val = bgep->param_adv_1000hdx; 990 break; 991 case MAC_PROP_EN_1000HDX_CAP: 992 *(uint8_t *)pr_val = bgep->param_en_1000hdx; 993 break; 994 case MAC_PROP_ADV_100FDX_CAP: 995 *(uint8_t *)pr_val = bgep->param_adv_100fdx; 996 break; 997 case MAC_PROP_EN_100FDX_CAP: 998 *(uint8_t *)pr_val = bgep->param_en_100fdx; 999 break; 1000 case MAC_PROP_ADV_100HDX_CAP: 1001 *(uint8_t *)pr_val = bgep->param_adv_100hdx; 1002 break; 1003 case MAC_PROP_EN_100HDX_CAP: 1004 *(uint8_t *)pr_val = bgep->param_en_100hdx; 1005 break; 1006 case MAC_PROP_ADV_10FDX_CAP: 1007 *(uint8_t *)pr_val = bgep->param_adv_10fdx; 1008 break; 1009 case MAC_PROP_EN_10FDX_CAP: 1010 *(uint8_t *)pr_val = bgep->param_en_10fdx; 1011 break; 1012 case MAC_PROP_ADV_10HDX_CAP: 1013 *(uint8_t *)pr_val = bgep->param_adv_10hdx; 1014 break; 1015 case MAC_PROP_EN_10HDX_CAP: 1016 *(uint8_t *)pr_val = bgep->param_en_10hdx; 1017 break; 1018 case MAC_PROP_ADV_100T4_CAP: 1019 case MAC_PROP_EN_100T4_CAP: 1020 *(uint8_t *)pr_val = 0; 1021 break; 1022 case MAC_PROP_PRIVATE: 1023 err = bge_get_priv_prop(bgep, pr_name, 1024 pr_valsize, pr_val); 1025 return (err); 1026 default: 1027 return (ENOTSUP); 1028 } 1029 return (0); 1030 } 1031 1032 static void 1033 bge_m_propinfo(void *barg, const char *pr_name, mac_prop_id_t pr_num, 1034 mac_prop_info_handle_t prh) 1035 { 1036 bge_t *bgep = barg; 1037 int flags = bgep->chipid.flags; 1038 1039 /* 1040 * By default permissions are read/write unless specified 1041 * otherwise by the driver. 1042 */ 1043 1044 switch (pr_num) { 1045 case MAC_PROP_DUPLEX: 1046 case MAC_PROP_SPEED: 1047 case MAC_PROP_STATUS: 1048 case MAC_PROP_ADV_1000FDX_CAP: 1049 case MAC_PROP_ADV_1000HDX_CAP: 1050 case MAC_PROP_ADV_100FDX_CAP: 1051 case MAC_PROP_ADV_100HDX_CAP: 1052 case MAC_PROP_ADV_10FDX_CAP: 1053 case MAC_PROP_ADV_10HDX_CAP: 1054 case MAC_PROP_ADV_100T4_CAP: 1055 case MAC_PROP_EN_100T4_CAP: 1056 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1057 break; 1058 1059 case MAC_PROP_EN_1000FDX_CAP: 1060 case MAC_PROP_EN_1000HDX_CAP: 1061 if (DEVICE_5906_SERIES_CHIPSETS(bgep)) 1062 mac_prop_info_set_default_uint8(prh, 0); 1063 else 1064 mac_prop_info_set_default_uint8(prh, 1); 1065 break; 1066 1067 case MAC_PROP_EN_100FDX_CAP: 1068 case MAC_PROP_EN_100HDX_CAP: 1069 case MAC_PROP_EN_10FDX_CAP: 1070 case MAC_PROP_EN_10HDX_CAP: 1071 mac_prop_info_set_default_uint8(prh, 1072 (flags & CHIP_FLAG_SERDES) ? 0 : 1); 1073 break; 1074 1075 case MAC_PROP_AUTONEG: 1076 mac_prop_info_set_default_uint8(prh, 1); 1077 break; 1078 1079 case MAC_PROP_FLOWCTRL: 1080 mac_prop_info_set_default_link_flowctrl(prh, 1081 LINK_FLOWCTRL_BI); 1082 break; 1083 1084 case MAC_PROP_MTU: 1085 mac_prop_info_set_range_uint32(prh, BGE_DEFAULT_MTU, 1086 (flags & CHIP_FLAG_NO_JUMBO) ? 1087 BGE_DEFAULT_MTU : BGE_MAXIMUM_MTU); 1088 break; 1089 1090 case MAC_PROP_PRIVATE: 1091 bge_priv_propinfo(pr_name, prh); 1092 break; 1093 } 1094 1095 mutex_enter(bgep->genlock); 1096 if ((bgep->param_loop_mode != BGE_LOOP_NONE && 1097 bge_param_locked(pr_num)) || 1098 ((bgep->chipid.flags & CHIP_FLAG_SERDES) && 1099 ((pr_num == MAC_PROP_EN_100FDX_CAP) || 1100 (pr_num == MAC_PROP_EN_100HDX_CAP) || 1101 (pr_num == MAC_PROP_EN_10FDX_CAP) || 1102 (pr_num == MAC_PROP_EN_10HDX_CAP))) || 1103 (DEVICE_5906_SERIES_CHIPSETS(bgep) && 1104 ((pr_num == MAC_PROP_EN_1000FDX_CAP) || 1105 (pr_num == MAC_PROP_EN_1000HDX_CAP)))) 1106 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1107 mutex_exit(bgep->genlock); 1108 } 1109 1110 /* ARGSUSED */ 1111 static int 1112 bge_set_priv_prop(bge_t *bgep, const char *pr_name, uint_t pr_valsize, 1113 const void *pr_val) 1114 { 1115 int err = 0; 1116 long result; 1117 1118 if (strcmp(pr_name, "_adv_pause_cap") == 0) { 1119 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1120 if (result > 1 || result < 0) { 1121 err = EINVAL; 1122 } else { 1123 bgep->param_adv_pause = (uint32_t)result; 1124 if (bge_reprogram(bgep) == IOC_INVAL) 1125 err = EINVAL; 1126 } 1127 return (err); 1128 } 1129 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 1130 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1131 if (result > 1 || result < 0) { 1132 err = EINVAL; 1133 } else { 1134 bgep->param_adv_asym_pause = (uint32_t)result; 1135 if (bge_reprogram(bgep) == IOC_INVAL) 1136 err = EINVAL; 1137 } 1138 return (err); 1139 } 1140 if (strcmp(pr_name, "_drain_max") == 0) { 1141 1142 /* 1143 * on the Tx side, we need to update the h/w register for 1144 * real packet transmission per packet. The drain_max parameter 1145 * is used to reduce the register access. This parameter 1146 * controls the max number of packets that we will hold before 1147 * updating the bge h/w to trigger h/w transmit. The bge 1148 * chipset usually has a max of 512 Tx descriptors, thus 1149 * the upper bound on drain_max is 512. 1150 */ 1151 if (pr_val == NULL) { 1152 err = EINVAL; 1153 return (err); 1154 } 1155 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1156 if (result > 512 || result < 1) 1157 err = EINVAL; 1158 else { 1159 bgep->param_drain_max = (uint32_t)result; 1160 if (bge_reprogram(bgep) == IOC_INVAL) 1161 err = EINVAL; 1162 } 1163 return (err); 1164 } 1165 if (strcmp(pr_name, "_msi_cnt") == 0) { 1166 1167 if (pr_val == NULL) { 1168 err = EINVAL; 1169 return (err); 1170 } 1171 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1172 if (result > 7 || result < 0) 1173 err = EINVAL; 1174 else { 1175 bgep->param_msi_cnt = (uint32_t)result; 1176 if (bge_reprogram(bgep) == IOC_INVAL) 1177 err = EINVAL; 1178 } 1179 return (err); 1180 } 1181 if (strcmp(pr_name, "_rx_intr_coalesce_blank_time") == 0) { 1182 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0) 1183 return (EINVAL); 1184 if (result < 0) 1185 err = EINVAL; 1186 else { 1187 bgep->chipid.rx_ticks_norm = (uint32_t)result; 1188 bge_chip_coalesce_update(bgep); 1189 } 1190 return (err); 1191 } 1192 1193 if (strcmp(pr_name, "_rx_intr_coalesce_pkt_cnt") == 0) { 1194 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0) 1195 return (EINVAL); 1196 1197 if (result < 0) 1198 err = EINVAL; 1199 else { 1200 bgep->chipid.rx_count_norm = (uint32_t)result; 1201 bge_chip_coalesce_update(bgep); 1202 } 1203 return (err); 1204 } 1205 if (strcmp(pr_name, "_tx_intr_coalesce_blank_time") == 0) { 1206 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0) 1207 return (EINVAL); 1208 if (result < 0) 1209 err = EINVAL; 1210 else { 1211 bgep->chipid.tx_ticks_norm = (uint32_t)result; 1212 bge_chip_coalesce_update(bgep); 1213 } 1214 return (err); 1215 } 1216 1217 if (strcmp(pr_name, "_tx_intr_coalesce_pkt_cnt") == 0) { 1218 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0) 1219 return (EINVAL); 1220 1221 if (result < 0) 1222 err = EINVAL; 1223 else { 1224 bgep->chipid.tx_count_norm = (uint32_t)result; 1225 bge_chip_coalesce_update(bgep); 1226 } 1227 return (err); 1228 } 1229 return (ENOTSUP); 1230 } 1231 1232 static int 1233 bge_get_priv_prop(bge_t *bge, const char *pr_name, uint_t pr_valsize, 1234 void *pr_val) 1235 { 1236 int value; 1237 1238 if (strcmp(pr_name, "_adv_pause_cap") == 0) 1239 value = bge->param_adv_pause; 1240 else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) 1241 value = bge->param_adv_asym_pause; 1242 else if (strcmp(pr_name, "_drain_max") == 0) 1243 value = bge->param_drain_max; 1244 else if (strcmp(pr_name, "_msi_cnt") == 0) 1245 value = bge->param_msi_cnt; 1246 else if (strcmp(pr_name, "_rx_intr_coalesce_blank_time") == 0) 1247 value = bge->chipid.rx_ticks_norm; 1248 else if (strcmp(pr_name, "_tx_intr_coalesce_blank_time") == 0) 1249 value = bge->chipid.tx_ticks_norm; 1250 else if (strcmp(pr_name, "_rx_intr_coalesce_pkt_cnt") == 0) 1251 value = bge->chipid.rx_count_norm; 1252 else if (strcmp(pr_name, "_tx_intr_coalesce_pkt_cnt") == 0) 1253 value = bge->chipid.tx_count_norm; 1254 else 1255 return (ENOTSUP); 1256 1257 (void) snprintf(pr_val, pr_valsize, "%d", value); 1258 return (0); 1259 } 1260 1261 static void 1262 bge_priv_propinfo(const char *pr_name, mac_prop_info_handle_t mph) 1263 { 1264 char valstr[64]; 1265 int value; 1266 1267 if (strcmp(pr_name, "_adv_pause_cap") == 0) 1268 value = 1; 1269 else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) 1270 value = 1; 1271 else if (strcmp(pr_name, "_drain_max") == 0) 1272 value = 64; 1273 else if (strcmp(pr_name, "_msi_cnt") == 0) 1274 value = 0; 1275 else if (strcmp(pr_name, "_rx_intr_coalesce_blank_time") == 0) 1276 value = bge_rx_ticks_norm; 1277 else if (strcmp(pr_name, "_tx_intr_coalesce_blank_time") == 0) 1278 value = bge_tx_ticks_norm; 1279 else if (strcmp(pr_name, "_rx_intr_coalesce_pkt_cnt") == 0) 1280 value = bge_rx_count_norm; 1281 else if (strcmp(pr_name, "_tx_intr_coalesce_pkt_cnt") == 0) 1282 value = bge_tx_count_norm; 1283 else 1284 return; 1285 1286 (void) snprintf(valstr, sizeof (valstr), "%d", value); 1287 mac_prop_info_set_default_str(mph, valstr); 1288 } 1289 1290 1291 static int 1292 bge_m_unicst(void * arg, const uint8_t * mac_addr) 1293 { 1294 bge_t *bgep = arg; 1295 int i; 1296 1297 /* XXX sets the mac address for all ring slots... OK? */ 1298 for (i = 0; i < MIN(bgep->chipid.rx_rings, MAC_ADDRESS_REGS_MAX); i++) 1299 bge_addmac(&bgep->recv[i], mac_addr); 1300 1301 return (0); 1302 } 1303 1304 1305 /* 1306 * Compute the index of the required bit in the multicast hash map. 1307 * This must mirror the way the hardware actually does it! 1308 * See Broadcom document 570X-PG102-R page 125. 1309 */ 1310 static uint32_t 1311 bge_hash_index(const uint8_t *mca) 1312 { 1313 uint32_t hash; 1314 1315 CRC32(hash, mca, ETHERADDRL, -1U, crc32_table); 1316 1317 return (hash); 1318 } 1319 1320 /* 1321 * bge_m_multicst_add() -- enable/disable a multicast address 1322 */ 1323 static int 1324 bge_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 1325 { 1326 bge_t *bgep = arg; /* private device info */ 1327 uint32_t hash; 1328 uint32_t index; 1329 uint32_t word; 1330 uint32_t bit; 1331 uint8_t *refp; 1332 1333 BGE_TRACE(("bge_m_multicst($%p, %s, %s)", arg, 1334 (add) ? "add" : "remove", ether_sprintf((void *)mca))); 1335 1336 /* 1337 * Precalculate all required masks, pointers etc ... 1338 */ 1339 hash = bge_hash_index(mca); 1340 index = hash % BGE_HASH_TABLE_SIZE; 1341 word = index/32u; 1342 bit = 1 << (index % 32u); 1343 refp = &bgep->mcast_refs[index]; 1344 1345 BGE_DEBUG(("bge_m_multicst: hash 0x%x index %d (%d:0x%x) = %d", 1346 hash, index, word, bit, *refp)); 1347 1348 /* 1349 * We must set the appropriate bit in the hash map (and the 1350 * corresponding h/w register) when the refcount goes from 0 1351 * to >0, and clear it when the last ref goes away (refcount 1352 * goes from >0 back to 0). If we change the hash map, we 1353 * must also update the chip's hardware map registers. 1354 */ 1355 mutex_enter(bgep->genlock); 1356 if (!(bgep->progress & PROGRESS_INTR)) { 1357 /* can happen during autorecovery */ 1358 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 1359 mutex_exit(bgep->genlock); 1360 return (EIO); 1361 } 1362 if (add) { 1363 if ((*refp)++ == 0) { 1364 bgep->mcast_hash[word] |= bit; 1365 #ifdef BGE_IPMI_ASF 1366 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) { 1367 #else 1368 if (bge_chip_sync(bgep) == DDI_FAILURE) { 1369 #endif 1370 (void) bge_check_acc_handle(bgep, 1371 bgep->cfg_handle); 1372 (void) bge_check_acc_handle(bgep, 1373 bgep->io_handle); 1374 ddi_fm_service_impact(bgep->devinfo, 1375 DDI_SERVICE_DEGRADED); 1376 mutex_exit(bgep->genlock); 1377 return (EIO); 1378 } 1379 } 1380 } else { 1381 if (--(*refp) == 0) { 1382 bgep->mcast_hash[word] &= ~bit; 1383 #ifdef BGE_IPMI_ASF 1384 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) { 1385 #else 1386 if (bge_chip_sync(bgep) == DDI_FAILURE) { 1387 #endif 1388 (void) bge_check_acc_handle(bgep, 1389 bgep->cfg_handle); 1390 (void) bge_check_acc_handle(bgep, 1391 bgep->io_handle); 1392 ddi_fm_service_impact(bgep->devinfo, 1393 DDI_SERVICE_DEGRADED); 1394 mutex_exit(bgep->genlock); 1395 return (EIO); 1396 } 1397 } 1398 } 1399 BGE_DEBUG(("bge_m_multicst($%p) done", arg)); 1400 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 1401 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 1402 mutex_exit(bgep->genlock); 1403 return (EIO); 1404 } 1405 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 1406 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 1407 mutex_exit(bgep->genlock); 1408 return (EIO); 1409 } 1410 mutex_exit(bgep->genlock); 1411 1412 return (0); 1413 } 1414 1415 /* 1416 * bge_m_promisc() -- set or reset promiscuous mode on the board 1417 * 1418 * Program the hardware to enable/disable promiscuous and/or 1419 * receive-all-multicast modes. 1420 */ 1421 static int 1422 bge_m_promisc(void *arg, boolean_t on) 1423 { 1424 bge_t *bgep = arg; 1425 1426 BGE_TRACE(("bge_m_promisc_set($%p, %d)", arg, on)); 1427 1428 /* 1429 * Store MAC layer specified mode and pass to chip layer to update h/w 1430 */ 1431 mutex_enter(bgep->genlock); 1432 if (!(bgep->progress & PROGRESS_INTR)) { 1433 /* can happen during autorecovery */ 1434 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 1435 mutex_exit(bgep->genlock); 1436 return (EIO); 1437 } 1438 bgep->promisc = on; 1439 #ifdef BGE_IPMI_ASF 1440 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) { 1441 #else 1442 if (bge_chip_sync(bgep) == DDI_FAILURE) { 1443 #endif 1444 (void) bge_check_acc_handle(bgep, bgep->cfg_handle); 1445 (void) bge_check_acc_handle(bgep, bgep->io_handle); 1446 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 1447 mutex_exit(bgep->genlock); 1448 return (EIO); 1449 } 1450 BGE_DEBUG(("bge_m_promisc_set($%p) done", arg)); 1451 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 1452 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 1453 mutex_exit(bgep->genlock); 1454 return (EIO); 1455 } 1456 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 1457 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 1458 mutex_exit(bgep->genlock); 1459 return (EIO); 1460 } 1461 mutex_exit(bgep->genlock); 1462 return (0); 1463 } 1464 1465 #ifdef MC_RESOURCES 1466 1467 static void 1468 bge_blank(void * arg, time_t tick_cnt, uint_t pkt_cnt) 1469 { 1470 (void)arg; 1471 (void)tick_cnt; 1472 (void)pkt_cnt; 1473 } 1474 1475 static void 1476 bge_m_resources(void * arg) 1477 { 1478 bge_t *bgep = arg; 1479 mac_rx_fifo_t mrf; 1480 int i; 1481 1482 mrf.mrf_type = MAC_RX_FIFO; 1483 mrf.mrf_blank = bge_blank; 1484 mrf.mrf_arg = (void *)bgep; 1485 mrf.mrf_normal_blank_time = 25; 1486 mrf.mrf_normal_pkt_count = 8; 1487 1488 for (i = 0; i < BGE_RECV_RINGS_MAX; i++) { 1489 bgep->macRxResourceHandles[i] = 1490 mac_resource_add(bgep->mh, (mac_resource_t *)&mrf); 1491 } 1492 } 1493 1494 #endif /* MC_RESOURCES */ 1495 1496 /* 1497 * Find the slot for the specified unicast address 1498 */ 1499 int 1500 bge_unicst_find(bge_t *bgep, const uint8_t *mac_addr) 1501 { 1502 int slot; 1503 1504 ASSERT(mutex_owned(bgep->genlock)); 1505 1506 for (slot = 0; slot < bgep->unicst_addr_total; slot++) { 1507 if (bcmp(bgep->curr_addr[slot].addr, mac_addr, ETHERADDRL) == 0) 1508 return (slot); 1509 } 1510 1511 return (-1); 1512 } 1513 1514 /* 1515 * Programs the classifier to start steering packets matching 'mac_addr' to the 1516 * specified ring 'arg'. 1517 */ 1518 static int 1519 bge_addmac(void *arg, const uint8_t * mac_addr) 1520 { 1521 recv_ring_t *rrp = (recv_ring_t *)arg; 1522 bge_t *bgep = rrp->bgep; 1523 bge_recv_rule_t *rulep = bgep->recv_rules; 1524 bge_rule_info_t *rinfop = NULL; 1525 uint8_t ring = (uint8_t)(rrp - bgep->recv) + 1; 1526 int i; 1527 uint16_t tmp16; 1528 uint32_t tmp32; 1529 int slot; 1530 int err; 1531 1532 mutex_enter(bgep->genlock); 1533 if (bgep->unicst_addr_avail == 0) { 1534 mutex_exit(bgep->genlock); 1535 return (ENOSPC); 1536 } 1537 1538 /* 1539 * First add the unicast address to a available slot. 1540 */ 1541 slot = bge_unicst_find(bgep, mac_addr); 1542 ASSERT(slot == -1); 1543 1544 for (slot = 0; slot < bgep->unicst_addr_total; slot++) { 1545 if (!bgep->curr_addr[slot].set) { 1546 bgep->curr_addr[slot].set = B_TRUE; 1547 break; 1548 } 1549 } 1550 1551 ASSERT(slot < bgep->unicst_addr_total); 1552 bgep->unicst_addr_avail--; 1553 mutex_exit(bgep->genlock); 1554 1555 if ((err = bge_unicst_set(bgep, mac_addr, slot)) != 0) 1556 goto fail; 1557 1558 /* A rule is already here. Deny this. */ 1559 if (rrp->mac_addr_rule != NULL) { 1560 err = ether_cmp(mac_addr, rrp->mac_addr_val) ? EEXIST : EBUSY; 1561 goto fail; 1562 } 1563 1564 /* 1565 * Allocate a bge_rule_info_t to keep track of which rule slots 1566 * are being used. 1567 */ 1568 rinfop = kmem_zalloc(sizeof (bge_rule_info_t), KM_NOSLEEP); 1569 if (rinfop == NULL) { 1570 err = ENOMEM; 1571 goto fail; 1572 } 1573 1574 /* 1575 * Look for the starting slot to place the rules. 1576 * The two slots we reserve must be contiguous. 1577 */ 1578 for (i = 0; i + 1 < RECV_RULES_NUM_MAX; i++) 1579 if ((rulep[i].control & RECV_RULE_CTL_ENABLE) == 0 && 1580 (rulep[i+1].control & RECV_RULE_CTL_ENABLE) == 0) 1581 break; 1582 1583 ASSERT(i + 1 < RECV_RULES_NUM_MAX); 1584 1585 bcopy(mac_addr, &tmp32, sizeof (tmp32)); 1586 rulep[i].mask_value = ntohl(tmp32); 1587 rulep[i].control = RULE_DEST_MAC_1(ring) | RECV_RULE_CTL_AND; 1588 bge_reg_put32(bgep, RECV_RULE_MASK_REG(i), rulep[i].mask_value); 1589 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(i), rulep[i].control); 1590 1591 bcopy(mac_addr + 4, &tmp16, sizeof (tmp16)); 1592 rulep[i+1].mask_value = 0xffff0000 | ntohs(tmp16); 1593 rulep[i+1].control = RULE_DEST_MAC_2(ring); 1594 bge_reg_put32(bgep, RECV_RULE_MASK_REG(i+1), rulep[i+1].mask_value); 1595 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(i+1), rulep[i+1].control); 1596 rinfop->start = i; 1597 rinfop->count = 2; 1598 1599 rrp->mac_addr_rule = rinfop; 1600 bcopy(mac_addr, rrp->mac_addr_val, ETHERADDRL); 1601 1602 return (0); 1603 1604 fail: 1605 /* Clear the address just set */ 1606 (void) bge_unicst_set(bgep, zero_addr, slot); 1607 mutex_enter(bgep->genlock); 1608 bgep->curr_addr[slot].set = B_FALSE; 1609 bgep->unicst_addr_avail++; 1610 mutex_exit(bgep->genlock); 1611 1612 return (err); 1613 } 1614 1615 /* 1616 * Stop classifying packets matching the MAC address to the specified ring. 1617 */ 1618 static int 1619 bge_remmac(void *arg, const uint8_t *mac_addr) 1620 { 1621 recv_ring_t *rrp = (recv_ring_t *)arg; 1622 bge_t *bgep = rrp->bgep; 1623 bge_recv_rule_t *rulep = bgep->recv_rules; 1624 bge_rule_info_t *rinfop = rrp->mac_addr_rule; 1625 int start; 1626 int slot; 1627 int err; 1628 1629 /* 1630 * Remove the MAC address from its slot. 1631 */ 1632 mutex_enter(bgep->genlock); 1633 slot = bge_unicst_find(bgep, mac_addr); 1634 if (slot == -1) { 1635 mutex_exit(bgep->genlock); 1636 return (EINVAL); 1637 } 1638 1639 ASSERT(bgep->curr_addr[slot].set); 1640 mutex_exit(bgep->genlock); 1641 1642 if ((err = bge_unicst_set(bgep, zero_addr, slot)) != 0) 1643 return (err); 1644 1645 if (rinfop == NULL || ether_cmp(mac_addr, rrp->mac_addr_val) != 0) 1646 return (EINVAL); 1647 1648 start = rinfop->start; 1649 rulep[start].mask_value = 0; 1650 rulep[start].control = 0; 1651 bge_reg_put32(bgep, RECV_RULE_MASK_REG(start), rulep[start].mask_value); 1652 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(start), rulep[start].control); 1653 start++; 1654 rulep[start].mask_value = 0; 1655 rulep[start].control = 0; 1656 bge_reg_put32(bgep, RECV_RULE_MASK_REG(start), rulep[start].mask_value); 1657 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(start), rulep[start].control); 1658 1659 kmem_free(rinfop, sizeof (bge_rule_info_t)); 1660 rrp->mac_addr_rule = NULL; 1661 bzero(rrp->mac_addr_val, ETHERADDRL); 1662 1663 mutex_enter(bgep->genlock); 1664 bgep->curr_addr[slot].set = B_FALSE; 1665 bgep->unicst_addr_avail++; 1666 mutex_exit(bgep->genlock); 1667 1668 return (0); 1669 } 1670 1671 1672 static int 1673 bge_flag_intr_enable(mac_ring_driver_t ih) 1674 { 1675 recv_ring_t *rrp = (recv_ring_t *)ih; 1676 bge_t *bgep = rrp->bgep; 1677 1678 mutex_enter(bgep->genlock); 1679 rrp->poll_flag = 0; 1680 mutex_exit(bgep->genlock); 1681 1682 return (0); 1683 } 1684 1685 static int 1686 bge_flag_intr_disable(mac_ring_driver_t ih) 1687 { 1688 recv_ring_t *rrp = (recv_ring_t *)ih; 1689 bge_t *bgep = rrp->bgep; 1690 1691 mutex_enter(bgep->genlock); 1692 rrp->poll_flag = 1; 1693 mutex_exit(bgep->genlock); 1694 1695 return (0); 1696 } 1697 1698 static int 1699 bge_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num) 1700 { 1701 recv_ring_t *rx_ring; 1702 1703 rx_ring = (recv_ring_t *)rh; 1704 mutex_enter(rx_ring->rx_lock); 1705 rx_ring->ring_gen_num = mr_gen_num; 1706 mutex_exit(rx_ring->rx_lock); 1707 return (0); 1708 } 1709 1710 1711 /* 1712 * Callback funtion for MAC layer to register all rings 1713 * for given ring_group, noted by rg_index. 1714 */ 1715 void 1716 bge_fill_ring(void *arg, mac_ring_type_t rtype, const int rg_index, 1717 const int index, mac_ring_info_t *infop, mac_ring_handle_t rh) 1718 { 1719 bge_t *bgep = arg; 1720 mac_intr_t *mintr; 1721 1722 switch (rtype) { 1723 case MAC_RING_TYPE_RX: { 1724 recv_ring_t *rx_ring; 1725 ASSERT(rg_index >= 0 && rg_index < MIN(bgep->chipid.rx_rings, 1726 MAC_ADDRESS_REGS_MAX) && index == 0); 1727 1728 rx_ring = &bgep->recv[rg_index]; 1729 rx_ring->ring_handle = rh; 1730 1731 infop->mri_driver = (mac_ring_driver_t)rx_ring; 1732 infop->mri_start = bge_ring_start; 1733 infop->mri_stop = NULL; 1734 infop->mri_poll = bge_poll_ring; 1735 infop->mri_stat = bge_rx_ring_stat; 1736 1737 mintr = &infop->mri_intr; 1738 mintr->mi_enable = (mac_intr_enable_t)bge_flag_intr_enable; 1739 mintr->mi_disable = (mac_intr_disable_t)bge_flag_intr_disable; 1740 1741 break; 1742 } 1743 case MAC_RING_TYPE_TX: 1744 default: 1745 ASSERT(0); 1746 break; 1747 } 1748 } 1749 1750 /* 1751 * Fill infop passed as argument 1752 * fill in respective ring_group info 1753 * Each group has a single ring in it. We keep it simple 1754 * and use the same internal handle for rings and groups. 1755 */ 1756 void 1757 bge_fill_group(void *arg, mac_ring_type_t rtype, const int rg_index, 1758 mac_group_info_t * infop, mac_group_handle_t gh) 1759 { 1760 bge_t *bgep = arg; 1761 1762 switch (rtype) { 1763 case MAC_RING_TYPE_RX: { 1764 recv_ring_t *rx_ring; 1765 1766 ASSERT(rg_index >= 0 && rg_index < MIN(bgep->chipid.rx_rings, 1767 MAC_ADDRESS_REGS_MAX)); 1768 rx_ring = &bgep->recv[rg_index]; 1769 rx_ring->ring_group_handle = gh; 1770 1771 infop->mgi_driver = (mac_group_driver_t)rx_ring; 1772 infop->mgi_start = NULL; 1773 infop->mgi_stop = NULL; 1774 infop->mgi_addmac = bge_addmac; 1775 infop->mgi_remmac = bge_remmac; 1776 infop->mgi_count = 1; 1777 break; 1778 } 1779 case MAC_RING_TYPE_TX: 1780 default: 1781 ASSERT(0); 1782 break; 1783 } 1784 } 1785 1786 1787 /*ARGSUSED*/ 1788 static boolean_t 1789 bge_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 1790 { 1791 bge_t *bgep = arg; 1792 mac_capab_rings_t *cap_rings; 1793 1794 switch (cap) { 1795 case MAC_CAPAB_HCKSUM: { 1796 uint32_t *txflags = cap_data; 1797 1798 *txflags = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM; 1799 break; 1800 } 1801 1802 case MAC_CAPAB_RINGS: 1803 cap_rings = (mac_capab_rings_t *)cap_data; 1804 1805 /* Temporarily disable multiple tx rings. */ 1806 if (cap_rings->mr_type != MAC_RING_TYPE_RX) 1807 return (B_FALSE); 1808 1809 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 1810 cap_rings->mr_rnum = 1811 cap_rings->mr_gnum = 1812 MIN(bgep->chipid.rx_rings, MAC_ADDRESS_REGS_MAX); 1813 cap_rings->mr_rget = bge_fill_ring; 1814 cap_rings->mr_gget = bge_fill_group; 1815 break; 1816 1817 default: 1818 return (B_FALSE); 1819 } 1820 return (B_TRUE); 1821 } 1822 1823 #ifdef NOT_SUPPORTED_XXX 1824 1825 /* 1826 * Loopback ioctl code 1827 */ 1828 1829 static lb_property_t loopmodes[] = { 1830 { normal, "normal", BGE_LOOP_NONE }, 1831 { external, "1000Mbps", BGE_LOOP_EXTERNAL_1000 }, 1832 { external, "100Mbps", BGE_LOOP_EXTERNAL_100 }, 1833 { external, "10Mbps", BGE_LOOP_EXTERNAL_10 }, 1834 { internal, "PHY", BGE_LOOP_INTERNAL_PHY }, 1835 { internal, "MAC", BGE_LOOP_INTERNAL_MAC } 1836 }; 1837 1838 static enum ioc_reply 1839 bge_set_loop_mode(bge_t *bgep, uint32_t mode) 1840 { 1841 /* 1842 * If the mode isn't being changed, there's nothing to do ... 1843 */ 1844 if (mode == bgep->param_loop_mode) 1845 return (IOC_ACK); 1846 1847 /* 1848 * Validate the requested mode and prepare a suitable message 1849 * to explain the link down/up cycle that the change will 1850 * probably induce ... 1851 */ 1852 switch (mode) { 1853 default: 1854 return (IOC_INVAL); 1855 1856 case BGE_LOOP_NONE: 1857 case BGE_LOOP_EXTERNAL_1000: 1858 case BGE_LOOP_EXTERNAL_100: 1859 case BGE_LOOP_EXTERNAL_10: 1860 case BGE_LOOP_INTERNAL_PHY: 1861 case BGE_LOOP_INTERNAL_MAC: 1862 break; 1863 } 1864 1865 /* 1866 * All OK; tell the caller to reprogram 1867 * the PHY and/or MAC for the new mode ... 1868 */ 1869 bgep->param_loop_mode = mode; 1870 return (IOC_RESTART_ACK); 1871 } 1872 1873 static enum ioc_reply 1874 bge_loop_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp) 1875 { 1876 lb_info_sz_t *lbsp; 1877 lb_property_t *lbpp; 1878 uint32_t *lbmp; 1879 int cmd; 1880 1881 _NOTE(ARGUNUSED(wq)) 1882 1883 /* 1884 * Validate format of ioctl 1885 */ 1886 if (mp->b_cont == NULL) 1887 return (IOC_INVAL); 1888 1889 cmd = iocp->ioc_cmd; 1890 switch (cmd) { 1891 default: 1892 /* NOTREACHED */ 1893 bge_error(bgep, "bge_loop_ioctl: invalid cmd 0x%x", cmd); 1894 return (IOC_INVAL); 1895 1896 case LB_GET_INFO_SIZE: 1897 if (iocp->ioc_count != sizeof (lb_info_sz_t)) 1898 return (IOC_INVAL); 1899 lbsp = (void *)mp->b_cont->b_rptr; 1900 *lbsp = sizeof (loopmodes); 1901 return (IOC_REPLY); 1902 1903 case LB_GET_INFO: 1904 if (iocp->ioc_count != sizeof (loopmodes)) 1905 return (IOC_INVAL); 1906 lbpp = (void *)mp->b_cont->b_rptr; 1907 bcopy(loopmodes, lbpp, sizeof (loopmodes)); 1908 return (IOC_REPLY); 1909 1910 case LB_GET_MODE: 1911 if (iocp->ioc_count != sizeof (uint32_t)) 1912 return (IOC_INVAL); 1913 lbmp = (void *)mp->b_cont->b_rptr; 1914 *lbmp = bgep->param_loop_mode; 1915 return (IOC_REPLY); 1916 1917 case LB_SET_MODE: 1918 if (iocp->ioc_count != sizeof (uint32_t)) 1919 return (IOC_INVAL); 1920 lbmp = (void *)mp->b_cont->b_rptr; 1921 return (bge_set_loop_mode(bgep, *lbmp)); 1922 } 1923 } 1924 1925 #endif /* NOT_SUPPORTED_XXX */ 1926 1927 /* 1928 * Specific bge IOCTLs, the gld module handles the generic ones. 1929 */ 1930 static void 1931 bge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 1932 { 1933 bge_t *bgep = arg; 1934 struct iocblk *iocp; 1935 enum ioc_reply status; 1936 boolean_t need_privilege; 1937 int err; 1938 int cmd; 1939 1940 /* 1941 * Validate the command before bothering with the mutex ... 1942 */ 1943 iocp = (void *)mp->b_rptr; 1944 iocp->ioc_error = 0; 1945 need_privilege = B_TRUE; 1946 cmd = iocp->ioc_cmd; 1947 switch (cmd) { 1948 default: 1949 miocnak(wq, mp, 0, EINVAL); 1950 return; 1951 1952 case BGE_MII_READ: 1953 case BGE_MII_WRITE: 1954 case BGE_SEE_READ: 1955 case BGE_SEE_WRITE: 1956 case BGE_FLASH_READ: 1957 case BGE_FLASH_WRITE: 1958 case BGE_DIAG: 1959 case BGE_PEEK: 1960 case BGE_POKE: 1961 case BGE_PHY_RESET: 1962 case BGE_SOFT_RESET: 1963 case BGE_HARD_RESET: 1964 break; 1965 1966 #ifdef NOT_SUPPORTED_XXX 1967 case LB_GET_INFO_SIZE: 1968 case LB_GET_INFO: 1969 case LB_GET_MODE: 1970 need_privilege = B_FALSE; 1971 /* FALLTHRU */ 1972 case LB_SET_MODE: 1973 break; 1974 #endif 1975 1976 } 1977 1978 if (need_privilege) { 1979 /* 1980 * Check for specific net_config privilege on Solaris 10+. 1981 */ 1982 err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 1983 if (err != 0) { 1984 miocnak(wq, mp, 0, err); 1985 return; 1986 } 1987 } 1988 1989 mutex_enter(bgep->genlock); 1990 if (!(bgep->progress & PROGRESS_INTR)) { 1991 /* can happen during autorecovery */ 1992 mutex_exit(bgep->genlock); 1993 miocnak(wq, mp, 0, EIO); 1994 return; 1995 } 1996 1997 switch (cmd) { 1998 default: 1999 _NOTE(NOTREACHED) 2000 status = IOC_INVAL; 2001 break; 2002 2003 case BGE_MII_READ: 2004 case BGE_MII_WRITE: 2005 case BGE_SEE_READ: 2006 case BGE_SEE_WRITE: 2007 case BGE_FLASH_READ: 2008 case BGE_FLASH_WRITE: 2009 case BGE_DIAG: 2010 case BGE_PEEK: 2011 case BGE_POKE: 2012 case BGE_PHY_RESET: 2013 case BGE_SOFT_RESET: 2014 case BGE_HARD_RESET: 2015 status = bge_chip_ioctl(bgep, wq, mp, iocp); 2016 break; 2017 2018 #ifdef NOT_SUPPORTED_XXX 2019 case LB_GET_INFO_SIZE: 2020 case LB_GET_INFO: 2021 case LB_GET_MODE: 2022 case LB_SET_MODE: 2023 status = bge_loop_ioctl(bgep, wq, mp, iocp); 2024 break; 2025 #endif 2026 2027 } 2028 2029 /* 2030 * Do we need to reprogram the PHY and/or the MAC? 2031 * Do it now, while we still have the mutex. 2032 * 2033 * Note: update the PHY first, 'cos it controls the 2034 * speed/duplex parameters that the MAC code uses. 2035 */ 2036 switch (status) { 2037 case IOC_RESTART_REPLY: 2038 case IOC_RESTART_ACK: 2039 if (bge_reprogram(bgep) == IOC_INVAL) 2040 status = IOC_INVAL; 2041 break; 2042 } 2043 2044 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 2045 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 2046 status = IOC_INVAL; 2047 } 2048 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 2049 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 2050 status = IOC_INVAL; 2051 } 2052 mutex_exit(bgep->genlock); 2053 2054 /* 2055 * Finally, decide how to reply 2056 */ 2057 switch (status) { 2058 default: 2059 case IOC_INVAL: 2060 /* 2061 * Error, reply with a NAK and EINVAL or the specified error 2062 */ 2063 miocnak(wq, mp, 0, iocp->ioc_error == 0 ? 2064 EINVAL : iocp->ioc_error); 2065 break; 2066 2067 case IOC_DONE: 2068 /* 2069 * OK, reply already sent 2070 */ 2071 break; 2072 2073 case IOC_RESTART_ACK: 2074 case IOC_ACK: 2075 /* 2076 * OK, reply with an ACK 2077 */ 2078 miocack(wq, mp, 0, 0); 2079 break; 2080 2081 case IOC_RESTART_REPLY: 2082 case IOC_REPLY: 2083 /* 2084 * OK, send prepared reply as ACK or NAK 2085 */ 2086 mp->b_datap->db_type = iocp->ioc_error == 0 ? 2087 M_IOCACK : M_IOCNAK; 2088 qreply(wq, mp); 2089 break; 2090 } 2091 } 2092 2093 /* 2094 * ========== Per-instance setup/teardown code ========== 2095 */ 2096 2097 #undef BGE_DBG 2098 #define BGE_DBG BGE_DBG_MEM /* debug flag for this code */ 2099 /* 2100 * Allocate an area of memory and a DMA handle for accessing it 2101 */ 2102 static int 2103 bge_alloc_dma_mem(bge_t *bgep, size_t memsize, ddi_device_acc_attr_t *attr_p, 2104 uint_t dma_flags, dma_area_t *dma_p) 2105 { 2106 caddr_t va; 2107 int err; 2108 2109 BGE_TRACE(("bge_alloc_dma_mem($%p, %ld, $%p, 0x%x, $%p)", 2110 (void *)bgep, memsize, attr_p, dma_flags, dma_p)); 2111 2112 /* 2113 * Allocate handle 2114 */ 2115 err = ddi_dma_alloc_handle(bgep->devinfo, &dma_attr, 2116 DDI_DMA_DONTWAIT, NULL, &dma_p->dma_hdl); 2117 if (err != DDI_SUCCESS) 2118 return (DDI_FAILURE); 2119 2120 /* 2121 * Allocate memory 2122 */ 2123 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p, 2124 dma_flags, DDI_DMA_DONTWAIT, NULL, &va, &dma_p->alength, 2125 &dma_p->acc_hdl); 2126 if (err != DDI_SUCCESS) 2127 return (DDI_FAILURE); 2128 2129 /* 2130 * Bind the two together 2131 */ 2132 dma_p->mem_va = va; 2133 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, 2134 va, dma_p->alength, dma_flags, DDI_DMA_DONTWAIT, NULL, 2135 &dma_p->cookie, &dma_p->ncookies); 2136 2137 BGE_DEBUG(("bge_alloc_dma_mem(): bind %d bytes; err %d, %d cookies", 2138 dma_p->alength, err, dma_p->ncookies)); 2139 2140 if (err != DDI_DMA_MAPPED || dma_p->ncookies != 1) 2141 return (DDI_FAILURE); 2142 2143 dma_p->nslots = ~0U; 2144 dma_p->size = ~0U; 2145 dma_p->token = ~0U; 2146 dma_p->offset = 0; 2147 return (DDI_SUCCESS); 2148 } 2149 2150 /* 2151 * Free one allocated area of DMAable memory 2152 */ 2153 static void 2154 bge_free_dma_mem(dma_area_t *dma_p) 2155 { 2156 if (dma_p->dma_hdl != NULL) { 2157 if (dma_p->ncookies) { 2158 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 2159 dma_p->ncookies = 0; 2160 } 2161 ddi_dma_free_handle(&dma_p->dma_hdl); 2162 dma_p->dma_hdl = NULL; 2163 } 2164 2165 if (dma_p->acc_hdl != NULL) { 2166 ddi_dma_mem_free(&dma_p->acc_hdl); 2167 dma_p->acc_hdl = NULL; 2168 } 2169 } 2170 /* 2171 * Utility routine to carve a slice off a chunk of allocated memory, 2172 * updating the chunk descriptor accordingly. The size of the slice 2173 * is given by the product of the <qty> and <size> parameters. 2174 */ 2175 static void 2176 bge_slice_chunk(dma_area_t *slice, dma_area_t *chunk, 2177 uint32_t qty, uint32_t size) 2178 { 2179 static uint32_t sequence = 0xbcd5704a; 2180 size_t totsize; 2181 2182 totsize = qty*size; 2183 ASSERT(totsize <= chunk->alength); 2184 2185 *slice = *chunk; 2186 slice->nslots = qty; 2187 slice->size = size; 2188 slice->alength = totsize; 2189 slice->token = ++sequence; 2190 2191 chunk->mem_va = (caddr_t)chunk->mem_va + totsize; 2192 chunk->alength -= totsize; 2193 chunk->offset += totsize; 2194 chunk->cookie.dmac_laddress += totsize; 2195 chunk->cookie.dmac_size -= totsize; 2196 } 2197 2198 /* 2199 * Initialise the specified Receive Producer (Buffer) Ring, using 2200 * the information in the <dma_area> descriptors that it contains 2201 * to set up all the other fields. This routine should be called 2202 * only once for each ring. 2203 */ 2204 static void 2205 bge_init_buff_ring(bge_t *bgep, uint64_t ring) 2206 { 2207 buff_ring_t *brp; 2208 bge_status_t *bsp; 2209 sw_rbd_t *srbdp; 2210 dma_area_t pbuf; 2211 uint32_t bufsize; 2212 uint32_t nslots; 2213 uint32_t slot; 2214 uint32_t split; 2215 2216 static bge_regno_t nic_ring_addrs[BGE_BUFF_RINGS_MAX] = { 2217 NIC_MEM_SHADOW_BUFF_STD, 2218 NIC_MEM_SHADOW_BUFF_JUMBO, 2219 NIC_MEM_SHADOW_BUFF_MINI 2220 }; 2221 static bge_regno_t mailbox_regs[BGE_BUFF_RINGS_MAX] = { 2222 RECV_STD_PROD_INDEX_REG, 2223 RECV_JUMBO_PROD_INDEX_REG, 2224 RECV_MINI_PROD_INDEX_REG 2225 }; 2226 static bge_regno_t buff_cons_xref[BGE_BUFF_RINGS_MAX] = { 2227 STATUS_STD_BUFF_CONS_INDEX, 2228 STATUS_JUMBO_BUFF_CONS_INDEX, 2229 STATUS_MINI_BUFF_CONS_INDEX 2230 }; 2231 2232 BGE_TRACE(("bge_init_buff_ring($%p, %d)", 2233 (void *)bgep, ring)); 2234 2235 brp = &bgep->buff[ring]; 2236 nslots = brp->desc.nslots; 2237 ASSERT(brp->buf[0].nslots == nslots/BGE_SPLIT); 2238 bufsize = brp->buf[0].size; 2239 2240 /* 2241 * Set up the copy of the h/w RCB 2242 * 2243 * Note: unlike Send & Receive Return Rings, (where the max_len 2244 * field holds the number of slots), in a Receive Buffer Ring 2245 * this field indicates the size of each buffer in the ring. 2246 */ 2247 brp->hw_rcb.host_ring_addr = brp->desc.cookie.dmac_laddress; 2248 brp->hw_rcb.max_len = (uint16_t)bufsize; 2249 brp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED; 2250 brp->hw_rcb.nic_ring_addr = nic_ring_addrs[ring]; 2251 2252 /* 2253 * Other one-off initialisation of per-ring data 2254 */ 2255 brp->bgep = bgep; 2256 bsp = DMA_VPTR(bgep->status_block); 2257 brp->cons_index_p = &bsp->buff_cons_index[buff_cons_xref[ring]]; 2258 brp->chip_mbx_reg = mailbox_regs[ring]; 2259 mutex_init(brp->rf_lock, NULL, MUTEX_DRIVER, 2260 DDI_INTR_PRI(bgep->intr_pri)); 2261 2262 /* 2263 * Allocate the array of s/w Receive Buffer Descriptors 2264 */ 2265 srbdp = kmem_zalloc(nslots*sizeof (*srbdp), KM_SLEEP); 2266 brp->sw_rbds = srbdp; 2267 2268 /* 2269 * Now initialise each array element once and for all 2270 */ 2271 for (split = 0; split < BGE_SPLIT; ++split) { 2272 pbuf = brp->buf[split]; 2273 for (slot = 0; slot < nslots/BGE_SPLIT; ++srbdp, ++slot) 2274 bge_slice_chunk(&srbdp->pbuf, &pbuf, 1, bufsize); 2275 ASSERT(pbuf.alength == 0); 2276 } 2277 } 2278 2279 /* 2280 * Clean up initialisation done above before the memory is freed 2281 */ 2282 static void 2283 bge_fini_buff_ring(bge_t *bgep, uint64_t ring) 2284 { 2285 buff_ring_t *brp; 2286 sw_rbd_t *srbdp; 2287 2288 BGE_TRACE(("bge_fini_buff_ring($%p, %d)", 2289 (void *)bgep, ring)); 2290 2291 brp = &bgep->buff[ring]; 2292 srbdp = brp->sw_rbds; 2293 kmem_free(srbdp, brp->desc.nslots*sizeof (*srbdp)); 2294 2295 mutex_destroy(brp->rf_lock); 2296 } 2297 2298 /* 2299 * Initialise the specified Receive (Return) Ring, using the 2300 * information in the <dma_area> descriptors that it contains 2301 * to set up all the other fields. This routine should be called 2302 * only once for each ring. 2303 */ 2304 static void 2305 bge_init_recv_ring(bge_t *bgep, uint64_t ring) 2306 { 2307 recv_ring_t *rrp; 2308 bge_status_t *bsp; 2309 uint32_t nslots; 2310 2311 BGE_TRACE(("bge_init_recv_ring($%p, %d)", 2312 (void *)bgep, ring)); 2313 2314 /* 2315 * The chip architecture requires that receive return rings have 2316 * 512 or 1024 or 2048 elements per ring. See 570X-PG108-R page 103. 2317 */ 2318 rrp = &bgep->recv[ring]; 2319 nslots = rrp->desc.nslots; 2320 ASSERT(nslots == 0 || nslots == 512 || 2321 nslots == 1024 || nslots == 2048); 2322 2323 /* 2324 * Set up the copy of the h/w RCB 2325 */ 2326 rrp->hw_rcb.host_ring_addr = rrp->desc.cookie.dmac_laddress; 2327 rrp->hw_rcb.max_len = (uint16_t)nslots; 2328 rrp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED; 2329 rrp->hw_rcb.nic_ring_addr = 0; 2330 2331 /* 2332 * Other one-off initialisation of per-ring data 2333 */ 2334 rrp->bgep = bgep; 2335 bsp = DMA_VPTR(bgep->status_block); 2336 rrp->prod_index_p = RECV_INDEX_P(bsp, ring); 2337 rrp->chip_mbx_reg = RECV_RING_CONS_INDEX_REG(ring); 2338 mutex_init(rrp->rx_lock, NULL, MUTEX_DRIVER, 2339 DDI_INTR_PRI(bgep->intr_pri)); 2340 } 2341 2342 2343 /* 2344 * Clean up initialisation done above before the memory is freed 2345 */ 2346 static void 2347 bge_fini_recv_ring(bge_t *bgep, uint64_t ring) 2348 { 2349 recv_ring_t *rrp; 2350 2351 BGE_TRACE(("bge_fini_recv_ring($%p, %d)", 2352 (void *)bgep, ring)); 2353 2354 rrp = &bgep->recv[ring]; 2355 if (rrp->rx_softint) 2356 ddi_remove_softintr(rrp->rx_softint); 2357 mutex_destroy(rrp->rx_lock); 2358 } 2359 2360 /* 2361 * Initialise the specified Send Ring, using the information in the 2362 * <dma_area> descriptors that it contains to set up all the other 2363 * fields. This routine should be called only once for each ring. 2364 */ 2365 static void 2366 bge_init_send_ring(bge_t *bgep, uint64_t ring) 2367 { 2368 send_ring_t *srp; 2369 bge_status_t *bsp; 2370 sw_sbd_t *ssbdp; 2371 dma_area_t desc; 2372 dma_area_t pbuf; 2373 uint32_t nslots; 2374 uint32_t slot; 2375 uint32_t split; 2376 sw_txbuf_t *txbuf; 2377 2378 BGE_TRACE(("bge_init_send_ring($%p, %d)", 2379 (void *)bgep, ring)); 2380 2381 /* 2382 * The chip architecture requires that host-based send rings 2383 * have 512 elements per ring. See 570X-PG102-R page 56. 2384 */ 2385 srp = &bgep->send[ring]; 2386 nslots = srp->desc.nslots; 2387 ASSERT(nslots == 0 || nslots == 512); 2388 2389 /* 2390 * Set up the copy of the h/w RCB 2391 */ 2392 srp->hw_rcb.host_ring_addr = srp->desc.cookie.dmac_laddress; 2393 srp->hw_rcb.max_len = (uint16_t)nslots; 2394 srp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED; 2395 srp->hw_rcb.nic_ring_addr = NIC_MEM_SHADOW_SEND_RING(ring, nslots); 2396 2397 /* 2398 * Other one-off initialisation of per-ring data 2399 */ 2400 srp->bgep = bgep; 2401 bsp = DMA_VPTR(bgep->status_block); 2402 srp->cons_index_p = SEND_INDEX_P(bsp, ring); 2403 srp->chip_mbx_reg = SEND_RING_HOST_INDEX_REG(ring); 2404 mutex_init(srp->tx_lock, NULL, MUTEX_DRIVER, 2405 DDI_INTR_PRI(bgep->intr_pri)); 2406 mutex_init(srp->txbuf_lock, NULL, MUTEX_DRIVER, 2407 DDI_INTR_PRI(bgep->intr_pri)); 2408 mutex_init(srp->freetxbuf_lock, NULL, MUTEX_DRIVER, 2409 DDI_INTR_PRI(bgep->intr_pri)); 2410 mutex_init(srp->tc_lock, NULL, MUTEX_DRIVER, 2411 DDI_INTR_PRI(bgep->intr_pri)); 2412 if (nslots == 0) 2413 return; 2414 2415 /* 2416 * Allocate the array of s/w Send Buffer Descriptors 2417 */ 2418 ssbdp = kmem_zalloc(nslots*sizeof (*ssbdp), KM_SLEEP); 2419 txbuf = kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (*txbuf), KM_SLEEP); 2420 srp->txbuf_head = 2421 kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (bge_queue_item_t), KM_SLEEP); 2422 srp->pktp = kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (send_pkt_t), KM_SLEEP); 2423 srp->sw_sbds = ssbdp; 2424 srp->txbuf = txbuf; 2425 srp->tx_buffers = BGE_SEND_BUF_NUM; 2426 srp->tx_buffers_low = srp->tx_buffers / 4; 2427 if (bgep->chipid.snd_buff_size > BGE_SEND_BUFF_SIZE_DEFAULT) 2428 srp->tx_array_max = BGE_SEND_BUF_ARRAY_JUMBO; 2429 else 2430 srp->tx_array_max = BGE_SEND_BUF_ARRAY; 2431 srp->tx_array = 1; 2432 2433 /* 2434 * Chunk tx desc area 2435 */ 2436 desc = srp->desc; 2437 for (slot = 0; slot < nslots; ++ssbdp, ++slot) { 2438 bge_slice_chunk(&ssbdp->desc, &desc, 1, 2439 sizeof (bge_sbd_t)); 2440 } 2441 ASSERT(desc.alength == 0); 2442 2443 /* 2444 * Chunk tx buffer area 2445 */ 2446 for (split = 0; split < BGE_SPLIT; ++split) { 2447 pbuf = srp->buf[0][split]; 2448 for (slot = 0; slot < BGE_SEND_BUF_NUM/BGE_SPLIT; ++slot) { 2449 bge_slice_chunk(&txbuf->buf, &pbuf, 1, 2450 bgep->chipid.snd_buff_size); 2451 txbuf++; 2452 } 2453 ASSERT(pbuf.alength == 0); 2454 } 2455 } 2456 2457 /* 2458 * Clean up initialisation done above before the memory is freed 2459 */ 2460 static void 2461 bge_fini_send_ring(bge_t *bgep, uint64_t ring) 2462 { 2463 send_ring_t *srp; 2464 uint32_t array; 2465 uint32_t split; 2466 uint32_t nslots; 2467 2468 BGE_TRACE(("bge_fini_send_ring($%p, %d)", 2469 (void *)bgep, ring)); 2470 2471 srp = &bgep->send[ring]; 2472 mutex_destroy(srp->tc_lock); 2473 mutex_destroy(srp->freetxbuf_lock); 2474 mutex_destroy(srp->txbuf_lock); 2475 mutex_destroy(srp->tx_lock); 2476 nslots = srp->desc.nslots; 2477 if (nslots == 0) 2478 return; 2479 2480 for (array = 1; array < srp->tx_array; ++array) 2481 for (split = 0; split < BGE_SPLIT; ++split) 2482 bge_free_dma_mem(&srp->buf[array][split]); 2483 kmem_free(srp->sw_sbds, nslots*sizeof (*srp->sw_sbds)); 2484 kmem_free(srp->txbuf_head, BGE_SEND_BUF_MAX*sizeof (*srp->txbuf_head)); 2485 kmem_free(srp->txbuf, BGE_SEND_BUF_MAX*sizeof (*srp->txbuf)); 2486 kmem_free(srp->pktp, BGE_SEND_BUF_MAX*sizeof (*srp->pktp)); 2487 srp->sw_sbds = NULL; 2488 srp->txbuf_head = NULL; 2489 srp->txbuf = NULL; 2490 srp->pktp = NULL; 2491 } 2492 2493 /* 2494 * Initialise all transmit, receive, and buffer rings. 2495 */ 2496 void 2497 bge_init_rings(bge_t *bgep) 2498 { 2499 uint32_t ring; 2500 2501 BGE_TRACE(("bge_init_rings($%p)", (void *)bgep)); 2502 2503 /* 2504 * Perform one-off initialisation of each ring ... 2505 */ 2506 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring) 2507 bge_init_send_ring(bgep, ring); 2508 for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring) 2509 bge_init_recv_ring(bgep, ring); 2510 for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring) 2511 bge_init_buff_ring(bgep, ring); 2512 } 2513 2514 /* 2515 * Undo the work of bge_init_rings() above before the memory is freed 2516 */ 2517 void 2518 bge_fini_rings(bge_t *bgep) 2519 { 2520 uint32_t ring; 2521 2522 BGE_TRACE(("bge_fini_rings($%p)", (void *)bgep)); 2523 2524 for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring) 2525 bge_fini_buff_ring(bgep, ring); 2526 for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring) 2527 bge_fini_recv_ring(bgep, ring); 2528 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring) 2529 bge_fini_send_ring(bgep, ring); 2530 } 2531 2532 /* 2533 * Called from the bge_m_stop() to free the tx buffers which are 2534 * allocated from the tx process. 2535 */ 2536 void 2537 bge_free_txbuf_arrays(send_ring_t *srp) 2538 { 2539 uint32_t array; 2540 uint32_t split; 2541 2542 ASSERT(mutex_owned(srp->tx_lock)); 2543 2544 /* 2545 * Free the extra tx buffer DMA area 2546 */ 2547 for (array = 1; array < srp->tx_array; ++array) 2548 for (split = 0; split < BGE_SPLIT; ++split) 2549 bge_free_dma_mem(&srp->buf[array][split]); 2550 2551 /* 2552 * Restore initial tx buffer numbers 2553 */ 2554 srp->tx_array = 1; 2555 srp->tx_buffers = BGE_SEND_BUF_NUM; 2556 srp->tx_buffers_low = srp->tx_buffers / 4; 2557 srp->tx_flow = 0; 2558 bzero(srp->pktp, BGE_SEND_BUF_MAX * sizeof (*srp->pktp)); 2559 } 2560 2561 /* 2562 * Called from tx process to allocate more tx buffers 2563 */ 2564 bge_queue_item_t * 2565 bge_alloc_txbuf_array(bge_t *bgep, send_ring_t *srp) 2566 { 2567 bge_queue_t *txbuf_queue; 2568 bge_queue_item_t *txbuf_item_last; 2569 bge_queue_item_t *txbuf_item; 2570 bge_queue_item_t *txbuf_item_rtn; 2571 sw_txbuf_t *txbuf; 2572 dma_area_t area; 2573 size_t txbuffsize; 2574 uint32_t slot; 2575 uint32_t array; 2576 uint32_t split; 2577 uint32_t err; 2578 2579 ASSERT(mutex_owned(srp->tx_lock)); 2580 2581 array = srp->tx_array; 2582 if (array >= srp->tx_array_max) 2583 return (NULL); 2584 2585 /* 2586 * Allocate memory & handles for TX buffers 2587 */ 2588 txbuffsize = BGE_SEND_BUF_NUM*bgep->chipid.snd_buff_size; 2589 ASSERT((txbuffsize % BGE_SPLIT) == 0); 2590 for (split = 0; split < BGE_SPLIT; ++split) { 2591 err = bge_alloc_dma_mem(bgep, txbuffsize/BGE_SPLIT, 2592 &bge_data_accattr, DDI_DMA_WRITE | BGE_DMA_MODE, 2593 &srp->buf[array][split]); 2594 if (err != DDI_SUCCESS) { 2595 /* Free the last already allocated OK chunks */ 2596 for (slot = 0; slot <= split; ++slot) 2597 bge_free_dma_mem(&srp->buf[array][slot]); 2598 srp->tx_alloc_fail++; 2599 return (NULL); 2600 } 2601 } 2602 2603 /* 2604 * Chunk tx buffer area 2605 */ 2606 txbuf = srp->txbuf + array*BGE_SEND_BUF_NUM; 2607 for (split = 0; split < BGE_SPLIT; ++split) { 2608 area = srp->buf[array][split]; 2609 for (slot = 0; slot < BGE_SEND_BUF_NUM/BGE_SPLIT; ++slot) { 2610 bge_slice_chunk(&txbuf->buf, &area, 1, 2611 bgep->chipid.snd_buff_size); 2612 txbuf++; 2613 } 2614 } 2615 2616 /* 2617 * Add above buffers to the tx buffer pop queue 2618 */ 2619 txbuf_item = srp->txbuf_head + array*BGE_SEND_BUF_NUM; 2620 txbuf = srp->txbuf + array*BGE_SEND_BUF_NUM; 2621 txbuf_item_last = NULL; 2622 for (slot = 0; slot < BGE_SEND_BUF_NUM; ++slot) { 2623 txbuf_item->item = txbuf; 2624 txbuf_item->next = txbuf_item_last; 2625 txbuf_item_last = txbuf_item; 2626 txbuf++; 2627 txbuf_item++; 2628 } 2629 txbuf_item = srp->txbuf_head + array*BGE_SEND_BUF_NUM; 2630 txbuf_item_rtn = txbuf_item; 2631 txbuf_item++; 2632 txbuf_queue = srp->txbuf_pop_queue; 2633 mutex_enter(txbuf_queue->lock); 2634 txbuf_item->next = txbuf_queue->head; 2635 txbuf_queue->head = txbuf_item_last; 2636 txbuf_queue->count += BGE_SEND_BUF_NUM - 1; 2637 mutex_exit(txbuf_queue->lock); 2638 2639 srp->tx_array++; 2640 srp->tx_buffers += BGE_SEND_BUF_NUM; 2641 srp->tx_buffers_low = srp->tx_buffers / 4; 2642 2643 return (txbuf_item_rtn); 2644 } 2645 2646 /* 2647 * This function allocates all the transmit and receive buffers 2648 * and descriptors, in four chunks. 2649 */ 2650 int 2651 bge_alloc_bufs(bge_t *bgep) 2652 { 2653 dma_area_t area; 2654 size_t rxbuffsize; 2655 size_t txbuffsize; 2656 size_t rxbuffdescsize; 2657 size_t rxdescsize; 2658 size_t txdescsize; 2659 uint32_t ring; 2660 uint32_t rx_rings = bgep->chipid.rx_rings; 2661 uint32_t tx_rings = bgep->chipid.tx_rings; 2662 int split; 2663 int err; 2664 2665 BGE_TRACE(("bge_alloc_bufs($%p)", 2666 (void *)bgep)); 2667 2668 rxbuffsize = BGE_STD_SLOTS_USED*bgep->chipid.std_buf_size; 2669 rxbuffsize += bgep->chipid.jumbo_slots*bgep->chipid.recv_jumbo_size; 2670 rxbuffsize += BGE_MINI_SLOTS_USED*BGE_MINI_BUFF_SIZE; 2671 2672 txbuffsize = BGE_SEND_BUF_NUM*bgep->chipid.snd_buff_size; 2673 txbuffsize *= tx_rings; 2674 2675 rxdescsize = rx_rings*bgep->chipid.recv_slots; 2676 rxdescsize *= sizeof (bge_rbd_t); 2677 2678 rxbuffdescsize = BGE_STD_SLOTS_USED; 2679 rxbuffdescsize += bgep->chipid.jumbo_slots; 2680 rxbuffdescsize += BGE_MINI_SLOTS_USED; 2681 rxbuffdescsize *= sizeof (bge_rbd_t); 2682 2683 txdescsize = tx_rings*BGE_SEND_SLOTS_USED; 2684 txdescsize *= sizeof (bge_sbd_t); 2685 txdescsize += sizeof (bge_statistics_t); 2686 txdescsize += sizeof (bge_status_t); 2687 txdescsize += BGE_STATUS_PADDING; 2688 2689 /* 2690 * Enable PCI relaxed ordering only for RX/TX data buffers 2691 */ 2692 if (!(DEVICE_5717_SERIES_CHIPSETS(bgep) || 2693 DEVICE_5725_SERIES_CHIPSETS(bgep))) { 2694 if (bge_relaxed_ordering) 2695 dma_attr.dma_attr_flags |= DDI_DMA_RELAXED_ORDERING; 2696 } 2697 2698 /* 2699 * Allocate memory & handles for RX buffers 2700 */ 2701 ASSERT((rxbuffsize % BGE_SPLIT) == 0); 2702 for (split = 0; split < BGE_SPLIT; ++split) { 2703 err = bge_alloc_dma_mem(bgep, rxbuffsize/BGE_SPLIT, 2704 &bge_data_accattr, DDI_DMA_READ | BGE_DMA_MODE, 2705 &bgep->rx_buff[split]); 2706 if (err != DDI_SUCCESS) 2707 return (DDI_FAILURE); 2708 } 2709 BGE_DEBUG(("DMA ALLOC: allocated %d chunks for Rx Buffers (rxbuffsize = %d)", 2710 rxbuffsize/BGE_SPLIT, 2711 rxbuffsize)); 2712 2713 /* 2714 * Allocate memory & handles for TX buffers 2715 */ 2716 ASSERT((txbuffsize % BGE_SPLIT) == 0); 2717 for (split = 0; split < BGE_SPLIT; ++split) { 2718 err = bge_alloc_dma_mem(bgep, txbuffsize/BGE_SPLIT, 2719 &bge_data_accattr, DDI_DMA_WRITE | BGE_DMA_MODE, 2720 &bgep->tx_buff[split]); 2721 if (err != DDI_SUCCESS) 2722 return (DDI_FAILURE); 2723 } 2724 BGE_DEBUG(("DMA ALLOC: allocated %d chunks for Tx Buffers (txbuffsize = %d)", 2725 txbuffsize/BGE_SPLIT, 2726 txbuffsize)); 2727 2728 if (!(DEVICE_5717_SERIES_CHIPSETS(bgep) || 2729 DEVICE_5725_SERIES_CHIPSETS(bgep))) { 2730 /* no relaxed ordering for descriptors rings? */ 2731 dma_attr.dma_attr_flags &= ~DDI_DMA_RELAXED_ORDERING; 2732 } 2733 2734 /* 2735 * Allocate memory & handles for receive return rings 2736 */ 2737 ASSERT((rxdescsize % rx_rings) == 0); 2738 for (split = 0; split < rx_rings; ++split) { 2739 err = bge_alloc_dma_mem(bgep, rxdescsize/rx_rings, 2740 &bge_desc_accattr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 2741 &bgep->rx_desc[split]); 2742 if (err != DDI_SUCCESS) 2743 return (DDI_FAILURE); 2744 } 2745 BGE_DEBUG(("DMA ALLOC: allocated %d chunks for Rx Descs cons (rx_rings = %d, rxdescsize = %d)", 2746 rxdescsize/rx_rings, 2747 rx_rings, 2748 rxdescsize)); 2749 2750 /* 2751 * Allocate memory & handles for buffer (producer) descriptor rings. 2752 * Note that split=rx_rings. 2753 */ 2754 err = bge_alloc_dma_mem(bgep, rxbuffdescsize, &bge_desc_accattr, 2755 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &bgep->rx_desc[split]); 2756 if (err != DDI_SUCCESS) 2757 return (DDI_FAILURE); 2758 BGE_DEBUG(("DMA ALLOC: allocated 1 chunks for Rx Descs prod (rxbuffdescsize = %d)", 2759 rxdescsize)); 2760 2761 /* 2762 * Allocate memory & handles for TX descriptor rings, 2763 * status block, and statistics area 2764 */ 2765 err = bge_alloc_dma_mem(bgep, txdescsize, &bge_desc_accattr, 2766 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &bgep->tx_desc); 2767 if (err != DDI_SUCCESS) 2768 return (DDI_FAILURE); 2769 BGE_DEBUG(("DMA ALLOC: allocated 1 chunks for Tx Descs / Status Block / Stats (txdescdize = %d)", 2770 txdescsize)); 2771 2772 /* 2773 * Now carve up each of the allocated areas ... 2774 */ 2775 2776 /* rx buffers */ 2777 for (split = 0; split < BGE_SPLIT; ++split) { 2778 area = bgep->rx_buff[split]; 2779 2780 BGE_DEBUG(("RXB CHNK %d INIT: va=%p alen=%d off=%d pa=%llx psz=%d", 2781 split, 2782 area.mem_va, 2783 area.alength, 2784 area.offset, 2785 area.cookie.dmac_laddress, 2786 area.cookie.dmac_size)); 2787 2788 bge_slice_chunk(&bgep->buff[BGE_STD_BUFF_RING].buf[split], 2789 &area, BGE_STD_SLOTS_USED/BGE_SPLIT, 2790 bgep->chipid.std_buf_size); 2791 2792 BGE_DEBUG(("RXB SLCE %d STND: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2793 split, 2794 bgep->buff[BGE_STD_BUFF_RING].buf[split].mem_va, 2795 bgep->buff[BGE_STD_BUFF_RING].buf[split].alength, 2796 bgep->buff[BGE_STD_BUFF_RING].buf[split].offset, 2797 bgep->buff[BGE_STD_BUFF_RING].buf[split].cookie.dmac_laddress, 2798 bgep->buff[BGE_STD_BUFF_RING].buf[split].cookie.dmac_size, 2799 BGE_STD_SLOTS_USED/BGE_SPLIT, 2800 bgep->chipid.std_buf_size)); 2801 2802 bge_slice_chunk(&bgep->buff[BGE_JUMBO_BUFF_RING].buf[split], 2803 &area, bgep->chipid.jumbo_slots/BGE_SPLIT, 2804 bgep->chipid.recv_jumbo_size); 2805 2806 if ((bgep->chipid.jumbo_slots / BGE_SPLIT) > 0) 2807 { 2808 BGE_DEBUG(("RXB SLCE %d JUMB: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2809 split, 2810 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].mem_va, 2811 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].alength, 2812 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].offset, 2813 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].cookie.dmac_laddress, 2814 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].cookie.dmac_size, 2815 bgep->chipid.jumbo_slots/BGE_SPLIT, 2816 bgep->chipid.recv_jumbo_size)); 2817 } 2818 2819 bge_slice_chunk(&bgep->buff[BGE_MINI_BUFF_RING].buf[split], 2820 &area, BGE_MINI_SLOTS_USED/BGE_SPLIT, 2821 BGE_MINI_BUFF_SIZE); 2822 2823 if ((BGE_MINI_SLOTS_USED / BGE_SPLIT) > 0) 2824 { 2825 BGE_DEBUG(("RXB SLCE %d MINI: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2826 split, 2827 bgep->buff[BGE_MINI_BUFF_RING].buf[split].mem_va, 2828 bgep->buff[BGE_MINI_BUFF_RING].buf[split].alength, 2829 bgep->buff[BGE_MINI_BUFF_RING].buf[split].offset, 2830 bgep->buff[BGE_MINI_BUFF_RING].buf[split].cookie.dmac_laddress, 2831 bgep->buff[BGE_MINI_BUFF_RING].buf[split].cookie.dmac_size, 2832 BGE_MINI_SLOTS_USED/BGE_SPLIT, 2833 BGE_MINI_BUFF_SIZE)); 2834 } 2835 2836 BGE_DEBUG(("RXB CHNK %d DONE: va=%p alen=%d off=%d pa=%llx psz=%d", 2837 split, 2838 area.mem_va, 2839 area.alength, 2840 area.offset, 2841 area.cookie.dmac_laddress, 2842 area.cookie.dmac_size)); 2843 } 2844 2845 /* tx buffers */ 2846 for (split = 0; split < BGE_SPLIT; ++split) { 2847 area = bgep->tx_buff[split]; 2848 2849 BGE_DEBUG(("TXB CHNK %d INIT: va=%p alen=%d off=%d pa=%llx psz=%d", 2850 split, 2851 area.mem_va, 2852 area.alength, 2853 area.offset, 2854 area.cookie.dmac_laddress, 2855 area.cookie.dmac_size)); 2856 2857 for (ring = 0; ring < tx_rings; ++ring) { 2858 bge_slice_chunk(&bgep->send[ring].buf[0][split], 2859 &area, BGE_SEND_BUF_NUM/BGE_SPLIT, 2860 bgep->chipid.snd_buff_size); 2861 2862 BGE_DEBUG(("TXB SLCE %d RING %d: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2863 split, ring, 2864 bgep->send[ring].buf[0][split].mem_va, 2865 bgep->send[ring].buf[0][split].alength, 2866 bgep->send[ring].buf[0][split].offset, 2867 bgep->send[ring].buf[0][split].cookie.dmac_laddress, 2868 bgep->send[ring].buf[0][split].cookie.dmac_size, 2869 BGE_SEND_BUF_NUM/BGE_SPLIT, 2870 bgep->chipid.snd_buff_size)); 2871 } 2872 2873 for (; ring < BGE_SEND_RINGS_MAX; ++ring) { 2874 bge_slice_chunk(&bgep->send[ring].buf[0][split], 2875 &area, 0, bgep->chipid.snd_buff_size); 2876 } 2877 2878 BGE_DEBUG(("TXB CHNK %d DONE: va=%p alen=%d off=%d pa=%llx psz=%d", 2879 split, 2880 area.mem_va, 2881 area.alength, 2882 area.offset, 2883 area.cookie.dmac_laddress, 2884 area.cookie.dmac_size)); 2885 } 2886 2887 for (ring = 0; ring < rx_rings; ++ring) { 2888 bge_slice_chunk(&bgep->recv[ring].desc, &bgep->rx_desc[ring], 2889 bgep->chipid.recv_slots, sizeof (bge_rbd_t)); 2890 2891 BGE_DEBUG(("RXD CONS RING %d: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2892 ring, 2893 bgep->recv[ring].desc.mem_va, 2894 bgep->recv[ring].desc.alength, 2895 bgep->recv[ring].desc.offset, 2896 bgep->recv[ring].desc.cookie.dmac_laddress, 2897 bgep->recv[ring].desc.cookie.dmac_size, 2898 bgep->chipid.recv_slots, 2899 sizeof(bge_rbd_t))); 2900 } 2901 2902 /* dma alloc for rxbuffdescsize is located at bgep->rx_desc[#rings] */ 2903 area = bgep->rx_desc[rx_rings]; /* note rx_rings = one beyond rings */ 2904 2905 for (; ring < BGE_RECV_RINGS_MAX; ++ring) /* skip unused rings */ 2906 bge_slice_chunk(&bgep->recv[ring].desc, &area, 2907 0, sizeof (bge_rbd_t)); 2908 2909 BGE_DEBUG(("RXD PROD INIT: va=%p alen=%d off=%d pa=%llx psz=%d", 2910 area.mem_va, 2911 area.alength, 2912 area.offset, 2913 area.cookie.dmac_laddress, 2914 area.cookie.dmac_size)); 2915 2916 bge_slice_chunk(&bgep->buff[BGE_STD_BUFF_RING].desc, &area, 2917 BGE_STD_SLOTS_USED, sizeof (bge_rbd_t)); 2918 BGE_DEBUG(("RXD PROD STND: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2919 bgep->buff[BGE_STD_BUFF_RING].desc.mem_va, 2920 bgep->buff[BGE_STD_BUFF_RING].desc.alength, 2921 bgep->buff[BGE_STD_BUFF_RING].desc.offset, 2922 bgep->buff[BGE_STD_BUFF_RING].desc.cookie.dmac_laddress, 2923 bgep->buff[BGE_STD_BUFF_RING].desc.cookie.dmac_size, 2924 BGE_STD_SLOTS_USED, 2925 sizeof(bge_rbd_t))); 2926 2927 bge_slice_chunk(&bgep->buff[BGE_JUMBO_BUFF_RING].desc, &area, 2928 bgep->chipid.jumbo_slots, sizeof (bge_rbd_t)); 2929 BGE_DEBUG(("RXD PROD JUMB: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2930 bgep->buff[BGE_JUMBO_BUFF_RING].desc.mem_va, 2931 bgep->buff[BGE_JUMBO_BUFF_RING].desc.alength, 2932 bgep->buff[BGE_JUMBO_BUFF_RING].desc.offset, 2933 bgep->buff[BGE_JUMBO_BUFF_RING].desc.cookie.dmac_laddress, 2934 bgep->buff[BGE_JUMBO_BUFF_RING].desc.cookie.dmac_size, 2935 bgep->chipid.jumbo_slots, 2936 sizeof(bge_rbd_t))); 2937 2938 bge_slice_chunk(&bgep->buff[BGE_MINI_BUFF_RING].desc, &area, 2939 BGE_MINI_SLOTS_USED, sizeof (bge_rbd_t)); 2940 BGE_DEBUG(("RXD PROD MINI: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2941 bgep->buff[BGE_MINI_BUFF_RING].desc.mem_va, 2942 bgep->buff[BGE_MINI_BUFF_RING].desc.alength, 2943 bgep->buff[BGE_MINI_BUFF_RING].desc.offset, 2944 bgep->buff[BGE_MINI_BUFF_RING].desc.cookie.dmac_laddress, 2945 bgep->buff[BGE_MINI_BUFF_RING].desc.cookie.dmac_size, 2946 BGE_MINI_SLOTS_USED, 2947 sizeof(bge_rbd_t))); 2948 2949 BGE_DEBUG(("RXD PROD DONE: va=%p alen=%d off=%d pa=%llx psz=%d", 2950 area.mem_va, 2951 area.alength, 2952 area.offset, 2953 area.cookie.dmac_laddress, 2954 area.cookie.dmac_size)); 2955 2956 ASSERT(area.alength == 0); 2957 2958 area = bgep->tx_desc; 2959 2960 BGE_DEBUG(("TXD INIT: va=%p alen=%d off=%d pa=%llx psz=%d", 2961 area.mem_va, 2962 area.alength, 2963 area.offset, 2964 area.cookie.dmac_laddress, 2965 area.cookie.dmac_size)); 2966 2967 for (ring = 0; ring < tx_rings; ++ring) { 2968 bge_slice_chunk(&bgep->send[ring].desc, &area, 2969 BGE_SEND_SLOTS_USED, sizeof (bge_sbd_t)); 2970 2971 BGE_DEBUG(("TXD RING %d: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2972 ring, 2973 bgep->send[ring].desc.mem_va, 2974 bgep->send[ring].desc.alength, 2975 bgep->send[ring].desc.offset, 2976 bgep->send[ring].desc.cookie.dmac_laddress, 2977 bgep->send[ring].desc.cookie.dmac_size, 2978 BGE_SEND_SLOTS_USED, 2979 sizeof(bge_sbd_t))); 2980 } 2981 2982 for (; ring < BGE_SEND_RINGS_MAX; ++ring) /* skip unused rings */ 2983 bge_slice_chunk(&bgep->send[ring].desc, &area, 2984 0, sizeof (bge_sbd_t)); 2985 2986 bge_slice_chunk(&bgep->statistics, &area, 1, sizeof (bge_statistics_t)); 2987 BGE_DEBUG(("TXD STATISTICS: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2988 bgep->statistics.mem_va, 2989 bgep->statistics.alength, 2990 bgep->statistics.offset, 2991 bgep->statistics.cookie.dmac_laddress, 2992 bgep->statistics.cookie.dmac_size, 2993 1, 2994 sizeof(bge_statistics_t))); 2995 2996 bge_slice_chunk(&bgep->status_block, &area, 1, sizeof (bge_status_t)); 2997 BGE_DEBUG(("TXD STATUS BLOCK: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)", 2998 bgep->status_block.mem_va, 2999 bgep->status_block.alength, 3000 bgep->status_block.offset, 3001 bgep->status_block.cookie.dmac_laddress, 3002 bgep->status_block.cookie.dmac_size, 3003 1, 3004 sizeof(bge_status_t))); 3005 3006 BGE_DEBUG(("TXD DONE: va=%p alen=%d off=%d pa=%llx psz=%d", 3007 area.mem_va, 3008 area.alength, 3009 area.offset, 3010 area.cookie.dmac_laddress, 3011 area.cookie.dmac_size)); 3012 3013 ASSERT(area.alength == BGE_STATUS_PADDING); 3014 3015 DMA_ZERO(bgep->status_block); 3016 3017 return (DDI_SUCCESS); 3018 } 3019 3020 #undef BGE_DBG 3021 #define BGE_DBG BGE_DBG_INIT /* debug flag for this code */ 3022 3023 /* 3024 * This routine frees the transmit and receive buffers and descriptors. 3025 * Make sure the chip is stopped before calling it! 3026 */ 3027 void 3028 bge_free_bufs(bge_t *bgep) 3029 { 3030 int split; 3031 3032 BGE_TRACE(("bge_free_bufs($%p)", 3033 (void *)bgep)); 3034 3035 bge_free_dma_mem(&bgep->tx_desc); 3036 for (split = 0; split < BGE_RECV_RINGS_SPLIT; ++split) 3037 bge_free_dma_mem(&bgep->rx_desc[split]); 3038 for (split = 0; split < BGE_SPLIT; ++split) 3039 bge_free_dma_mem(&bgep->tx_buff[split]); 3040 for (split = 0; split < BGE_SPLIT; ++split) 3041 bge_free_dma_mem(&bgep->rx_buff[split]); 3042 } 3043 3044 /* 3045 * Determine (initial) MAC address ("BIA") to use for this interface 3046 */ 3047 3048 static void 3049 bge_find_mac_address(bge_t *bgep, chip_id_t *cidp) 3050 { 3051 struct ether_addr sysaddr; 3052 char propbuf[8]; /* "true" or "false", plus NUL */ 3053 uchar_t *bytes; 3054 int *ints; 3055 uint_t nelts; 3056 int err; 3057 3058 BGE_TRACE(("bge_find_mac_address($%p)", 3059 (void *)bgep)); 3060 3061 BGE_DEBUG(("bge_find_mac_address: hw_mac_addr %012llx, => %s (%sset)", 3062 cidp->hw_mac_addr, 3063 ether_sprintf((void *)cidp->vendor_addr.addr), 3064 cidp->vendor_addr.set ? "" : "not ")); 3065 3066 /* 3067 * The "vendor's factory-set address" may already have 3068 * been extracted from the chip, but if the property 3069 * "local-mac-address" is set we use that instead. It 3070 * will normally be set by OBP, but it could also be 3071 * specified in a .conf file(!) 3072 * 3073 * There doesn't seem to be a way to define byte-array 3074 * properties in a .conf, so we check whether it looks 3075 * like an array of 6 ints instead. 3076 * 3077 * Then, we check whether it looks like an array of 6 3078 * bytes (which it should, if OBP set it). If we can't 3079 * make sense of it either way, we'll ignore it. 3080 */ 3081 err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, bgep->devinfo, 3082 DDI_PROP_DONTPASS, localmac_propname, &ints, &nelts); 3083 if (err == DDI_PROP_SUCCESS) { 3084 if (nelts == ETHERADDRL) { 3085 while (nelts--) 3086 cidp->vendor_addr.addr[nelts] = ints[nelts]; 3087 cidp->vendor_addr.set = B_TRUE; 3088 } 3089 ddi_prop_free(ints); 3090 } 3091 3092 err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, bgep->devinfo, 3093 DDI_PROP_DONTPASS, localmac_propname, &bytes, &nelts); 3094 if (err == DDI_PROP_SUCCESS) { 3095 if (nelts == ETHERADDRL) { 3096 while (nelts--) 3097 cidp->vendor_addr.addr[nelts] = bytes[nelts]; 3098 cidp->vendor_addr.set = B_TRUE; 3099 } 3100 ddi_prop_free(bytes); 3101 } 3102 3103 BGE_DEBUG(("bge_find_mac_address: +local %s (%sset)", 3104 ether_sprintf((void *)cidp->vendor_addr.addr), 3105 cidp->vendor_addr.set ? "" : "not ")); 3106 3107 /* 3108 * Look up the OBP property "local-mac-address?". Note that even 3109 * though its value is a string (which should be "true" or "false"), 3110 * it can't be decoded by ddi_prop_lookup_string(9F). So, we zero 3111 * the buffer first and then fetch the property as an untyped array; 3112 * this may or may not include a final NUL, but since there will 3113 * always be one left at the end of the buffer we can now treat it 3114 * as a string anyway. 3115 */ 3116 nelts = sizeof (propbuf); 3117 bzero(propbuf, nelts--); 3118 err = ddi_getlongprop_buf(DDI_DEV_T_ANY, bgep->devinfo, 3119 DDI_PROP_CANSLEEP, localmac_boolname, propbuf, (int *)&nelts); 3120 3121 /* 3122 * Now, if the address still isn't set from the hardware (SEEPROM) 3123 * or the OBP or .conf property, OR if the user has foolishly set 3124 * 'local-mac-address? = false', use "the system address" instead 3125 * (but only if it's non-null i.e. has been set from the IDPROM). 3126 */ 3127 if (cidp->vendor_addr.set == B_FALSE || strcmp(propbuf, "false") == 0) 3128 if (localetheraddr(NULL, &sysaddr) != 0) { 3129 ethaddr_copy(&sysaddr, cidp->vendor_addr.addr); 3130 cidp->vendor_addr.set = B_TRUE; 3131 } 3132 3133 BGE_DEBUG(("bge_find_mac_address: +system %s (%sset)", 3134 ether_sprintf((void *)cidp->vendor_addr.addr), 3135 cidp->vendor_addr.set ? "" : "not ")); 3136 3137 /* 3138 * Finally(!), if there's a valid "mac-address" property (created 3139 * if we netbooted from this interface), we must use this instead 3140 * of any of the above to ensure that the NFS/install server doesn't 3141 * get confused by the address changing as Solaris takes over! 3142 */ 3143 err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, bgep->devinfo, 3144 DDI_PROP_DONTPASS, macaddr_propname, &bytes, &nelts); 3145 if (err == DDI_PROP_SUCCESS) { 3146 if (nelts == ETHERADDRL) { 3147 while (nelts--) 3148 cidp->vendor_addr.addr[nelts] = bytes[nelts]; 3149 cidp->vendor_addr.set = B_TRUE; 3150 } 3151 ddi_prop_free(bytes); 3152 } 3153 3154 BGE_DEBUG(("bge_find_mac_address: =final %s (%sset)", 3155 ether_sprintf((void *)cidp->vendor_addr.addr), 3156 cidp->vendor_addr.set ? "" : "not ")); 3157 } 3158 3159 /*ARGSUSED*/ 3160 int 3161 bge_check_acc_handle(bge_t *bgep, ddi_acc_handle_t handle) 3162 { 3163 ddi_fm_error_t de; 3164 3165 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION); 3166 ddi_fm_acc_err_clear(handle, DDI_FME_VERSION); 3167 return (de.fme_status); 3168 } 3169 3170 /*ARGSUSED*/ 3171 int 3172 bge_check_dma_handle(bge_t *bgep, ddi_dma_handle_t handle) 3173 { 3174 ddi_fm_error_t de; 3175 3176 ASSERT(bgep->progress & PROGRESS_BUFS); 3177 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION); 3178 return (de.fme_status); 3179 } 3180 3181 /* 3182 * The IO fault service error handling callback function 3183 */ 3184 /*ARGSUSED*/ 3185 static int 3186 bge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 3187 { 3188 /* 3189 * as the driver can always deal with an error in any dma or 3190 * access handle, we can just return the fme_status value. 3191 */ 3192 pci_ereport_post(dip, err, NULL); 3193 return (err->fme_status); 3194 } 3195 3196 static void 3197 bge_fm_init(bge_t *bgep) 3198 { 3199 ddi_iblock_cookie_t iblk; 3200 3201 /* Only register with IO Fault Services if we have some capability */ 3202 if (bgep->fm_capabilities) { 3203 bge_reg_accattr.devacc_attr_access = DDI_FLAGERR_ACC; 3204 dma_attr.dma_attr_flags = DDI_DMA_FLAGERR; 3205 3206 /* Register capabilities with IO Fault Services */ 3207 ddi_fm_init(bgep->devinfo, &bgep->fm_capabilities, &iblk); 3208 3209 /* 3210 * Initialize pci ereport capabilities if ereport capable 3211 */ 3212 if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) || 3213 DDI_FM_ERRCB_CAP(bgep->fm_capabilities)) 3214 pci_ereport_setup(bgep->devinfo); 3215 3216 /* 3217 * Register error callback if error callback capable 3218 */ 3219 if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities)) 3220 ddi_fm_handler_register(bgep->devinfo, 3221 bge_fm_error_cb, (void*) bgep); 3222 } else { 3223 /* 3224 * These fields have to be cleared of FMA if there are no 3225 * FMA capabilities at runtime. 3226 */ 3227 bge_reg_accattr.devacc_attr_access = DDI_DEFAULT_ACC; 3228 dma_attr.dma_attr_flags = 0; 3229 } 3230 } 3231 3232 static void 3233 bge_fm_fini(bge_t *bgep) 3234 { 3235 /* Only unregister FMA capabilities if we registered some */ 3236 if (bgep->fm_capabilities) { 3237 3238 /* 3239 * Release any resources allocated by pci_ereport_setup() 3240 */ 3241 if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) || 3242 DDI_FM_ERRCB_CAP(bgep->fm_capabilities)) 3243 pci_ereport_teardown(bgep->devinfo); 3244 3245 /* 3246 * Un-register error callback if error callback capable 3247 */ 3248 if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities)) 3249 ddi_fm_handler_unregister(bgep->devinfo); 3250 3251 /* Unregister from IO Fault Services */ 3252 ddi_fm_fini(bgep->devinfo); 3253 } 3254 } 3255 3256 static void 3257 #ifdef BGE_IPMI_ASF 3258 bge_unattach(bge_t *bgep, uint_t asf_mode) 3259 #else 3260 bge_unattach(bge_t *bgep) 3261 #endif 3262 { 3263 BGE_TRACE(("bge_unattach($%p)", 3264 (void *)bgep)); 3265 3266 /* 3267 * Flag that no more activity may be initiated 3268 */ 3269 bgep->progress &= ~PROGRESS_READY; 3270 3271 /* 3272 * Quiesce the PHY and MAC (leave it reset but still powered). 3273 * Clean up and free all BGE data structures 3274 */ 3275 if (bgep->periodic_id != NULL) { 3276 ddi_periodic_delete(bgep->periodic_id); 3277 bgep->periodic_id = NULL; 3278 } 3279 3280 if (bgep->progress & PROGRESS_KSTATS) 3281 bge_fini_kstats(bgep); 3282 if (bgep->progress & PROGRESS_PHY) 3283 bge_phys_reset(bgep); 3284 if (bgep->progress & PROGRESS_HWINT) { 3285 mutex_enter(bgep->genlock); 3286 #ifdef BGE_IPMI_ASF 3287 if (bge_chip_reset(bgep, B_FALSE, asf_mode) != DDI_SUCCESS) 3288 #else 3289 if (bge_chip_reset(bgep, B_FALSE) != DDI_SUCCESS) 3290 #endif 3291 ddi_fm_service_impact(bgep->devinfo, 3292 DDI_SERVICE_UNAFFECTED); 3293 #ifdef BGE_IPMI_ASF 3294 if (bgep->asf_enabled) { 3295 /* 3296 * This register has been overlaid. We restore its 3297 * initial value here. 3298 */ 3299 bge_nic_put32(bgep, BGE_NIC_DATA_SIG_ADDR, 3300 BGE_NIC_DATA_SIG); 3301 } 3302 #endif 3303 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) 3304 ddi_fm_service_impact(bgep->devinfo, 3305 DDI_SERVICE_UNAFFECTED); 3306 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) 3307 ddi_fm_service_impact(bgep->devinfo, 3308 DDI_SERVICE_UNAFFECTED); 3309 mutex_exit(bgep->genlock); 3310 } 3311 if (bgep->progress & PROGRESS_INTR) { 3312 bge_intr_disable(bgep); 3313 bge_fini_rings(bgep); 3314 } 3315 if (bgep->progress & PROGRESS_HWINT) { 3316 bge_rem_intrs(bgep); 3317 rw_destroy(bgep->errlock); 3318 mutex_destroy(bgep->softintrlock); 3319 mutex_destroy(bgep->genlock); 3320 } 3321 if (bgep->progress & PROGRESS_FACTOTUM) 3322 ddi_remove_softintr(bgep->factotum_id); 3323 if (bgep->progress & PROGRESS_RESCHED) 3324 ddi_remove_softintr(bgep->drain_id); 3325 if (bgep->progress & PROGRESS_BUFS) 3326 bge_free_bufs(bgep); 3327 if (bgep->progress & PROGRESS_REGS) { 3328 ddi_regs_map_free(&bgep->io_handle); 3329 if (bgep->ape_enabled) 3330 ddi_regs_map_free(&bgep->ape_handle); 3331 } 3332 if (bgep->progress & PROGRESS_CFG) 3333 pci_config_teardown(&bgep->cfg_handle); 3334 3335 bge_fm_fini(bgep); 3336 3337 ddi_remove_minor_node(bgep->devinfo, NULL); 3338 kmem_free(bgep->pstats, sizeof (bge_statistics_reg_t)); 3339 kmem_free(bgep, sizeof (*bgep)); 3340 } 3341 3342 static int 3343 bge_resume(dev_info_t *devinfo) 3344 { 3345 bge_t *bgep; /* Our private data */ 3346 chip_id_t *cidp; 3347 chip_id_t chipid; 3348 3349 bgep = ddi_get_driver_private(devinfo); 3350 if (bgep == NULL) 3351 return (DDI_FAILURE); 3352 3353 /* 3354 * Refuse to resume if the data structures aren't consistent 3355 */ 3356 if (bgep->devinfo != devinfo) 3357 return (DDI_FAILURE); 3358 3359 #ifdef BGE_IPMI_ASF 3360 /* 3361 * Power management hasn't been supported in BGE now. If you 3362 * want to implement it, please add the ASF/IPMI related 3363 * code here. 3364 */ 3365 3366 #endif 3367 3368 /* 3369 * Read chip ID & set up config space command register(s) 3370 * Refuse to resume if the chip has changed its identity! 3371 */ 3372 cidp = &bgep->chipid; 3373 mutex_enter(bgep->genlock); 3374 bge_chip_cfg_init(bgep, &chipid, B_FALSE); 3375 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 3376 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 3377 mutex_exit(bgep->genlock); 3378 return (DDI_FAILURE); 3379 } 3380 mutex_exit(bgep->genlock); 3381 if (chipid.vendor != cidp->vendor) 3382 return (DDI_FAILURE); 3383 if (chipid.device != cidp->device) 3384 return (DDI_FAILURE); 3385 if (chipid.revision != cidp->revision) 3386 return (DDI_FAILURE); 3387 if (chipid.asic_rev != cidp->asic_rev) 3388 return (DDI_FAILURE); 3389 3390 /* 3391 * All OK, reinitialise h/w & kick off GLD scheduling 3392 */ 3393 mutex_enter(bgep->genlock); 3394 if (bge_restart(bgep, B_TRUE) != DDI_SUCCESS) { 3395 (void) bge_check_acc_handle(bgep, bgep->cfg_handle); 3396 (void) bge_check_acc_handle(bgep, bgep->io_handle); 3397 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 3398 mutex_exit(bgep->genlock); 3399 return (DDI_FAILURE); 3400 } 3401 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 3402 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 3403 mutex_exit(bgep->genlock); 3404 return (DDI_FAILURE); 3405 } 3406 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 3407 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 3408 mutex_exit(bgep->genlock); 3409 return (DDI_FAILURE); 3410 } 3411 mutex_exit(bgep->genlock); 3412 return (DDI_SUCCESS); 3413 } 3414 3415 static int 3416 bge_fw_img_is_valid(bge_t *bgep, uint32_t offset) 3417 { 3418 uint32_t val; 3419 3420 if (bge_nvmem_read32(bgep, offset, &val) || 3421 (val & 0xfc000000) != 0x0c000000 || 3422 bge_nvmem_read32(bgep, offset + 4, &val) || 3423 val != 0) 3424 return (0); 3425 3426 return (1); 3427 } 3428 3429 static void 3430 bge_read_mgmtfw_ver(bge_t *bgep) 3431 { 3432 uint32_t val; 3433 uint32_t offset; 3434 uint32_t start; 3435 int i, vlen; 3436 3437 for (offset = NVM_DIR_START; 3438 offset < NVM_DIR_END; 3439 offset += NVM_DIRENT_SIZE) { 3440 if (bge_nvmem_read32(bgep, offset, &val)) 3441 return; 3442 3443 if ((val >> NVM_DIRTYPE_SHIFT) == NVM_DIRTYPE_ASFINI) 3444 break; 3445 } 3446 3447 if (offset == NVM_DIR_END) 3448 return; 3449 3450 if (bge_nvmem_read32(bgep, offset - 4, &start)) 3451 return; 3452 3453 if (bge_nvmem_read32(bgep, offset + 4, &offset) || 3454 !bge_fw_img_is_valid(bgep, offset) || 3455 bge_nvmem_read32(bgep, offset + 8, &val)) 3456 return; 3457 3458 offset += val - start; 3459 3460 vlen = strlen(bgep->fw_version); 3461 3462 bgep->fw_version[vlen++] = ','; 3463 bgep->fw_version[vlen++] = ' '; 3464 3465 for (i = 0; i < 4; i++) { 3466 uint32_t v; 3467 3468 if (bge_nvmem_read32(bgep, offset, &v)) 3469 return; 3470 3471 v = BE_32(v); 3472 3473 offset += sizeof(v); 3474 3475 if (vlen > BGE_FW_VER_SIZE - sizeof(v)) { 3476 memcpy(&bgep->fw_version[vlen], &v, BGE_FW_VER_SIZE - vlen); 3477 break; 3478 } 3479 3480 memcpy(&bgep->fw_version[vlen], &v, sizeof(v)); 3481 vlen += sizeof(v); 3482 } 3483 } 3484 3485 static void 3486 bge_read_dash_ver(bge_t *bgep) 3487 { 3488 int vlen; 3489 uint32_t apedata; 3490 char *fwtype; 3491 3492 if (!bgep->ape_enabled || !bgep->asf_enabled) 3493 return; 3494 3495 apedata = bge_ape_get32(bgep, BGE_APE_SEG_SIG); 3496 if (apedata != APE_SEG_SIG_MAGIC) 3497 return; 3498 3499 apedata = bge_ape_get32(bgep, BGE_APE_FW_STATUS); 3500 if (!(apedata & APE_FW_STATUS_READY)) 3501 return; 3502 3503 apedata = bge_ape_get32(bgep, BGE_APE_FW_VERSION); 3504 3505 if (bge_ape_get32(bgep, BGE_APE_FW_FEATURES) & 3506 BGE_APE_FW_FEATURE_NCSI) { 3507 bgep->ape_has_ncsi = B_TRUE; 3508 fwtype = "NCSI"; 3509 } else if ((bgep->chipid.device == DEVICE_ID_5725) || 3510 (bgep->chipid.device == DEVICE_ID_5727)) { 3511 fwtype = "SMASH"; 3512 } else { 3513 fwtype = "DASH"; 3514 } 3515 3516 vlen = strlen(bgep->fw_version); 3517 3518 snprintf(&bgep->fw_version[vlen], BGE_FW_VER_SIZE - vlen, 3519 " %s v%d.%d.%d.%d", fwtype, 3520 (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT, 3521 (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT, 3522 (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT, 3523 (apedata & APE_FW_VERSION_BLDMSK)); 3524 } 3525 3526 static void 3527 bge_read_bc_ver(bge_t *bgep) 3528 { 3529 uint32_t val; 3530 uint32_t offset; 3531 uint32_t start; 3532 uint32_t ver_offset; 3533 int i, dst_off; 3534 uint32_t major; 3535 uint32_t minor; 3536 boolean_t newver = B_FALSE; 3537 3538 if (bge_nvmem_read32(bgep, 0xc, &offset) || 3539 bge_nvmem_read32(bgep, 0x4, &start)) 3540 return; 3541 3542 if (bge_nvmem_read32(bgep, offset, &val)) 3543 return; 3544 3545 if ((val & 0xfc000000) == 0x0c000000) { 3546 if (bge_nvmem_read32(bgep, offset + 4, &val)) 3547 return; 3548 3549 if (val == 0) 3550 newver = B_TRUE; 3551 } 3552 3553 dst_off = strlen(bgep->fw_version); 3554 3555 if (newver) { 3556 if (((BGE_FW_VER_SIZE - dst_off) < 16) || 3557 bge_nvmem_read32(bgep, offset + 8, &ver_offset)) 3558 return; 3559 3560 offset = offset + ver_offset - start; 3561 for (i = 0; i < 16; i += 4) { 3562 if (bge_nvmem_read32(bgep, offset + i, &val)) 3563 return; 3564 val = BE_32(val); 3565 memcpy(bgep->fw_version + dst_off + i, &val, 3566 sizeof(val)); 3567 } 3568 } else { 3569 if (bge_nvmem_read32(bgep, NVM_PTREV_BCVER, &ver_offset)) 3570 return; 3571 3572 major = (ver_offset & NVM_BCVER_MAJMSK) >> NVM_BCVER_MAJSFT; 3573 minor = ver_offset & NVM_BCVER_MINMSK; 3574 snprintf(&bgep->fw_version[dst_off], BGE_FW_VER_SIZE - dst_off, 3575 "v%d.%02d", major, minor); 3576 } 3577 } 3578 3579 static void 3580 bge_read_fw_ver(bge_t *bgep) 3581 { 3582 uint32_t val; 3583 uint32_t magic; 3584 3585 *bgep->fw_version = 0; 3586 3587 if ((bgep->chipid.nvtype == BGE_NVTYPE_NONE) || 3588 (bgep->chipid.nvtype == BGE_NVTYPE_UNKNOWN)) { 3589 snprintf(bgep->fw_version, sizeof(bgep->fw_version), "sb"); 3590 return; 3591 } 3592 3593 mutex_enter(bgep->genlock); 3594 3595 bge_nvmem_read32(bgep, 0, &magic); 3596 3597 if (magic == EEPROM_MAGIC) { 3598 bge_read_bc_ver(bgep); 3599 } else { 3600 /* ignore other configs for now */ 3601 mutex_exit(bgep->genlock); 3602 return; 3603 } 3604 3605 if (bgep->ape_enabled) { 3606 if (bgep->asf_enabled) { 3607 bge_read_dash_ver(bgep); 3608 } 3609 } else if (bgep->asf_enabled) { 3610 bge_read_mgmtfw_ver(bgep); 3611 } 3612 3613 mutex_exit(bgep->genlock); 3614 3615 bgep->fw_version[BGE_FW_VER_SIZE - 1] = 0; /* safety */ 3616 } 3617 3618 /* 3619 * attach(9E) -- Attach a device to the system 3620 * 3621 * Called once for each board successfully probed. 3622 */ 3623 static int 3624 bge_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) 3625 { 3626 bge_t *bgep; /* Our private data */ 3627 mac_register_t *macp; 3628 chip_id_t *cidp; 3629 caddr_t regs; 3630 int instance; 3631 int err; 3632 int intr_types; 3633 int *props = NULL; 3634 uint_t numProps; 3635 uint32_t regval; 3636 uint32_t pci_state_reg; 3637 #ifdef BGE_IPMI_ASF 3638 uint32_t mhcrValue; 3639 #ifdef __sparc 3640 uint16_t value16; 3641 #endif 3642 #ifdef BGE_NETCONSOLE 3643 int retval; 3644 #endif 3645 #endif 3646 3647 instance = ddi_get_instance(devinfo); 3648 3649 BGE_GTRACE(("bge_attach($%p, %d) instance %d", 3650 (void *)devinfo, cmd, instance)); 3651 BGE_BRKPT(NULL, "bge_attach"); 3652 3653 switch (cmd) { 3654 default: 3655 return (DDI_FAILURE); 3656 3657 case DDI_RESUME: 3658 return (bge_resume(devinfo)); 3659 3660 case DDI_ATTACH: 3661 break; 3662 } 3663 3664 bgep = kmem_zalloc(sizeof (*bgep), KM_SLEEP); 3665 bgep->pstats = kmem_zalloc(sizeof (bge_statistics_reg_t), KM_SLEEP); 3666 ddi_set_driver_private(devinfo, bgep); 3667 bgep->bge_guard = BGE_GUARD; 3668 bgep->devinfo = devinfo; 3669 bgep->param_drain_max = 64; 3670 bgep->param_msi_cnt = 0; 3671 bgep->param_loop_mode = 0; 3672 3673 /* 3674 * Initialize more fields in BGE private data 3675 */ 3676 bgep->debug = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3677 DDI_PROP_DONTPASS, debug_propname, bge_debug); 3678 (void) snprintf(bgep->ifname, sizeof (bgep->ifname), "%s%d", 3679 BGE_DRIVER_NAME, instance); 3680 3681 /* 3682 * Initialize for fma support 3683 */ 3684 bgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3685 DDI_PROP_DONTPASS, fm_cap, 3686 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 3687 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 3688 BGE_DEBUG(("bgep->fm_capabilities = %d", bgep->fm_capabilities)); 3689 bge_fm_init(bgep); 3690 3691 /* 3692 * Look up the IOMMU's page size for DVMA mappings (must be 3693 * a power of 2) and convert to a mask. This can be used to 3694 * determine whether a message buffer crosses a page boundary. 3695 * Note: in 2s complement binary notation, if X is a power of 3696 * 2, then -X has the representation "11...1100...00". 3697 */ 3698 bgep->pagemask = dvma_pagesize(devinfo); 3699 ASSERT(ddi_ffs(bgep->pagemask) == ddi_fls(bgep->pagemask)); 3700 bgep->pagemask = -bgep->pagemask; 3701 3702 /* 3703 * Map config space registers 3704 * Read chip ID & set up config space command register(s) 3705 * 3706 * Note: this leaves the chip accessible by Memory Space 3707 * accesses, but with interrupts and Bus Mastering off. 3708 * This should ensure that nothing untoward will happen 3709 * if it has been left active by the (net-)bootloader. 3710 * We'll re-enable Bus Mastering once we've reset the chip, 3711 * and allow interrupts only when everything else is set up. 3712 */ 3713 err = pci_config_setup(devinfo, &bgep->cfg_handle); 3714 #ifdef BGE_IPMI_ASF 3715 #ifdef __sparc 3716 /* 3717 * We need to determine the type of chipset for accessing some configure 3718 * registers. (This information will be used by bge_ind_put32, 3719 * bge_ind_get32 and bge_nic_read32) 3720 */ 3721 bgep->chipid.device = pci_config_get16(bgep->cfg_handle, 3722 PCI_CONF_DEVID); 3723 value16 = pci_config_get16(bgep->cfg_handle, PCI_CONF_COMM); 3724 value16 = value16 | (PCI_COMM_MAE | PCI_COMM_ME); 3725 pci_config_put16(bgep->cfg_handle, PCI_CONF_COMM, value16); 3726 mhcrValue = MHCR_ENABLE_INDIRECT_ACCESS | 3727 MHCR_ENABLE_TAGGED_STATUS_MODE | 3728 MHCR_MASK_INTERRUPT_MODE | 3729 MHCR_MASK_PCI_INT_OUTPUT | 3730 MHCR_CLEAR_INTERRUPT_INTA | 3731 MHCR_ENABLE_ENDIAN_WORD_SWAP | 3732 MHCR_ENABLE_ENDIAN_BYTE_SWAP; 3733 /* 3734 * For some chipsets (e.g., BCM5718), if MHCR_ENABLE_ENDIAN_BYTE_SWAP 3735 * has been set in PCI_CONF_COMM already, we need to write the 3736 * byte-swapped value to it. So we just write zero first for simplicity. 3737 */ 3738 if (DEVICE_5717_SERIES_CHIPSETS(bgep) || 3739 DEVICE_5725_SERIES_CHIPSETS(bgep)) 3740 pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, 0); 3741 #else 3742 mhcrValue = MHCR_ENABLE_INDIRECT_ACCESS | 3743 MHCR_ENABLE_TAGGED_STATUS_MODE | 3744 MHCR_MASK_INTERRUPT_MODE | 3745 MHCR_MASK_PCI_INT_OUTPUT | 3746 MHCR_CLEAR_INTERRUPT_INTA; 3747 #endif 3748 pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcrValue); 3749 bge_ind_put32(bgep, MEMORY_ARBITER_MODE_REG, 3750 bge_ind_get32(bgep, MEMORY_ARBITER_MODE_REG) | 3751 MEMORY_ARBITER_ENABLE); 3752 if (mhcrValue & MHCR_ENABLE_ENDIAN_WORD_SWAP) { 3753 bgep->asf_wordswapped = B_TRUE; 3754 } else { 3755 bgep->asf_wordswapped = B_FALSE; 3756 } 3757 bge_asf_get_config(bgep); 3758 #endif 3759 if (err != DDI_SUCCESS) { 3760 bge_problem(bgep, "pci_config_setup() failed"); 3761 goto attach_fail; 3762 } 3763 bgep->progress |= PROGRESS_CFG; 3764 cidp = &bgep->chipid; 3765 bzero(cidp, sizeof(*cidp)); 3766 bge_chip_cfg_init(bgep, cidp, B_FALSE); 3767 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 3768 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 3769 goto attach_fail; 3770 } 3771 3772 #ifdef BGE_IPMI_ASF 3773 if (DEVICE_5721_SERIES_CHIPSETS(bgep) || 3774 DEVICE_5714_SERIES_CHIPSETS(bgep)) { 3775 bgep->asf_newhandshake = B_TRUE; 3776 } else { 3777 bgep->asf_newhandshake = B_FALSE; 3778 } 3779 #endif 3780 3781 /* 3782 * Update those parts of the chip ID derived from volatile 3783 * registers with the values seen by OBP (in case the chip 3784 * has been reset externally and therefore lost them). 3785 */ 3786 cidp->subven = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3787 DDI_PROP_DONTPASS, subven_propname, cidp->subven); 3788 cidp->subdev = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3789 DDI_PROP_DONTPASS, subdev_propname, cidp->subdev); 3790 cidp->clsize = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3791 DDI_PROP_DONTPASS, clsize_propname, cidp->clsize); 3792 cidp->latency = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3793 DDI_PROP_DONTPASS, latency_propname, cidp->latency); 3794 cidp->rx_rings = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3795 DDI_PROP_DONTPASS, rxrings_propname, cidp->rx_rings); 3796 cidp->tx_rings = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3797 DDI_PROP_DONTPASS, txrings_propname, cidp->tx_rings); 3798 cidp->eee = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3799 DDI_PROP_DONTPASS, eee_propname, cidp->eee); 3800 3801 cidp->default_mtu = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo, 3802 DDI_PROP_DONTPASS, default_mtu, BGE_DEFAULT_MTU); 3803 if ((cidp->default_mtu < BGE_DEFAULT_MTU) || 3804 (cidp->default_mtu > BGE_MAXIMUM_MTU)) { 3805 cidp->default_mtu = BGE_DEFAULT_MTU; 3806 } 3807 3808 /* 3809 * Map operating registers 3810 */ 3811 err = ddi_regs_map_setup(devinfo, BGE_PCI_OPREGS_RNUMBER, 3812 ®s, 0, 0, &bge_reg_accattr, &bgep->io_handle); 3813 if (err != DDI_SUCCESS) { 3814 bge_problem(bgep, "ddi_regs_map_setup() failed"); 3815 goto attach_fail; 3816 } 3817 bgep->io_regs = regs; 3818 3819 bgep->ape_enabled = B_FALSE; 3820 bgep->ape_regs = NULL; 3821 if (DEVICE_5717_SERIES_CHIPSETS(bgep) || 3822 DEVICE_5725_SERIES_CHIPSETS(bgep)) { 3823 err = ddi_regs_map_setup(devinfo, BGE_PCI_APEREGS_RNUMBER, 3824 ®s, 0, 0, &bge_reg_accattr, &bgep->ape_handle); 3825 if (err != DDI_SUCCESS) { 3826 ddi_regs_map_free(&bgep->io_handle); 3827 bge_problem(bgep, "ddi_regs_map_setup() failed"); 3828 goto attach_fail; 3829 } 3830 bgep->ape_regs = regs; 3831 bgep->ape_enabled = B_TRUE; 3832 3833 /* 3834 * Allow reads and writes to the 3835 * APE register and memory space. 3836 */ 3837 3838 pci_state_reg = pci_config_get32(bgep->cfg_handle, 3839 PCI_CONF_BGE_PCISTATE); 3840 pci_state_reg |= PCISTATE_ALLOW_APE_CTLSPC_WR | 3841 PCISTATE_ALLOW_APE_SHMEM_WR | PCISTATE_ALLOW_APE_PSPACE_WR; 3842 pci_config_put32(bgep->cfg_handle, 3843 PCI_CONF_BGE_PCISTATE, pci_state_reg); 3844 3845 bge_ape_lock_init(bgep); 3846 } 3847 3848 bgep->progress |= PROGRESS_REGS; 3849 3850 /* 3851 * Characterise the device, so we know its requirements. 3852 * Then allocate the appropriate TX and RX descriptors & buffers. 3853 */ 3854 if (bge_chip_id_init(bgep) == EIO) { 3855 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 3856 goto attach_fail; 3857 } 3858 3859 err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, bgep->devinfo, 3860 0, "reg", &props, &numProps); 3861 if ((err == DDI_PROP_SUCCESS) && (numProps > 0)) { 3862 bgep->pci_bus = PCI_REG_BUS_G(props[0]); 3863 bgep->pci_dev = PCI_REG_DEV_G(props[0]); 3864 bgep->pci_func = PCI_REG_FUNC_G(props[0]); 3865 ddi_prop_free(props); 3866 } 3867 3868 if (DEVICE_5717_SERIES_CHIPSETS(bgep) || 3869 DEVICE_5725_SERIES_CHIPSETS(bgep)) { 3870 regval = bge_reg_get32(bgep, CPMU_STATUS_REG); 3871 if ((bgep->chipid.device == DEVICE_ID_5719) || 3872 (bgep->chipid.device == DEVICE_ID_5720)) { 3873 bgep->pci_func = 3874 ((regval & CPMU_STATUS_FUNC_NUM_5719) >> 3875 CPMU_STATUS_FUNC_NUM_5719_SHIFT); 3876 } else { 3877 bgep->pci_func = ((regval & CPMU_STATUS_FUNC_NUM) >> 3878 CPMU_STATUS_FUNC_NUM_SHIFT); 3879 } 3880 } 3881 3882 err = bge_alloc_bufs(bgep); 3883 if (err != DDI_SUCCESS) { 3884 bge_problem(bgep, "DMA buffer allocation failed"); 3885 goto attach_fail; 3886 } 3887 bgep->progress |= PROGRESS_BUFS; 3888 3889 /* 3890 * Add the softint handlers: 3891 * 3892 * Both of these handlers are used to avoid restrictions on the 3893 * context and/or mutexes required for some operations. In 3894 * particular, the hardware interrupt handler and its subfunctions 3895 * can detect a number of conditions that we don't want to handle 3896 * in that context or with that set of mutexes held. So, these 3897 * softints are triggered instead: 3898 * 3899 * the <resched> softint is triggered if we have previously 3900 * had to refuse to send a packet because of resource shortage 3901 * (we've run out of transmit buffers), but the send completion 3902 * interrupt handler has now detected that more buffers have 3903 * become available. 3904 * 3905 * the <factotum> is triggered if the h/w interrupt handler 3906 * sees the <link state changed> or <error> bits in the status 3907 * block. It's also triggered periodically to poll the link 3908 * state, just in case we aren't getting link status change 3909 * interrupts ... 3910 */ 3911 err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &bgep->drain_id, 3912 NULL, NULL, bge_send_drain, (caddr_t)bgep); 3913 if (err != DDI_SUCCESS) { 3914 bge_problem(bgep, "ddi_add_softintr() failed"); 3915 goto attach_fail; 3916 } 3917 bgep->progress |= PROGRESS_RESCHED; 3918 err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &bgep->factotum_id, 3919 NULL, NULL, bge_chip_factotum, (caddr_t)bgep); 3920 if (err != DDI_SUCCESS) { 3921 bge_problem(bgep, "ddi_add_softintr() failed"); 3922 goto attach_fail; 3923 } 3924 bgep->progress |= PROGRESS_FACTOTUM; 3925 3926 /* Get supported interrupt types */ 3927 if (ddi_intr_get_supported_types(devinfo, &intr_types) != DDI_SUCCESS) { 3928 bge_error(bgep, "ddi_intr_get_supported_types failed\n"); 3929 3930 goto attach_fail; 3931 } 3932 3933 BGE_DEBUG(("%s: ddi_intr_get_supported_types() returned: %x", 3934 bgep->ifname, intr_types)); 3935 3936 if ((intr_types & DDI_INTR_TYPE_MSI) && bgep->chipid.msi_enabled) { 3937 if (bge_add_intrs(bgep, DDI_INTR_TYPE_MSI) != DDI_SUCCESS) { 3938 bge_error(bgep, "MSI registration failed, " 3939 "trying FIXED interrupt type\n"); 3940 } else { 3941 BGE_DEBUG(("%s: Using MSI interrupt type", 3942 bgep->ifname)); 3943 bgep->intr_type = DDI_INTR_TYPE_MSI; 3944 bgep->progress |= PROGRESS_HWINT; 3945 } 3946 } 3947 3948 if (!(bgep->progress & PROGRESS_HWINT) && 3949 (intr_types & DDI_INTR_TYPE_FIXED)) { 3950 if (bge_add_intrs(bgep, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS) { 3951 bge_error(bgep, "FIXED interrupt " 3952 "registration failed\n"); 3953 goto attach_fail; 3954 } 3955 3956 BGE_DEBUG(("%s: Using FIXED interrupt type", bgep->ifname)); 3957 3958 bgep->intr_type = DDI_INTR_TYPE_FIXED; 3959 bgep->progress |= PROGRESS_HWINT; 3960 } 3961 3962 if (!(bgep->progress & PROGRESS_HWINT)) { 3963 bge_error(bgep, "No interrupts registered\n"); 3964 goto attach_fail; 3965 } 3966 3967 /* 3968 * Note that interrupts are not enabled yet as 3969 * mutex locks are not initialized. Initialize mutex locks. 3970 */ 3971 mutex_init(bgep->genlock, NULL, MUTEX_DRIVER, 3972 DDI_INTR_PRI(bgep->intr_pri)); 3973 mutex_init(bgep->softintrlock, NULL, MUTEX_DRIVER, 3974 DDI_INTR_PRI(bgep->intr_pri)); 3975 rw_init(bgep->errlock, NULL, RW_DRIVER, 3976 DDI_INTR_PRI(bgep->intr_pri)); 3977 3978 /* 3979 * Initialize rings. 3980 */ 3981 bge_init_rings(bgep); 3982 3983 /* 3984 * Now that mutex locks are initialized, enable interrupts. 3985 */ 3986 bge_intr_enable(bgep); 3987 bgep->progress |= PROGRESS_INTR; 3988 3989 /* 3990 * Initialise link state variables 3991 * Stop, reset & reinitialise the chip. 3992 * Initialise the (internal) PHY. 3993 */ 3994 bgep->link_state = LINK_STATE_UNKNOWN; 3995 3996 mutex_enter(bgep->genlock); 3997 3998 /* 3999 * Reset chip & rings to initial state; also reset address 4000 * filtering, promiscuity, loopback mode. 4001 */ 4002 #ifdef BGE_IPMI_ASF 4003 #ifdef BGE_NETCONSOLE 4004 if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) { 4005 #else 4006 if (bge_reset(bgep, ASF_MODE_SHUTDOWN) != DDI_SUCCESS) { 4007 #endif 4008 #else 4009 if (bge_reset(bgep) != DDI_SUCCESS) { 4010 #endif 4011 (void) bge_check_acc_handle(bgep, bgep->cfg_handle); 4012 (void) bge_check_acc_handle(bgep, bgep->io_handle); 4013 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 4014 mutex_exit(bgep->genlock); 4015 goto attach_fail; 4016 } 4017 4018 #ifdef BGE_IPMI_ASF 4019 if (bgep->asf_enabled) { 4020 bgep->asf_status = ASF_STAT_RUN_INIT; 4021 } 4022 #endif 4023 4024 bzero(bgep->mcast_hash, sizeof (bgep->mcast_hash)); 4025 bzero(bgep->mcast_refs, sizeof (bgep->mcast_refs)); 4026 bgep->promisc = B_FALSE; 4027 bgep->param_loop_mode = BGE_LOOP_NONE; 4028 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 4029 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 4030 mutex_exit(bgep->genlock); 4031 goto attach_fail; 4032 } 4033 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 4034 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 4035 mutex_exit(bgep->genlock); 4036 goto attach_fail; 4037 } 4038 4039 mutex_exit(bgep->genlock); 4040 4041 if (bge_phys_init(bgep) == EIO) { 4042 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST); 4043 goto attach_fail; 4044 } 4045 bgep->progress |= PROGRESS_PHY; 4046 4047 /* 4048 * initialize NDD-tweakable parameters 4049 */ 4050 if (bge_nd_init(bgep)) { 4051 bge_problem(bgep, "bge_nd_init() failed"); 4052 goto attach_fail; 4053 } 4054 bgep->progress |= PROGRESS_NDD; 4055 4056 /* 4057 * Create & initialise named kstats 4058 */ 4059 bge_init_kstats(bgep, instance); 4060 bgep->progress |= PROGRESS_KSTATS; 4061 4062 /* 4063 * Determine whether to override the chip's own MAC address 4064 */ 4065 bge_find_mac_address(bgep, cidp); 4066 { 4067 int slot; 4068 for (slot = 0; slot < MAC_ADDRESS_REGS_MAX; slot++) { 4069 ethaddr_copy(cidp->vendor_addr.addr, 4070 bgep->curr_addr[slot].addr); 4071 bgep->curr_addr[slot].set = 1; 4072 } 4073 } 4074 4075 bge_read_fw_ver(bgep); 4076 4077 bgep->unicst_addr_total = MAC_ADDRESS_REGS_MAX; 4078 bgep->unicst_addr_avail = MAC_ADDRESS_REGS_MAX; 4079 4080 if ((macp = mac_alloc(MAC_VERSION)) == NULL) 4081 goto attach_fail; 4082 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 4083 macp->m_driver = bgep; 4084 macp->m_dip = devinfo; 4085 macp->m_src_addr = cidp->vendor_addr.addr; 4086 macp->m_callbacks = &bge_m_callbacks; 4087 macp->m_min_sdu = 0; 4088 macp->m_max_sdu = cidp->ethmax_size - sizeof (struct ether_header); 4089 macp->m_margin = VLAN_TAGSZ; 4090 macp->m_priv_props = bge_priv_prop; 4091 4092 #if defined(ILLUMOS) 4093 bge_m_unicst(bgep, cidp->vendor_addr.addr); 4094 #endif 4095 4096 /* 4097 * Finally, we're ready to register ourselves with the MAC layer 4098 * interface; if this succeeds, we're all ready to start() 4099 */ 4100 err = mac_register(macp, &bgep->mh); 4101 mac_free(macp); 4102 if (err != 0) 4103 goto attach_fail; 4104 4105 mac_link_update(bgep->mh, LINK_STATE_UNKNOWN); 4106 4107 /* 4108 * Register a periodical handler. 4109 * bge_chip_cyclic() is invoked in kernel context. 4110 */ 4111 bgep->periodic_id = ddi_periodic_add(bge_chip_cyclic, bgep, 4112 BGE_CYCLIC_PERIOD, DDI_IPL_0); 4113 4114 bgep->progress |= PROGRESS_READY; 4115 ASSERT(bgep->bge_guard == BGE_GUARD); 4116 #ifdef BGE_IPMI_ASF 4117 #ifdef BGE_NETCONSOLE 4118 if (bgep->asf_enabled) { 4119 mutex_enter(bgep->genlock); 4120 retval = bge_chip_start(bgep, B_TRUE); 4121 mutex_exit(bgep->genlock); 4122 if (retval != DDI_SUCCESS) 4123 goto attach_fail; 4124 } 4125 #endif 4126 #endif 4127 4128 ddi_report_dev(devinfo); 4129 4130 return (DDI_SUCCESS); 4131 4132 attach_fail: 4133 #ifdef BGE_IPMI_ASF 4134 bge_unattach(bgep, ASF_MODE_SHUTDOWN); 4135 #else 4136 bge_unattach(bgep); 4137 #endif 4138 return (DDI_FAILURE); 4139 } 4140 4141 /* 4142 * bge_suspend() -- suspend transmit/receive for powerdown 4143 */ 4144 static int 4145 bge_suspend(bge_t *bgep) 4146 { 4147 /* 4148 * Stop processing and idle (powerdown) the PHY ... 4149 */ 4150 mutex_enter(bgep->genlock); 4151 #ifdef BGE_IPMI_ASF 4152 /* 4153 * Power management hasn't been supported in BGE now. If you 4154 * want to implement it, please add the ASF/IPMI related 4155 * code here. 4156 */ 4157 #endif 4158 bge_stop(bgep); 4159 if (bge_phys_idle(bgep) != DDI_SUCCESS) { 4160 (void) bge_check_acc_handle(bgep, bgep->io_handle); 4161 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 4162 mutex_exit(bgep->genlock); 4163 return (DDI_FAILURE); 4164 } 4165 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 4166 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 4167 mutex_exit(bgep->genlock); 4168 return (DDI_FAILURE); 4169 } 4170 mutex_exit(bgep->genlock); 4171 4172 return (DDI_SUCCESS); 4173 } 4174 4175 /* 4176 * quiesce(9E) entry point. 4177 * 4178 * This function is called when the system is single-threaded at high 4179 * PIL with preemption disabled. Therefore, this function must not be 4180 * blocked. 4181 * 4182 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 4183 * DDI_FAILURE indicates an error condition and should almost never happen. 4184 */ 4185 #ifdef __sparc 4186 #define bge_quiesce ddi_quiesce_not_supported 4187 #else 4188 static int 4189 bge_quiesce(dev_info_t *devinfo) 4190 { 4191 bge_t *bgep = ddi_get_driver_private(devinfo); 4192 4193 if (bgep == NULL) 4194 return (DDI_FAILURE); 4195 4196 if (bgep->intr_type == DDI_INTR_TYPE_FIXED) { 4197 bge_reg_set32(bgep, PCI_CONF_BGE_MHCR, 4198 MHCR_MASK_PCI_INT_OUTPUT); 4199 } else { 4200 bge_reg_clr32(bgep, MSI_MODE_REG, MSI_MSI_ENABLE); 4201 } 4202 4203 /* Stop the chip */ 4204 bge_chip_stop_nonblocking(bgep); 4205 4206 return (DDI_SUCCESS); 4207 } 4208 #endif 4209 4210 /* 4211 * detach(9E) -- Detach a device from the system 4212 */ 4213 static int 4214 bge_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) 4215 { 4216 bge_t *bgep; 4217 #ifdef BGE_IPMI_ASF 4218 uint_t asf_mode; 4219 asf_mode = ASF_MODE_NONE; 4220 #endif 4221 4222 BGE_GTRACE(("bge_detach($%p, %d)", (void *)devinfo, cmd)); 4223 4224 bgep = ddi_get_driver_private(devinfo); 4225 4226 switch (cmd) { 4227 default: 4228 return (DDI_FAILURE); 4229 4230 case DDI_SUSPEND: 4231 return (bge_suspend(bgep)); 4232 4233 case DDI_DETACH: 4234 break; 4235 } 4236 4237 #ifdef BGE_IPMI_ASF 4238 mutex_enter(bgep->genlock); 4239 if (bgep->asf_enabled && ((bgep->asf_status == ASF_STAT_RUN) || 4240 (bgep->asf_status == ASF_STAT_RUN_INIT))) { 4241 4242 bge_asf_update_status(bgep); 4243 if (bgep->asf_status == ASF_STAT_RUN) { 4244 bge_asf_stop_timer(bgep); 4245 } 4246 bgep->asf_status = ASF_STAT_STOP; 4247 4248 bge_asf_pre_reset_operations(bgep, BGE_SHUTDOWN_RESET); 4249 4250 if (bgep->asf_pseudostop) { 4251 bge_chip_stop(bgep, B_FALSE); 4252 bgep->bge_mac_state = BGE_MAC_STOPPED; 4253 bgep->asf_pseudostop = B_FALSE; 4254 } 4255 4256 asf_mode = ASF_MODE_POST_SHUTDOWN; 4257 4258 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) 4259 ddi_fm_service_impact(bgep->devinfo, 4260 DDI_SERVICE_UNAFFECTED); 4261 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) 4262 ddi_fm_service_impact(bgep->devinfo, 4263 DDI_SERVICE_UNAFFECTED); 4264 } 4265 mutex_exit(bgep->genlock); 4266 #endif 4267 4268 /* 4269 * Unregister from the GLD subsystem. This can fail, in 4270 * particular if there are DLPI style-2 streams still open - 4271 * in which case we just return failure without shutting 4272 * down chip operations. 4273 */ 4274 if (mac_unregister(bgep->mh) != 0) 4275 return (DDI_FAILURE); 4276 4277 /* 4278 * All activity stopped, so we can clean up & exit 4279 */ 4280 #ifdef BGE_IPMI_ASF 4281 bge_unattach(bgep, asf_mode); 4282 #else 4283 bge_unattach(bgep); 4284 #endif 4285 return (DDI_SUCCESS); 4286 } 4287 4288 4289 /* 4290 * ========== Module Loading Data & Entry Points ========== 4291 */ 4292 4293 #undef BGE_DBG 4294 #define BGE_DBG BGE_DBG_INIT /* debug flag for this code */ 4295 4296 DDI_DEFINE_STREAM_OPS(bge_dev_ops, 4297 nulldev, /* identify */ 4298 nulldev, /* probe */ 4299 bge_attach, /* attach */ 4300 bge_detach, /* detach */ 4301 nodev, /* reset */ 4302 NULL, /* cb_ops */ 4303 D_MP, /* bus_ops */ 4304 NULL, /* power */ 4305 bge_quiesce /* quiesce */ 4306 ); 4307 4308 static struct modldrv bge_modldrv = { 4309 &mod_driverops, /* Type of module. This one is a driver */ 4310 bge_ident, /* short description */ 4311 &bge_dev_ops /* driver specific ops */ 4312 }; 4313 4314 static struct modlinkage modlinkage = { 4315 MODREV_1, (void *)&bge_modldrv, NULL 4316 }; 4317 4318 4319 int 4320 _info(struct modinfo *modinfop) 4321 { 4322 return (mod_info(&modlinkage, modinfop)); 4323 } 4324 4325 int 4326 _init(void) 4327 { 4328 int status; 4329 4330 mac_init_ops(&bge_dev_ops, "bge"); 4331 status = mod_install(&modlinkage); 4332 if (status == DDI_SUCCESS) 4333 mutex_init(bge_log_mutex, NULL, MUTEX_DRIVER, NULL); 4334 else 4335 mac_fini_ops(&bge_dev_ops); 4336 return (status); 4337 } 4338 4339 int 4340 _fini(void) 4341 { 4342 int status; 4343 4344 status = mod_remove(&modlinkage); 4345 if (status == DDI_SUCCESS) { 4346 mac_fini_ops(&bge_dev_ops); 4347 mutex_destroy(bge_log_mutex); 4348 } 4349 return (status); 4350 } 4351 4352 4353 /* 4354 * bge_add_intrs: 4355 * 4356 * Register FIXED or MSI interrupts. 4357 */ 4358 static int 4359 bge_add_intrs(bge_t *bgep, int intr_type) 4360 { 4361 dev_info_t *dip = bgep->devinfo; 4362 int avail, actual, intr_size, count = 0; 4363 int i, flag, ret; 4364 4365 BGE_DEBUG(("bge_add_intrs($%p, 0x%x)", (void *)bgep, intr_type)); 4366 4367 /* Get number of interrupts */ 4368 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 4369 if ((ret != DDI_SUCCESS) || (count == 0)) { 4370 bge_error(bgep, "ddi_intr_get_nintrs() failure, ret: %d, " 4371 "count: %d", ret, count); 4372 4373 return (DDI_FAILURE); 4374 } 4375 4376 /* Get number of available interrupts */ 4377 ret = ddi_intr_get_navail(dip, intr_type, &avail); 4378 if ((ret != DDI_SUCCESS) || (avail == 0)) { 4379 bge_error(bgep, "ddi_intr_get_navail() failure, " 4380 "ret: %d, avail: %d\n", ret, avail); 4381 4382 return (DDI_FAILURE); 4383 } 4384 4385 if (avail < count) { 4386 BGE_DEBUG(("%s: nintrs() returned %d, navail returned %d", 4387 bgep->ifname, count, avail)); 4388 } 4389 4390 /* 4391 * BGE hardware generates only single MSI even though it claims 4392 * to support multiple MSIs. So, hard code MSI count value to 1. 4393 */ 4394 if (intr_type == DDI_INTR_TYPE_MSI) { 4395 count = 1; 4396 flag = DDI_INTR_ALLOC_STRICT; 4397 } else { 4398 flag = DDI_INTR_ALLOC_NORMAL; 4399 } 4400 4401 /* Allocate an array of interrupt handles */ 4402 intr_size = count * sizeof (ddi_intr_handle_t); 4403 bgep->htable = kmem_alloc(intr_size, KM_SLEEP); 4404 4405 /* Call ddi_intr_alloc() */ 4406 ret = ddi_intr_alloc(dip, bgep->htable, intr_type, 0, 4407 count, &actual, flag); 4408 4409 if ((ret != DDI_SUCCESS) || (actual == 0)) { 4410 bge_error(bgep, "ddi_intr_alloc() failed %d\n", ret); 4411 4412 kmem_free(bgep->htable, intr_size); 4413 return (DDI_FAILURE); 4414 } 4415 4416 if (actual < count) { 4417 BGE_DEBUG(("%s: Requested: %d, Received: %d", 4418 bgep->ifname, count, actual)); 4419 } 4420 4421 bgep->intr_cnt = actual; 4422 4423 /* 4424 * Get priority for first msi, assume remaining are all the same 4425 */ 4426 if ((ret = ddi_intr_get_pri(bgep->htable[0], &bgep->intr_pri)) != 4427 DDI_SUCCESS) { 4428 bge_error(bgep, "ddi_intr_get_pri() failed %d\n", ret); 4429 4430 /* Free already allocated intr */ 4431 for (i = 0; i < actual; i++) { 4432 (void) ddi_intr_free(bgep->htable[i]); 4433 } 4434 4435 kmem_free(bgep->htable, intr_size); 4436 return (DDI_FAILURE); 4437 } 4438 4439 /* Call ddi_intr_add_handler() */ 4440 for (i = 0; i < actual; i++) { 4441 if ((ret = ddi_intr_add_handler(bgep->htable[i], bge_intr, 4442 (caddr_t)bgep, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 4443 bge_error(bgep, "ddi_intr_add_handler() " 4444 "failed %d\n", ret); 4445 4446 /* Free already allocated intr */ 4447 for (i = 0; i < actual; i++) { 4448 (void) ddi_intr_free(bgep->htable[i]); 4449 } 4450 4451 kmem_free(bgep->htable, intr_size); 4452 return (DDI_FAILURE); 4453 } 4454 } 4455 4456 if ((ret = ddi_intr_get_cap(bgep->htable[0], &bgep->intr_cap)) 4457 != DDI_SUCCESS) { 4458 bge_error(bgep, "ddi_intr_get_cap() failed %d\n", ret); 4459 4460 for (i = 0; i < actual; i++) { 4461 (void) ddi_intr_remove_handler(bgep->htable[i]); 4462 (void) ddi_intr_free(bgep->htable[i]); 4463 } 4464 4465 kmem_free(bgep->htable, intr_size); 4466 return (DDI_FAILURE); 4467 } 4468 4469 return (DDI_SUCCESS); 4470 } 4471 4472 /* 4473 * bge_rem_intrs: 4474 * 4475 * Unregister FIXED or MSI interrupts 4476 */ 4477 static void 4478 bge_rem_intrs(bge_t *bgep) 4479 { 4480 int i; 4481 4482 BGE_DEBUG(("bge_rem_intrs($%p)", (void *)bgep)); 4483 4484 /* Call ddi_intr_remove_handler() */ 4485 for (i = 0; i < bgep->intr_cnt; i++) { 4486 (void) ddi_intr_remove_handler(bgep->htable[i]); 4487 (void) ddi_intr_free(bgep->htable[i]); 4488 } 4489 4490 kmem_free(bgep->htable, bgep->intr_cnt * sizeof (ddi_intr_handle_t)); 4491 } 4492 4493 4494 void 4495 bge_intr_enable(bge_t *bgep) 4496 { 4497 int i; 4498 4499 if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) { 4500 /* Call ddi_intr_block_enable() for MSI interrupts */ 4501 (void) ddi_intr_block_enable(bgep->htable, bgep->intr_cnt); 4502 } else { 4503 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 4504 for (i = 0; i < bgep->intr_cnt; i++) { 4505 (void) ddi_intr_enable(bgep->htable[i]); 4506 } 4507 } 4508 } 4509 4510 4511 void 4512 bge_intr_disable(bge_t *bgep) 4513 { 4514 int i; 4515 4516 if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) { 4517 /* Call ddi_intr_block_disable() */ 4518 (void) ddi_intr_block_disable(bgep->htable, bgep->intr_cnt); 4519 } else { 4520 for (i = 0; i < bgep->intr_cnt; i++) { 4521 (void) ddi_intr_disable(bgep->htable[i]); 4522 } 4523 } 4524 } 4525 4526 int 4527 bge_reprogram(bge_t *bgep) 4528 { 4529 int status = 0; 4530 4531 ASSERT(mutex_owned(bgep->genlock)); 4532 4533 if (bge_phys_update(bgep) != DDI_SUCCESS) { 4534 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 4535 status = IOC_INVAL; 4536 } 4537 #ifdef BGE_IPMI_ASF 4538 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) { 4539 #else 4540 if (bge_chip_sync(bgep) == DDI_FAILURE) { 4541 #endif 4542 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 4543 status = IOC_INVAL; 4544 } 4545 if (bgep->intr_type == DDI_INTR_TYPE_MSI) 4546 bge_chip_msi_trig(bgep); 4547 return (status); 4548 } 4549