xref: /illumos-gate/usr/src/uts/common/io/hxge/hpi_pfc.c (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
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 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <hxge_impl.h>
30 #include <hpi_pfc.h>
31 
32 #define	TCAM_COMPLETION_TRY_COUNT	10
33 #define	HXGE_VLAN_TABLE_ENTRIES		128
34 #define	HXGE_PFC_INT_STATUS_CLEAR	0x7ULL
35 
36 static uint64_t
37 hpi_pfc_tcam_check_completion(hpi_handle_t handle, tcam_op_t op_type)
38 {
39 	uint32_t	try_counter, tcam_delay = 10;
40 	pfc_tcam_ctrl_t	tctl;
41 
42 	try_counter = TCAM_COMPLETION_TRY_COUNT;
43 
44 	switch (op_type) {
45 	case TCAM_RWC_STAT:
46 		READ_TCAM_REG_CTL(handle, &tctl.value);
47 		while ((try_counter) &&
48 		    (tctl.bits.status != TCAM_CTL_RWC_RWC_STAT)) {
49 			try_counter--;
50 			HXGE_DELAY(tcam_delay);
51 			READ_TCAM_REG_CTL(handle, &tctl.value);
52 		}
53 
54 		if (!try_counter) {
55 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
56 			    " TCAM RWC_STAT operation"
57 			    " failed to complete \n"));
58 			return (HPI_PFC_TCAM_HW_ERROR);
59 		}
60 
61 		tctl.value = 0;
62 		break;
63 	case TCAM_RWC_MATCH:
64 		READ_TCAM_REG_CTL(handle, &tctl.value);
65 
66 		while ((try_counter) &&
67 		    (tctl.bits.match != TCAM_CTL_RWC_RWC_MATCH)) {
68 			try_counter--;
69 			HXGE_DELAY(tcam_delay);
70 			READ_TCAM_REG_CTL(handle, &tctl.value);
71 		}
72 
73 		if (!try_counter) {
74 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
75 			    " TCAM Match operationfailed to find match \n"));
76 		}
77 
78 		break;
79 	default:
80 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
81 		    " Invalid TCAM completion Request \n"));
82 		return (HPI_PFC_ERROR | HPI_TCAM_ERROR | OPCODE_INVALID);
83 	}
84 
85 	return (tctl.value);
86 }
87 
88 hpi_status_t
89 hpi_pfc_tcam_entry_read(hpi_handle_t handle, uint32_t location,
90     hxge_tcam_entry_t *tcam_ptr)
91 {
92 	pfc_tcam_ctrl_t tctl;
93 	pfc_tcam_ctrl_t tctl_rv;
94 
95 	/*
96 	 * Hydra doesn't allow to read TCAM entries. Use compare instead.
97 	 */
98 	WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
99 	WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
100 
101 	WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
102 	WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
103 
104 	tctl.value = 0;
105 	tctl.bits.addr = location;
106 	tctl.bits.cmd = TCAM_CTL_RWC_TCAM_CMP;
107 
108 	WRITE_TCAM_REG_CTL(handle, tctl.value);
109 
110 	tctl_rv.value = hpi_pfc_tcam_check_completion(handle, TCAM_RWC_MATCH);
111 
112 	if (tctl_rv.bits.match)
113 		return (HPI_SUCCESS);
114 	else
115 		return (HPI_FAILURE);
116 }
117 
118 hpi_status_t
119 hpi_pfc_tcam_asc_ram_entry_read(hpi_handle_t handle,
120     uint32_t location, uint64_t *ram_data)
121 {
122 	uint64_t tcam_stat;
123 	pfc_tcam_ctrl_t tctl;
124 
125 	tctl.value = 0;
126 	tctl.bits.addr = location;
127 	tctl.bits.cmd = TCAM_CTL_RWC_RAM_RD;
128 
129 	WRITE_TCAM_REG_CTL(handle, tctl.value);
130 
131 	tcam_stat = hpi_pfc_tcam_check_completion(handle, TCAM_RWC_STAT);
132 
133 	if (tcam_stat & HPI_FAILURE) {
134 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
135 		    "TCAM RAM read failed loc %d \n", location));
136 		return (HPI_PFC_ASC_RAM_RD_ERROR);
137 	}
138 
139 	READ_TCAM_REG_KEY0(handle, ram_data);
140 
141 	return (HPI_SUCCESS);
142 }
143 
144 hpi_status_t
145 hpi_pfc_tcam_asc_ram_entry_write(hpi_handle_t handle, uint32_t location,
146     uint64_t ram_data)
147 {
148 	uint64_t	tcam_stat = 0;
149 	pfc_tcam_ctrl_t	tctl;
150 
151 	WRITE_TCAM_REG_KEY0(handle, ram_data);
152 
153 	tctl.value = 0;
154 	tctl.bits.addr = location;
155 	tctl.bits.cmd = TCAM_CTL_RWC_RAM_WR;
156 
157 	HPI_DEBUG_MSG((handle.function, HPI_PFC_CTL,
158 	    " tcam ascr write: location %x data %llx ctl value %llx \n",
159 	    location, ram_data, tctl.value));
160 	WRITE_TCAM_REG_CTL(handle, tctl.value);
161 	tcam_stat = hpi_pfc_tcam_check_completion(handle, TCAM_RWC_STAT);
162 
163 	if (tcam_stat & HPI_FAILURE) {
164 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
165 		    "TCAM RAM write failed loc %d \n", location));
166 		return (HPI_PFC_ASC_RAM_WR_ERROR);
167 	}
168 
169 	return (HPI_SUCCESS);
170 }
171 
172 static hpi_status_t
173 hpi_pfc_set_config(hpi_handle_t handle, pfc_config_t config)
174 {
175 	uint64_t offset;
176 
177 	offset = PFC_CONFIG;
178 	REG_PIO_WRITE64(handle, offset, config.value);
179 
180 	return (HPI_SUCCESS);
181 }
182 
183 static hpi_status_t
184 hpi_pfc_get_config(hpi_handle_t handle, pfc_config_t *configp)
185 {
186 	uint64_t offset;
187 
188 	offset = PFC_CONFIG;
189 	REG_PIO_READ64(handle, offset, &configp->value);
190 
191 	return (HPI_SUCCESS);
192 }
193 
194 hpi_status_t
195 hpi_pfc_set_tcam_enable(hpi_handle_t handle, boolean_t tcam)
196 {
197 	pfc_config_t	config;
198 
199 	/*
200 	 * Read the register first.
201 	 */
202 	(void) hpi_pfc_get_config(handle, &config);
203 
204 	if (tcam)
205 		config.bits.tcam_en = 1;
206 	else
207 		config.bits.tcam_en = 0;
208 
209 	return (hpi_pfc_set_config(handle, config));
210 }
211 
212 hpi_status_t
213 hpi_pfc_set_l2_hash(hpi_handle_t handle, boolean_t l2_hash)
214 {
215 	pfc_config_t	config;
216 
217 	/*
218 	 * Read the register first.
219 	 */
220 	(void) hpi_pfc_get_config(handle, &config);
221 
222 	if (l2_hash)
223 		config.bits.l2_hash_en = 1;
224 	else
225 		config.bits.l2_hash_en = 0;
226 
227 	return (hpi_pfc_set_config(handle, config));
228 }
229 
230 hpi_status_t
231 hpi_pfc_set_tcp_cksum(hpi_handle_t handle, boolean_t cksum)
232 {
233 	pfc_config_t	config;
234 
235 	/*
236 	 * Read the register first.
237 	 */
238 	(void) hpi_pfc_get_config(handle, &config);
239 
240 	if (cksum)
241 		config.bits.tcp_cs_en = 1;
242 	else
243 		config.bits.tcp_cs_en = 0;
244 
245 	return (hpi_pfc_set_config(handle, config));
246 }
247 
248 hpi_status_t
249 hpi_pfc_set_default_dma(hpi_handle_t handle, uint32_t dma_channel_no)
250 {
251 	pfc_config_t	config;
252 
253 	(void) hpi_pfc_get_config(handle, &config);
254 
255 	if (dma_channel_no > PFC_MAX_DMA_CHANNELS)
256 		return (HPI_FAILURE);
257 
258 	config.bits.default_dma = dma_channel_no;
259 
260 	return (hpi_pfc_set_config(handle, config));
261 }
262 
263 hpi_status_t
264 hpi_pfc_mac_addr_enable(hpi_handle_t handle, uint32_t slot)
265 {
266 	pfc_config_t	config;
267 	uint32_t	bit;
268 
269 	if (slot >= PFC_N_MAC_ADDRESSES) {
270 		return (HPI_FAILURE);
271 	}
272 
273 	(void) hpi_pfc_get_config(handle, &config);
274 
275 	if (slot < 24) {
276 		bit = 1 << slot;
277 		config.bits.mac_addr_en_l = config.bits.mac_addr_en_l | bit;
278 	} else {
279 		bit = 1 << (slot - 24);
280 		config.bits.mac_addr_en = config.bits.mac_addr_en | bit;
281 	}
282 
283 	return (hpi_pfc_set_config(handle, config));
284 }
285 
286 hpi_status_t
287 hpi_pfc_mac_addr_disable(hpi_handle_t handle, uint32_t slot)
288 {
289 	pfc_config_t	config;
290 	uint32_t	bit;
291 
292 	if (slot >= PFC_N_MAC_ADDRESSES) {
293 		return (HPI_FAILURE);
294 	}
295 
296 	(void) hpi_pfc_get_config(handle, &config);
297 
298 	if (slot < 24) {
299 		bit = 1 << slot;
300 		config.bits.mac_addr_en_l = config.bits.mac_addr_en_l & ~bit;
301 	} else {
302 		bit = 1 << (slot - 24);
303 		config.bits.mac_addr_en = config.bits.mac_addr_en & ~bit;
304 	}
305 
306 	return (hpi_pfc_set_config(handle, config));
307 }
308 
309 hpi_status_t
310 hpi_pfc_set_force_csum(hpi_handle_t handle, boolean_t force)
311 {
312 	pfc_config_t	config;
313 
314 	(void) hpi_pfc_get_config(handle, &config);
315 
316 	if (force)
317 		config.bits.force_cs_en = 1;
318 	else
319 		config.bits.force_cs_en = 0;
320 
321 	return (hpi_pfc_set_config(handle, config));
322 }
323 
324 hpi_status_t
325 hpi_pfc_cfg_vlan_table_clear(hpi_handle_t handle)
326 {
327 	int			i;
328 	int			offset;
329 	int			step = 8;
330 	pfc_vlan_table_t	table_entry;
331 
332 	table_entry.value = 0;
333 	for (i = 0; i < HXGE_VLAN_TABLE_ENTRIES; i++) {
334 		table_entry.bits.member = 0;
335 		offset = PFC_VLAN_TABLE + i * step;
336 		REG_PIO_WRITE64(handle, offset, table_entry.value);
337 	}
338 
339 	return (HPI_SUCCESS);
340 }
341 
342 hpi_status_t
343 hpi_pfc_cfg_vlan_table_entry_clear(hpi_handle_t handle, vlan_id_t vlan_id)
344 {
345 	uint64_t		offset;
346 	pfc_vlan_table_t	vlan_tbl_entry;
347 	uint64_t		bit;
348 
349 	/*
350 	 * Assumes that the hardware will generate the new parity
351 	 * data.
352 	 */
353 	offset = PFC_VLAN_REG_OFFSET(vlan_id);
354 	REG_PIO_READ64(handle, offset, (uint64_t *)&vlan_tbl_entry.value);
355 
356 	bit = PFC_VLAN_BIT_OFFSET(vlan_id);
357 	bit = 1 << bit;
358 	vlan_tbl_entry.bits.member = vlan_tbl_entry.bits.member & ~bit;
359 
360 	REG_PIO_WRITE64(handle, offset, vlan_tbl_entry.value);
361 
362 	return (HPI_SUCCESS);
363 }
364 
365 hpi_status_t
366 hpi_pfc_cfg_vlan_table_entry_set(hpi_handle_t handle, vlan_id_t vlan_id)
367 {
368 	uint64_t		offset;
369 	pfc_vlan_table_t	vlan_tbl_entry;
370 	uint64_t		bit;
371 
372 	/*
373 	 * Assumes that the hardware will generate the new parity
374 	 * data.
375 	 */
376 	offset = PFC_VLAN_REG_OFFSET(vlan_id);
377 	REG_PIO_READ64(handle, offset, (uint64_t *)&vlan_tbl_entry.value);
378 
379 	bit = PFC_VLAN_BIT_OFFSET(vlan_id);
380 	bit = 1 << bit;
381 	vlan_tbl_entry.bits.member = vlan_tbl_entry.bits.member | bit;
382 
383 	REG_PIO_WRITE64(handle, offset, vlan_tbl_entry.value);
384 
385 	return (HPI_SUCCESS);
386 }
387 
388 hpi_status_t
389 hpi_pfc_cfg_vlan_control_set(hpi_handle_t handle, boolean_t parity,
390     boolean_t valid, vlan_id_t vlan_id)
391 {
392 	pfc_vlan_ctrl_t	vlan_control;
393 
394 	vlan_control.value = 0;
395 
396 	if (parity)
397 		vlan_control.bits.par_en = 1;
398 	else
399 		vlan_control.bits.par_en = 0;
400 
401 	if (valid)
402 		vlan_control.bits.valid = 1;
403 	else
404 		vlan_control.bits.valid = 0;
405 
406 	vlan_control.bits.id = vlan_id;
407 
408 	REG_PIO_WRITE64(handle, PFC_VLAN_CTRL, vlan_control.value);
409 
410 	return (HPI_SUCCESS);
411 }
412 
413 hpi_status_t
414 hpi_pfc_get_vlan_parity_log(hpi_handle_t handle, pfc_vlan_par_err_log_t *logp)
415 {
416 	uint64_t offset;
417 
418 	offset = PFC_VLAN_PAR_ERR_LOG;
419 	REG_PIO_READ64(handle, offset, &logp->value);
420 
421 	return (HPI_SUCCESS);
422 }
423 
424 hpi_status_t
425 hpi_pfc_set_mac_address(hpi_handle_t handle, uint32_t slot, uint64_t address)
426 {
427 	uint64_t		offset;
428 	uint64_t		moffset;
429 	pfc_mac_addr_mask_t	mask;
430 	pfc_mac_addr_t		addr;
431 
432 	if (slot >= PFC_N_MAC_ADDRESSES)
433 		return (HPI_FAILURE);
434 
435 	offset = PFC_MAC_ADDRESS(slot);
436 	moffset = PFC_MAC_ADDRESS_MASK(slot);
437 
438 	addr.bits.addr = address >> 32;
439 	addr.bits.addr_l = address & 0xffffffff;
440 	mask.bits.mask = 0x0;
441 	mask.bits.mask_l = 0x0;
442 
443 	REG_PIO_WRITE64(handle, offset, addr.value);
444 	REG_PIO_WRITE64(handle, moffset, mask.value);
445 
446 	return (hpi_pfc_mac_addr_enable(handle, slot));
447 }
448 
449 hpi_status_t
450 hpi_pfc_clear_mac_address(hpi_handle_t handle, uint32_t slot)
451 {
452 	uint64_t offset, moffset;
453 	uint64_t zaddr = 0x0ULL;
454 	uint64_t zmask = 0x0ULL;
455 
456 	if (slot >= PFC_N_MAC_ADDRESSES)
457 		return (HPI_FAILURE);
458 
459 	(void) hpi_pfc_mac_addr_disable(handle, slot);
460 
461 	offset = PFC_MAC_ADDRESS(slot);
462 	moffset = PFC_MAC_ADDRESS_MASK(slot);
463 
464 	REG_PIO_WRITE64(handle, offset, zaddr);
465 	REG_PIO_WRITE64(handle, moffset, zmask);
466 
467 	return (HPI_SUCCESS);
468 }
469 
470 hpi_status_t
471 hpi_pfc_clear_multicast_hash_table(hpi_handle_t handle, uint32_t slot)
472 {
473 	uint64_t offset;
474 
475 	if (slot >= PFC_N_MAC_ADDRESSES)
476 		return (HPI_FAILURE);
477 
478 	offset = PFC_HASH_ADDR(slot);
479 	REG_PIO_WRITE64(handle, offset, 0ULL);
480 
481 	return (HPI_SUCCESS);
482 }
483 
484 hpi_status_t
485 hpi_pfc_set_multicast_hash_table(hpi_handle_t handle, uint32_t slot,
486 	uint64_t address)
487 {
488 	uint64_t offset;
489 
490 	if (slot >= PFC_N_MAC_ADDRESSES)
491 		return (HPI_FAILURE);
492 
493 	offset = PFC_HASH_ADDR(slot);
494 	REG_PIO_WRITE64(handle, offset, address);
495 
496 	return (HPI_SUCCESS);
497 }
498 
499 hpi_status_t
500 hpi_pfc_set_l2_class_slot(hpi_handle_t handle, uint16_t etype, boolean_t valid,
501     int slot)
502 {
503 	pfc_l2_class_config_t	l2_config;
504 	uint64_t		offset;
505 
506 	if (slot >= PFC_N_MAC_ADDRESSES)
507 		return (HPI_FAILURE);
508 
509 	l2_config.value = 0;
510 
511 	if (valid)
512 		l2_config.bits.valid = 1;
513 	else
514 		l2_config.bits.valid = 0;
515 
516 	l2_config.bits.etype = etype;
517 	l2_config.bits.rsrvd = 0;
518 
519 	offset = PFC_L2_CONFIG(slot);
520 	REG_PIO_WRITE64(handle, offset, l2_config.value);
521 
522 	return (HPI_SUCCESS);
523 }
524 
525 hpi_status_t
526 hpi_pfc_set_l3_class_config(hpi_handle_t handle, tcam_class_t slot,
527     tcam_key_cfg_t cfg)
528 {
529 	pfc_l3_class_config_t	l3_config;
530 	uint64_t		offset;
531 
532 	if (slot >= PFC_N_MAC_ADDRESSES)
533 		return (HPI_FAILURE);
534 
535 	l3_config.value = 0;
536 
537 	if (cfg.lookup_enable)
538 		l3_config.bits.tsel = 1;
539 	else
540 		l3_config.bits.tsel = 0;
541 
542 	if (cfg.discard)
543 		l3_config.bits.discard = 1;
544 	else
545 		l3_config.bits.discard = 0;
546 
547 	offset = PFC_L3_CONFIG(slot);
548 	REG_PIO_WRITE64(handle, offset, l3_config.value);
549 
550 	return (HPI_SUCCESS);
551 }
552 
553 hpi_status_t
554 hpi_pfc_get_l3_class_config(hpi_handle_t handle, tcam_class_t slot,
555     tcam_key_cfg_t *cfg)
556 {
557 	pfc_l3_class_config_t	l3_config;
558 	uint64_t		offset;
559 
560 	if (slot >= PFC_N_MAC_ADDRESSES)
561 		return (HPI_FAILURE);
562 
563 	offset = PFC_L3_CONFIG(slot);
564 	REG_PIO_READ64(handle, offset, &l3_config.value);
565 
566 	if (l3_config.bits.tsel)
567 		cfg->lookup_enable = 1;
568 	else
569 		cfg->lookup_enable = 0;
570 
571 	if (l3_config.bits.discard)
572 		cfg->discard = 1;
573 	else
574 		cfg->discard = 0;
575 
576 	return (HPI_SUCCESS);
577 }
578 
579 static hpi_status_t
580 hpi_pfc_set_tcam_control(hpi_handle_t handle, pfc_tcam_ctrl_t *tcontrolp)
581 {
582 	uint64_t offset;
583 
584 	offset = PFC_TCAM_CTRL;
585 	REG_PIO_WRITE64(handle, offset, tcontrolp->value);
586 
587 	return (HPI_SUCCESS);
588 }
589 
590 hpi_status_t
591 hpi_pfc_tcam_entry_invalidate(hpi_handle_t handle, uint32_t location)
592 {
593 	hxge_tcam_entry_t	tcam_ptr;
594 
595 	(void) memset(&tcam_ptr, 0, sizeof (hxge_tcam_entry_t));
596 	(void) hpi_pfc_tcam_entry_write(handle, location, &tcam_ptr);
597 
598 	return (HPI_SUCCESS);
599 }
600 
601 hpi_status_t
602 hpi_pfc_tcam_invalidate_all(hpi_handle_t handle)
603 {
604 	int		i;
605 	pfc_tcam_ctrl_t	tcontrol;
606 
607 	tcontrol.value = 0;
608 	for (i = 0; i < PFC_N_TCAM_ENTRIES; i++) {
609 		(void) hpi_pfc_set_tcam_control(handle, &tcontrol);
610 		(void) hpi_pfc_tcam_entry_invalidate(handle, i);
611 	}
612 
613 	return (HPI_SUCCESS);
614 }
615 
616 hpi_status_t
617 hpi_pfc_tcam_entry_write(hpi_handle_t handle, uint32_t location,
618     hxge_tcam_entry_t *tcam_ptr)
619 {
620 	uint64_t	tcam_stat;
621 	pfc_tcam_ctrl_t	tctl;
622 
623 	WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
624 	WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
625 
626 	WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
627 	WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
628 
629 	HPI_DEBUG_MSG((handle.function, HPI_PFC_CTL,
630 	    " tcam write: location %x\n key:  %llx %llx\n mask: %llx %llx\n",
631 	    location, tcam_ptr->key0, tcam_ptr->key1,
632 	    tcam_ptr->mask0, tcam_ptr->mask1));
633 
634 	tctl.value = 0;
635 	tctl.bits.addr = location;
636 	tctl.bits.cmd = TCAM_CTL_RWC_TCAM_WR;
637 
638 	HPI_DEBUG_MSG((handle.function, HPI_PFC_CTL,
639 	    " tcam write: ctl value %llx \n", tctl.value));
640 
641 	WRITE_TCAM_REG_CTL(handle, tctl.value);
642 
643 	tcam_stat = hpi_pfc_tcam_check_completion(handle, TCAM_RWC_STAT);
644 
645 	if (tcam_stat & HPI_FAILURE) {
646 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
647 		    "TCAM Write failed loc %d \n", location));
648 		return (HPI_PFC_TCAM_WR_ERROR);
649 	}
650 
651 	return (HPI_SUCCESS);
652 }
653 
654 hpi_status_t
655 hpi_pfc_get_tcam_parity_log(hpi_handle_t handle, pfc_tcam_par_err_log_t *logp)
656 {
657 	uint64_t offset;
658 
659 	offset = PFC_TCAM_PAR_ERR_LOG;
660 	REG_PIO_READ64(handle, offset, &logp->value);
661 
662 	return (HPI_SUCCESS);
663 }
664 
665 hpi_status_t
666 hpi_pfc_get_tcam_auto_init(hpi_handle_t handle, pfc_auto_init_t *autoinitp)
667 {
668 	uint64_t offset;
669 
670 	offset = PFC_AUTO_INIT;
671 	REG_PIO_READ64(handle, offset, &autoinitp->value);
672 
673 	return (HPI_SUCCESS);
674 }
675 
676 hpi_status_t
677 hpi_pfc_set_tcp_control_discard(hpi_handle_t handle, boolean_t discard)
678 {
679 	uint64_t	offset;
680 	tcp_ctrl_mask_t	tcp;
681 
682 	tcp.value = 0;
683 
684 	offset = TCP_CTRL_MASK;
685 	REG_PIO_READ64(handle, offset, &tcp.value);
686 
687 	if (discard)
688 		tcp.bits.discard = 1;
689 	else
690 		tcp.bits.discard = 0;
691 
692 	REG_PIO_WRITE64(handle, offset, tcp.value);
693 
694 	return (HPI_SUCCESS);
695 }
696 
697 hpi_status_t
698 hpi_pfc_set_tcp_control_fin(hpi_handle_t handle, boolean_t fin)
699 {
700 	uint64_t	offset;
701 	tcp_ctrl_mask_t	tcp;
702 
703 	tcp.value = 0;
704 
705 	offset = TCP_CTRL_MASK;
706 	REG_PIO_READ64(handle, offset, &tcp.value);
707 
708 	if (fin)
709 		tcp.bits.fin = 1;
710 	else
711 		tcp.bits.fin = 0;
712 
713 	REG_PIO_WRITE64(handle, offset, tcp.value);
714 	return (HPI_SUCCESS);
715 }
716 
717 hpi_status_t
718 hpi_pfc_set_tcp_control_syn(hpi_handle_t handle, boolean_t syn)
719 {
720 	uint64_t	offset;
721 	tcp_ctrl_mask_t	tcp;
722 
723 	tcp.value = 0;
724 
725 	offset = TCP_CTRL_MASK;
726 	REG_PIO_READ64(handle, offset, &tcp.value);
727 
728 	if (syn)
729 		tcp.bits.syn = 1;
730 	else
731 		tcp.bits.syn = 0;
732 
733 	REG_PIO_WRITE64(handle, offset, tcp.value);
734 	return (HPI_SUCCESS);
735 }
736 
737 hpi_status_t
738 hpi_pfc_set_tcp_control_rst(hpi_handle_t handle, boolean_t rst)
739 {
740 	uint64_t	offset;
741 	tcp_ctrl_mask_t	tcp;
742 
743 	tcp.value = 0;
744 
745 	offset = TCP_CTRL_MASK;
746 	REG_PIO_READ64(handle, offset, &tcp.value);
747 
748 	if (rst)
749 		tcp.bits.rst = 1;
750 	else
751 		tcp.bits.rst = 0;
752 
753 	REG_PIO_WRITE64(handle, offset, tcp.value);
754 	return (HPI_SUCCESS);
755 }
756 
757 hpi_status_t
758 hpi_pfc_set_tcp_control_psh(hpi_handle_t handle, boolean_t push)
759 {
760 	uint64_t	offset;
761 	tcp_ctrl_mask_t	tcp;
762 
763 	tcp.value = 0;
764 
765 	offset = TCP_CTRL_MASK;
766 	REG_PIO_READ64(handle, offset, &tcp.value);
767 
768 	if (push)
769 		tcp.bits.psh = 1;
770 	else
771 		tcp.bits.psh = 0;
772 
773 	REG_PIO_WRITE64(handle, offset, tcp.value);
774 	return (HPI_SUCCESS);
775 }
776 
777 hpi_status_t
778 hpi_pfc_set_tcp_control_ack(hpi_handle_t handle, boolean_t ack)
779 {
780 	uint64_t	offset;
781 	tcp_ctrl_mask_t	tcp;
782 
783 	tcp.value = 0;
784 
785 	offset = TCP_CTRL_MASK;
786 	REG_PIO_READ64(handle, offset, &tcp.value);
787 
788 	if (ack)
789 		tcp.bits.ack = 1;
790 	else
791 		tcp.bits.ack = 0;
792 
793 	REG_PIO_WRITE64(handle, offset, tcp.value);
794 	return (HPI_SUCCESS);
795 }
796 
797 hpi_status_t
798 hpi_pfc_set_hash_seed_value(hpi_handle_t handle, uint32_t seed)
799 {
800 	uint64_t	offset;
801 	src_hash_val_t	src_hash_seed;
802 
803 	src_hash_seed.value = 0;
804 	src_hash_seed.bits.seed = seed;
805 
806 	offset = SRC_HASH_VAL;
807 	REG_PIO_WRITE64(handle, offset, src_hash_seed.value);
808 
809 	return (HPI_SUCCESS);
810 }
811 
812 hpi_status_t
813 hpi_pfc_get_interrupt_status(hpi_handle_t handle, pfc_int_status_t *statusp)
814 {
815 	uint64_t offset;
816 
817 	offset = PFC_INT_STATUS;
818 	REG_PIO_READ64(handle, offset, &statusp->value);
819 
820 	return (HPI_SUCCESS);
821 }
822 
823 hpi_status_t
824 hpi_pfc_clear_interrupt_status(hpi_handle_t handle)
825 {
826 	uint64_t offset;
827 
828 	offset = PFC_INT_STATUS;
829 	REG_PIO_WRITE64(handle, offset, HXGE_PFC_INT_STATUS_CLEAR);
830 
831 	return (HPI_SUCCESS);
832 }
833 
834 hpi_status_t
835 hpi_pfc_set_interrupt_mask(hpi_handle_t handle, boolean_t drop,
836 	boolean_t tcam_parity_error, boolean_t vlan_parity_error)
837 {
838 	pfc_int_mask_t	mask;
839 	uint64_t	offset;
840 
841 	mask.value = 0;
842 
843 	if (drop)
844 		mask.bits.pkt_drop_mask = 1;
845 	else
846 		mask.bits.pkt_drop_mask = 0;
847 
848 	if (tcam_parity_error)
849 		mask.bits.tcam_parity_err_mask = 1;
850 	else
851 		mask.bits.tcam_parity_err_mask = 0;
852 
853 	if (vlan_parity_error)
854 		mask.bits.vlan_parity_err_mask = 1;
855 	else
856 		mask.bits.vlan_parity_err_mask = 0;
857 
858 	offset = PFC_INT_MASK;
859 	REG_PIO_WRITE64(handle, offset, mask.value);
860 
861 	return (HPI_SUCCESS);
862 }
863 
864 hpi_status_t
865 hpi_pfc_get_drop_log(hpi_handle_t handle, pfc_drop_log_t *logp)
866 {
867 	uint64_t offset;
868 
869 	offset = PFC_DROP_LOG;
870 	REG_PIO_READ64(handle, offset, &logp->value);
871 
872 	return (HPI_SUCCESS);
873 }
874 
875 hpi_status_t
876 hpi_pfc_set_drop_log_mask(hpi_handle_t handle, boolean_t vlan_drop,
877     boolean_t tcam_drop, boolean_t class_code_drop, boolean_t l2_addr_drop,
878     boolean_t tcp_ctrl_drop)
879 {
880 	uint64_t		offset;
881 	pfc_drop_log_mask_t	log;
882 
883 	log.value = 0;
884 
885 	if (vlan_drop)
886 		log.bits.vlan_drop_mask = 1;
887 	if (tcam_drop)
888 		log.bits.tcam_drop_mask = 1;
889 	if (class_code_drop)
890 		log.bits.class_code_drop_mask = 1;
891 	if (l2_addr_drop)
892 		log.bits.l2_addr_drop_mask = 1;
893 	if (tcp_ctrl_drop)
894 		log.bits.tcp_ctrl_drop_mask = 1;
895 
896 	offset = PFC_DROP_LOG_MASK;
897 	REG_PIO_WRITE64(handle, offset, log.value);
898 
899 	return (HPI_SUCCESS);
900 }
901 
902 hpi_status_t
903 hpi_pfc_get_bad_csum_counter(hpi_handle_t handle, uint64_t *countp)
904 {
905 	uint64_t offset;
906 
907 	offset = PFC_BAD_CS_COUNTER;
908 	REG_PIO_READ64(handle, offset, countp);
909 
910 	return (HPI_SUCCESS);
911 }
912 
913 hpi_status_t
914 hpi_pfc_get_drop_counter(hpi_handle_t handle, uint64_t *countp)
915 {
916 	uint64_t offset;
917 
918 	offset = PFC_DROP_COUNTER;
919 	REG_PIO_READ64(handle, offset, countp);
920 
921 	return (HPI_SUCCESS);
922 }
923 
924 hpi_status_t
925 hpi_pfc_get_number_mac_addrs(hpi_handle_t handle, uint32_t *n_of_addrs)
926 {
927 	HXGE_REG_RD32(handle, HCR_REG + HCR_N_MAC_ADDRS, n_of_addrs);
928 	return (HPI_SUCCESS);
929 }
930 
931 hpi_status_t
932 hpi_pfc_mac_addr_get_i(hpi_handle_t handle, uint8_t *data, int slot)
933 {
934 	uint32_t step = sizeof (uint32_t);
935 	uint32_t addr_hi = 0, addr_lo = 0;
936 
937 	if (slot >= PFC_N_MAC_ADDRESSES)
938 		return (HPI_FAILURE);
939 
940 	/*
941 	 * Read the MAC address out of the SPROM at the blade's
942 	 * specific location.
943 	 */
944 	HXGE_REG_RD32(handle, HCR_REG + HCR_ADDR_LO + slot * step, &addr_lo);
945 	HXGE_REG_RD32(handle, HCR_REG + HCR_ADDR_HI + slot * step, &addr_hi);
946 
947 	data[0] = addr_lo & 0x000000ff;
948 	data[1] = (addr_lo & 0x0000ff00) >> 8;
949 	data[2] = (addr_lo & 0x00ff0000) >> 16;
950 	data[3] = (addr_lo & 0xff000000) >> 24;
951 	data[4] = (addr_hi & 0x00000ff00) >> 8;
952 	data[5] = (addr_hi & 0x0000000ff);
953 
954 	return (HPI_SUCCESS);
955 }
956 
957 hpi_status_t
958 hpi_pfc_num_macs_get(hpi_handle_t handle, uint8_t *data)
959 {
960 	uint8_t	addr[6];
961 	uint8_t	num = 0;
962 	int	i;
963 
964 	for (i = 0; i < 16; i++) {
965 		(void) hpi_pfc_mac_addr_get_i(handle, addr, i);
966 		if (addr[0] || addr[1] || addr[2] ||
967 		    addr[3] || addr[4] || addr[5])
968 			num++;
969 	}
970 
971 	*data = num;
972 
973 	return (HPI_SUCCESS);
974 }
975