144961713Sgirish /* 244961713Sgirish * CDDL HEADER START 344961713Sgirish * 444961713Sgirish * The contents of this file are subject to the terms of the 544961713Sgirish * Common Development and Distribution License (the "License"). 644961713Sgirish * You may not use this file except in compliance with the License. 744961713Sgirish * 844961713Sgirish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 944961713Sgirish * or http://www.opensolaris.org/os/licensing. 1044961713Sgirish * See the License for the specific language governing permissions 1144961713Sgirish * and limitations under the License. 1244961713Sgirish * 1344961713Sgirish * When distributing Covered Code, include this CDDL HEADER in each 1444961713Sgirish * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1544961713Sgirish * If applicable, add the following below this CDDL HEADER, with the 1644961713Sgirish * fields enclosed by brackets "[]" replaced with your own identifying 1744961713Sgirish * information: Portions Copyright [yyyy] [name of copyright owner] 1844961713Sgirish * 1944961713Sgirish * CDDL HEADER END 2044961713Sgirish */ 2144961713Sgirish /* 22*678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #pragma ident "%Z%%M% %I% %E% SMI" 2744961713Sgirish 2844961713Sgirish #include <nxge_impl.h> 2944961713Sgirish #include <npi_mac.h> 3044961713Sgirish #include <npi_rxdma.h> 31*678453a8Sspeer #include <nxge_hio.h> 3244961713Sgirish 3344961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 3444961713Sgirish static int nxge_herr2kerr(uint64_t); 3544961713Sgirish #endif 3644961713Sgirish 37*678453a8Sspeer static nxge_status_t nxge_init_fzc_rdc_pages(p_nxge_t, 38*678453a8Sspeer uint16_t, dma_log_page_t *, dma_log_page_t *); 39*678453a8Sspeer 40*678453a8Sspeer static nxge_status_t nxge_init_fzc_tdc_pages(p_nxge_t, 41*678453a8Sspeer uint16_t, dma_log_page_t *, dma_log_page_t *); 42*678453a8Sspeer 4344961713Sgirish /* 4444961713Sgirish * The following interfaces are controlled by the 4544961713Sgirish * function control registers. Some global registers 4644961713Sgirish * are to be initialized by only byt one of the 2/4 functions. 4744961713Sgirish * Use the test and set register. 4844961713Sgirish */ 4944961713Sgirish /*ARGSUSED*/ 5044961713Sgirish nxge_status_t 5144961713Sgirish nxge_test_and_set(p_nxge_t nxgep, uint8_t tas) 5244961713Sgirish { 5344961713Sgirish npi_handle_t handle; 5444961713Sgirish npi_status_t rs = NPI_SUCCESS; 5544961713Sgirish 5644961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 5744961713Sgirish if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas)) 5844961713Sgirish != NPI_SUCCESS) { 5944961713Sgirish return (NXGE_ERROR | rs); 6044961713Sgirish } 6144961713Sgirish 6244961713Sgirish return (NXGE_OK); 6344961713Sgirish } 6444961713Sgirish 6544961713Sgirish nxge_status_t 6644961713Sgirish nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc) 6744961713Sgirish { 6844961713Sgirish npi_handle_t handle; 6944961713Sgirish npi_status_t rs = NPI_SUCCESS; 7044961713Sgirish 7144961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl")); 7244961713Sgirish 7344961713Sgirish /* 7444961713Sgirish * In multi-partitioning, the partition manager 7544961713Sgirish * who owns function zero should set this multi-partition 7644961713Sgirish * control bit. 7744961713Sgirish */ 7844961713Sgirish if (nxgep->use_partition && nxgep->function_num) { 7944961713Sgirish return (NXGE_ERROR); 8044961713Sgirish } 8144961713Sgirish 8244961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 8344961713Sgirish if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) { 8444961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 8544961713Sgirish "<== nxge_set_fzc_multi_part_ctl")); 8644961713Sgirish return (NXGE_ERROR | rs); 8744961713Sgirish } 8844961713Sgirish 8944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl")); 9044961713Sgirish 9144961713Sgirish return (NXGE_OK); 9244961713Sgirish } 9344961713Sgirish 9444961713Sgirish nxge_status_t 9544961713Sgirish nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p) 9644961713Sgirish { 9744961713Sgirish npi_handle_t handle; 9844961713Sgirish npi_status_t rs = NPI_SUCCESS; 9944961713Sgirish 10044961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl")); 10144961713Sgirish 10244961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 10344961713Sgirish if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) { 10444961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 10544961713Sgirish "<== nxge_set_fzc_multi_part_ctl")); 10644961713Sgirish return (NXGE_ERROR | rs); 10744961713Sgirish } 10844961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl")); 10944961713Sgirish 11044961713Sgirish return (NXGE_OK); 11144961713Sgirish } 11244961713Sgirish 11344961713Sgirish /* 11444961713Sgirish * System interrupt registers that are under function zero 11544961713Sgirish * management. 11644961713Sgirish */ 11744961713Sgirish nxge_status_t 11844961713Sgirish nxge_fzc_intr_init(p_nxge_t nxgep) 11944961713Sgirish { 12044961713Sgirish nxge_status_t status = NXGE_OK; 12144961713Sgirish 12244961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init")); 12344961713Sgirish 12444961713Sgirish /* Configure the initial timer resolution */ 12544961713Sgirish if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) { 12644961713Sgirish return (status); 12744961713Sgirish } 12844961713Sgirish 1292e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 13044961713Sgirish /* 13144961713Sgirish * Set up the logical device group's logical devices that 13244961713Sgirish * the group owns. 13344961713Sgirish */ 13459ac0c16Sdavemq if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK) 13559ac0c16Sdavemq goto fzc_intr_init_exit; 13644961713Sgirish 13744961713Sgirish /* Configure the system interrupt data */ 13859ac0c16Sdavemq if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK) 13959ac0c16Sdavemq goto fzc_intr_init_exit; 14044961713Sgirish } 14144961713Sgirish 14259ac0c16Sdavemq fzc_intr_init_exit: 14359ac0c16Sdavemq 14444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init")); 14544961713Sgirish 14644961713Sgirish return (status); 14744961713Sgirish } 14844961713Sgirish 14944961713Sgirish nxge_status_t 15044961713Sgirish nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep) 15144961713Sgirish { 15244961713Sgirish p_nxge_ldg_t ldgp; 15344961713Sgirish p_nxge_ldv_t ldvp; 15444961713Sgirish npi_handle_t handle; 15544961713Sgirish int i, j; 15644961713Sgirish npi_status_t rs = NPI_SUCCESS; 15744961713Sgirish 15844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set")); 15944961713Sgirish 16044961713Sgirish if (nxgep->ldgvp == NULL) { 16144961713Sgirish return (NXGE_ERROR); 16244961713Sgirish } 16344961713Sgirish 16444961713Sgirish ldgp = nxgep->ldgvp->ldgp; 16544961713Sgirish ldvp = nxgep->ldgvp->ldvp; 16644961713Sgirish if (ldgp == NULL || ldvp == NULL) { 16744961713Sgirish return (NXGE_ERROR); 16844961713Sgirish } 16944961713Sgirish 17044961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 17144961713Sgirish 17244961713Sgirish for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 17344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 17444961713Sgirish "==> nxge_fzc_intr_ldg_num_set " 17544961713Sgirish "<== nxge_f(Neptune): # ldv %d " 17644961713Sgirish "in group %d", ldgp->nldvs, ldgp->ldg)); 17744961713Sgirish 17844961713Sgirish for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 17944961713Sgirish rs = npi_fzc_ldg_num_set(handle, ldvp->ldv, 18044961713Sgirish ldvp->ldg_assigned); 18144961713Sgirish if (rs != NPI_SUCCESS) { 18244961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 18344961713Sgirish "<== nxge_fzc_intr_ldg_num_set failed " 18444961713Sgirish " rs 0x%x ldv %d ldg %d", 18544961713Sgirish rs, ldvp->ldv, ldvp->ldg_assigned)); 18644961713Sgirish return (NXGE_ERROR | rs); 18744961713Sgirish } 18844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 18944961713Sgirish "<== nxge_fzc_intr_ldg_num_set OK " 19044961713Sgirish " ldv %d ldg %d", 19144961713Sgirish ldvp->ldv, ldvp->ldg_assigned)); 19244961713Sgirish } 19344961713Sgirish } 19444961713Sgirish 19544961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set")); 19644961713Sgirish 19744961713Sgirish return (NXGE_OK); 19844961713Sgirish } 19944961713Sgirish 20044961713Sgirish nxge_status_t 20144961713Sgirish nxge_fzc_intr_tmres_set(p_nxge_t nxgep) 20244961713Sgirish { 20344961713Sgirish npi_handle_t handle; 20444961713Sgirish npi_status_t rs = NPI_SUCCESS; 20544961713Sgirish 20644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set")); 20744961713Sgirish if (nxgep->ldgvp == NULL) { 20844961713Sgirish return (NXGE_ERROR); 20944961713Sgirish } 21044961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 21144961713Sgirish if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) { 21244961713Sgirish return (NXGE_ERROR | rs); 21344961713Sgirish } 21444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set")); 21544961713Sgirish 21644961713Sgirish return (NXGE_OK); 21744961713Sgirish } 21844961713Sgirish 21944961713Sgirish nxge_status_t 22044961713Sgirish nxge_fzc_intr_sid_set(p_nxge_t nxgep) 22144961713Sgirish { 22244961713Sgirish npi_handle_t handle; 22344961713Sgirish p_nxge_ldg_t ldgp; 22444961713Sgirish fzc_sid_t sid; 22544961713Sgirish int i; 22644961713Sgirish npi_status_t rs = NPI_SUCCESS; 22744961713Sgirish 22844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set")); 22944961713Sgirish if (nxgep->ldgvp == NULL) { 23044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 23144961713Sgirish "<== nxge_fzc_intr_sid_set: no ldg")); 23244961713Sgirish return (NXGE_ERROR); 23344961713Sgirish } 23444961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 23544961713Sgirish ldgp = nxgep->ldgvp->ldgp; 23644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 23744961713Sgirish "==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs)); 23844961713Sgirish for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 23944961713Sgirish sid.ldg = ldgp->ldg; 24044961713Sgirish sid.niu = B_FALSE; 24144961713Sgirish sid.func = ldgp->func; 24244961713Sgirish sid.vector = ldgp->vector; 24344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 24444961713Sgirish "==> nxge_fzc_intr_sid_set(%d): func %d group %d " 24544961713Sgirish "vector %d", 24644961713Sgirish i, sid.func, sid.ldg, sid.vector)); 24744961713Sgirish rs = npi_fzc_sid_set(handle, sid); 24844961713Sgirish if (rs != NPI_SUCCESS) { 24944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 25044961713Sgirish "<== nxge_fzc_intr_sid_set:failed 0x%x", 25144961713Sgirish rs)); 25244961713Sgirish return (NXGE_ERROR | rs); 25344961713Sgirish } 25444961713Sgirish } 25544961713Sgirish 25644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set")); 25744961713Sgirish 25844961713Sgirish return (NXGE_OK); 25944961713Sgirish 26044961713Sgirish } 26144961713Sgirish 26244961713Sgirish /* 263*678453a8Sspeer * nxge_init_fzc_rdc 264*678453a8Sspeer * 265*678453a8Sspeer * Initialize all of a RDC's FZC_DMC registers. 266*678453a8Sspeer * This is executed by the service domain, on behalf of a 267*678453a8Sspeer * guest domain, who cannot access these registers. 268*678453a8Sspeer * 269*678453a8Sspeer * Arguments: 270*678453a8Sspeer * nxgep 271*678453a8Sspeer * channel The channel to initialize. 272*678453a8Sspeer * 273*678453a8Sspeer * NPI_NXGE function calls: 274*678453a8Sspeer * nxge_init_fzc_rdc_pages() 275*678453a8Sspeer * 276*678453a8Sspeer * Context: 277*678453a8Sspeer * Service Domain 27844961713Sgirish */ 27944961713Sgirish /*ARGSUSED*/ 28044961713Sgirish nxge_status_t 281*678453a8Sspeer nxge_init_fzc_rdc(p_nxge_t nxgep, uint16_t channel) 28244961713Sgirish { 28344961713Sgirish nxge_status_t status = NXGE_OK; 284*678453a8Sspeer 285*678453a8Sspeer dma_log_page_t page1, page2; 286*678453a8Sspeer npi_handle_t handle; 287*678453a8Sspeer rdc_red_para_t red; 288*678453a8Sspeer 289*678453a8Sspeer /* 290*678453a8Sspeer * Initialize the RxDMA channel-specific FZC control 291*678453a8Sspeer * registers. 292*678453a8Sspeer */ 293*678453a8Sspeer 294*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc")); 295*678453a8Sspeer 296*678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep); 297*678453a8Sspeer 298*678453a8Sspeer /* Reset RXDMA channel */ 299*678453a8Sspeer status = npi_rxdma_cfg_rdc_reset(handle, channel); 300*678453a8Sspeer if (status != NPI_SUCCESS) { 301*678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 302*678453a8Sspeer "==> nxge_init_fzc_rdc: npi_rxdma_cfg_rdc_reset(%d) " 303*678453a8Sspeer "returned 0x%08x", channel, status)); 304*678453a8Sspeer return (NXGE_ERROR | status); 305*678453a8Sspeer } 306*678453a8Sspeer 307*678453a8Sspeer /* 308*678453a8Sspeer * These values have been copied from 309*678453a8Sspeer * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring(). 310*678453a8Sspeer */ 311*678453a8Sspeer page1.page_num = 0; 312*678453a8Sspeer page1.valid = 1; 313*678453a8Sspeer page1.func_num = nxgep->function_num; 314*678453a8Sspeer page1.mask = 0; 315*678453a8Sspeer page1.value = 0; 316*678453a8Sspeer page1.reloc = 0; 317*678453a8Sspeer 318*678453a8Sspeer page2.page_num = 1; 319*678453a8Sspeer page2.valid = 1; 320*678453a8Sspeer page2.func_num = nxgep->function_num; 321*678453a8Sspeer page2.mask = 0; 322*678453a8Sspeer page2.value = 0; 323*678453a8Sspeer page2.reloc = 0; 324*678453a8Sspeer 325*678453a8Sspeer if (nxgep->niu_type == N2_NIU) { 326*678453a8Sspeer #if !defined(NIU_HV_WORKAROUND) 327*678453a8Sspeer status = NXGE_OK; 328*678453a8Sspeer #else 329*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, RX_CTL, 330*678453a8Sspeer "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to " 331*678453a8Sspeer "set up logical pages")); 332*678453a8Sspeer /* Initialize the RXDMA logical pages */ 333*678453a8Sspeer status = nxge_init_fzc_rdc_pages(nxgep, channel, 334*678453a8Sspeer &page1, &page2); 335*678453a8Sspeer if (status != NXGE_OK) { 336*678453a8Sspeer return (status); 337*678453a8Sspeer } 338*678453a8Sspeer #endif 339*678453a8Sspeer } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 340*678453a8Sspeer /* Initialize the RXDMA logical pages */ 341*678453a8Sspeer status = nxge_init_fzc_rdc_pages(nxgep, channel, 342*678453a8Sspeer &page1, &page2); 343*678453a8Sspeer if (status != NXGE_OK) { 344*678453a8Sspeer return (status); 345*678453a8Sspeer } 346*678453a8Sspeer } else { 347*678453a8Sspeer return (NXGE_ERROR); 348*678453a8Sspeer } 349*678453a8Sspeer 350*678453a8Sspeer /* 351*678453a8Sspeer * Configure RED parameters 352*678453a8Sspeer */ 353*678453a8Sspeer red.value = 0; 354*678453a8Sspeer red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT; 355*678453a8Sspeer red.bits.ldw.thre = 356*678453a8Sspeer (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES); 357*678453a8Sspeer red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT; 358*678453a8Sspeer red.bits.ldw.thre_sync = 359*678453a8Sspeer (nxgep->nxge_port_rcr_size - RXDMA_RED_LESS_ENTRIES); 360*678453a8Sspeer 361*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 362*678453a8Sspeer "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))", 363*678453a8Sspeer red.bits.ldw.thre_sync, 364*678453a8Sspeer red.bits.ldw.thre_sync)); 365*678453a8Sspeer 366*678453a8Sspeer status |= npi_rxdma_cfg_wred_param(handle, channel, &red); 367*678453a8Sspeer 368*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc")); 369*678453a8Sspeer 370*678453a8Sspeer return (status); 371*678453a8Sspeer } 372*678453a8Sspeer 373*678453a8Sspeer /* 374*678453a8Sspeer * nxge_init_fzc_rxdma_channel 375*678453a8Sspeer * 376*678453a8Sspeer * Initialize all per-channel FZC_DMC registers. 377*678453a8Sspeer * 378*678453a8Sspeer * Arguments: 379*678453a8Sspeer * nxgep 380*678453a8Sspeer * channel The channel to start 381*678453a8Sspeer * 382*678453a8Sspeer * NPI_NXGE function calls: 383*678453a8Sspeer * nxge_init_hv_fzc_rxdma_channel_pages() 384*678453a8Sspeer * nxge_init_fzc_rxdma_channel_pages() 385*678453a8Sspeer * nxge_init_fzc_rxdma_channel_red() 386*678453a8Sspeer * 387*678453a8Sspeer * Context: 388*678453a8Sspeer * Service Domain 389*678453a8Sspeer */ 390*678453a8Sspeer /*ARGSUSED*/ 391*678453a8Sspeer nxge_status_t 392*678453a8Sspeer nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel) 393*678453a8Sspeer { 394*678453a8Sspeer rx_rbr_ring_t *rbr_ring; 395*678453a8Sspeer rx_rcr_ring_t *rcr_ring; 396*678453a8Sspeer 397*678453a8Sspeer nxge_status_t status = NXGE_OK; 398*678453a8Sspeer 39944961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel")); 40044961713Sgirish 401*678453a8Sspeer rbr_ring = nxgep->rx_rbr_rings->rbr_rings[channel]; 402*678453a8Sspeer rcr_ring = nxgep->rx_rcr_rings->rcr_rings[channel]; 403*678453a8Sspeer 40459ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 40544961713Sgirish #ifndef NIU_HV_WORKAROUND 40644961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 40744961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, 40859ac0c16Sdavemq "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV " 40959ac0c16Sdavemq "set up logical pages")); 41044961713Sgirish /* Initialize the RXDMA logical pages */ 41144961713Sgirish status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel, 412*678453a8Sspeer rbr_ring); 41344961713Sgirish if (status != NXGE_OK) { 41444961713Sgirish return (status); 41544961713Sgirish } 41644961713Sgirish #endif 41759ac0c16Sdavemq status = NXGE_OK; 41844961713Sgirish #else 41944961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, 42059ac0c16Sdavemq "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to " 42159ac0c16Sdavemq "set up logical pages")); 42244961713Sgirish /* Initialize the RXDMA logical pages */ 42344961713Sgirish status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel, 424*678453a8Sspeer rbr_ring); 42544961713Sgirish if (status != NXGE_OK) { 42644961713Sgirish return (status); 42744961713Sgirish } 42844961713Sgirish #endif 4292e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 43059ac0c16Sdavemq /* Initialize the RXDMA logical pages */ 43159ac0c16Sdavemq status = nxge_init_fzc_rxdma_channel_pages(nxgep, 432*678453a8Sspeer channel, rbr_ring); 43359ac0c16Sdavemq if (status != NXGE_OK) { 43459ac0c16Sdavemq return (status); 43559ac0c16Sdavemq } 43659ac0c16Sdavemq } else { 43759ac0c16Sdavemq return (NXGE_ERROR); 43844961713Sgirish } 43944961713Sgirish 44044961713Sgirish /* Configure RED parameters */ 441*678453a8Sspeer status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_ring); 44244961713Sgirish 44344961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel")); 44444961713Sgirish return (status); 44544961713Sgirish } 44644961713Sgirish 447*678453a8Sspeer /* 448*678453a8Sspeer * nxge_init_fzc_rdc_pages 449*678453a8Sspeer * 450*678453a8Sspeer * Configure a TDC's logical pages. 451*678453a8Sspeer * 452*678453a8Sspeer * This function is executed by the service domain, on behalf of 453*678453a8Sspeer * a guest domain, to whom this RDC has been loaned. 454*678453a8Sspeer * 455*678453a8Sspeer * Arguments: 456*678453a8Sspeer * nxgep 457*678453a8Sspeer * channel The channel to initialize. 458*678453a8Sspeer * page0 Logical page 0 definition. 459*678453a8Sspeer * page1 Logical page 1 definition. 460*678453a8Sspeer * 461*678453a8Sspeer * Notes: 462*678453a8Sspeer * I think that this function can be called from any 463*678453a8Sspeer * domain, but I need to check. 464*678453a8Sspeer * 465*678453a8Sspeer * NPI/NXGE function calls: 466*678453a8Sspeer * hv_niu_tx_logical_page_conf() 467*678453a8Sspeer * hv_niu_tx_logical_page_info() 468*678453a8Sspeer * 469*678453a8Sspeer * Context: 470*678453a8Sspeer * Any domain 471*678453a8Sspeer */ 472*678453a8Sspeer nxge_status_t 473*678453a8Sspeer nxge_init_fzc_rdc_pages( 474*678453a8Sspeer p_nxge_t nxgep, 475*678453a8Sspeer uint16_t channel, 476*678453a8Sspeer dma_log_page_t *page0, 477*678453a8Sspeer dma_log_page_t *page1) 478*678453a8Sspeer { 479*678453a8Sspeer npi_handle_t handle; 480*678453a8Sspeer npi_status_t rs; 481*678453a8Sspeer 482*678453a8Sspeer uint64_t page_handle; 483*678453a8Sspeer 484*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 485*678453a8Sspeer "==> nxge_init_fzc_txdma_channel_pages")); 486*678453a8Sspeer 487*678453a8Sspeer #ifndef NIU_HV_WORKAROUND 488*678453a8Sspeer if (nxgep->niu_type == N2_NIU) { 489*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 490*678453a8Sspeer "<== nxge_init_fzc_rdc_pages: " 491*678453a8Sspeer "N2_NIU: no need to set rxdma logical pages")); 492*678453a8Sspeer return (NXGE_OK); 493*678453a8Sspeer } 494*678453a8Sspeer #else 495*678453a8Sspeer if (nxgep->niu_type == N2_NIU) { 496*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 497*678453a8Sspeer "<== nxge_init_fzc_rdc_pages: " 498*678453a8Sspeer "N2_NIU: NEED to set rxdma logical pages")); 499*678453a8Sspeer } 500*678453a8Sspeer #endif 501*678453a8Sspeer 502*678453a8Sspeer /* 503*678453a8Sspeer * Initialize logical page 1. 504*678453a8Sspeer */ 505*678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep); 506*678453a8Sspeer if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page0)) 507*678453a8Sspeer != NPI_SUCCESS) 508*678453a8Sspeer return (NXGE_ERROR | rs); 509*678453a8Sspeer 510*678453a8Sspeer /* 511*678453a8Sspeer * Initialize logical page 2. 512*678453a8Sspeer */ 513*678453a8Sspeer if ((rs = npi_rxdma_cfg_logical_page(handle, channel, page1)) 514*678453a8Sspeer != NPI_SUCCESS) 515*678453a8Sspeer return (NXGE_ERROR | rs); 516*678453a8Sspeer 517*678453a8Sspeer /* 518*678453a8Sspeer * Initialize the page handle. 519*678453a8Sspeer * (In the current driver, this is always set to 0.) 520*678453a8Sspeer */ 521*678453a8Sspeer page_handle = 0; 522*678453a8Sspeer rs = npi_rxdma_cfg_logical_page_handle(handle, channel, page_handle); 523*678453a8Sspeer if (rs == NPI_SUCCESS) { 524*678453a8Sspeer return (NXGE_OK); 525*678453a8Sspeer } else { 526*678453a8Sspeer return (NXGE_ERROR | rs); 527*678453a8Sspeer } 528*678453a8Sspeer } 529*678453a8Sspeer 53044961713Sgirish /*ARGSUSED*/ 53144961713Sgirish nxge_status_t 53244961713Sgirish nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep, 53344961713Sgirish uint16_t channel, p_rx_rbr_ring_t rbrp) 53444961713Sgirish { 53544961713Sgirish npi_handle_t handle; 53644961713Sgirish dma_log_page_t cfg; 53744961713Sgirish npi_status_t rs = NPI_SUCCESS; 53844961713Sgirish 53944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 54044961713Sgirish "==> nxge_init_fzc_rxdma_channel_pages")); 54144961713Sgirish 54244961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 54344961713Sgirish /* 54444961713Sgirish * Initialize logical page 1. 54544961713Sgirish */ 54644961713Sgirish cfg.func_num = nxgep->function_num; 54744961713Sgirish cfg.page_num = 0; 54844961713Sgirish cfg.valid = rbrp->page_valid.bits.ldw.page0; 54944961713Sgirish cfg.value = rbrp->page_value_1.value; 55044961713Sgirish cfg.mask = rbrp->page_mask_1.value; 55144961713Sgirish cfg.reloc = rbrp->page_reloc_1.value; 55244961713Sgirish rs = npi_rxdma_cfg_logical_page(handle, channel, 55344961713Sgirish (p_dma_log_page_t)&cfg); 55444961713Sgirish if (rs != NPI_SUCCESS) { 55544961713Sgirish return (NXGE_ERROR | rs); 55644961713Sgirish } 55744961713Sgirish 55844961713Sgirish /* 55944961713Sgirish * Initialize logical page 2. 56044961713Sgirish */ 56144961713Sgirish cfg.page_num = 1; 56244961713Sgirish cfg.valid = rbrp->page_valid.bits.ldw.page1; 56344961713Sgirish cfg.value = rbrp->page_value_2.value; 56444961713Sgirish cfg.mask = rbrp->page_mask_2.value; 56544961713Sgirish cfg.reloc = rbrp->page_reloc_2.value; 56644961713Sgirish 56744961713Sgirish rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg); 56844961713Sgirish if (rs != NPI_SUCCESS) { 56944961713Sgirish return (NXGE_ERROR | rs); 57044961713Sgirish } 57144961713Sgirish 57244961713Sgirish /* Initialize the page handle */ 57344961713Sgirish rs = npi_rxdma_cfg_logical_page_handle(handle, channel, 57444961713Sgirish rbrp->page_hdl.bits.ldw.handle); 57544961713Sgirish 57644961713Sgirish if (rs != NPI_SUCCESS) { 57744961713Sgirish return (NXGE_ERROR | rs); 57844961713Sgirish } 57944961713Sgirish 58044961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 58144961713Sgirish "<== nxge_init_fzc_rxdma_channel_pages")); 58244961713Sgirish 58344961713Sgirish return (NXGE_OK); 58444961713Sgirish } 58544961713Sgirish 58644961713Sgirish /*ARGSUSED*/ 58744961713Sgirish nxge_status_t 58844961713Sgirish nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep, 58944961713Sgirish uint16_t channel, p_rx_rcr_ring_t rcr_p) 59044961713Sgirish { 59144961713Sgirish npi_handle_t handle; 59244961713Sgirish rdc_red_para_t red; 59344961713Sgirish npi_status_t rs = NPI_SUCCESS; 59444961713Sgirish 59544961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red")); 59644961713Sgirish 59744961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 59844961713Sgirish red.value = 0; 59944961713Sgirish red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT; 60044961713Sgirish red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 60144961713Sgirish red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT; 60244961713Sgirish red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES); 60344961713Sgirish 60444961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 60544961713Sgirish "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))", 60644961713Sgirish red.bits.ldw.thre_sync, 60744961713Sgirish red.bits.ldw.thre_sync)); 60844961713Sgirish 60944961713Sgirish rs = npi_rxdma_cfg_wred_param(handle, channel, &red); 61044961713Sgirish if (rs != NPI_SUCCESS) { 61144961713Sgirish return (NXGE_ERROR | rs); 61244961713Sgirish } 61344961713Sgirish 61444961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 61544961713Sgirish "<== nxge_init_fzc_rxdma_channel_red")); 61644961713Sgirish 61744961713Sgirish return (NXGE_OK); 61844961713Sgirish } 61944961713Sgirish 620*678453a8Sspeer /* 621*678453a8Sspeer * nxge_init_fzc_tdc 622*678453a8Sspeer * 623*678453a8Sspeer * Initialize all of a TDC's FZC_DMC registers. 624*678453a8Sspeer * This is executed by the service domain, on behalf of a 625*678453a8Sspeer * guest domain, who cannot access these registers. 626*678453a8Sspeer * 627*678453a8Sspeer * Arguments: 628*678453a8Sspeer * nxgep 629*678453a8Sspeer * channel The channel to initialize. 630*678453a8Sspeer * 631*678453a8Sspeer * NPI_NXGE function calls: 632*678453a8Sspeer * nxge_init_fzc_tdc_pages() 633*678453a8Sspeer * npi_txc_dma_max_burst_set() 634*678453a8Sspeer * 635*678453a8Sspeer * Registers accessed: 636*678453a8Sspeer * TXC_DMA_MAX_BURST 637*678453a8Sspeer * 638*678453a8Sspeer * Context: 639*678453a8Sspeer * Service Domain 640*678453a8Sspeer */ 641*678453a8Sspeer /*ARGSUSED*/ 642*678453a8Sspeer nxge_status_t 643*678453a8Sspeer nxge_init_fzc_tdc(p_nxge_t nxgep, uint16_t channel) 644*678453a8Sspeer { 645*678453a8Sspeer nxge_status_t status = NXGE_OK; 646*678453a8Sspeer 647*678453a8Sspeer dma_log_page_t page1, page2; 648*678453a8Sspeer npi_handle_t handle; 649*678453a8Sspeer 650*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_tdc")); 651*678453a8Sspeer 652*678453a8Sspeer /* 653*678453a8Sspeer * These values have been copied from 654*678453a8Sspeer * nxge_txdma.c:nxge_map_txdma_channel_cfg_ring(). 655*678453a8Sspeer */ 656*678453a8Sspeer page1.page_num = 0; 657*678453a8Sspeer page1.valid = 1; 658*678453a8Sspeer page1.func_num = nxgep->function_num; 659*678453a8Sspeer page1.mask = 0; 660*678453a8Sspeer page1.value = 0; 661*678453a8Sspeer page1.reloc = 0; 662*678453a8Sspeer 663*678453a8Sspeer page1.page_num = 1; 664*678453a8Sspeer page1.valid = 1; 665*678453a8Sspeer page1.func_num = nxgep->function_num; 666*678453a8Sspeer page1.mask = 0; 667*678453a8Sspeer page1.value = 0; 668*678453a8Sspeer page1.reloc = 0; 669*678453a8Sspeer 670*678453a8Sspeer #ifdef NIU_HV_WORKAROUND 671*678453a8Sspeer if (nxgep->niu_type == N2_NIU) { 672*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 673*678453a8Sspeer "==> nxge_init_fzc_txdma_channel " 674*678453a8Sspeer "N2_NIU: NEED to set up txdma logical pages")); 675*678453a8Sspeer /* Initialize the TXDMA logical pages */ 676*678453a8Sspeer (void) nxge_init_fzc_tdc_pages(nxgep, channel, 677*678453a8Sspeer &page1, &page2); 678*678453a8Sspeer } 679*678453a8Sspeer #endif 680*678453a8Sspeer if (nxgep->niu_type != N2_NIU) { 681*678453a8Sspeer if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 682*678453a8Sspeer /* Initialize the TXDMA logical pages */ 683*678453a8Sspeer (void) nxge_init_fzc_tdc_pages(nxgep, channel, 684*678453a8Sspeer &page1, &page2); 685*678453a8Sspeer } else 686*678453a8Sspeer return (NXGE_ERROR); 687*678453a8Sspeer } 688*678453a8Sspeer 689*678453a8Sspeer /* 690*678453a8Sspeer * Configure the TXC DMA Max Burst value. 691*678453a8Sspeer * 692*678453a8Sspeer * PRM.13.5 693*678453a8Sspeer * 694*678453a8Sspeer * TXC DMA Max Burst. TXC_DMA_MAX (FZC_TXC + 0000016) 695*678453a8Sspeer * 19:0 dma_max_burst RW 696*678453a8Sspeer * Max burst value associated with DMA. Used by DRR engine 697*678453a8Sspeer * for computing when DMA has gone into deficit. 698*678453a8Sspeer */ 699*678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep); 700*678453a8Sspeer (void) npi_txc_dma_max_burst_set( 701*678453a8Sspeer handle, channel, TXC_DMA_MAX_BURST_DEFAULT); 702*678453a8Sspeer 703*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_tdc")); 704*678453a8Sspeer 705*678453a8Sspeer return (status); 706*678453a8Sspeer } 707*678453a8Sspeer 70844961713Sgirish /*ARGSUSED*/ 70944961713Sgirish nxge_status_t 71044961713Sgirish nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel, 71144961713Sgirish p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p) 71244961713Sgirish { 71344961713Sgirish nxge_status_t status = NXGE_OK; 71444961713Sgirish 71544961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 71644961713Sgirish "==> nxge_init_fzc_txdma_channel")); 71744961713Sgirish 71859ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 71944961713Sgirish #ifndef NIU_HV_WORKAROUND 72044961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 72144961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 72259ac0c16Sdavemq "==> nxge_init_fzc_txdma_channel " 72359ac0c16Sdavemq "N2_NIU: call HV to set up txdma logical pages")); 72444961713Sgirish status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel, 72559ac0c16Sdavemq tx_ring_p); 72644961713Sgirish if (status != NXGE_OK) { 72744961713Sgirish return (status); 72844961713Sgirish } 72944961713Sgirish #endif 73059ac0c16Sdavemq status = NXGE_OK; 73144961713Sgirish #else 73244961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 73359ac0c16Sdavemq "==> nxge_init_fzc_txdma_channel " 73459ac0c16Sdavemq "N2_NIU: NEED to set up txdma logical pages")); 73544961713Sgirish /* Initialize the TXDMA logical pages */ 73644961713Sgirish (void) nxge_init_fzc_txdma_channel_pages(nxgep, channel, 73759ac0c16Sdavemq tx_ring_p); 73844961713Sgirish #endif 7392e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 74059ac0c16Sdavemq /* Initialize the TXDMA logical pages */ 74159ac0c16Sdavemq (void) nxge_init_fzc_txdma_channel_pages(nxgep, 74259ac0c16Sdavemq channel, tx_ring_p); 74359ac0c16Sdavemq } else { 74459ac0c16Sdavemq return (NXGE_ERROR); 74544961713Sgirish } 74644961713Sgirish 74744961713Sgirish /* 74844961713Sgirish * Configure Transmit DRR Weight parameters 74944961713Sgirish * (It actually programs the TXC max burst register). 75044961713Sgirish */ 75144961713Sgirish (void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p); 75244961713Sgirish 75344961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 75444961713Sgirish "<== nxge_init_fzc_txdma_channel")); 75544961713Sgirish return (status); 75644961713Sgirish } 75744961713Sgirish 75844961713Sgirish nxge_status_t 75944961713Sgirish nxge_init_fzc_common(p_nxge_t nxgep) 76044961713Sgirish { 76144961713Sgirish nxge_status_t status = NXGE_OK; 76244961713Sgirish 76344961713Sgirish (void) nxge_init_fzc_rx_common(nxgep); 76444961713Sgirish 76544961713Sgirish return (status); 76644961713Sgirish } 76744961713Sgirish 76844961713Sgirish nxge_status_t 76944961713Sgirish nxge_init_fzc_rx_common(p_nxge_t nxgep) 77044961713Sgirish { 77144961713Sgirish npi_handle_t handle; 77244961713Sgirish npi_status_t rs = NPI_SUCCESS; 77344961713Sgirish nxge_status_t status = NXGE_OK; 77444961713Sgirish clock_t lbolt; 775*678453a8Sspeer int table; 776*678453a8Sspeer 777*678453a8Sspeer nxge_hw_pt_cfg_t *hardware; 77844961713Sgirish 77944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common")); 78044961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 78144961713Sgirish if (!handle.regp) { 78244961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 78344961713Sgirish "==> nxge_init_fzc_rx_common null ptr")); 78444961713Sgirish return (NXGE_ERROR); 78544961713Sgirish } 78644961713Sgirish 78744961713Sgirish /* 78844961713Sgirish * Configure the rxdma clock divider 78944961713Sgirish * This is the granularity counter based on 79044961713Sgirish * the hardware system clock (i.e. 300 Mhz) and 79144961713Sgirish * it is running around 3 nanoseconds. 79244961713Sgirish * So, set the clock divider counter to 1000 to get 79344961713Sgirish * microsecond granularity. 79444961713Sgirish * For example, for a 3 microsecond timeout, the timeout 79544961713Sgirish * will be set to 1. 79644961713Sgirish */ 79744961713Sgirish rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT); 79844961713Sgirish if (rs != NPI_SUCCESS) 79944961713Sgirish return (NXGE_ERROR | rs); 80044961713Sgirish 80144961713Sgirish #if defined(__i386) 80244961713Sgirish rs = npi_rxdma_cfg_32bitmode_enable(handle); 80344961713Sgirish if (rs != NPI_SUCCESS) 80444961713Sgirish return (NXGE_ERROR | rs); 80544961713Sgirish rs = npi_txdma_mode32_set(handle, B_TRUE); 80644961713Sgirish if (rs != NPI_SUCCESS) 80744961713Sgirish return (NXGE_ERROR | rs); 80844961713Sgirish #endif 80944961713Sgirish 81044961713Sgirish /* 81144961713Sgirish * Enable WRED and program an initial value. 81244961713Sgirish * Use time to set the initial random number. 81344961713Sgirish */ 81444961713Sgirish (void) drv_getparm(LBOLT, &lbolt); 81544961713Sgirish rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt); 81644961713Sgirish if (rs != NPI_SUCCESS) 81744961713Sgirish return (NXGE_ERROR | rs); 81844961713Sgirish 819*678453a8Sspeer hardware = &nxgep->pt_config.hw_config; 820*678453a8Sspeer for (table = 0; table < NXGE_MAX_RDC_GRPS; table++) { 821*678453a8Sspeer /* Does this table belong to <nxgep>? */ 822*678453a8Sspeer if (hardware->grpids[table] == (nxgep->function_num + 256)) 823*678453a8Sspeer status = nxge_init_fzc_rdc_tbl(nxgep, table); 824*678453a8Sspeer } 82544961713Sgirish 82644961713Sgirish /* Ethernet Timeout Counter (?) */ 82744961713Sgirish 82844961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 82944961713Sgirish "<== nxge_init_fzc_rx_common:status 0x%08x", status)); 83044961713Sgirish 83144961713Sgirish return (status); 83244961713Sgirish } 83344961713Sgirish 83444961713Sgirish nxge_status_t 835*678453a8Sspeer nxge_init_fzc_rdc_tbl(p_nxge_t nxge, int rdc_tbl) 83644961713Sgirish { 837*678453a8Sspeer nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio; 838*678453a8Sspeer nx_rdc_tbl_t *table; 839*678453a8Sspeer nxge_rdc_grp_t *group; 840*678453a8Sspeer npi_handle_t handle; 84144961713Sgirish 842*678453a8Sspeer npi_status_t rs = NPI_SUCCESS; 843*678453a8Sspeer nxge_status_t status = NXGE_OK; 84444961713Sgirish 845*678453a8Sspeer NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_init_fzc_rdc_tbl(%d)", table)); 846*678453a8Sspeer 847*678453a8Sspeer group = &nxge->pt_config.rdc_grps[rdc_tbl]; 848*678453a8Sspeer 849*678453a8Sspeer /* This RDC table must have been previously bound to <nxge>. */ 850*678453a8Sspeer MUTEX_ENTER(&nhd->lock); 851*678453a8Sspeer table = &nhd->rdc_tbl[rdc_tbl]; 852*678453a8Sspeer if (table->nxge != (uintptr_t)nxge) { 853*678453a8Sspeer MUTEX_EXIT(&nhd->lock); 854*678453a8Sspeer NXGE_ERROR_MSG((nxge, DMA_CTL, 855*678453a8Sspeer "nxge_init_fzc_rdc_tbl(%d): not owner", table)); 856*678453a8Sspeer return (NXGE_ERROR); 857*678453a8Sspeer } else { 858*678453a8Sspeer table->map = group->map; 859*678453a8Sspeer } 860*678453a8Sspeer MUTEX_EXIT(&nhd->lock); 861*678453a8Sspeer 862*678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxge); 863*678453a8Sspeer 864*678453a8Sspeer rs = npi_rxdma_rdc_table_config(handle, rdc_tbl, 865*678453a8Sspeer group->map, group->max_rdcs); 866*678453a8Sspeer 867*678453a8Sspeer if (rs != NPI_SUCCESS) { 868*678453a8Sspeer status = NXGE_ERROR | rs; 86944961713Sgirish } 87044961713Sgirish 871*678453a8Sspeer NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_init_fzc_rdc_tbl(%d)", table)); 87244961713Sgirish return (status); 87344961713Sgirish } 87444961713Sgirish 875*678453a8Sspeer static 876*678453a8Sspeer int 877*678453a8Sspeer rdc_tbl_bind(p_nxge_t nxge, int rdc_tbl) 878*678453a8Sspeer { 879*678453a8Sspeer nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio; 880*678453a8Sspeer nx_rdc_tbl_t *table; 881*678453a8Sspeer int i; 882*678453a8Sspeer 883*678453a8Sspeer NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_bind")); 884*678453a8Sspeer 885*678453a8Sspeer MUTEX_ENTER(&nhd->lock); 886*678453a8Sspeer /* is the caller asking for a particular table? */ 887*678453a8Sspeer if (rdc_tbl >= 0 && rdc_tbl < NXGE_MAX_RDC_GROUPS) { 888*678453a8Sspeer table = &nhd->rdc_tbl[rdc_tbl]; 889*678453a8Sspeer if (table->nxge == 0) { 890*678453a8Sspeer table->nxge = (uintptr_t)nxge; /* It is now bound. */ 891*678453a8Sspeer NXGE_DEBUG_MSG((nxge, DMA_CTL, 892*678453a8Sspeer "<== nxge_fzc_rdc_tbl_bind(%d)", rdc_tbl)); 893*678453a8Sspeer MUTEX_EXIT(&nhd->lock); 894*678453a8Sspeer return (rdc_tbl); 895*678453a8Sspeer } 896*678453a8Sspeer } else { /* The caller will take any old RDC table. */ 897*678453a8Sspeer for (i = 0; i < NXGE_MAX_RDC_GROUPS; i++) { 898*678453a8Sspeer nx_rdc_tbl_t *table = &nhd->rdc_tbl[i]; 899*678453a8Sspeer if (table->nxge == 0) { 900*678453a8Sspeer table->nxge = (uintptr_t)nxge; 901*678453a8Sspeer /* It is now bound. */ 902*678453a8Sspeer MUTEX_EXIT(&nhd->lock); 903*678453a8Sspeer NXGE_DEBUG_MSG((nxge, DMA_CTL, 904*678453a8Sspeer "<== nxge_fzc_rdc_tbl_bind: %d", i)); 905*678453a8Sspeer return (i); 906*678453a8Sspeer } 907*678453a8Sspeer } 908*678453a8Sspeer } 909*678453a8Sspeer MUTEX_EXIT(&nhd->lock); 910*678453a8Sspeer 911*678453a8Sspeer NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_fzc_rdc_tbl_bind")); 912*678453a8Sspeer 913*678453a8Sspeer return (-EBUSY); /* RDC tables are bound. */ 914*678453a8Sspeer } 915*678453a8Sspeer 916*678453a8Sspeer int 917*678453a8Sspeer nxge_fzc_rdc_tbl_bind( 918*678453a8Sspeer nxge_t *nxge, 919*678453a8Sspeer int grp_index, 920*678453a8Sspeer int acceptNoSubstitutes) 921*678453a8Sspeer { 922*678453a8Sspeer nxge_hw_pt_cfg_t *hardware; 923*678453a8Sspeer int index; 924*678453a8Sspeer 925*678453a8Sspeer hardware = &nxge->pt_config.hw_config; 926*678453a8Sspeer 927*678453a8Sspeer if ((index = rdc_tbl_bind(nxge, grp_index)) < 0) { 928*678453a8Sspeer if (acceptNoSubstitutes) 929*678453a8Sspeer return (index); 930*678453a8Sspeer index = rdc_tbl_bind(nxge, grp_index); 931*678453a8Sspeer if (index < 0) { 932*678453a8Sspeer NXGE_ERROR_MSG((nxge, OBP_CTL, 933*678453a8Sspeer "nxge_fzc_rdc_tbl_init: " 934*678453a8Sspeer "there are no free RDC tables!")); 935*678453a8Sspeer return (index); 936*678453a8Sspeer } 937*678453a8Sspeer } 938*678453a8Sspeer 939*678453a8Sspeer hardware->grpids[index] = nxge->function_num + 256; 940*678453a8Sspeer 941*678453a8Sspeer return (index); 942*678453a8Sspeer } 943*678453a8Sspeer 944*678453a8Sspeer int 945*678453a8Sspeer nxge_fzc_rdc_tbl_unbind(p_nxge_t nxge, int rdc_tbl) 946*678453a8Sspeer { 947*678453a8Sspeer nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio; 948*678453a8Sspeer nx_rdc_tbl_t *table; 949*678453a8Sspeer 950*678453a8Sspeer NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_unbind(%d)", 951*678453a8Sspeer rdc_tbl)); 952*678453a8Sspeer 953*678453a8Sspeer table = &nhd->rdc_tbl[rdc_tbl]; 954*678453a8Sspeer if (table->nxge != (uintptr_t)nxge) { 955*678453a8Sspeer NXGE_ERROR_MSG((nxge, DMA_CTL, 956*678453a8Sspeer "nxge_fzc_rdc_tbl_unbind(%d): func%d not owner", 957*678453a8Sspeer nxge->function_num, rdc_tbl)); 958*678453a8Sspeer return (EINVAL); 959*678453a8Sspeer } else { 960*678453a8Sspeer bzero(table, sizeof (*table)); 961*678453a8Sspeer } 962*678453a8Sspeer 963*678453a8Sspeer NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_fzc_rdc_tbl_unbind(%d)", 964*678453a8Sspeer rdc_tbl)); 965*678453a8Sspeer 966*678453a8Sspeer return (0); 967*678453a8Sspeer } 968*678453a8Sspeer 96944961713Sgirish nxge_status_t 97044961713Sgirish nxge_init_fzc_rxdma_port(p_nxge_t nxgep) 97144961713Sgirish { 97244961713Sgirish npi_handle_t handle; 97344961713Sgirish p_nxge_dma_pt_cfg_t p_all_cfgp; 97444961713Sgirish p_nxge_hw_pt_cfg_t p_cfgp; 97544961713Sgirish hostinfo_t hostinfo; 97644961713Sgirish int i; 97744961713Sgirish npi_status_t rs = NPI_SUCCESS; 97844961713Sgirish p_nxge_class_pt_cfg_t p_class_cfgp; 97944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port")); 98044961713Sgirish 98144961713Sgirish p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 98244961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 98344961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 98444961713Sgirish /* 98544961713Sgirish * Initialize the port scheduler DRR weight. 98644961713Sgirish * npi_rxdma_cfg_port_ddr_weight(); 98744961713Sgirish */ 98844961713Sgirish 9892e59129aSraghus if ((nxgep->mac.portmode == PORT_1G_COPPER) || 9902e59129aSraghus (nxgep->mac.portmode == PORT_1G_FIBER) || 9912e59129aSraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 9922e59129aSraghus rs = npi_rxdma_cfg_port_ddr_weight(handle, 9932e59129aSraghus nxgep->function_num, NXGE_RX_DRR_WT_1G); 9942e59129aSraghus if (rs != NPI_SUCCESS) { 9952e59129aSraghus return (NXGE_ERROR | rs); 99644961713Sgirish } 99744961713Sgirish } 99844961713Sgirish 99944961713Sgirish /* Program the default RDC of a port */ 100044961713Sgirish rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num, 1001*678453a8Sspeer p_cfgp->def_rdc); 100244961713Sgirish if (rs != NPI_SUCCESS) { 100344961713Sgirish return (NXGE_ERROR | rs); 100444961713Sgirish } 100544961713Sgirish 100644961713Sgirish /* 100744961713Sgirish * Configure the MAC host info table with RDC tables 100844961713Sgirish */ 100944961713Sgirish hostinfo.value = 0; 101044961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 101144961713Sgirish for (i = 0; i < p_cfgp->max_macs; i++) { 1012*678453a8Sspeer hostinfo.bits.w0.rdc_tbl_num = p_cfgp->def_mac_rxdma_grpid; 101344961713Sgirish hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref; 101444961713Sgirish if (p_class_cfgp->mac_host_info[i].flag) { 101544961713Sgirish hostinfo.bits.w0.rdc_tbl_num = 101644961713Sgirish p_class_cfgp->mac_host_info[i].rdctbl; 101744961713Sgirish hostinfo.bits.w0.mac_pref = 101844961713Sgirish p_class_cfgp->mac_host_info[i].mpr_npr; 101944961713Sgirish } 102044961713Sgirish 102144961713Sgirish rs = npi_mac_hostinfo_entry(handle, OP_SET, 102244961713Sgirish nxgep->function_num, i, &hostinfo); 102344961713Sgirish if (rs != NPI_SUCCESS) 102444961713Sgirish return (NXGE_ERROR | rs); 102544961713Sgirish } 102644961713Sgirish 102744961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 102844961713Sgirish "<== nxge_init_fzc_rxdma_port rs 0x%08x", rs)); 102944961713Sgirish 103044961713Sgirish return (NXGE_OK); 103144961713Sgirish 103244961713Sgirish } 103344961713Sgirish 103444961713Sgirish nxge_status_t 103544961713Sgirish nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc) 103644961713Sgirish { 103744961713Sgirish npi_status_t rs = NPI_SUCCESS; 103844961713Sgirish rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle, 103944961713Sgirish port, rdc); 104044961713Sgirish if (rs & NPI_FAILURE) 104144961713Sgirish return (NXGE_ERROR | rs); 104244961713Sgirish return (NXGE_OK); 104344961713Sgirish } 104444961713Sgirish 1045*678453a8Sspeer /* 1046*678453a8Sspeer * nxge_init_fzc_tdc_pages 1047*678453a8Sspeer * 1048*678453a8Sspeer * Configure a TDC's logical pages. 1049*678453a8Sspeer * 1050*678453a8Sspeer * This function is executed by the service domain, on behalf of 1051*678453a8Sspeer * a guest domain, to whom this TDC has been loaned. 1052*678453a8Sspeer * 1053*678453a8Sspeer * Arguments: 1054*678453a8Sspeer * nxgep 1055*678453a8Sspeer * channel The channel to initialize. 1056*678453a8Sspeer * page0 Logical page 0 definition. 1057*678453a8Sspeer * page1 Logical page 1 definition. 1058*678453a8Sspeer * 1059*678453a8Sspeer * Notes: 1060*678453a8Sspeer * I think that this function can be called from any 1061*678453a8Sspeer * domain, but I need to check. 1062*678453a8Sspeer * 1063*678453a8Sspeer * NPI/NXGE function calls: 1064*678453a8Sspeer * hv_niu_tx_logical_page_conf() 1065*678453a8Sspeer * hv_niu_tx_logical_page_info() 1066*678453a8Sspeer * 1067*678453a8Sspeer * Context: 1068*678453a8Sspeer * Any domain 1069*678453a8Sspeer */ 1070*678453a8Sspeer nxge_status_t 1071*678453a8Sspeer nxge_init_fzc_tdc_pages( 1072*678453a8Sspeer p_nxge_t nxgep, 1073*678453a8Sspeer uint16_t channel, 1074*678453a8Sspeer dma_log_page_t *page0, 1075*678453a8Sspeer dma_log_page_t *page1) 1076*678453a8Sspeer { 1077*678453a8Sspeer npi_handle_t handle; 1078*678453a8Sspeer npi_status_t rs; 1079*678453a8Sspeer 1080*678453a8Sspeer log_page_hdl_t page_handle; 1081*678453a8Sspeer 1082*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1083*678453a8Sspeer "==> nxge_init_fzc_txdma_channel_pages")); 1084*678453a8Sspeer 1085*678453a8Sspeer #ifndef NIU_HV_WORKAROUND 1086*678453a8Sspeer if (nxgep->niu_type == N2_NIU) { 1087*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1088*678453a8Sspeer "<== nxge_init_fzc_tdc_pages: " 1089*678453a8Sspeer "N2_NIU: no need to set txdma logical pages")); 1090*678453a8Sspeer return (NXGE_OK); 1091*678453a8Sspeer } 1092*678453a8Sspeer #else 1093*678453a8Sspeer if (nxgep->niu_type == N2_NIU) { 1094*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, DMA_CTL, 1095*678453a8Sspeer "<== nxge_init_fzc_tdc_pages: " 1096*678453a8Sspeer "N2_NIU: NEED to set txdma logical pages")); 1097*678453a8Sspeer } 1098*678453a8Sspeer #endif 1099*678453a8Sspeer 1100*678453a8Sspeer /* 1101*678453a8Sspeer * Initialize logical page 1. 1102*678453a8Sspeer */ 1103*678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep); 1104*678453a8Sspeer if ((rs = npi_txdma_log_page_set(handle, channel, page0)) 1105*678453a8Sspeer != NPI_SUCCESS) 1106*678453a8Sspeer return (NXGE_ERROR | rs); 1107*678453a8Sspeer 1108*678453a8Sspeer /* 1109*678453a8Sspeer * Initialize logical page 2. 1110*678453a8Sspeer */ 1111*678453a8Sspeer if ((rs = npi_txdma_log_page_set(handle, channel, page1)) 1112*678453a8Sspeer != NPI_SUCCESS) 1113*678453a8Sspeer return (NXGE_ERROR | rs); 1114*678453a8Sspeer 1115*678453a8Sspeer /* 1116*678453a8Sspeer * Initialize the page handle. 1117*678453a8Sspeer * (In the current driver, this is always set to 0.) 1118*678453a8Sspeer */ 1119*678453a8Sspeer page_handle.value = 0; 1120*678453a8Sspeer rs = npi_txdma_log_page_handle_set(handle, channel, &page_handle); 1121*678453a8Sspeer if (rs == NPI_SUCCESS) { 1122*678453a8Sspeer return (NXGE_OK); 1123*678453a8Sspeer } else { 1124*678453a8Sspeer return (NXGE_ERROR | rs); 1125*678453a8Sspeer } 1126*678453a8Sspeer } 1127*678453a8Sspeer 112844961713Sgirish nxge_status_t 112944961713Sgirish nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 113044961713Sgirish p_tx_ring_t tx_ring_p) 113144961713Sgirish { 113244961713Sgirish npi_handle_t handle; 113344961713Sgirish dma_log_page_t cfg; 113444961713Sgirish npi_status_t rs = NPI_SUCCESS; 113544961713Sgirish 113644961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 113744961713Sgirish "==> nxge_init_fzc_txdma_channel_pages")); 113844961713Sgirish 113944961713Sgirish #ifndef NIU_HV_WORKAROUND 114044961713Sgirish if (nxgep->niu_type == N2_NIU) { 114144961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 114244961713Sgirish "<== nxge_init_fzc_txdma_channel_pages: " 114344961713Sgirish "N2_NIU: no need to set txdma logical pages")); 114444961713Sgirish return (NXGE_OK); 114544961713Sgirish } 114644961713Sgirish #else 114744961713Sgirish if (nxgep->niu_type == N2_NIU) { 114844961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 114944961713Sgirish "<== nxge_init_fzc_txdma_channel_pages: " 115044961713Sgirish "N2_NIU: NEED to set txdma logical pages")); 115144961713Sgirish } 115244961713Sgirish #endif 115344961713Sgirish 115444961713Sgirish /* 115544961713Sgirish * Initialize logical page 1. 115644961713Sgirish */ 115744961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 115844961713Sgirish cfg.func_num = nxgep->function_num; 115944961713Sgirish cfg.page_num = 0; 116044961713Sgirish cfg.valid = tx_ring_p->page_valid.bits.ldw.page0; 116144961713Sgirish cfg.value = tx_ring_p->page_value_1.value; 116244961713Sgirish cfg.mask = tx_ring_p->page_mask_1.value; 116344961713Sgirish cfg.reloc = tx_ring_p->page_reloc_1.value; 116444961713Sgirish 116544961713Sgirish rs = npi_txdma_log_page_set(handle, channel, 116644961713Sgirish (p_dma_log_page_t)&cfg); 116744961713Sgirish if (rs != NPI_SUCCESS) { 116844961713Sgirish return (NXGE_ERROR | rs); 116944961713Sgirish } 117044961713Sgirish 117144961713Sgirish /* 117244961713Sgirish * Initialize logical page 2. 117344961713Sgirish */ 117444961713Sgirish cfg.page_num = 1; 117544961713Sgirish cfg.valid = tx_ring_p->page_valid.bits.ldw.page1; 117644961713Sgirish cfg.value = tx_ring_p->page_value_2.value; 117744961713Sgirish cfg.mask = tx_ring_p->page_mask_2.value; 117844961713Sgirish cfg.reloc = tx_ring_p->page_reloc_2.value; 117944961713Sgirish 118044961713Sgirish rs = npi_txdma_log_page_set(handle, channel, &cfg); 118144961713Sgirish if (rs != NPI_SUCCESS) { 118244961713Sgirish return (NXGE_ERROR | rs); 118344961713Sgirish } 118444961713Sgirish 118544961713Sgirish /* Initialize the page handle */ 118644961713Sgirish rs = npi_txdma_log_page_handle_set(handle, channel, 118744961713Sgirish &tx_ring_p->page_hdl); 118844961713Sgirish 118944961713Sgirish if (rs == NPI_SUCCESS) { 119044961713Sgirish return (NXGE_OK); 119144961713Sgirish } else { 119244961713Sgirish return (NXGE_ERROR | rs); 119344961713Sgirish } 119444961713Sgirish } 119544961713Sgirish 119644961713Sgirish 119744961713Sgirish nxge_status_t 119844961713Sgirish nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel, 119944961713Sgirish p_tx_ring_t tx_ring_p) 120044961713Sgirish { 120144961713Sgirish npi_status_t rs = NPI_SUCCESS; 120244961713Sgirish npi_handle_t handle; 120344961713Sgirish 120444961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 120544961713Sgirish rs = npi_txc_dma_max_burst_set(handle, channel, 120644961713Sgirish tx_ring_p->max_burst.value); 120744961713Sgirish if (rs == NPI_SUCCESS) { 120844961713Sgirish return (NXGE_OK); 120944961713Sgirish } else { 121044961713Sgirish return (NXGE_ERROR | rs); 121144961713Sgirish } 121244961713Sgirish } 121344961713Sgirish 121444961713Sgirish nxge_status_t 121544961713Sgirish nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask) 121644961713Sgirish { 121744961713Sgirish npi_status_t rs = NPI_SUCCESS; 121844961713Sgirish npi_handle_t handle; 121944961713Sgirish 122044961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 122144961713Sgirish rs = npi_fzc_sys_err_mask_set(handle, mask); 122244961713Sgirish if (rs == NPI_SUCCESS) { 122344961713Sgirish return (NXGE_OK); 122444961713Sgirish } else { 122544961713Sgirish return (NXGE_ERROR | rs); 122644961713Sgirish } 122744961713Sgirish } 122844961713Sgirish 1229*678453a8Sspeer /* 1230*678453a8Sspeer * nxge_init_hv_fzc_txdma_channel_pages 1231*678453a8Sspeer * 1232*678453a8Sspeer * Configure a TDC's logical pages. 1233*678453a8Sspeer * 1234*678453a8Sspeer * Arguments: 1235*678453a8Sspeer * nxgep 1236*678453a8Sspeer * channel The channel to initialize. 1237*678453a8Sspeer * tx_ring_p The transmit ring. 1238*678453a8Sspeer * 1239*678453a8Sspeer * Notes: 1240*678453a8Sspeer * I think that this function can be called from any 1241*678453a8Sspeer * domain, but I need to check. 1242*678453a8Sspeer * 1243*678453a8Sspeer * NPI/NXGE function calls: 1244*678453a8Sspeer * hv_niu_tx_logical_page_conf() 1245*678453a8Sspeer * hv_niu_tx_logical_page_info() 1246*678453a8Sspeer * 1247*678453a8Sspeer * Context: 1248*678453a8Sspeer * Any domain 1249*678453a8Sspeer */ 1250*678453a8Sspeer #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 125144961713Sgirish nxge_status_t 125244961713Sgirish nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel, 125344961713Sgirish p_tx_ring_t tx_ring_p) 125444961713Sgirish { 125544961713Sgirish int err; 125644961713Sgirish uint64_t hverr; 125744961713Sgirish #ifdef DEBUG 125844961713Sgirish uint64_t ra, size; 125944961713Sgirish #endif 126044961713Sgirish 126144961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, 126244961713Sgirish "==> nxge_init_hv_fzc_txdma_channel_pages")); 126344961713Sgirish 126444961713Sgirish if (tx_ring_p->hv_set) { 126544961713Sgirish return (NXGE_OK); 126644961713Sgirish } 126744961713Sgirish 126844961713Sgirish /* 126944961713Sgirish * Initialize logical page 1 for data buffers. 127044961713Sgirish */ 127144961713Sgirish hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 127244961713Sgirish (uint64_t)0, 127344961713Sgirish tx_ring_p->hv_tx_buf_base_ioaddr_pp, 127444961713Sgirish tx_ring_p->hv_tx_buf_ioaddr_size); 127544961713Sgirish 127644961713Sgirish err = (nxge_status_t)nxge_herr2kerr(hverr); 127744961713Sgirish if (err != 0) { 127844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 127944961713Sgirish "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d " 128044961713Sgirish "error status 0x%x " 128144961713Sgirish "(page 0 data buf) hverr 0x%llx " 128244961713Sgirish "ioaddr_pp $%p " 128344961713Sgirish "size 0x%llx ", 128444961713Sgirish channel, 128544961713Sgirish err, 128644961713Sgirish hverr, 128744961713Sgirish tx_ring_p->hv_tx_buf_base_ioaddr_pp, 128844961713Sgirish tx_ring_p->hv_tx_buf_ioaddr_size)); 128944961713Sgirish return (NXGE_ERROR | err); 129044961713Sgirish } 129144961713Sgirish 129244961713Sgirish #ifdef DEBUG 129344961713Sgirish ra = size = 0; 129444961713Sgirish hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 129544961713Sgirish (uint64_t)0, 129644961713Sgirish &ra, 129744961713Sgirish &size); 129844961713Sgirish 129944961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, 130044961713Sgirish "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 130144961713Sgirish "ok status 0x%x " 130244961713Sgirish "(page 0 data buf) hverr 0x%llx " 130344961713Sgirish "set ioaddr_pp $%p " 130444961713Sgirish "set size 0x%llx " 130544961713Sgirish "get ra ioaddr_pp $%p " 130644961713Sgirish "get size 0x%llx ", 130744961713Sgirish channel, 130844961713Sgirish err, 130944961713Sgirish hverr, 131044961713Sgirish tx_ring_p->hv_tx_buf_base_ioaddr_pp, 131144961713Sgirish tx_ring_p->hv_tx_buf_ioaddr_size, 131244961713Sgirish ra, 131344961713Sgirish size)); 131444961713Sgirish #endif 131544961713Sgirish 131644961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, 131744961713Sgirish "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 131844961713Sgirish "(page 0 data buf) hverr 0x%llx " 131944961713Sgirish "ioaddr_pp $%p " 132044961713Sgirish "size 0x%llx ", 132144961713Sgirish channel, 132244961713Sgirish hverr, 132344961713Sgirish tx_ring_p->hv_tx_buf_base_ioaddr_pp, 132444961713Sgirish tx_ring_p->hv_tx_buf_ioaddr_size)); 132544961713Sgirish 132644961713Sgirish /* 132744961713Sgirish * Initialize logical page 2 for control buffers. 132844961713Sgirish */ 132944961713Sgirish hverr = hv_niu_tx_logical_page_conf((uint64_t)channel, 133044961713Sgirish (uint64_t)1, 133144961713Sgirish tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 133244961713Sgirish tx_ring_p->hv_tx_cntl_ioaddr_size); 133344961713Sgirish 133444961713Sgirish err = (nxge_status_t)nxge_herr2kerr(hverr); 133544961713Sgirish 133644961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, 133744961713Sgirish "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d" 133844961713Sgirish "ok status 0x%x " 133944961713Sgirish "(page 1 cntl buf) hverr 0x%llx " 134044961713Sgirish "ioaddr_pp $%p " 134144961713Sgirish "size 0x%llx ", 134244961713Sgirish channel, 134344961713Sgirish err, 134444961713Sgirish hverr, 134544961713Sgirish tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 134644961713Sgirish tx_ring_p->hv_tx_cntl_ioaddr_size)); 134744961713Sgirish 134844961713Sgirish if (err != 0) { 134944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 135044961713Sgirish "<== nxge_init_hv_fzc_txdma_channel_pages: channel %d" 135144961713Sgirish "error status 0x%x " 135244961713Sgirish "(page 1 cntl buf) hverr 0x%llx " 135344961713Sgirish "ioaddr_pp $%p " 135444961713Sgirish "size 0x%llx ", 135544961713Sgirish channel, 135644961713Sgirish err, 135744961713Sgirish hverr, 135844961713Sgirish tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 135944961713Sgirish tx_ring_p->hv_tx_cntl_ioaddr_size)); 136044961713Sgirish return (NXGE_ERROR | err); 136144961713Sgirish } 136244961713Sgirish 136344961713Sgirish #ifdef DEBUG 136444961713Sgirish ra = size = 0; 136544961713Sgirish hverr = hv_niu_tx_logical_page_info((uint64_t)channel, 136644961713Sgirish (uint64_t)1, 136744961713Sgirish &ra, 136844961713Sgirish &size); 136944961713Sgirish 137044961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, 137144961713Sgirish "==> nxge_init_hv_fzc_txdma_channel_pages: channel %d " 137244961713Sgirish "(page 1 cntl buf) hverr 0x%llx " 137344961713Sgirish "set ioaddr_pp $%p " 137444961713Sgirish "set size 0x%llx " 137544961713Sgirish "get ra ioaddr_pp $%p " 137644961713Sgirish "get size 0x%llx ", 137744961713Sgirish channel, 137844961713Sgirish hverr, 137944961713Sgirish tx_ring_p->hv_tx_cntl_base_ioaddr_pp, 138044961713Sgirish tx_ring_p->hv_tx_cntl_ioaddr_size, 138144961713Sgirish ra, 138244961713Sgirish size)); 138344961713Sgirish #endif 138444961713Sgirish 138544961713Sgirish tx_ring_p->hv_set = B_TRUE; 138644961713Sgirish 138744961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, 138844961713Sgirish "<== nxge_init_hv_fzc_txdma_channel_pages")); 138944961713Sgirish 139044961713Sgirish return (NXGE_OK); 139144961713Sgirish } 139244961713Sgirish 139344961713Sgirish /*ARGSUSED*/ 139444961713Sgirish nxge_status_t 139544961713Sgirish nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep, 139644961713Sgirish uint16_t channel, p_rx_rbr_ring_t rbrp) 139744961713Sgirish { 139844961713Sgirish int err; 139944961713Sgirish uint64_t hverr; 140044961713Sgirish #ifdef DEBUG 140144961713Sgirish uint64_t ra, size; 140244961713Sgirish #endif 140344961713Sgirish 140444961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, 140544961713Sgirish "==> nxge_init_hv_fzc_rxdma_channel_pages")); 140644961713Sgirish 140744961713Sgirish if (rbrp->hv_set) { 140844961713Sgirish return (NXGE_OK); 140944961713Sgirish } 141044961713Sgirish 141144961713Sgirish /* Initialize data buffers for page 0 */ 141244961713Sgirish hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 141344961713Sgirish (uint64_t)0, 141444961713Sgirish rbrp->hv_rx_buf_base_ioaddr_pp, 141544961713Sgirish rbrp->hv_rx_buf_ioaddr_size); 141644961713Sgirish err = (nxge_status_t)nxge_herr2kerr(hverr); 141744961713Sgirish if (err != 0) { 141844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 141944961713Sgirish "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 142044961713Sgirish "error status 0x%x " 142144961713Sgirish "(page 0 data buf) hverr 0x%llx " 142244961713Sgirish "ioaddr_pp $%p " 142344961713Sgirish "size 0x%llx ", 142444961713Sgirish channel, 142544961713Sgirish err, 142644961713Sgirish hverr, 142744961713Sgirish rbrp->hv_rx_buf_base_ioaddr_pp, 142844961713Sgirish rbrp->hv_rx_buf_ioaddr_size)); 142944961713Sgirish 143044961713Sgirish return (NXGE_ERROR | err); 143144961713Sgirish } 143244961713Sgirish 143344961713Sgirish #ifdef DEBUG 143444961713Sgirish ra = size = 0; 143544961713Sgirish (void) hv_niu_rx_logical_page_info((uint64_t)channel, 143644961713Sgirish (uint64_t)0, 143744961713Sgirish &ra, 143844961713Sgirish &size); 143944961713Sgirish 144044961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, 144144961713Sgirish "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 144244961713Sgirish "ok status 0x%x " 144344961713Sgirish "(page 0 data buf) hverr 0x%llx " 144444961713Sgirish "set databuf ioaddr_pp $%p " 144544961713Sgirish "set databuf size 0x%llx " 144644961713Sgirish "get databuf ra ioaddr_pp %p " 144744961713Sgirish "get databuf size 0x%llx", 144844961713Sgirish channel, 144944961713Sgirish err, 145044961713Sgirish hverr, 145144961713Sgirish rbrp->hv_rx_buf_base_ioaddr_pp, 145244961713Sgirish rbrp->hv_rx_buf_ioaddr_size, 145344961713Sgirish ra, 145444961713Sgirish size)); 145544961713Sgirish #endif 145644961713Sgirish 145744961713Sgirish /* Initialize control buffers for logical page 1. */ 145844961713Sgirish hverr = hv_niu_rx_logical_page_conf((uint64_t)channel, 145944961713Sgirish (uint64_t)1, 146044961713Sgirish rbrp->hv_rx_cntl_base_ioaddr_pp, 146144961713Sgirish rbrp->hv_rx_cntl_ioaddr_size); 146244961713Sgirish 146344961713Sgirish err = (nxge_status_t)nxge_herr2kerr(hverr); 146444961713Sgirish if (err != 0) { 146544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 146644961713Sgirish "<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d" 146744961713Sgirish "error status 0x%x " 146844961713Sgirish "(page 1 cntl buf) hverr 0x%llx " 146944961713Sgirish "ioaddr_pp $%p " 147044961713Sgirish "size 0x%llx ", 147144961713Sgirish channel, 147244961713Sgirish err, 147344961713Sgirish hverr, 147444961713Sgirish rbrp->hv_rx_buf_base_ioaddr_pp, 147544961713Sgirish rbrp->hv_rx_buf_ioaddr_size)); 147644961713Sgirish 147744961713Sgirish return (NXGE_ERROR | err); 147844961713Sgirish } 147944961713Sgirish 148044961713Sgirish #ifdef DEBUG 148144961713Sgirish ra = size = 0; 148244961713Sgirish (void) hv_niu_rx_logical_page_info((uint64_t)channel, 148344961713Sgirish (uint64_t)1, 148444961713Sgirish &ra, 148544961713Sgirish &size); 148644961713Sgirish 148744961713Sgirish 148844961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, 148944961713Sgirish "==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d " 149044961713Sgirish "error status 0x%x " 149144961713Sgirish "(page 1 cntl buf) hverr 0x%llx " 149244961713Sgirish "set cntl ioaddr_pp $%p " 149344961713Sgirish "set cntl size 0x%llx " 149444961713Sgirish "get cntl ioaddr_pp $%p " 149544961713Sgirish "get cntl size 0x%llx ", 149644961713Sgirish channel, 149744961713Sgirish err, 149844961713Sgirish hverr, 149944961713Sgirish rbrp->hv_rx_cntl_base_ioaddr_pp, 150044961713Sgirish rbrp->hv_rx_cntl_ioaddr_size, 150144961713Sgirish ra, 150244961713Sgirish size)); 150344961713Sgirish #endif 150444961713Sgirish 150544961713Sgirish rbrp->hv_set = B_FALSE; 150644961713Sgirish 150744961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, 150844961713Sgirish "<== nxge_init_hv_fzc_rxdma_channel_pages")); 150944961713Sgirish 151044961713Sgirish return (NXGE_OK); 151144961713Sgirish } 151244961713Sgirish 151344961713Sgirish /* 151444961713Sgirish * Map hypervisor error code to errno. Only 151544961713Sgirish * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful 151644961713Sgirish * for niu driver. Any other error codes are mapped to EINVAL. 151744961713Sgirish */ 151844961713Sgirish static int 151944961713Sgirish nxge_herr2kerr(uint64_t hv_errcode) 152044961713Sgirish { 152144961713Sgirish int s_errcode; 152244961713Sgirish 152344961713Sgirish switch (hv_errcode) { 152444961713Sgirish case H_ENORADDR: 152544961713Sgirish case H_EBADALIGN: 152644961713Sgirish s_errcode = EFAULT; 152744961713Sgirish break; 152844961713Sgirish case H_EOK: 152944961713Sgirish s_errcode = 0; 153044961713Sgirish break; 153144961713Sgirish default: 153244961713Sgirish s_errcode = EINVAL; 153344961713Sgirish break; 153444961713Sgirish } 153544961713Sgirish return (s_errcode); 153644961713Sgirish } 153744961713Sgirish 153844961713Sgirish #endif /* sun4v and NIU_LP_WORKAROUND */ 1539