5255 uts shouldn't open-code ISP2
1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 NetXen, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #include <sys/types.h> 30 #include <sys/conf.h> 31 #include <sys/debug.h> 32 #include <sys/stropts.h> 33 #include <sys/stream.h> 34 #include <sys/strlog.h> 35 #include <sys/kmem.h> 36 #include <sys/stat.h> 37 #include <sys/kstat.h> 38 #include <sys/vtrace.h> 39 #include <sys/dlpi.h> 40 #include <sys/strsun.h> 41 #include <sys/ethernet.h> 42 #include <sys/modctl.h> 43 #include <sys/errno.h> 44 #include <sys/dditypes.h> 45 #include <sys/ddi.h> 46 #include <sys/sunddi.h> 47 #include <sys/sysmacros.h> 48 #include <sys/pci.h> 49 #include <sys/ddi_intr.h> 50 51 #include "unm_nic.h" 52 #include "unm_nic_hw.h" 53 #include "unm_brdcfg.h" 54 #include "nic_cmn.h" 55 #include "nic_phan_reg.h" 56 #include "unm_nic_ioctl.h" 57 #include "nx_hw_pci_regs.h" 58 59 char ident[] = "Netxen nic driver v" UNM_NIC_VERSIONID; 60 char unm_nic_driver_name[] = "ntxn"; 61 int verbmsg = 0; 62 63 static char txbcopythreshold_propname[] = "tx_bcopy_threshold"; 64 static char rxbcopythreshold_propname[] = "rx_bcopy_threshold"; 65 static char rxringsize_propname[] = "rx_ring_size"; 66 static char jumborxringsize_propname[] = "jumbo_rx_ring_size"; 67 static char txringsize_propname[] = "tx_ring_size"; 68 static char defaultmtu_propname[] = "default_mtu"; 69 static char dmesg_propname[] = "verbose_driver"; 70 71 #define STRUCT_COPY(a, b) bcopy(&(b), &(a), sizeof (a)) 72 73 extern int unm_register_mac(unm_adapter *adapter); 74 extern void unm_fini_kstats(unm_adapter* adapter); 75 extern void unm_nic_remove(unm_adapter *adapter); 76 extern int unm_nic_suspend(unm_adapter *); 77 extern uint_t unm_intr(caddr_t, caddr_t); 78 79 /* Data access requirements. */ 80 static struct ddi_device_acc_attr unm_dev_attr = { 81 DDI_DEVICE_ATTR_V0, 82 DDI_STRUCTURE_LE_ACC, 83 DDI_STRICTORDER_ACC 84 }; 85 86 static struct ddi_device_acc_attr unm_buf_attr = { 87 DDI_DEVICE_ATTR_V0, 88 DDI_NEVERSWAP_ACC, 89 DDI_STRICTORDER_ACC 90 }; 91 92 static ddi_dma_attr_t unm_dma_attr_desc = { 93 DMA_ATTR_V0, /* dma_attr_version */ 94 0, /* dma_attr_addr_lo */ 95 0xffffffffull, /* dma_attr_addr_hi */ 96 0x000fffffull, /* dma_attr_count_max */ 97 4096, /* dma_attr_align */ 98 0x000fffffull, /* dma_attr_burstsizes */ 99 4, /* dma_attr_minxfer */ 100 0x003fffffull, /* dma_attr_maxxfer */ 101 0xffffffffull, /* dma_attr_seg */ 102 1, /* dma_attr_sgllen */ 103 1, /* dma_attr_granular */ 104 0 /* dma_attr_flags */ 105 }; 106 107 static ddi_dma_attr_t unm_dma_attr_rxbuf = { 108 DMA_ATTR_V0, /* dma_attr_version */ 109 0, /* dma_attr_addr_lo */ 110 0x7ffffffffULL, /* dma_attr_addr_hi */ 111 0xffffull, /* dma_attr_count_max */ 112 4096, /* dma_attr_align */ 113 0xfff8ull, /* dma_attr_burstsizes */ 114 1, /* dma_attr_minxfer */ 115 0xffffffffull, /* dma_attr_maxxfer */ 116 0xffffull, /* dma_attr_seg */ 117 1, /* dma_attr_sgllen */ 118 1, /* dma_attr_granular */ 119 0 /* dma_attr_flags */ 120 }; 121 122 static ddi_dma_attr_t unm_dma_attr_cmddesc = { 123 DMA_ATTR_V0, /* dma_attr_version */ 124 0, /* dma_attr_addr_lo */ 125 0x7ffffffffULL, /* dma_attr_addr_hi */ 126 0xffffull, /* dma_attr_count_max */ 127 1, /* dma_attr_align */ 128 0xfff8ull, /* dma_attr_burstsizes */ 129 1, /* dma_attr_minxfer */ 130 0xffff0ull, /* dma_attr_maxxfer */ 131 0xffffull, /* dma_attr_seg */ 132 16, /* dma_attr_sgllen */ 133 1, /* dma_attr_granular */ 134 0 /* dma_attr_flags */ 135 }; 136 137 static struct nx_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; 138 139 static int 140 check_hw_init(struct unm_adapter_s *adapter) 141 { 142 u32 val; 143 int ret = 0; 144 145 adapter->unm_nic_hw_read_wx(adapter, UNM_CAM_RAM(0x1fc), &val, 4); 146 if (val == 0x55555555) { 147 /* This is the first boot after power up */ 148 adapter->unm_nic_hw_read_wx(adapter, UNM_ROMUSB_GLB_SW_RESET, 149 &val, 4); 150 if (val != 0x80000f) 151 ret = -1; 152 153 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 154 /* Start P2 boot loader */ 155 adapter->unm_nic_pci_write_normalize(adapter, 156 UNM_CAM_RAM(0x1fc), UNM_BDINFO_MAGIC); 157 adapter->unm_nic_pci_write_normalize(adapter, 158 UNM_ROMUSB_GLB_PEGTUNE_DONE, 1); 159 } 160 } 161 return (ret); 162 } 163 164 165 static int 166 unm_get_flash_block(unm_adapter *adapter, int base, int size, uint32_t *buf) 167 { 168 int i, addr; 169 uint32_t *ptr32; 170 171 addr = base; 172 ptr32 = buf; 173 for (i = 0; i < size / sizeof (uint32_t); i++) { 174 if (rom_fast_read(adapter, addr, (int *)ptr32) == -1) 175 return (-1); 176 ptr32++; 177 addr += sizeof (uint32_t); 178 } 179 if ((char *)buf + size > (char *)ptr32) { 180 int local; 181 182 if (rom_fast_read(adapter, addr, &local) == -1) 183 return (-1); 184 (void) memcpy(ptr32, &local, 185 (uintptr_t)((char *)buf + size) - (uintptr_t)(char *)ptr32); 186 } 187 188 return (0); 189 } 190 191 192 static int 193 get_flash_mac_addr(struct unm_adapter_s *adapter, u64 mac[]) 194 { 195 uint32_t *pmac = (uint32_t *)&mac[0]; 196 197 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 198 uint32_t temp, crbaddr; 199 uint16_t *pmac16 = (uint16_t *)pmac; 200 201 // FOR P3, read from CAM RAM 202 203 int pci_func = adapter->ahw.pci_func; 204 pmac16 += (4 * pci_func); 205 crbaddr = CRB_MAC_BLOCK_START + (4 * ((pci_func/2) * 3)) + 206 (4 * (pci_func & 1)); 207 208 adapter->unm_nic_hw_read_wx(adapter, crbaddr, &temp, 4); 209 if (pci_func & 1) { 210 *pmac16++ = (temp >> 16); 211 adapter->unm_nic_hw_read_wx(adapter, crbaddr+4, 212 &temp, 4); 213 *pmac16++ = (temp & 0xffff); 214 *pmac16++ = (temp >> 16); 215 *pmac16 = 0; 216 } else { 217 *pmac16++ = (temp & 0xffff); 218 *pmac16++ = (temp >> 16); 219 adapter->unm_nic_hw_read_wx(adapter, crbaddr+4, 220 &temp, 4); 221 *pmac16++ = (temp & 0xffff); 222 *pmac16 = 0; 223 } 224 return (0); 225 } 226 227 228 if (unm_get_flash_block(adapter, USER_START + 229 offsetof(unm_user_info_t, mac_addr), FLASH_NUM_PORTS * sizeof (U64), 230 pmac) == -1) 231 return (-1); 232 233 if (*mac == ~0ULL) { 234 if (unm_get_flash_block(adapter, USER_START_OLD + 235 offsetof(unm_old_user_info_t, mac_addr), 236 FLASH_NUM_PORTS * sizeof (U64), pmac) == -1) 237 return (-1); 238 239 if (*mac == ~0ULL) 240 return (-1); 241 } 242 243 return (0); 244 } 245 246 static int 247 unm_initialize_dummy_dma(unm_adapter *adapter) 248 { 249 uint32_t hi, lo, temp; 250 ddi_dma_cookie_t cookie; 251 252 if (unm_pci_alloc_consistent(adapter, UNM_HOST_DUMMY_DMA_SIZE, 253 (caddr_t *)&adapter->dummy_dma.addr, &cookie, 254 &adapter->dummy_dma.dma_handle, 255 &adapter->dummy_dma.acc_handle) != DDI_SUCCESS) { 256 cmn_err(CE_WARN, "%s%d: Unable to alloc dummy dma buf\n", 257 adapter->name, adapter->instance); 258 return (DDI_ENOMEM); 259 } 260 261 adapter->dummy_dma.phys_addr = cookie.dmac_laddress; 262 263 hi = (adapter->dummy_dma.phys_addr >> 32) & 0xffffffff; 264 lo = adapter->dummy_dma.phys_addr & 0xffffffff; 265 266 UNM_READ_LOCK(&adapter->adapter_lock); 267 adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, 268 &hi, 4); 269 adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, 270 &lo, 4); 271 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 272 temp = DUMMY_BUF_INIT; 273 adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, 274 &temp, 4); 275 } 276 UNM_READ_UNLOCK(&adapter->adapter_lock); 277 278 return (DDI_SUCCESS); 279 } 280 281 void 282 unm_free_dummy_dma(unm_adapter *adapter) 283 { 284 if (adapter->dummy_dma.addr) { 285 unm_pci_free_consistent(&adapter->dummy_dma.dma_handle, 286 &adapter->dummy_dma.acc_handle); 287 adapter->dummy_dma.addr = NULL; 288 } 289 } 290 291 static int 292 unm_pci_cfg_init(unm_adapter *adapter) 293 { 294 hardware_context *hwcontext; 295 ddi_acc_handle_t pci_cfg_hdl; 296 int *reg_options; 297 dev_info_t *dip; 298 uint_t noptions; 299 int ret; 300 uint16_t vendor_id, pci_cmd_word; 301 uint8_t base_class, sub_class, prog_class; 302 uint32_t pexsizes; 303 struct nx_legacy_intr_set *legacy_intrp; 304 305 hwcontext = &adapter->ahw; 306 pci_cfg_hdl = adapter->pci_cfg_handle; 307 dip = adapter->dip; 308 309 vendor_id = pci_config_get16(pci_cfg_hdl, PCI_CONF_VENID); 310 311 if (vendor_id != 0x4040) { 312 cmn_err(CE_WARN, "%s%d: vendor id %x not 0x4040\n", 313 adapter->name, adapter->instance, vendor_id); 314 return (DDI_FAILURE); 315 } 316 317 ret = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, 318 dip, 0, "reg", ®_options, &noptions); 319 if (ret != DDI_PROP_SUCCESS) { 320 cmn_err(CE_WARN, "%s%d: Could not determine reg property\n", 321 adapter->name, adapter->instance); 322 return (DDI_FAILURE); 323 } 324 325 hwcontext->pci_func = (reg_options[0] >> 8) & 0x7; 326 ddi_prop_free(reg_options); 327 328 base_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_BASCLASS); 329 sub_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_SUBCLASS); 330 prog_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_PROGCLASS); 331 332 /* 333 * Need this check so that MEZZ card mgmt interface ntxn0 could fail 334 * attach & return and proceed to next interfaces ntxn1 and ntxn2 335 */ 336 if ((base_class != 0x02) || (sub_class != 0) || (prog_class != 0)) { 337 cmn_err(CE_WARN, "%s%d: Base/sub/prog class problem %d/%d/%d\n", 338 adapter->name, adapter->instance, base_class, sub_class, 339 prog_class); 340 return (DDI_FAILURE); 341 } 342 343 hwcontext->revision_id = pci_config_get8(pci_cfg_hdl, PCI_CONF_REVID); 344 345 /* 346 * Refuse to work with dubious P3 cards. 347 */ 348 if ((hwcontext->revision_id >= NX_P3_A0) && 349 (hwcontext->revision_id < NX_P3_B1)) { 350 cmn_err(CE_WARN, "%s%d: NetXen chip revs between 0x%x-0x%x " 351 "is unsupported\n", adapter->name, adapter->instance, 352 NX_P3_A0, NX_P3_B0); 353 return (DDI_FAILURE); 354 } 355 356 /* 357 * Save error reporting settings; clear [19:16] error status bits. 358 * Set max read request [14:12] to 0 for 128 bytes. Set max payload 359 * size[7:5] to 0 for for 128 bytes. 360 */ 361 if (NX_IS_REVISION_P2(hwcontext->revision_id)) { 362 pexsizes = pci_config_get32(pci_cfg_hdl, 0xd8); 363 pexsizes &= 7; 364 pexsizes |= 0xF0000; 365 pci_config_put32(pci_cfg_hdl, 0xd8, pexsizes); 366 } 367 368 pci_cmd_word = pci_config_get16(pci_cfg_hdl, PCI_CONF_COMM); 369 pci_cmd_word |= (PCI_COMM_INTX_DISABLE | PCI_COMM_SERR_ENABLE); 370 pci_config_put16(pci_cfg_hdl, PCI_CONF_COMM, pci_cmd_word); 371 372 if (hwcontext->revision_id >= NX_P3_B0) 373 legacy_intrp = &legacy_intr[hwcontext->pci_func]; 374 else 375 legacy_intrp = &legacy_intr[0]; 376 377 adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit; 378 adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg; 379 adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg; 380 adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg; 381 382 return (DDI_SUCCESS); 383 } 384 385 static void 386 unm_free_tx_dmahdl(unm_adapter *adapter) 387 { 388 int i; 389 unm_dmah_node_t *nodep; 390 391 mutex_enter(&adapter->tx_lock); 392 nodep = &adapter->tx_dma_hdls[0]; 393 394 for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) { 395 if (nodep->dmahdl != NULL) { 396 ddi_dma_free_handle(&nodep->dmahdl); 397 nodep->dmahdl = NULL; 398 } 399 nodep->next = NULL; 400 nodep++; 401 } 402 403 adapter->dmahdl_pool = NULL; 404 adapter->freehdls = 0; 405 mutex_exit(&adapter->tx_lock); 406 } 407 408 static int 409 unm_alloc_tx_dmahdl(unm_adapter *adapter) 410 { 411 int i; 412 unm_dmah_node_t *nodep = &adapter->tx_dma_hdls[0]; 413 414 mutex_enter(&adapter->tx_lock); 415 for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) { 416 if (ddi_dma_alloc_handle(adapter->dip, &unm_dma_attr_cmddesc, 417 DDI_DMA_DONTWAIT, NULL, &nodep->dmahdl) != DDI_SUCCESS) { 418 mutex_exit(&adapter->tx_lock); 419 goto alloc_hdl_fail; 420 } 421 422 if (i > 0) 423 nodep->next = nodep - 1; 424 nodep++; 425 } 426 427 adapter->dmahdl_pool = nodep - 1; 428 adapter->freehdls = i; 429 mutex_exit(&adapter->tx_lock); 430 431 return (DDI_SUCCESS); 432 433 alloc_hdl_fail: 434 unm_free_tx_dmahdl(adapter); 435 cmn_err(CE_WARN, "%s%d: Failed transmit ring dma handle allocation\n", 436 adapter->name, adapter->instance); 437 return (DDI_FAILURE); 438 } 439 440 static void 441 unm_free_dma_mem(dma_area_t *dma_p) 442 { 443 if (dma_p->dma_hdl != NULL) { 444 if (dma_p->ncookies) { 445 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 446 dma_p->ncookies = 0; 447 } 448 } 449 if (dma_p->acc_hdl != NULL) { 450 ddi_dma_mem_free(&dma_p->acc_hdl); 451 dma_p->acc_hdl = NULL; 452 } 453 if (dma_p->dma_hdl != NULL) { 454 ddi_dma_free_handle(&dma_p->dma_hdl); 455 dma_p->dma_hdl = NULL; 456 } 457 } 458 459 static int 460 unm_alloc_dma_mem(unm_adapter *adapter, int size, uint_t dma_flag, 461 ddi_dma_attr_t *dma_attr_p, dma_area_t *dma_p) 462 { 463 int ret; 464 caddr_t vaddr; 465 size_t actual_size; 466 ddi_dma_cookie_t cookie; 467 468 ret = ddi_dma_alloc_handle(adapter->dip, 469 dma_attr_p, DDI_DMA_DONTWAIT, 470 NULL, &dma_p->dma_hdl); 471 if (ret != DDI_SUCCESS) { 472 cmn_err(CE_WARN, "%s%d: Failed ddi_dma_alloc_handle\n", 473 adapter->name, adapter->instance); 474 goto dma_mem_fail; 475 } 476 477 ret = ddi_dma_mem_alloc(dma_p->dma_hdl, 478 size, &adapter->gc_attr_desc, 479 dma_flag & (DDI_DMA_STREAMING | DDI_DMA_CONSISTENT), 480 DDI_DMA_DONTWAIT, NULL, &vaddr, &actual_size, 481 &dma_p->acc_hdl); 482 if (ret != DDI_SUCCESS) { 483 cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() failed\n", 484 adapter->name, adapter->instance); 485 goto dma_mem_fail; 486 } 487 488 if (actual_size < size) { 489 cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() allocated small\n", 490 adapter->name, adapter->instance); 491 goto dma_mem_fail; 492 } 493 494 ret = ddi_dma_addr_bind_handle(dma_p->dma_hdl, 495 NULL, vaddr, size, dma_flag, DDI_DMA_DONTWAIT, 496 NULL, &cookie, &dma_p->ncookies); 497 if (ret != DDI_DMA_MAPPED || dma_p->ncookies != 1) { 498 cmn_err(CE_WARN, "%s%d: ddi_dma_addr_bind_handle() failed, " 499 "%d, %d\n", adapter->name, adapter->instance, ret, 500 dma_p->ncookies); 501 goto dma_mem_fail; 502 } 503 504 dma_p->dma_addr = cookie.dmac_laddress; 505 dma_p->vaddr = vaddr; 506 (void) memset(vaddr, 0, size); 507 508 return (DDI_SUCCESS); 509 510 dma_mem_fail: 511 unm_free_dma_mem(dma_p); 512 return (DDI_FAILURE); 513 } 514 515 static void 516 unm_free_tx_buffers(unm_adapter *adapter) 517 { 518 int i; 519 dma_area_t *dma_p; 520 struct unm_cmd_buffer *cmd_buf; 521 unm_dmah_node_t *nodep; 522 523 cmd_buf = &adapter->cmd_buf_arr[0]; 524 525 for (i = 0; i < adapter->MaxTxDescCount; i++) { 526 dma_p = &cmd_buf->dma_area; 527 unm_free_dma_mem(dma_p); 528 nodep = cmd_buf->head; 529 while (nodep != NULL) { 530 (void) ddi_dma_unbind_handle(nodep->dmahdl); 531 nodep = nodep->next; 532 } 533 if (cmd_buf->msg != NULL) 534 freemsg(cmd_buf->msg); 535 cmd_buf++; 536 } 537 adapter->freecmds = 0; 538 } 539 540 static int 541 unm_alloc_tx_buffers(unm_adapter *adapter) 542 { 543 int i, ret, size, allocated = 0; 544 dma_area_t *dma_p; 545 struct unm_cmd_buffer *cmd_buf; 546 547 cmd_buf = &adapter->cmd_buf_arr[0]; 548 size = adapter->maxmtu; 549 550 for (i = 0; i < adapter->MaxTxDescCount; i++) { 551 dma_p = &cmd_buf->dma_area; 552 ret = unm_alloc_dma_mem(adapter, size, 553 DDI_DMA_WRITE | DDI_DMA_STREAMING, 554 &unm_dma_attr_rxbuf, dma_p); 555 if (ret != DDI_SUCCESS) 556 goto alloc_tx_buffer_fail; 557 558 allocated++; 559 cmd_buf++; 560 } 561 adapter->freecmds = adapter->MaxTxDescCount; 562 return (DDI_SUCCESS); 563 564 alloc_tx_buffer_fail: 565 566 cmd_buf = &adapter->cmd_buf_arr[0]; 567 for (i = 0; i < allocated; i++) { 568 dma_p = &cmd_buf->dma_area; 569 unm_free_dma_mem(dma_p); 570 cmd_buf++; 571 } 572 cmn_err(CE_WARN, "%s%d: Failed transmit ring memory allocation\n", 573 adapter->name, adapter->instance); 574 return (DDI_FAILURE); 575 } 576 577 /* 578 * Called by freemsg() to "free" the resource. 579 */ 580 static void 581 unm_rx_buffer_recycle(char *arg) 582 { 583 unm_rx_buffer_t *rx_buffer = (unm_rx_buffer_t *)(uintptr_t)arg; 584 unm_adapter *adapter = rx_buffer->adapter; 585 unm_rcv_desc_ctx_t *rcv_desc = rx_buffer->rcv_desc; 586 587 rx_buffer->mp = desballoc(rx_buffer->dma_info.vaddr, 588 rcv_desc->dma_size, 0, &rx_buffer->rx_recycle); 589 590 if (rx_buffer->mp == NULL) 591 adapter->stats.desballocfailed++; 592 593 mutex_enter(rcv_desc->recycle_lock); 594 rx_buffer->next = rcv_desc->recycle_list; 595 rcv_desc->recycle_list = rx_buffer; 596 rcv_desc->rx_buf_recycle++; 597 mutex_exit(rcv_desc->recycle_lock); 598 } 599 600 static void 601 unm_destroy_rx_ring(unm_rcv_desc_ctx_t *rcv_desc) 602 { 603 uint32_t i, total_buf; 604 unm_rx_buffer_t *buf_pool; 605 606 total_buf = rcv_desc->rx_buf_total; 607 buf_pool = rcv_desc->rx_buf_pool; 608 for (i = 0; i < total_buf; i++) { 609 if (buf_pool->mp != NULL) 610 freemsg(buf_pool->mp); 611 unm_free_dma_mem(&buf_pool->dma_info); 612 buf_pool++; 613 } 614 615 kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf); 616 rcv_desc->rx_buf_pool = NULL; 617 rcv_desc->pool_list = NULL; 618 rcv_desc->recycle_list = NULL; 619 rcv_desc->rx_buf_free = 0; 620 621 mutex_destroy(rcv_desc->pool_lock); 622 mutex_destroy(rcv_desc->recycle_lock); 623 } 624 625 static int 626 unm_create_rx_ring(unm_adapter *adapter, unm_rcv_desc_ctx_t *rcv_desc) 627 { 628 int i, ret, allocate = 0, sreoff; 629 uint32_t total_buf; 630 dma_area_t *dma_info; 631 unm_rx_buffer_t *rx_buffer; 632 633 sreoff = adapter->ahw.cut_through ? 0 : IP_ALIGNMENT_BYTES; 634 635 /* temporarily set the total rx buffers two times of MaxRxDescCount */ 636 total_buf = rcv_desc->rx_buf_total = rcv_desc->MaxRxDescCount * 2; 637 638 rcv_desc->rx_buf_pool = kmem_zalloc(sizeof (unm_rx_buffer_t) * 639 total_buf, KM_SLEEP); 640 rx_buffer = rcv_desc->rx_buf_pool; 641 for (i = 0; i < total_buf; i++) { 642 dma_info = &rx_buffer->dma_info; 643 ret = unm_alloc_dma_mem(adapter, rcv_desc->buf_size, 644 DDI_DMA_READ | DDI_DMA_STREAMING, 645 &unm_dma_attr_rxbuf, dma_info); 646 if (ret != DDI_SUCCESS) 647 goto alloc_mem_failed; 648 else { 649 allocate++; 650 dma_info->vaddr = (void *) ((char *)dma_info->vaddr + 651 sreoff); 652 dma_info->dma_addr += sreoff; 653 rx_buffer->rx_recycle.free_func = 654 unm_rx_buffer_recycle; 655 rx_buffer->rx_recycle.free_arg = (caddr_t)rx_buffer; 656 rx_buffer->next = NULL; 657 rx_buffer->mp = desballoc(dma_info->vaddr, 658 rcv_desc->dma_size, 0, &rx_buffer->rx_recycle); 659 if (rx_buffer->mp == NULL) 660 adapter->stats.desballocfailed++; 661 rx_buffer->rcv_desc = rcv_desc; 662 rx_buffer->adapter = adapter; 663 rx_buffer++; 664 } 665 } 666 667 for (i = 0; i < (total_buf - 1); i++) { 668 rcv_desc->rx_buf_pool[i].next = &rcv_desc->rx_buf_pool[i + 1]; 669 } 670 671 rcv_desc->pool_list = rcv_desc->rx_buf_pool; 672 rcv_desc->recycle_list = NULL; 673 rcv_desc->rx_buf_free = total_buf; 674 675 mutex_init(rcv_desc->pool_lock, NULL, 676 MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri))); 677 mutex_init(rcv_desc->recycle_lock, NULL, 678 MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri))); 679 680 return (DDI_SUCCESS); 681 682 alloc_mem_failed: 683 rx_buffer = rcv_desc->rx_buf_pool; 684 for (i = 0; i < allocate; i++, rx_buffer++) { 685 dma_info = &rx_buffer->dma_info; 686 if (rx_buffer->mp != NULL) 687 freemsg(rx_buffer->mp); 688 unm_free_dma_mem(dma_info); 689 } 690 691 kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf); 692 rcv_desc->rx_buf_pool = NULL; 693 694 cmn_err(CE_WARN, "%s%d: Failed receive ring resource allocation\n", 695 adapter->name, adapter->instance); 696 return (DDI_FAILURE); 697 } 698 699 static void 700 unm_check_options(unm_adapter *adapter) 701 { 702 int i, ring, tx_desc, rx_desc, rx_jdesc, maxrx; 703 unm_recv_context_t *recv_ctx; 704 unm_rcv_desc_ctx_t *rcv_desc; 705 uint8_t revid = adapter->ahw.revision_id; 706 dev_info_t *dip = adapter->dip; 707 708 /* 709 * Reduce number of regular rcv desc to half on x86. 710 */ 711 maxrx = MAX_RCV_DESCRIPTORS; 712 #if !defined(_LP64) 713 maxrx /= 2; 714 #endif /* !_LP64 */ 715 716 verbmsg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 717 dmesg_propname, 0); 718 719 adapter->tx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, 720 dip, DDI_PROP_DONTPASS, txbcopythreshold_propname, 721 UNM_TX_BCOPY_THRESHOLD); 722 adapter->rx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, 723 dip, DDI_PROP_DONTPASS, rxbcopythreshold_propname, 724 UNM_RX_BCOPY_THRESHOLD); 725 726 tx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 727 txringsize_propname, MAX_CMD_DESCRIPTORS_HOST); 728 if (tx_desc >= 256 && tx_desc <= MAX_CMD_DESCRIPTORS && 729 !(tx_desc & (tx_desc - 1))) { 730 adapter->MaxTxDescCount = tx_desc; 731 } else { 732 cmn_err(CE_WARN, "%s%d: TxRingSize defaulting to %d, since " 733 ".conf value is not 2 power aligned in range 256 - %d\n", 734 adapter->name, adapter->instance, MAX_CMD_DESCRIPTORS_HOST, 735 MAX_CMD_DESCRIPTORS); 736 adapter->MaxTxDescCount = MAX_CMD_DESCRIPTORS_HOST; 737 } 738 739 rx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 740 rxringsize_propname, maxrx); 741 if (rx_desc >= NX_MIN_DRIVER_RDS_SIZE && 742 rx_desc <= NX_MAX_SUPPORTED_RDS_SIZE && 743 !(rx_desc & (rx_desc - 1))) { 744 adapter->MaxRxDescCount = rx_desc; 745 } else { 746 cmn_err(CE_WARN, "%s%d: RxRingSize defaulting to %d, since " 747 ".conf value is not 2 power aligned in range %d - %d\n", 748 adapter->name, adapter->instance, MAX_RCV_DESCRIPTORS, 749 NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_RDS_SIZE); 750 adapter->MaxRxDescCount = MAX_RCV_DESCRIPTORS; 751 } 752 753 rx_jdesc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 754 jumborxringsize_propname, MAX_JUMBO_RCV_DESCRIPTORS); 755 if (rx_jdesc >= NX_MIN_DRIVER_RDS_SIZE && 756 rx_jdesc <= NX_MAX_SUPPORTED_JUMBO_RDS_SIZE && 757 !(rx_jdesc & (rx_jdesc - 1))) { 758 adapter->MaxJumboRxDescCount = rx_jdesc; 759 } else { 760 cmn_err(CE_WARN, "%s%d: JumboRingSize defaulting to %d, since " 761 ".conf value is not 2 power aligned in range %d - %d\n", 762 adapter->name, adapter->instance, MAX_JUMBO_RCV_DESCRIPTORS, 763 NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_JUMBO_RDS_SIZE); 764 adapter->MaxJumboRxDescCount = MAX_JUMBO_RCV_DESCRIPTORS; 765 } 766 767 /* 768 * Solaris does not use LRO, but older firmware needs to have a 769 * couple of descriptors for initialization. 770 */ 771 adapter->MaxLroRxDescCount = (adapter->fw_major < 4) ? 2 : 0; 772 773 adapter->mtu = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 774 DDI_PROP_DONTPASS, defaultmtu_propname, MTU_SIZE); 775 776 if (adapter->mtu < MTU_SIZE) { 777 cmn_err(CE_WARN, "Raising mtu to %d\n", MTU_SIZE); 778 adapter->mtu = MTU_SIZE; 779 } 780 adapter->maxmtu = NX_IS_REVISION_P2(revid) ? P2_MAX_MTU : P3_MAX_MTU; 781 if (adapter->mtu > adapter->maxmtu) { 782 cmn_err(CE_WARN, "Lowering mtu to %d\n", adapter->maxmtu); 783 adapter->mtu = adapter->maxmtu; 784 } 785 786 adapter->maxmtu = adapter->mtu + NX_MAX_ETHERHDR; 787 788 /* 789 * If we are not expecting to receive jumbo frames, save memory and 790 * do not allocate. 791 */ 792 if (adapter->mtu <= MTU_SIZE) 793 adapter->MaxJumboRxDescCount = NX_MIN_DRIVER_RDS_SIZE; 794 795 for (i = 0; i < MAX_RCV_CTX; ++i) { 796 recv_ctx = &adapter->recv_ctx[i]; 797 798 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 799 rcv_desc = &recv_ctx->rcv_desc[ring]; 800 801 switch (RCV_DESC_TYPE(ring)) { 802 case RCV_DESC_NORMAL: 803 rcv_desc->MaxRxDescCount = 804 adapter->MaxRxDescCount; 805 if (adapter->ahw.cut_through) { 806 rcv_desc->dma_size = 807 NX_CT_DEFAULT_RX_BUF_LEN; 808 rcv_desc->buf_size = rcv_desc->dma_size; 809 } else { 810 rcv_desc->dma_size = 811 NX_RX_NORMAL_BUF_MAX_LEN; 812 rcv_desc->buf_size = 813 rcv_desc->dma_size + 814 IP_ALIGNMENT_BYTES; 815 } 816 break; 817 818 case RCV_DESC_JUMBO: 819 rcv_desc->MaxRxDescCount = 820 adapter->MaxJumboRxDescCount; 821 if (adapter->ahw.cut_through) { 822 rcv_desc->dma_size = 823 rcv_desc->buf_size = 824 NX_P3_RX_JUMBO_BUF_MAX_LEN; 825 } else { 826 if (NX_IS_REVISION_P2(revid)) 827 rcv_desc->dma_size = 828 NX_P2_RX_JUMBO_BUF_MAX_LEN; 829 else 830 rcv_desc->dma_size = 831 NX_P3_RX_JUMBO_BUF_MAX_LEN; 832 rcv_desc->buf_size = 833 rcv_desc->dma_size + 834 IP_ALIGNMENT_BYTES; 835 } 836 break; 837 838 case RCV_RING_LRO: 839 rcv_desc->MaxRxDescCount = 840 adapter->MaxLroRxDescCount; 841 rcv_desc->buf_size = MAX_RX_LRO_BUFFER_LENGTH; 842 rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; 843 break; 844 default: 845 break; 846 } 847 } 848 } 849 } 850 851 static void 852 vector128M(unm_adapter *aptr) 853 { 854 aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_128M; 855 aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_128M; 856 aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_128M; 857 aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_128M; 858 aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_ioctl_128M; 859 aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_ioctl_128M; 860 aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_128M; 861 aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_128M; 862 aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_128M; 863 aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_128M; 864 aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_128M; 865 aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_128M; 866 aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_128M; 867 aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_128M; 868 aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_128M; 869 } 870 871 static void 872 vector2M(unm_adapter *aptr) 873 { 874 aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_2M; 875 aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_2M; 876 aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_2M; 877 aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_2M; 878 aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_wx_2M; 879 aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_wx_2M; 880 aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_2M; 881 aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_2M; 882 aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_2M; 883 aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_2M; 884 aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_2M; 885 aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_2M; 886 aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_2M; 887 aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_2M; 888 aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_2M; 889 } 890 891 static int 892 unm_pci_map_setup(unm_adapter *adapter) 893 { 894 int ret; 895 caddr_t reg_base, db_base; 896 caddr_t mem_ptr0, mem_ptr1 = NULL, mem_ptr2 = NULL; 897 unsigned long pci_len0; 898 unsigned long first_page_group_start, first_page_group_end; 899 900 off_t regsize, dbsize = UNM_DB_MAPSIZE_BYTES; 901 dev_info_t *dip = adapter->dip; 902 903 adapter->ahw.qdr_sn_window = adapter->ahw.ddr_mn_window = -1; 904 905 /* map register space */ 906 907 ret = ddi_dev_regsize(dip, 1, ®size); 908 if (ret != DDI_SUCCESS) { 909 cmn_err(CE_WARN, "%s%d: failed to read reg size for bar0\n", 910 adapter->name, adapter->instance); 911 return (DDI_FAILURE); 912 } 913 914 ret = ddi_regs_map_setup(dip, 1, ®_base, 0, 915 regsize, &unm_dev_attr, &adapter->regs_handle); 916 if (ret != DDI_SUCCESS) { 917 cmn_err(CE_WARN, "%s%d: failed to map registers\n", 918 adapter->name, adapter->instance); 919 return (DDI_FAILURE); 920 } 921 922 mem_ptr0 = reg_base; 923 924 if (regsize == UNM_PCI_128MB_SIZE) { 925 pci_len0 = FIRST_PAGE_GROUP_SIZE; 926 mem_ptr1 = mem_ptr0 + SECOND_PAGE_GROUP_START; 927 mem_ptr2 = mem_ptr0 + THIRD_PAGE_GROUP_START; 928 first_page_group_start = FIRST_PAGE_GROUP_START; 929 first_page_group_end = FIRST_PAGE_GROUP_END; 930 vector128M(adapter); 931 } else if (regsize == UNM_PCI_32MB_SIZE) { 932 pci_len0 = 0; 933 mem_ptr1 = mem_ptr0; 934 mem_ptr2 = mem_ptr0 + 935 (THIRD_PAGE_GROUP_START - SECOND_PAGE_GROUP_START); 936 first_page_group_start = 0; 937 first_page_group_end = 0; 938 vector128M(adapter); 939 } else if (regsize == UNM_PCI_2MB_SIZE) { 940 pci_len0 = UNM_PCI_2MB_SIZE; 941 first_page_group_start = 0; 942 first_page_group_end = 0; 943 adapter->ahw.ddr_mn_window = adapter->ahw.qdr_sn_window = 0; 944 adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW + 945 (adapter->ahw.pci_func * 0x20); 946 if (adapter->ahw.pci_func < 4) 947 adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW + 948 (adapter->ahw.pci_func * 0x20); 949 else 950 adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW + 951 0xA0 + ((adapter->ahw.pci_func - 4) * 0x10); 952 vector2M(adapter); 953 } else { 954 cmn_err(CE_WARN, "%s%d: invalid pci regs map size %ld\n", 955 adapter->name, adapter->instance, regsize); 956 ddi_regs_map_free(&adapter->regs_handle); 957 return (DDI_FAILURE); 958 } 959 960 adapter->ahw.pci_base0 = (unsigned long)mem_ptr0; 961 adapter->ahw.pci_len0 = pci_len0; 962 adapter->ahw.pci_base1 = (unsigned long)mem_ptr1; 963 adapter->ahw.pci_len1 = SECOND_PAGE_GROUP_SIZE; 964 adapter->ahw.pci_base2 = (unsigned long)mem_ptr2; 965 adapter->ahw.pci_len2 = THIRD_PAGE_GROUP_SIZE; 966 adapter->ahw.crb_base = 967 PCI_OFFSET_SECOND_RANGE(adapter, UNM_PCI_CRBSPACE); 968 969 adapter->ahw.first_page_group_start = first_page_group_start; 970 adapter->ahw.first_page_group_end = first_page_group_end; 971 972 /* map doorbell */ 973 974 ret = ddi_regs_map_setup(dip, 2, &db_base, 0, 975 dbsize, &unm_dev_attr, &adapter->db_handle); 976 if (ret != DDI_SUCCESS) { 977 cmn_err(CE_WARN, "%s%d: failed to map doorbell\n", 978 adapter->name, adapter->instance); 979 ddi_regs_map_free(&adapter->regs_handle); 980 return (DDI_FAILURE); 981 } 982 983 adapter->ahw.db_base = (unsigned long)db_base; 984 adapter->ahw.db_len = dbsize; 985 986 return (DDI_SUCCESS); 987 } 988 989 static int 990 unm_initialize_intr(unm_adapter *adapter) 991 { 992 993 int ret; 994 int type, count, avail, actual; 995 996 ret = ddi_intr_get_supported_types(adapter->dip, &type); 997 if (ret != DDI_SUCCESS) { 998 cmn_err(CE_WARN, "%s%d: ddi_intr_get_supported_types() " 999 "failed\n", adapter->name, adapter->instance); 1000 return (DDI_FAILURE); 1001 } 1002 1003 type = DDI_INTR_TYPE_MSI; 1004 ret = ddi_intr_get_nintrs(adapter->dip, type, &count); 1005 if ((ret == DDI_SUCCESS) && (count > 0)) 1006 goto found_msi; 1007 1008 type = DDI_INTR_TYPE_FIXED; 1009 ret = ddi_intr_get_nintrs(adapter->dip, type, &count); 1010 if ((ret != DDI_SUCCESS) || (count == 0)) { 1011 cmn_err(CE_WARN, 1012 "ddi_intr_get_nintrs() failure ret=%d\n", ret); 1013 return (DDI_FAILURE); 1014 } 1015 1016 found_msi: 1017 adapter->intr_type = type; 1018 adapter->flags &= ~(UNM_NIC_MSI_ENABLED | UNM_NIC_MSIX_ENABLED); 1019 if (type == DDI_INTR_TYPE_MSI) 1020 adapter->flags |= UNM_NIC_MSI_ENABLED; 1021 1022 /* Get number of available interrupts */ 1023 ret = ddi_intr_get_navail(adapter->dip, type, &avail); 1024 if ((ret != DDI_SUCCESS) || (avail == 0)) { 1025 cmn_err(CE_WARN, "ddi_intr_get_navail() failure, ret=%d\n", 1026 ret); 1027 return (DDI_FAILURE); 1028 } 1029 1030 ret = ddi_intr_alloc(adapter->dip, &adapter->intr_handle, 1031 type, 0, 1, &actual, DDI_INTR_ALLOC_NORMAL); 1032 if ((ret != DDI_SUCCESS) || (actual == 0)) { 1033 cmn_err(CE_WARN, "ddi_intr_alloc() failure: %d\n", ret); 1034 return (DDI_FAILURE); 1035 } 1036 1037 ret = ddi_intr_get_pri(adapter->intr_handle, &adapter->intr_pri); 1038 if (ret != DDI_SUCCESS) { 1039 cmn_err(CE_WARN, "ddi_intr_get_pri() failure: %d\n", ret); 1040 } 1041 1042 /* Call ddi_intr_add_handler() */ 1043 ret = ddi_intr_add_handler(adapter->intr_handle, unm_intr, 1044 (caddr_t)adapter, NULL); 1045 if (ret != DDI_SUCCESS) { 1046 cmn_err(CE_WARN, "%s%d: ddi_intr_add_handler() failure\n", 1047 adapter->name, adapter->instance); 1048 (void) ddi_intr_free(adapter->intr_handle); 1049 return (DDI_FAILURE); 1050 } 1051 1052 /* Add softintr if required */ 1053 1054 return (DDI_SUCCESS); 1055 1056 } 1057 1058 void 1059 unm_destroy_intr(unm_adapter *adapter) 1060 { 1061 /* disable interrupt */ 1062 if (adapter->intr_type == DDI_INTR_TYPE_MSI) 1063 (void) ddi_intr_block_disable(&adapter->intr_handle, 1); 1064 else 1065 (void) ddi_intr_disable(adapter->intr_handle); 1066 1067 (void) ddi_intr_remove_handler(adapter->intr_handle); 1068 (void) ddi_intr_free(adapter->intr_handle); 1069 1070 /* Remove the software intr handler */ 1071 } 1072 1073 static void 1074 netxen_set_port_mode(unm_adapter *adapter) 1075 { 1076 static int wol_port_mode = UNM_PORT_MODE_AUTO_NEG_1G; 1077 static int port_mode = UNM_PORT_MODE_AUTO_NEG; 1078 int btype = adapter->ahw.boardcfg.board_type, data = 0; 1079 1080 if (btype == UNM_BRDTYPE_P3_HMEZ || btype == UNM_BRDTYPE_P3_XG_LOM) { 1081 data = port_mode; /* set to port_mode normally */ 1082 if ((port_mode != UNM_PORT_MODE_802_3_AP) && 1083 (port_mode != UNM_PORT_MODE_XG) && 1084 (port_mode != UNM_PORT_MODE_AUTO_NEG_1G) && 1085 (port_mode != UNM_PORT_MODE_AUTO_NEG_XG)) 1086 data = UNM_PORT_MODE_AUTO_NEG; 1087 1088 adapter->unm_nic_hw_write_wx(adapter, UNM_PORT_MODE_ADDR, 1089 &data, 4); 1090 1091 if ((wol_port_mode != UNM_PORT_MODE_802_3_AP) && 1092 (wol_port_mode != UNM_PORT_MODE_XG) && 1093 (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_1G) && 1094 (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_XG)) 1095 wol_port_mode = UNM_PORT_MODE_AUTO_NEG; 1096 1097 adapter->unm_nic_hw_write_wx(adapter, UNM_WOL_PORT_MODE, 1098 &wol_port_mode, 4); 1099 } 1100 } 1101 1102 static void 1103 netxen_pcie_strap_init(unm_adapter *adapter) 1104 { 1105 ddi_acc_handle_t pcihdl = adapter->pci_cfg_handle; 1106 u32 chicken, control, c8c9value = 0xF1000; 1107 1108 adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3), 1109 &chicken, 4); 1110 1111 chicken &= 0xFCFFFFFF; /* clear chicken3 25:24 */ 1112 control = pci_config_get32(pcihdl, 0xD0); 1113 if ((control & 0x000F0000) != 0x00020000) /* is it gen1? */ 1114 chicken |= 0x01000000; 1115 adapter->unm_nic_hw_write_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3), 1116 &chicken, 4); 1117 control = pci_config_get32(pcihdl, 0xC8); 1118 control = pci_config_get32(pcihdl, 0xC8); 1119 pci_config_put32(pcihdl, 0xC8, c8c9value); 1120 } 1121 1122 static int 1123 netxen_read_mac_addr(unm_adapter *adapter) 1124 { 1125 u64 mac_addr[8 + 1]; 1126 unsigned char *p; 1127 int i; 1128 1129 if (get_flash_mac_addr(adapter, mac_addr) != 0) 1130 return (-1); 1131 1132 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1133 p = (unsigned char *)&mac_addr[adapter->ahw.pci_func]; 1134 else 1135 p = (unsigned char *)&mac_addr[adapter->portnum]; 1136 1137 for (i = 0; i < 6; i++) 1138 adapter->mac_addr[i] = p[5 - i]; 1139 1140 if (unm_nic_macaddr_set(adapter, adapter->mac_addr) != 0) 1141 return (-1); 1142 1143 return (0); 1144 } 1145 1146 static int 1147 unmattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1148 { 1149 unm_adapter *adapter; 1150 int i, first_driver = 0; 1151 int ret, temp; 1152 1153 switch (cmd) { 1154 case DDI_ATTACH: 1155 break; 1156 case DDI_RESUME: 1157 case DDI_PM_RESUME: 1158 default: 1159 return (DDI_FAILURE); 1160 } 1161 1162 adapter = kmem_zalloc(sizeof (unm_adapter), KM_SLEEP); 1163 adapter->dip = dip; 1164 ddi_set_driver_private(dip, adapter); 1165 adapter->instance = ddi_get_instance(dip); 1166 1167 adapter->name = ddi_driver_name(dip); 1168 1169 ret = pci_config_setup(dip, &adapter->pci_cfg_handle); 1170 if (ret != DDI_SUCCESS) { 1171 cmn_err(CE_WARN, "%s%d: pci_config_setup failed\n", 1172 adapter->name, adapter->instance); 1173 goto attach_setup_err; 1174 } 1175 1176 ret = unm_pci_cfg_init(adapter); 1177 if (ret != DDI_SUCCESS) 1178 goto attach_err; 1179 1180 ret = unm_pci_map_setup(adapter); 1181 if (ret != DDI_SUCCESS) 1182 goto attach_err; 1183 1184 if (unm_initialize_intr(adapter) != DDI_SUCCESS) 1185 goto attach_unmap_regs; 1186 1187 rw_init(&adapter->adapter_lock, NULL, 1188 RW_DRIVER, DDI_INTR_PRI(adapter->intr_pri)); 1189 mutex_init(&adapter->tx_lock, NULL, 1190 MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri))); 1191 mutex_init(&adapter->lock, NULL, 1192 MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri))); 1193 1194 adapter->portnum = (int8_t)adapter->ahw.pci_func; 1195 1196 /* 1197 * Set the CRB window to invalid. If any register in window 0 is 1198 * accessed it should set window to 0 and then reset it to 1. 1199 */ 1200 adapter->curr_window = 255; 1201 1202 adapter->fw_major = adapter->unm_nic_pci_read_normalize(adapter, 1203 UNM_FW_VERSION_MAJOR); 1204 1205 if (adapter->fw_major < 4) 1206 adapter->max_rds_rings = 3; 1207 else 1208 adapter->max_rds_rings = 2; 1209 1210 STRUCT_COPY(adapter->gc_dma_attr_desc, unm_dma_attr_desc); 1211 STRUCT_COPY(adapter->gc_attr_desc, unm_buf_attr); 1212 1213 ret = unm_nic_get_board_info(adapter); 1214 if (ret != DDI_SUCCESS) { 1215 cmn_err(CE_WARN, "%s%d: error reading board config\n", 1216 adapter->name, adapter->instance); 1217 goto attach_destroy_intr; 1218 } 1219 1220 /* Mezz cards have PCI function 0, 2, 3 enabled */ 1221 switch (adapter->ahw.boardcfg.board_type) { 1222 case UNM_BRDTYPE_P2_SB31_10G_IMEZ: 1223 case UNM_BRDTYPE_P2_SB31_10G_HMEZ: 1224 if (adapter->ahw.pci_func >= 2) { 1225 adapter->portnum = adapter->ahw.pci_func - 2; 1226 } 1227 default: 1228 break; 1229 } 1230 1231 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 1232 temp = UNM_CRB_READ_VAL_ADAPTER(UNM_MIU_MN_CONTROL, adapter); 1233 adapter->ahw.cut_through = NX_IS_SYSTEM_CUT_THROUGH(temp); 1234 if (adapter->ahw.pci_func == 0) 1235 first_driver = 1; 1236 } else { 1237 if (adapter->portnum == 0) 1238 first_driver = 1; 1239 } 1240 1241 unm_check_options(adapter); 1242 1243 if (first_driver) { 1244 int first_boot = adapter->unm_nic_pci_read_normalize(adapter, 1245 UNM_CAM_RAM(0x1fc)); 1246 1247 if (check_hw_init(adapter) != 0) { 1248 cmn_err(CE_WARN, "%s%d: Error in HW init sequence\n", 1249 adapter->name, adapter->instance); 1250 goto attach_destroy_intr; 1251 } 1252 1253 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1254 netxen_set_port_mode(adapter); 1255 1256 if (first_boot != 0x55555555) { 1257 temp = 0; 1258 adapter->unm_nic_hw_write_wx(adapter, CRB_CMDPEG_STATE, 1259 &temp, 4); 1260 if (pinit_from_rom(adapter, 0) != 0) 1261 goto attach_destroy_intr; 1262 1263 drv_usecwait(500); 1264 1265 ret = load_from_flash(adapter); 1266 if (ret != DDI_SUCCESS) 1267 goto attach_destroy_intr; 1268 } 1269 1270 if (ret = unm_initialize_dummy_dma(adapter)) 1271 goto attach_destroy_intr; 1272 1273 /* 1274 * Tell the hardware our version number. 1275 */ 1276 i = (_UNM_NIC_MAJOR << 16) | 1277 ((_UNM_NIC_MINOR << 8)) | (_UNM_NIC_SUBVERSION); 1278 adapter->unm_nic_hw_write_wx(adapter, CRB_DRIVER_VERSION, 1279 &i, 4); 1280 1281 /* Unlock the HW, prompting the boot sequence */ 1282 if ((first_boot == 0x55555555) && 1283 (NX_IS_REVISION_P2(adapter->ahw.revision_id))) 1284 adapter->unm_nic_pci_write_normalize(adapter, 1285 UNM_ROMUSB_GLB_PEGTUNE_DONE, 1); 1286 1287 /* Handshake with the card before we register the devices. */ 1288 if (phantom_init(adapter, 0) != DDI_SUCCESS) 1289 goto attach_destroy_intr; 1290 } 1291 1292 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1293 netxen_pcie_strap_init(adapter); 1294 1295 /* 1296 * See if the firmware gave us a virtual-physical port mapping. 1297 */ 1298 adapter->physical_port = adapter->portnum; 1299 i = adapter->unm_nic_pci_read_normalize(adapter, 1300 CRB_V2P(adapter->portnum)); 1301 if (i != 0x55555555) 1302 adapter->physical_port = (uint16_t)i; 1303 1304 adapter->ahw.linkup = 0; 1305 1306 if (receive_peg_ready(adapter)) { 1307 ret = -EIO; 1308 goto free_dummy_dma; 1309 } 1310 1311 if (netxen_read_mac_addr(adapter)) 1312 cmn_err(CE_WARN, "%s%d: Failed to read MAC addr\n", 1313 adapter->name, adapter->instance); 1314 1315 unm_nic_flash_print(adapter); 1316 1317 if (verbmsg != 0) { 1318 switch (adapter->ahw.board_type) { 1319 case UNM_NIC_GBE: 1320 cmn_err(CE_NOTE, "%s: QUAD GbE port %d initialized\n", 1321 unm_nic_driver_name, adapter->portnum); 1322 break; 1323 1324 case UNM_NIC_XGBE: 1325 cmn_err(CE_NOTE, "%s: XGbE port %d initialized\n", 1326 unm_nic_driver_name, adapter->portnum); 1327 break; 1328 } 1329 } 1330 1331 ret = unm_register_mac(adapter); 1332 if (ret != DDI_SUCCESS) { 1333 cmn_err(CE_NOTE, "%s%d: Mac registration error\n", 1334 adapter->name, adapter->instance); 1335 goto free_dummy_dma; 1336 } 1337 1338 return (DDI_SUCCESS); 1339 1340 free_dummy_dma: 1341 if (first_driver) 1342 unm_free_dummy_dma(adapter); 1343 attach_destroy_intr: 1344 unm_destroy_intr(adapter); 1345 attach_unmap_regs: 1346 ddi_regs_map_free(&(adapter->regs_handle)); 1347 ddi_regs_map_free(&(adapter->db_handle)); 1348 attach_err: 1349 pci_config_teardown(&adapter->pci_cfg_handle); 1350 attach_setup_err: 1351 kmem_free(adapter, sizeof (unm_adapter)); 1352 return (ret); 1353 } 1354 1355 static int 1356 unmdetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1357 { 1358 unm_adapter *adapter = (unm_adapter *)ddi_get_driver_private(dip); 1359 1360 if (adapter == NULL) 1361 return (DDI_FAILURE); 1362 1363 switch (cmd) { 1364 case DDI_DETACH: 1365 unm_fini_kstats(adapter); 1366 adapter->kstats[0] = NULL; 1367 1368 if (adapter->pci_cfg_handle != NULL) 1369 pci_config_teardown(&adapter->pci_cfg_handle); 1370 1371 unm_nd_cleanup(adapter); 1372 unm_nic_remove(adapter); 1373 return (DDI_SUCCESS); 1374 1375 case DDI_SUSPEND: 1376 return (unm_nic_suspend(adapter)); 1377 1378 default: 1379 break; 1380 } 1381 1382 return (DDI_FAILURE); 1383 } 1384 1385 int 1386 create_rxtx_rings(unm_adapter *adapter) 1387 { 1388 unm_recv_context_t *recv_ctx; 1389 unm_rcv_desc_ctx_t *rcv_desc; 1390 int i, ring; 1391 1392 adapter->cmd_buf_arr = (struct unm_cmd_buffer *)kmem_zalloc( 1393 sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount, 1394 KM_SLEEP); 1395 1396 for (i = 0; i < MAX_RCV_CTX; ++i) { 1397 recv_ctx = &adapter->recv_ctx[i]; 1398 1399 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1400 rcv_desc = &recv_ctx->rcv_desc[ring]; 1401 if (unm_create_rx_ring(adapter, rcv_desc) != 1402 DDI_SUCCESS) 1403 goto attach_free_cmdbufs; 1404 } 1405 } 1406 1407 if (unm_alloc_tx_dmahdl(adapter) != DDI_SUCCESS) 1408 goto attach_free_cmdbufs; 1409 1410 if (unm_alloc_tx_buffers(adapter) != DDI_SUCCESS) 1411 goto attach_free_tx_dmahdl; 1412 1413 return (DDI_SUCCESS); 1414 1415 attach_free_tx_buffers: 1416 unm_free_tx_buffers(adapter); 1417 attach_free_tx_dmahdl: 1418 unm_free_tx_dmahdl(adapter); 1419 attach_free_cmdbufs: 1420 kmem_free(adapter->cmd_buf_arr, sizeof (struct unm_cmd_buffer) * 1421 adapter->MaxTxDescCount); 1422 for (i = 0; i < MAX_RCV_CTX; ++i) { 1423 recv_ctx = &adapter->recv_ctx[i]; 1424 1425 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1426 rcv_desc = &recv_ctx->rcv_desc[ring]; 1427 if (rcv_desc->rx_buf_pool != NULL) 1428 unm_destroy_rx_ring(rcv_desc); 1429 } 1430 } 1431 return (DDI_FAILURE); 1432 } 1433 1434 void 1435 destroy_rxtx_rings(unm_adapter *adapter) 1436 { 1437 unm_recv_context_t *recv_ctx; 1438 unm_rcv_desc_ctx_t *rcv_desc; 1439 int ctx, ring; 1440 1441 unm_free_tx_buffers(adapter); 1442 unm_free_tx_dmahdl(adapter); 1443 1444 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 1445 recv_ctx = &adapter->recv_ctx[ctx]; 1446 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1447 rcv_desc = &recv_ctx->rcv_desc[ring]; 1448 if (rcv_desc->rx_buf_pool != NULL) 1449 unm_destroy_rx_ring(rcv_desc); 1450 } 1451 } 1452 1453 if (adapter->cmd_buf_arr != NULL) 1454 kmem_free(adapter->cmd_buf_arr, 1455 sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount); 1456 } 1457 1458 #ifdef SOLARIS11 1459 DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach, 1460 nodev, NULL, D_MP, NULL, NULL); 1461 #else 1462 DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach, 1463 nodev, NULL, D_MP, NULL); 1464 #endif 1465 1466 static struct modldrv modldrv = { 1467 &mod_driverops, /* Type of module. This one is a driver */ 1468 ident, 1469 &unm_ops, /* driver ops */ 1470 }; 1471 1472 static struct modlinkage modlinkage = { 1473 MODREV_1, 1474 (&modldrv), 1475 NULL 1476 }; 1477 1478 1479 int 1480 _init(void) 1481 { 1482 int ret; 1483 1484 unm_ops.devo_cb_ops->cb_str = NULL; 1485 mac_init_ops(&unm_ops, "ntxn"); 1486 1487 ret = mod_install(&modlinkage); 1488 if (ret != DDI_SUCCESS) { 1489 mac_fini_ops(&unm_ops); 1490 cmn_err(CE_WARN, "ntxn: mod_install failed\n"); 1491 } 1492 1493 return (ret); 1494 } 1495 1496 1497 int 1498 _fini(void) 1499 { 1500 int ret; 1501 1502 ret = mod_remove(&modlinkage); 1503 if (ret == DDI_SUCCESS) 1504 mac_fini_ops(&unm_ops); 1505 return (ret); 1506 } 1507 1508 int 1509 _info(struct modinfo *modinfop) 1510 { 1511 return (mod_info(&modlinkage, modinfop)); 1512 } --- EOF ---