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