xref: /illumos-gate/usr/src/uts/common/io/hxge/hxge_fzc.c (revision 3dec9fcd)
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
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
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
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
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
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
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
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
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
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
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