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 && ISP2(tx_desc)) { 729 adapter->MaxTxDescCount = tx_desc; 730 } else { 731 cmn_err(CE_WARN, "%s%d: TxRingSize defaulting to %d, since " 732 ".conf value is not 2 power aligned in range 256 - %d\n", 733 adapter->name, adapter->instance, MAX_CMD_DESCRIPTORS_HOST, 734 MAX_CMD_DESCRIPTORS); 735 adapter->MaxTxDescCount = MAX_CMD_DESCRIPTORS_HOST; 736 } 737 738 rx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 739 rxringsize_propname, maxrx); 740 if (rx_desc >= NX_MIN_DRIVER_RDS_SIZE && 741 rx_desc <= NX_MAX_SUPPORTED_RDS_SIZE && ISP2(rx_desc)) { 742 adapter->MaxRxDescCount = rx_desc; 743 } else { 744 cmn_err(CE_WARN, "%s%d: RxRingSize defaulting to %d, since " 745 ".conf value is not 2 power aligned in range %d - %d\n", 746 adapter->name, adapter->instance, MAX_RCV_DESCRIPTORS, 747 NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_RDS_SIZE); 748 adapter->MaxRxDescCount = MAX_RCV_DESCRIPTORS; 749 } 750 751 rx_jdesc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 752 jumborxringsize_propname, MAX_JUMBO_RCV_DESCRIPTORS); 753 if (rx_jdesc >= NX_MIN_DRIVER_RDS_SIZE && 754 rx_jdesc <= NX_MAX_SUPPORTED_JUMBO_RDS_SIZE && ISP2(rx_jdesc)) { 755 adapter->MaxJumboRxDescCount = rx_jdesc; 756 } else { 757 cmn_err(CE_WARN, "%s%d: JumboRingSize defaulting to %d, since " 758 ".conf value is not 2 power aligned in range %d - %d\n", 759 adapter->name, adapter->instance, MAX_JUMBO_RCV_DESCRIPTORS, 760 NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_JUMBO_RDS_SIZE); 761 adapter->MaxJumboRxDescCount = MAX_JUMBO_RCV_DESCRIPTORS; 762 } 763 764 /* 765 * Solaris does not use LRO, but older firmware needs to have a 766 * couple of descriptors for initialization. 767 */ 768 adapter->MaxLroRxDescCount = (adapter->fw_major < 4) ? 2 : 0; 769 770 adapter->mtu = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 771 DDI_PROP_DONTPASS, defaultmtu_propname, MTU_SIZE); 772 773 if (adapter->mtu < MTU_SIZE) { 774 cmn_err(CE_WARN, "Raising mtu to %d\n", MTU_SIZE); 775 adapter->mtu = MTU_SIZE; 776 } 777 adapter->maxmtu = NX_IS_REVISION_P2(revid) ? P2_MAX_MTU : P3_MAX_MTU; 778 if (adapter->mtu > adapter->maxmtu) { 779 cmn_err(CE_WARN, "Lowering mtu to %d\n", adapter->maxmtu); 780 adapter->mtu = adapter->maxmtu; 781 } 782 783 adapter->maxmtu = adapter->mtu + NX_MAX_ETHERHDR; 784 785 /* 786 * If we are not expecting to receive jumbo frames, save memory and 787 * do not allocate. 788 */ 789 if (adapter->mtu <= MTU_SIZE) 790 adapter->MaxJumboRxDescCount = NX_MIN_DRIVER_RDS_SIZE; 791 792 for (i = 0; i < MAX_RCV_CTX; ++i) { 793 recv_ctx = &adapter->recv_ctx[i]; 794 795 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 796 rcv_desc = &recv_ctx->rcv_desc[ring]; 797 798 switch (RCV_DESC_TYPE(ring)) { 799 case RCV_DESC_NORMAL: 800 rcv_desc->MaxRxDescCount = 801 adapter->MaxRxDescCount; 802 if (adapter->ahw.cut_through) { 803 rcv_desc->dma_size = 804 NX_CT_DEFAULT_RX_BUF_LEN; 805 rcv_desc->buf_size = rcv_desc->dma_size; 806 } else { 807 rcv_desc->dma_size = 808 NX_RX_NORMAL_BUF_MAX_LEN; 809 rcv_desc->buf_size = 810 rcv_desc->dma_size + 811 IP_ALIGNMENT_BYTES; 812 } 813 break; 814 815 case RCV_DESC_JUMBO: 816 rcv_desc->MaxRxDescCount = 817 adapter->MaxJumboRxDescCount; 818 if (adapter->ahw.cut_through) { 819 rcv_desc->dma_size = 820 rcv_desc->buf_size = 821 NX_P3_RX_JUMBO_BUF_MAX_LEN; 822 } else { 823 if (NX_IS_REVISION_P2(revid)) 824 rcv_desc->dma_size = 825 NX_P2_RX_JUMBO_BUF_MAX_LEN; 826 else 827 rcv_desc->dma_size = 828 NX_P3_RX_JUMBO_BUF_MAX_LEN; 829 rcv_desc->buf_size = 830 rcv_desc->dma_size + 831 IP_ALIGNMENT_BYTES; 832 } 833 break; 834 835 case RCV_RING_LRO: 836 rcv_desc->MaxRxDescCount = 837 adapter->MaxLroRxDescCount; 838 rcv_desc->buf_size = MAX_RX_LRO_BUFFER_LENGTH; 839 rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; 840 break; 841 default: 842 break; 843 } 844 } 845 } 846 } 847 848 static void 849 vector128M(unm_adapter *aptr) 850 { 851 aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_128M; 852 aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_128M; 853 aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_128M; 854 aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_128M; 855 aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_ioctl_128M; 856 aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_ioctl_128M; 857 aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_128M; 858 aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_128M; 859 aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_128M; 860 aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_128M; 861 aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_128M; 862 aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_128M; 863 aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_128M; 864 aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_128M; 865 aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_128M; 866 } 867 868 static void 869 vector2M(unm_adapter *aptr) 870 { 871 aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_2M; 872 aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_2M; 873 aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_2M; 874 aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_2M; 875 aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_wx_2M; 876 aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_wx_2M; 877 aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_2M; 878 aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_2M; 879 aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_2M; 880 aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_2M; 881 aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_2M; 882 aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_2M; 883 aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_2M; 884 aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_2M; 885 aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_2M; 886 } 887 888 static int 889 unm_pci_map_setup(unm_adapter *adapter) 890 { 891 int ret; 892 caddr_t reg_base, db_base; 893 caddr_t mem_ptr0, mem_ptr1 = NULL, mem_ptr2 = NULL; 894 unsigned long pci_len0; 895 unsigned long first_page_group_start, first_page_group_end; 896 897 off_t regsize, dbsize = UNM_DB_MAPSIZE_BYTES; 898 dev_info_t *dip = adapter->dip; 899 900 adapter->ahw.qdr_sn_window = adapter->ahw.ddr_mn_window = -1; 901 902 /* map register space */ 903 904 ret = ddi_dev_regsize(dip, 1, ®size); 905 if (ret != DDI_SUCCESS) { 906 cmn_err(CE_WARN, "%s%d: failed to read reg size for bar0\n", 907 adapter->name, adapter->instance); 908 return (DDI_FAILURE); 909 } 910 911 ret = ddi_regs_map_setup(dip, 1, ®_base, 0, 912 regsize, &unm_dev_attr, &adapter->regs_handle); 913 if (ret != DDI_SUCCESS) { 914 cmn_err(CE_WARN, "%s%d: failed to map registers\n", 915 adapter->name, adapter->instance); 916 return (DDI_FAILURE); 917 } 918 919 mem_ptr0 = reg_base; 920 921 if (regsize == UNM_PCI_128MB_SIZE) { 922 pci_len0 = FIRST_PAGE_GROUP_SIZE; 923 mem_ptr1 = mem_ptr0 + SECOND_PAGE_GROUP_START; 924 mem_ptr2 = mem_ptr0 + THIRD_PAGE_GROUP_START; 925 first_page_group_start = FIRST_PAGE_GROUP_START; 926 first_page_group_end = FIRST_PAGE_GROUP_END; 927 vector128M(adapter); 928 } else if (regsize == UNM_PCI_32MB_SIZE) { 929 pci_len0 = 0; 930 mem_ptr1 = mem_ptr0; 931 mem_ptr2 = mem_ptr0 + 932 (THIRD_PAGE_GROUP_START - SECOND_PAGE_GROUP_START); 933 first_page_group_start = 0; 934 first_page_group_end = 0; 935 vector128M(adapter); 936 } else if (regsize == UNM_PCI_2MB_SIZE) { 937 pci_len0 = UNM_PCI_2MB_SIZE; 938 first_page_group_start = 0; 939 first_page_group_end = 0; 940 adapter->ahw.ddr_mn_window = adapter->ahw.qdr_sn_window = 0; 941 adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW + 942 (adapter->ahw.pci_func * 0x20); 943 if (adapter->ahw.pci_func < 4) 944 adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW + 945 (adapter->ahw.pci_func * 0x20); 946 else 947 adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW + 948 0xA0 + ((adapter->ahw.pci_func - 4) * 0x10); 949 vector2M(adapter); 950 } else { 951 cmn_err(CE_WARN, "%s%d: invalid pci regs map size %ld\n", 952 adapter->name, adapter->instance, regsize); 953 ddi_regs_map_free(&adapter->regs_handle); 954 return (DDI_FAILURE); 955 } 956 957 adapter->ahw.pci_base0 = (unsigned long)mem_ptr0; 958 adapter->ahw.pci_len0 = pci_len0; 959 adapter->ahw.pci_base1 = (unsigned long)mem_ptr1; 960 adapter->ahw.pci_len1 = SECOND_PAGE_GROUP_SIZE; 961 adapter->ahw.pci_base2 = (unsigned long)mem_ptr2; 962 adapter->ahw.pci_len2 = THIRD_PAGE_GROUP_SIZE; 963 adapter->ahw.crb_base = 964 PCI_OFFSET_SECOND_RANGE(adapter, UNM_PCI_CRBSPACE); 965 966 adapter->ahw.first_page_group_start = first_page_group_start; 967 adapter->ahw.first_page_group_end = first_page_group_end; 968 969 /* map doorbell */ 970 971 ret = ddi_regs_map_setup(dip, 2, &db_base, 0, 972 dbsize, &unm_dev_attr, &adapter->db_handle); 973 if (ret != DDI_SUCCESS) { 974 cmn_err(CE_WARN, "%s%d: failed to map doorbell\n", 975 adapter->name, adapter->instance); 976 ddi_regs_map_free(&adapter->regs_handle); 977 return (DDI_FAILURE); 978 } 979 980 adapter->ahw.db_base = (unsigned long)db_base; 981 adapter->ahw.db_len = dbsize; 982 983 return (DDI_SUCCESS); 984 } 985 986 static int 987 unm_initialize_intr(unm_adapter *adapter) 988 { 989 990 int ret; 991 int type, count, avail, actual; 992 993 ret = ddi_intr_get_supported_types(adapter->dip, &type); 994 if (ret != DDI_SUCCESS) { 995 cmn_err(CE_WARN, "%s%d: ddi_intr_get_supported_types() " 996 "failed\n", adapter->name, adapter->instance); 997 return (DDI_FAILURE); 998 } 999 1000 type = DDI_INTR_TYPE_MSI; 1001 ret = ddi_intr_get_nintrs(adapter->dip, type, &count); 1002 if ((ret == DDI_SUCCESS) && (count > 0)) 1003 goto found_msi; 1004 1005 type = DDI_INTR_TYPE_FIXED; 1006 ret = ddi_intr_get_nintrs(adapter->dip, type, &count); 1007 if ((ret != DDI_SUCCESS) || (count == 0)) { 1008 cmn_err(CE_WARN, 1009 "ddi_intr_get_nintrs() failure ret=%d\n", ret); 1010 return (DDI_FAILURE); 1011 } 1012 1013 found_msi: 1014 adapter->intr_type = type; 1015 adapter->flags &= ~(UNM_NIC_MSI_ENABLED | UNM_NIC_MSIX_ENABLED); 1016 if (type == DDI_INTR_TYPE_MSI) 1017 adapter->flags |= UNM_NIC_MSI_ENABLED; 1018 1019 /* Get number of available interrupts */ 1020 ret = ddi_intr_get_navail(adapter->dip, type, &avail); 1021 if ((ret != DDI_SUCCESS) || (avail == 0)) { 1022 cmn_err(CE_WARN, "ddi_intr_get_navail() failure, ret=%d\n", 1023 ret); 1024 return (DDI_FAILURE); 1025 } 1026 1027 ret = ddi_intr_alloc(adapter->dip, &adapter->intr_handle, 1028 type, 0, 1, &actual, DDI_INTR_ALLOC_NORMAL); 1029 if ((ret != DDI_SUCCESS) || (actual == 0)) { 1030 cmn_err(CE_WARN, "ddi_intr_alloc() failure: %d\n", ret); 1031 return (DDI_FAILURE); 1032 } 1033 1034 ret = ddi_intr_get_pri(adapter->intr_handle, &adapter->intr_pri); 1035 if (ret != DDI_SUCCESS) { 1036 cmn_err(CE_WARN, "ddi_intr_get_pri() failure: %d\n", ret); 1037 } 1038 1039 /* Call ddi_intr_add_handler() */ 1040 ret = ddi_intr_add_handler(adapter->intr_handle, unm_intr, 1041 (caddr_t)adapter, NULL); 1042 if (ret != DDI_SUCCESS) { 1043 cmn_err(CE_WARN, "%s%d: ddi_intr_add_handler() failure\n", 1044 adapter->name, adapter->instance); 1045 (void) ddi_intr_free(adapter->intr_handle); 1046 return (DDI_FAILURE); 1047 } 1048 1049 /* Add softintr if required */ 1050 1051 return (DDI_SUCCESS); 1052 1053 } 1054 1055 void 1056 unm_destroy_intr(unm_adapter *adapter) 1057 { 1058 /* disable interrupt */ 1059 if (adapter->intr_type == DDI_INTR_TYPE_MSI) 1060 (void) ddi_intr_block_disable(&adapter->intr_handle, 1); 1061 else 1062 (void) ddi_intr_disable(adapter->intr_handle); 1063 1064 (void) ddi_intr_remove_handler(adapter->intr_handle); 1065 (void) ddi_intr_free(adapter->intr_handle); 1066 1067 /* Remove the software intr handler */ 1068 } 1069 1070 static void 1071 netxen_set_port_mode(unm_adapter *adapter) 1072 { 1073 static int wol_port_mode = UNM_PORT_MODE_AUTO_NEG_1G; 1074 static int port_mode = UNM_PORT_MODE_AUTO_NEG; 1075 int btype = adapter->ahw.boardcfg.board_type, data = 0; 1076 1077 if (btype == UNM_BRDTYPE_P3_HMEZ || btype == UNM_BRDTYPE_P3_XG_LOM) { 1078 data = port_mode; /* set to port_mode normally */ 1079 if ((port_mode != UNM_PORT_MODE_802_3_AP) && 1080 (port_mode != UNM_PORT_MODE_XG) && 1081 (port_mode != UNM_PORT_MODE_AUTO_NEG_1G) && 1082 (port_mode != UNM_PORT_MODE_AUTO_NEG_XG)) 1083 data = UNM_PORT_MODE_AUTO_NEG; 1084 1085 adapter->unm_nic_hw_write_wx(adapter, UNM_PORT_MODE_ADDR, 1086 &data, 4); 1087 1088 if ((wol_port_mode != UNM_PORT_MODE_802_3_AP) && 1089 (wol_port_mode != UNM_PORT_MODE_XG) && 1090 (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_1G) && 1091 (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_XG)) 1092 wol_port_mode = UNM_PORT_MODE_AUTO_NEG; 1093 1094 adapter->unm_nic_hw_write_wx(adapter, UNM_WOL_PORT_MODE, 1095 &wol_port_mode, 4); 1096 } 1097 } 1098 1099 static void 1100 netxen_pcie_strap_init(unm_adapter *adapter) 1101 { 1102 ddi_acc_handle_t pcihdl = adapter->pci_cfg_handle; 1103 u32 chicken, control, c8c9value = 0xF1000; 1104 1105 adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3), 1106 &chicken, 4); 1107 1108 chicken &= 0xFCFFFFFF; /* clear chicken3 25:24 */ 1109 control = pci_config_get32(pcihdl, 0xD0); 1110 if ((control & 0x000F0000) != 0x00020000) /* is it gen1? */ 1111 chicken |= 0x01000000; 1112 adapter->unm_nic_hw_write_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3), 1113 &chicken, 4); 1114 control = pci_config_get32(pcihdl, 0xC8); 1115 control = pci_config_get32(pcihdl, 0xC8); 1116 pci_config_put32(pcihdl, 0xC8, c8c9value); 1117 } 1118 1119 static int 1120 netxen_read_mac_addr(unm_adapter *adapter) 1121 { 1122 u64 mac_addr[8 + 1]; 1123 unsigned char *p; 1124 int i; 1125 1126 if (get_flash_mac_addr(adapter, mac_addr) != 0) 1127 return (-1); 1128 1129 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1130 p = (unsigned char *)&mac_addr[adapter->ahw.pci_func]; 1131 else 1132 p = (unsigned char *)&mac_addr[adapter->portnum]; 1133 1134 for (i = 0; i < 6; i++) 1135 adapter->mac_addr[i] = p[5 - i]; 1136 1137 if (unm_nic_macaddr_set(adapter, adapter->mac_addr) != 0) 1138 return (-1); 1139 1140 return (0); 1141 } 1142 1143 static int 1144 unmattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1145 { 1146 unm_adapter *adapter; 1147 int i, first_driver = 0; 1148 int ret, temp; 1149 1150 switch (cmd) { 1151 case DDI_ATTACH: 1152 break; 1153 case DDI_RESUME: 1154 case DDI_PM_RESUME: 1155 default: 1156 return (DDI_FAILURE); 1157 } 1158 1159 adapter = kmem_zalloc(sizeof (unm_adapter), KM_SLEEP); 1160 adapter->dip = dip; 1161 ddi_set_driver_private(dip, adapter); 1162 adapter->instance = ddi_get_instance(dip); 1163 1164 adapter->name = ddi_driver_name(dip); 1165 1166 ret = pci_config_setup(dip, &adapter->pci_cfg_handle); 1167 if (ret != DDI_SUCCESS) { 1168 cmn_err(CE_WARN, "%s%d: pci_config_setup failed\n", 1169 adapter->name, adapter->instance); 1170 goto attach_setup_err; 1171 } 1172 1173 ret = unm_pci_cfg_init(adapter); 1174 if (ret != DDI_SUCCESS) 1175 goto attach_err; 1176 1177 ret = unm_pci_map_setup(adapter); 1178 if (ret != DDI_SUCCESS) 1179 goto attach_err; 1180 1181 if (unm_initialize_intr(adapter) != DDI_SUCCESS) 1182 goto attach_unmap_regs; 1183 1184 rw_init(&adapter->adapter_lock, NULL, 1185 RW_DRIVER, DDI_INTR_PRI(adapter->intr_pri)); 1186 mutex_init(&adapter->tx_lock, NULL, 1187 MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri))); 1188 mutex_init(&adapter->lock, NULL, 1189 MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri))); 1190 1191 adapter->portnum = (int8_t)adapter->ahw.pci_func; 1192 1193 /* 1194 * Set the CRB window to invalid. If any register in window 0 is 1195 * accessed it should set window to 0 and then reset it to 1. 1196 */ 1197 adapter->curr_window = 255; 1198 1199 adapter->fw_major = adapter->unm_nic_pci_read_normalize(adapter, 1200 UNM_FW_VERSION_MAJOR); 1201 1202 if (adapter->fw_major < 4) 1203 adapter->max_rds_rings = 3; 1204 else 1205 adapter->max_rds_rings = 2; 1206 1207 STRUCT_COPY(adapter->gc_dma_attr_desc, unm_dma_attr_desc); 1208 STRUCT_COPY(adapter->gc_attr_desc, unm_buf_attr); 1209 1210 ret = unm_nic_get_board_info(adapter); 1211 if (ret != DDI_SUCCESS) { 1212 cmn_err(CE_WARN, "%s%d: error reading board config\n", 1213 adapter->name, adapter->instance); 1214 goto attach_destroy_intr; 1215 } 1216 1217 /* Mezz cards have PCI function 0, 2, 3 enabled */ 1218 switch (adapter->ahw.boardcfg.board_type) { 1219 case UNM_BRDTYPE_P2_SB31_10G_IMEZ: 1220 case UNM_BRDTYPE_P2_SB31_10G_HMEZ: 1221 if (adapter->ahw.pci_func >= 2) { 1222 adapter->portnum = adapter->ahw.pci_func - 2; 1223 } 1224 default: 1225 break; 1226 } 1227 1228 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 1229 temp = UNM_CRB_READ_VAL_ADAPTER(UNM_MIU_MN_CONTROL, adapter); 1230 adapter->ahw.cut_through = NX_IS_SYSTEM_CUT_THROUGH(temp); 1231 if (adapter->ahw.pci_func == 0) 1232 first_driver = 1; 1233 } else { 1234 if (adapter->portnum == 0) 1235 first_driver = 1; 1236 } 1237 1238 unm_check_options(adapter); 1239 1240 if (first_driver) { 1241 int first_boot = adapter->unm_nic_pci_read_normalize(adapter, 1242 UNM_CAM_RAM(0x1fc)); 1243 1244 if (check_hw_init(adapter) != 0) { 1245 cmn_err(CE_WARN, "%s%d: Error in HW init sequence\n", 1246 adapter->name, adapter->instance); 1247 goto attach_destroy_intr; 1248 } 1249 1250 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1251 netxen_set_port_mode(adapter); 1252 1253 if (first_boot != 0x55555555) { 1254 temp = 0; 1255 adapter->unm_nic_hw_write_wx(adapter, CRB_CMDPEG_STATE, 1256 &temp, 4); 1257 if (pinit_from_rom(adapter, 0) != 0) 1258 goto attach_destroy_intr; 1259 1260 drv_usecwait(500); 1261 1262 ret = load_from_flash(adapter); 1263 if (ret != DDI_SUCCESS) 1264 goto attach_destroy_intr; 1265 } 1266 1267 if (ret = unm_initialize_dummy_dma(adapter)) 1268 goto attach_destroy_intr; 1269 1270 /* 1271 * Tell the hardware our version number. 1272 */ 1273 i = (_UNM_NIC_MAJOR << 16) | 1274 ((_UNM_NIC_MINOR << 8)) | (_UNM_NIC_SUBVERSION); 1275 adapter->unm_nic_hw_write_wx(adapter, CRB_DRIVER_VERSION, 1276 &i, 4); 1277 1278 /* Unlock the HW, prompting the boot sequence */ 1279 if ((first_boot == 0x55555555) && 1280 (NX_IS_REVISION_P2(adapter->ahw.revision_id))) 1281 adapter->unm_nic_pci_write_normalize(adapter, 1282 UNM_ROMUSB_GLB_PEGTUNE_DONE, 1); 1283 1284 /* Handshake with the card before we register the devices. */ 1285 if (phantom_init(adapter, 0) != DDI_SUCCESS) 1286 goto attach_destroy_intr; 1287 } 1288 1289 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1290 netxen_pcie_strap_init(adapter); 1291 1292 /* 1293 * See if the firmware gave us a virtual-physical port mapping. 1294 */ 1295 adapter->physical_port = adapter->portnum; 1296 i = adapter->unm_nic_pci_read_normalize(adapter, 1297 CRB_V2P(adapter->portnum)); 1298 if (i != 0x55555555) 1299 adapter->physical_port = (uint16_t)i; 1300 1301 adapter->ahw.linkup = 0; 1302 1303 if (receive_peg_ready(adapter)) { 1304 ret = -EIO; 1305 goto free_dummy_dma; 1306 } 1307 1308 if (netxen_read_mac_addr(adapter)) 1309 cmn_err(CE_WARN, "%s%d: Failed to read MAC addr\n", 1310 adapter->name, adapter->instance); 1311 1312 unm_nic_flash_print(adapter); 1313 1314 if (verbmsg != 0) { 1315 switch (adapter->ahw.board_type) { 1316 case UNM_NIC_GBE: 1317 cmn_err(CE_NOTE, "%s: QUAD GbE port %d initialized\n", 1318 unm_nic_driver_name, adapter->portnum); 1319 break; 1320 1321 case UNM_NIC_XGBE: 1322 cmn_err(CE_NOTE, "%s: XGbE port %d initialized\n", 1323 unm_nic_driver_name, adapter->portnum); 1324 break; 1325 } 1326 } 1327 1328 ret = unm_register_mac(adapter); 1329 if (ret != DDI_SUCCESS) { 1330 cmn_err(CE_NOTE, "%s%d: Mac registration error\n", 1331 adapter->name, adapter->instance); 1332 goto free_dummy_dma; 1333 } 1334 1335 return (DDI_SUCCESS); 1336 1337 free_dummy_dma: 1338 if (first_driver) 1339 unm_free_dummy_dma(adapter); 1340 attach_destroy_intr: 1341 unm_destroy_intr(adapter); 1342 attach_unmap_regs: 1343 ddi_regs_map_free(&(adapter->regs_handle)); 1344 ddi_regs_map_free(&(adapter->db_handle)); 1345 attach_err: 1346 pci_config_teardown(&adapter->pci_cfg_handle); 1347 attach_setup_err: 1348 kmem_free(adapter, sizeof (unm_adapter)); 1349 return (ret); 1350 } 1351 1352 static int 1353 unmdetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1354 { 1355 unm_adapter *adapter = (unm_adapter *)ddi_get_driver_private(dip); 1356 1357 if (adapter == NULL) 1358 return (DDI_FAILURE); 1359 1360 switch (cmd) { 1361 case DDI_DETACH: 1362 unm_fini_kstats(adapter); 1363 adapter->kstats[0] = NULL; 1364 1365 if (adapter->pci_cfg_handle != NULL) 1366 pci_config_teardown(&adapter->pci_cfg_handle); 1367 1368 unm_nd_cleanup(adapter); 1369 unm_nic_remove(adapter); 1370 return (DDI_SUCCESS); 1371 1372 case DDI_SUSPEND: 1373 return (unm_nic_suspend(adapter)); 1374 1375 default: 1376 break; 1377 } 1378 1379 return (DDI_FAILURE); 1380 } 1381 1382 int 1383 create_rxtx_rings(unm_adapter *adapter) 1384 { 1385 unm_recv_context_t *recv_ctx; 1386 unm_rcv_desc_ctx_t *rcv_desc; 1387 int i, ring; 1388 1389 adapter->cmd_buf_arr = (struct unm_cmd_buffer *)kmem_zalloc( 1390 sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount, 1391 KM_SLEEP); 1392 1393 for (i = 0; i < MAX_RCV_CTX; ++i) { 1394 recv_ctx = &adapter->recv_ctx[i]; 1395 1396 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1397 rcv_desc = &recv_ctx->rcv_desc[ring]; 1398 if (unm_create_rx_ring(adapter, rcv_desc) != 1399 DDI_SUCCESS) 1400 goto attach_free_cmdbufs; 1401 } 1402 } 1403 1404 if (unm_alloc_tx_dmahdl(adapter) != DDI_SUCCESS) 1405 goto attach_free_cmdbufs; 1406 1407 if (unm_alloc_tx_buffers(adapter) != DDI_SUCCESS) 1408 goto attach_free_tx_dmahdl; 1409 1410 return (DDI_SUCCESS); 1411 1412 attach_free_tx_buffers: 1413 unm_free_tx_buffers(adapter); 1414 attach_free_tx_dmahdl: 1415 unm_free_tx_dmahdl(adapter); 1416 attach_free_cmdbufs: 1417 kmem_free(adapter->cmd_buf_arr, sizeof (struct unm_cmd_buffer) * 1418 adapter->MaxTxDescCount); 1419 for (i = 0; i < MAX_RCV_CTX; ++i) { 1420 recv_ctx = &adapter->recv_ctx[i]; 1421 1422 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1423 rcv_desc = &recv_ctx->rcv_desc[ring]; 1424 if (rcv_desc->rx_buf_pool != NULL) 1425 unm_destroy_rx_ring(rcv_desc); 1426 } 1427 } 1428 return (DDI_FAILURE); 1429 } 1430 1431 void 1432 destroy_rxtx_rings(unm_adapter *adapter) 1433 { 1434 unm_recv_context_t *recv_ctx; 1435 unm_rcv_desc_ctx_t *rcv_desc; 1436 int ctx, ring; 1437 1438 unm_free_tx_buffers(adapter); 1439 unm_free_tx_dmahdl(adapter); 1440 1441 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 1442 recv_ctx = &adapter->recv_ctx[ctx]; 1443 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1444 rcv_desc = &recv_ctx->rcv_desc[ring]; 1445 if (rcv_desc->rx_buf_pool != NULL) 1446 unm_destroy_rx_ring(rcv_desc); 1447 } 1448 } 1449 1450 if (adapter->cmd_buf_arr != NULL) 1451 kmem_free(adapter->cmd_buf_arr, 1452 sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount); 1453 } 1454 1455 #ifdef SOLARIS11 1456 DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach, 1457 nodev, NULL, D_MP, NULL, NULL); 1458 #else 1459 DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach, 1460 nodev, NULL, D_MP, NULL); 1461 #endif 1462 1463 static struct modldrv modldrv = { 1464 &mod_driverops, /* Type of module. This one is a driver */ 1465 ident, 1466 &unm_ops, /* driver ops */ 1467 }; 1468 1469 static struct modlinkage modlinkage = { 1470 MODREV_1, 1471 (&modldrv), 1472 NULL 1473 }; 1474 1475 1476 int 1477 _init(void) 1478 { 1479 int ret; 1480 1481 unm_ops.devo_cb_ops->cb_str = NULL; 1482 mac_init_ops(&unm_ops, "ntxn"); 1483 1484 ret = mod_install(&modlinkage); 1485 if (ret != DDI_SUCCESS) { 1486 mac_fini_ops(&unm_ops); 1487 cmn_err(CE_WARN, "ntxn: mod_install failed\n"); 1488 } 1489 1490 return (ret); 1491 } 1492 1493 1494 int 1495 _fini(void) 1496 { 1497 int ret; 1498 1499 ret = mod_remove(&modlinkage); 1500 if (ret == DDI_SUCCESS) 1501 mac_fini_ops(&unm_ops); 1502 return (ret); 1503 } 1504 1505 int 1506 _info(struct modinfo *modinfop) 1507 { 1508 return (mod_info(&modlinkage, modinfop)); 1509 } --- EOF ---