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