1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <nxge_impl.h> 28 #include <npi_mac.h> 29 #include <npi_rxdma.h> 30 #include <nxge_hio.h> 31 32 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 33 static int nxge_herr2kerr(uint64_t); 34 #endif 35 36 static nxge_status_t nxge_init_fzc_rdc_pages(p_nxge_t, 37 uint16_t, dma_log_page_t *, dma_log_page_t *); 38 39 static nxge_status_t nxge_init_fzc_tdc_pages(p_nxge_t, 40 uint16_t, dma_log_page_t *, dma_log_page_t *); 41 42 /* 43 * The following interfaces are controlled by the 44 * function control registers. Some global registers 45 * are to be initialized by only byt one of the 2/4 functions. 46 * Use the test and set register. 47 */ 48 /*ARGSUSED*/ 49 nxge_status_t 50 nxge_test_and_set(p_nxge_t nxgep, uint8_t tas) 51 { 52 npi_handle_t handle; 53 npi_status_t rs = NPI_SUCCESS; 54 55 handle = NXGE_DEV_NPI_HANDLE(nxgep); 56 if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas)) 57 != NPI_SUCCESS) { 58 return (NXGE_ERROR | rs); 59 } 60 61 return (NXGE_OK); 62 } 63 64 nxge_status_t 65 nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc) 66 { 67 npi_handle_t handle; 68 npi_status_t rs = NPI_SUCCESS; 69 70 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl")); 71 72 /* 73 * In multi-partitioning, the partition manager 74 * who owns function zero should set this multi-partition 75 * control bit. 76 */ 77 if (nxgep->use_partition && nxgep->function_num) { 78 return (NXGE_ERROR); 79 } 80 81 handle = NXGE_DEV_NPI_HANDLE(nxgep); 82 if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) { 83 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 84 "<== nxge_set_fzc_multi_part_ctl")); 85 return (NXGE_ERROR | rs); 86 } 87 88 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl")); 89 90 return (NXGE_OK); 91 } 92 93 nxge_status_t 94 nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p) 95 { 96 npi_handle_t handle; 97 npi_status_t rs = NPI_SUCCESS; 98 99 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl")); 100 101 handle = NXGE_DEV_NPI_HANDLE(nxgep); 102 if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) { 103 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 104 "<== nxge_set_fzc_multi_part_ctl")); 105 return (NXGE_ERROR | rs); 106 } 107 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl")); 108 109 return (NXGE_OK); 110 } 111 112 /* 113 * System interrupt registers that are under function zero 114 * management. 115 */ 116 nxge_status_t 117 nxge_fzc_intr_init(p_nxge_t nxgep) 118 { 119 nxge_status_t status = NXGE_OK; 120 121 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init")); 122 123 /* Configure the initial timer resolution */ 124 if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) { 125 return (status); 126 } 127 128 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 129 /* 130 * Set up the logical device group's logical devices that 131 * the group owns. 132 */ 133 if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK) 134 goto fzc_intr_init_exit; 135 136 /* Configure the system interrupt data */ 137 if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK) 138 goto fzc_intr_init_exit; 139 } 140 141 fzc_intr_init_exit: 142 143 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init")); 144 145 return (status); 146 } 147 148 nxge_status_t 149 nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep) 150 { 151 p_nxge_ldg_t ldgp; 152 p_nxge_ldv_t ldvp; 153 npi_handle_t handle; 154 int i, j; 155 npi_status_t rs = NPI_SUCCESS; 156 157 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set")); 158 159 if (nxgep->ldgvp == NULL) { 160 return (NXGE_ERROR); 161 } 162 163 ldgp = nxgep->ldgvp->ldgp; 164 ldvp = nxgep->ldgvp->ldvp; 165 if (ldgp == NULL || ldvp == NULL) { 166 return (NXGE_ERROR); 167 } 168 169 handle = NXGE_DEV_NPI_HANDLE(nxgep); 170 171 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 172 NXGE_DEBUG_MSG((nxgep, INT_CTL, 173 "==> nxge_fzc_intr_ldg_num_set " 174 "<== nxge_f(Neptune): # ldv %d " 175 "in group %d", ldgp->nldvs, ldgp->ldg)); 176 177 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 178 rs = npi_fzc_ldg_num_set(handle, ldvp->ldv, 179 ldvp->ldg_assigned); 180 if (rs != NPI_SUCCESS) { 181 NXGE_DEBUG_MSG((nxgep, INT_CTL, 182 "<== nxge_fzc_intr_ldg_num_set failed " 183 " rs 0x%x ldv %d ldg %d", 184 rs, ldvp->ldv, ldvp->ldg_assigned)); 185 return (NXGE_ERROR | rs); 186 } 187 NXGE_DEBUG_MSG((nxgep, INT_CTL, 188 "<== nxge_fzc_intr_ldg_num_set OK " 189 " ldv %d ldg %d", 190 ldvp->ldv, ldvp->ldg_assigned)); 191 } 192 } 193 194 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set")); 195 196 return (NXGE_OK); 197 } 198 199 nxge_status_t 200 nxge_fzc_intr_tmres_set(p_nxge_t nxgep) 201 { 202 npi_handle_t handle; 203 npi_status_t rs = NPI_SUCCESS; 204 205 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set")); 206 if (nxgep->ldgvp == NULL) { 207 return (NXGE_ERROR); 208 } 209 handle = NXGE_DEV_NPI_HANDLE(nxgep); 210 if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) { 211 return (NXGE_ERROR | rs); 212 } 213 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set")); 214 215 return (NXGE_OK); 216 } 217 218 nxge_status_t 219 nxge_fzc_intr_sid_set(p_nxge_t nxgep) 220 { 221 npi_handle_t handle; 222 p_nxge_ldg_t ldgp; 223 fzc_sid_t sid; 224 int i; 225 npi_status_t rs = NPI_SUCCESS; 226 227 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set")); 228 if (nxgep->ldgvp == NULL) { 229 NXGE_DEBUG_MSG((nxgep, INT_CTL, 230 "<== nxge_fzc_intr_sid_set: no ldg")); 231 return (NXGE_ERROR); 232 } 233 handle = NXGE_DEV_NPI_HANDLE(nxgep); 234 ldgp = nxgep->ldgvp->ldgp; 235 NXGE_DEBUG_MSG((nxgep, INT_CTL, 236 "==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs)); 237 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 238 sid.ldg = ldgp->ldg; 239 sid.niu = B_FALSE; 240 sid.func = ldgp->func; 241 sid.vector = ldgp->vector; 242 NXGE_DEBUG_MSG((nxgep, INT_CTL, 243 "==> nxge_fzc_intr_sid_set(%d): func %d group %d " 244 "vector %d", 245 i, sid.func, sid.ldg, sid.vector)); 246 rs = npi_fzc_sid_set(handle, sid); 247 if (rs != NPI_SUCCESS) { 248 NXGE_DEBUG_MSG((nxgep, INT_CTL, 249 "<== nxge_fzc_intr_sid_set:failed 0x%x", 250 rs)); 251 return (NXGE_ERROR | rs); 252 } 253 } 254 255 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set")); 256 257 return (NXGE_OK); 258 259 } 260 261 /* 262 * nxge_init_fzc_rdc 263 * 264 * Initialize all of a RDC's FZC_DMC registers. 265 * This is executed by the service domain, on behalf of a 266 * guest domain, who cannot access these registers. 267 * 268 * Arguments: 269 * nxgep 270 * channel The channel to initialize. 271 * 272 * NPI_NXGE function calls: 273 * nxge_init_fzc_rdc_pages() 274 * 275 * Context: 276 * Service Domain 277 */ 278 /*ARGSUSED*/ 279 nxge_status_t 280 nxge_init_fzc_rdc(p_nxge_t nxgep, uint16_t channel) 281 { 282 nxge_status_t status = NXGE_OK; 283 284 dma_log_page_t page1, page2; 285 npi_handle_t handle; 286 rdc_red_para_t red; 287 288 /* 289 * Initialize the RxDMA channel-specific FZC control 290 * registers. 291 */ 292 293 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc")); 294 295 handle = NXGE_DEV_NPI_HANDLE(nxgep); 296 297 /* Reset RXDMA channel */ 298 status = npi_rxdma_cfg_rdc_reset(handle, channel); 299 if (status != NPI_SUCCESS) { 300 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 301 "==> nxge_init_fzc_rdc: npi_rxdma_cfg_rdc_reset(%d) " 302 "returned 0x%08x", channel, status)); 303 return (NXGE_ERROR | status); 304 } 305 306 /* 307 * These values have been copied from 308 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring(). 309 */ 310 page1.page_num = 0; 311 page1.valid = 1; 312 page1.func_num = nxgep->function_num; 313 page1.mask = 0; 314 page1.value = 0; 315 page1.reloc = 0; 316 317 page2.page_num = 1; 318 page2.valid = 1; 319 page2.func_num = nxgep->function_num; 320 page2.mask = 0; 321 page2.value = 0; 322 page2.reloc = 0; 323 324 if (nxgep->niu_type == N2_NIU) { 325 #if !defined(NIU_HV_WORKAROUND) 326 status = NXGE_OK; 327 #else 328 NXGE_DEBUG_MSG((nxgep, RX_CTL, 329 "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to " 330 "set up logical pages")); 331 /* Initialize the RXDMA logical pages */ 332 status = nxge_init_fzc_rdc_pages(nxgep, channel, 333 &page1, &page2); 334 if (status != NXGE_OK) { 335 return (status); 336 } 337 #endif 338 } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 339 /* Initialize the RXDMA logical pages */ 340 status = nxge_init_fzc_rdc_pages(nxgep, channel, 341 &page1, &page2); 342 if (status != NXGE_OK) { 343 return (status); 344 } 345 } else { 346 return (NXGE_ERROR); 347 } 348 349 /* 350 * Configure RED parameters 351 */ 352 red.value = 0; 353 red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT; 354 red.bits.ldw.thre = 355 (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES); 356 red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT; 357 red.bits.ldw.thre_sync = 358 (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES); 359 360 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 361 "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))", 362 red.bits.ldw.thre_sync, 363 red.bits.ldw.thre_sync)); 364 365 status |= npi_rxdma_cfg_wred_param(handle, channel, &red); 366 367 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc")); 368 369 return (status); 370 } 371 372 /* 373 * nxge_init_fzc_rxdma_channel 374 * 375 * Initialize all per-channel FZC_DMC registers. 376 * 377 * Arguments: 378 * nxgep 379 * channel The channel to start 380 * 381 * NPI_NXGE function calls: 382 * nxge_init_hv_fzc_rxdma_channel_pages() 383 * nxge_init_fzc_rxdma_channel_pages() 384 * nxge_init_fzc_rxdma_channel_red() 385 * 386 * Context: 387 * Service Domain 388 */ 389 /*ARGSUSED*/ 390 nxge_status_t 391 nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel) 392 { 393 rx_rbr_ring_t *rbr_ring; 394 rx_rcr_ring_t *rcr_ring; 395 396 nxge_status_t status = NXGE_OK; 397 398 NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel")); 399 400 rbr_ring = nxgep->rx_rbr_rings->rbr_rings[channel]; 401 rcr_ring = nxgep->rx_rcr_rings->rcr_rings[channel]; 402 403 if (nxgep->niu_type == N2_NIU) { 404 #ifndef NIU_HV_WORKAROUND 405 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 406 NXGE_DEBUG_MSG((nxgep, RX_CTL, 407 "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV " 408 "set up logical pages")); 409 /* Initialize the RXDMA logical pages */ 410 status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel, 411 rbr_ring); 412 if (status != NXGE_OK) { 413 return (status); 414 } 415 #endif 416 status = NXGE_OK; 417 #else 418 NXGE_DEBUG_MSG((nxgep, RX_CTL, 419 "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to " 420 "set up logical pages")); 421 /* Initialize the RXDMA logical pages */ 422 status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel, 423 rbr_ring); 424 if (status != NXGE_OK) { 425 return (status); 426 } 427 #endif 428 } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 429 /* Initialize the RXDMA logical pages */ 430 status = nxge_init_fzc_rxdma_channel_pages(nxgep, 431 channel, rbr_ring); 432 if (status != NXGE_OK) { 433 return (status); 434 } 435 } else { 436 return (NXGE_ERROR); 437 } 438 439 /* Configure RED parameters */ 440 status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_ring); 441 442 NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel")); 443 return (status); 444 } 445 446 /* 447 * nxge_init_fzc_rdc_pages 448 * 449 * Configure a TDC's logical pages. 450 * 451 * This function is executed by the service domain, on behalf of 452 * a guest domain, to whom this RDC has been loaned. 453 * 454 * Arguments: 455 * nxgep 456 * channel The channel to initialize. 457 * page0 Logical page 0 definition. 458 * page1 Logical page 1 definition. 459 * 460 * Notes: 461 * I think that this function can be called from any 462 * domain, but I need to check. 463 * 464 * NPI/NXGE function calls: 465 * hv_niu_tx_logical_page_conf() 466 * hv_niu_tx_logical_page_info() 467 * 468 * Context: 469 * Any domain 470 */ 471 nxge_status_t 472 nxge_init_fzc_rdc_pages( 473 p_nxge_t nxgep, 474 uint16_t channel, 475 dma_log_page_t *page0, 476 dma_log_page_t *page1) 477 { 478 npi_handle_t handle; 479 npi_status_t rs; 480 481 uint64_t page_handle; 482 483 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 484 "==> nxge_init_fzc_txdma_channel_pages")); 485 486 #ifndef NIU_HV_WORKAROUND 487 if (nxgep->niu_type == N2_NIU) { 488 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 489 "<== nxge_init_fzc_rdc_pages: " 490 "N2_NIU: no need to set rxdma logical pages")); 491 return (NXGE_OK); 492 } 493 #else 494 if (nxgep->niu_type == N2_NIU) { 495 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 496 "<== nxge_init_fzc_rdc_pages: " 497 "N2_NIU: NEED to set rxdma logical pages")); 498 } 499 #endif 500 501 /* 502 * Initialize logical page 1. 503 */ 504 handle = NXGE_DEV_NPI_HANDLE(nxgep); 505 if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page0)) 506 != NPI_SUCCESS) 507 return (NXGE_ERROR | rs); 508 509 /* 510 * Initialize logical page 2. 511 */ 512 if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page1)) 513 != NPI_SUCCESS) 514 return (NXGE_ERROR | rs); 515 516 /* 517 * Initialize the page handle. 518 * (In the current driver, this is always set to 0.) 519 */ 520 page_handle = 0; 521 rs = npi_rxdma_cfg_logical_page_handle(handle, channel, page_handle); 522 if (rs == NPI_SUCCESS) { 523 return (NXGE_OK); 524 } else { 525 return (NXGE_ERROR | rs); 526 } 527 } 528 529 /*ARGSUSED*/ 530 nxge_status_t 531 nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep, 532 uint16_t channel, p_rx_rbr_ring_t rbrp) 533 { 534 npi_handle_t handle; 535 dma_log_page_t cfg; 536 npi_status_t rs = NPI_SUCCESS; 537 538 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 539 "==> nxge_init_fzc_rxdma_channel_pages")); 540 541 handle = NXGE_DEV_NPI_HANDLE(nxgep); 542 /* 543 * Initialize logical page 1. 544 */ 545 cfg.func_num = nxgep->function_num; 546 cfg.page_num = 0; 547 cfg.valid = rbrp->page_valid.bits.ldw.page0; 548 cfg.value = rbrp->page_value_1.value; 549 cfg.mask = rbrp->page_mask_1.value; 550 cfg.reloc = rbrp->page_reloc_1.value; 551 rs = npi_rxdma_cfg_logical_page(handle, channel, 552 (p_dma_log_page_t)&cfg); 553 if (rs != NPI_SUCCESS) { 554 return (NXGE_ERROR | rs); 555 } 556 557 /* 558 * Initialize logical page 2. 559 */ 560 cfg.page_num = 1; 561 cfg.valid = rbrp->page_valid.bits.ldw.page1; 562 cfg.value = rbrp->page_value_2.value; 563 cfg.mask = rbrp->page_mask_2.value; 564 cfg.reloc = rbrp->page_reloc_2.value; 565 566 rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg); 567 if (rs != NPI_SUCCESS) { 568 return (NXGE_ERROR | rs); 569 } 570 571 /* Initialize the page handle */ 572 rs = npi_rxdma_cfg_logical_page_handle(handle, channel, 573 rbrp->page_hdl.bits.ldw.handle); 574 575 if (rs != NPI_SUCCESS) { 576 return (NXGE_ERROR | rs); 577 } 578 579 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 580 "<== nxge_init_fzc_rxdma_channel_pages")); 581 582 return (NXGE_OK); 583 } 584 585 /*ARGSUSED*/ 586 nxge_status_t 587 nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep, 588 uint16_t channel, p_rx_rcr_ring_t rcr_p) 589 { 590 npi_handle_t handle; 591 rdc_red_para_t red; 592 npi_status_t rs = NPI_SUCCESS; 593 594 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red")); 595 596 handle = NXGE_DEV_NPI_HANDLE(nxgep); 597 red.value = 0; 598 red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT; 599 red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 600 red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT; 601 red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 602 603 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 604 "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))", 605 red.bits.ldw.thre_sync, 606 red.bits.ldw.thre_sync)); 607 608 rs = npi_rxdma_cfg_wred_param(handle, channel, &red); 609 if (rs != NPI_SUCCESS) { 610 return (NXGE_ERROR | rs); 611 } 612 613 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 614 "<== nxge_init_fzc_rxdma_channel_red")); 615 616 return (NXGE_OK); 617 } 618 619 /* 620 * nxge_init_fzc_tdc 621 * 622 * Initialize all of a TDC's FZC_DMC registers. 623 * This is executed by the service domain, on behalf of a 624 * guest domain, who cannot access these registers. 625 * 626 * Arguments: 627 * nxgep 628 * channel The channel to initialize. 629 * 630 * NPI_NXGE function calls: 631 * nxge_init_fzc_tdc_pages() 632 * npi_txc_dma_max_burst_set() 633 * 634 * Registers accessed: 635 * TXC_DMA_MAX_BURST 636 * 637 * Context: 638 * Service Domain 639 */ 640 /*ARGSUSED*/ 641 nxge_status_t 642 nxge_init_fzc_tdc(p_nxge_t nxgep, uint16_t channel) 643 { 644 nxge_status_t status = NXGE_OK; 645 646 dma_log_page_t page1, page2; 647 npi_handle_t handle; 648 649 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc")); 650 651 /* 652 * These values have been copied from 653 * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring(). 654 */ 655 page1.page_num = 0; 656 page1.valid = 1; 657 page1.func_num = nxgep->function_num; 658 page1.mask = 0; 659 page1.value = 0; 660 page1.reloc = 0; 661 662 page1.page_num = 1; 663 page1.valid = 1; 664 page1.func_num = nxgep->function_num; 665 page1.mask = 0; 666 page1.value = 0; 667 page1.reloc = 0; 668 669 #ifdef NIU_HV_WORKAROUND 670 if (nxgep->niu_type == N2_NIU) { 671 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 672 "==> nxge_init_fzc_txdma_channel " 673 "N2_NIU: NEED to set up txdma logical pages")); 674 /* Initialize the TXDMA logical pages */ 675 (void) nxge_init_fzc_tdc_pages(nxgep, channel, 676 &page1, &page2); 677 } 678 #endif 679 if (nxgep->niu_type != N2_NIU) { 680 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 681 /* Initialize the TXDMA logical pages */ 682 (void) nxge_init_fzc_tdc_pages(nxgep, channel, 683 &page1, &page2); 684 } else 685 return (NXGE_ERROR); 686 } 687 688 /* 689 * Configure the TXC DMA Max Burst value. 690 * 691 * PRM.13.5 692 * 693 * TXC DMA Max Burst. TXC_DMA_MAX (FZC_TXC + 0000016) 694 * 19:0 dma_max_burst RW 695 * Max burst value associated with DMA. Used by DRR engine 696 * for computing when DMA has gone into deficit. 697 */ 698 handle = NXGE_DEV_NPI_HANDLE(nxgep); 699 (void) npi_txc_dma_max_burst_set( 700 handle, channel, TXC_DMA_MAX_BURST_DEFAULT); 701 702 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_tdc")); 703 704 return (status); 705 } 706 707 /*ARGSUSED*/ 708 nxge_status_t 709 nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel, 710 p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p) 711 { 712 nxge_status_t status = NXGE_OK; 713 714 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 715 "==> nxge_init_fzc_txdma_channel")); 716 717 if (nxgep->niu_type == N2_NIU) { 718 #ifndef NIU_HV_WORKAROUND 719 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 720 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 721 "==> nxge_init_fzc_txdma_channel " 722 "N2_NIU: call HV to set up txdma logical pages")); 723 status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel, 724 tx_ring_p); 725 if (status != NXGE_OK) { 726 return (status); 727 } 728 #endif 729 status = NXGE_OK; 730 #else 731 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 732 "==> nxge_init_fzc_txdma_channel " 733 "N2_NIU: NEED to set up txdma logical pages")); 734 /* Initialize the TXDMA logical pages */ 735 (void) nxge_init_fzc_txdma_channel_pages(nxgep, channel, 736 tx_ring_p); 737 #endif 738 } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 739 /* Initialize the TXDMA logical pages */ 740 (void) nxge_init_fzc_txdma_channel_pages(nxgep, 741 channel, tx_ring_p); 742 } else { 743 return (NXGE_ERROR); 744 } 745 746 /* 747 * Configure Transmit DRR Weight parameters 748 * (It actually programs the TXC max burst register). 749 */ 750 (void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p); 751 752 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 753 "<== nxge_init_fzc_txdma_channel")); 754 return (status); 755 } 756 757 758 nxge_status_t 759 nxge_init_fzc_rx_common(p_nxge_t nxgep) 760 { 761 npi_handle_t handle; 762 npi_status_t rs = NPI_SUCCESS; 763 nxge_status_t status = NXGE_OK; 764 nxge_rdc_grp_t *rdc_grp_p; 765 clock_t lbolt; 766 int table; 767 768 nxge_hw_pt_cfg_t *hardware; 769 770 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common")); 771 handle = NXGE_DEV_NPI_HANDLE(nxgep); 772 if (!handle.regp) { 773 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 774 "==> nxge_init_fzc_rx_common null ptr")); 775 return (NXGE_ERROR); 776 } 777 778 /* 779 * Configure the rxdma clock divider 780 * This is the granularity counter based on 781 * the hardware system clock (i.e. 300 Mhz) and 782 * it is running around 3 nanoseconds. 783 * So, set the clock divider counter to 1000 to get 784 * microsecond granularity. 785 * For example, for a 3 microsecond timeout, the timeout 786 * will be set to 1. 787 */ 788 rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT); 789 if (rs != NPI_SUCCESS) 790 return (NXGE_ERROR | rs); 791 792 #if defined(__i386) 793 rs = npi_rxdma_cfg_32bitmode_enable(handle); 794 if (rs != NPI_SUCCESS) 795 return (NXGE_ERROR | rs); 796 rs = npi_txdma_mode32_set(handle, B_TRUE); 797 if (rs != NPI_SUCCESS) 798 return (NXGE_ERROR | rs); 799 #endif 800 801 /* 802 * Enable WRED and program an initial value. 803 * Use time to set the initial random number. 804 */ 805 (void) drv_getparm(LBOLT, &lbolt); 806 rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt); 807 if (rs != NPI_SUCCESS) 808 return (NXGE_ERROR | rs); 809 810 hardware = &nxgep->pt_config.hw_config; 811 for (table = 0; table < NXGE_MAX_RDC_GRPS; table++) { 812 /* Does this table belong to <nxgep>? */ 813 if (hardware->grpids[table] == (nxgep->function_num + 256)) { 814 rdc_grp_p = &nxgep->pt_config.rdc_grps[table]; 815 status = nxge_init_fzc_rdc_tbl(nxgep, rdc_grp_p, table); 816 } 817 } 818 819 /* Ethernet Timeout Counter (?) */ 820 821 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 822 "<== nxge_init_fzc_rx_common:status 0x%08x", status)); 823 824 return (status); 825 } 826 827 nxge_status_t 828 nxge_init_fzc_rdc_tbl(p_nxge_t nxge, nxge_rdc_grp_t *group, int rdc_tbl) 829 { 830 nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio; 831 nx_rdc_tbl_t *table; 832 npi_handle_t handle; 833 834 npi_status_t rs = NPI_SUCCESS; 835 nxge_status_t status = NXGE_OK; 836 837 NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_init_fzc_rdc_tbl(%d)", table)); 838 839 /* This RDC table must have been previously bound to <nxge>. */ 840 MUTEX_ENTER(&nhd->lock); 841 table = &nhd->rdc_tbl[rdc_tbl]; 842 if (table->nxge != (uintptr_t)nxge) { 843 MUTEX_EXIT(&nhd->lock); 844 NXGE_ERROR_MSG((nxge, DMA_CTL, 845 "nxge_init_fzc_rdc_tbl(%d): not owner", table)); 846 return (NXGE_ERROR); 847 } else { 848 table->map = group->map; 849 } 850 MUTEX_EXIT(&nhd->lock); 851 852 handle = NXGE_DEV_NPI_HANDLE(nxge); 853 854 rs = npi_rxdma_rdc_table_config(handle, rdc_tbl, 855 group->map, group->max_rdcs); 856 857 if (rs != NPI_SUCCESS) { 858 status = NXGE_ERROR | rs; 859 } 860 861 NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_init_fzc_rdc_tbl(%d)", table)); 862 return (status); 863 } 864 865 static 866 int 867 rdc_tbl_bind(p_nxge_t nxge, int rdc_tbl) 868 { 869 nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio; 870 nx_rdc_tbl_t *table; 871 int i; 872 873 NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_bind")); 874 875 MUTEX_ENTER(&nhd->lock); 876 /* is the caller asking for a particular table? */ 877 if (rdc_tbl >= 0 && rdc_tbl < NXGE_MAX_RDC_GROUPS) { 878 table = &nhd->rdc_tbl[rdc_tbl]; 879 if (table->nxge == 0) { 880 table->nxge = (uintptr_t)nxge; /* It is now bound. */ 881 NXGE_DEBUG_MSG((nxge, DMA_CTL, 882 "<== nxge_fzc_rdc_tbl_bind(%d)", rdc_tbl)); 883 MUTEX_EXIT(&nhd->lock); 884 return (rdc_tbl); 885 } 886 } else { /* The caller will take any old RDC table. */ 887 for (i = 0; i < NXGE_MAX_RDC_GROUPS; i++) { 888 nx_rdc_tbl_t *table = &nhd->rdc_tbl[i]; 889 if (table->nxge == 0) { 890 table->nxge = (uintptr_t)nxge; 891 /* It is now bound. */ 892 MUTEX_EXIT(&nhd->lock); 893 NXGE_DEBUG_MSG((nxge, DMA_CTL, 894 "<== nxge_fzc_rdc_tbl_bind: %d", i)); 895 return (i); 896 } 897 } 898 } 899 MUTEX_EXIT(&nhd->lock); 900 901 NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_fzc_rdc_tbl_bind")); 902 903 return (-EBUSY); /* RDC tables are bound. */ 904 } 905 906 int 907 nxge_fzc_rdc_tbl_bind( 908 nxge_t *nxge, 909 int grp_index, 910 int acceptNoSubstitutes) 911 { 912 nxge_hw_pt_cfg_t *hardware; 913 int index; 914 915 hardware = &nxge->pt_config.hw_config; 916 917 if ((index = rdc_tbl_bind(nxge, grp_index)) < 0) { 918 if (acceptNoSubstitutes) 919 return (index); 920 index = rdc_tbl_bind(nxge, grp_index); 921 if (index < 0) { 922 NXGE_ERROR_MSG((nxge, OBP_CTL, 923 "nxge_fzc_rdc_tbl_init: " 924 "there are no free RDC tables!")); 925 return (index); 926 } 927 } 928 929 hardware->grpids[index] = nxge->function_num + 256; 930 931 return (index); 932 } 933 934 int 935 nxge_fzc_rdc_tbl_unbind(p_nxge_t nxge, int rdc_tbl) 936 { 937 nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio; 938 nx_rdc_tbl_t *table; 939 940 if (nhd == NULL) 941 return (0); 942 943 NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_unbind(%d)", 944 rdc_tbl)); 945 946 MUTEX_ENTER(&nhd->lock); 947 table = &nhd->rdc_tbl[rdc_tbl]; 948 if (table->nxge != (uintptr_t)nxge) { 949 NXGE_ERROR_MSG((nxge, DMA_CTL, 950 "nxge_fzc_rdc_tbl_unbind(%d): func%d not owner", 951 nxge->function_num, rdc_tbl)); 952 MUTEX_EXIT(&nhd->lock); 953 return (EINVAL); 954 } else { 955 bzero(table, sizeof (*table)); 956 } 957 MUTEX_EXIT(&nhd->lock); 958 959 NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_fzc_rdc_tbl_unbind(%d)", 960 rdc_tbl)); 961 962 return (0); 963 } 964 965 nxge_status_t 966 nxge_init_fzc_rxdma_port(p_nxge_t nxgep) 967 { 968 npi_handle_t handle; 969 p_nxge_dma_pt_cfg_t p_all_cfgp; 970 p_nxge_hw_pt_cfg_t p_cfgp; 971 hostinfo_t hostinfo; 972 int i; 973 npi_status_t rs = NPI_SUCCESS; 974 p_nxge_class_pt_cfg_t p_class_cfgp; 975 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port")); 976 977 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 978 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 979 handle = NXGE_DEV_NPI_HANDLE(nxgep); 980 /* 981 * Initialize the port scheduler DRR weight. 982 * npi_rxdma_cfg_port_ddr_weight(); 983 */ 984 985 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 986 (nxgep->mac.portmode == PORT_1G_FIBER) || 987 (nxgep->mac.portmode == PORT_1G_TN1010) || 988 (nxgep->mac.portmode == PORT_1G_SERDES)) { 989 rs = npi_rxdma_cfg_port_ddr_weight(handle, 990 nxgep->function_num, NXGE_RX_DRR_WT_1G); 991 if (rs != NPI_SUCCESS) { 992 return (NXGE_ERROR | rs); 993 } 994 } 995 996 /* Program the default RDC of a port */ 997 rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num, 998 p_cfgp->def_rdc); 999 if (rs != NPI_SUCCESS) { 1000 return (NXGE_ERROR | rs); 1001 } 1002 1003 /* 1004 * Configure the MAC host info table with RDC tables 1005 */ 1006 hostinfo.value = 0; 1007 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1008 for (i = 0; i < p_cfgp->max_macs; i++) { 1009 hostinfo.bits.w0.rdc_tbl_num = p_cfgp->def_mac_rxdma_grpid; 1010 hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref; 1011 if (p_class_cfgp->mac_host_info[i].flag) { 1012 hostinfo.bits.w0.rdc_tbl_num = 1013 p_class_cfgp->mac_host_info[i].rdctbl; 1014 hostinfo.bits.w0.mac_pref = 1015 p_class_cfgp->mac_host_info[i].mpr_npr; 1016 } 1017 1018 rs = npi_mac_hostinfo_entry(handle, OP_SET, 1019 nxgep->function_num, i, &hostinfo); 1020 if (rs != NPI_SUCCESS) 1021 return (NXGE_ERROR | rs); 1022 } 1023 1024 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1025 "<== nxge_init_fzc_rxdma_port rs 0x%08x", rs)); 1026 1027 return (NXGE_OK); 1028 1029 } 1030 1031 nxge_status_t 1032 nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc) 1033 { 1034 npi_status_t rs = NPI_SUCCESS; 1035 rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle, 1036 port, rdc); 1037 if (rs & NPI_FAILURE) 1038 return (NXGE_ERROR | rs); 1039 return (NXGE_OK); 1040 } 1041 1042 /* 1043 * nxge_init_fzc_tdc_pages 1044 * 1045 * Configure a TDC's logical pages. 1046 * 1047 * This function is executed by the service domain, on behalf of 1048 * a guest domain, to whom this TDC has been loaned. 1049 * 1050 * Arguments: 1051 * nxgep 1052 * channel The channel to initialize. 1053 * page0 Logical page 0 definition. 1054 * page1 Logical page 1 definition. 1055 * 1056 * Notes: 1057 * I think that this function can be called from any 1058 * domain, but I need to check. 1059 * 1060 * NPI/NXGE function calls: 1061 * hv_niu_tx_logical_page_conf() 1062 * hv_niu_tx_logical_page_info() 1063 * 1064 * Context: 1065 * Any domain 1066 */ 1067 nxge_status_t 1068 nxge_init_fzc_tdc_pages( 1069 p_nxge_t nxgep, 1070 uint16_t channel, 1071 dma_log_page_t *page0, 1072 dma_log_page_t *page1) 1073 { 1074 npi_handle_t handle; 1075 npi_status_t rs; 1076 1077 log_page_hdl_t page_handle; 1078 1079 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1080 "==> nxge_init_fzc_txdma_channel_pages")); 1081 1082 #ifndef NIU_HV_WORKAROUND 1083 if (nxgep->niu_type == N2_NIU) { 1084 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1085 "<== nxge_init_fzc_tdc_pages: " 1086 "N2_NIU: no need to set txdma logical pages")); 1087 return (NXGE_OK); 1088 } 1089 #else 1090 if (nxgep->niu_type == N2_NIU) { 1091 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1092 "<== nxge_init_fzc_tdc_pages: " 1093 "N2_NIU: NEED to set txdma logical pages")); 1094 } 1095 #endif 1096 1097 /* 1098 * Initialize logical page 1. 1099 */ 1100 handle = NXGE_DEV_NPI_HANDLE(nxgep); 1101 if ((rs = npi_txdma_log_page_set(handle, channel, page0)) 1102 != NPI_SUCCESS) 1103 return (NXGE_ERROR | rs); 1104 1105 /* 1106 * Initialize logical page 2. 1107 */ 1108 if ((rs = npi_txdma_log_page_set(handle, channel, page1)) 1109 != NPI_SUCCESS) 1110 return (NXGE_ERROR | rs); 1111 1112 /* 1113 * Initialize the page handle. 1114 * (In the current driver, this is always set to 0.) 1115 */ 1116 page_handle.value = 0; 1117 rs = npi_txdma_log_page_handle_set(handle, channel, &page_handle); 1118 if (rs == NPI_SUCCESS) { 1119 return (NXGE_OK); 1120 } else { 1121 return (NXGE_ERROR | rs); 1122 } 1123 } 1124 1125 nxge_status_t 1126 nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 1127 p_tx_ring_t tx_ring_p) 1128 { 1129 npi_handle_t handle; 1130 dma_log_page_t cfg; 1131 npi_status_t rs = NPI_SUCCESS; 1132 1133 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1134 "==> nxge_init_fzc_txdma_channel_pages")); 1135 1136 #ifndef NIU_HV_WORKAROUND 1137 if (nxgep->niu_type == N2_NIU) { 1138 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1139 "<== nxge_init_fzc_txdma_channel_pages: " 1140 "N2_NIU: no need to set txdma logical pages")); 1141 return (NXGE_OK); 1142 } 1143 #else 1144 if (nxgep->niu_type == N2_NIU) { 1145 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1146 "<== nxge_init_fzc_txdma_channel_pages: " 1147 "N2_NIU: NEED to set txdma logical pages")); 1148 } 1149 #endif 1150 1151 /* 1152 * Initialize logical page 1. 1153 */ 1154 handle = NXGE_DEV_NPI_HANDLE(nxgep); 1155 cfg.func_num = nxgep->function_num; 1156 cfg.page_num = 0; 1157 cfg.valid = tx_ring_p->page_valid.bits.ldw.page0; 1158 cfg.value = tx_ring_p->page_value_1.value; 1159 cfg.mask = tx_ring_p->page_mask_1.value; 1160 cfg.reloc = tx_ring_p->page_reloc_1.value; 1161 1162 rs = npi_txdma_log_page_set(handle, channel, 1163 (p_dma_log_page_t)&cfg); 1164 if (rs != NPI_SUCCESS) { 1165 return (NXGE_ERROR | rs); 1166 } 1167 1168 /* 1169 * Initialize logical page 2. 1170 */ 1171 cfg.page_num = 1; 1172 cfg.valid = tx_ring_p->page_valid.bits.ldw.page1; 1173 cfg.value = tx_ring_p->page_value_2.value; 1174 cfg.mask = tx_ring_p->page_mask_2.value; 1175 cfg.reloc = tx_ring_p->page_reloc_2.value; 1176 1177 rs = npi_txdma_log_page_set(handle, channel, &cfg); 1178 if (rs != NPI_SUCCESS) { 1179 return (NXGE_ERROR | rs); 1180 } 1181 1182 /* Initialize the page handle */ 1183 rs = npi_txdma_log_page_handle_set(handle, channel, 1184 &tx_ring_p->page_hdl); 1185 1186 if (rs == NPI_SUCCESS) { 1187 return (NXGE_OK); 1188 } else { 1189 return (NXGE_ERROR | rs); 1190 } 1191 } 1192 1193 1194 nxge_status_t 1195 nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel, 1196 p_tx_ring_t tx_ring_p) 1197 { 1198 npi_status_t rs = NPI_SUCCESS; 1199 npi_handle_t handle; 1200 1201 handle = NXGE_DEV_NPI_HANDLE(nxgep); 1202 rs = npi_txc_dma_max_burst_set(handle, channel, 1203 tx_ring_p->max_burst.value); 1204 if (rs == NPI_SUCCESS) { 1205 return (NXGE_OK); 1206 } else { 1207 return (NXGE_ERROR | rs); 1208 } 1209 } 1210 1211 nxge_status_t 1212 nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask) 1213 { 1214 npi_status_t rs = NPI_SUCCESS; 1215 npi_handle_t handle; 1216 1217 handle = NXGE_DEV_NPI_HANDLE(nxgep); 1218 rs = npi_fzc_sys_err_mask_set(handle, mask); 1219 if (rs == NPI_SUCCESS) { 1220 return (NXGE_OK); 1221 } else { 1222 return (NXGE_ERROR | rs); 1223 } 1224 } 1225 1226 /* 1227 * nxge_init_hv_fzc_txdma_channel_pages 1228 * 1229 * Configure a TDC's logical pages. 1230 * 1231 * Arguments: 1232 * nxgep 1233 * channel The channel to initialize. 1234 * tx_ring_p The transmit ring. 1235 * 1236 * Notes: 1237 * I think that this function can be called from any 1238 * domain, but I need to check. 1239 * 1240 * NPI/NXGE function calls: 1241 * hv_niu_tx_logical_page_conf() 1242 * hv_niu_tx_logical_page_info() 1243 * 1244 * Context: 1245 * Any domain 1246 */ 1247 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 1248 nxge_status_t 1249 nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 1250 p_tx_ring_t tx_ring_p) 1251 { 1252 int err; 1253 uint64_t hverr; 1254 #ifdef DEBUG 1255 uint64_t ra, size; 1256 #endif 1257 1258 NXGE_DEBUG_MSG((nxgep, TX_CTL, 1259 "==> nxge_init_hv_fzc_txdma_channel_pages")); 1260 1261 if (tx_ring_p->hv_set) { 1262 return (NXGE_OK); 1263 } 1264 1265 /* 1266 * Initialize logical page 1 for data buffers. 1267 */ 1268 hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 1269 (uint64_t)0, 1270 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 1271 tx_ring_p->hv_tx_buf_ioaddr_size); 1272 1273 err = (nxge_status_t)nxge_herr2kerr(hverr); 1274 if (err != 0) { 1275 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1276 "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d " 1277 "error status 0x%x " 1278 "(page 0 data buf) hverr 0x%llx " 1279 "ioaddr_pp $%p " 1280 "size 0x%llx ", 1281 channel, 1282 err, 1283 hverr, 1284 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 1285 tx_ring_p->hv_tx_buf_ioaddr_size)); 1286 return (NXGE_ERROR | err); 1287 } 1288 1289 #ifdef DEBUG 1290 ra = size = 0; 1291 hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 1292 (uint64_t)0, 1293 &ra, 1294 &size); 1295 1296 NXGE_DEBUG_MSG((nxgep, TX_CTL, 1297 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 1298 "ok status 0x%x " 1299 "(page 0 data buf) hverr 0x%llx " 1300 "set ioaddr_pp $%p " 1301 "set size 0x%llx " 1302 "get ra ioaddr_pp $%p " 1303 "get size 0x%llx ", 1304 channel, 1305 err, 1306 hverr, 1307 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 1308 tx_ring_p->hv_tx_buf_ioaddr_size, 1309 ra, 1310 size)); 1311 #endif 1312 1313 NXGE_DEBUG_MSG((nxgep, TX_CTL, 1314 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 1315 "(page 0 data buf) hverr 0x%llx " 1316 "ioaddr_pp $%p " 1317 "size 0x%llx ", 1318 channel, 1319 hverr, 1320 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 1321 tx_ring_p->hv_tx_buf_ioaddr_size)); 1322 1323 /* 1324 * Initialize logical page 2 for control buffers. 1325 */ 1326 hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 1327 (uint64_t)1, 1328 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 1329 tx_ring_p->hv_tx_cntl_ioaddr_size); 1330 1331 err = (nxge_status_t)nxge_herr2kerr(hverr); 1332 1333 NXGE_DEBUG_MSG((nxgep, TX_CTL, 1334 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d" 1335 "ok status 0x%x " 1336 "(page 1 cntl buf) hverr 0x%llx " 1337 "ioaddr_pp $%p " 1338 "size 0x%llx ", 1339 channel, 1340 err, 1341 hverr, 1342 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 1343 tx_ring_p->hv_tx_cntl_ioaddr_size)); 1344 1345 if (err != 0) { 1346 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1347 "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d" 1348 "error status 0x%x " 1349 "(page 1 cntl buf) hverr 0x%llx " 1350 "ioaddr_pp $%p " 1351 "size 0x%llx ", 1352 channel, 1353 err, 1354 hverr, 1355 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 1356 tx_ring_p->hv_tx_cntl_ioaddr_size)); 1357 return (NXGE_ERROR | err); 1358 } 1359 1360 #ifdef DEBUG 1361 ra = size = 0; 1362 hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 1363 (uint64_t)1, 1364 &ra, 1365 &size); 1366 1367 NXGE_DEBUG_MSG((nxgep, TX_CTL, 1368 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 1369 "(page 1 cntl buf) hverr 0x%llx " 1370 "set ioaddr_pp $%p " 1371 "set size 0x%llx " 1372 "get ra ioaddr_pp $%p " 1373 "get size 0x%llx ", 1374 channel, 1375 hverr, 1376 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 1377 tx_ring_p->hv_tx_cntl_ioaddr_size, 1378 ra, 1379 size)); 1380 #endif 1381 1382 tx_ring_p->hv_set = B_TRUE; 1383 1384 NXGE_DEBUG_MSG((nxgep, TX_CTL, 1385 "<== nxge_init_hv_fzc_txdma_channel_pages")); 1386 1387 return (NXGE_OK); 1388 } 1389 1390 /*ARGSUSED*/ 1391 nxge_status_t 1392 nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep, 1393 uint16_t channel, p_rx_rbr_ring_t rbrp) 1394 { 1395 int err; 1396 uint64_t hverr; 1397 #ifdef DEBUG 1398 uint64_t ra, size; 1399 #endif 1400 1401 NXGE_DEBUG_MSG((nxgep, RX_CTL, 1402 "==> nxge_init_hv_fzc_rxdma_channel_pages")); 1403 1404 if (rbrp->hv_set) { 1405 return (NXGE_OK); 1406 } 1407 1408 /* Initialize data buffers for page 0 */ 1409 hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 1410 (uint64_t)0, 1411 rbrp->hv_rx_buf_base_ioaddr_pp, 1412 rbrp->hv_rx_buf_ioaddr_size); 1413 err = (nxge_status_t)nxge_herr2kerr(hverr); 1414 if (err != 0) { 1415 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1416 "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 1417 "error status 0x%x " 1418 "(page 0 data buf) hverr 0x%llx " 1419 "ioaddr_pp $%p " 1420 "size 0x%llx ", 1421 channel, 1422 err, 1423 hverr, 1424 rbrp->hv_rx_buf_base_ioaddr_pp, 1425 rbrp->hv_rx_buf_ioaddr_size)); 1426 1427 return (NXGE_ERROR | err); 1428 } 1429 1430 #ifdef DEBUG 1431 ra = size = 0; 1432 (void) hv_niu_rx_logical_page_info((uint64_t)channel, 1433 (uint64_t)0, 1434 &ra, 1435 &size); 1436 1437 NXGE_DEBUG_MSG((nxgep, RX_CTL, 1438 "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 1439 "ok status 0x%x " 1440 "(page 0 data buf) hverr 0x%llx " 1441 "set databuf ioaddr_pp $%p " 1442 "set databuf size 0x%llx " 1443 "get databuf ra ioaddr_pp %p " 1444 "get databuf size 0x%llx", 1445 channel, 1446 err, 1447 hverr, 1448 rbrp->hv_rx_buf_base_ioaddr_pp, 1449 rbrp->hv_rx_buf_ioaddr_size, 1450 ra, 1451 size)); 1452 #endif 1453 1454 /* Initialize control buffers for logical page 1. */ 1455 hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 1456 (uint64_t)1, 1457 rbrp->hv_rx_cntl_base_ioaddr_pp, 1458 rbrp->hv_rx_cntl_ioaddr_size); 1459 1460 err = (nxge_status_t)nxge_herr2kerr(hverr); 1461 if (err != 0) { 1462 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1463 "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 1464 "error status 0x%x " 1465 "(page 1 cntl buf) hverr 0x%llx " 1466 "ioaddr_pp $%p " 1467 "size 0x%llx ", 1468 channel, 1469 err, 1470 hverr, 1471 rbrp->hv_rx_buf_base_ioaddr_pp, 1472 rbrp->hv_rx_buf_ioaddr_size)); 1473 1474 return (NXGE_ERROR | err); 1475 } 1476 1477 #ifdef DEBUG 1478 ra = size = 0; 1479 (void) hv_niu_rx_logical_page_info((uint64_t)channel, 1480 (uint64_t)1, 1481 &ra, 1482 &size); 1483 1484 1485 NXGE_DEBUG_MSG((nxgep, RX_CTL, 1486 "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 1487 "error status 0x%x " 1488 "(page 1 cntl buf) hverr 0x%llx " 1489 "set cntl ioaddr_pp $%p " 1490 "set cntl size 0x%llx " 1491 "get cntl ioaddr_pp $%p " 1492 "get cntl size 0x%llx ", 1493 channel, 1494 err, 1495 hverr, 1496 rbrp->hv_rx_cntl_base_ioaddr_pp, 1497 rbrp->hv_rx_cntl_ioaddr_size, 1498 ra, 1499 size)); 1500 #endif 1501 1502 rbrp->hv_set = B_FALSE; 1503 1504 NXGE_DEBUG_MSG((nxgep, RX_CTL, 1505 "<== nxge_init_hv_fzc_rxdma_channel_pages")); 1506 1507 return (NXGE_OK); 1508 } 1509 1510 /* 1511 * Map hypervisor error code to errno. Only 1512 * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful 1513 * for niu driver. Any other error codes are mapped to EINVAL. 1514 */ 1515 static int 1516 nxge_herr2kerr(uint64_t hv_errcode) 1517 { 1518 int s_errcode; 1519 1520 switch (hv_errcode) { 1521 case H_ENORADDR: 1522 case H_EBADALIGN: 1523 s_errcode = EFAULT; 1524 break; 1525 case H_EOK: 1526 s_errcode = 0; 1527 break; 1528 default: 1529 s_errcode = EINVAL; 1530 break; 1531 } 1532 return (s_errcode); 1533 } 1534 1535 #endif /* sun4v and NIU_LP_WORKAROUND */ 1536