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