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 2007 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 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 123 /* 124 * Set up the logical device group's logical devices that 125 * the group owns. 126 */ 127 if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK) 128 goto fzc_intr_init_exit; 129 130 /* Configure the system interrupt data */ 131 if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK) 132 goto fzc_intr_init_exit; 133 } 134 135 fzc_intr_init_exit: 136 137 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init")); 138 139 return (status); 140 } 141 142 nxge_status_t 143 nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep) 144 { 145 p_nxge_ldg_t ldgp; 146 p_nxge_ldv_t ldvp; 147 npi_handle_t handle; 148 int i, j; 149 npi_status_t rs = NPI_SUCCESS; 150 151 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set")); 152 153 if (nxgep->ldgvp == NULL) { 154 return (NXGE_ERROR); 155 } 156 157 ldgp = nxgep->ldgvp->ldgp; 158 ldvp = nxgep->ldgvp->ldvp; 159 if (ldgp == NULL || ldvp == NULL) { 160 return (NXGE_ERROR); 161 } 162 163 handle = NXGE_DEV_NPI_HANDLE(nxgep); 164 165 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 166 NXGE_DEBUG_MSG((nxgep, INT_CTL, 167 "==> nxge_fzc_intr_ldg_num_set " 168 "<== nxge_f(Neptune): # ldv %d " 169 "in group %d", ldgp->nldvs, ldgp->ldg)); 170 171 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 172 rs = npi_fzc_ldg_num_set(handle, ldvp->ldv, 173 ldvp->ldg_assigned); 174 if (rs != NPI_SUCCESS) { 175 NXGE_DEBUG_MSG((nxgep, INT_CTL, 176 "<== nxge_fzc_intr_ldg_num_set failed " 177 " rs 0x%x ldv %d ldg %d", 178 rs, ldvp->ldv, ldvp->ldg_assigned)); 179 return (NXGE_ERROR | rs); 180 } 181 NXGE_DEBUG_MSG((nxgep, INT_CTL, 182 "<== nxge_fzc_intr_ldg_num_set OK " 183 " ldv %d ldg %d", 184 ldvp->ldv, ldvp->ldg_assigned)); 185 } 186 } 187 188 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set")); 189 190 return (NXGE_OK); 191 } 192 193 nxge_status_t 194 nxge_fzc_intr_tmres_set(p_nxge_t nxgep) 195 { 196 npi_handle_t handle; 197 npi_status_t rs = NPI_SUCCESS; 198 199 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set")); 200 if (nxgep->ldgvp == NULL) { 201 return (NXGE_ERROR); 202 } 203 handle = NXGE_DEV_NPI_HANDLE(nxgep); 204 if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) { 205 return (NXGE_ERROR | rs); 206 } 207 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set")); 208 209 return (NXGE_OK); 210 } 211 212 nxge_status_t 213 nxge_fzc_intr_sid_set(p_nxge_t nxgep) 214 { 215 npi_handle_t handle; 216 p_nxge_ldg_t ldgp; 217 fzc_sid_t sid; 218 int i; 219 npi_status_t rs = NPI_SUCCESS; 220 221 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set")); 222 if (nxgep->ldgvp == NULL) { 223 NXGE_DEBUG_MSG((nxgep, INT_CTL, 224 "<== nxge_fzc_intr_sid_set: no ldg")); 225 return (NXGE_ERROR); 226 } 227 handle = NXGE_DEV_NPI_HANDLE(nxgep); 228 ldgp = nxgep->ldgvp->ldgp; 229 NXGE_DEBUG_MSG((nxgep, INT_CTL, 230 "==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs)); 231 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 232 sid.ldg = ldgp->ldg; 233 sid.niu = B_FALSE; 234 sid.func = ldgp->func; 235 sid.vector = ldgp->vector; 236 NXGE_DEBUG_MSG((nxgep, INT_CTL, 237 "==> nxge_fzc_intr_sid_set(%d): func %d group %d " 238 "vector %d", 239 i, sid.func, sid.ldg, sid.vector)); 240 rs = npi_fzc_sid_set(handle, sid); 241 if (rs != NPI_SUCCESS) { 242 NXGE_DEBUG_MSG((nxgep, INT_CTL, 243 "<== nxge_fzc_intr_sid_set:failed 0x%x", 244 rs)); 245 return (NXGE_ERROR | rs); 246 } 247 } 248 249 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set")); 250 251 return (NXGE_OK); 252 253 } 254 255 /* 256 * Receive DMA registers that are under function zero 257 * management. 258 */ 259 /*ARGSUSED*/ 260 nxge_status_t 261 nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel, 262 p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p) 263 { 264 nxge_status_t status = NXGE_OK; 265 NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel")); 266 267 if (nxgep->niu_type == N2_NIU) { 268 #ifndef NIU_HV_WORKAROUND 269 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 270 NXGE_DEBUG_MSG((nxgep, RX_CTL, 271 "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV " 272 "set up logical pages")); 273 /* Initialize the RXDMA logical pages */ 274 status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel, 275 rbr_p); 276 if (status != NXGE_OK) { 277 return (status); 278 } 279 #endif 280 status = NXGE_OK; 281 #else 282 NXGE_DEBUG_MSG((nxgep, RX_CTL, 283 "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to " 284 "set up logical pages")); 285 /* Initialize the RXDMA logical pages */ 286 status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel, 287 rbr_p); 288 if (status != NXGE_OK) { 289 return (status); 290 } 291 #endif 292 } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 293 /* Initialize the RXDMA logical pages */ 294 status = nxge_init_fzc_rxdma_channel_pages(nxgep, 295 channel, rbr_p); 296 if (status != NXGE_OK) { 297 return (status); 298 } 299 } else { 300 return (NXGE_ERROR); 301 } 302 303 /* Configure RED parameters */ 304 status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_p); 305 306 NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel")); 307 return (status); 308 } 309 310 /*ARGSUSED*/ 311 nxge_status_t 312 nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep, 313 uint16_t channel, p_rx_rbr_ring_t rbrp) 314 { 315 npi_handle_t handle; 316 dma_log_page_t cfg; 317 npi_status_t rs = NPI_SUCCESS; 318 319 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 320 "==> nxge_init_fzc_rxdma_channel_pages")); 321 322 handle = NXGE_DEV_NPI_HANDLE(nxgep); 323 /* 324 * Initialize logical page 1. 325 */ 326 cfg.func_num = nxgep->function_num; 327 cfg.page_num = 0; 328 cfg.valid = rbrp->page_valid.bits.ldw.page0; 329 cfg.value = rbrp->page_value_1.value; 330 cfg.mask = rbrp->page_mask_1.value; 331 cfg.reloc = rbrp->page_reloc_1.value; 332 rs = npi_rxdma_cfg_logical_page(handle, channel, 333 (p_dma_log_page_t)&cfg); 334 if (rs != NPI_SUCCESS) { 335 return (NXGE_ERROR | rs); 336 } 337 338 /* 339 * Initialize logical page 2. 340 */ 341 cfg.page_num = 1; 342 cfg.valid = rbrp->page_valid.bits.ldw.page1; 343 cfg.value = rbrp->page_value_2.value; 344 cfg.mask = rbrp->page_mask_2.value; 345 cfg.reloc = rbrp->page_reloc_2.value; 346 347 rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg); 348 if (rs != NPI_SUCCESS) { 349 return (NXGE_ERROR | rs); 350 } 351 352 /* Initialize the page handle */ 353 rs = npi_rxdma_cfg_logical_page_handle(handle, channel, 354 rbrp->page_hdl.bits.ldw.handle); 355 356 if (rs != NPI_SUCCESS) { 357 return (NXGE_ERROR | rs); 358 } 359 360 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 361 "<== nxge_init_fzc_rxdma_channel_pages")); 362 363 return (NXGE_OK); 364 } 365 366 /*ARGSUSED*/ 367 nxge_status_t 368 nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep, 369 uint16_t channel, p_rx_rcr_ring_t rcr_p) 370 { 371 npi_handle_t handle; 372 rdc_red_para_t red; 373 npi_status_t rs = NPI_SUCCESS; 374 375 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red")); 376 377 handle = NXGE_DEV_NPI_HANDLE(nxgep); 378 red.value = 0; 379 red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT; 380 red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 381 red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT; 382 red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 383 384 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 385 "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))", 386 red.bits.ldw.thre_sync, 387 red.bits.ldw.thre_sync)); 388 389 rs = npi_rxdma_cfg_wred_param(handle, channel, &red); 390 if (rs != NPI_SUCCESS) { 391 return (NXGE_ERROR | rs); 392 } 393 394 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 395 "<== nxge_init_fzc_rxdma_channel_red")); 396 397 return (NXGE_OK); 398 } 399 400 /*ARGSUSED*/ 401 nxge_status_t 402 nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel, 403 p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p) 404 { 405 nxge_status_t status = NXGE_OK; 406 407 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 408 "==> nxge_init_fzc_txdma_channel")); 409 410 if (nxgep->niu_type == N2_NIU) { 411 #ifndef NIU_HV_WORKAROUND 412 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 413 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 414 "==> nxge_init_fzc_txdma_channel " 415 "N2_NIU: call HV to set up txdma logical pages")); 416 status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel, 417 tx_ring_p); 418 if (status != NXGE_OK) { 419 return (status); 420 } 421 #endif 422 status = NXGE_OK; 423 #else 424 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 425 "==> nxge_init_fzc_txdma_channel " 426 "N2_NIU: NEED to set up txdma logical pages")); 427 /* Initialize the TXDMA logical pages */ 428 (void) nxge_init_fzc_txdma_channel_pages(nxgep, channel, 429 tx_ring_p); 430 #endif 431 } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 432 /* Initialize the TXDMA logical pages */ 433 (void) nxge_init_fzc_txdma_channel_pages(nxgep, 434 channel, tx_ring_p); 435 } else { 436 return (NXGE_ERROR); 437 } 438 439 /* 440 * Configure Transmit DRR Weight parameters 441 * (It actually programs the TXC max burst register). 442 */ 443 (void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p); 444 445 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 446 "<== nxge_init_fzc_txdma_channel")); 447 return (status); 448 } 449 450 nxge_status_t 451 nxge_init_fzc_common(p_nxge_t nxgep) 452 { 453 nxge_status_t status = NXGE_OK; 454 455 (void) nxge_init_fzc_rx_common(nxgep); 456 457 return (status); 458 } 459 460 nxge_status_t 461 nxge_init_fzc_rx_common(p_nxge_t nxgep) 462 { 463 npi_handle_t handle; 464 npi_status_t rs = NPI_SUCCESS; 465 nxge_status_t status = NXGE_OK; 466 clock_t lbolt; 467 468 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common")); 469 handle = NXGE_DEV_NPI_HANDLE(nxgep); 470 if (!handle.regp) { 471 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 472 "==> nxge_init_fzc_rx_common null ptr")); 473 return (NXGE_ERROR); 474 } 475 476 /* 477 * Configure the rxdma clock divider 478 * This is the granularity counter based on 479 * the hardware system clock (i.e. 300 Mhz) and 480 * it is running around 3 nanoseconds. 481 * So, set the clock divider counter to 1000 to get 482 * microsecond granularity. 483 * For example, for a 3 microsecond timeout, the timeout 484 * will be set to 1. 485 */ 486 rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT); 487 if (rs != NPI_SUCCESS) 488 return (NXGE_ERROR | rs); 489 490 #if defined(__i386) 491 rs = npi_rxdma_cfg_32bitmode_enable(handle); 492 if (rs != NPI_SUCCESS) 493 return (NXGE_ERROR | rs); 494 rs = npi_txdma_mode32_set(handle, B_TRUE); 495 if (rs != NPI_SUCCESS) 496 return (NXGE_ERROR | rs); 497 #endif 498 499 /* 500 * Enable WRED and program an initial value. 501 * Use time to set the initial random number. 502 */ 503 (void) drv_getparm(LBOLT, &lbolt); 504 rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt); 505 if (rs != NPI_SUCCESS) 506 return (NXGE_ERROR | rs); 507 508 /* Initialize the RDC tables for each group */ 509 status = nxge_init_fzc_rdc_tbl(nxgep); 510 511 512 /* Ethernet Timeout Counter (?) */ 513 514 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 515 "<== nxge_init_fzc_rx_common:status 0x%08x", status)); 516 517 return (status); 518 } 519 520 nxge_status_t 521 nxge_init_fzc_rdc_tbl(p_nxge_t nxgep) 522 { 523 npi_handle_t handle; 524 p_nxge_dma_pt_cfg_t p_dma_cfgp; 525 p_nxge_hw_pt_cfg_t p_cfgp; 526 p_nxge_rdc_grp_t rdc_grp_p; 527 uint8_t grp_tbl_id; 528 int ngrps; 529 int i; 530 npi_status_t rs = NPI_SUCCESS; 531 nxge_status_t status = NXGE_OK; 532 533 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rdc_tbl")); 534 535 handle = NXGE_DEV_NPI_HANDLE(nxgep); 536 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 537 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 538 539 grp_tbl_id = p_cfgp->start_rdc_grpid; 540 rdc_grp_p = &p_dma_cfgp->rdc_grps[0]; 541 ngrps = p_cfgp->max_rdc_grpids; 542 for (i = 0; i < ngrps; i++, rdc_grp_p++) { 543 rs = npi_rxdma_cfg_rdc_table(handle, grp_tbl_id++, 544 rdc_grp_p->rdc); 545 if (rs != NPI_SUCCESS) { 546 status = NXGE_ERROR | rs; 547 break; 548 } 549 } 550 551 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc_tbl")); 552 return (status); 553 } 554 555 nxge_status_t 556 nxge_init_fzc_rxdma_port(p_nxge_t nxgep) 557 { 558 npi_handle_t handle; 559 p_nxge_dma_pt_cfg_t p_all_cfgp; 560 p_nxge_hw_pt_cfg_t p_cfgp; 561 hostinfo_t hostinfo; 562 int i; 563 npi_status_t rs = NPI_SUCCESS; 564 p_nxge_class_pt_cfg_t p_class_cfgp; 565 NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port")); 566 567 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 568 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 569 handle = NXGE_DEV_NPI_HANDLE(nxgep); 570 /* 571 * Initialize the port scheduler DRR weight. 572 * npi_rxdma_cfg_port_ddr_weight(); 573 */ 574 575 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 576 (nxgep->mac.portmode == PORT_1G_FIBER) || 577 (nxgep->mac.portmode == PORT_1G_SERDES)) { 578 rs = npi_rxdma_cfg_port_ddr_weight(handle, 579 nxgep->function_num, NXGE_RX_DRR_WT_1G); 580 if (rs != NPI_SUCCESS) { 581 return (NXGE_ERROR | rs); 582 } 583 } 584 585 /* Program the default RDC of a port */ 586 rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num, 587 p_cfgp->def_rdc); 588 if (rs != NPI_SUCCESS) { 589 return (NXGE_ERROR | rs); 590 } 591 592 /* 593 * Configure the MAC host info table with RDC tables 594 */ 595 hostinfo.value = 0; 596 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 597 for (i = 0; i < p_cfgp->max_macs; i++) { 598 hostinfo.bits.w0.rdc_tbl_num = p_cfgp->start_rdc_grpid; 599 hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref; 600 if (p_class_cfgp->mac_host_info[i].flag) { 601 hostinfo.bits.w0.rdc_tbl_num = 602 p_class_cfgp->mac_host_info[i].rdctbl; 603 hostinfo.bits.w0.mac_pref = 604 p_class_cfgp->mac_host_info[i].mpr_npr; 605 } 606 607 rs = npi_mac_hostinfo_entry(handle, OP_SET, 608 nxgep->function_num, i, &hostinfo); 609 if (rs != NPI_SUCCESS) 610 return (NXGE_ERROR | rs); 611 } 612 613 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 614 "<== nxge_init_fzc_rxdma_port rs 0x%08x", rs)); 615 616 return (NXGE_OK); 617 618 } 619 620 nxge_status_t 621 nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc) 622 { 623 npi_status_t rs = NPI_SUCCESS; 624 rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle, 625 port, rdc); 626 if (rs & NPI_FAILURE) 627 return (NXGE_ERROR | rs); 628 return (NXGE_OK); 629 } 630 631 nxge_status_t 632 nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 633 p_tx_ring_t tx_ring_p) 634 { 635 npi_handle_t handle; 636 dma_log_page_t cfg; 637 npi_status_t rs = NPI_SUCCESS; 638 639 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 640 "==> nxge_init_fzc_txdma_channel_pages")); 641 642 #ifndef NIU_HV_WORKAROUND 643 if (nxgep->niu_type == N2_NIU) { 644 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 645 "<== nxge_init_fzc_txdma_channel_pages: " 646 "N2_NIU: no need to set txdma logical pages")); 647 return (NXGE_OK); 648 } 649 #else 650 if (nxgep->niu_type == N2_NIU) { 651 NXGE_DEBUG_MSG((nxgep, DMA_CTL, 652 "<== nxge_init_fzc_txdma_channel_pages: " 653 "N2_NIU: NEED to set txdma logical pages")); 654 } 655 #endif 656 657 /* 658 * Initialize logical page 1. 659 */ 660 handle = NXGE_DEV_NPI_HANDLE(nxgep); 661 cfg.func_num = nxgep->function_num; 662 cfg.page_num = 0; 663 cfg.valid = tx_ring_p->page_valid.bits.ldw.page0; 664 cfg.value = tx_ring_p->page_value_1.value; 665 cfg.mask = tx_ring_p->page_mask_1.value; 666 cfg.reloc = tx_ring_p->page_reloc_1.value; 667 668 rs = npi_txdma_log_page_set(handle, channel, 669 (p_dma_log_page_t)&cfg); 670 if (rs != NPI_SUCCESS) { 671 return (NXGE_ERROR | rs); 672 } 673 674 /* 675 * Initialize logical page 2. 676 */ 677 cfg.page_num = 1; 678 cfg.valid = tx_ring_p->page_valid.bits.ldw.page1; 679 cfg.value = tx_ring_p->page_value_2.value; 680 cfg.mask = tx_ring_p->page_mask_2.value; 681 cfg.reloc = tx_ring_p->page_reloc_2.value; 682 683 rs = npi_txdma_log_page_set(handle, channel, &cfg); 684 if (rs != NPI_SUCCESS) { 685 return (NXGE_ERROR | rs); 686 } 687 688 /* Initialize the page handle */ 689 rs = npi_txdma_log_page_handle_set(handle, channel, 690 &tx_ring_p->page_hdl); 691 692 if (rs == NPI_SUCCESS) { 693 return (NXGE_OK); 694 } else { 695 return (NXGE_ERROR | rs); 696 } 697 } 698 699 700 nxge_status_t 701 nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel, 702 p_tx_ring_t tx_ring_p) 703 { 704 npi_status_t rs = NPI_SUCCESS; 705 npi_handle_t handle; 706 707 handle = NXGE_DEV_NPI_HANDLE(nxgep); 708 rs = npi_txc_dma_max_burst_set(handle, channel, 709 tx_ring_p->max_burst.value); 710 if (rs == NPI_SUCCESS) { 711 return (NXGE_OK); 712 } else { 713 return (NXGE_ERROR | rs); 714 } 715 } 716 717 nxge_status_t 718 nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask) 719 { 720 npi_status_t rs = NPI_SUCCESS; 721 npi_handle_t handle; 722 723 handle = NXGE_DEV_NPI_HANDLE(nxgep); 724 rs = npi_fzc_sys_err_mask_set(handle, mask); 725 if (rs == NPI_SUCCESS) { 726 return (NXGE_OK); 727 } else { 728 return (NXGE_ERROR | rs); 729 } 730 } 731 732 #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 733 nxge_status_t 734 nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 735 p_tx_ring_t tx_ring_p) 736 { 737 int err; 738 uint64_t hverr; 739 #ifdef DEBUG 740 uint64_t ra, size; 741 #endif 742 743 NXGE_DEBUG_MSG((nxgep, TX_CTL, 744 "==> nxge_init_hv_fzc_txdma_channel_pages")); 745 746 if (tx_ring_p->hv_set) { 747 return (NXGE_OK); 748 } 749 750 /* 751 * Initialize logical page 1 for data buffers. 752 */ 753 hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 754 (uint64_t)0, 755 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 756 tx_ring_p->hv_tx_buf_ioaddr_size); 757 758 err = (nxge_status_t)nxge_herr2kerr(hverr); 759 if (err != 0) { 760 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 761 "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d " 762 "error status 0x%x " 763 "(page 0 data buf) hverr 0x%llx " 764 "ioaddr_pp $%p " 765 "size 0x%llx ", 766 channel, 767 err, 768 hverr, 769 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 770 tx_ring_p->hv_tx_buf_ioaddr_size)); 771 return (NXGE_ERROR | err); 772 } 773 774 #ifdef DEBUG 775 ra = size = 0; 776 hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 777 (uint64_t)0, 778 &ra, 779 &size); 780 781 NXGE_DEBUG_MSG((nxgep, TX_CTL, 782 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 783 "ok status 0x%x " 784 "(page 0 data buf) hverr 0x%llx " 785 "set ioaddr_pp $%p " 786 "set size 0x%llx " 787 "get ra ioaddr_pp $%p " 788 "get size 0x%llx ", 789 channel, 790 err, 791 hverr, 792 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 793 tx_ring_p->hv_tx_buf_ioaddr_size, 794 ra, 795 size)); 796 #endif 797 798 NXGE_DEBUG_MSG((nxgep, TX_CTL, 799 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 800 "(page 0 data buf) hverr 0x%llx " 801 "ioaddr_pp $%p " 802 "size 0x%llx ", 803 channel, 804 hverr, 805 tx_ring_p->hv_tx_buf_base_ioaddr_pp, 806 tx_ring_p->hv_tx_buf_ioaddr_size)); 807 808 /* 809 * Initialize logical page 2 for control buffers. 810 */ 811 hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 812 (uint64_t)1, 813 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 814 tx_ring_p->hv_tx_cntl_ioaddr_size); 815 816 err = (nxge_status_t)nxge_herr2kerr(hverr); 817 818 NXGE_DEBUG_MSG((nxgep, TX_CTL, 819 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d" 820 "ok status 0x%x " 821 "(page 1 cntl buf) hverr 0x%llx " 822 "ioaddr_pp $%p " 823 "size 0x%llx ", 824 channel, 825 err, 826 hverr, 827 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 828 tx_ring_p->hv_tx_cntl_ioaddr_size)); 829 830 if (err != 0) { 831 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 832 "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d" 833 "error status 0x%x " 834 "(page 1 cntl buf) hverr 0x%llx " 835 "ioaddr_pp $%p " 836 "size 0x%llx ", 837 channel, 838 err, 839 hverr, 840 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 841 tx_ring_p->hv_tx_cntl_ioaddr_size)); 842 return (NXGE_ERROR | err); 843 } 844 845 #ifdef DEBUG 846 ra = size = 0; 847 hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 848 (uint64_t)1, 849 &ra, 850 &size); 851 852 NXGE_DEBUG_MSG((nxgep, TX_CTL, 853 "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 854 "(page 1 cntl buf) hverr 0x%llx " 855 "set ioaddr_pp $%p " 856 "set size 0x%llx " 857 "get ra ioaddr_pp $%p " 858 "get size 0x%llx ", 859 channel, 860 hverr, 861 tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 862 tx_ring_p->hv_tx_cntl_ioaddr_size, 863 ra, 864 size)); 865 #endif 866 867 tx_ring_p->hv_set = B_TRUE; 868 869 NXGE_DEBUG_MSG((nxgep, TX_CTL, 870 "<== nxge_init_hv_fzc_txdma_channel_pages")); 871 872 return (NXGE_OK); 873 } 874 875 /*ARGSUSED*/ 876 nxge_status_t 877 nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep, 878 uint16_t channel, p_rx_rbr_ring_t rbrp) 879 { 880 int err; 881 uint64_t hverr; 882 #ifdef DEBUG 883 uint64_t ra, size; 884 #endif 885 886 NXGE_DEBUG_MSG((nxgep, RX_CTL, 887 "==> nxge_init_hv_fzc_rxdma_channel_pages")); 888 889 if (rbrp->hv_set) { 890 return (NXGE_OK); 891 } 892 893 /* Initialize data buffers for page 0 */ 894 hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 895 (uint64_t)0, 896 rbrp->hv_rx_buf_base_ioaddr_pp, 897 rbrp->hv_rx_buf_ioaddr_size); 898 err = (nxge_status_t)nxge_herr2kerr(hverr); 899 if (err != 0) { 900 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 901 "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 902 "error status 0x%x " 903 "(page 0 data buf) hverr 0x%llx " 904 "ioaddr_pp $%p " 905 "size 0x%llx ", 906 channel, 907 err, 908 hverr, 909 rbrp->hv_rx_buf_base_ioaddr_pp, 910 rbrp->hv_rx_buf_ioaddr_size)); 911 912 return (NXGE_ERROR | err); 913 } 914 915 #ifdef DEBUG 916 ra = size = 0; 917 (void) hv_niu_rx_logical_page_info((uint64_t)channel, 918 (uint64_t)0, 919 &ra, 920 &size); 921 922 NXGE_DEBUG_MSG((nxgep, RX_CTL, 923 "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 924 "ok status 0x%x " 925 "(page 0 data buf) hverr 0x%llx " 926 "set databuf ioaddr_pp $%p " 927 "set databuf size 0x%llx " 928 "get databuf ra ioaddr_pp %p " 929 "get databuf size 0x%llx", 930 channel, 931 err, 932 hverr, 933 rbrp->hv_rx_buf_base_ioaddr_pp, 934 rbrp->hv_rx_buf_ioaddr_size, 935 ra, 936 size)); 937 #endif 938 939 /* Initialize control buffers for logical page 1. */ 940 hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 941 (uint64_t)1, 942 rbrp->hv_rx_cntl_base_ioaddr_pp, 943 rbrp->hv_rx_cntl_ioaddr_size); 944 945 err = (nxge_status_t)nxge_herr2kerr(hverr); 946 if (err != 0) { 947 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 948 "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 949 "error status 0x%x " 950 "(page 1 cntl buf) hverr 0x%llx " 951 "ioaddr_pp $%p " 952 "size 0x%llx ", 953 channel, 954 err, 955 hverr, 956 rbrp->hv_rx_buf_base_ioaddr_pp, 957 rbrp->hv_rx_buf_ioaddr_size)); 958 959 return (NXGE_ERROR | err); 960 } 961 962 #ifdef DEBUG 963 ra = size = 0; 964 (void) hv_niu_rx_logical_page_info((uint64_t)channel, 965 (uint64_t)1, 966 &ra, 967 &size); 968 969 970 NXGE_DEBUG_MSG((nxgep, RX_CTL, 971 "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 972 "error status 0x%x " 973 "(page 1 cntl buf) hverr 0x%llx " 974 "set cntl ioaddr_pp $%p " 975 "set cntl size 0x%llx " 976 "get cntl ioaddr_pp $%p " 977 "get cntl size 0x%llx ", 978 channel, 979 err, 980 hverr, 981 rbrp->hv_rx_cntl_base_ioaddr_pp, 982 rbrp->hv_rx_cntl_ioaddr_size, 983 ra, 984 size)); 985 #endif 986 987 rbrp->hv_set = B_FALSE; 988 989 NXGE_DEBUG_MSG((nxgep, RX_CTL, 990 "<== nxge_init_hv_fzc_rxdma_channel_pages")); 991 992 return (NXGE_OK); 993 } 994 995 /* 996 * Map hypervisor error code to errno. Only 997 * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful 998 * for niu driver. Any other error codes are mapped to EINVAL. 999 */ 1000 static int 1001 nxge_herr2kerr(uint64_t hv_errcode) 1002 { 1003 int s_errcode; 1004 1005 switch (hv_errcode) { 1006 case H_ENORADDR: 1007 case H_EBADALIGN: 1008 s_errcode = EFAULT; 1009 break; 1010 case H_EOK: 1011 s_errcode = 0; 1012 break; 1013 default: 1014 s_errcode = EINVAL; 1015 break; 1016 } 1017 return (s_errcode); 1018 } 1019 1020 #endif /* sun4v and NIU_LP_WORKAROUND */ 1021