xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fzc.c (revision 59ac0c1669407488b67ae9e273667a340dccc611)
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 2007 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	<nxge_impl.h>
29 #include	<npi_mac.h>
30 #include	<npi_rxdma.h>
31 
32 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
33 static int	nxge_herr2kerr(uint64_t);
34 #endif
35 
36 /*
37  * The following interfaces are controlled by the
38  * function control registers. Some global registers
39  * are to be initialized by only byt one of the 2/4 functions.
40  * Use the test and set register.
41  */
42 /*ARGSUSED*/
43 nxge_status_t
44 nxge_test_and_set(p_nxge_t nxgep, uint8_t tas)
45 {
46 	npi_handle_t		handle;
47 	npi_status_t		rs = NPI_SUCCESS;
48 
49 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
50 	if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas))
51 			!= NPI_SUCCESS) {
52 		return (NXGE_ERROR | rs);
53 	}
54 
55 	return (NXGE_OK);
56 }
57 
58 nxge_status_t
59 nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc)
60 {
61 	npi_handle_t		handle;
62 	npi_status_t		rs = NPI_SUCCESS;
63 
64 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl"));
65 
66 	/*
67 	 * In multi-partitioning, the partition manager
68 	 * who owns function zero should set this multi-partition
69 	 * control bit.
70 	 */
71 	if (nxgep->use_partition && nxgep->function_num) {
72 		return (NXGE_ERROR);
73 	}
74 
75 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
76 	if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) {
77 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
78 			"<== nxge_set_fzc_multi_part_ctl"));
79 		return (NXGE_ERROR | rs);
80 	}
81 
82 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl"));
83 
84 	return (NXGE_OK);
85 }
86 
87 nxge_status_t
88 nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p)
89 {
90 	npi_handle_t		handle;
91 	npi_status_t		rs = NPI_SUCCESS;
92 
93 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
94 
95 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
96 	if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) {
97 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
98 			"<== nxge_set_fzc_multi_part_ctl"));
99 		return (NXGE_ERROR | rs);
100 	}
101 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
102 
103 	return (NXGE_OK);
104 }
105 
106 /*
107  * System interrupt registers that are under function zero
108  * management.
109  */
110 nxge_status_t
111 nxge_fzc_intr_init(p_nxge_t nxgep)
112 {
113 	nxge_status_t	status = NXGE_OK;
114 
115 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init"));
116 
117 	/* Configure the initial timer resolution */
118 	if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) {
119 		return (status);
120 	}
121 
122 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
123 		/*
124 		 * Set up the logical device group's logical devices that
125 		 * the group owns.
126 		 */
127 		if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK)
128 			goto fzc_intr_init_exit;
129 
130 		/* Configure the system interrupt data */
131 		if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK)
132 			goto fzc_intr_init_exit;
133 	}
134 
135 fzc_intr_init_exit:
136 
137 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init"));
138 
139 	return (status);
140 }
141 
142 nxge_status_t
143 nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)
144 {
145 	p_nxge_ldg_t	ldgp;
146 	p_nxge_ldv_t	ldvp;
147 	npi_handle_t	handle;
148 	int		i, j;
149 	npi_status_t	rs = NPI_SUCCESS;
150 
151 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set"));
152 
153 	if (nxgep->ldgvp == NULL) {
154 		return (NXGE_ERROR);
155 	}
156 
157 	ldgp = nxgep->ldgvp->ldgp;
158 	ldvp = nxgep->ldgvp->ldvp;
159 	if (ldgp == NULL || ldvp == NULL) {
160 		return (NXGE_ERROR);
161 	}
162 
163 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
164 
165 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
166 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
167 			"==> nxge_fzc_intr_ldg_num_set "
168 			"<== nxge_f(Neptune): # ldv %d "
169 			"in group %d", ldgp->nldvs, ldgp->ldg));
170 
171 		for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
172 			rs = npi_fzc_ldg_num_set(handle, ldvp->ldv,
173 				ldvp->ldg_assigned);
174 			if (rs != NPI_SUCCESS) {
175 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
176 					"<== nxge_fzc_intr_ldg_num_set failed "
177 					" rs 0x%x ldv %d ldg %d",
178 					rs, ldvp->ldv, ldvp->ldg_assigned));
179 				return (NXGE_ERROR | rs);
180 			}
181 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
182 				"<== nxge_fzc_intr_ldg_num_set OK "
183 				" ldv %d ldg %d",
184 				ldvp->ldv, ldvp->ldg_assigned));
185 		}
186 	}
187 
188 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set"));
189 
190 	return (NXGE_OK);
191 }
192 
193 nxge_status_t
194 nxge_fzc_intr_tmres_set(p_nxge_t nxgep)
195 {
196 	npi_handle_t	handle;
197 	npi_status_t	rs = NPI_SUCCESS;
198 
199 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set"));
200 	if (nxgep->ldgvp == NULL) {
201 		return (NXGE_ERROR);
202 	}
203 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
204 	if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) {
205 		return (NXGE_ERROR | rs);
206 	}
207 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set"));
208 
209 	return (NXGE_OK);
210 }
211 
212 nxge_status_t
213 nxge_fzc_intr_sid_set(p_nxge_t nxgep)
214 {
215 	npi_handle_t	handle;
216 	p_nxge_ldg_t	ldgp;
217 	fzc_sid_t	sid;
218 	int		i;
219 	npi_status_t	rs = NPI_SUCCESS;
220 
221 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set"));
222 	if (nxgep->ldgvp == NULL) {
223 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
224 			"<== nxge_fzc_intr_sid_set: no ldg"));
225 		return (NXGE_ERROR);
226 	}
227 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
228 	ldgp = nxgep->ldgvp->ldgp;
229 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
230 		"==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs));
231 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
232 		sid.ldg = ldgp->ldg;
233 		sid.niu = B_FALSE;
234 		sid.func = ldgp->func;
235 		sid.vector = ldgp->vector;
236 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
237 			"==> nxge_fzc_intr_sid_set(%d): func %d group %d "
238 			"vector %d",
239 			i, sid.func, sid.ldg, sid.vector));
240 		rs = npi_fzc_sid_set(handle, sid);
241 		if (rs != NPI_SUCCESS) {
242 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
243 				"<== nxge_fzc_intr_sid_set:failed 0x%x",
244 				rs));
245 			return (NXGE_ERROR | rs);
246 		}
247 	}
248 
249 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set"));
250 
251 	return (NXGE_OK);
252 
253 }
254 
255 /*
256  * Receive DMA registers that are under function zero
257  * management.
258  */
259 /*ARGSUSED*/
260 nxge_status_t
261 nxge_init_fzc_rxdma_channel(p_nxge_t nxgep, uint16_t channel,
262 	p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p)
263 {
264 	nxge_status_t	status = NXGE_OK;
265 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel"));
266 
267 	if (nxgep->niu_type == N2_NIU) {
268 #ifndef	NIU_HV_WORKAROUND
269 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
270 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
271 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV "
272 		    "set up logical pages"));
273 		/* Initialize the RXDMA logical pages */
274 		status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel,
275 			rbr_p);
276 		if (status != NXGE_OK) {
277 			return (status);
278 		}
279 #endif
280 		status = NXGE_OK;
281 #else
282 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
283 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
284 		    "set up logical pages"));
285 		/* Initialize the RXDMA logical pages */
286 		status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel,
287 		    rbr_p);
288 		if (status != NXGE_OK) {
289 			return (status);
290 		}
291 #endif
292 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
293 		/* Initialize the RXDMA logical pages */
294 		status = nxge_init_fzc_rxdma_channel_pages(nxgep,
295 		    channel, rbr_p);
296 		if (status != NXGE_OK) {
297 			return (status);
298 		}
299 	} else {
300 		return (NXGE_ERROR);
301 	}
302 
303 	/* Configure RED parameters */
304 	status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_p);
305 
306 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel"));
307 	return (status);
308 }
309 
310 /*ARGSUSED*/
311 nxge_status_t
312 nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,
313 		uint16_t channel, p_rx_rbr_ring_t rbrp)
314 {
315 	npi_handle_t		handle;
316 	dma_log_page_t		cfg;
317 	npi_status_t		rs = NPI_SUCCESS;
318 
319 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
320 		"==> nxge_init_fzc_rxdma_channel_pages"));
321 
322 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
323 	/*
324 	 * Initialize logical page 1.
325 	 */
326 	cfg.func_num = nxgep->function_num;
327 	cfg.page_num = 0;
328 	cfg.valid = rbrp->page_valid.bits.ldw.page0;
329 	cfg.value = rbrp->page_value_1.value;
330 	cfg.mask = rbrp->page_mask_1.value;
331 	cfg.reloc = rbrp->page_reloc_1.value;
332 	rs = npi_rxdma_cfg_logical_page(handle, channel,
333 			(p_dma_log_page_t)&cfg);
334 	if (rs != NPI_SUCCESS) {
335 		return (NXGE_ERROR | rs);
336 	}
337 
338 	/*
339 	 * Initialize logical page 2.
340 	 */
341 	cfg.page_num = 1;
342 	cfg.valid = rbrp->page_valid.bits.ldw.page1;
343 	cfg.value = rbrp->page_value_2.value;
344 	cfg.mask = rbrp->page_mask_2.value;
345 	cfg.reloc = rbrp->page_reloc_2.value;
346 
347 	rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg);
348 	if (rs != NPI_SUCCESS) {
349 		return (NXGE_ERROR | rs);
350 	}
351 
352 	/* Initialize the page handle */
353 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel,
354 			rbrp->page_hdl.bits.ldw.handle);
355 
356 	if (rs != NPI_SUCCESS) {
357 		return (NXGE_ERROR | rs);
358 	}
359 
360 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
361 		"<== nxge_init_fzc_rxdma_channel_pages"));
362 
363 	return (NXGE_OK);
364 }
365 
366 /*ARGSUSED*/
367 nxge_status_t
368 nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,
369 	uint16_t channel, p_rx_rcr_ring_t rcr_p)
370 {
371 	npi_handle_t		handle;
372 	rdc_red_para_t		red;
373 	npi_status_t		rs = NPI_SUCCESS;
374 
375 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red"));
376 
377 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
378 	red.value = 0;
379 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
380 	red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
381 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
382 	red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
383 
384 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
385 		"==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
386 		red.bits.ldw.thre_sync,
387 		red.bits.ldw.thre_sync));
388 
389 	rs = npi_rxdma_cfg_wred_param(handle, channel, &red);
390 	if (rs != NPI_SUCCESS) {
391 		return (NXGE_ERROR | rs);
392 	}
393 
394 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
395 		"<== nxge_init_fzc_rxdma_channel_red"));
396 
397 	return (NXGE_OK);
398 }
399 
400 /*ARGSUSED*/
401 nxge_status_t
402 nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel,
403 	p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p)
404 {
405 	nxge_status_t	status = NXGE_OK;
406 
407 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
408 		"==> nxge_init_fzc_txdma_channel"));
409 
410 	if (nxgep->niu_type == N2_NIU) {
411 #ifndef	NIU_HV_WORKAROUND
412 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
413 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
414 		    "==> nxge_init_fzc_txdma_channel "
415 		    "N2_NIU: call HV to set up txdma logical pages"));
416 		status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel,
417 		    tx_ring_p);
418 		if (status != NXGE_OK) {
419 			return (status);
420 		}
421 #endif
422 		status = NXGE_OK;
423 #else
424 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
425 		    "==> nxge_init_fzc_txdma_channel "
426 		    "N2_NIU: NEED to set up txdma logical pages"));
427 		/* Initialize the TXDMA logical pages */
428 		(void) nxge_init_fzc_txdma_channel_pages(nxgep, channel,
429 		    tx_ring_p);
430 #endif
431 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
432 		/* Initialize the TXDMA logical pages */
433 		(void) nxge_init_fzc_txdma_channel_pages(nxgep,
434 		    channel, tx_ring_p);
435 	} else {
436 		return (NXGE_ERROR);
437 	}
438 
439 	/*
440 	 * Configure Transmit DRR Weight parameters
441 	 * (It actually programs the TXC max burst register).
442 	 */
443 	(void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p);
444 
445 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
446 		"<== nxge_init_fzc_txdma_channel"));
447 	return (status);
448 }
449 
450 nxge_status_t
451 nxge_init_fzc_common(p_nxge_t nxgep)
452 {
453 	nxge_status_t	status = NXGE_OK;
454 
455 	(void) nxge_init_fzc_rx_common(nxgep);
456 
457 	return (status);
458 }
459 
460 nxge_status_t
461 nxge_init_fzc_rx_common(p_nxge_t nxgep)
462 {
463 	npi_handle_t	handle;
464 	npi_status_t	rs = NPI_SUCCESS;
465 	nxge_status_t	status = NXGE_OK;
466 	clock_t		lbolt;
467 
468 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common"));
469 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
470 	if (!handle.regp) {
471 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
472 			"==> nxge_init_fzc_rx_common null ptr"));
473 		return (NXGE_ERROR);
474 	}
475 
476 	/*
477 	 * Configure the rxdma clock divider
478 	 * This is the granularity counter based on
479 	 * the hardware system clock (i.e. 300 Mhz) and
480 	 * it is running around 3 nanoseconds.
481 	 * So, set the clock divider counter to 1000 to get
482 	 * microsecond granularity.
483 	 * For example, for a 3 microsecond timeout, the timeout
484 	 * will be set to 1.
485 	 */
486 	rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT);
487 	if (rs != NPI_SUCCESS)
488 		return (NXGE_ERROR | rs);
489 
490 #if defined(__i386)
491 	rs = npi_rxdma_cfg_32bitmode_enable(handle);
492 	if (rs != NPI_SUCCESS)
493 		return (NXGE_ERROR | rs);
494 	rs = npi_txdma_mode32_set(handle, B_TRUE);
495 	if (rs != NPI_SUCCESS)
496 		return (NXGE_ERROR | rs);
497 #endif
498 
499 	/*
500 	 * Enable WRED and program an initial value.
501 	 * Use time to set the initial random number.
502 	 */
503 	(void) drv_getparm(LBOLT, &lbolt);
504 	rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt);
505 	if (rs != NPI_SUCCESS)
506 		return (NXGE_ERROR | rs);
507 
508 	/* Initialize the RDC tables for each group */
509 	status = nxge_init_fzc_rdc_tbl(nxgep);
510 
511 
512 	/* Ethernet Timeout Counter (?) */
513 
514 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
515 		"<== nxge_init_fzc_rx_common:status 0x%08x", status));
516 
517 	return (status);
518 }
519 
520 nxge_status_t
521 nxge_init_fzc_rdc_tbl(p_nxge_t nxgep)
522 {
523 	npi_handle_t		handle;
524 	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
525 	p_nxge_hw_pt_cfg_t	p_cfgp;
526 	p_nxge_rdc_grp_t	rdc_grp_p;
527 	uint8_t 		grp_tbl_id;
528 	int			ngrps;
529 	int			i;
530 	npi_status_t		rs = NPI_SUCCESS;
531 	nxge_status_t		status = NXGE_OK;
532 
533 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rdc_tbl"));
534 
535 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
536 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
537 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
538 
539 	grp_tbl_id = p_cfgp->start_rdc_grpid;
540 	rdc_grp_p = &p_dma_cfgp->rdc_grps[0];
541 	ngrps = p_cfgp->max_rdc_grpids;
542 	for (i = 0; i < ngrps; i++, rdc_grp_p++) {
543 		rs = npi_rxdma_cfg_rdc_table(handle, grp_tbl_id++,
544 			rdc_grp_p->rdc);
545 		if (rs != NPI_SUCCESS) {
546 			status = NXGE_ERROR | rs;
547 			break;
548 		}
549 	}
550 
551 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_init_fzc_rdc_tbl"));
552 	return (status);
553 }
554 
555 nxge_status_t
556 nxge_init_fzc_rxdma_port(p_nxge_t nxgep)
557 {
558 	npi_handle_t		handle;
559 	p_nxge_dma_pt_cfg_t	p_all_cfgp;
560 	p_nxge_hw_pt_cfg_t	p_cfgp;
561 	hostinfo_t 		hostinfo;
562 	int			i;
563 	npi_status_t		rs = NPI_SUCCESS;
564 	p_nxge_class_pt_cfg_t 	p_class_cfgp;
565 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_port"));
566 
567 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
568 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
569 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
570 	/*
571 	 * Initialize the port scheduler DRR weight.
572 	 * npi_rxdma_cfg_port_ddr_weight();
573 	 */
574 
575 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep->niu_type)) {
576 		if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
577 		    (nxgep->mac.portmode == PORT_1G_FIBER)) {
578 			rs = npi_rxdma_cfg_port_ddr_weight(handle,
579 			    nxgep->function_num,
580 			    NXGE_RX_DRR_WT_1G);
581 			if (rs != NPI_SUCCESS) {
582 				return (NXGE_ERROR | rs);
583 			}
584 		}
585 	}
586 
587 	/* Program the default RDC of a port */
588 	rs = npi_rxdma_cfg_default_port_rdc(handle, nxgep->function_num,
589 			p_cfgp->def_rdc);
590 	if (rs != NPI_SUCCESS) {
591 		return (NXGE_ERROR | rs);
592 	}
593 
594 	/*
595 	 * Configure the MAC host info table with RDC tables
596 	 */
597 	hostinfo.value = 0;
598 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
599 	for (i = 0; i < p_cfgp->max_macs; i++) {
600 		hostinfo.bits.w0.rdc_tbl_num = p_cfgp->start_rdc_grpid;
601 		hostinfo.bits.w0.mac_pref = p_cfgp->mac_pref;
602 		if (p_class_cfgp->mac_host_info[i].flag) {
603 			hostinfo.bits.w0.rdc_tbl_num =
604 				p_class_cfgp->mac_host_info[i].rdctbl;
605 			hostinfo.bits.w0.mac_pref =
606 				p_class_cfgp->mac_host_info[i].mpr_npr;
607 		}
608 
609 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
610 				nxgep->function_num, i, &hostinfo);
611 		if (rs != NPI_SUCCESS)
612 			return (NXGE_ERROR | rs);
613 	}
614 
615 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
616 		"<== nxge_init_fzc_rxdma_port rs 0x%08x", rs));
617 
618 	return (NXGE_OK);
619 
620 }
621 
622 nxge_status_t
623 nxge_fzc_dmc_def_port_rdc(p_nxge_t nxgep, uint8_t port, uint16_t rdc)
624 {
625 	npi_status_t rs = NPI_SUCCESS;
626 	rs = npi_rxdma_cfg_default_port_rdc(nxgep->npi_reg_handle,
627 				    port, rdc);
628 	if (rs & NPI_FAILURE)
629 		return (NXGE_ERROR | rs);
630 	return (NXGE_OK);
631 }
632 
633 nxge_status_t
634 nxge_init_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
635 	p_tx_ring_t tx_ring_p)
636 {
637 	npi_handle_t		handle;
638 	dma_log_page_t		cfg;
639 	npi_status_t		rs = NPI_SUCCESS;
640 
641 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
642 		"==> nxge_init_fzc_txdma_channel_pages"));
643 
644 #ifndef	NIU_HV_WORKAROUND
645 	if (nxgep->niu_type == N2_NIU) {
646 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
647 			"<== nxge_init_fzc_txdma_channel_pages: "
648 			"N2_NIU: no need to set txdma logical pages"));
649 		return (NXGE_OK);
650 	}
651 #else
652 	if (nxgep->niu_type == N2_NIU) {
653 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
654 			"<== nxge_init_fzc_txdma_channel_pages: "
655 			"N2_NIU: NEED to set txdma logical pages"));
656 	}
657 #endif
658 
659 	/*
660 	 * Initialize logical page 1.
661 	 */
662 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
663 	cfg.func_num = nxgep->function_num;
664 	cfg.page_num = 0;
665 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page0;
666 	cfg.value = tx_ring_p->page_value_1.value;
667 	cfg.mask = tx_ring_p->page_mask_1.value;
668 	cfg.reloc = tx_ring_p->page_reloc_1.value;
669 
670 	rs = npi_txdma_log_page_set(handle, channel,
671 		(p_dma_log_page_t)&cfg);
672 	if (rs != NPI_SUCCESS) {
673 		return (NXGE_ERROR | rs);
674 	}
675 
676 	/*
677 	 * Initialize logical page 2.
678 	 */
679 	cfg.page_num = 1;
680 	cfg.valid = tx_ring_p->page_valid.bits.ldw.page1;
681 	cfg.value = tx_ring_p->page_value_2.value;
682 	cfg.mask = tx_ring_p->page_mask_2.value;
683 	cfg.reloc = tx_ring_p->page_reloc_2.value;
684 
685 	rs = npi_txdma_log_page_set(handle, channel, &cfg);
686 	if (rs != NPI_SUCCESS) {
687 		return (NXGE_ERROR | rs);
688 	}
689 
690 	/* Initialize the page handle */
691 	rs = npi_txdma_log_page_handle_set(handle, channel,
692 			&tx_ring_p->page_hdl);
693 
694 	if (rs == NPI_SUCCESS) {
695 		return (NXGE_OK);
696 	} else {
697 		return (NXGE_ERROR | rs);
698 	}
699 }
700 
701 
702 nxge_status_t
703 nxge_init_fzc_txdma_channel_drr(p_nxge_t nxgep, uint16_t channel,
704 	p_tx_ring_t tx_ring_p)
705 {
706 	npi_status_t	rs = NPI_SUCCESS;
707 	npi_handle_t	handle;
708 
709 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
710 	rs = npi_txc_dma_max_burst_set(handle, channel,
711 			tx_ring_p->max_burst.value);
712 	if (rs == NPI_SUCCESS) {
713 		return (NXGE_OK);
714 	} else {
715 		return (NXGE_ERROR | rs);
716 	}
717 }
718 
719 nxge_status_t
720 nxge_fzc_sys_err_mask_set(p_nxge_t nxgep, uint64_t mask)
721 {
722 	npi_status_t	rs = NPI_SUCCESS;
723 	npi_handle_t	handle;
724 
725 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
726 	rs = npi_fzc_sys_err_mask_set(handle, mask);
727 	if (rs == NPI_SUCCESS) {
728 		return (NXGE_OK);
729 	} else {
730 		return (NXGE_ERROR | rs);
731 	}
732 }
733 
734 #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
735 nxge_status_t
736 nxge_init_hv_fzc_txdma_channel_pages(p_nxge_t nxgep, uint16_t channel,
737 	p_tx_ring_t tx_ring_p)
738 {
739 	int			err;
740 	uint64_t		hverr;
741 #ifdef	DEBUG
742 	uint64_t		ra, size;
743 #endif
744 
745 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
746 		"==> nxge_init_hv_fzc_txdma_channel_pages"));
747 
748 	if (tx_ring_p->hv_set) {
749 		return (NXGE_OK);
750 	}
751 
752 	/*
753 	 * Initialize logical page 1 for data buffers.
754 	 */
755 	hverr = hv_niu_tx_logical_page_conf((uint64_t)channel,
756 			(uint64_t)0,
757 			tx_ring_p->hv_tx_buf_base_ioaddr_pp,
758 			tx_ring_p->hv_tx_buf_ioaddr_size);
759 
760 	err = (nxge_status_t)nxge_herr2kerr(hverr);
761 	if (err != 0) {
762 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
763 			"<== nxge_init_hv_fzc_txdma_channel_pages: channel %d "
764 			"error status 0x%x "
765 			"(page 0 data buf) hverr 0x%llx "
766 			"ioaddr_pp $%p "
767 			"size 0x%llx ",
768 			channel,
769 			err,
770 			hverr,
771 			tx_ring_p->hv_tx_buf_base_ioaddr_pp,
772 			tx_ring_p->hv_tx_buf_ioaddr_size));
773 		return (NXGE_ERROR | err);
774 	}
775 
776 #ifdef	DEBUG
777 	ra = size = 0;
778 	hverr = hv_niu_tx_logical_page_info((uint64_t)channel,
779 			(uint64_t)0,
780 			&ra,
781 			&size);
782 
783 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
784 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
785 		"ok status 0x%x "
786 		"(page 0 data buf) hverr 0x%llx "
787 		"set ioaddr_pp $%p "
788 		"set size 0x%llx "
789 		"get ra ioaddr_pp $%p "
790 		"get size 0x%llx ",
791 		channel,
792 		err,
793 		hverr,
794 		tx_ring_p->hv_tx_buf_base_ioaddr_pp,
795 		tx_ring_p->hv_tx_buf_ioaddr_size,
796 		ra,
797 		size));
798 #endif
799 
800 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
801 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
802 		"(page 0 data buf) hverr 0x%llx "
803 		"ioaddr_pp $%p "
804 		"size 0x%llx ",
805 		channel,
806 		hverr,
807 		tx_ring_p->hv_tx_buf_base_ioaddr_pp,
808 		tx_ring_p->hv_tx_buf_ioaddr_size));
809 
810 	/*
811 	 * Initialize logical page 2 for control buffers.
812 	 */
813 	hverr = hv_niu_tx_logical_page_conf((uint64_t)channel,
814 			(uint64_t)1,
815 			tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
816 			tx_ring_p->hv_tx_cntl_ioaddr_size);
817 
818 	err = (nxge_status_t)nxge_herr2kerr(hverr);
819 
820 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
821 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d"
822 		"ok status 0x%x "
823 		"(page 1 cntl buf) hverr 0x%llx "
824 		"ioaddr_pp $%p "
825 		"size 0x%llx ",
826 		channel,
827 		err,
828 		hverr,
829 		tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
830 		tx_ring_p->hv_tx_cntl_ioaddr_size));
831 
832 	if (err != 0) {
833 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
834 			"<== nxge_init_hv_fzc_txdma_channel_pages: channel %d"
835 			"error status 0x%x "
836 			"(page 1 cntl buf) hverr 0x%llx "
837 			"ioaddr_pp $%p "
838 			"size 0x%llx ",
839 			channel,
840 			err,
841 			hverr,
842 			tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
843 			tx_ring_p->hv_tx_cntl_ioaddr_size));
844 		return (NXGE_ERROR | err);
845 	}
846 
847 #ifdef	DEBUG
848 	ra = size = 0;
849 	hverr = hv_niu_tx_logical_page_info((uint64_t)channel,
850 			(uint64_t)1,
851 			&ra,
852 			&size);
853 
854 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
855 		"==> nxge_init_hv_fzc_txdma_channel_pages: channel %d "
856 		"(page 1 cntl buf) hverr 0x%llx "
857 		"set ioaddr_pp $%p "
858 		"set size 0x%llx "
859 		"get ra ioaddr_pp $%p "
860 		"get size 0x%llx ",
861 		channel,
862 		hverr,
863 		tx_ring_p->hv_tx_cntl_base_ioaddr_pp,
864 		tx_ring_p->hv_tx_cntl_ioaddr_size,
865 		ra,
866 		size));
867 #endif
868 
869 	tx_ring_p->hv_set = B_TRUE;
870 
871 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
872 		"<== nxge_init_hv_fzc_txdma_channel_pages"));
873 
874 	return (NXGE_OK);
875 }
876 
877 /*ARGSUSED*/
878 nxge_status_t
879 nxge_init_hv_fzc_rxdma_channel_pages(p_nxge_t nxgep,
880 		uint16_t channel, p_rx_rbr_ring_t rbrp)
881 {
882 	int			err;
883 	uint64_t		hverr;
884 #ifdef	DEBUG
885 	uint64_t		ra, size;
886 #endif
887 
888 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
889 		"==> nxge_init_hv_fzc_rxdma_channel_pages"));
890 
891 	if (rbrp->hv_set) {
892 		return (NXGE_OK);
893 	}
894 
895 	/* Initialize data buffers for page 0 */
896 	hverr = hv_niu_rx_logical_page_conf((uint64_t)channel,
897 			(uint64_t)0,
898 			rbrp->hv_rx_buf_base_ioaddr_pp,
899 			rbrp->hv_rx_buf_ioaddr_size);
900 	err = (nxge_status_t)nxge_herr2kerr(hverr);
901 	if (err != 0) {
902 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
903 			"<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
904 			"error status 0x%x "
905 			"(page 0 data buf) hverr 0x%llx "
906 			"ioaddr_pp $%p "
907 			"size 0x%llx ",
908 			channel,
909 			err,
910 			hverr,
911 			rbrp->hv_rx_buf_base_ioaddr_pp,
912 			rbrp->hv_rx_buf_ioaddr_size));
913 
914 		return (NXGE_ERROR | err);
915 	}
916 
917 #ifdef	DEBUG
918 	ra = size = 0;
919 	(void) hv_niu_rx_logical_page_info((uint64_t)channel,
920 			(uint64_t)0,
921 			&ra,
922 			&size);
923 
924 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
925 		"==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
926 		"ok status 0x%x "
927 		"(page 0 data buf) hverr 0x%llx "
928 		"set databuf ioaddr_pp $%p "
929 		"set databuf size 0x%llx "
930 		"get databuf ra ioaddr_pp %p "
931 		"get databuf size 0x%llx",
932 		channel,
933 		err,
934 		hverr,
935 		rbrp->hv_rx_buf_base_ioaddr_pp,
936 		rbrp->hv_rx_buf_ioaddr_size,
937 		ra,
938 		size));
939 #endif
940 
941 	/* Initialize control buffers for logical page 1.  */
942 	hverr = hv_niu_rx_logical_page_conf((uint64_t)channel,
943 			(uint64_t)1,
944 			rbrp->hv_rx_cntl_base_ioaddr_pp,
945 			rbrp->hv_rx_cntl_ioaddr_size);
946 
947 	err = (nxge_status_t)nxge_herr2kerr(hverr);
948 	if (err != 0) {
949 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
950 			"<== nxge_init_hv_fzc_rxdma_channel_pages: channel %d"
951 			"error status 0x%x "
952 			"(page 1 cntl buf) hverr 0x%llx "
953 			"ioaddr_pp $%p "
954 			"size 0x%llx ",
955 			channel,
956 			err,
957 			hverr,
958 			rbrp->hv_rx_buf_base_ioaddr_pp,
959 			rbrp->hv_rx_buf_ioaddr_size));
960 
961 		return (NXGE_ERROR | err);
962 	}
963 
964 #ifdef	DEBUG
965 	ra = size = 0;
966 	(void) hv_niu_rx_logical_page_info((uint64_t)channel,
967 			(uint64_t)1,
968 			&ra,
969 			&size);
970 
971 
972 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
973 		"==> nxge_init_hv_fzc_rxdma_channel_pages: channel %d "
974 		"error status 0x%x "
975 		"(page 1 cntl buf) hverr 0x%llx "
976 		"set cntl ioaddr_pp $%p "
977 		"set cntl size 0x%llx "
978 		"get cntl ioaddr_pp $%p "
979 		"get cntl size 0x%llx ",
980 		channel,
981 		err,
982 		hverr,
983 		rbrp->hv_rx_cntl_base_ioaddr_pp,
984 		rbrp->hv_rx_cntl_ioaddr_size,
985 		ra,
986 		size));
987 #endif
988 
989 	rbrp->hv_set = B_FALSE;
990 
991 	NXGE_DEBUG_MSG((nxgep, RX_CTL,
992 		"<== nxge_init_hv_fzc_rxdma_channel_pages"));
993 
994 	return (NXGE_OK);
995 }
996 
997 /*
998  * Map hypervisor error code to errno. Only
999  * H_ENORADDR, H_EBADALIGN and H_EINVAL are meaningful
1000  * for niu driver. Any other error codes are mapped to EINVAL.
1001  */
1002 static int
1003 nxge_herr2kerr(uint64_t hv_errcode)
1004 {
1005 	int	s_errcode;
1006 
1007 	switch (hv_errcode) {
1008 	case H_ENORADDR:
1009 	case H_EBADALIGN:
1010 		s_errcode = EFAULT;
1011 		break;
1012 	case H_EOK:
1013 		s_errcode = 0;
1014 		break;
1015 	default:
1016 		s_errcode = EINVAL;
1017 		break;
1018 	}
1019 	return (s_errcode);
1020 }
1021 
1022 #endif	/* sun4v and NIU_LP_WORKAROUND */
1023