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