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