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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <hxge_impl.h> 27 #include <hpi_vmac.h> 28 #include <hpi_rxdma.h> 29 30 /* 31 * System interrupt registers that are under function zero management. 32 */ 33 hxge_status_t 34 hxge_fzc_intr_init(p_hxge_t hxgep) 35 { 36 hxge_status_t status = HXGE_OK; 37 38 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_init")); 39 40 /* Configure the initial timer resolution */ 41 if ((status = hxge_fzc_intr_tmres_set(hxgep)) != HXGE_OK) { 42 return (status); 43 } 44 45 /* 46 * Set up the logical device group's logical devices that 47 * the group owns. 48 */ 49 if ((status = hxge_fzc_intr_ldg_num_set(hxgep)) != HXGE_OK) { 50 return (status); 51 } 52 53 /* Configure the system interrupt data */ 54 if ((status = hxge_fzc_intr_sid_set(hxgep)) != HXGE_OK) { 55 return (status); 56 } 57 58 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_init")); 59 60 return (status); 61 } 62 63 hxge_status_t 64 hxge_fzc_intr_ldg_num_set(p_hxge_t hxgep) 65 { 66 p_hxge_ldg_t ldgp; 67 p_hxge_ldv_t ldvp; 68 hpi_handle_t handle; 69 int i, j; 70 hpi_status_t rs = HPI_SUCCESS; 71 72 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_ldg_num_set")); 73 74 if (hxgep->ldgvp == NULL) { 75 return (HXGE_ERROR); 76 } 77 78 ldgp = hxgep->ldgvp->ldgp; 79 ldvp = hxgep->ldgvp->ldvp; 80 if (ldgp == NULL || ldvp == NULL) { 81 return (HXGE_ERROR); 82 } 83 84 handle = HXGE_DEV_HPI_HANDLE(hxgep); 85 86 for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) { 87 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_ldg_num_set " 88 "<== hxge_f(Hydra): # ldv %d in group %d", ldgp->nldvs, 89 ldgp->ldg)); 90 91 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 92 rs = hpi_fzc_ldg_num_set(handle, ldvp->ldv, 93 ldvp->ldg_assigned); 94 if (rs != HPI_SUCCESS) { 95 HXGE_DEBUG_MSG((hxgep, INT_CTL, 96 "<== hxge_fzc_intr_ldg_num_set failed " 97 " rs 0x%x ldv %d ldg %d", 98 rs, ldvp->ldv, ldvp->ldg_assigned)); 99 return (HXGE_ERROR | rs); 100 } 101 HXGE_DEBUG_MSG((hxgep, INT_CTL, 102 "<== hxge_fzc_intr_ldg_num_set OK ldv %d ldg %d", 103 ldvp->ldv, ldvp->ldg_assigned)); 104 } 105 } 106 107 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_ldg_num_set")); 108 return (HXGE_OK); 109 } 110 111 hxge_status_t 112 hxge_fzc_intr_tmres_set(p_hxge_t hxgep) 113 { 114 hpi_handle_t handle; 115 hpi_status_t rs = HPI_SUCCESS; 116 117 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_tmrese_set")); 118 if (hxgep->ldgvp == NULL) { 119 return (HXGE_ERROR); 120 } 121 122 handle = HXGE_DEV_HPI_HANDLE(hxgep); 123 if ((rs = hpi_fzc_ldg_timer_res_set(handle, hxgep->ldgvp->tmres))) { 124 return (HXGE_ERROR | rs); 125 } 126 127 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_tmrese_set")); 128 return (HXGE_OK); 129 } 130 131 hxge_status_t 132 hxge_fzc_intr_sid_set(p_hxge_t hxgep) 133 { 134 hpi_handle_t handle; 135 p_hxge_ldg_t ldgp; 136 fzc_sid_t sid; 137 int i; 138 hpi_status_t rs = HPI_SUCCESS; 139 140 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_sid_set")); 141 if (hxgep->ldgvp == NULL) { 142 HXGE_DEBUG_MSG((hxgep, INT_CTL, 143 "<== hxge_fzc_intr_sid_set: no ldg")); 144 return (HXGE_ERROR); 145 } 146 147 handle = HXGE_DEV_HPI_HANDLE(hxgep); 148 ldgp = hxgep->ldgvp->ldgp; 149 HXGE_DEBUG_MSG((hxgep, INT_CTL, 150 "==> hxge_fzc_intr_sid_set: #int %d", hxgep->ldgvp->ldg_intrs)); 151 for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) { 152 sid.ldg = ldgp->ldg; 153 sid.vector = ldgp->vector; 154 HXGE_DEBUG_MSG((hxgep, INT_CTL, 155 "==> hxge_fzc_intr_sid_set(%d): group %d vector %d", 156 i, sid.ldg, sid.vector)); 157 rs = hpi_fzc_sid_set(handle, sid); 158 if (rs != HPI_SUCCESS) { 159 HXGE_DEBUG_MSG((hxgep, INT_CTL, 160 "<== hxge_fzc_intr_sid_set:failed 0x%x", rs)); 161 return (HXGE_ERROR | rs); 162 } 163 } 164 165 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_sid_set")); 166 return (HXGE_OK); 167 } 168 169 /* 170 * Receive DMA registers that are under function zero management. 171 */ 172 /*ARGSUSED*/ 173 hxge_status_t 174 hxge_init_fzc_rxdma_channel(p_hxge_t hxgep, uint16_t channel, 175 p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p) 176 { 177 hxge_status_t status = HXGE_OK; 178 179 HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_init_fzc_rxdma_channel")); 180 181 /* Initialize the RXDMA logical pages */ 182 status = hxge_init_fzc_rxdma_channel_pages(hxgep, channel, rbr_p); 183 if (status != HXGE_OK) 184 return (status); 185 186 HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_init_fzc_rxdma_channel")); 187 return (status); 188 } 189 190 /*ARGSUSED*/ 191 hxge_status_t 192 hxge_init_fzc_rxdma_channel_pages(p_hxge_t hxgep, 193 uint16_t channel, p_rx_rbr_ring_t rbrp) 194 { 195 hpi_handle_t handle; 196 hpi_status_t rs = HPI_SUCCESS; 197 198 HXGE_DEBUG_MSG((hxgep, DMA_CTL, 199 "==> hxge_init_fzc_rxdma_channel_pages")); 200 201 handle = HXGE_DEV_HPI_HANDLE(hxgep); 202 203 /* Initialize the page handle */ 204 rs = hpi_rxdma_cfg_logical_page_handle(handle, channel, 205 rbrp->page_hdl.bits.handle); 206 if (rs != HPI_SUCCESS) 207 return (HXGE_ERROR | rs); 208 209 HXGE_DEBUG_MSG((hxgep, DMA_CTL, 210 "<== hxge_init_fzc_rxdma_channel_pages")); 211 return (HXGE_OK); 212 } 213 214 /*ARGSUSED*/ 215 hxge_status_t 216 hxge_init_fzc_txdma_channel(p_hxge_t hxgep, uint16_t channel, 217 p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p) 218 { 219 hxge_status_t status = HXGE_OK; 220 221 HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_txdma_channel")); 222 223 /* Initialize the TXDMA logical pages */ 224 (void) hxge_init_fzc_txdma_channel_pages(hxgep, channel, tx_ring_p); 225 226 HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_init_fzc_txdma_channel")); 227 return (status); 228 } 229 230 hxge_status_t 231 hxge_init_fzc_rx_common(p_hxge_t hxgep) 232 { 233 hpi_handle_t handle; 234 hpi_status_t rs = HPI_SUCCESS; 235 hxge_status_t status = HXGE_OK; 236 237 HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_rx_common")); 238 handle = HXGE_DEV_HPI_HANDLE(hxgep); 239 240 /* 241 * Configure the rxdma clock divider 242 * This is the granularity counter based on 243 * the hardware system clock (i.e. 300 Mhz) and 244 * it is running around 3 nanoseconds. 245 * So, set the clock divider counter to 1000 to get 246 * microsecond granularity. 247 * For example, for a 3 microsecond timeout, the timeout 248 * will be set to 1. 249 */ 250 rs = hpi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT); 251 if (rs != HPI_SUCCESS) 252 return (HXGE_ERROR | rs); 253 254 HXGE_DEBUG_MSG((hxgep, DMA_CTL, 255 "<== hxge_init_fzc_rx_common:status 0x%08x", status)); 256 return (status); 257 } 258 259 hxge_status_t 260 hxge_init_fzc_txdma_channel_pages(p_hxge_t hxgep, uint16_t channel, 261 p_tx_ring_t tx_ring_p) 262 { 263 hpi_handle_t handle; 264 hpi_status_t rs = HPI_SUCCESS; 265 266 HXGE_DEBUG_MSG((hxgep, DMA_CTL, 267 "==> hxge_init_fzc_txdma_channel_pages")); 268 269 handle = HXGE_DEV_HPI_HANDLE(hxgep); 270 271 /* Initialize the page handle */ 272 rs = hpi_txdma_log_page_handle_set(handle, channel, 273 &tx_ring_p->page_hdl); 274 275 if (rs == HPI_SUCCESS) 276 return (HXGE_OK); 277 else 278 return (HXGE_ERROR | rs); 279 } 280 281 hxge_status_t 282 hxge_fzc_sys_err_mask_set(p_hxge_t hxgep, boolean_t mask) 283 { 284 hpi_status_t rs = HPI_SUCCESS; 285 hpi_handle_t handle; 286 287 handle = HXGE_DEV_HPI_HANDLE(hxgep); 288 rs = hpi_fzc_sys_err_mask_set(handle, mask); 289 if (rs == HPI_SUCCESS) 290 return (HXGE_OK); 291 else 292 return (HXGE_ERROR | rs); 293 } 294