1*678453a8Sspeer /* 2*678453a8Sspeer * CDDL HEADER START 3*678453a8Sspeer * 4*678453a8Sspeer * The contents of this file are subject to the terms of the 5*678453a8Sspeer * Common Development and Distribution License (the "License"). 6*678453a8Sspeer * You may not use this file except in compliance with the License. 7*678453a8Sspeer * 8*678453a8Sspeer * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*678453a8Sspeer * or http://www.opensolaris.org/os/licensing. 10*678453a8Sspeer * See the License for the specific language governing permissions 11*678453a8Sspeer * and limitations under the License. 12*678453a8Sspeer * 13*678453a8Sspeer * When distributing Covered Code, include this CDDL HEADER in each 14*678453a8Sspeer * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*678453a8Sspeer * If applicable, add the following below this CDDL HEADER, with the 16*678453a8Sspeer * fields enclosed by brackets "[]" replaced with your own identifying 17*678453a8Sspeer * information: Portions Copyright [yyyy] [name of copyright owner] 18*678453a8Sspeer * 19*678453a8Sspeer * CDDL HEADER END 20*678453a8Sspeer */ 21*678453a8Sspeer /* 22*678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*678453a8Sspeer * Use is subject to license terms. 24*678453a8Sspeer */ 25*678453a8Sspeer 26*678453a8Sspeer #ifndef _NPI_RX_RD32_H 27*678453a8Sspeer #define _NPI_RX_RD32_H 28*678453a8Sspeer 29*678453a8Sspeer #pragma ident "%Z%%M% %I% %E% SMI" 30*678453a8Sspeer 31*678453a8Sspeer #ifdef __cplusplus 32*678453a8Sspeer extern "C" { 33*678453a8Sspeer #endif 34*678453a8Sspeer 35*678453a8Sspeer #include <npi.h> 36*678453a8Sspeer 37*678453a8Sspeer static uint32_t RXDMA_REG_READ32(npi_handle_t, uint32_t, int); 38*678453a8Sspeer #pragma inline(RXDMA_REG_READ32) 39*678453a8Sspeer 40*678453a8Sspeer /* 41*678453a8Sspeer * RXDMA_REG_READ32 42*678453a8Sspeer * 43*678453a8Sspeer * Read a 32-bit value from a DMC register. 44*678453a8Sspeer * 45*678453a8Sspeer * Arguments: 46*678453a8Sspeer * handle The NPI handle to use. 47*678453a8Sspeer * offset The offset into the DMA CSR (the register). 48*678453a8Sspeer * channel The channel, which is used as a multiplicand. 49*678453a8Sspeer * 50*678453a8Sspeer * Notes: 51*678453a8Sspeer * If handle.regp is a virtual address (the address of a VR), 52*678453a8Sspeer * we have to subtract the value DMC right off the bat. DMC 53*678453a8Sspeer * is defined as 0x600000, which works in a non-virtual address 54*678453a8Sspeer * space, but not in a VR. In a VR, a DMA CSR's space begins 55*678453a8Sspeer * at zero (0). So, since every call to RXMDA_REG_READ32 uses 56*678453a8Sspeer * a register macro which adds in DMC, we have to subtract it. 57*678453a8Sspeer * 58*678453a8Sspeer * The rest of it is pretty straighforward. In a VR, a channel is 59*678453a8Sspeer * logical, not absolute; and every DMA CSR is 512 bytes big; 60*678453a8Sspeer * furthermore, a subpage of a VR is always ordered with the 61*678453a8Sspeer * transmit CSRs first, followed by the receive CSRs. That is, 62*678453a8Sspeer * a 512 byte space of Tx CSRs, followed by a 512 byte space of 63*678453a8Sspeer * Rx CSRs. Hence this calculation: 64*678453a8Sspeer * 65*678453a8Sspeer * offset += ((channel << 1) + 1) << DMA_CSR_SLL; 66*678453a8Sspeer * 67*678453a8Sspeer * Here's an example: 68*678453a8Sspeer * 69*678453a8Sspeer * RXDMA_REG_READ32(handle, RX_DMA_CTL_STAT_REG, channel); 70*678453a8Sspeer * Let's say channel is 3 71*678453a8Sspeer * #define RX_DMA_CTL_STAT_REG (DMC + 0x00070) 72*678453a8Sspeer * offset = 0x600070 73*678453a8Sspeer * offset &= 0xff = 0x70 74*678453a8Sspeer * offset += ((3 << 1) + 1) << 9 75*678453a8Sspeer * 3 << 1 = 6 76*678453a8Sspeer * 6 + 1 = 7 77*678453a8Sspeer * 7 << 9 = 0xe00 78*678453a8Sspeer * offset += 0xe00 = 0xe70 79*678453a8Sspeer * 80*678453a8Sspeer * Therefore, our register's (virtual) PIO address is 0xe70. 81*678453a8Sspeer * 82*678453a8Sspeer * cf. Table 10-6 on page 181 of the Neptune PRM, v 1.4: 83*678453a8Sspeer * 84*678453a8Sspeer * E00 - FFF CSRs for bound logical receive DMA channel 3. 85*678453a8Sspeer * 86*678453a8Sspeer * In a non-virtual environment, you simply multiply the absolute 87*678453a8Sspeer * channel number by 512 bytes, and get the correct offset to 88*678453a8Sspeer * the register you're looking for. That is, the RX_DMA_CTL_STAT CSR, 89*678453a8Sspeer * is, as are all of these registers, in a table where each channel 90*678453a8Sspeer * is offset 512 bytes from the previous channel (count 16 step 512). 91*678453a8Sspeer * 92*678453a8Sspeer * offset += (channel << DMA_CSR_SLL); // channel<<9 = channel*512 93*678453a8Sspeer * 94*678453a8Sspeer * Here's an example: 95*678453a8Sspeer * 96*678453a8Sspeer * RXDMA_REG_READ32(handle, RX_DMA_CTL_STAT_REG, channel); 97*678453a8Sspeer * Let's say channel is 3 98*678453a8Sspeer * #define RX_DMA_CTL_STAT_REG (DMC + 0x00070) 99*678453a8Sspeer * offset = 0x600070 100*678453a8Sspeer * offset += (3 << 9) 101*678453a8Sspeer * 3 << 9 = 0x600 102*678453a8Sspeer * offset += 0x600 = 0x600670 103*678453a8Sspeer * 104*678453a8Sspeer * Therefore, our register's PIO address is 0x600670. 105*678453a8Sspeer * 106*678453a8Sspeer * cf. Table 12-42 on page 234 of the Neptune PRM, v 1.4: 107*678453a8Sspeer * RX_DMA_CTL_STAT (DMC + [0x]00070) (count 16 step [0x]200) 108*678453a8Sspeer * 109*678453a8Sspeer * Context: 110*678453a8Sspeer * Guest domain 111*678453a8Sspeer * 112*678453a8Sspeer */ 113*678453a8Sspeer uint32_t 114*678453a8Sspeer RXDMA_REG_READ32( 115*678453a8Sspeer npi_handle_t handle, 116*678453a8Sspeer uint32_t offset, 117*678453a8Sspeer int channel) 118*678453a8Sspeer { 119*678453a8Sspeer if (handle.is_vraddr) { 120*678453a8Sspeer offset &= DMA_CSR_MASK; 121*678453a8Sspeer offset += (((channel << 1) + 1) << DMA_CSR_SLL); 122*678453a8Sspeer } else { 123*678453a8Sspeer offset += (channel << DMA_CSR_SLL); 124*678453a8Sspeer } 125*678453a8Sspeer 126*678453a8Sspeer return (ddi_get32(handle.regh, (uint32_t *)(handle.regp + offset))); 127*678453a8Sspeer } 128*678453a8Sspeer 129*678453a8Sspeer #ifdef __cplusplus 130*678453a8Sspeer } 131*678453a8Sspeer #endif 132*678453a8Sspeer 133*678453a8Sspeer #endif /* _NPI_RX_RD32_H */ 134