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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <nxge_impl.h> 29 #include <npi_mac.h> 30 #include <npi_rxdma.h> 31 32 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 33 static int nxge_herr2kerr(uint64_t); 34 #endif 35 36 /* 37 * The following interfaces are controlled by the 38 * function control registers. Some global registers 39 * are to be initialized by only byt one of the 2/4 functions. 40 * Use the test and set register. 41 */ 42 /*ARGSUSED*/ 43 nxge_status_t 44 nxge_test_and_set(p_nxge_t nxgep, uint8_t tas) 45 { 46 npi_handle_t handle; 47 npi_status_t rs = NPI_SUCCESS; 48 49 handle = NXGE_DEV_NPI_HANDLE(nxgep); 50 if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas)) 51 != NPI_SUCCESS) { 52 return (NXGE_ERROR | rs); 53 } 54 55 return (NXGE_OK); 56 } 57 58 nxge_status_t 59 nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc) 60 { 61 npi_handle_t handle; 62 npi_status_t rs = NPI_SUCCESS; 63 64 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl")); 65 66 /* 67 * In multi-partitioning, the partition manager 68 * who owns function zero should set this multi-partition 69 * control bit. 70 */ 71 if (nxgep->use_partition && nxgep->function_num) { 72 return (NXGE_ERROR); 73 } 74 75 handle = NXGE_DEV_NPI_HANDLE(nxgep); 76 if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) { 77 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 78 "<== nxge_set_fzc_multi_part_ctl")); 79 return (NXGE_ERROR | rs); 80 } 81 82 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl")); 83 84 return (NXGE_OK); 85 } 86 87 nxge_status_t 88 nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p) 89 { 90 npi_handle_t handle; 91 npi_status_t rs = NPI_SUCCESS; 92 93 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl")); 94 95 handle = NXGE_DEV_NPI_HANDLE(nxgep); 96 if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) { 97 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 98 "<== nxge_set_fzc_multi_part_ctl")); 99 return (NXGE_ERROR | rs); 100 } 101 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl")); 102 103 return (NXGE_OK); 104 } 105 106 /* 107 * System interrupt registers that are under function zero 108 * management. 109 */ 110 nxge_status_t 111 nxge_fzc_intr_init(p_nxge_t nxgep) 112 { 113 nxge_status_t status = NXGE_OK; 114 115 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init")); 116 117 /* Configure the initial timer resolution */ 118 if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) { 119 return (status); 120 } 121 122 switch (nxgep->niu_type) { 123 case NEPTUNE: 124 case NEPTUNE_2: 125 /* 126 * Set up the logical device group's logical devices that 127 * the group owns. 128 */ 129 if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) 130 != NXGE_OK) { 131 break; 132 } 133 134 /* Configure the system interrupt data */ 135 if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK) { 136 break; 137 } 138 139 break; 140 } 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 * Receive DMA registers that are under function zero 262 * management. 263 */ 264 /*ARGSUSED*/ 265 nxge_status_t 266 nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel, 267 p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p) 268 { 269 nxge_status_t status = NXGE_OK; 270 NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel")); 271 272 switch (nxgep->niu_type) { 273 case NEPTUNE: 274 case NEPTUNE_2: 275 default: 276 /* Initialize the RXDMA logical pages */ 277 status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel, 278 rbr_p); 279 if (status != NXGE_OK) { 280 return (status); 281 } 282 283 break; 284 285 #ifndef NIU_HV_WORKAROUND 286 case N2_NIU: 287 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 288 NXGE_DEBUG_MSG((nxgep, RX_CTL, 289 "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV " 290 "set up logical pages")); 291 /* Initialize the RXDMA logical pages */ 292 status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel, 293 rbr_p); 294 if (status != NXGE_OK) { 295 return (status); 296 } 297 #endif 298 break; 299 #else 300 case N2_NIU: 301 NXGE_DEBUG_MSG((nxgep, RX_CTL, 302 "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to " 303 "set up logical pages")); 304 /* Initialize the RXDMA logical pages */ 305 status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel, 306 rbr_p); 307 if (status != NXGE_OK) { 308 return (status); 309 } 310 311 break; 312 #endif 313 } 314 315 /* Configure RED parameters */ 316 status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_p); 317 318 NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel")); 319 return (status); 320 } 321 322 /*ARGSUSED*/ 323 nxge_status_t 324 nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep, 325 uint16_t channel, p_rx_rbr_ring_t rbrp) 326 { 327 npi_handle_t handle; 328 dma_log_page_t cfg; 329 npi_status_t rs = NPI_SUCCESS; 330 331 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 332 "==> nxge_init_fzc_rxdma_channel_pages")); 333 334 handle = NXGE_DEV_NPI_HANDLE(nxgep); 335 /* 336 * Initialize logical page 1. 337 */ 338 cfg.func_num = nxgep->function_num; 339 cfg.page_num = 0; 340 cfg.valid = rbrp->page_valid.bits.ldw.page0; 341 cfg.value = rbrp->page_value_1.value; 342 cfg.mask = rbrp->page_mask_1.value; 343 cfg.reloc = rbrp->page_reloc_1.value; 344 rs = npi_rxdma_cfg_logical_page(handle, channel, 345 (p_dma_log_page_t)&cfg); 346 if (rs != NPI_SUCCESS) { 347 return (NXGE_ERROR | rs); 348 } 349 350 /* 351 * Initialize logical page 2. 352 */ 353 cfg.page_num = 1; 354 cfg.valid = rbrp->page_valid.bits.ldw.page1; 355 cfg.value = rbrp->page_value_2.value; 356 cfg.mask = rbrp->page_mask_2.value; 357 cfg.reloc = rbrp->page_reloc_2.value; 358 359 rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg); 360 if (rs != NPI_SUCCESS) { 361 return (NXGE_ERROR | rs); 362 } 363 364 /* Initialize the page handle */ 365 rs = npi_rxdma_cfg_logical_page_handle(handle, channel, 366 rbrp->page_hdl.bits.ldw.handle); 367 368 if (rs != NPI_SUCCESS) { 369 return (NXGE_ERROR | rs); 370 } 371 372 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 373 "<== nxge_init_fzc_rxdma_channel_pages")); 374 375 return (NXGE_OK); 376 } 377 378 /*ARGSUSED*/ 379 nxge_status_t 380 nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep, 381 uint16_t channel, p_rx_rcr_ring_t rcr_p) 382 { 383 npi_handle_t handle; 384 rdc_red_para_t red; 385 npi_status_t rs = NPI_SUCCESS; 386 387 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red")); 388 389 handle = NXGE_DEV_NPI_HANDLE(nxgep); 390 red.value = 0; 391 red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT; 392 red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 393 red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT; 394 red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 395 396 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 397 "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))", 398 red.bits.ldw.thre_sync, 399 red.bits.ldw.thre_sync)); 400 401 rs = npi_rxdma_cfg_wred_param(handle, channel, &red); 402 if (rs != NPI_SUCCESS) { 403 return (NXGE_ERROR | rs); 404 } 405 406 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 407 "<== nxge_init_fzc_rxdma_channel_red")); 408 409 return (NXGE_OK); 410 } 411 412 /*ARGSUSED*/ 413 nxge_status_t 414 nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel, 415 p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p) 416 { 417 nxge_status_t status = NXGE_OK; 418 419 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 420 "==> nxge_init_fzc_txdma_channel")); 421 422 switch (nxgep->niu_type) { 423 case NEPTUNE: 424 case NEPTUNE_2: 425 default: 426 /* Initialize the TXDMA logical pages */ 427 (void) nxge_init_fzc_txdma_channel_pages(nxgep, channel, 428 tx_ring_p); 429 break; 430 431 #ifndef NIU_HV_WORKAROUND 432 case N2_NIU: 433 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 434 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 435 "==> nxge_init_fzc_txdma_channel " 436 "N2_NIU: call HV to set up txdma logical pages")); 437 status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel, 438 tx_ring_p); 439 if (status != NXGE_OK) { 440 return (status); 441 } 442 #endif 443 break; 444 #else 445 case N2_NIU: 446 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 447 "==> nxge_init_fzc_txdma_channel " 448 "N2_NIU: NEED to set up txdma logical pages")); 449 /* Initialize the TXDMA logical pages */ 450 (void) nxge_init_fzc_txdma_channel_pages(nxgep, channel, 451 tx_ring_p); 452 break; 453 #endif 454 } 455 456 /* 457 * Configure Transmit DRR Weight parameters 458 * (It actually programs the TXC max burst register). 459 */ 460 (void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p); 461 462 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 463 "<== nxge_init_fzc_txdma_channel")); 464 return (status); 465 } 466 467 nxge_status_t 468 nxge_init_fzc_common(p_nxge_t nxgep) 469 { 470 nxge_status_t status = NXGE_OK; 471 472 (void) nxge_init_fzc_rx_common(nxgep); 473 474 return (status); 475 } 476 477 nxge_status_t 478 nxge_init_fzc_rx_common(p_nxge_t nxgep) 479 { 480 npi_handle_t handle; 481 npi_status_t rs = NPI_SUCCESS; 482 nxge_status_t status = NXGE_OK; 483 clock_t lbolt; 484 485 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common")); 486 handle = NXGE_DEV_NPI_HANDLE(nxgep); 487 if (!handle.regp) { 488 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 489 "==> nxge_init_fzc_rx_common null ptr")); 490 return (NXGE_ERROR); 491 } 492 493 /* 494 * Configure the rxdma clock divider 495 * This is the granularity counter based on 496 * the hardware system clock (i.e. 300 Mhz) and 497 * it is running around 3 nanoseconds. 498 * So, set the clock divider counter to 1000 to get 499 * microsecond granularity. 500 * For example, for a 3 microsecond timeout, the timeout 501 * will be set to 1. 502 */ 503 rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT); 504 if (rs != NPI_SUCCESS) 505 return (NXGE_ERROR | rs); 506 507 #if defined(__i386) 508 rs = npi_rxdma_cfg_32bitmode_enable(handle); 509 if (rs != NPI_SUCCESS) 510 return (NXGE_ERROR | rs); 511 rs = npi_txdma_mode32_set(handle, B_TRUE); 512 if (rs != NPI_SUCCESS) 513 return (NXGE_ERROR | rs); 514 #endif 515 516 /* 517 * Enable WRED and program an initial value. 518 * Use time to set the initial random number. 519 */ 520 (void) drv_getparm(LBOLT, &lbolt); 521 rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt); 522 if (rs != NPI_SUCCESS) 523 return (NXGE_ERROR | rs); 524 525 /* Initialize the RDC tables for each group */ 526 status = nxge_init_fzc_rdc_tbl(nxgep); 527 528 529 /* Ethernet Timeout Counter (?) */ 530 531 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 532 "<== nxge_init_fzc_rx_common:status 0x%08x", status)); 533 534 return (status); 535 } 536 537 nxge_status_t 538 nxge_init_fzc_rdc_tbl(p_nxge_t nxgep) 539 { 540 npi_handle_t handle; 541 p_nxge_dma_pt_cfg_t p_dma_cfgp; 542 p_nxge_hw_pt_cfg_t p_cfgp; 543 p_nxge_rdc_grp_t rdc_grp_p; 544 uint8_t grp_tbl_id; 545 int ngrps; 546 int i; 547 npi_status_t rs = NPI_SUCCESS; 548 nxge_status_t status = NXGE_OK; 549 550 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rdc_tbl")); 551 552 handle = NXGE_DEV_NPI_HANDLE(nxgep); 553 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 554 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 555 556 grp_tbl_id = p_cfgp->start_rdc_grpid; 557 rdc_grp_p = &p_dma_cfgp->rdc_grps[0]; 558 ngrps = p_cfgp->max_rdc_grpids; 559 for (i = 0; i < ngrps; i++, rdc_grp_p++) { 560 rs = npi_rxdma_cfg_rdc_table(handle, grp_tbl_id++, 561 rdc_grp_p->rdc); 562 if (rs != NPI_SUCCESS) { 563 status = NXGE_ERROR | rs; 564 break; 565 } 566 } 567 568 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc_tbl")); 569 return (status); 570 } 571 572 nxge_status_t 573 nxge_init_fzc_rxdma_port(p_nxge_t nxgep) 574 { 575 npi_handle_t handle; 576 p_nxge_dma_pt_cfg_t p_all_cfgp; 577 p_nxge_hw_pt_cfg_t p_cfgp; 578 hostinfo_t hostinfo; 579 int i; 580 npi_status_t rs = NPI_SUCCESS; 581 p_nxge_class_pt_cfg_t p_class_cfgp; 582 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port")); 583 584 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 585 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 586 handle = NXGE_DEV_NPI_HANDLE(nxgep); 587 /* 588 * Initialize the port scheduler DRR weight. 589 * npi_rxdma_cfg_port_ddr_weight(); 590 */ 591 592 if (nxgep->niu_type == NEPTUNE) { 593 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 594 (nxgep->mac.portmode == PORT_1G_FIBER)) { 595 rs = npi_rxdma_cfg_port_ddr_weight(handle, 596 nxgep->function_num, 597 NXGE_RX_DRR_WT_1G); 598 if (rs != NPI_SUCCESS) { 599 return (NXGE_ERROR | rs); 600 } 601 } 602 } 603 604 /* Program the default RDC of a port */ 605 rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num, 606 p_cfgp->def_rdc); 607 if (rs != NPI_SUCCESS) { 608 return (NXGE_ERROR | rs); 609 } 610 611 /* 612 * Configure the MAC host info table with RDC tables 613 */ 614 hostinfo.value = 0; 615 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 616 for (i = 0; i < p_cfgp->max_macs; i++) { 617 hostinfo.bits.w0.rdc_tbl_num = p_cfgp->start_rdc_grpid; 618 hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref; 619 if (p_class_cfgp->mac_host_info[i].flag) { 620 hostinfo.bits.w0.rdc_tbl_num = 621 p_class_cfgp->mac_host_info[i].rdctbl; 622 hostinfo.bits.w0.mac_pref = 623 p_class_cfgp->mac_host_info[i].mpr_npr; 624 } 625 626 rs = npi_mac_hostinfo_entry(handle, OP_SET, 627 nxgep->function_num, i, &hostinfo); 628 if (rs != NPI_SUCCESS) 629 return (NXGE_ERROR | rs); 630 } 631 632 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 633 "<== nxge_init_fzc_rxdma_port rs 0x%08x", rs)); 634 635 return (NXGE_OK); 636 637 } 638 639 nxge_status_t 640 nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc) 641 { 642 npi_status_t rs = NPI_SUCCESS; 643 rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle, 644 port, rdc); 645 if (rs & NPI_FAILURE) 646 return (NXGE_ERROR | rs); 647 return (NXGE_OK); 648 } 649 650 nxge_status_t 651 nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 652 p_tx_ring_t tx_ring_p) 653 { 654 npi_handle_t handle; 655 dma_log_page_t cfg; 656 npi_status_t rs = NPI_SUCCESS; 657 658 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 659 "==> nxge_init_fzc_txdma_channel_pages")); 660 661 #ifndef NIU_HV_WORKAROUND 662 if (nxgep->niu_type == N2_NIU) { 663 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 664 "<== nxge_init_fzc_txdma_channel_pages: " 665 "N2_NIU: no need to set txdma logical pages")); 666 return (NXGE_OK); 667 } 668 #else 669 if (nxgep->niu_type == N2_NIU) { 670 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 671 "<== nxge_init_fzc_txdma_channel_pages: " 672 "N2_NIU: NEED to set txdma logical pages")); 673 } 674 #endif 675 676 /* 677 * Initialize logical page 1. 678 */ 679 handle = NXGE_DEV_NPI_HANDLE(nxgep); 680 cfg.func_num = nxgep->function_num; 681 cfg.page_num = 0; 682 cfg.valid = tx_ring_p->page_valid.bits.ldw.page0; 683 cfg.value = tx_ring_p->page_value_1.value; 684 cfg.mask = tx_ring_p->page_mask_1.value; 685 cfg.reloc = tx_ring_p->page_reloc_1.value; 686 687 rs = npi_txdma_log_page_set(handle, channel, 688 (p_dma_log_page_t)&cfg); 689 if (rs != NPI_SUCCESS) { 690 return (NXGE_ERROR | rs); 691 } 692 693 /* 694 * Initialize logical page 2. 695 */ 696 cfg.page_num = 1; 697 cfg.valid = tx_ring_p->page_valid.bits.ldw.page1; 698 cfg.value = tx_ring_p->page_value_2.value; 699 cfg.mask = tx_ring_p->page_mask_2.value; 700 cfg.reloc = tx_ring_p->page_reloc_2.value; 701 702 rs = npi_txdma_log_page_set(handle, channel, &cfg); 703 if (rs != NPI_SUCCESS) { 704 return (NXGE_ERROR | rs); 705 } 706 707 /* Initialize the page handle */ 708 rs = npi_txdma_log_page_handle_set(handle, channel, 709 &tx_ring_p->page_hdl); 710 711 if (rs == NPI_SUCCESS) { 712 return (NXGE_OK); 713 } else { 714 return (NXGE_ERROR | rs); 715 } 716 } 717 718 719 nxge_status_t 720 nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel, 721 p_tx_ring_t tx_ring_p) 722 { 723 npi_status_t rs = NPI_SUCCESS; 724 npi_handle_t handle; 725 726 handle = NXGE_DEV_NPI_HANDLE(nxgep); 727 rs = npi_txc_dma_max_burst_set(handle, channel, 728 tx_ring_p->max_burst.value); 729 if (rs == NPI_SUCCESS) { 730 return (NXGE_OK); 731 } else { 732 return (NXGE_ERROR | rs); 733 } 734 } 735 736 nxge_status_t 737 nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask) 738 { 739 npi_status_t rs = NPI_SUCCESS; 740 npi_handle_t handle; 741 742 handle = NXGE_DEV_NPI_HANDLE(nxgep); 743 rs = npi_fzc_sys_err_mask_set(handle, mask); 744 if (rs == NPI_SUCCESS) { 745 return (NXGE_OK); 746 } else { 747 return (NXGE_ERROR | rs); 748 } 749 } 750 751 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 752 nxge_status_t 753 nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 754 p_tx_ring_t tx_ring_p) 755 { 756 int err; 757 uint64_t hverr; 758 #ifdef DEBUG 759 uint64_t ra, size; 760 #endif 761 762 NXGE_DEBUG_MSG((nxgep, TX_CTL, 763 "==> nxge_init_hv_fzc_txdma_channel_pages")); 764 765 if (tx_ring_p->hv_set) { 766 return (NXGE_OK); 767 } 768 769 /* 770 * Initialize logical page 1 for data buffers. 771 */ 772 hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 773 (uint64_t)0, 774 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 775 tx_ring_p->hv_tx_buf_ioaddr_size); 776 777 err = (nxge_status_t)nxge_herr2kerr(hverr); 778 if (err != 0) { 779 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 780 "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d " 781 "error status 0x%x " 782 "(page 0 data buf) hverr 0x%llx " 783 "ioaddr_pp $%p " 784 "size 0x%llx ", 785 channel, 786 err, 787 hverr, 788 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 789 tx_ring_p->hv_tx_buf_ioaddr_size)); 790 return (NXGE_ERROR | err); 791 } 792 793 #ifdef DEBUG 794 ra = size = 0; 795 hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 796 (uint64_t)0, 797 &ra, 798 &size); 799 800 NXGE_DEBUG_MSG((nxgep, TX_CTL, 801 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 802 "ok status 0x%x " 803 "(page 0 data buf) hverr 0x%llx " 804 "set ioaddr_pp $%p " 805 "set size 0x%llx " 806 "get ra ioaddr_pp $%p " 807 "get size 0x%llx ", 808 channel, 809 err, 810 hverr, 811 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 812 tx_ring_p->hv_tx_buf_ioaddr_size, 813 ra, 814 size)); 815 #endif 816 817 NXGE_DEBUG_MSG((nxgep, TX_CTL, 818 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 819 "(page 0 data buf) hverr 0x%llx " 820 "ioaddr_pp $%p " 821 "size 0x%llx ", 822 channel, 823 hverr, 824 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 825 tx_ring_p->hv_tx_buf_ioaddr_size)); 826 827 /* 828 * Initialize logical page 2 for control buffers. 829 */ 830 hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 831 (uint64_t)1, 832 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 833 tx_ring_p->hv_tx_cntl_ioaddr_size); 834 835 err = (nxge_status_t)nxge_herr2kerr(hverr); 836 837 NXGE_DEBUG_MSG((nxgep, TX_CTL, 838 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d" 839 "ok status 0x%x " 840 "(page 1 cntl buf) hverr 0x%llx " 841 "ioaddr_pp $%p " 842 "size 0x%llx ", 843 channel, 844 err, 845 hverr, 846 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 847 tx_ring_p->hv_tx_cntl_ioaddr_size)); 848 849 if (err != 0) { 850 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 851 "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d" 852 "error status 0x%x " 853 "(page 1 cntl buf) hverr 0x%llx " 854 "ioaddr_pp $%p " 855 "size 0x%llx ", 856 channel, 857 err, 858 hverr, 859 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 860 tx_ring_p->hv_tx_cntl_ioaddr_size)); 861 return (NXGE_ERROR | err); 862 } 863 864 #ifdef DEBUG 865 ra = size = 0; 866 hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 867 (uint64_t)1, 868 &ra, 869 &size); 870 871 NXGE_DEBUG_MSG((nxgep, TX_CTL, 872 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 873 "(page 1 cntl buf) hverr 0x%llx " 874 "set ioaddr_pp $%p " 875 "set size 0x%llx " 876 "get ra ioaddr_pp $%p " 877 "get size 0x%llx ", 878 channel, 879 hverr, 880 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 881 tx_ring_p->hv_tx_cntl_ioaddr_size, 882 ra, 883 size)); 884 #endif 885 886 tx_ring_p->hv_set = B_TRUE; 887 888 NXGE_DEBUG_MSG((nxgep, TX_CTL, 889 "<== nxge_init_hv_fzc_txdma_channel_pages")); 890 891 return (NXGE_OK); 892 } 893 894 /*ARGSUSED*/ 895 nxge_status_t 896 nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep, 897 uint16_t channel, p_rx_rbr_ring_t rbrp) 898 { 899 int err; 900 uint64_t hverr; 901 #ifdef DEBUG 902 uint64_t ra, size; 903 #endif 904 905 NXGE_DEBUG_MSG((nxgep, RX_CTL, 906 "==> nxge_init_hv_fzc_rxdma_channel_pages")); 907 908 if (rbrp->hv_set) { 909 return (NXGE_OK); 910 } 911 912 /* Initialize data buffers for page 0 */ 913 hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 914 (uint64_t)0, 915 rbrp->hv_rx_buf_base_ioaddr_pp, 916 rbrp->hv_rx_buf_ioaddr_size); 917 err = (nxge_status_t)nxge_herr2kerr(hverr); 918 if (err != 0) { 919 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 920 "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 921 "error status 0x%x " 922 "(page 0 data buf) hverr 0x%llx " 923 "ioaddr_pp $%p " 924 "size 0x%llx ", 925 channel, 926 err, 927 hverr, 928 rbrp->hv_rx_buf_base_ioaddr_pp, 929 rbrp->hv_rx_buf_ioaddr_size)); 930 931 return (NXGE_ERROR | err); 932 } 933 934 #ifdef DEBUG 935 ra = size = 0; 936 (void) hv_niu_rx_logical_page_info((uint64_t)channel, 937 (uint64_t)0, 938 &ra, 939 &size); 940 941 NXGE_DEBUG_MSG((nxgep, RX_CTL, 942 "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 943 "ok status 0x%x " 944 "(page 0 data buf) hverr 0x%llx " 945 "set databuf ioaddr_pp $%p " 946 "set databuf size 0x%llx " 947 "get databuf ra ioaddr_pp %p " 948 "get databuf size 0x%llx", 949 channel, 950 err, 951 hverr, 952 rbrp->hv_rx_buf_base_ioaddr_pp, 953 rbrp->hv_rx_buf_ioaddr_size, 954 ra, 955 size)); 956 #endif 957 958 /* Initialize control buffers for logical page 1. */ 959 hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 960 (uint64_t)1, 961 rbrp->hv_rx_cntl_base_ioaddr_pp, 962 rbrp->hv_rx_cntl_ioaddr_size); 963 964 err = (nxge_status_t)nxge_herr2kerr(hverr); 965 if (err != 0) { 966 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 967 "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 968 "error status 0x%x " 969 "(page 1 cntl buf) hverr 0x%llx " 970 "ioaddr_pp $%p " 971 "size 0x%llx ", 972 channel, 973 err, 974 hverr, 975 rbrp->hv_rx_buf_base_ioaddr_pp, 976 rbrp->hv_rx_buf_ioaddr_size)); 977 978 return (NXGE_ERROR | err); 979 } 980 981 #ifdef DEBUG 982 ra = size = 0; 983 (void) hv_niu_rx_logical_page_info((uint64_t)channel, 984 (uint64_t)1, 985 &ra, 986 &size); 987 988 989 NXGE_DEBUG_MSG((nxgep, RX_CTL, 990 "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 991 "error status 0x%x " 992 "(page 1 cntl buf) hverr 0x%llx " 993 "set cntl ioaddr_pp $%p " 994 "set cntl size 0x%llx " 995 "get cntl ioaddr_pp $%p " 996 "get cntl size 0x%llx ", 997 channel, 998 err, 999 hverr, 1000 rbrp->hv_rx_cntl_base_ioaddr_pp, 1001 rbrp->hv_rx_cntl_ioaddr_size, 1002 ra, 1003 size)); 1004 #endif 1005 1006 rbrp->hv_set = B_FALSE; 1007 1008 NXGE_DEBUG_MSG((nxgep, RX_CTL, 1009 "<== nxge_init_hv_fzc_rxdma_channel_pages")); 1010 1011 return (NXGE_OK); 1012 } 1013 1014 /* 1015 * Map hypervisor error code to errno. Only 1016 * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful 1017 * for niu driver. Any other error codes are mapped to EINVAL. 1018 */ 1019 static int 1020 nxge_herr2kerr(uint64_t hv_errcode) 1021 { 1022 int s_errcode; 1023 1024 switch (hv_errcode) { 1025 case H_ENORADDR: 1026 case H_EBADALIGN: 1027 s_errcode = EFAULT; 1028 break; 1029 case H_EOK: 1030 s_errcode = 0; 1031 break; 1032 default: 1033 s_errcode = EINVAL; 1034 break; 1035 } 1036 return (s_errcode); 1037 } 1038 1039 #endif /* sun4v and NIU_LP_WORKAROUND */ 1040