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 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * SunOs MT STREAMS NIU/Neptune 10Gb Ethernet Device Driver. 30 */ 31 #include <sys/nxge/nxge_impl.h> 32 #include <sys/pcie.h> 33 34 uint32_t nxge_use_partition = 0; /* debug partition flag */ 35 uint32_t nxge_dma_obp_props_only = 1; /* use obp published props */ 36 uint32_t nxge_use_rdc_intr = 1; /* debug to assign rdc intr */ 37 /* 38 * PSARC/2007/453 MSI-X interrupt limit override 39 * (This PSARC case is limited to MSI-X vectors 40 * and SPARC platforms only). 41 */ 42 #if defined(_BIG_ENDIAN) 43 uint32_t nxge_msi_enable = 2; 44 #else 45 uint32_t nxge_msi_enable = 1; 46 #endif 47 48 /* 49 * Globals: tunable parameters (/etc/system or adb) 50 * 51 */ 52 uint32_t nxge_rbr_size = NXGE_RBR_RBB_DEFAULT; 53 uint32_t nxge_rbr_spare_size = 0; 54 uint32_t nxge_rcr_size = NXGE_RCR_DEFAULT; 55 uint32_t nxge_tx_ring_size = NXGE_TX_RING_DEFAULT; 56 boolean_t nxge_no_msg = B_TRUE; /* control message display */ 57 uint32_t nxge_no_link_notify = 0; /* control DL_NOTIFY */ 58 uint32_t nxge_bcopy_thresh = TX_BCOPY_MAX; 59 uint32_t nxge_dvma_thresh = TX_FASTDVMA_MIN; 60 uint32_t nxge_dma_stream_thresh = TX_STREAM_MIN; 61 uint32_t nxge_jumbo_mtu = TX_JUMBO_MTU; 62 boolean_t nxge_jumbo_enable = B_FALSE; 63 uint16_t nxge_rcr_timeout = NXGE_RDC_RCR_TIMEOUT; 64 uint16_t nxge_rcr_threshold = NXGE_RDC_RCR_THRESHOLD; 65 nxge_tx_mode_t nxge_tx_scheme = NXGE_USE_SERIAL; 66 67 /* MAX LSO size */ 68 #define NXGE_LSO_MAXLEN 65535 69 /* Enable Software LSO flag */ 70 uint32_t nxge_lso_enable = 1; 71 uint32_t nxge_lso_max = NXGE_LSO_MAXLEN; 72 73 /* 74 * Debugging flags: 75 * nxge_no_tx_lb : transmit load balancing 76 * nxge_tx_lb_policy: 0 - TCP port (default) 77 * 3 - DEST MAC 78 */ 79 uint32_t nxge_no_tx_lb = 0; 80 uint32_t nxge_tx_lb_policy = NXGE_TX_LB_TCPUDP; 81 82 /* 83 * Add tunable to reduce the amount of time spent in the 84 * ISR doing Rx Processing. 85 */ 86 uint32_t nxge_max_rx_pkts = 1024; 87 88 /* 89 * Tunables to manage the receive buffer blocks. 90 * 91 * nxge_rx_threshold_hi: copy all buffers. 92 * nxge_rx_bcopy_size_type: receive buffer block size type. 93 * nxge_rx_threshold_lo: copy only up to tunable block size type. 94 */ 95 nxge_rxbuf_threshold_t nxge_rx_threshold_hi = NXGE_RX_COPY_6; 96 nxge_rxbuf_type_t nxge_rx_buf_size_type = RCR_PKTBUFSZ_0; 97 nxge_rxbuf_threshold_t nxge_rx_threshold_lo = NXGE_RX_COPY_3; 98 99 rtrace_t npi_rtracebuf; 100 101 #if defined(sun4v) 102 /* 103 * Hypervisor N2/NIU services information. 104 */ 105 static hsvc_info_t niu_hsvc = { 106 HSVC_REV_1, NULL, HSVC_GROUP_NIU, NIU_MAJOR_VER, 107 NIU_MINOR_VER, "nxge" 108 }; 109 #endif 110 111 /* 112 * Function Prototypes 113 */ 114 static int nxge_attach(dev_info_t *, ddi_attach_cmd_t); 115 static int nxge_detach(dev_info_t *, ddi_detach_cmd_t); 116 static void nxge_unattach(p_nxge_t); 117 118 #if NXGE_PROPERTY 119 static void nxge_remove_hard_properties(p_nxge_t); 120 #endif 121 122 static nxge_status_t nxge_setup_system_dma_pages(p_nxge_t); 123 124 static nxge_status_t nxge_setup_mutexes(p_nxge_t); 125 static void nxge_destroy_mutexes(p_nxge_t); 126 127 static nxge_status_t nxge_map_regs(p_nxge_t nxgep); 128 static void nxge_unmap_regs(p_nxge_t nxgep); 129 #ifdef NXGE_DEBUG 130 static void nxge_test_map_regs(p_nxge_t nxgep); 131 #endif 132 133 static nxge_status_t nxge_add_intrs(p_nxge_t nxgep); 134 static nxge_status_t nxge_add_soft_intrs(p_nxge_t nxgep); 135 static void nxge_remove_intrs(p_nxge_t nxgep); 136 static void nxge_remove_soft_intrs(p_nxge_t nxgep); 137 138 static nxge_status_t nxge_add_intrs_adv(p_nxge_t nxgep); 139 static nxge_status_t nxge_add_intrs_adv_type(p_nxge_t, uint32_t); 140 static nxge_status_t nxge_add_intrs_adv_type_fix(p_nxge_t, uint32_t); 141 static void nxge_intrs_enable(p_nxge_t nxgep); 142 static void nxge_intrs_disable(p_nxge_t nxgep); 143 144 static void nxge_suspend(p_nxge_t); 145 static nxge_status_t nxge_resume(p_nxge_t); 146 147 static nxge_status_t nxge_setup_dev(p_nxge_t); 148 static void nxge_destroy_dev(p_nxge_t); 149 150 static nxge_status_t nxge_alloc_mem_pool(p_nxge_t); 151 static void nxge_free_mem_pool(p_nxge_t); 152 153 static nxge_status_t nxge_alloc_rx_mem_pool(p_nxge_t); 154 static void nxge_free_rx_mem_pool(p_nxge_t); 155 156 static nxge_status_t nxge_alloc_tx_mem_pool(p_nxge_t); 157 static void nxge_free_tx_mem_pool(p_nxge_t); 158 159 static nxge_status_t nxge_dma_mem_alloc(p_nxge_t, dma_method_t, 160 struct ddi_dma_attr *, 161 size_t, ddi_device_acc_attr_t *, uint_t, 162 p_nxge_dma_common_t); 163 164 static void nxge_dma_mem_free(p_nxge_dma_common_t); 165 166 static nxge_status_t nxge_alloc_rx_buf_dma(p_nxge_t, uint16_t, 167 p_nxge_dma_common_t *, size_t, size_t, uint32_t *); 168 static void nxge_free_rx_buf_dma(p_nxge_t, p_nxge_dma_common_t, uint32_t); 169 170 static nxge_status_t nxge_alloc_rx_cntl_dma(p_nxge_t, uint16_t, 171 p_nxge_dma_common_t *, size_t); 172 static void nxge_free_rx_cntl_dma(p_nxge_t, p_nxge_dma_common_t); 173 174 static nxge_status_t nxge_alloc_tx_buf_dma(p_nxge_t, uint16_t, 175 p_nxge_dma_common_t *, size_t, size_t, uint32_t *); 176 static void nxge_free_tx_buf_dma(p_nxge_t, p_nxge_dma_common_t, uint32_t); 177 178 static nxge_status_t nxge_alloc_tx_cntl_dma(p_nxge_t, uint16_t, 179 p_nxge_dma_common_t *, 180 size_t); 181 static void nxge_free_tx_cntl_dma(p_nxge_t, p_nxge_dma_common_t); 182 183 static int nxge_init_common_dev(p_nxge_t); 184 static void nxge_uninit_common_dev(p_nxge_t); 185 186 /* 187 * The next declarations are for the GLDv3 interface. 188 */ 189 static int nxge_m_start(void *); 190 static void nxge_m_stop(void *); 191 static int nxge_m_unicst(void *, const uint8_t *); 192 static int nxge_m_multicst(void *, boolean_t, const uint8_t *); 193 static int nxge_m_promisc(void *, boolean_t); 194 static void nxge_m_ioctl(void *, queue_t *, mblk_t *); 195 static void nxge_m_resources(void *); 196 mblk_t *nxge_m_tx(void *arg, mblk_t *); 197 static nxge_status_t nxge_mac_register(p_nxge_t); 198 static int nxge_altmac_set(p_nxge_t nxgep, uint8_t *mac_addr, 199 mac_addr_slot_t slot); 200 static void nxge_mmac_kstat_update(p_nxge_t nxgep, mac_addr_slot_t slot, 201 boolean_t factory); 202 static int nxge_m_mmac_add(void *arg, mac_multi_addr_t *maddr); 203 static int nxge_m_mmac_reserve(void *arg, mac_multi_addr_t *maddr); 204 static int nxge_m_mmac_remove(void *arg, mac_addr_slot_t slot); 205 static int nxge_m_mmac_modify(void *arg, mac_multi_addr_t *maddr); 206 static int nxge_m_mmac_get(void *arg, mac_multi_addr_t *maddr); 207 208 #define NXGE_NEPTUNE_MAGIC 0x4E584745UL 209 #define MAX_DUMP_SZ 256 210 211 #define NXGE_M_CALLBACK_FLAGS (MC_RESOURCES | MC_IOCTL | MC_GETCAPAB) 212 213 static boolean_t nxge_m_getcapab(void *, mac_capab_t, void *); 214 static mac_callbacks_t nxge_m_callbacks = { 215 NXGE_M_CALLBACK_FLAGS, 216 nxge_m_stat, 217 nxge_m_start, 218 nxge_m_stop, 219 nxge_m_promisc, 220 nxge_m_multicst, 221 nxge_m_unicst, 222 nxge_m_tx, 223 nxge_m_resources, 224 nxge_m_ioctl, 225 nxge_m_getcapab 226 }; 227 228 void 229 nxge_err_inject(p_nxge_t, queue_t *, mblk_t *); 230 231 /* PSARC/2007/453 MSI-X interrupt limit override. */ 232 #define NXGE_MSIX_REQUEST_10G 8 233 #define NXGE_MSIX_REQUEST_1G 2 234 static int nxge_create_msi_property(p_nxge_t); 235 236 /* 237 * These global variables control the message 238 * output. 239 */ 240 out_dbgmsg_t nxge_dbgmsg_out = DBG_CONSOLE | STR_LOG; 241 uint64_t nxge_debug_level = 0; 242 243 /* 244 * This list contains the instance structures for the Neptune 245 * devices present in the system. The lock exists to guarantee 246 * mutually exclusive access to the list. 247 */ 248 void *nxge_list = NULL; 249 250 void *nxge_hw_list = NULL; 251 nxge_os_mutex_t nxge_common_lock; 252 253 extern uint64_t npi_debug_level; 254 255 extern nxge_status_t nxge_ldgv_init(p_nxge_t, int *, int *); 256 extern nxge_status_t nxge_ldgv_init_n2(p_nxge_t, int *, int *); 257 extern nxge_status_t nxge_ldgv_uninit(p_nxge_t); 258 extern nxge_status_t nxge_intr_ldgv_init(p_nxge_t); 259 extern void nxge_fm_init(p_nxge_t, 260 ddi_device_acc_attr_t *, 261 ddi_device_acc_attr_t *, 262 ddi_dma_attr_t *); 263 extern void nxge_fm_fini(p_nxge_t); 264 extern npi_status_t npi_mac_altaddr_disable(npi_handle_t, uint8_t, uint8_t); 265 266 /* 267 * Count used to maintain the number of buffers being used 268 * by Neptune instances and loaned up to the upper layers. 269 */ 270 uint32_t nxge_mblks_pending = 0; 271 272 /* 273 * Device register access attributes for PIO. 274 */ 275 static ddi_device_acc_attr_t nxge_dev_reg_acc_attr = { 276 DDI_DEVICE_ATTR_V0, 277 DDI_STRUCTURE_LE_ACC, 278 DDI_STRICTORDER_ACC, 279 }; 280 281 /* 282 * Device descriptor access attributes for DMA. 283 */ 284 static ddi_device_acc_attr_t nxge_dev_desc_dma_acc_attr = { 285 DDI_DEVICE_ATTR_V0, 286 DDI_STRUCTURE_LE_ACC, 287 DDI_STRICTORDER_ACC 288 }; 289 290 /* 291 * Device buffer access attributes for DMA. 292 */ 293 static ddi_device_acc_attr_t nxge_dev_buf_dma_acc_attr = { 294 DDI_DEVICE_ATTR_V0, 295 DDI_STRUCTURE_BE_ACC, 296 DDI_STRICTORDER_ACC 297 }; 298 299 ddi_dma_attr_t nxge_desc_dma_attr = { 300 DMA_ATTR_V0, /* version number. */ 301 0, /* low address */ 302 0xffffffffffffffff, /* high address */ 303 0xffffffffffffffff, /* address counter max */ 304 #ifndef NIU_PA_WORKAROUND 305 0x100000, /* alignment */ 306 #else 307 0x2000, 308 #endif 309 0xfc00fc, /* dlim_burstsizes */ 310 0x1, /* minimum transfer size */ 311 0xffffffffffffffff, /* maximum transfer size */ 312 0xffffffffffffffff, /* maximum segment size */ 313 1, /* scatter/gather list length */ 314 (unsigned int) 1, /* granularity */ 315 0 /* attribute flags */ 316 }; 317 318 ddi_dma_attr_t nxge_tx_dma_attr = { 319 DMA_ATTR_V0, /* version number. */ 320 0, /* low address */ 321 0xffffffffffffffff, /* high address */ 322 0xffffffffffffffff, /* address counter max */ 323 #if defined(_BIG_ENDIAN) 324 0x2000, /* alignment */ 325 #else 326 0x1000, /* alignment */ 327 #endif 328 0xfc00fc, /* dlim_burstsizes */ 329 0x1, /* minimum transfer size */ 330 0xffffffffffffffff, /* maximum transfer size */ 331 0xffffffffffffffff, /* maximum segment size */ 332 5, /* scatter/gather list length */ 333 (unsigned int) 1, /* granularity */ 334 0 /* attribute flags */ 335 }; 336 337 ddi_dma_attr_t nxge_rx_dma_attr = { 338 DMA_ATTR_V0, /* version number. */ 339 0, /* low address */ 340 0xffffffffffffffff, /* high address */ 341 0xffffffffffffffff, /* address counter max */ 342 0x2000, /* alignment */ 343 0xfc00fc, /* dlim_burstsizes */ 344 0x1, /* minimum transfer size */ 345 0xffffffffffffffff, /* maximum transfer size */ 346 0xffffffffffffffff, /* maximum segment size */ 347 1, /* scatter/gather list length */ 348 (unsigned int) 1, /* granularity */ 349 DDI_DMA_RELAXED_ORDERING /* attribute flags */ 350 }; 351 352 ddi_dma_lim_t nxge_dma_limits = { 353 (uint_t)0, /* dlim_addr_lo */ 354 (uint_t)0xffffffff, /* dlim_addr_hi */ 355 (uint_t)0xffffffff, /* dlim_cntr_max */ 356 (uint_t)0xfc00fc, /* dlim_burstsizes for 32 and 64 bit xfers */ 357 0x1, /* dlim_minxfer */ 358 1024 /* dlim_speed */ 359 }; 360 361 dma_method_t nxge_force_dma = DVMA; 362 363 /* 364 * dma chunk sizes. 365 * 366 * Try to allocate the largest possible size 367 * so that fewer number of dma chunks would be managed 368 */ 369 #ifdef NIU_PA_WORKAROUND 370 size_t alloc_sizes [] = {0x2000}; 371 #else 372 size_t alloc_sizes [] = {0x1000, 0x2000, 0x4000, 0x8000, 373 0x10000, 0x20000, 0x40000, 0x80000, 374 0x100000, 0x200000, 0x400000, 0x800000, 375 0x1000000, 0x2000000, 0x4000000}; 376 #endif 377 378 /* 379 * Translate "dev_t" to a pointer to the associated "dev_info_t". 380 */ 381 382 static int 383 nxge_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 384 { 385 p_nxge_t nxgep = NULL; 386 int instance; 387 int status = DDI_SUCCESS; 388 uint8_t portn; 389 nxge_mmac_t *mmac_info; 390 391 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_attach")); 392 393 /* 394 * Get the device instance since we'll need to setup 395 * or retrieve a soft state for this instance. 396 */ 397 instance = ddi_get_instance(dip); 398 399 switch (cmd) { 400 case DDI_ATTACH: 401 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_ATTACH")); 402 break; 403 404 case DDI_RESUME: 405 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_RESUME")); 406 nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance); 407 if (nxgep == NULL) { 408 status = DDI_FAILURE; 409 break; 410 } 411 if (nxgep->dip != dip) { 412 status = DDI_FAILURE; 413 break; 414 } 415 if (nxgep->suspended == DDI_PM_SUSPEND) { 416 status = ddi_dev_is_needed(nxgep->dip, 0, 1); 417 } else { 418 status = nxge_resume(nxgep); 419 } 420 goto nxge_attach_exit; 421 422 case DDI_PM_RESUME: 423 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_PM_RESUME")); 424 nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance); 425 if (nxgep == NULL) { 426 status = DDI_FAILURE; 427 break; 428 } 429 if (nxgep->dip != dip) { 430 status = DDI_FAILURE; 431 break; 432 } 433 status = nxge_resume(nxgep); 434 goto nxge_attach_exit; 435 436 default: 437 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing unknown")); 438 status = DDI_FAILURE; 439 goto nxge_attach_exit; 440 } 441 442 443 if (ddi_soft_state_zalloc(nxge_list, instance) == DDI_FAILURE) { 444 status = DDI_FAILURE; 445 goto nxge_attach_exit; 446 } 447 448 nxgep = ddi_get_soft_state(nxge_list, instance); 449 if (nxgep == NULL) { 450 status = NXGE_ERROR; 451 goto nxge_attach_fail2; 452 } 453 454 nxgep->nxge_magic = NXGE_MAGIC; 455 456 nxgep->drv_state = 0; 457 nxgep->dip = dip; 458 nxgep->instance = instance; 459 nxgep->p_dip = ddi_get_parent(dip); 460 nxgep->nxge_debug_level = nxge_debug_level; 461 npi_debug_level = nxge_debug_level; 462 463 nxge_fm_init(nxgep, &nxge_dev_reg_acc_attr, &nxge_dev_desc_dma_acc_attr, 464 &nxge_rx_dma_attr); 465 466 status = nxge_map_regs(nxgep); 467 if (status != NXGE_OK) { 468 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_map_regs failed")); 469 goto nxge_attach_fail3; 470 } 471 472 status = nxge_init_common_dev(nxgep); 473 if (status != NXGE_OK) { 474 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 475 "nxge_init_common_dev failed")); 476 goto nxge_attach_fail4; 477 } 478 479 if (nxgep->niu_type == NEPTUNE_2_10GF) { 480 if (nxgep->function_num > 1) { 481 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Unsupported" 482 " function %d. Only functions 0 and 1 are " 483 "supported for this card.", nxgep->function_num)); 484 status = NXGE_ERROR; 485 goto nxge_attach_fail4; 486 } 487 } 488 489 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 490 nxgep->mac.portnum = portn; 491 if ((portn == 0) || (portn == 1)) 492 nxgep->mac.porttype = PORT_TYPE_XMAC; 493 else 494 nxgep->mac.porttype = PORT_TYPE_BMAC; 495 /* 496 * Neptune has 4 ports, the first 2 ports use XMAC (10G MAC) 497 * internally, the rest 2 ports use BMAC (1G "Big" MAC). 498 * The two types of MACs have different characterizations. 499 */ 500 mmac_info = &nxgep->nxge_mmac_info; 501 if (nxgep->function_num < 2) { 502 mmac_info->num_mmac = XMAC_MAX_ALT_ADDR_ENTRY; 503 mmac_info->naddrfree = XMAC_MAX_ALT_ADDR_ENTRY; 504 } else { 505 mmac_info->num_mmac = BMAC_MAX_ALT_ADDR_ENTRY; 506 mmac_info->naddrfree = BMAC_MAX_ALT_ADDR_ENTRY; 507 } 508 /* 509 * Setup the Ndd parameters for the this instance. 510 */ 511 nxge_init_param(nxgep); 512 513 /* 514 * Setup Register Tracing Buffer. 515 */ 516 npi_rtrace_buf_init((rtrace_t *)&npi_rtracebuf); 517 518 /* init stats ptr */ 519 nxge_init_statsp(nxgep); 520 521 /* 522 * read the vpd info from the eeprom into local data 523 * structure and check for the VPD info validity 524 */ 525 nxge_vpd_info_get(nxgep); 526 527 status = nxge_xcvr_find(nxgep); 528 529 if (status != NXGE_OK) { 530 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_attach: " 531 " Couldn't determine card type" 532 " .... exit ")); 533 goto nxge_attach_fail5; 534 } 535 536 status = nxge_get_config_properties(nxgep); 537 538 if (status != NXGE_OK) { 539 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "get_hw create failed")); 540 goto nxge_attach_fail; 541 } 542 543 /* 544 * Setup the Kstats for the driver. 545 */ 546 nxge_setup_kstats(nxgep); 547 548 nxge_setup_param(nxgep); 549 550 status = nxge_setup_system_dma_pages(nxgep); 551 if (status != NXGE_OK) { 552 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "set dma page failed")); 553 goto nxge_attach_fail; 554 } 555 556 #if defined(sun4v) 557 if (nxgep->niu_type == N2_NIU) { 558 nxgep->niu_hsvc_available = B_FALSE; 559 bcopy(&niu_hsvc, &nxgep->niu_hsvc, sizeof (hsvc_info_t)); 560 if ((status = 561 hsvc_register(&nxgep->niu_hsvc, 562 &nxgep->niu_min_ver)) != 0) { 563 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 564 "nxge_attach: " 565 "%s: cannot negotiate " 566 "hypervisor services " 567 "revision %d " 568 "group: 0x%lx " 569 "major: 0x%lx minor: 0x%lx " 570 "errno: %d", 571 niu_hsvc.hsvc_modname, 572 niu_hsvc.hsvc_rev, 573 niu_hsvc.hsvc_group, 574 niu_hsvc.hsvc_major, 575 niu_hsvc.hsvc_minor, 576 status)); 577 status = DDI_FAILURE; 578 goto nxge_attach_fail; 579 } 580 581 nxgep->niu_hsvc_available = B_TRUE; 582 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 583 "NIU Hypervisor service enabled")); 584 } 585 #endif 586 587 nxge_hw_id_init(nxgep); 588 nxge_hw_init_niu_common(nxgep); 589 590 status = nxge_setup_mutexes(nxgep); 591 if (status != NXGE_OK) { 592 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "set mutex failed")); 593 goto nxge_attach_fail; 594 } 595 596 status = nxge_setup_dev(nxgep); 597 if (status != DDI_SUCCESS) { 598 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "set dev failed")); 599 goto nxge_attach_fail; 600 } 601 602 status = nxge_add_intrs(nxgep); 603 if (status != DDI_SUCCESS) { 604 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "add_intr failed")); 605 goto nxge_attach_fail; 606 } 607 status = nxge_add_soft_intrs(nxgep); 608 if (status != DDI_SUCCESS) { 609 NXGE_DEBUG_MSG((nxgep, NXGE_ERR_CTL, "add_soft_intr failed")); 610 goto nxge_attach_fail; 611 } 612 613 /* 614 * Enable interrupts. 615 */ 616 nxge_intrs_enable(nxgep); 617 618 if ((status = nxge_mac_register(nxgep)) != NXGE_OK) { 619 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 620 "unable to register to mac layer (%d)", status)); 621 goto nxge_attach_fail; 622 } 623 624 mac_link_update(nxgep->mach, LINK_STATE_UNKNOWN); 625 626 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "registered to mac (instance %d)", 627 instance)); 628 629 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 630 631 goto nxge_attach_exit; 632 633 nxge_attach_fail: 634 nxge_unattach(nxgep); 635 goto nxge_attach_fail1; 636 637 nxge_attach_fail5: 638 /* 639 * Tear down the ndd parameters setup. 640 */ 641 nxge_destroy_param(nxgep); 642 643 /* 644 * Tear down the kstat setup. 645 */ 646 nxge_destroy_kstats(nxgep); 647 648 nxge_attach_fail4: 649 if (nxgep->nxge_hw_p) { 650 nxge_uninit_common_dev(nxgep); 651 nxgep->nxge_hw_p = NULL; 652 } 653 654 nxge_attach_fail3: 655 /* 656 * Unmap the register setup. 657 */ 658 nxge_unmap_regs(nxgep); 659 660 nxge_fm_fini(nxgep); 661 662 nxge_attach_fail2: 663 ddi_soft_state_free(nxge_list, nxgep->instance); 664 665 nxge_attach_fail1: 666 if (status != NXGE_OK) 667 status = (NXGE_ERROR | NXGE_DDI_FAILED); 668 nxgep = NULL; 669 670 nxge_attach_exit: 671 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_attach status = 0x%08x", 672 status)); 673 674 return (status); 675 } 676 677 static int 678 nxge_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 679 { 680 int status = DDI_SUCCESS; 681 int instance; 682 p_nxge_t nxgep = NULL; 683 684 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_detach")); 685 instance = ddi_get_instance(dip); 686 nxgep = ddi_get_soft_state(nxge_list, instance); 687 if (nxgep == NULL) { 688 status = DDI_FAILURE; 689 goto nxge_detach_exit; 690 } 691 692 switch (cmd) { 693 case DDI_DETACH: 694 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_DETACH")); 695 break; 696 697 case DDI_PM_SUSPEND: 698 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_PM_SUSPEND")); 699 nxgep->suspended = DDI_PM_SUSPEND; 700 nxge_suspend(nxgep); 701 break; 702 703 case DDI_SUSPEND: 704 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_SUSPEND")); 705 if (nxgep->suspended != DDI_PM_SUSPEND) { 706 nxgep->suspended = DDI_SUSPEND; 707 nxge_suspend(nxgep); 708 } 709 break; 710 711 default: 712 status = DDI_FAILURE; 713 } 714 715 if (cmd != DDI_DETACH) 716 goto nxge_detach_exit; 717 718 /* 719 * Stop the xcvr polling. 720 */ 721 nxgep->suspended = cmd; 722 723 (void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP); 724 725 if (nxgep->mach && (status = mac_unregister(nxgep->mach)) != 0) { 726 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 727 "<== nxge_detach status = 0x%08X", status)); 728 return (DDI_FAILURE); 729 } 730 731 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 732 "<== nxge_detach (mac_unregister) status = 0x%08X", status)); 733 734 nxge_unattach(nxgep); 735 nxgep = NULL; 736 737 nxge_detach_exit: 738 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_detach status = 0x%08X", 739 status)); 740 741 return (status); 742 } 743 744 static void 745 nxge_unattach(p_nxge_t nxgep) 746 { 747 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_unattach")); 748 749 if (nxgep == NULL || nxgep->dev_regs == NULL) { 750 return; 751 } 752 753 nxgep->nxge_magic = 0; 754 755 if (nxgep->nxge_timerid) { 756 nxge_stop_timer(nxgep, nxgep->nxge_timerid); 757 nxgep->nxge_timerid = 0; 758 } 759 760 if (nxgep->nxge_hw_p) { 761 nxge_uninit_common_dev(nxgep); 762 nxgep->nxge_hw_p = NULL; 763 } 764 765 #if defined(sun4v) 766 if (nxgep->niu_type == N2_NIU && nxgep->niu_hsvc_available == B_TRUE) { 767 (void) hsvc_unregister(&nxgep->niu_hsvc); 768 nxgep->niu_hsvc_available = B_FALSE; 769 } 770 #endif 771 /* 772 * Stop any further interrupts. 773 */ 774 nxge_remove_intrs(nxgep); 775 776 /* remove soft interrups */ 777 nxge_remove_soft_intrs(nxgep); 778 779 /* 780 * Stop the device and free resources. 781 */ 782 nxge_destroy_dev(nxgep); 783 784 /* 785 * Tear down the ndd parameters setup. 786 */ 787 nxge_destroy_param(nxgep); 788 789 /* 790 * Tear down the kstat setup. 791 */ 792 nxge_destroy_kstats(nxgep); 793 794 /* 795 * Destroy all mutexes. 796 */ 797 nxge_destroy_mutexes(nxgep); 798 799 /* 800 * Remove the list of ndd parameters which 801 * were setup during attach. 802 */ 803 if (nxgep->dip) { 804 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 805 " nxge_unattach: remove all properties")); 806 807 (void) ddi_prop_remove_all(nxgep->dip); 808 } 809 810 #if NXGE_PROPERTY 811 nxge_remove_hard_properties(nxgep); 812 #endif 813 814 /* 815 * Unmap the register setup. 816 */ 817 nxge_unmap_regs(nxgep); 818 819 nxge_fm_fini(nxgep); 820 821 ddi_soft_state_free(nxge_list, nxgep->instance); 822 823 NXGE_DEBUG_MSG((NULL, DDI_CTL, "<== nxge_unattach")); 824 } 825 826 static char n2_siu_name[] = "niu"; 827 828 static nxge_status_t 829 nxge_map_regs(p_nxge_t nxgep) 830 { 831 int ddi_status = DDI_SUCCESS; 832 p_dev_regs_t dev_regs; 833 char buf[MAXPATHLEN + 1]; 834 char *devname; 835 #ifdef NXGE_DEBUG 836 char *sysname; 837 #endif 838 off_t regsize; 839 nxge_status_t status = NXGE_OK; 840 #if !defined(_BIG_ENDIAN) 841 off_t pci_offset; 842 uint16_t pcie_devctl; 843 #endif 844 845 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_map_regs")); 846 nxgep->dev_regs = NULL; 847 dev_regs = KMEM_ZALLOC(sizeof (dev_regs_t), KM_SLEEP); 848 dev_regs->nxge_regh = NULL; 849 dev_regs->nxge_pciregh = NULL; 850 dev_regs->nxge_msix_regh = NULL; 851 dev_regs->nxge_vir_regh = NULL; 852 dev_regs->nxge_vir2_regh = NULL; 853 nxgep->niu_type = NIU_TYPE_NONE; 854 855 devname = ddi_pathname(nxgep->dip, buf); 856 ASSERT(strlen(devname) > 0); 857 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 858 "nxge_map_regs: pathname devname %s", devname)); 859 860 if (strstr(devname, n2_siu_name)) { 861 /* N2/NIU */ 862 nxgep->niu_type = N2_NIU; 863 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 864 "nxge_map_regs: N2/NIU devname %s", devname)); 865 /* get function number */ 866 nxgep->function_num = 867 (devname[strlen(devname) -1] == '1' ? 1 : 0); 868 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 869 "nxge_map_regs: N2/NIU function number %d", 870 nxgep->function_num)); 871 } else { 872 int *prop_val; 873 uint_t prop_len; 874 uint8_t func_num; 875 876 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 877 0, "reg", 878 &prop_val, &prop_len) != DDI_PROP_SUCCESS) { 879 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 880 "Reg property not found")); 881 ddi_status = DDI_FAILURE; 882 goto nxge_map_regs_fail0; 883 884 } else { 885 func_num = (prop_val[0] >> 8) & 0x7; 886 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 887 "Reg property found: fun # %d", 888 func_num)); 889 nxgep->function_num = func_num; 890 ddi_prop_free(prop_val); 891 } 892 } 893 894 switch (nxgep->niu_type) { 895 default: 896 (void) ddi_dev_regsize(nxgep->dip, 0, ®size); 897 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 898 "nxge_map_regs: pci config size 0x%x", regsize)); 899 900 ddi_status = ddi_regs_map_setup(nxgep->dip, 0, 901 (caddr_t *)&(dev_regs->nxge_pciregp), 0, 0, 902 &nxge_dev_reg_acc_attr, &dev_regs->nxge_pciregh); 903 if (ddi_status != DDI_SUCCESS) { 904 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 905 "ddi_map_regs, nxge bus config regs failed")); 906 goto nxge_map_regs_fail0; 907 } 908 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 909 "nxge_map_reg: PCI config addr 0x%0llx " 910 " handle 0x%0llx", dev_regs->nxge_pciregp, 911 dev_regs->nxge_pciregh)); 912 /* 913 * IMP IMP 914 * workaround for bit swapping bug in HW 915 * which ends up in no-snoop = yes 916 * resulting, in DMA not synched properly 917 */ 918 #if !defined(_BIG_ENDIAN) 919 /* workarounds for x86 systems */ 920 pci_offset = 0x80 + PCIE_DEVCTL; 921 pcie_devctl = 0x0; 922 pcie_devctl &= PCIE_DEVCTL_ENABLE_NO_SNOOP; 923 pcie_devctl |= PCIE_DEVCTL_RO_EN; 924 pci_config_put16(dev_regs->nxge_pciregh, pci_offset, 925 pcie_devctl); 926 #endif 927 928 (void) ddi_dev_regsize(nxgep->dip, 1, ®size); 929 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 930 "nxge_map_regs: pio size 0x%x", regsize)); 931 /* set up the device mapped register */ 932 ddi_status = ddi_regs_map_setup(nxgep->dip, 1, 933 (caddr_t *)&(dev_regs->nxge_regp), 0, 0, 934 &nxge_dev_reg_acc_attr, &dev_regs->nxge_regh); 935 if (ddi_status != DDI_SUCCESS) { 936 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 937 "ddi_map_regs for Neptune global reg failed")); 938 goto nxge_map_regs_fail1; 939 } 940 941 /* set up the msi/msi-x mapped register */ 942 (void) ddi_dev_regsize(nxgep->dip, 2, ®size); 943 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 944 "nxge_map_regs: msix size 0x%x", regsize)); 945 ddi_status = ddi_regs_map_setup(nxgep->dip, 2, 946 (caddr_t *)&(dev_regs->nxge_msix_regp), 0, 0, 947 &nxge_dev_reg_acc_attr, &dev_regs->nxge_msix_regh); 948 if (ddi_status != DDI_SUCCESS) { 949 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 950 "ddi_map_regs for msi reg failed")); 951 goto nxge_map_regs_fail2; 952 } 953 954 /* set up the vio region mapped register */ 955 (void) ddi_dev_regsize(nxgep->dip, 3, ®size); 956 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 957 "nxge_map_regs: vio size 0x%x", regsize)); 958 ddi_status = ddi_regs_map_setup(nxgep->dip, 3, 959 (caddr_t *)&(dev_regs->nxge_vir_regp), 0, 0, 960 &nxge_dev_reg_acc_attr, &dev_regs->nxge_vir_regh); 961 962 if (ddi_status != DDI_SUCCESS) { 963 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 964 "ddi_map_regs for nxge vio reg failed")); 965 goto nxge_map_regs_fail3; 966 } 967 nxgep->dev_regs = dev_regs; 968 969 NPI_PCI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_pciregh); 970 NPI_PCI_ADD_HANDLE_SET(nxgep, 971 (npi_reg_ptr_t)dev_regs->nxge_pciregp); 972 NPI_MSI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_msix_regh); 973 NPI_MSI_ADD_HANDLE_SET(nxgep, 974 (npi_reg_ptr_t)dev_regs->nxge_msix_regp); 975 976 NPI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 977 NPI_ADD_HANDLE_SET(nxgep, (npi_reg_ptr_t)dev_regs->nxge_regp); 978 979 NPI_REG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 980 NPI_REG_ADD_HANDLE_SET(nxgep, 981 (npi_reg_ptr_t)dev_regs->nxge_regp); 982 983 NPI_VREG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_vir_regh); 984 NPI_VREG_ADD_HANDLE_SET(nxgep, 985 (npi_reg_ptr_t)dev_regs->nxge_vir_regp); 986 987 break; 988 989 case N2_NIU: 990 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "ddi_map_regs, NIU")); 991 /* 992 * Set up the device mapped register (FWARC 2006/556) 993 * (changed back to 1: reg starts at 1!) 994 */ 995 (void) ddi_dev_regsize(nxgep->dip, 1, ®size); 996 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 997 "nxge_map_regs: dev size 0x%x", regsize)); 998 ddi_status = ddi_regs_map_setup(nxgep->dip, 1, 999 (caddr_t *)&(dev_regs->nxge_regp), 0, 0, 1000 &nxge_dev_reg_acc_attr, &dev_regs->nxge_regh); 1001 1002 if (ddi_status != DDI_SUCCESS) { 1003 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1004 "ddi_map_regs for N2/NIU, global reg failed ")); 1005 goto nxge_map_regs_fail1; 1006 } 1007 1008 /* set up the vio region mapped register */ 1009 (void) ddi_dev_regsize(nxgep->dip, 2, ®size); 1010 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1011 "nxge_map_regs: vio (1) size 0x%x", regsize)); 1012 ddi_status = ddi_regs_map_setup(nxgep->dip, 2, 1013 (caddr_t *)&(dev_regs->nxge_vir_regp), 0, 0, 1014 &nxge_dev_reg_acc_attr, &dev_regs->nxge_vir_regh); 1015 1016 if (ddi_status != DDI_SUCCESS) { 1017 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1018 "ddi_map_regs for nxge vio reg failed")); 1019 goto nxge_map_regs_fail2; 1020 } 1021 /* set up the vio region mapped register */ 1022 (void) ddi_dev_regsize(nxgep->dip, 3, ®size); 1023 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1024 "nxge_map_regs: vio (3) size 0x%x", regsize)); 1025 ddi_status = ddi_regs_map_setup(nxgep->dip, 3, 1026 (caddr_t *)&(dev_regs->nxge_vir2_regp), 0, 0, 1027 &nxge_dev_reg_acc_attr, &dev_regs->nxge_vir2_regh); 1028 1029 if (ddi_status != DDI_SUCCESS) { 1030 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1031 "ddi_map_regs for nxge vio2 reg failed")); 1032 goto nxge_map_regs_fail3; 1033 } 1034 nxgep->dev_regs = dev_regs; 1035 1036 NPI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 1037 NPI_ADD_HANDLE_SET(nxgep, (npi_reg_ptr_t)dev_regs->nxge_regp); 1038 1039 NPI_REG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 1040 NPI_REG_ADD_HANDLE_SET(nxgep, 1041 (npi_reg_ptr_t)dev_regs->nxge_regp); 1042 1043 NPI_VREG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_vir_regh); 1044 NPI_VREG_ADD_HANDLE_SET(nxgep, 1045 (npi_reg_ptr_t)dev_regs->nxge_vir_regp); 1046 1047 NPI_V2REG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_vir2_regh); 1048 NPI_V2REG_ADD_HANDLE_SET(nxgep, 1049 (npi_reg_ptr_t)dev_regs->nxge_vir2_regp); 1050 1051 break; 1052 } 1053 1054 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_map_reg: hardware addr 0x%0llx " 1055 " handle 0x%0llx", dev_regs->nxge_regp, dev_regs->nxge_regh)); 1056 1057 goto nxge_map_regs_exit; 1058 nxge_map_regs_fail3: 1059 if (dev_regs->nxge_msix_regh) { 1060 ddi_regs_map_free(&dev_regs->nxge_msix_regh); 1061 } 1062 if (dev_regs->nxge_vir_regh) { 1063 ddi_regs_map_free(&dev_regs->nxge_regh); 1064 } 1065 nxge_map_regs_fail2: 1066 if (dev_regs->nxge_regh) { 1067 ddi_regs_map_free(&dev_regs->nxge_regh); 1068 } 1069 nxge_map_regs_fail1: 1070 if (dev_regs->nxge_pciregh) { 1071 ddi_regs_map_free(&dev_regs->nxge_pciregh); 1072 } 1073 nxge_map_regs_fail0: 1074 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "Freeing register set memory")); 1075 kmem_free(dev_regs, sizeof (dev_regs_t)); 1076 1077 nxge_map_regs_exit: 1078 if (ddi_status != DDI_SUCCESS) 1079 status |= (NXGE_ERROR | NXGE_DDI_FAILED); 1080 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_map_regs")); 1081 return (status); 1082 } 1083 1084 static void 1085 nxge_unmap_regs(p_nxge_t nxgep) 1086 { 1087 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_unmap_regs")); 1088 if (nxgep->dev_regs) { 1089 if (nxgep->dev_regs->nxge_pciregh) { 1090 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1091 "==> nxge_unmap_regs: bus")); 1092 ddi_regs_map_free(&nxgep->dev_regs->nxge_pciregh); 1093 nxgep->dev_regs->nxge_pciregh = NULL; 1094 } 1095 if (nxgep->dev_regs->nxge_regh) { 1096 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1097 "==> nxge_unmap_regs: device registers")); 1098 ddi_regs_map_free(&nxgep->dev_regs->nxge_regh); 1099 nxgep->dev_regs->nxge_regh = NULL; 1100 } 1101 if (nxgep->dev_regs->nxge_msix_regh) { 1102 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1103 "==> nxge_unmap_regs: device interrupts")); 1104 ddi_regs_map_free(&nxgep->dev_regs->nxge_msix_regh); 1105 nxgep->dev_regs->nxge_msix_regh = NULL; 1106 } 1107 if (nxgep->dev_regs->nxge_vir_regh) { 1108 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1109 "==> nxge_unmap_regs: vio region")); 1110 ddi_regs_map_free(&nxgep->dev_regs->nxge_vir_regh); 1111 nxgep->dev_regs->nxge_vir_regh = NULL; 1112 } 1113 if (nxgep->dev_regs->nxge_vir2_regh) { 1114 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1115 "==> nxge_unmap_regs: vio2 region")); 1116 ddi_regs_map_free(&nxgep->dev_regs->nxge_vir2_regh); 1117 nxgep->dev_regs->nxge_vir2_regh = NULL; 1118 } 1119 1120 kmem_free(nxgep->dev_regs, sizeof (dev_regs_t)); 1121 nxgep->dev_regs = NULL; 1122 } 1123 1124 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_unmap_regs")); 1125 } 1126 1127 static nxge_status_t 1128 nxge_setup_mutexes(p_nxge_t nxgep) 1129 { 1130 int ddi_status = DDI_SUCCESS; 1131 nxge_status_t status = NXGE_OK; 1132 nxge_classify_t *classify_ptr; 1133 int partition; 1134 1135 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_setup_mutexes")); 1136 1137 /* 1138 * Get the interrupt cookie so the mutexes can be 1139 * Initialized. 1140 */ 1141 ddi_status = ddi_get_iblock_cookie(nxgep->dip, 0, 1142 &nxgep->interrupt_cookie); 1143 if (ddi_status != DDI_SUCCESS) { 1144 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1145 "<== nxge_setup_mutexes: failed 0x%x", ddi_status)); 1146 goto nxge_setup_mutexes_exit; 1147 } 1148 1149 cv_init(&nxgep->poll_cv, NULL, CV_DRIVER, NULL); 1150 MUTEX_INIT(&nxgep->poll_lock, NULL, 1151 MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 1152 1153 /* 1154 * Initialize mutexes for this device. 1155 */ 1156 MUTEX_INIT(nxgep->genlock, NULL, 1157 MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 1158 MUTEX_INIT(&nxgep->ouraddr_lock, NULL, 1159 MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 1160 MUTEX_INIT(&nxgep->mif_lock, NULL, 1161 MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 1162 RW_INIT(&nxgep->filter_lock, NULL, 1163 RW_DRIVER, (void *)nxgep->interrupt_cookie); 1164 1165 classify_ptr = &nxgep->classifier; 1166 /* 1167 * FFLP Mutexes are never used in interrupt context 1168 * as fflp operation can take very long time to 1169 * complete and hence not suitable to invoke from interrupt 1170 * handlers. 1171 */ 1172 MUTEX_INIT(&classify_ptr->tcam_lock, NULL, 1173 NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 1174 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1175 MUTEX_INIT(&classify_ptr->fcram_lock, NULL, 1176 NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 1177 for (partition = 0; partition < MAX_PARTITION; partition++) { 1178 MUTEX_INIT(&classify_ptr->hash_lock[partition], NULL, 1179 NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 1180 } 1181 } 1182 1183 nxge_setup_mutexes_exit: 1184 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1185 "<== nxge_setup_mutexes status = %x", status)); 1186 1187 if (ddi_status != DDI_SUCCESS) 1188 status |= (NXGE_ERROR | NXGE_DDI_FAILED); 1189 1190 return (status); 1191 } 1192 1193 static void 1194 nxge_destroy_mutexes(p_nxge_t nxgep) 1195 { 1196 int partition; 1197 nxge_classify_t *classify_ptr; 1198 1199 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_destroy_mutexes")); 1200 RW_DESTROY(&nxgep->filter_lock); 1201 MUTEX_DESTROY(&nxgep->mif_lock); 1202 MUTEX_DESTROY(&nxgep->ouraddr_lock); 1203 MUTEX_DESTROY(nxgep->genlock); 1204 1205 classify_ptr = &nxgep->classifier; 1206 MUTEX_DESTROY(&classify_ptr->tcam_lock); 1207 1208 /* Destroy all polling resources. */ 1209 MUTEX_DESTROY(&nxgep->poll_lock); 1210 cv_destroy(&nxgep->poll_cv); 1211 1212 /* free data structures, based on HW type */ 1213 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1214 MUTEX_DESTROY(&classify_ptr->fcram_lock); 1215 for (partition = 0; partition < MAX_PARTITION; partition++) { 1216 MUTEX_DESTROY(&classify_ptr->hash_lock[partition]); 1217 } 1218 } 1219 1220 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_destroy_mutexes")); 1221 } 1222 1223 nxge_status_t 1224 nxge_init(p_nxge_t nxgep) 1225 { 1226 nxge_status_t status = NXGE_OK; 1227 1228 NXGE_DEBUG_MSG((nxgep, STR_CTL, "==> nxge_init")); 1229 1230 if (nxgep->drv_state & STATE_HW_INITIALIZED) { 1231 return (status); 1232 } 1233 1234 /* 1235 * Allocate system memory for the receive/transmit buffer blocks 1236 * and receive/transmit descriptor rings. 1237 */ 1238 status = nxge_alloc_mem_pool(nxgep); 1239 if (status != NXGE_OK) { 1240 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "alloc mem failed\n")); 1241 goto nxge_init_fail1; 1242 } 1243 1244 /* 1245 * Initialize and enable TXC registers 1246 * (Globally enable TX controller, 1247 * enable a port, configure dma channel bitmap, 1248 * configure the max burst size). 1249 */ 1250 status = nxge_txc_init(nxgep); 1251 if (status != NXGE_OK) { 1252 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init txc failed\n")); 1253 goto nxge_init_fail2; 1254 } 1255 1256 /* 1257 * Initialize and enable TXDMA channels. 1258 */ 1259 status = nxge_init_txdma_channels(nxgep); 1260 if (status != NXGE_OK) { 1261 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init txdma failed\n")); 1262 goto nxge_init_fail3; 1263 } 1264 1265 /* 1266 * Initialize and enable RXDMA channels. 1267 */ 1268 status = nxge_init_rxdma_channels(nxgep); 1269 if (status != NXGE_OK) { 1270 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init rxdma failed\n")); 1271 goto nxge_init_fail4; 1272 } 1273 1274 /* 1275 * Initialize TCAM and FCRAM (Neptune). 1276 */ 1277 status = nxge_classify_init(nxgep); 1278 if (status != NXGE_OK) { 1279 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init classify failed\n")); 1280 goto nxge_init_fail5; 1281 } 1282 1283 /* 1284 * Initialize ZCP 1285 */ 1286 status = nxge_zcp_init(nxgep); 1287 if (status != NXGE_OK) { 1288 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init ZCP failed\n")); 1289 goto nxge_init_fail5; 1290 } 1291 1292 /* 1293 * Initialize IPP. 1294 */ 1295 status = nxge_ipp_init(nxgep); 1296 if (status != NXGE_OK) { 1297 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init IPP failed\n")); 1298 goto nxge_init_fail5; 1299 } 1300 1301 /* 1302 * Initialize the MAC block. 1303 */ 1304 status = nxge_mac_init(nxgep); 1305 if (status != NXGE_OK) { 1306 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init MAC failed\n")); 1307 goto nxge_init_fail5; 1308 } 1309 1310 nxge_intrs_enable(nxgep); 1311 1312 /* 1313 * Enable hardware interrupts. 1314 */ 1315 nxge_intr_hw_enable(nxgep); 1316 nxgep->drv_state |= STATE_HW_INITIALIZED; 1317 1318 goto nxge_init_exit; 1319 1320 nxge_init_fail5: 1321 nxge_uninit_rxdma_channels(nxgep); 1322 nxge_init_fail4: 1323 nxge_uninit_txdma_channels(nxgep); 1324 nxge_init_fail3: 1325 (void) nxge_txc_uninit(nxgep); 1326 nxge_init_fail2: 1327 nxge_free_mem_pool(nxgep); 1328 nxge_init_fail1: 1329 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1330 "<== nxge_init status (failed) = 0x%08x", status)); 1331 return (status); 1332 1333 nxge_init_exit: 1334 1335 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_init status = 0x%08x", 1336 status)); 1337 return (status); 1338 } 1339 1340 1341 timeout_id_t 1342 nxge_start_timer(p_nxge_t nxgep, fptrv_t func, int msec) 1343 { 1344 if ((nxgep->suspended == 0) || 1345 (nxgep->suspended == DDI_RESUME)) { 1346 return (timeout(func, (caddr_t)nxgep, 1347 drv_usectohz(1000 * msec))); 1348 } 1349 return (NULL); 1350 } 1351 1352 /*ARGSUSED*/ 1353 void 1354 nxge_stop_timer(p_nxge_t nxgep, timeout_id_t timerid) 1355 { 1356 if (timerid) { 1357 (void) untimeout(timerid); 1358 } 1359 } 1360 1361 void 1362 nxge_uninit(p_nxge_t nxgep) 1363 { 1364 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_uninit")); 1365 1366 if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 1367 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1368 "==> nxge_uninit: not initialized")); 1369 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1370 "<== nxge_uninit")); 1371 return; 1372 } 1373 1374 /* stop timer */ 1375 if (nxgep->nxge_timerid) { 1376 nxge_stop_timer(nxgep, nxgep->nxge_timerid); 1377 nxgep->nxge_timerid = 0; 1378 } 1379 1380 (void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP); 1381 (void) nxge_intr_hw_disable(nxgep); 1382 1383 /* 1384 * Reset the receive MAC side. 1385 */ 1386 (void) nxge_rx_mac_disable(nxgep); 1387 1388 /* Disable and soft reset the IPP */ 1389 (void) nxge_ipp_disable(nxgep); 1390 1391 /* Free classification resources */ 1392 (void) nxge_classify_uninit(nxgep); 1393 1394 /* 1395 * Reset the transmit/receive DMA side. 1396 */ 1397 (void) nxge_txdma_hw_mode(nxgep, NXGE_DMA_STOP); 1398 (void) nxge_rxdma_hw_mode(nxgep, NXGE_DMA_STOP); 1399 1400 nxge_uninit_txdma_channels(nxgep); 1401 nxge_uninit_rxdma_channels(nxgep); 1402 1403 /* 1404 * Reset the transmit MAC side. 1405 */ 1406 (void) nxge_tx_mac_disable(nxgep); 1407 1408 nxge_free_mem_pool(nxgep); 1409 1410 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 1411 1412 nxgep->drv_state &= ~STATE_HW_INITIALIZED; 1413 1414 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_uninit: " 1415 "nxge_mblks_pending %d", nxge_mblks_pending)); 1416 } 1417 1418 void 1419 nxge_get64(p_nxge_t nxgep, p_mblk_t mp) 1420 { 1421 #if defined(__i386) 1422 size_t reg; 1423 #else 1424 uint64_t reg; 1425 #endif 1426 uint64_t regdata; 1427 int i, retry; 1428 1429 bcopy((char *)mp->b_rptr, (char *)®, sizeof (uint64_t)); 1430 regdata = 0; 1431 retry = 1; 1432 1433 for (i = 0; i < retry; i++) { 1434 NXGE_REG_RD64(nxgep->npi_handle, reg, ®data); 1435 } 1436 bcopy((char *)®data, (char *)mp->b_rptr, sizeof (uint64_t)); 1437 } 1438 1439 void 1440 nxge_put64(p_nxge_t nxgep, p_mblk_t mp) 1441 { 1442 #if defined(__i386) 1443 size_t reg; 1444 #else 1445 uint64_t reg; 1446 #endif 1447 uint64_t buf[2]; 1448 1449 bcopy((char *)mp->b_rptr, (char *)&buf[0], 2 * sizeof (uint64_t)); 1450 #if defined(__i386) 1451 reg = (size_t)buf[0]; 1452 #else 1453 reg = buf[0]; 1454 #endif 1455 1456 NXGE_NPI_PIO_WRITE64(nxgep->npi_handle, reg, buf[1]); 1457 } 1458 1459 1460 nxge_os_mutex_t nxgedebuglock; 1461 int nxge_debug_init = 0; 1462 1463 /*ARGSUSED*/ 1464 /*VARARGS*/ 1465 void 1466 nxge_debug_msg(p_nxge_t nxgep, uint64_t level, char *fmt, ...) 1467 { 1468 char msg_buffer[1048]; 1469 char prefix_buffer[32]; 1470 int instance; 1471 uint64_t debug_level; 1472 int cmn_level = CE_CONT; 1473 va_list ap; 1474 1475 debug_level = (nxgep == NULL) ? nxge_debug_level : 1476 nxgep->nxge_debug_level; 1477 1478 if ((level & debug_level) || 1479 (level == NXGE_NOTE) || 1480 (level == NXGE_ERR_CTL)) { 1481 /* do the msg processing */ 1482 if (nxge_debug_init == 0) { 1483 MUTEX_INIT(&nxgedebuglock, NULL, MUTEX_DRIVER, NULL); 1484 nxge_debug_init = 1; 1485 } 1486 1487 MUTEX_ENTER(&nxgedebuglock); 1488 1489 if ((level & NXGE_NOTE)) { 1490 cmn_level = CE_NOTE; 1491 } 1492 1493 if (level & NXGE_ERR_CTL) { 1494 cmn_level = CE_WARN; 1495 } 1496 1497 va_start(ap, fmt); 1498 (void) vsprintf(msg_buffer, fmt, ap); 1499 va_end(ap); 1500 if (nxgep == NULL) { 1501 instance = -1; 1502 (void) sprintf(prefix_buffer, "%s :", "nxge"); 1503 } else { 1504 instance = nxgep->instance; 1505 (void) sprintf(prefix_buffer, 1506 "%s%d :", "nxge", instance); 1507 } 1508 1509 MUTEX_EXIT(&nxgedebuglock); 1510 cmn_err(cmn_level, "!%s %s\n", 1511 prefix_buffer, msg_buffer); 1512 1513 } 1514 } 1515 1516 char * 1517 nxge_dump_packet(char *addr, int size) 1518 { 1519 uchar_t *ap = (uchar_t *)addr; 1520 int i; 1521 static char etherbuf[1024]; 1522 char *cp = etherbuf; 1523 char digits[] = "0123456789abcdef"; 1524 1525 if (!size) 1526 size = 60; 1527 1528 if (size > MAX_DUMP_SZ) { 1529 /* Dump the leading bytes */ 1530 for (i = 0; i < MAX_DUMP_SZ/2; i++) { 1531 if (*ap > 0x0f) 1532 *cp++ = digits[*ap >> 4]; 1533 *cp++ = digits[*ap++ & 0xf]; 1534 *cp++ = ':'; 1535 } 1536 for (i = 0; i < 20; i++) 1537 *cp++ = '.'; 1538 /* Dump the last MAX_DUMP_SZ/2 bytes */ 1539 ap = (uchar_t *)(addr + (size - MAX_DUMP_SZ/2)); 1540 for (i = 0; i < MAX_DUMP_SZ/2; i++) { 1541 if (*ap > 0x0f) 1542 *cp++ = digits[*ap >> 4]; 1543 *cp++ = digits[*ap++ & 0xf]; 1544 *cp++ = ':'; 1545 } 1546 } else { 1547 for (i = 0; i < size; i++) { 1548 if (*ap > 0x0f) 1549 *cp++ = digits[*ap >> 4]; 1550 *cp++ = digits[*ap++ & 0xf]; 1551 *cp++ = ':'; 1552 } 1553 } 1554 *--cp = 0; 1555 return (etherbuf); 1556 } 1557 1558 #ifdef NXGE_DEBUG 1559 static void 1560 nxge_test_map_regs(p_nxge_t nxgep) 1561 { 1562 ddi_acc_handle_t cfg_handle; 1563 p_pci_cfg_t cfg_ptr; 1564 ddi_acc_handle_t dev_handle; 1565 char *dev_ptr; 1566 ddi_acc_handle_t pci_config_handle; 1567 uint32_t regval; 1568 int i; 1569 1570 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_test_map_regs")); 1571 1572 dev_handle = nxgep->dev_regs->nxge_regh; 1573 dev_ptr = (char *)nxgep->dev_regs->nxge_regp; 1574 1575 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1576 cfg_handle = nxgep->dev_regs->nxge_pciregh; 1577 cfg_ptr = (void *)nxgep->dev_regs->nxge_pciregp; 1578 1579 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1580 "Neptune PCI regp cfg_ptr 0x%llx", (char *)cfg_ptr)); 1581 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1582 "Neptune PCI cfg_ptr vendor id ptr 0x%llx", 1583 &cfg_ptr->vendorid)); 1584 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1585 "\tvendorid 0x%x devid 0x%x", 1586 NXGE_PIO_READ16(cfg_handle, &cfg_ptr->vendorid, 0), 1587 NXGE_PIO_READ16(cfg_handle, &cfg_ptr->devid, 0))); 1588 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1589 "PCI BAR: base 0x%x base14 0x%x base 18 0x%x " 1590 "bar1c 0x%x", 1591 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base, 0), 1592 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base14, 0), 1593 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base18, 0), 1594 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base1c, 0))); 1595 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1596 "\nNeptune PCI BAR: base20 0x%x base24 0x%x " 1597 "base 28 0x%x bar2c 0x%x\n", 1598 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base20, 0), 1599 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base24, 0), 1600 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base28, 0), 1601 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base2c, 0))); 1602 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1603 "\nNeptune PCI BAR: base30 0x%x\n", 1604 NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base30, 0))); 1605 1606 cfg_handle = nxgep->dev_regs->nxge_pciregh; 1607 cfg_ptr = (void *)nxgep->dev_regs->nxge_pciregp; 1608 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1609 "first 0x%llx second 0x%llx third 0x%llx " 1610 "last 0x%llx ", 1611 NXGE_PIO_READ64(dev_handle, 1612 (uint64_t *)(dev_ptr + 0), 0), 1613 NXGE_PIO_READ64(dev_handle, 1614 (uint64_t *)(dev_ptr + 8), 0), 1615 NXGE_PIO_READ64(dev_handle, 1616 (uint64_t *)(dev_ptr + 16), 0), 1617 NXGE_PIO_READ64(cfg_handle, 1618 (uint64_t *)(dev_ptr + 24), 0))); 1619 } 1620 } 1621 1622 #endif 1623 1624 static void 1625 nxge_suspend(p_nxge_t nxgep) 1626 { 1627 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_suspend")); 1628 1629 nxge_intrs_disable(nxgep); 1630 nxge_destroy_dev(nxgep); 1631 1632 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_suspend")); 1633 } 1634 1635 static nxge_status_t 1636 nxge_resume(p_nxge_t nxgep) 1637 { 1638 nxge_status_t status = NXGE_OK; 1639 1640 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_resume")); 1641 1642 nxgep->suspended = DDI_RESUME; 1643 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 1644 (void) nxge_rxdma_hw_mode(nxgep, NXGE_DMA_START); 1645 (void) nxge_txdma_hw_mode(nxgep, NXGE_DMA_START); 1646 (void) nxge_rx_mac_enable(nxgep); 1647 (void) nxge_tx_mac_enable(nxgep); 1648 nxge_intrs_enable(nxgep); 1649 nxgep->suspended = 0; 1650 1651 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1652 "<== nxge_resume status = 0x%x", status)); 1653 return (status); 1654 } 1655 1656 static nxge_status_t 1657 nxge_setup_dev(p_nxge_t nxgep) 1658 { 1659 nxge_status_t status = NXGE_OK; 1660 1661 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_setup_dev port %d", 1662 nxgep->mac.portnum)); 1663 1664 status = nxge_link_init(nxgep); 1665 1666 if (fm_check_acc_handle(nxgep->dev_regs->nxge_regh) != DDI_FM_OK) { 1667 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1668 "port%d Bad register acc handle", nxgep->mac.portnum)); 1669 status = NXGE_ERROR; 1670 } 1671 1672 if (status != NXGE_OK) { 1673 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1674 " nxge_setup_dev status " 1675 "(xcvr init 0x%08x)", status)); 1676 goto nxge_setup_dev_exit; 1677 } 1678 1679 nxge_setup_dev_exit: 1680 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1681 "<== nxge_setup_dev port %d status = 0x%08x", 1682 nxgep->mac.portnum, status)); 1683 1684 return (status); 1685 } 1686 1687 static void 1688 nxge_destroy_dev(p_nxge_t nxgep) 1689 { 1690 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_destroy_dev")); 1691 1692 (void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP); 1693 1694 (void) nxge_hw_stop(nxgep); 1695 1696 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_destroy_dev")); 1697 } 1698 1699 static nxge_status_t 1700 nxge_setup_system_dma_pages(p_nxge_t nxgep) 1701 { 1702 int ddi_status = DDI_SUCCESS; 1703 uint_t count; 1704 ddi_dma_cookie_t cookie; 1705 uint_t iommu_pagesize; 1706 nxge_status_t status = NXGE_OK; 1707 1708 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_setup_system_dma_pages")); 1709 nxgep->sys_page_sz = ddi_ptob(nxgep->dip, (ulong_t)1); 1710 if (nxgep->niu_type != N2_NIU) { 1711 iommu_pagesize = dvma_pagesize(nxgep->dip); 1712 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1713 " nxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 1714 " default_block_size %d iommu_pagesize %d", 1715 nxgep->sys_page_sz, 1716 ddi_ptob(nxgep->dip, (ulong_t)1), 1717 nxgep->rx_default_block_size, 1718 iommu_pagesize)); 1719 1720 if (iommu_pagesize != 0) { 1721 if (nxgep->sys_page_sz == iommu_pagesize) { 1722 if (iommu_pagesize > 0x4000) 1723 nxgep->sys_page_sz = 0x4000; 1724 } else { 1725 if (nxgep->sys_page_sz > iommu_pagesize) 1726 nxgep->sys_page_sz = iommu_pagesize; 1727 } 1728 } 1729 } 1730 nxgep->sys_page_mask = ~(nxgep->sys_page_sz - 1); 1731 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1732 "==> nxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 1733 "default_block_size %d page mask %d", 1734 nxgep->sys_page_sz, 1735 ddi_ptob(nxgep->dip, (ulong_t)1), 1736 nxgep->rx_default_block_size, 1737 nxgep->sys_page_mask)); 1738 1739 1740 switch (nxgep->sys_page_sz) { 1741 default: 1742 nxgep->sys_page_sz = 0x1000; 1743 nxgep->sys_page_mask = ~(nxgep->sys_page_sz - 1); 1744 nxgep->rx_default_block_size = 0x1000; 1745 nxgep->rx_bksize_code = RBR_BKSIZE_4K; 1746 break; 1747 case 0x1000: 1748 nxgep->rx_default_block_size = 0x1000; 1749 nxgep->rx_bksize_code = RBR_BKSIZE_4K; 1750 break; 1751 case 0x2000: 1752 nxgep->rx_default_block_size = 0x2000; 1753 nxgep->rx_bksize_code = RBR_BKSIZE_8K; 1754 break; 1755 case 0x4000: 1756 nxgep->rx_default_block_size = 0x4000; 1757 nxgep->rx_bksize_code = RBR_BKSIZE_16K; 1758 break; 1759 case 0x8000: 1760 nxgep->rx_default_block_size = 0x8000; 1761 nxgep->rx_bksize_code = RBR_BKSIZE_32K; 1762 break; 1763 } 1764 1765 #ifndef USE_RX_BIG_BUF 1766 nxge_rx_dma_attr.dma_attr_align = nxgep->sys_page_sz; 1767 #else 1768 nxgep->rx_default_block_size = 0x2000; 1769 nxgep->rx_bksize_code = RBR_BKSIZE_8K; 1770 #endif 1771 /* 1772 * Get the system DMA burst size. 1773 */ 1774 ddi_status = ddi_dma_alloc_handle(nxgep->dip, &nxge_tx_dma_attr, 1775 DDI_DMA_DONTWAIT, 0, 1776 &nxgep->dmasparehandle); 1777 if (ddi_status != DDI_SUCCESS) { 1778 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1779 "ddi_dma_alloc_handle: failed " 1780 " status 0x%x", ddi_status)); 1781 goto nxge_get_soft_properties_exit; 1782 } 1783 1784 ddi_status = ddi_dma_addr_bind_handle(nxgep->dmasparehandle, NULL, 1785 (caddr_t)nxgep->dmasparehandle, 1786 sizeof (nxgep->dmasparehandle), 1787 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1788 DDI_DMA_DONTWAIT, 0, 1789 &cookie, &count); 1790 if (ddi_status != DDI_DMA_MAPPED) { 1791 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1792 "Binding spare handle to find system" 1793 " burstsize failed.")); 1794 ddi_status = DDI_FAILURE; 1795 goto nxge_get_soft_properties_fail1; 1796 } 1797 1798 nxgep->sys_burst_sz = ddi_dma_burstsizes(nxgep->dmasparehandle); 1799 (void) ddi_dma_unbind_handle(nxgep->dmasparehandle); 1800 1801 nxge_get_soft_properties_fail1: 1802 ddi_dma_free_handle(&nxgep->dmasparehandle); 1803 1804 nxge_get_soft_properties_exit: 1805 1806 if (ddi_status != DDI_SUCCESS) 1807 status |= (NXGE_ERROR | NXGE_DDI_FAILED); 1808 1809 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 1810 "<== nxge_setup_system_dma_pages status = 0x%08x", status)); 1811 return (status); 1812 } 1813 1814 static nxge_status_t 1815 nxge_alloc_mem_pool(p_nxge_t nxgep) 1816 { 1817 nxge_status_t status = NXGE_OK; 1818 1819 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_alloc_mem_pool")); 1820 1821 status = nxge_alloc_rx_mem_pool(nxgep); 1822 if (status != NXGE_OK) { 1823 return (NXGE_ERROR); 1824 } 1825 1826 status = nxge_alloc_tx_mem_pool(nxgep); 1827 if (status != NXGE_OK) { 1828 nxge_free_rx_mem_pool(nxgep); 1829 return (NXGE_ERROR); 1830 } 1831 1832 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_alloc_mem_pool")); 1833 return (NXGE_OK); 1834 } 1835 1836 static void 1837 nxge_free_mem_pool(p_nxge_t nxgep) 1838 { 1839 NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_free_mem_pool")); 1840 1841 nxge_free_rx_mem_pool(nxgep); 1842 nxge_free_tx_mem_pool(nxgep); 1843 1844 NXGE_DEBUG_MSG((nxgep, MEM_CTL, "<== nxge_free_mem_pool")); 1845 } 1846 1847 static nxge_status_t 1848 nxge_alloc_rx_mem_pool(p_nxge_t nxgep) 1849 { 1850 int i, j; 1851 uint32_t ndmas, st_rdc; 1852 p_nxge_dma_pt_cfg_t p_all_cfgp; 1853 p_nxge_hw_pt_cfg_t p_cfgp; 1854 p_nxge_dma_pool_t dma_poolp; 1855 p_nxge_dma_common_t *dma_buf_p; 1856 p_nxge_dma_pool_t dma_cntl_poolp; 1857 p_nxge_dma_common_t *dma_cntl_p; 1858 size_t rx_buf_alloc_size; 1859 size_t rx_cntl_alloc_size; 1860 uint32_t *num_chunks; /* per dma */ 1861 nxge_status_t status = NXGE_OK; 1862 1863 uint32_t nxge_port_rbr_size; 1864 uint32_t nxge_port_rbr_spare_size; 1865 uint32_t nxge_port_rcr_size; 1866 1867 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_rx_mem_pool")); 1868 1869 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1870 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 1871 st_rdc = p_cfgp->start_rdc; 1872 ndmas = p_cfgp->max_rdcs; 1873 1874 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1875 " nxge_alloc_rx_mem_pool st_rdc %d ndmas %d", st_rdc, ndmas)); 1876 1877 /* 1878 * Allocate memory for each receive DMA channel. 1879 */ 1880 dma_poolp = (p_nxge_dma_pool_t)KMEM_ZALLOC(sizeof (nxge_dma_pool_t), 1881 KM_SLEEP); 1882 dma_buf_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 1883 sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 1884 1885 dma_cntl_poolp = (p_nxge_dma_pool_t) 1886 KMEM_ZALLOC(sizeof (nxge_dma_pool_t), KM_SLEEP); 1887 dma_cntl_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 1888 sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 1889 1890 num_chunks = (uint32_t *)KMEM_ZALLOC( 1891 sizeof (uint32_t) * ndmas, KM_SLEEP); 1892 1893 /* 1894 * Assume that each DMA channel will be configured with default 1895 * block size. 1896 * rbr block counts are mod of batch count (16). 1897 */ 1898 nxge_port_rbr_size = p_all_cfgp->rbr_size; 1899 nxge_port_rcr_size = p_all_cfgp->rcr_size; 1900 1901 if (!nxge_port_rbr_size) { 1902 nxge_port_rbr_size = NXGE_RBR_RBB_DEFAULT; 1903 } 1904 if (nxge_port_rbr_size % NXGE_RXDMA_POST_BATCH) { 1905 nxge_port_rbr_size = (NXGE_RXDMA_POST_BATCH * 1906 (nxge_port_rbr_size / NXGE_RXDMA_POST_BATCH + 1)); 1907 } 1908 1909 p_all_cfgp->rbr_size = nxge_port_rbr_size; 1910 nxge_port_rbr_spare_size = nxge_rbr_spare_size; 1911 1912 if (nxge_port_rbr_spare_size % NXGE_RXDMA_POST_BATCH) { 1913 nxge_port_rbr_spare_size = (NXGE_RXDMA_POST_BATCH * 1914 (nxge_port_rbr_spare_size / NXGE_RXDMA_POST_BATCH + 1)); 1915 } 1916 if (nxge_port_rbr_size > RBR_DEFAULT_MAX_BLKS) { 1917 NXGE_DEBUG_MSG((nxgep, MEM_CTL, 1918 "nxge_alloc_rx_mem_pool: RBR size too high %d, " 1919 "set to default %d", 1920 nxge_port_rbr_size, RBR_DEFAULT_MAX_BLKS)); 1921 nxge_port_rbr_size = RBR_DEFAULT_MAX_BLKS; 1922 } 1923 if (nxge_port_rcr_size > RCR_DEFAULT_MAX) { 1924 NXGE_DEBUG_MSG((nxgep, MEM_CTL, 1925 "nxge_alloc_rx_mem_pool: RCR too high %d, " 1926 "set to default %d", 1927 nxge_port_rcr_size, RCR_DEFAULT_MAX)); 1928 nxge_port_rcr_size = RCR_DEFAULT_MAX; 1929 } 1930 1931 /* 1932 * N2/NIU has limitation on the descriptor sizes (contiguous 1933 * memory allocation on data buffers to 4M (contig_mem_alloc) 1934 * and little endian for control buffers (must use the ddi/dki mem alloc 1935 * function). 1936 */ 1937 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 1938 if (nxgep->niu_type == N2_NIU) { 1939 nxge_port_rbr_spare_size = 0; 1940 if ((nxge_port_rbr_size > NXGE_NIU_CONTIG_RBR_MAX) || 1941 (!ISP2(nxge_port_rbr_size))) { 1942 nxge_port_rbr_size = NXGE_NIU_CONTIG_RBR_MAX; 1943 } 1944 if ((nxge_port_rcr_size > NXGE_NIU_CONTIG_RCR_MAX) || 1945 (!ISP2(nxge_port_rcr_size))) { 1946 nxge_port_rcr_size = NXGE_NIU_CONTIG_RCR_MAX; 1947 } 1948 } 1949 #endif 1950 1951 rx_buf_alloc_size = (nxgep->rx_default_block_size * 1952 (nxge_port_rbr_size + nxge_port_rbr_spare_size)); 1953 1954 /* 1955 * Addresses of receive block ring, receive completion ring and the 1956 * mailbox must be all cache-aligned (64 bytes). 1957 */ 1958 rx_cntl_alloc_size = nxge_port_rbr_size + nxge_port_rbr_spare_size; 1959 rx_cntl_alloc_size *= (sizeof (rx_desc_t)); 1960 rx_cntl_alloc_size += (sizeof (rcr_entry_t) * nxge_port_rcr_size); 1961 rx_cntl_alloc_size += sizeof (rxdma_mailbox_t); 1962 1963 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "==> nxge_alloc_rx_mem_pool: " 1964 "nxge_port_rbr_size = %d nxge_port_rbr_spare_size = %d " 1965 "nxge_port_rcr_size = %d " 1966 "rx_cntl_alloc_size = %d", 1967 nxge_port_rbr_size, nxge_port_rbr_spare_size, 1968 nxge_port_rcr_size, 1969 rx_cntl_alloc_size)); 1970 1971 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 1972 if (nxgep->niu_type == N2_NIU) { 1973 if (!ISP2(rx_buf_alloc_size)) { 1974 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1975 "==> nxge_alloc_rx_mem_pool: " 1976 " must be power of 2")); 1977 status |= (NXGE_ERROR | NXGE_DDI_FAILED); 1978 goto nxge_alloc_rx_mem_pool_exit; 1979 } 1980 1981 if (rx_buf_alloc_size > (1 << 22)) { 1982 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1983 "==> nxge_alloc_rx_mem_pool: " 1984 " limit size to 4M")); 1985 status |= (NXGE_ERROR | NXGE_DDI_FAILED); 1986 goto nxge_alloc_rx_mem_pool_exit; 1987 } 1988 1989 if (rx_cntl_alloc_size < 0x2000) { 1990 rx_cntl_alloc_size = 0x2000; 1991 } 1992 } 1993 #endif 1994 nxgep->nxge_port_rbr_size = nxge_port_rbr_size; 1995 nxgep->nxge_port_rcr_size = nxge_port_rcr_size; 1996 1997 /* 1998 * Allocate memory for receive buffers and descriptor rings. 1999 * Replace allocation functions with interface functions provided 2000 * by the partition manager when it is available. 2001 */ 2002 /* 2003 * Allocate memory for the receive buffer blocks. 2004 */ 2005 for (i = 0; i < ndmas; i++) { 2006 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2007 " nxge_alloc_rx_mem_pool to alloc mem: " 2008 " dma %d dma_buf_p %llx &dma_buf_p %llx", 2009 i, dma_buf_p[i], &dma_buf_p[i])); 2010 num_chunks[i] = 0; 2011 status = nxge_alloc_rx_buf_dma(nxgep, st_rdc, &dma_buf_p[i], 2012 rx_buf_alloc_size, 2013 nxgep->rx_default_block_size, &num_chunks[i]); 2014 if (status != NXGE_OK) { 2015 break; 2016 } 2017 st_rdc++; 2018 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2019 " nxge_alloc_rx_mem_pool DONE alloc mem: " 2020 "dma %d dma_buf_p %llx &dma_buf_p %llx", i, 2021 dma_buf_p[i], &dma_buf_p[i])); 2022 } 2023 if (i < ndmas) { 2024 goto nxge_alloc_rx_mem_fail1; 2025 } 2026 /* 2027 * Allocate memory for descriptor rings and mailbox. 2028 */ 2029 st_rdc = p_cfgp->start_rdc; 2030 for (j = 0; j < ndmas; j++) { 2031 status = nxge_alloc_rx_cntl_dma(nxgep, st_rdc, &dma_cntl_p[j], 2032 rx_cntl_alloc_size); 2033 if (status != NXGE_OK) { 2034 break; 2035 } 2036 st_rdc++; 2037 } 2038 if (j < ndmas) { 2039 goto nxge_alloc_rx_mem_fail2; 2040 } 2041 2042 dma_poolp->ndmas = ndmas; 2043 dma_poolp->num_chunks = num_chunks; 2044 dma_poolp->buf_allocated = B_TRUE; 2045 nxgep->rx_buf_pool_p = dma_poolp; 2046 dma_poolp->dma_buf_pool_p = dma_buf_p; 2047 2048 dma_cntl_poolp->ndmas = ndmas; 2049 dma_cntl_poolp->buf_allocated = B_TRUE; 2050 nxgep->rx_cntl_pool_p = dma_cntl_poolp; 2051 dma_cntl_poolp->dma_buf_pool_p = dma_cntl_p; 2052 2053 goto nxge_alloc_rx_mem_pool_exit; 2054 2055 nxge_alloc_rx_mem_fail2: 2056 /* Free control buffers */ 2057 j--; 2058 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2059 "==> nxge_alloc_rx_mem_pool: freeing control bufs (%d)", j)); 2060 for (; j >= 0; j--) { 2061 nxge_free_rx_cntl_dma(nxgep, 2062 (p_nxge_dma_common_t)dma_cntl_p[j]); 2063 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2064 "==> nxge_alloc_rx_mem_pool: control bufs freed (%d)", 2065 j)); 2066 } 2067 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2068 "==> nxge_alloc_rx_mem_pool: control bufs freed (%d)", j)); 2069 2070 nxge_alloc_rx_mem_fail1: 2071 /* Free data buffers */ 2072 i--; 2073 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2074 "==> nxge_alloc_rx_mem_pool: freeing data bufs (%d)", i)); 2075 for (; i >= 0; i--) { 2076 nxge_free_rx_buf_dma(nxgep, (p_nxge_dma_common_t)dma_buf_p[i], 2077 num_chunks[i]); 2078 } 2079 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2080 "==> nxge_alloc_rx_mem_pool: data bufs freed (%d)", i)); 2081 2082 KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 2083 KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 2084 KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 2085 KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 2086 KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 2087 2088 nxge_alloc_rx_mem_pool_exit: 2089 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2090 "<== nxge_alloc_rx_mem_pool:status 0x%08x", status)); 2091 2092 return (status); 2093 } 2094 2095 static void 2096 nxge_free_rx_mem_pool(p_nxge_t nxgep) 2097 { 2098 uint32_t i, ndmas; 2099 p_nxge_dma_pool_t dma_poolp; 2100 p_nxge_dma_common_t *dma_buf_p; 2101 p_nxge_dma_pool_t dma_cntl_poolp; 2102 p_nxge_dma_common_t *dma_cntl_p; 2103 uint32_t *num_chunks; 2104 2105 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "==> nxge_free_rx_mem_pool")); 2106 2107 dma_poolp = nxgep->rx_buf_pool_p; 2108 if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 2109 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2110 "<== nxge_free_rx_mem_pool " 2111 "(null rx buf pool or buf not allocated")); 2112 return; 2113 } 2114 2115 dma_cntl_poolp = nxgep->rx_cntl_pool_p; 2116 if (dma_cntl_poolp == NULL || (!dma_cntl_poolp->buf_allocated)) { 2117 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2118 "<== nxge_free_rx_mem_pool " 2119 "(null rx cntl buf pool or cntl buf not allocated")); 2120 return; 2121 } 2122 2123 dma_buf_p = dma_poolp->dma_buf_pool_p; 2124 num_chunks = dma_poolp->num_chunks; 2125 2126 dma_cntl_p = dma_cntl_poolp->dma_buf_pool_p; 2127 ndmas = dma_cntl_poolp->ndmas; 2128 2129 for (i = 0; i < ndmas; i++) { 2130 nxge_free_rx_buf_dma(nxgep, dma_buf_p[i], num_chunks[i]); 2131 } 2132 2133 for (i = 0; i < ndmas; i++) { 2134 nxge_free_rx_cntl_dma(nxgep, dma_cntl_p[i]); 2135 } 2136 2137 for (i = 0; i < ndmas; i++) { 2138 KMEM_FREE(dma_buf_p[i], 2139 sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 2140 KMEM_FREE(dma_cntl_p[i], sizeof (nxge_dma_common_t)); 2141 } 2142 2143 KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 2144 KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 2145 KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 2146 KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 2147 KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 2148 2149 nxgep->rx_buf_pool_p = NULL; 2150 nxgep->rx_cntl_pool_p = NULL; 2151 2152 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "<== nxge_free_rx_mem_pool")); 2153 } 2154 2155 2156 static nxge_status_t 2157 nxge_alloc_rx_buf_dma(p_nxge_t nxgep, uint16_t dma_channel, 2158 p_nxge_dma_common_t *dmap, 2159 size_t alloc_size, size_t block_size, uint32_t *num_chunks) 2160 { 2161 p_nxge_dma_common_t rx_dmap; 2162 nxge_status_t status = NXGE_OK; 2163 size_t total_alloc_size; 2164 size_t allocated = 0; 2165 int i, size_index, array_size; 2166 2167 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_rx_buf_dma")); 2168 2169 rx_dmap = (p_nxge_dma_common_t) 2170 KMEM_ZALLOC(sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK, 2171 KM_SLEEP); 2172 2173 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2174 " alloc_rx_buf_dma rdc %d asize %x bsize %x bbuf %llx ", 2175 dma_channel, alloc_size, block_size, dmap)); 2176 2177 total_alloc_size = alloc_size; 2178 2179 #if defined(RX_USE_RECLAIM_POST) 2180 total_alloc_size = alloc_size + alloc_size/4; 2181 #endif 2182 2183 i = 0; 2184 size_index = 0; 2185 array_size = sizeof (alloc_sizes)/sizeof (size_t); 2186 while ((alloc_sizes[size_index] < alloc_size) && 2187 (size_index < array_size)) 2188 size_index++; 2189 if (size_index >= array_size) { 2190 size_index = array_size - 1; 2191 } 2192 2193 while ((allocated < total_alloc_size) && 2194 (size_index >= 0) && (i < NXGE_DMA_BLOCK)) { 2195 rx_dmap[i].dma_chunk_index = i; 2196 rx_dmap[i].block_size = block_size; 2197 rx_dmap[i].alength = alloc_sizes[size_index]; 2198 rx_dmap[i].orig_alength = rx_dmap[i].alength; 2199 rx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 2200 rx_dmap[i].dma_channel = dma_channel; 2201 rx_dmap[i].contig_alloc_type = B_FALSE; 2202 2203 /* 2204 * N2/NIU: data buffers must be contiguous as the driver 2205 * needs to call Hypervisor api to set up 2206 * logical pages. 2207 */ 2208 if ((nxgep->niu_type == N2_NIU) && (NXGE_DMA_BLOCK == 1)) { 2209 rx_dmap[i].contig_alloc_type = B_TRUE; 2210 } 2211 2212 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2213 "alloc_rx_buf_dma rdc %d chunk %d bufp %llx size %x " 2214 "i %d nblocks %d alength %d", 2215 dma_channel, i, &rx_dmap[i], block_size, 2216 i, rx_dmap[i].nblocks, 2217 rx_dmap[i].alength)); 2218 status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 2219 &nxge_rx_dma_attr, 2220 rx_dmap[i].alength, 2221 &nxge_dev_buf_dma_acc_attr, 2222 DDI_DMA_READ | DDI_DMA_STREAMING, 2223 (p_nxge_dma_common_t)(&rx_dmap[i])); 2224 if (status != NXGE_OK) { 2225 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2226 " nxge_alloc_rx_buf_dma: Alloc Failed ")); 2227 size_index--; 2228 } else { 2229 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2230 " alloc_rx_buf_dma allocated rdc %d " 2231 "chunk %d size %x dvma %x bufp %llx ", 2232 dma_channel, i, rx_dmap[i].alength, 2233 rx_dmap[i].ioaddr_pp, &rx_dmap[i])); 2234 i++; 2235 allocated += alloc_sizes[size_index]; 2236 } 2237 } 2238 2239 2240 if (allocated < total_alloc_size) { 2241 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2242 "==> nxge_alloc_rx_buf_dma: not enough for channe %d " 2243 "allocated 0x%x requested 0x%x", 2244 dma_channel, 2245 allocated, total_alloc_size)); 2246 status = NXGE_ERROR; 2247 goto nxge_alloc_rx_mem_fail1; 2248 } 2249 2250 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2251 "==> nxge_alloc_rx_buf_dma: Allocated for channe %d " 2252 "allocated 0x%x requested 0x%x", 2253 dma_channel, 2254 allocated, total_alloc_size)); 2255 2256 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2257 " alloc_rx_buf_dma rdc %d allocated %d chunks", 2258 dma_channel, i)); 2259 *num_chunks = i; 2260 *dmap = rx_dmap; 2261 2262 goto nxge_alloc_rx_mem_exit; 2263 2264 nxge_alloc_rx_mem_fail1: 2265 KMEM_FREE(rx_dmap, sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 2266 2267 nxge_alloc_rx_mem_exit: 2268 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2269 "<== nxge_alloc_rx_buf_dma status 0x%08x", status)); 2270 2271 return (status); 2272 } 2273 2274 /*ARGSUSED*/ 2275 static void 2276 nxge_free_rx_buf_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap, 2277 uint32_t num_chunks) 2278 { 2279 int i; 2280 2281 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2282 "==> nxge_free_rx_buf_dma: # of chunks %d", num_chunks)); 2283 2284 for (i = 0; i < num_chunks; i++) { 2285 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2286 "==> nxge_free_rx_buf_dma: chunk %d dmap 0x%llx", 2287 i, dmap)); 2288 nxge_dma_mem_free(dmap++); 2289 } 2290 2291 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "==> nxge_free_rx_buf_dma")); 2292 } 2293 2294 /*ARGSUSED*/ 2295 static nxge_status_t 2296 nxge_alloc_rx_cntl_dma(p_nxge_t nxgep, uint16_t dma_channel, 2297 p_nxge_dma_common_t *dmap, size_t size) 2298 { 2299 p_nxge_dma_common_t rx_dmap; 2300 nxge_status_t status = NXGE_OK; 2301 2302 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_rx_cntl_dma")); 2303 2304 rx_dmap = (p_nxge_dma_common_t) 2305 KMEM_ZALLOC(sizeof (nxge_dma_common_t), KM_SLEEP); 2306 2307 rx_dmap->contig_alloc_type = B_FALSE; 2308 2309 status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 2310 &nxge_desc_dma_attr, 2311 size, 2312 &nxge_dev_desc_dma_acc_attr, 2313 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 2314 rx_dmap); 2315 if (status != NXGE_OK) { 2316 goto nxge_alloc_rx_cntl_dma_fail1; 2317 } 2318 2319 *dmap = rx_dmap; 2320 goto nxge_alloc_rx_cntl_dma_exit; 2321 2322 nxge_alloc_rx_cntl_dma_fail1: 2323 KMEM_FREE(rx_dmap, sizeof (nxge_dma_common_t)); 2324 2325 nxge_alloc_rx_cntl_dma_exit: 2326 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2327 "<== nxge_alloc_rx_cntl_dma status 0x%08x", status)); 2328 2329 return (status); 2330 } 2331 2332 /*ARGSUSED*/ 2333 static void 2334 nxge_free_rx_cntl_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap) 2335 { 2336 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_free_rx_cntl_dma")); 2337 2338 nxge_dma_mem_free(dmap); 2339 2340 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_free_rx_cntl_dma")); 2341 } 2342 2343 static nxge_status_t 2344 nxge_alloc_tx_mem_pool(p_nxge_t nxgep) 2345 { 2346 nxge_status_t status = NXGE_OK; 2347 int i, j; 2348 uint32_t ndmas, st_tdc; 2349 p_nxge_dma_pt_cfg_t p_all_cfgp; 2350 p_nxge_hw_pt_cfg_t p_cfgp; 2351 p_nxge_dma_pool_t dma_poolp; 2352 p_nxge_dma_common_t *dma_buf_p; 2353 p_nxge_dma_pool_t dma_cntl_poolp; 2354 p_nxge_dma_common_t *dma_cntl_p; 2355 size_t tx_buf_alloc_size; 2356 size_t tx_cntl_alloc_size; 2357 uint32_t *num_chunks; /* per dma */ 2358 uint32_t bcopy_thresh; 2359 2360 NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_alloc_tx_mem_pool")); 2361 2362 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2363 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 2364 st_tdc = p_cfgp->start_tdc; 2365 ndmas = p_cfgp->max_tdcs; 2366 2367 NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_alloc_tx_mem_pool: " 2368 "p_cfgp 0x%016llx start_tdc %d ndmas %d nxgep->max_tdcs %d", 2369 p_cfgp, p_cfgp->start_tdc, p_cfgp->max_tdcs, nxgep->max_tdcs)); 2370 /* 2371 * Allocate memory for each transmit DMA channel. 2372 */ 2373 dma_poolp = (p_nxge_dma_pool_t)KMEM_ZALLOC(sizeof (nxge_dma_pool_t), 2374 KM_SLEEP); 2375 dma_buf_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 2376 sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 2377 2378 dma_cntl_poolp = (p_nxge_dma_pool_t) 2379 KMEM_ZALLOC(sizeof (nxge_dma_pool_t), KM_SLEEP); 2380 dma_cntl_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 2381 sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 2382 2383 if (nxge_tx_ring_size > TDC_DEFAULT_MAX) { 2384 NXGE_DEBUG_MSG((nxgep, MEM_CTL, 2385 "nxge_alloc_tx_mem_pool: TDC too high %d, " 2386 "set to default %d", 2387 nxge_tx_ring_size, TDC_DEFAULT_MAX)); 2388 nxge_tx_ring_size = TDC_DEFAULT_MAX; 2389 } 2390 2391 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 2392 /* 2393 * N2/NIU has limitation on the descriptor sizes (contiguous 2394 * memory allocation on data buffers to 4M (contig_mem_alloc) 2395 * and little endian for control buffers (must use the ddi/dki mem alloc 2396 * function). The transmit ring is limited to 8K (includes the 2397 * mailbox). 2398 */ 2399 if (nxgep->niu_type == N2_NIU) { 2400 if ((nxge_tx_ring_size > NXGE_NIU_CONTIG_TX_MAX) || 2401 (!ISP2(nxge_tx_ring_size))) { 2402 nxge_tx_ring_size = NXGE_NIU_CONTIG_TX_MAX; 2403 } 2404 } 2405 #endif 2406 2407 nxgep->nxge_port_tx_ring_size = nxge_tx_ring_size; 2408 2409 /* 2410 * Assume that each DMA channel will be configured with default 2411 * transmit bufer size for copying transmit data. 2412 * (For packet payload over this limit, packets will not be 2413 * copied.) 2414 */ 2415 if (nxgep->niu_type == N2_NIU) { 2416 bcopy_thresh = TX_BCOPY_SIZE; 2417 } else { 2418 bcopy_thresh = nxge_bcopy_thresh; 2419 } 2420 tx_buf_alloc_size = (bcopy_thresh * nxge_tx_ring_size); 2421 2422 /* 2423 * Addresses of transmit descriptor ring and the 2424 * mailbox must be all cache-aligned (64 bytes). 2425 */ 2426 tx_cntl_alloc_size = nxge_tx_ring_size; 2427 tx_cntl_alloc_size *= (sizeof (tx_desc_t)); 2428 tx_cntl_alloc_size += sizeof (txdma_mailbox_t); 2429 2430 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 2431 if (nxgep->niu_type == N2_NIU) { 2432 if (!ISP2(tx_buf_alloc_size)) { 2433 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2434 "==> nxge_alloc_tx_mem_pool: " 2435 " must be power of 2")); 2436 status |= (NXGE_ERROR | NXGE_DDI_FAILED); 2437 goto nxge_alloc_tx_mem_pool_exit; 2438 } 2439 2440 if (tx_buf_alloc_size > (1 << 22)) { 2441 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2442 "==> nxge_alloc_tx_mem_pool: " 2443 " limit size to 4M")); 2444 status |= (NXGE_ERROR | NXGE_DDI_FAILED); 2445 goto nxge_alloc_tx_mem_pool_exit; 2446 } 2447 2448 if (tx_cntl_alloc_size < 0x2000) { 2449 tx_cntl_alloc_size = 0x2000; 2450 } 2451 } 2452 #endif 2453 2454 num_chunks = (uint32_t *)KMEM_ZALLOC( 2455 sizeof (uint32_t) * ndmas, KM_SLEEP); 2456 2457 /* 2458 * Allocate memory for transmit buffers and descriptor rings. 2459 * Replace allocation functions with interface functions provided 2460 * by the partition manager when it is available. 2461 * 2462 * Allocate memory for the transmit buffer pool. 2463 */ 2464 for (i = 0; i < ndmas; i++) { 2465 num_chunks[i] = 0; 2466 status = nxge_alloc_tx_buf_dma(nxgep, st_tdc, &dma_buf_p[i], 2467 tx_buf_alloc_size, 2468 bcopy_thresh, &num_chunks[i]); 2469 if (status != NXGE_OK) { 2470 break; 2471 } 2472 st_tdc++; 2473 } 2474 if (i < ndmas) { 2475 goto nxge_alloc_tx_mem_pool_fail1; 2476 } 2477 2478 st_tdc = p_cfgp->start_tdc; 2479 /* 2480 * Allocate memory for descriptor rings and mailbox. 2481 */ 2482 for (j = 0; j < ndmas; j++) { 2483 status = nxge_alloc_tx_cntl_dma(nxgep, st_tdc, &dma_cntl_p[j], 2484 tx_cntl_alloc_size); 2485 if (status != NXGE_OK) { 2486 break; 2487 } 2488 st_tdc++; 2489 } 2490 if (j < ndmas) { 2491 goto nxge_alloc_tx_mem_pool_fail2; 2492 } 2493 2494 dma_poolp->ndmas = ndmas; 2495 dma_poolp->num_chunks = num_chunks; 2496 dma_poolp->buf_allocated = B_TRUE; 2497 dma_poolp->dma_buf_pool_p = dma_buf_p; 2498 nxgep->tx_buf_pool_p = dma_poolp; 2499 2500 dma_cntl_poolp->ndmas = ndmas; 2501 dma_cntl_poolp->buf_allocated = B_TRUE; 2502 dma_cntl_poolp->dma_buf_pool_p = dma_cntl_p; 2503 nxgep->tx_cntl_pool_p = dma_cntl_poolp; 2504 2505 NXGE_DEBUG_MSG((nxgep, MEM_CTL, 2506 "==> nxge_alloc_tx_mem_pool: start_tdc %d " 2507 "ndmas %d poolp->ndmas %d", 2508 st_tdc, ndmas, dma_poolp->ndmas)); 2509 2510 goto nxge_alloc_tx_mem_pool_exit; 2511 2512 nxge_alloc_tx_mem_pool_fail2: 2513 /* Free control buffers */ 2514 j--; 2515 for (; j >= 0; j--) { 2516 nxge_free_tx_cntl_dma(nxgep, 2517 (p_nxge_dma_common_t)dma_cntl_p[j]); 2518 } 2519 2520 nxge_alloc_tx_mem_pool_fail1: 2521 /* Free data buffers */ 2522 i--; 2523 for (; i >= 0; i--) { 2524 nxge_free_tx_buf_dma(nxgep, (p_nxge_dma_common_t)dma_buf_p[i], 2525 num_chunks[i]); 2526 } 2527 2528 KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 2529 KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 2530 KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 2531 KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 2532 KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 2533 2534 nxge_alloc_tx_mem_pool_exit: 2535 NXGE_DEBUG_MSG((nxgep, MEM_CTL, 2536 "<== nxge_alloc_tx_mem_pool:status 0x%08x", status)); 2537 2538 return (status); 2539 } 2540 2541 static nxge_status_t 2542 nxge_alloc_tx_buf_dma(p_nxge_t nxgep, uint16_t dma_channel, 2543 p_nxge_dma_common_t *dmap, size_t alloc_size, 2544 size_t block_size, uint32_t *num_chunks) 2545 { 2546 p_nxge_dma_common_t tx_dmap; 2547 nxge_status_t status = NXGE_OK; 2548 size_t total_alloc_size; 2549 size_t allocated = 0; 2550 int i, size_index, array_size; 2551 2552 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_tx_buf_dma")); 2553 2554 tx_dmap = (p_nxge_dma_common_t) 2555 KMEM_ZALLOC(sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK, 2556 KM_SLEEP); 2557 2558 total_alloc_size = alloc_size; 2559 i = 0; 2560 size_index = 0; 2561 array_size = sizeof (alloc_sizes) / sizeof (size_t); 2562 while ((alloc_sizes[size_index] < alloc_size) && 2563 (size_index < array_size)) 2564 size_index++; 2565 if (size_index >= array_size) { 2566 size_index = array_size - 1; 2567 } 2568 2569 while ((allocated < total_alloc_size) && 2570 (size_index >= 0) && (i < NXGE_DMA_BLOCK)) { 2571 2572 tx_dmap[i].dma_chunk_index = i; 2573 tx_dmap[i].block_size = block_size; 2574 tx_dmap[i].alength = alloc_sizes[size_index]; 2575 tx_dmap[i].orig_alength = tx_dmap[i].alength; 2576 tx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 2577 tx_dmap[i].dma_channel = dma_channel; 2578 tx_dmap[i].contig_alloc_type = B_FALSE; 2579 2580 /* 2581 * N2/NIU: data buffers must be contiguous as the driver 2582 * needs to call Hypervisor api to set up 2583 * logical pages. 2584 */ 2585 if ((nxgep->niu_type == N2_NIU) && (NXGE_DMA_BLOCK == 1)) { 2586 tx_dmap[i].contig_alloc_type = B_TRUE; 2587 } 2588 2589 status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 2590 &nxge_tx_dma_attr, 2591 tx_dmap[i].alength, 2592 &nxge_dev_buf_dma_acc_attr, 2593 DDI_DMA_WRITE | DDI_DMA_STREAMING, 2594 (p_nxge_dma_common_t)(&tx_dmap[i])); 2595 if (status != NXGE_OK) { 2596 size_index--; 2597 } else { 2598 i++; 2599 allocated += alloc_sizes[size_index]; 2600 } 2601 } 2602 2603 if (allocated < total_alloc_size) { 2604 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2605 "==> nxge_alloc_tx_buf_dma: not enough channel %d: " 2606 "allocated 0x%x requested 0x%x", 2607 dma_channel, 2608 allocated, total_alloc_size)); 2609 status = NXGE_ERROR; 2610 goto nxge_alloc_tx_mem_fail1; 2611 } 2612 2613 NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 2614 "==> nxge_alloc_tx_buf_dma: Allocated for channel %d: " 2615 "allocated 0x%x requested 0x%x", 2616 dma_channel, 2617 allocated, total_alloc_size)); 2618 2619 *num_chunks = i; 2620 *dmap = tx_dmap; 2621 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2622 "==> nxge_alloc_tx_buf_dma dmap 0x%016llx num chunks %d", 2623 *dmap, i)); 2624 goto nxge_alloc_tx_mem_exit; 2625 2626 nxge_alloc_tx_mem_fail1: 2627 KMEM_FREE(tx_dmap, sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 2628 2629 nxge_alloc_tx_mem_exit: 2630 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2631 "<== nxge_alloc_tx_buf_dma status 0x%08x", status)); 2632 2633 return (status); 2634 } 2635 2636 /*ARGSUSED*/ 2637 static void 2638 nxge_free_tx_buf_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap, 2639 uint32_t num_chunks) 2640 { 2641 int i; 2642 2643 NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_free_tx_buf_dma")); 2644 2645 for (i = 0; i < num_chunks; i++) { 2646 nxge_dma_mem_free(dmap++); 2647 } 2648 2649 NXGE_DEBUG_MSG((nxgep, MEM_CTL, "<== nxge_free_tx_buf_dma")); 2650 } 2651 2652 /*ARGSUSED*/ 2653 static nxge_status_t 2654 nxge_alloc_tx_cntl_dma(p_nxge_t nxgep, uint16_t dma_channel, 2655 p_nxge_dma_common_t *dmap, size_t size) 2656 { 2657 p_nxge_dma_common_t tx_dmap; 2658 nxge_status_t status = NXGE_OK; 2659 2660 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_tx_cntl_dma")); 2661 tx_dmap = (p_nxge_dma_common_t) 2662 KMEM_ZALLOC(sizeof (nxge_dma_common_t), KM_SLEEP); 2663 2664 tx_dmap->contig_alloc_type = B_FALSE; 2665 2666 status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 2667 &nxge_desc_dma_attr, 2668 size, 2669 &nxge_dev_desc_dma_acc_attr, 2670 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 2671 tx_dmap); 2672 if (status != NXGE_OK) { 2673 goto nxge_alloc_tx_cntl_dma_fail1; 2674 } 2675 2676 *dmap = tx_dmap; 2677 goto nxge_alloc_tx_cntl_dma_exit; 2678 2679 nxge_alloc_tx_cntl_dma_fail1: 2680 KMEM_FREE(tx_dmap, sizeof (nxge_dma_common_t)); 2681 2682 nxge_alloc_tx_cntl_dma_exit: 2683 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2684 "<== nxge_alloc_tx_cntl_dma status 0x%08x", status)); 2685 2686 return (status); 2687 } 2688 2689 /*ARGSUSED*/ 2690 static void 2691 nxge_free_tx_cntl_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap) 2692 { 2693 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_free_tx_cntl_dma")); 2694 2695 nxge_dma_mem_free(dmap); 2696 2697 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_free_tx_cntl_dma")); 2698 } 2699 2700 static void 2701 nxge_free_tx_mem_pool(p_nxge_t nxgep) 2702 { 2703 uint32_t i, ndmas; 2704 p_nxge_dma_pool_t dma_poolp; 2705 p_nxge_dma_common_t *dma_buf_p; 2706 p_nxge_dma_pool_t dma_cntl_poolp; 2707 p_nxge_dma_common_t *dma_cntl_p; 2708 uint32_t *num_chunks; 2709 2710 NXGE_DEBUG_MSG((nxgep, MEM3_CTL, "==> nxge_free_tx_mem_pool")); 2711 2712 dma_poolp = nxgep->tx_buf_pool_p; 2713 if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 2714 NXGE_DEBUG_MSG((nxgep, MEM3_CTL, 2715 "<== nxge_free_tx_mem_pool " 2716 "(null rx buf pool or buf not allocated")); 2717 return; 2718 } 2719 2720 dma_cntl_poolp = nxgep->tx_cntl_pool_p; 2721 if (dma_cntl_poolp == NULL || (!dma_cntl_poolp->buf_allocated)) { 2722 NXGE_DEBUG_MSG((nxgep, MEM3_CTL, 2723 "<== nxge_free_tx_mem_pool " 2724 "(null tx cntl buf pool or cntl buf not allocated")); 2725 return; 2726 } 2727 2728 dma_buf_p = dma_poolp->dma_buf_pool_p; 2729 num_chunks = dma_poolp->num_chunks; 2730 2731 dma_cntl_p = dma_cntl_poolp->dma_buf_pool_p; 2732 ndmas = dma_cntl_poolp->ndmas; 2733 2734 for (i = 0; i < ndmas; i++) { 2735 nxge_free_tx_buf_dma(nxgep, dma_buf_p[i], num_chunks[i]); 2736 } 2737 2738 for (i = 0; i < ndmas; i++) { 2739 nxge_free_tx_cntl_dma(nxgep, dma_cntl_p[i]); 2740 } 2741 2742 for (i = 0; i < ndmas; i++) { 2743 KMEM_FREE(dma_buf_p[i], 2744 sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 2745 KMEM_FREE(dma_cntl_p[i], sizeof (nxge_dma_common_t)); 2746 } 2747 2748 KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 2749 KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 2750 KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 2751 KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 2752 KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 2753 2754 nxgep->tx_buf_pool_p = NULL; 2755 nxgep->tx_cntl_pool_p = NULL; 2756 2757 NXGE_DEBUG_MSG((nxgep, MEM3_CTL, "<== nxge_free_tx_mem_pool")); 2758 } 2759 2760 /*ARGSUSED*/ 2761 static nxge_status_t 2762 nxge_dma_mem_alloc(p_nxge_t nxgep, dma_method_t method, 2763 struct ddi_dma_attr *dma_attrp, 2764 size_t length, ddi_device_acc_attr_t *acc_attr_p, uint_t xfer_flags, 2765 p_nxge_dma_common_t dma_p) 2766 { 2767 caddr_t kaddrp; 2768 int ddi_status = DDI_SUCCESS; 2769 boolean_t contig_alloc_type; 2770 2771 contig_alloc_type = dma_p->contig_alloc_type; 2772 2773 if (contig_alloc_type && (nxgep->niu_type != N2_NIU)) { 2774 /* 2775 * contig_alloc_type for contiguous memory only allowed 2776 * for N2/NIU. 2777 */ 2778 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2779 "nxge_dma_mem_alloc: alloc type not allows (%d)", 2780 dma_p->contig_alloc_type)); 2781 return (NXGE_ERROR | NXGE_DDI_FAILED); 2782 } 2783 2784 dma_p->dma_handle = NULL; 2785 dma_p->acc_handle = NULL; 2786 dma_p->kaddrp = dma_p->last_kaddrp = NULL; 2787 dma_p->first_ioaddr_pp = dma_p->last_ioaddr_pp = NULL; 2788 ddi_status = ddi_dma_alloc_handle(nxgep->dip, dma_attrp, 2789 DDI_DMA_DONTWAIT, NULL, &dma_p->dma_handle); 2790 if (ddi_status != DDI_SUCCESS) { 2791 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2792 "nxge_dma_mem_alloc:ddi_dma_alloc_handle failed.")); 2793 return (NXGE_ERROR | NXGE_DDI_FAILED); 2794 } 2795 2796 switch (contig_alloc_type) { 2797 case B_FALSE: 2798 ddi_status = ddi_dma_mem_alloc(dma_p->dma_handle, length, 2799 acc_attr_p, 2800 xfer_flags, 2801 DDI_DMA_DONTWAIT, 0, &kaddrp, &dma_p->alength, 2802 &dma_p->acc_handle); 2803 if (ddi_status != DDI_SUCCESS) { 2804 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2805 "nxge_dma_mem_alloc:ddi_dma_mem_alloc failed")); 2806 ddi_dma_free_handle(&dma_p->dma_handle); 2807 dma_p->dma_handle = NULL; 2808 return (NXGE_ERROR | NXGE_DDI_FAILED); 2809 } 2810 if (dma_p->alength < length) { 2811 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2812 "nxge_dma_mem_alloc:ddi_dma_mem_alloc " 2813 "< length.")); 2814 ddi_dma_mem_free(&dma_p->acc_handle); 2815 ddi_dma_free_handle(&dma_p->dma_handle); 2816 dma_p->acc_handle = NULL; 2817 dma_p->dma_handle = NULL; 2818 return (NXGE_ERROR); 2819 } 2820 2821 ddi_status = ddi_dma_addr_bind_handle(dma_p->dma_handle, NULL, 2822 kaddrp, dma_p->alength, xfer_flags, DDI_DMA_DONTWAIT, 0, 2823 &dma_p->dma_cookie, &dma_p->ncookies); 2824 if (ddi_status != DDI_DMA_MAPPED) { 2825 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2826 "nxge_dma_mem_alloc:di_dma_addr_bind failed " 2827 "(staus 0x%x ncookies %d.)", ddi_status, 2828 dma_p->ncookies)); 2829 if (dma_p->acc_handle) { 2830 ddi_dma_mem_free(&dma_p->acc_handle); 2831 dma_p->acc_handle = NULL; 2832 } 2833 ddi_dma_free_handle(&dma_p->dma_handle); 2834 dma_p->dma_handle = NULL; 2835 return (NXGE_ERROR | NXGE_DDI_FAILED); 2836 } 2837 2838 if (dma_p->ncookies != 1) { 2839 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2840 "nxge_dma_mem_alloc:ddi_dma_addr_bind " 2841 "> 1 cookie" 2842 "(staus 0x%x ncookies %d.)", ddi_status, 2843 dma_p->ncookies)); 2844 if (dma_p->acc_handle) { 2845 ddi_dma_mem_free(&dma_p->acc_handle); 2846 dma_p->acc_handle = NULL; 2847 } 2848 (void) ddi_dma_unbind_handle(dma_p->dma_handle); 2849 ddi_dma_free_handle(&dma_p->dma_handle); 2850 dma_p->dma_handle = NULL; 2851 return (NXGE_ERROR); 2852 } 2853 break; 2854 2855 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 2856 case B_TRUE: 2857 kaddrp = (caddr_t)contig_mem_alloc(length); 2858 if (kaddrp == NULL) { 2859 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2860 "nxge_dma_mem_alloc:contig_mem_alloc failed.")); 2861 ddi_dma_free_handle(&dma_p->dma_handle); 2862 return (NXGE_ERROR | NXGE_DDI_FAILED); 2863 } 2864 2865 dma_p->alength = length; 2866 ddi_status = ddi_dma_addr_bind_handle(dma_p->dma_handle, NULL, 2867 kaddrp, dma_p->alength, xfer_flags, DDI_DMA_DONTWAIT, 0, 2868 &dma_p->dma_cookie, &dma_p->ncookies); 2869 if (ddi_status != DDI_DMA_MAPPED) { 2870 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2871 "nxge_dma_mem_alloc:di_dma_addr_bind failed " 2872 "(status 0x%x ncookies %d.)", ddi_status, 2873 dma_p->ncookies)); 2874 2875 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 2876 "==> nxge_dma_mem_alloc: (not mapped)" 2877 "length %lu (0x%x) " 2878 "free contig kaddrp $%p " 2879 "va_to_pa $%p", 2880 length, length, 2881 kaddrp, 2882 va_to_pa(kaddrp))); 2883 2884 2885 contig_mem_free((void *)kaddrp, length); 2886 ddi_dma_free_handle(&dma_p->dma_handle); 2887 2888 dma_p->dma_handle = NULL; 2889 dma_p->acc_handle = NULL; 2890 dma_p->alength = NULL; 2891 dma_p->kaddrp = NULL; 2892 2893 return (NXGE_ERROR | NXGE_DDI_FAILED); 2894 } 2895 2896 if (dma_p->ncookies != 1 || 2897 (dma_p->dma_cookie.dmac_laddress == NULL)) { 2898 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2899 "nxge_dma_mem_alloc:di_dma_addr_bind > 1 " 2900 "cookie or " 2901 "dmac_laddress is NULL $%p size %d " 2902 " (status 0x%x ncookies %d.)", 2903 ddi_status, 2904 dma_p->dma_cookie.dmac_laddress, 2905 dma_p->dma_cookie.dmac_size, 2906 dma_p->ncookies)); 2907 2908 contig_mem_free((void *)kaddrp, length); 2909 (void) ddi_dma_unbind_handle(dma_p->dma_handle); 2910 ddi_dma_free_handle(&dma_p->dma_handle); 2911 2912 dma_p->alength = 0; 2913 dma_p->dma_handle = NULL; 2914 dma_p->acc_handle = NULL; 2915 dma_p->kaddrp = NULL; 2916 2917 return (NXGE_ERROR | NXGE_DDI_FAILED); 2918 } 2919 break; 2920 2921 #else 2922 case B_TRUE: 2923 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2924 "nxge_dma_mem_alloc: invalid alloc type for !sun4v")); 2925 return (NXGE_ERROR | NXGE_DDI_FAILED); 2926 #endif 2927 } 2928 2929 dma_p->kaddrp = kaddrp; 2930 dma_p->last_kaddrp = (unsigned char *)kaddrp + 2931 dma_p->alength - RXBUF_64B_ALIGNED; 2932 #if defined(__i386) 2933 dma_p->ioaddr_pp = 2934 (unsigned char *)(uint32_t)dma_p->dma_cookie.dmac_laddress; 2935 #else 2936 dma_p->ioaddr_pp = (unsigned char *)dma_p->dma_cookie.dmac_laddress; 2937 #endif 2938 dma_p->last_ioaddr_pp = 2939 #if defined(__i386) 2940 (unsigned char *)(uint32_t)dma_p->dma_cookie.dmac_laddress + 2941 #else 2942 (unsigned char *)dma_p->dma_cookie.dmac_laddress + 2943 #endif 2944 dma_p->alength - RXBUF_64B_ALIGNED; 2945 2946 NPI_DMA_ACC_HANDLE_SET(dma_p, dma_p->acc_handle); 2947 2948 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 2949 dma_p->orig_ioaddr_pp = 2950 (unsigned char *)dma_p->dma_cookie.dmac_laddress; 2951 dma_p->orig_alength = length; 2952 dma_p->orig_kaddrp = kaddrp; 2953 dma_p->orig_vatopa = (uint64_t)va_to_pa(kaddrp); 2954 #endif 2955 2956 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_dma_mem_alloc: " 2957 "dma buffer allocated: dma_p $%p " 2958 "return dmac_ladress from cookie $%p cookie dmac_size %d " 2959 "dma_p->ioaddr_p $%p " 2960 "dma_p->orig_ioaddr_p $%p " 2961 "orig_vatopa $%p " 2962 "alength %d (0x%x) " 2963 "kaddrp $%p " 2964 "length %d (0x%x)", 2965 dma_p, 2966 dma_p->dma_cookie.dmac_laddress, dma_p->dma_cookie.dmac_size, 2967 dma_p->ioaddr_pp, 2968 dma_p->orig_ioaddr_pp, 2969 dma_p->orig_vatopa, 2970 dma_p->alength, dma_p->alength, 2971 kaddrp, 2972 length, length)); 2973 2974 return (NXGE_OK); 2975 } 2976 2977 static void 2978 nxge_dma_mem_free(p_nxge_dma_common_t dma_p) 2979 { 2980 if (dma_p->dma_handle != NULL) { 2981 if (dma_p->ncookies) { 2982 (void) ddi_dma_unbind_handle(dma_p->dma_handle); 2983 dma_p->ncookies = 0; 2984 } 2985 ddi_dma_free_handle(&dma_p->dma_handle); 2986 dma_p->dma_handle = NULL; 2987 } 2988 2989 if (dma_p->acc_handle != NULL) { 2990 ddi_dma_mem_free(&dma_p->acc_handle); 2991 dma_p->acc_handle = NULL; 2992 NPI_DMA_ACC_HANDLE_SET(dma_p, NULL); 2993 } 2994 2995 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 2996 if (dma_p->contig_alloc_type && 2997 dma_p->orig_kaddrp && dma_p->orig_alength) { 2998 NXGE_DEBUG_MSG((NULL, DMA_CTL, "nxge_dma_mem_free: " 2999 "kaddrp $%p (orig_kaddrp $%p)" 3000 "mem type %d ", 3001 "orig_alength %d " 3002 "alength 0x%x (%d)", 3003 dma_p->kaddrp, 3004 dma_p->orig_kaddrp, 3005 dma_p->contig_alloc_type, 3006 dma_p->orig_alength, 3007 dma_p->alength, dma_p->alength)); 3008 3009 contig_mem_free(dma_p->orig_kaddrp, dma_p->orig_alength); 3010 dma_p->orig_alength = NULL; 3011 dma_p->orig_kaddrp = NULL; 3012 dma_p->contig_alloc_type = B_FALSE; 3013 } 3014 #endif 3015 dma_p->kaddrp = NULL; 3016 dma_p->alength = NULL; 3017 } 3018 3019 /* 3020 * nxge_m_start() -- start transmitting and receiving. 3021 * 3022 * This function is called by the MAC layer when the first 3023 * stream is open to prepare the hardware ready for sending 3024 * and transmitting packets. 3025 */ 3026 static int 3027 nxge_m_start(void *arg) 3028 { 3029 p_nxge_t nxgep = (p_nxge_t)arg; 3030 3031 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_start")); 3032 3033 MUTEX_ENTER(nxgep->genlock); 3034 if (nxge_init(nxgep) != NXGE_OK) { 3035 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3036 "<== nxge_m_start: initialization failed")); 3037 MUTEX_EXIT(nxgep->genlock); 3038 return (EIO); 3039 } 3040 3041 if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) 3042 goto nxge_m_start_exit; 3043 /* 3044 * Start timer to check the system error and tx hangs 3045 */ 3046 nxgep->nxge_timerid = nxge_start_timer(nxgep, nxge_check_hw_state, 3047 NXGE_CHECK_TIMER); 3048 3049 nxgep->link_notify = B_TRUE; 3050 3051 nxgep->nxge_mac_state = NXGE_MAC_STARTED; 3052 3053 nxge_m_start_exit: 3054 MUTEX_EXIT(nxgep->genlock); 3055 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_start")); 3056 return (0); 3057 } 3058 3059 /* 3060 * nxge_m_stop(): stop transmitting and receiving. 3061 */ 3062 static void 3063 nxge_m_stop(void *arg) 3064 { 3065 p_nxge_t nxgep = (p_nxge_t)arg; 3066 3067 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_stop")); 3068 3069 if (nxgep->nxge_timerid) { 3070 nxge_stop_timer(nxgep, nxgep->nxge_timerid); 3071 nxgep->nxge_timerid = 0; 3072 } 3073 3074 MUTEX_ENTER(nxgep->genlock); 3075 nxge_uninit(nxgep); 3076 3077 nxgep->nxge_mac_state = NXGE_MAC_STOPPED; 3078 3079 MUTEX_EXIT(nxgep->genlock); 3080 3081 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_stop")); 3082 } 3083 3084 static int 3085 nxge_m_unicst(void *arg, const uint8_t *macaddr) 3086 { 3087 p_nxge_t nxgep = (p_nxge_t)arg; 3088 struct ether_addr addrp; 3089 3090 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_m_unicst")); 3091 3092 bcopy(macaddr, (uint8_t *)&addrp, ETHERADDRL); 3093 if (nxge_set_mac_addr(nxgep, &addrp)) { 3094 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3095 "<== nxge_m_unicst: set unitcast failed")); 3096 return (EINVAL); 3097 } 3098 3099 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_m_unicst")); 3100 3101 return (0); 3102 } 3103 3104 static int 3105 nxge_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 3106 { 3107 p_nxge_t nxgep = (p_nxge_t)arg; 3108 struct ether_addr addrp; 3109 3110 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3111 "==> nxge_m_multicst: add %d", add)); 3112 3113 bcopy(mca, (uint8_t *)&addrp, ETHERADDRL); 3114 if (add) { 3115 if (nxge_add_mcast_addr(nxgep, &addrp)) { 3116 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3117 "<== nxge_m_multicst: add multicast failed")); 3118 return (EINVAL); 3119 } 3120 } else { 3121 if (nxge_del_mcast_addr(nxgep, &addrp)) { 3122 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3123 "<== nxge_m_multicst: del multicast failed")); 3124 return (EINVAL); 3125 } 3126 } 3127 3128 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_m_multicst")); 3129 3130 return (0); 3131 } 3132 3133 static int 3134 nxge_m_promisc(void *arg, boolean_t on) 3135 { 3136 p_nxge_t nxgep = (p_nxge_t)arg; 3137 3138 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3139 "==> nxge_m_promisc: on %d", on)); 3140 3141 if (nxge_set_promisc(nxgep, on)) { 3142 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3143 "<== nxge_m_promisc: set promisc failed")); 3144 return (EINVAL); 3145 } 3146 3147 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3148 "<== nxge_m_promisc: on %d", on)); 3149 3150 return (0); 3151 } 3152 3153 static void 3154 nxge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 3155 { 3156 p_nxge_t nxgep = (p_nxge_t)arg; 3157 struct iocblk *iocp; 3158 boolean_t need_privilege; 3159 int err; 3160 int cmd; 3161 3162 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_ioctl")); 3163 3164 iocp = (struct iocblk *)mp->b_rptr; 3165 iocp->ioc_error = 0; 3166 need_privilege = B_TRUE; 3167 cmd = iocp->ioc_cmd; 3168 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_ioctl: cmd 0x%08x", cmd)); 3169 switch (cmd) { 3170 default: 3171 miocnak(wq, mp, 0, EINVAL); 3172 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_ioctl: invalid")); 3173 return; 3174 3175 case LB_GET_INFO_SIZE: 3176 case LB_GET_INFO: 3177 case LB_GET_MODE: 3178 need_privilege = B_FALSE; 3179 break; 3180 case LB_SET_MODE: 3181 break; 3182 3183 case ND_GET: 3184 need_privilege = B_FALSE; 3185 break; 3186 case ND_SET: 3187 break; 3188 3189 case NXGE_GET_MII: 3190 case NXGE_PUT_MII: 3191 case NXGE_GET64: 3192 case NXGE_PUT64: 3193 case NXGE_GET_TX_RING_SZ: 3194 case NXGE_GET_TX_DESC: 3195 case NXGE_TX_SIDE_RESET: 3196 case NXGE_RX_SIDE_RESET: 3197 case NXGE_GLOBAL_RESET: 3198 case NXGE_RESET_MAC: 3199 case NXGE_TX_REGS_DUMP: 3200 case NXGE_RX_REGS_DUMP: 3201 case NXGE_INT_REGS_DUMP: 3202 case NXGE_VIR_INT_REGS_DUMP: 3203 case NXGE_PUT_TCAM: 3204 case NXGE_GET_TCAM: 3205 case NXGE_RTRACE: 3206 case NXGE_RDUMP: 3207 3208 need_privilege = B_FALSE; 3209 break; 3210 case NXGE_INJECT_ERR: 3211 cmn_err(CE_NOTE, "!nxge_m_ioctl: Inject error\n"); 3212 nxge_err_inject(nxgep, wq, mp); 3213 break; 3214 } 3215 3216 if (need_privilege) { 3217 err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 3218 if (err != 0) { 3219 miocnak(wq, mp, 0, err); 3220 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3221 "<== nxge_m_ioctl: no priv")); 3222 return; 3223 } 3224 } 3225 3226 switch (cmd) { 3227 case ND_GET: 3228 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "ND_GET command")); 3229 case ND_SET: 3230 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "ND_SET command")); 3231 nxge_param_ioctl(nxgep, wq, mp, iocp); 3232 break; 3233 3234 case LB_GET_MODE: 3235 case LB_SET_MODE: 3236 case LB_GET_INFO_SIZE: 3237 case LB_GET_INFO: 3238 nxge_loopback_ioctl(nxgep, wq, mp, iocp); 3239 break; 3240 3241 case NXGE_GET_MII: 3242 case NXGE_PUT_MII: 3243 case NXGE_PUT_TCAM: 3244 case NXGE_GET_TCAM: 3245 case NXGE_GET64: 3246 case NXGE_PUT64: 3247 case NXGE_GET_TX_RING_SZ: 3248 case NXGE_GET_TX_DESC: 3249 case NXGE_TX_SIDE_RESET: 3250 case NXGE_RX_SIDE_RESET: 3251 case NXGE_GLOBAL_RESET: 3252 case NXGE_RESET_MAC: 3253 case NXGE_TX_REGS_DUMP: 3254 case NXGE_RX_REGS_DUMP: 3255 case NXGE_INT_REGS_DUMP: 3256 case NXGE_VIR_INT_REGS_DUMP: 3257 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, 3258 "==> nxge_m_ioctl: cmd 0x%x", cmd)); 3259 nxge_hw_ioctl(nxgep, wq, mp, iocp); 3260 break; 3261 } 3262 3263 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_ioctl")); 3264 } 3265 3266 extern void nxge_rx_hw_blank(void *arg, time_t ticks, uint_t count); 3267 3268 static void 3269 nxge_m_resources(void *arg) 3270 { 3271 p_nxge_t nxgep = arg; 3272 mac_rx_fifo_t mrf; 3273 p_rx_rcr_rings_t rcr_rings; 3274 p_rx_rcr_ring_t *rcr_p; 3275 uint32_t i, ndmas; 3276 nxge_status_t status; 3277 3278 NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_m_resources")); 3279 3280 MUTEX_ENTER(nxgep->genlock); 3281 3282 /* 3283 * CR 6492541 Check to see if the drv_state has been initialized, 3284 * if not * call nxge_init(). 3285 */ 3286 if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 3287 status = nxge_init(nxgep); 3288 if (status != NXGE_OK) 3289 goto nxge_m_resources_exit; 3290 } 3291 3292 mrf.mrf_type = MAC_RX_FIFO; 3293 mrf.mrf_blank = nxge_rx_hw_blank; 3294 mrf.mrf_arg = (void *)nxgep; 3295 3296 mrf.mrf_normal_blank_time = 128; 3297 mrf.mrf_normal_pkt_count = 8; 3298 rcr_rings = nxgep->rx_rcr_rings; 3299 rcr_p = rcr_rings->rcr_rings; 3300 ndmas = rcr_rings->ndmas; 3301 3302 /* 3303 * Export our receive resources to the MAC layer. 3304 */ 3305 for (i = 0; i < ndmas; i++) { 3306 ((p_rx_rcr_ring_t)rcr_p[i])->rcr_mac_handle = 3307 mac_resource_add(nxgep->mach, 3308 (mac_resource_t *)&mrf); 3309 3310 NXGE_DEBUG_MSG((nxgep, NXGE_CTL, 3311 "==> nxge_m_resources: vdma %d dma %d " 3312 "rcrptr 0x%016llx mac_handle 0x%016llx", 3313 i, ((p_rx_rcr_ring_t)rcr_p[i])->rdc, 3314 rcr_p[i], 3315 ((p_rx_rcr_ring_t)rcr_p[i])->rcr_mac_handle)); 3316 } 3317 3318 nxge_m_resources_exit: 3319 MUTEX_EXIT(nxgep->genlock); 3320 NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_m_resources")); 3321 } 3322 3323 static void 3324 nxge_mmac_kstat_update(p_nxge_t nxgep, mac_addr_slot_t slot, boolean_t factory) 3325 { 3326 p_nxge_mmac_stats_t mmac_stats; 3327 int i; 3328 nxge_mmac_t *mmac_info; 3329 3330 mmac_info = &nxgep->nxge_mmac_info; 3331 3332 mmac_stats = &nxgep->statsp->mmac_stats; 3333 mmac_stats->mmac_max_cnt = mmac_info->num_mmac; 3334 mmac_stats->mmac_avail_cnt = mmac_info->naddrfree; 3335 3336 for (i = 0; i < ETHERADDRL; i++) { 3337 if (factory) { 3338 mmac_stats->mmac_avail_pool[slot-1].ether_addr_octet[i] 3339 = mmac_info->factory_mac_pool[slot][(ETHERADDRL-1) - i]; 3340 } else { 3341 mmac_stats->mmac_avail_pool[slot-1].ether_addr_octet[i] 3342 = mmac_info->mac_pool[slot].addr[(ETHERADDRL - 1) - i]; 3343 } 3344 } 3345 } 3346 3347 /* 3348 * nxge_altmac_set() -- Set an alternate MAC address 3349 */ 3350 static int 3351 nxge_altmac_set(p_nxge_t nxgep, uint8_t *maddr, mac_addr_slot_t slot) 3352 { 3353 uint8_t addrn; 3354 uint8_t portn; 3355 npi_mac_addr_t altmac; 3356 hostinfo_t mac_rdc; 3357 p_nxge_class_pt_cfg_t clscfgp; 3358 3359 altmac.w2 = ((uint16_t)maddr[0] << 8) | ((uint16_t)maddr[1] & 0x0ff); 3360 altmac.w1 = ((uint16_t)maddr[2] << 8) | ((uint16_t)maddr[3] & 0x0ff); 3361 altmac.w0 = ((uint16_t)maddr[4] << 8) | ((uint16_t)maddr[5] & 0x0ff); 3362 3363 portn = nxgep->mac.portnum; 3364 addrn = (uint8_t)slot - 1; 3365 3366 if (npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET, portn, 3367 addrn, &altmac) != NPI_SUCCESS) 3368 return (EIO); 3369 3370 /* 3371 * Set the rdc table number for the host info entry 3372 * for this mac address slot. 3373 */ 3374 clscfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 3375 mac_rdc.value = 0; 3376 mac_rdc.bits.w0.rdc_tbl_num = clscfgp->mac_host_info[addrn].rdctbl; 3377 mac_rdc.bits.w0.mac_pref = clscfgp->mac_host_info[addrn].mpr_npr; 3378 3379 if (npi_mac_hostinfo_entry(nxgep->npi_handle, OP_SET, 3380 nxgep->function_num, addrn, &mac_rdc) != NPI_SUCCESS) { 3381 return (EIO); 3382 } 3383 3384 /* 3385 * Enable comparison with the alternate MAC address. 3386 * While the first alternate addr is enabled by bit 1 of register 3387 * BMAC_ALTAD_CMPEN, it is enabled by bit 0 of register 3388 * XMAC_ADDR_CMPEN, so slot needs to be converted to addrn 3389 * accordingly before calling npi_mac_altaddr_entry. 3390 */ 3391 if (portn == XMAC_PORT_0 || portn == XMAC_PORT_1) 3392 addrn = (uint8_t)slot - 1; 3393 else 3394 addrn = (uint8_t)slot; 3395 3396 if (npi_mac_altaddr_enable(nxgep->npi_handle, portn, addrn) 3397 != NPI_SUCCESS) 3398 return (EIO); 3399 3400 return (0); 3401 } 3402 3403 /* 3404 * nxeg_m_mmac_add() - find an unused address slot, set the address 3405 * value to the one specified, enable the port to start filtering on 3406 * the new MAC address. Returns 0 on success. 3407 */ 3408 static int 3409 nxge_m_mmac_add(void *arg, mac_multi_addr_t *maddr) 3410 { 3411 p_nxge_t nxgep = arg; 3412 mac_addr_slot_t slot; 3413 nxge_mmac_t *mmac_info; 3414 int err; 3415 nxge_status_t status; 3416 3417 mutex_enter(nxgep->genlock); 3418 3419 /* 3420 * Make sure that nxge is initialized, if _start() has 3421 * not been called. 3422 */ 3423 if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 3424 status = nxge_init(nxgep); 3425 if (status != NXGE_OK) { 3426 mutex_exit(nxgep->genlock); 3427 return (ENXIO); 3428 } 3429 } 3430 3431 mmac_info = &nxgep->nxge_mmac_info; 3432 if (mmac_info->naddrfree == 0) { 3433 mutex_exit(nxgep->genlock); 3434 return (ENOSPC); 3435 } 3436 if (!mac_unicst_verify(nxgep->mach, maddr->mma_addr, 3437 maddr->mma_addrlen)) { 3438 mutex_exit(nxgep->genlock); 3439 return (EINVAL); 3440 } 3441 /* 3442 * Search for the first available slot. Because naddrfree 3443 * is not zero, we are guaranteed to find one. 3444 * Slot 0 is for unique (primary) MAC. The first alternate 3445 * MAC slot is slot 1. 3446 * Each of the first two ports of Neptune has 16 alternate 3447 * MAC slots but only the first 7 (or 15) slots have assigned factory 3448 * MAC addresses. We first search among the slots without bundled 3449 * factory MACs. If we fail to find one in that range, then we 3450 * search the slots with bundled factory MACs. A factory MAC 3451 * will be wasted while the slot is used with a user MAC address. 3452 * But the slot could be used by factory MAC again after calling 3453 * nxge_m_mmac_remove and nxge_m_mmac_reserve. 3454 */ 3455 if (mmac_info->num_factory_mmac < mmac_info->num_mmac) { 3456 for (slot = mmac_info->num_factory_mmac + 1; 3457 slot <= mmac_info->num_mmac; slot++) { 3458 if (!(mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED)) 3459 break; 3460 } 3461 if (slot > mmac_info->num_mmac) { 3462 for (slot = 1; slot <= mmac_info->num_factory_mmac; 3463 slot++) { 3464 if (!(mmac_info->mac_pool[slot].flags 3465 & MMAC_SLOT_USED)) 3466 break; 3467 } 3468 } 3469 } else { 3470 for (slot = 1; slot <= mmac_info->num_mmac; slot++) { 3471 if (!(mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED)) 3472 break; 3473 } 3474 } 3475 ASSERT(slot <= mmac_info->num_mmac); 3476 if ((err = nxge_altmac_set(nxgep, maddr->mma_addr, slot)) != 0) { 3477 mutex_exit(nxgep->genlock); 3478 return (err); 3479 } 3480 bcopy(maddr->mma_addr, mmac_info->mac_pool[slot].addr, ETHERADDRL); 3481 mmac_info->mac_pool[slot].flags |= MMAC_SLOT_USED; 3482 mmac_info->mac_pool[slot].flags &= ~MMAC_VENDOR_ADDR; 3483 mmac_info->naddrfree--; 3484 nxge_mmac_kstat_update(nxgep, slot, B_FALSE); 3485 3486 maddr->mma_slot = slot; 3487 3488 mutex_exit(nxgep->genlock); 3489 return (0); 3490 } 3491 3492 /* 3493 * This function reserves an unused slot and programs the slot and the HW 3494 * with a factory mac address. 3495 */ 3496 static int 3497 nxge_m_mmac_reserve(void *arg, mac_multi_addr_t *maddr) 3498 { 3499 p_nxge_t nxgep = arg; 3500 mac_addr_slot_t slot; 3501 nxge_mmac_t *mmac_info; 3502 int err; 3503 nxge_status_t status; 3504 3505 mutex_enter(nxgep->genlock); 3506 3507 /* 3508 * Make sure that nxge is initialized, if _start() has 3509 * not been called. 3510 */ 3511 if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 3512 status = nxge_init(nxgep); 3513 if (status != NXGE_OK) { 3514 mutex_exit(nxgep->genlock); 3515 return (ENXIO); 3516 } 3517 } 3518 3519 mmac_info = &nxgep->nxge_mmac_info; 3520 if (mmac_info->naddrfree == 0) { 3521 mutex_exit(nxgep->genlock); 3522 return (ENOSPC); 3523 } 3524 3525 slot = maddr->mma_slot; 3526 if (slot == -1) { /* -1: Take the first available slot */ 3527 for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) { 3528 if (!(mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED)) 3529 break; 3530 } 3531 if (slot > mmac_info->num_factory_mmac) { 3532 mutex_exit(nxgep->genlock); 3533 return (ENOSPC); 3534 } 3535 } 3536 if (slot < 1 || slot > mmac_info->num_factory_mmac) { 3537 /* 3538 * Do not support factory MAC at a slot greater than 3539 * num_factory_mmac even when there are available factory 3540 * MAC addresses because the alternate MACs are bundled with 3541 * slot[1] through slot[num_factory_mmac] 3542 */ 3543 mutex_exit(nxgep->genlock); 3544 return (EINVAL); 3545 } 3546 if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) { 3547 mutex_exit(nxgep->genlock); 3548 return (EBUSY); 3549 } 3550 /* Verify the address to be reserved */ 3551 if (!mac_unicst_verify(nxgep->mach, 3552 mmac_info->factory_mac_pool[slot], ETHERADDRL)) { 3553 mutex_exit(nxgep->genlock); 3554 return (EINVAL); 3555 } 3556 if (err = nxge_altmac_set(nxgep, 3557 mmac_info->factory_mac_pool[slot], slot)) { 3558 mutex_exit(nxgep->genlock); 3559 return (err); 3560 } 3561 bcopy(mmac_info->factory_mac_pool[slot], maddr->mma_addr, ETHERADDRL); 3562 mmac_info->mac_pool[slot].flags |= MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 3563 mmac_info->naddrfree--; 3564 3565 nxge_mmac_kstat_update(nxgep, slot, B_TRUE); 3566 mutex_exit(nxgep->genlock); 3567 3568 /* Pass info back to the caller */ 3569 maddr->mma_slot = slot; 3570 maddr->mma_addrlen = ETHERADDRL; 3571 maddr->mma_flags = MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 3572 3573 return (0); 3574 } 3575 3576 /* 3577 * Remove the specified mac address and update the HW not to filter 3578 * the mac address anymore. 3579 */ 3580 static int 3581 nxge_m_mmac_remove(void *arg, mac_addr_slot_t slot) 3582 { 3583 p_nxge_t nxgep = arg; 3584 nxge_mmac_t *mmac_info; 3585 uint8_t addrn; 3586 uint8_t portn; 3587 int err = 0; 3588 nxge_status_t status; 3589 3590 mutex_enter(nxgep->genlock); 3591 3592 /* 3593 * Make sure that nxge is initialized, if _start() has 3594 * not been called. 3595 */ 3596 if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 3597 status = nxge_init(nxgep); 3598 if (status != NXGE_OK) { 3599 mutex_exit(nxgep->genlock); 3600 return (ENXIO); 3601 } 3602 } 3603 3604 mmac_info = &nxgep->nxge_mmac_info; 3605 if (slot < 1 || slot > mmac_info->num_mmac) { 3606 mutex_exit(nxgep->genlock); 3607 return (EINVAL); 3608 } 3609 3610 portn = nxgep->mac.portnum; 3611 if (portn == XMAC_PORT_0 || portn == XMAC_PORT_1) 3612 addrn = (uint8_t)slot - 1; 3613 else 3614 addrn = (uint8_t)slot; 3615 3616 if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) { 3617 if (npi_mac_altaddr_disable(nxgep->npi_handle, portn, addrn) 3618 == NPI_SUCCESS) { 3619 mmac_info->naddrfree++; 3620 mmac_info->mac_pool[slot].flags &= ~MMAC_SLOT_USED; 3621 /* 3622 * Regardless if the MAC we just stopped filtering 3623 * is a user addr or a facory addr, we must set 3624 * the MMAC_VENDOR_ADDR flag if this slot has an 3625 * associated factory MAC to indicate that a factory 3626 * MAC is available. 3627 */ 3628 if (slot <= mmac_info->num_factory_mmac) { 3629 mmac_info->mac_pool[slot].flags 3630 |= MMAC_VENDOR_ADDR; 3631 } 3632 /* 3633 * Clear mac_pool[slot].addr so that kstat shows 0 3634 * alternate MAC address if the slot is not used. 3635 * (But nxge_m_mmac_get returns the factory MAC even 3636 * when the slot is not used!) 3637 */ 3638 bzero(mmac_info->mac_pool[slot].addr, ETHERADDRL); 3639 nxge_mmac_kstat_update(nxgep, slot, B_FALSE); 3640 } else { 3641 err = EIO; 3642 } 3643 } else { 3644 err = EINVAL; 3645 } 3646 3647 mutex_exit(nxgep->genlock); 3648 return (err); 3649 } 3650 3651 3652 /* 3653 * Modify a mac address added by nxge_m_mmac_add or nxge_m_mmac_reserve(). 3654 */ 3655 static int 3656 nxge_m_mmac_modify(void *arg, mac_multi_addr_t *maddr) 3657 { 3658 p_nxge_t nxgep = arg; 3659 mac_addr_slot_t slot; 3660 nxge_mmac_t *mmac_info; 3661 int err = 0; 3662 nxge_status_t status; 3663 3664 if (!mac_unicst_verify(nxgep->mach, maddr->mma_addr, 3665 maddr->mma_addrlen)) 3666 return (EINVAL); 3667 3668 slot = maddr->mma_slot; 3669 3670 mutex_enter(nxgep->genlock); 3671 3672 /* 3673 * Make sure that nxge is initialized, if _start() has 3674 * not been called. 3675 */ 3676 if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 3677 status = nxge_init(nxgep); 3678 if (status != NXGE_OK) { 3679 mutex_exit(nxgep->genlock); 3680 return (ENXIO); 3681 } 3682 } 3683 3684 mmac_info = &nxgep->nxge_mmac_info; 3685 if (slot < 1 || slot > mmac_info->num_mmac) { 3686 mutex_exit(nxgep->genlock); 3687 return (EINVAL); 3688 } 3689 if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) { 3690 if ((err = nxge_altmac_set(nxgep, maddr->mma_addr, slot)) 3691 != 0) { 3692 bcopy(maddr->mma_addr, mmac_info->mac_pool[slot].addr, 3693 ETHERADDRL); 3694 /* 3695 * Assume that the MAC passed down from the caller 3696 * is not a factory MAC address (The user should 3697 * call mmac_remove followed by mmac_reserve if 3698 * he wants to use the factory MAC for this slot). 3699 */ 3700 mmac_info->mac_pool[slot].flags &= ~MMAC_VENDOR_ADDR; 3701 nxge_mmac_kstat_update(nxgep, slot, B_FALSE); 3702 } 3703 } else { 3704 err = EINVAL; 3705 } 3706 mutex_exit(nxgep->genlock); 3707 return (err); 3708 } 3709 3710 /* 3711 * nxge_m_mmac_get() - Get the MAC address and other information 3712 * related to the slot. mma_flags should be set to 0 in the call. 3713 * Note: although kstat shows MAC address as zero when a slot is 3714 * not used, Crossbow expects nxge_m_mmac_get to copy factory MAC 3715 * to the caller as long as the slot is not using a user MAC address. 3716 * The following table shows the rules, 3717 * 3718 * USED VENDOR mma_addr 3719 * ------------------------------------------------------------ 3720 * (1) Slot uses a user MAC: yes no user MAC 3721 * (2) Slot uses a factory MAC: yes yes factory MAC 3722 * (3) Slot is not used but is 3723 * factory MAC capable: no yes factory MAC 3724 * (4) Slot is not used and is 3725 * not factory MAC capable: no no 0 3726 * ------------------------------------------------------------ 3727 */ 3728 static int 3729 nxge_m_mmac_get(void *arg, mac_multi_addr_t *maddr) 3730 { 3731 nxge_t *nxgep = arg; 3732 mac_addr_slot_t slot; 3733 nxge_mmac_t *mmac_info; 3734 nxge_status_t status; 3735 3736 slot = maddr->mma_slot; 3737 3738 mutex_enter(nxgep->genlock); 3739 3740 /* 3741 * Make sure that nxge is initialized, if _start() has 3742 * not been called. 3743 */ 3744 if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 3745 status = nxge_init(nxgep); 3746 if (status != NXGE_OK) { 3747 mutex_exit(nxgep->genlock); 3748 return (ENXIO); 3749 } 3750 } 3751 3752 mmac_info = &nxgep->nxge_mmac_info; 3753 3754 if (slot < 1 || slot > mmac_info->num_mmac) { 3755 mutex_exit(nxgep->genlock); 3756 return (EINVAL); 3757 } 3758 maddr->mma_flags = 0; 3759 if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) 3760 maddr->mma_flags |= MMAC_SLOT_USED; 3761 3762 if (mmac_info->mac_pool[slot].flags & MMAC_VENDOR_ADDR) { 3763 maddr->mma_flags |= MMAC_VENDOR_ADDR; 3764 bcopy(mmac_info->factory_mac_pool[slot], 3765 maddr->mma_addr, ETHERADDRL); 3766 maddr->mma_addrlen = ETHERADDRL; 3767 } else { 3768 if (maddr->mma_flags & MMAC_SLOT_USED) { 3769 bcopy(mmac_info->mac_pool[slot].addr, 3770 maddr->mma_addr, ETHERADDRL); 3771 maddr->mma_addrlen = ETHERADDRL; 3772 } else { 3773 bzero(maddr->mma_addr, ETHERADDRL); 3774 maddr->mma_addrlen = 0; 3775 } 3776 } 3777 mutex_exit(nxgep->genlock); 3778 return (0); 3779 } 3780 3781 3782 static boolean_t 3783 nxge_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 3784 { 3785 nxge_t *nxgep = arg; 3786 uint32_t *txflags = cap_data; 3787 multiaddress_capab_t *mmacp = cap_data; 3788 3789 switch (cap) { 3790 case MAC_CAPAB_HCKSUM: 3791 *txflags = HCKSUM_INET_PARTIAL; 3792 break; 3793 case MAC_CAPAB_POLL: 3794 /* 3795 * There's nothing for us to fill in, simply returning 3796 * B_TRUE stating that we support polling is sufficient. 3797 */ 3798 break; 3799 3800 case MAC_CAPAB_MULTIADDRESS: 3801 mutex_enter(nxgep->genlock); 3802 3803 mmacp->maddr_naddr = nxgep->nxge_mmac_info.num_mmac; 3804 mmacp->maddr_naddrfree = nxgep->nxge_mmac_info.naddrfree; 3805 mmacp->maddr_flag = 0; /* 0 is requried by PSARC2006/265 */ 3806 /* 3807 * maddr_handle is driver's private data, passed back to 3808 * entry point functions as arg. 3809 */ 3810 mmacp->maddr_handle = nxgep; 3811 mmacp->maddr_add = nxge_m_mmac_add; 3812 mmacp->maddr_remove = nxge_m_mmac_remove; 3813 mmacp->maddr_modify = nxge_m_mmac_modify; 3814 mmacp->maddr_get = nxge_m_mmac_get; 3815 mmacp->maddr_reserve = nxge_m_mmac_reserve; 3816 3817 mutex_exit(nxgep->genlock); 3818 break; 3819 case MAC_CAPAB_LSO: { 3820 mac_capab_lso_t *cap_lso = cap_data; 3821 3822 if (nxge_lso_enable) { 3823 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; 3824 if (nxge_lso_max > NXGE_LSO_MAXLEN) { 3825 nxge_lso_max = NXGE_LSO_MAXLEN; 3826 } 3827 cap_lso->lso_basic_tcp_ipv4.lso_max = nxge_lso_max; 3828 break; 3829 } else { 3830 return (B_FALSE); 3831 } 3832 } 3833 3834 default: 3835 return (B_FALSE); 3836 } 3837 return (B_TRUE); 3838 } 3839 3840 /* 3841 * Module loading and removing entry points. 3842 */ 3843 3844 static struct cb_ops nxge_cb_ops = { 3845 nodev, /* cb_open */ 3846 nodev, /* cb_close */ 3847 nodev, /* cb_strategy */ 3848 nodev, /* cb_print */ 3849 nodev, /* cb_dump */ 3850 nodev, /* cb_read */ 3851 nodev, /* cb_write */ 3852 nodev, /* cb_ioctl */ 3853 nodev, /* cb_devmap */ 3854 nodev, /* cb_mmap */ 3855 nodev, /* cb_segmap */ 3856 nochpoll, /* cb_chpoll */ 3857 ddi_prop_op, /* cb_prop_op */ 3858 NULL, 3859 D_MP, /* cb_flag */ 3860 CB_REV, /* rev */ 3861 nodev, /* int (*cb_aread)() */ 3862 nodev /* int (*cb_awrite)() */ 3863 }; 3864 3865 static struct dev_ops nxge_dev_ops = { 3866 DEVO_REV, /* devo_rev */ 3867 0, /* devo_refcnt */ 3868 nulldev, 3869 nulldev, /* devo_identify */ 3870 nulldev, /* devo_probe */ 3871 nxge_attach, /* devo_attach */ 3872 nxge_detach, /* devo_detach */ 3873 nodev, /* devo_reset */ 3874 &nxge_cb_ops, /* devo_cb_ops */ 3875 (struct bus_ops *)NULL, /* devo_bus_ops */ 3876 ddi_power /* devo_power */ 3877 }; 3878 3879 extern struct mod_ops mod_driverops; 3880 3881 #define NXGE_DESC_VER "Sun NIU 10Gb Ethernet" 3882 3883 /* 3884 * Module linkage information for the kernel. 3885 */ 3886 static struct modldrv nxge_modldrv = { 3887 &mod_driverops, 3888 NXGE_DESC_VER, 3889 &nxge_dev_ops 3890 }; 3891 3892 static struct modlinkage modlinkage = { 3893 MODREV_1, (void *) &nxge_modldrv, NULL 3894 }; 3895 3896 int 3897 _init(void) 3898 { 3899 int status; 3900 3901 NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _init")); 3902 mac_init_ops(&nxge_dev_ops, "nxge"); 3903 status = ddi_soft_state_init(&nxge_list, sizeof (nxge_t), 0); 3904 if (status != 0) { 3905 NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 3906 "failed to init device soft state")); 3907 goto _init_exit; 3908 } 3909 status = mod_install(&modlinkage); 3910 if (status != 0) { 3911 ddi_soft_state_fini(&nxge_list); 3912 NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "Mod install failed")); 3913 goto _init_exit; 3914 } 3915 3916 MUTEX_INIT(&nxge_common_lock, NULL, MUTEX_DRIVER, NULL); 3917 3918 _init_exit: 3919 NXGE_DEBUG_MSG((NULL, MOD_CTL, "_init status = 0x%X", status)); 3920 3921 return (status); 3922 } 3923 3924 int 3925 _fini(void) 3926 { 3927 int status; 3928 3929 NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini")); 3930 3931 NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini: mod_remove")); 3932 3933 if (nxge_mblks_pending) 3934 return (EBUSY); 3935 3936 status = mod_remove(&modlinkage); 3937 if (status != DDI_SUCCESS) { 3938 NXGE_DEBUG_MSG((NULL, MOD_CTL, 3939 "Module removal failed 0x%08x", 3940 status)); 3941 goto _fini_exit; 3942 } 3943 3944 mac_fini_ops(&nxge_dev_ops); 3945 3946 ddi_soft_state_fini(&nxge_list); 3947 3948 MUTEX_DESTROY(&nxge_common_lock); 3949 _fini_exit: 3950 NXGE_DEBUG_MSG((NULL, MOD_CTL, "_fini status = 0x%08x", status)); 3951 3952 return (status); 3953 } 3954 3955 int 3956 _info(struct modinfo *modinfop) 3957 { 3958 int status; 3959 3960 NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _info")); 3961 status = mod_info(&modlinkage, modinfop); 3962 NXGE_DEBUG_MSG((NULL, MOD_CTL, " _info status = 0x%X", status)); 3963 3964 return (status); 3965 } 3966 3967 /*ARGSUSED*/ 3968 static nxge_status_t 3969 nxge_add_intrs(p_nxge_t nxgep) 3970 { 3971 3972 int intr_types; 3973 int type = 0; 3974 int ddi_status = DDI_SUCCESS; 3975 nxge_status_t status = NXGE_OK; 3976 3977 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs")); 3978 3979 nxgep->nxge_intr_type.intr_registered = B_FALSE; 3980 nxgep->nxge_intr_type.intr_enabled = B_FALSE; 3981 nxgep->nxge_intr_type.msi_intx_cnt = 0; 3982 nxgep->nxge_intr_type.intr_added = 0; 3983 nxgep->nxge_intr_type.niu_msi_enable = B_FALSE; 3984 nxgep->nxge_intr_type.intr_type = 0; 3985 3986 if (nxgep->niu_type == N2_NIU) { 3987 nxgep->nxge_intr_type.niu_msi_enable = B_TRUE; 3988 } else if (nxge_msi_enable) { 3989 nxgep->nxge_intr_type.niu_msi_enable = B_TRUE; 3990 } 3991 3992 /* Get the supported interrupt types */ 3993 if ((ddi_status = ddi_intr_get_supported_types(nxgep->dip, &intr_types)) 3994 != DDI_SUCCESS) { 3995 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_add_intrs: " 3996 "ddi_intr_get_supported_types failed: status 0x%08x", 3997 ddi_status)); 3998 return (NXGE_ERROR | NXGE_DDI_FAILED); 3999 } 4000 nxgep->nxge_intr_type.intr_types = intr_types; 4001 4002 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 4003 "ddi_intr_get_supported_types: 0x%08x", intr_types)); 4004 4005 /* 4006 * Solaris MSIX is not supported yet. use MSI for now. 4007 * nxge_msi_enable (1): 4008 * 1 - MSI 2 - MSI-X others - FIXED 4009 */ 4010 switch (nxge_msi_enable) { 4011 default: 4012 type = DDI_INTR_TYPE_FIXED; 4013 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 4014 "use fixed (intx emulation) type %08x", 4015 type)); 4016 break; 4017 4018 case 2: 4019 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 4020 "ddi_intr_get_supported_types: 0x%08x", intr_types)); 4021 if (intr_types & DDI_INTR_TYPE_MSIX) { 4022 type = DDI_INTR_TYPE_MSIX; 4023 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 4024 "ddi_intr_get_supported_types: MSIX 0x%08x", 4025 type)); 4026 } else if (intr_types & DDI_INTR_TYPE_MSI) { 4027 type = DDI_INTR_TYPE_MSI; 4028 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 4029 "ddi_intr_get_supported_types: MSI 0x%08x", 4030 type)); 4031 } else if (intr_types & DDI_INTR_TYPE_FIXED) { 4032 type = DDI_INTR_TYPE_FIXED; 4033 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 4034 "ddi_intr_get_supported_types: MSXED0x%08x", 4035 type)); 4036 } 4037 break; 4038 4039 case 1: 4040 if (intr_types & DDI_INTR_TYPE_MSI) { 4041 type = DDI_INTR_TYPE_MSI; 4042 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 4043 "ddi_intr_get_supported_types: MSI 0x%08x", 4044 type)); 4045 } else if (intr_types & DDI_INTR_TYPE_MSIX) { 4046 type = DDI_INTR_TYPE_MSIX; 4047 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 4048 "ddi_intr_get_supported_types: MSIX 0x%08x", 4049 type)); 4050 } else if (intr_types & DDI_INTR_TYPE_FIXED) { 4051 type = DDI_INTR_TYPE_FIXED; 4052 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 4053 "ddi_intr_get_supported_types: MSXED0x%08x", 4054 type)); 4055 } 4056 } 4057 4058 nxgep->nxge_intr_type.intr_type = type; 4059 if ((type == DDI_INTR_TYPE_MSIX || type == DDI_INTR_TYPE_MSI || 4060 type == DDI_INTR_TYPE_FIXED) && 4061 nxgep->nxge_intr_type.niu_msi_enable) { 4062 if ((status = nxge_add_intrs_adv(nxgep)) != DDI_SUCCESS) { 4063 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4064 " nxge_add_intrs: " 4065 " nxge_add_intrs_adv failed: status 0x%08x", 4066 status)); 4067 return (status); 4068 } else { 4069 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 4070 "interrupts registered : type %d", type)); 4071 nxgep->nxge_intr_type.intr_registered = B_TRUE; 4072 4073 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 4074 "\nAdded advanced nxge add_intr_adv " 4075 "intr type 0x%x\n", type)); 4076 4077 return (status); 4078 } 4079 } 4080 4081 if (!nxgep->nxge_intr_type.intr_registered) { 4082 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_add_intrs: " 4083 "failed to register interrupts")); 4084 return (NXGE_ERROR | NXGE_DDI_FAILED); 4085 } 4086 4087 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_add_intrs")); 4088 return (status); 4089 } 4090 4091 /*ARGSUSED*/ 4092 static nxge_status_t 4093 nxge_add_soft_intrs(p_nxge_t nxgep) 4094 { 4095 4096 int ddi_status = DDI_SUCCESS; 4097 nxge_status_t status = NXGE_OK; 4098 4099 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_soft_intrs")); 4100 4101 nxgep->resched_id = NULL; 4102 nxgep->resched_running = B_FALSE; 4103 ddi_status = ddi_add_softintr(nxgep->dip, DDI_SOFTINT_LOW, 4104 &nxgep->resched_id, 4105 NULL, NULL, nxge_reschedule, (caddr_t)nxgep); 4106 if (ddi_status != DDI_SUCCESS) { 4107 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_add_soft_intrs: " 4108 "ddi_add_softintrs failed: status 0x%08x", 4109 ddi_status)); 4110 return (NXGE_ERROR | NXGE_DDI_FAILED); 4111 } 4112 4113 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_ddi_add_soft_intrs")); 4114 4115 return (status); 4116 } 4117 4118 static nxge_status_t 4119 nxge_add_intrs_adv(p_nxge_t nxgep) 4120 { 4121 int intr_type; 4122 p_nxge_intr_t intrp; 4123 4124 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs_adv")); 4125 4126 intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 4127 intr_type = intrp->intr_type; 4128 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs_adv: type 0x%x", 4129 intr_type)); 4130 4131 switch (intr_type) { 4132 case DDI_INTR_TYPE_MSI: /* 0x2 */ 4133 case DDI_INTR_TYPE_MSIX: /* 0x4 */ 4134 return (nxge_add_intrs_adv_type(nxgep, intr_type)); 4135 4136 case DDI_INTR_TYPE_FIXED: /* 0x1 */ 4137 return (nxge_add_intrs_adv_type_fix(nxgep, intr_type)); 4138 4139 default: 4140 return (NXGE_ERROR); 4141 } 4142 } 4143 4144 4145 /*ARGSUSED*/ 4146 static nxge_status_t 4147 nxge_add_intrs_adv_type(p_nxge_t nxgep, uint32_t int_type) 4148 { 4149 dev_info_t *dip = nxgep->dip; 4150 p_nxge_ldg_t ldgp; 4151 p_nxge_intr_t intrp; 4152 uint_t *inthandler; 4153 void *arg1, *arg2; 4154 int behavior; 4155 int nintrs, navail, nrequest; 4156 int nactual, nrequired; 4157 int inum = 0; 4158 int x, y; 4159 int ddi_status = DDI_SUCCESS; 4160 nxge_status_t status = NXGE_OK; 4161 4162 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs_adv_type")); 4163 intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 4164 intrp->start_inum = 0; 4165 4166 ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 4167 if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 4168 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4169 "ddi_intr_get_nintrs() failed, status: 0x%x%, " 4170 "nintrs: %d", ddi_status, nintrs)); 4171 return (NXGE_ERROR | NXGE_DDI_FAILED); 4172 } 4173 4174 ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 4175 if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 4176 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4177 "ddi_intr_get_navail() failed, status: 0x%x%, " 4178 "nintrs: %d", ddi_status, navail)); 4179 return (NXGE_ERROR | NXGE_DDI_FAILED); 4180 } 4181 4182 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4183 "ddi_intr_get_navail() returned: nintrs %d, navail %d", 4184 nintrs, navail)); 4185 4186 /* PSARC/2007/453 MSI-X interrupt limit override */ 4187 if (int_type == DDI_INTR_TYPE_MSIX) { 4188 nrequest = nxge_create_msi_property(nxgep); 4189 if (nrequest < navail) { 4190 navail = nrequest; 4191 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4192 "nxge_add_intrs_adv_type: nintrs %d " 4193 "navail %d (nrequest %d)", 4194 nintrs, navail, nrequest)); 4195 } 4196 } 4197 4198 if (int_type == DDI_INTR_TYPE_MSI && !ISP2(navail)) { 4199 /* MSI must be power of 2 */ 4200 if ((navail & 16) == 16) { 4201 navail = 16; 4202 } else if ((navail & 8) == 8) { 4203 navail = 8; 4204 } else if ((navail & 4) == 4) { 4205 navail = 4; 4206 } else if ((navail & 2) == 2) { 4207 navail = 2; 4208 } else { 4209 navail = 1; 4210 } 4211 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4212 "ddi_intr_get_navail(): (msi power of 2) nintrs %d, " 4213 "navail %d", nintrs, navail)); 4214 } 4215 4216 behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 4217 DDI_INTR_ALLOC_NORMAL); 4218 intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 4219 intrp->htable = kmem_alloc(intrp->intr_size, KM_SLEEP); 4220 ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 4221 navail, &nactual, behavior); 4222 if (ddi_status != DDI_SUCCESS || nactual == 0) { 4223 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4224 " ddi_intr_alloc() failed: %d", 4225 ddi_status)); 4226 kmem_free(intrp->htable, intrp->intr_size); 4227 return (NXGE_ERROR | NXGE_DDI_FAILED); 4228 } 4229 4230 if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 4231 (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 4232 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4233 " ddi_intr_get_pri() failed: %d", 4234 ddi_status)); 4235 /* Free already allocated interrupts */ 4236 for (y = 0; y < nactual; y++) { 4237 (void) ddi_intr_free(intrp->htable[y]); 4238 } 4239 4240 kmem_free(intrp->htable, intrp->intr_size); 4241 return (NXGE_ERROR | NXGE_DDI_FAILED); 4242 } 4243 4244 nrequired = 0; 4245 switch (nxgep->niu_type) { 4246 default: 4247 status = nxge_ldgv_init(nxgep, &nactual, &nrequired); 4248 break; 4249 4250 case N2_NIU: 4251 status = nxge_ldgv_init_n2(nxgep, &nactual, &nrequired); 4252 break; 4253 } 4254 4255 if (status != NXGE_OK) { 4256 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4257 "nxge_add_intrs_adv_typ:nxge_ldgv_init " 4258 "failed: 0x%x", status)); 4259 /* Free already allocated interrupts */ 4260 for (y = 0; y < nactual; y++) { 4261 (void) ddi_intr_free(intrp->htable[y]); 4262 } 4263 4264 kmem_free(intrp->htable, intrp->intr_size); 4265 return (status); 4266 } 4267 4268 ldgp = nxgep->ldgvp->ldgp; 4269 for (x = 0; x < nrequired; x++, ldgp++) { 4270 ldgp->vector = (uint8_t)x; 4271 ldgp->intdata = SID_DATA(ldgp->func, x); 4272 arg1 = ldgp->ldvp; 4273 arg2 = nxgep; 4274 if (ldgp->nldvs == 1) { 4275 inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 4276 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4277 "nxge_add_intrs_adv_type: " 4278 "arg1 0x%x arg2 0x%x: " 4279 "1-1 int handler (entry %d intdata 0x%x)\n", 4280 arg1, arg2, 4281 x, ldgp->intdata)); 4282 } else if (ldgp->nldvs > 1) { 4283 inthandler = (uint_t *)ldgp->sys_intr_handler; 4284 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4285 "nxge_add_intrs_adv_type: " 4286 "arg1 0x%x arg2 0x%x: " 4287 "nldevs %d int handler " 4288 "(entry %d intdata 0x%x)\n", 4289 arg1, arg2, 4290 ldgp->nldvs, x, ldgp->intdata)); 4291 } 4292 4293 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4294 "==> nxge_add_intrs_adv_type: ddi_add_intr(inum) #%d " 4295 "htable 0x%llx", x, intrp->htable[x])); 4296 4297 if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 4298 (ddi_intr_handler_t *)inthandler, arg1, arg2)) 4299 != DDI_SUCCESS) { 4300 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4301 "==> nxge_add_intrs_adv_type: failed #%d " 4302 "status 0x%x", x, ddi_status)); 4303 for (y = 0; y < intrp->intr_added; y++) { 4304 (void) ddi_intr_remove_handler( 4305 intrp->htable[y]); 4306 } 4307 /* Free already allocated intr */ 4308 for (y = 0; y < nactual; y++) { 4309 (void) ddi_intr_free(intrp->htable[y]); 4310 } 4311 kmem_free(intrp->htable, intrp->intr_size); 4312 4313 (void) nxge_ldgv_uninit(nxgep); 4314 4315 return (NXGE_ERROR | NXGE_DDI_FAILED); 4316 } 4317 intrp->intr_added++; 4318 } 4319 4320 intrp->msi_intx_cnt = nactual; 4321 4322 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 4323 "Requested: %d, Allowed: %d msi_intx_cnt %d intr_added %d", 4324 navail, nactual, 4325 intrp->msi_intx_cnt, 4326 intrp->intr_added)); 4327 4328 (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 4329 4330 (void) nxge_intr_ldgv_init(nxgep); 4331 4332 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_add_intrs_adv_type")); 4333 4334 return (status); 4335 } 4336 4337 /*ARGSUSED*/ 4338 static nxge_status_t 4339 nxge_add_intrs_adv_type_fix(p_nxge_t nxgep, uint32_t int_type) 4340 { 4341 dev_info_t *dip = nxgep->dip; 4342 p_nxge_ldg_t ldgp; 4343 p_nxge_intr_t intrp; 4344 uint_t *inthandler; 4345 void *arg1, *arg2; 4346 int behavior; 4347 int nintrs, navail; 4348 int nactual, nrequired; 4349 int inum = 0; 4350 int x, y; 4351 int ddi_status = DDI_SUCCESS; 4352 nxge_status_t status = NXGE_OK; 4353 4354 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs_adv_type_fix")); 4355 intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 4356 intrp->start_inum = 0; 4357 4358 ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 4359 if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 4360 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4361 "ddi_intr_get_nintrs() failed, status: 0x%x%, " 4362 "nintrs: %d", status, nintrs)); 4363 return (NXGE_ERROR | NXGE_DDI_FAILED); 4364 } 4365 4366 ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 4367 if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 4368 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4369 "ddi_intr_get_navail() failed, status: 0x%x%, " 4370 "nintrs: %d", ddi_status, navail)); 4371 return (NXGE_ERROR | NXGE_DDI_FAILED); 4372 } 4373 4374 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4375 "ddi_intr_get_navail() returned: nintrs %d, naavail %d", 4376 nintrs, navail)); 4377 4378 behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 4379 DDI_INTR_ALLOC_NORMAL); 4380 intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 4381 intrp->htable = kmem_alloc(intrp->intr_size, KM_SLEEP); 4382 ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 4383 navail, &nactual, behavior); 4384 if (ddi_status != DDI_SUCCESS || nactual == 0) { 4385 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4386 " ddi_intr_alloc() failed: %d", 4387 ddi_status)); 4388 kmem_free(intrp->htable, intrp->intr_size); 4389 return (NXGE_ERROR | NXGE_DDI_FAILED); 4390 } 4391 4392 if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 4393 (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 4394 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4395 " ddi_intr_get_pri() failed: %d", 4396 ddi_status)); 4397 /* Free already allocated interrupts */ 4398 for (y = 0; y < nactual; y++) { 4399 (void) ddi_intr_free(intrp->htable[y]); 4400 } 4401 4402 kmem_free(intrp->htable, intrp->intr_size); 4403 return (NXGE_ERROR | NXGE_DDI_FAILED); 4404 } 4405 4406 nrequired = 0; 4407 switch (nxgep->niu_type) { 4408 default: 4409 status = nxge_ldgv_init(nxgep, &nactual, &nrequired); 4410 break; 4411 4412 case N2_NIU: 4413 status = nxge_ldgv_init_n2(nxgep, &nactual, &nrequired); 4414 break; 4415 } 4416 4417 if (status != NXGE_OK) { 4418 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4419 "nxge_add_intrs_adv_type_fix:nxge_ldgv_init " 4420 "failed: 0x%x", status)); 4421 /* Free already allocated interrupts */ 4422 for (y = 0; y < nactual; y++) { 4423 (void) ddi_intr_free(intrp->htable[y]); 4424 } 4425 4426 kmem_free(intrp->htable, intrp->intr_size); 4427 return (status); 4428 } 4429 4430 ldgp = nxgep->ldgvp->ldgp; 4431 for (x = 0; x < nrequired; x++, ldgp++) { 4432 ldgp->vector = (uint8_t)x; 4433 if (nxgep->niu_type != N2_NIU) { 4434 ldgp->intdata = SID_DATA(ldgp->func, x); 4435 } 4436 4437 arg1 = ldgp->ldvp; 4438 arg2 = nxgep; 4439 if (ldgp->nldvs == 1) { 4440 inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 4441 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4442 "nxge_add_intrs_adv_type_fix: " 4443 "1-1 int handler(%d) ldg %d ldv %d " 4444 "arg1 $%p arg2 $%p\n", 4445 x, ldgp->ldg, ldgp->ldvp->ldv, 4446 arg1, arg2)); 4447 } else if (ldgp->nldvs > 1) { 4448 inthandler = (uint_t *)ldgp->sys_intr_handler; 4449 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4450 "nxge_add_intrs_adv_type_fix: " 4451 "shared ldv %d int handler(%d) ldv %d ldg %d" 4452 "arg1 0x%016llx arg2 0x%016llx\n", 4453 x, ldgp->nldvs, ldgp->ldg, ldgp->ldvp->ldv, 4454 arg1, arg2)); 4455 } 4456 4457 if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 4458 (ddi_intr_handler_t *)inthandler, arg1, arg2)) 4459 != DDI_SUCCESS) { 4460 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4461 "==> nxge_add_intrs_adv_type_fix: failed #%d " 4462 "status 0x%x", x, ddi_status)); 4463 for (y = 0; y < intrp->intr_added; y++) { 4464 (void) ddi_intr_remove_handler( 4465 intrp->htable[y]); 4466 } 4467 for (y = 0; y < nactual; y++) { 4468 (void) ddi_intr_free(intrp->htable[y]); 4469 } 4470 /* Free already allocated intr */ 4471 kmem_free(intrp->htable, intrp->intr_size); 4472 4473 (void) nxge_ldgv_uninit(nxgep); 4474 4475 return (NXGE_ERROR | NXGE_DDI_FAILED); 4476 } 4477 intrp->intr_added++; 4478 } 4479 4480 intrp->msi_intx_cnt = nactual; 4481 4482 (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 4483 4484 status = nxge_intr_ldgv_init(nxgep); 4485 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_add_intrs_adv_type_fix")); 4486 4487 return (status); 4488 } 4489 4490 static void 4491 nxge_remove_intrs(p_nxge_t nxgep) 4492 { 4493 int i, inum; 4494 p_nxge_intr_t intrp; 4495 4496 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_remove_intrs")); 4497 intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 4498 if (!intrp->intr_registered) { 4499 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4500 "<== nxge_remove_intrs: interrupts not registered")); 4501 return; 4502 } 4503 4504 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_remove_intrs:advanced")); 4505 4506 if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 4507 (void) ddi_intr_block_disable(intrp->htable, 4508 intrp->intr_added); 4509 } else { 4510 for (i = 0; i < intrp->intr_added; i++) { 4511 (void) ddi_intr_disable(intrp->htable[i]); 4512 } 4513 } 4514 4515 for (inum = 0; inum < intrp->intr_added; inum++) { 4516 if (intrp->htable[inum]) { 4517 (void) ddi_intr_remove_handler(intrp->htable[inum]); 4518 } 4519 } 4520 4521 for (inum = 0; inum < intrp->msi_intx_cnt; inum++) { 4522 if (intrp->htable[inum]) { 4523 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 4524 "nxge_remove_intrs: ddi_intr_free inum %d " 4525 "msi_intx_cnt %d intr_added %d", 4526 inum, 4527 intrp->msi_intx_cnt, 4528 intrp->intr_added)); 4529 4530 (void) ddi_intr_free(intrp->htable[inum]); 4531 } 4532 } 4533 4534 kmem_free(intrp->htable, intrp->intr_size); 4535 intrp->intr_registered = B_FALSE; 4536 intrp->intr_enabled = B_FALSE; 4537 intrp->msi_intx_cnt = 0; 4538 intrp->intr_added = 0; 4539 4540 (void) nxge_ldgv_uninit(nxgep); 4541 4542 (void) ddi_prop_remove(DDI_DEV_T_NONE, nxgep->dip, 4543 "#msix-request"); 4544 4545 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_remove_intrs")); 4546 } 4547 4548 /*ARGSUSED*/ 4549 static void 4550 nxge_remove_soft_intrs(p_nxge_t nxgep) 4551 { 4552 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_remove_soft_intrs")); 4553 if (nxgep->resched_id) { 4554 ddi_remove_softintr(nxgep->resched_id); 4555 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4556 "==> nxge_remove_soft_intrs: removed")); 4557 nxgep->resched_id = NULL; 4558 } 4559 4560 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_remove_soft_intrs")); 4561 } 4562 4563 /*ARGSUSED*/ 4564 static void 4565 nxge_intrs_enable(p_nxge_t nxgep) 4566 { 4567 p_nxge_intr_t intrp; 4568 int i; 4569 int status; 4570 4571 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_enable")); 4572 4573 intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 4574 4575 if (!intrp->intr_registered) { 4576 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_intrs_enable: " 4577 "interrupts are not registered")); 4578 return; 4579 } 4580 4581 if (intrp->intr_enabled) { 4582 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4583 "<== nxge_intrs_enable: already enabled")); 4584 return; 4585 } 4586 4587 if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 4588 status = ddi_intr_block_enable(intrp->htable, 4589 intrp->intr_added); 4590 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_enable " 4591 "block enable - status 0x%x total inums #%d\n", 4592 status, intrp->intr_added)); 4593 } else { 4594 for (i = 0; i < intrp->intr_added; i++) { 4595 status = ddi_intr_enable(intrp->htable[i]); 4596 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_enable " 4597 "ddi_intr_enable:enable - status 0x%x " 4598 "total inums %d enable inum #%d\n", 4599 status, intrp->intr_added, i)); 4600 if (status == DDI_SUCCESS) { 4601 intrp->intr_enabled = B_TRUE; 4602 } 4603 } 4604 } 4605 4606 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intrs_enable")); 4607 } 4608 4609 /*ARGSUSED*/ 4610 static void 4611 nxge_intrs_disable(p_nxge_t nxgep) 4612 { 4613 p_nxge_intr_t intrp; 4614 int i; 4615 4616 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_disable")); 4617 4618 intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 4619 4620 if (!intrp->intr_registered) { 4621 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intrs_disable: " 4622 "interrupts are not registered")); 4623 return; 4624 } 4625 4626 if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 4627 (void) ddi_intr_block_disable(intrp->htable, 4628 intrp->intr_added); 4629 } else { 4630 for (i = 0; i < intrp->intr_added; i++) { 4631 (void) ddi_intr_disable(intrp->htable[i]); 4632 } 4633 } 4634 4635 intrp->intr_enabled = B_FALSE; 4636 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intrs_disable")); 4637 } 4638 4639 static nxge_status_t 4640 nxge_mac_register(p_nxge_t nxgep) 4641 { 4642 mac_register_t *macp; 4643 int status; 4644 4645 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_mac_register")); 4646 4647 if ((macp = mac_alloc(MAC_VERSION)) == NULL) 4648 return (NXGE_ERROR); 4649 4650 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 4651 macp->m_driver = nxgep; 4652 macp->m_dip = nxgep->dip; 4653 macp->m_src_addr = nxgep->ouraddr.ether_addr_octet; 4654 macp->m_callbacks = &nxge_m_callbacks; 4655 macp->m_min_sdu = 0; 4656 macp->m_max_sdu = nxgep->mac.maxframesize - 4657 sizeof (struct ether_header) - ETHERFCSL - 4; 4658 macp->m_margin = VLAN_TAGSZ; 4659 4660 status = mac_register(macp, &nxgep->mach); 4661 mac_free(macp); 4662 4663 if (status != 0) { 4664 cmn_err(CE_WARN, 4665 "!nxge_mac_register failed (status %d instance %d)", 4666 status, nxgep->instance); 4667 return (NXGE_ERROR); 4668 } 4669 4670 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_mac_register success " 4671 "(instance %d)", nxgep->instance)); 4672 4673 return (NXGE_OK); 4674 } 4675 4676 void 4677 nxge_err_inject(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 4678 { 4679 ssize_t size; 4680 mblk_t *nmp; 4681 uint8_t blk_id; 4682 uint8_t chan; 4683 uint32_t err_id; 4684 err_inject_t *eip; 4685 4686 NXGE_DEBUG_MSG((nxgep, STR_CTL, "==> nxge_err_inject")); 4687 4688 size = 1024; 4689 nmp = mp->b_cont; 4690 eip = (err_inject_t *)nmp->b_rptr; 4691 blk_id = eip->blk_id; 4692 err_id = eip->err_id; 4693 chan = eip->chan; 4694 cmn_err(CE_NOTE, "!blk_id = 0x%x\n", blk_id); 4695 cmn_err(CE_NOTE, "!err_id = 0x%x\n", err_id); 4696 cmn_err(CE_NOTE, "!chan = 0x%x\n", chan); 4697 switch (blk_id) { 4698 case MAC_BLK_ID: 4699 break; 4700 case TXMAC_BLK_ID: 4701 break; 4702 case RXMAC_BLK_ID: 4703 break; 4704 case MIF_BLK_ID: 4705 break; 4706 case IPP_BLK_ID: 4707 nxge_ipp_inject_err(nxgep, err_id); 4708 break; 4709 case TXC_BLK_ID: 4710 nxge_txc_inject_err(nxgep, err_id); 4711 break; 4712 case TXDMA_BLK_ID: 4713 nxge_txdma_inject_err(nxgep, err_id, chan); 4714 break; 4715 case RXDMA_BLK_ID: 4716 nxge_rxdma_inject_err(nxgep, err_id, chan); 4717 break; 4718 case ZCP_BLK_ID: 4719 nxge_zcp_inject_err(nxgep, err_id); 4720 break; 4721 case ESPC_BLK_ID: 4722 break; 4723 case FFLP_BLK_ID: 4724 break; 4725 case PHY_BLK_ID: 4726 break; 4727 case ETHER_SERDES_BLK_ID: 4728 break; 4729 case PCIE_SERDES_BLK_ID: 4730 break; 4731 case VIR_BLK_ID: 4732 break; 4733 } 4734 4735 nmp->b_wptr = nmp->b_rptr + size; 4736 NXGE_DEBUG_MSG((nxgep, STR_CTL, "<== nxge_err_inject")); 4737 4738 miocack(wq, mp, (int)size, 0); 4739 } 4740 4741 static int 4742 nxge_init_common_dev(p_nxge_t nxgep) 4743 { 4744 p_nxge_hw_list_t hw_p; 4745 dev_info_t *p_dip; 4746 4747 NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==> nxge_init_common_device")); 4748 4749 p_dip = nxgep->p_dip; 4750 MUTEX_ENTER(&nxge_common_lock); 4751 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4752 "==> nxge_init_common_dev:func # %d", 4753 nxgep->function_num)); 4754 /* 4755 * Loop through existing per neptune hardware list. 4756 */ 4757 for (hw_p = nxge_hw_list; hw_p; hw_p = hw_p->next) { 4758 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4759 "==> nxge_init_common_device:func # %d " 4760 "hw_p $%p parent dip $%p", 4761 nxgep->function_num, 4762 hw_p, 4763 p_dip)); 4764 if (hw_p->parent_devp == p_dip) { 4765 nxgep->nxge_hw_p = hw_p; 4766 hw_p->ndevs++; 4767 hw_p->nxge_p[nxgep->function_num] = nxgep; 4768 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4769 "==> nxge_init_common_device:func # %d " 4770 "hw_p $%p parent dip $%p " 4771 "ndevs %d (found)", 4772 nxgep->function_num, 4773 hw_p, 4774 p_dip, 4775 hw_p->ndevs)); 4776 break; 4777 } 4778 } 4779 4780 if (hw_p == NULL) { 4781 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4782 "==> nxge_init_common_device:func # %d " 4783 "parent dip $%p (new)", 4784 nxgep->function_num, 4785 p_dip)); 4786 hw_p = kmem_zalloc(sizeof (nxge_hw_list_t), KM_SLEEP); 4787 hw_p->parent_devp = p_dip; 4788 hw_p->magic = NXGE_NEPTUNE_MAGIC; 4789 nxgep->nxge_hw_p = hw_p; 4790 hw_p->ndevs++; 4791 hw_p->nxge_p[nxgep->function_num] = nxgep; 4792 hw_p->next = nxge_hw_list; 4793 if (nxgep->niu_type == N2_NIU) { 4794 hw_p->niu_type = N2_NIU; 4795 hw_p->platform_type = P_NEPTUNE_NIU; 4796 } else { 4797 hw_p->niu_type = NIU_TYPE_NONE; 4798 hw_p->platform_type = P_NEPTUNE_NONE; 4799 } 4800 4801 MUTEX_INIT(&hw_p->nxge_cfg_lock, NULL, MUTEX_DRIVER, NULL); 4802 MUTEX_INIT(&hw_p->nxge_tcam_lock, NULL, MUTEX_DRIVER, NULL); 4803 MUTEX_INIT(&hw_p->nxge_vlan_lock, NULL, MUTEX_DRIVER, NULL); 4804 MUTEX_INIT(&hw_p->nxge_mdio_lock, NULL, MUTEX_DRIVER, NULL); 4805 MUTEX_INIT(&hw_p->nxge_mii_lock, NULL, MUTEX_DRIVER, NULL); 4806 4807 nxge_hw_list = hw_p; 4808 4809 (void) nxge_scan_ports_phy(nxgep, nxge_hw_list); 4810 } 4811 4812 MUTEX_EXIT(&nxge_common_lock); 4813 4814 nxgep->platform_type = hw_p->platform_type; 4815 if (nxgep->niu_type != N2_NIU) { 4816 nxgep->niu_type = hw_p->niu_type; 4817 } 4818 4819 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4820 "==> nxge_init_common_device (nxge_hw_list) $%p", 4821 nxge_hw_list)); 4822 NXGE_DEBUG_MSG((nxgep, MOD_CTL, "<== nxge_init_common_device")); 4823 4824 return (NXGE_OK); 4825 } 4826 4827 static void 4828 nxge_uninit_common_dev(p_nxge_t nxgep) 4829 { 4830 p_nxge_hw_list_t hw_p, h_hw_p; 4831 dev_info_t *p_dip; 4832 4833 NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==> nxge_uninit_common_device")); 4834 if (nxgep->nxge_hw_p == NULL) { 4835 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4836 "<== nxge_uninit_common_device (no common)")); 4837 return; 4838 } 4839 4840 MUTEX_ENTER(&nxge_common_lock); 4841 h_hw_p = nxge_hw_list; 4842 for (hw_p = nxge_hw_list; hw_p; hw_p = hw_p->next) { 4843 p_dip = hw_p->parent_devp; 4844 if (nxgep->nxge_hw_p == hw_p && 4845 p_dip == nxgep->p_dip && 4846 nxgep->nxge_hw_p->magic == NXGE_NEPTUNE_MAGIC && 4847 hw_p->magic == NXGE_NEPTUNE_MAGIC) { 4848 4849 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4850 "==> nxge_uninit_common_device:func # %d " 4851 "hw_p $%p parent dip $%p " 4852 "ndevs %d (found)", 4853 nxgep->function_num, 4854 hw_p, 4855 p_dip, 4856 hw_p->ndevs)); 4857 4858 nxgep->nxge_hw_p = NULL; 4859 if (hw_p->ndevs) { 4860 hw_p->ndevs--; 4861 } 4862 hw_p->nxge_p[nxgep->function_num] = NULL; 4863 if (!hw_p->ndevs) { 4864 MUTEX_DESTROY(&hw_p->nxge_vlan_lock); 4865 MUTEX_DESTROY(&hw_p->nxge_tcam_lock); 4866 MUTEX_DESTROY(&hw_p->nxge_cfg_lock); 4867 MUTEX_DESTROY(&hw_p->nxge_mdio_lock); 4868 MUTEX_DESTROY(&hw_p->nxge_mii_lock); 4869 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4870 "==> nxge_uninit_common_device: " 4871 "func # %d " 4872 "hw_p $%p parent dip $%p " 4873 "ndevs %d (last)", 4874 nxgep->function_num, 4875 hw_p, 4876 p_dip, 4877 hw_p->ndevs)); 4878 4879 if (hw_p == nxge_hw_list) { 4880 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4881 "==> nxge_uninit_common_device:" 4882 "remove head func # %d " 4883 "hw_p $%p parent dip $%p " 4884 "ndevs %d (head)", 4885 nxgep->function_num, 4886 hw_p, 4887 p_dip, 4888 hw_p->ndevs)); 4889 nxge_hw_list = hw_p->next; 4890 } else { 4891 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4892 "==> nxge_uninit_common_device:" 4893 "remove middle func # %d " 4894 "hw_p $%p parent dip $%p " 4895 "ndevs %d (middle)", 4896 nxgep->function_num, 4897 hw_p, 4898 p_dip, 4899 hw_p->ndevs)); 4900 h_hw_p->next = hw_p->next; 4901 } 4902 4903 KMEM_FREE(hw_p, sizeof (nxge_hw_list_t)); 4904 } 4905 break; 4906 } else { 4907 h_hw_p = hw_p; 4908 } 4909 } 4910 4911 MUTEX_EXIT(&nxge_common_lock); 4912 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4913 "==> nxge_uninit_common_device (nxge_hw_list) $%p", 4914 nxge_hw_list)); 4915 4916 NXGE_DEBUG_MSG((nxgep, MOD_CTL, "<= nxge_uninit_common_device")); 4917 } 4918 4919 /* 4920 * Determines the number of ports from the niu_type or the platform type. 4921 * Returns the number of ports, or returns zero on failure. 4922 */ 4923 4924 int 4925 nxge_get_nports(p_nxge_t nxgep) 4926 { 4927 int nports = 0; 4928 4929 switch (nxgep->niu_type) { 4930 case N2_NIU: 4931 case NEPTUNE_2_10GF: 4932 nports = 2; 4933 break; 4934 case NEPTUNE_4_1GC: 4935 case NEPTUNE_2_10GF_2_1GC: 4936 case NEPTUNE_1_10GF_3_1GC: 4937 case NEPTUNE_1_1GC_1_10GF_2_1GC: 4938 nports = 4; 4939 break; 4940 default: 4941 switch (nxgep->platform_type) { 4942 case P_NEPTUNE_NIU: 4943 case P_NEPTUNE_ATLAS_2PORT: 4944 nports = 2; 4945 break; 4946 case P_NEPTUNE_ATLAS_4PORT: 4947 case P_NEPTUNE_MARAMBA_P0: 4948 case P_NEPTUNE_MARAMBA_P1: 4949 case P_NEPTUNE_ALONSO: 4950 nports = 4; 4951 break; 4952 default: 4953 break; 4954 } 4955 break; 4956 } 4957 4958 return (nports); 4959 } 4960 4961 /* 4962 * The following two functions are to support 4963 * PSARC/2007/453 MSI-X interrupt limit override. 4964 */ 4965 static int 4966 nxge_create_msi_property(p_nxge_t nxgep) 4967 { 4968 int nmsi; 4969 extern int ncpus; 4970 4971 NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==>nxge_create_msi_property")); 4972 4973 switch (nxgep->mac.portmode) { 4974 case PORT_10G_COPPER: 4975 case PORT_10G_FIBER: 4976 (void) ddi_prop_create(DDI_DEV_T_NONE, nxgep->dip, 4977 DDI_PROP_CANSLEEP, "#msix-request", NULL, 0); 4978 /* 4979 * The maximum MSI-X requested will be 8. 4980 * If the # of CPUs is less than 8, we will reqeust 4981 * # MSI-X based on the # of CPUs. 4982 */ 4983 if (ncpus >= NXGE_MSIX_REQUEST_10G) { 4984 nmsi = NXGE_MSIX_REQUEST_10G; 4985 } else { 4986 nmsi = ncpus; 4987 } 4988 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4989 "==>nxge_create_msi_property(10G): exists 0x%x (nmsi %d)", 4990 ddi_prop_exists(DDI_DEV_T_NONE, nxgep->dip, 4991 DDI_PROP_CANSLEEP, "#msix-request"), nmsi)); 4992 break; 4993 4994 default: 4995 nmsi = NXGE_MSIX_REQUEST_1G; 4996 NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4997 "==>nxge_create_msi_property(1G): exists 0x%x (nmsi %d)", 4998 ddi_prop_exists(DDI_DEV_T_NONE, nxgep->dip, 4999 DDI_PROP_CANSLEEP, "#msix-request"), nmsi)); 5000 break; 5001 } 5002 5003 NXGE_DEBUG_MSG((nxgep, MOD_CTL, "<==nxge_create_msi_property")); 5004 return (nmsi); 5005 } 5006