xref: /titanic_41/usr/src/uts/common/io/hxge/hpi_pfc.c (revision dda0f8f7c5e815497a73958de19df2bad6105a50)
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 	bit = 1 << slot;
276 	config.bits.mac_addr_en = config.bits.mac_addr_en | bit;
277 
278 	return (hpi_pfc_set_config(handle, config));
279 }
280 
281 hpi_status_t
282 hpi_pfc_mac_addr_disable(hpi_handle_t handle, uint32_t slot)
283 {
284 	pfc_config_t	config;
285 	uint32_t	bit;
286 
287 	if (slot >= PFC_N_MAC_ADDRESSES) {
288 		return (HPI_FAILURE);
289 	}
290 
291 	(void) hpi_pfc_get_config(handle, &config);
292 
293 	bit = 1 << slot;
294 	config.bits.mac_addr_en = config.bits.mac_addr_en & ~bit;
295 
296 	return (hpi_pfc_set_config(handle, config));
297 }
298 
299 hpi_status_t
300 hpi_pfc_set_force_csum(hpi_handle_t handle, boolean_t force)
301 {
302 	pfc_config_t	config;
303 
304 	(void) hpi_pfc_get_config(handle, &config);
305 
306 	if (force)
307 		config.bits.force_cs_en = 1;
308 	else
309 		config.bits.force_cs_en = 0;
310 
311 	return (hpi_pfc_set_config(handle, config));
312 }
313 
314 hpi_status_t
315 hpi_pfc_cfg_vlan_table_clear(hpi_handle_t handle)
316 {
317 	int			i;
318 	int			offset;
319 	int			step = 8;
320 	pfc_vlan_table_t	table_entry;
321 
322 	table_entry.value = 0;
323 	for (i = 0; i < HXGE_VLAN_TABLE_ENTRIES; i++) {
324 		table_entry.bits.member = 0;
325 		offset = PFC_VLAN_TABLE + i * step;
326 		REG_PIO_WRITE64(handle, offset, table_entry.value);
327 	}
328 
329 	return (HPI_SUCCESS);
330 }
331 
332 hpi_status_t
333 hpi_pfc_cfg_vlan_table_entry_clear(hpi_handle_t handle, vlan_id_t vlan_id)
334 {
335 	uint64_t		offset;
336 	pfc_vlan_table_t	vlan_tbl_entry;
337 	uint64_t		bit;
338 
339 	/*
340 	 * Assumes that the hardware will generate the new parity
341 	 * data.
342 	 */
343 	offset = PFC_VLAN_REG_OFFSET(vlan_id);
344 	REG_PIO_READ64(handle, offset, (uint64_t *)&vlan_tbl_entry.value);
345 
346 	bit = PFC_VLAN_BIT_OFFSET(vlan_id);
347 	bit = 1 << bit;
348 	vlan_tbl_entry.bits.member = vlan_tbl_entry.bits.member & ~bit;
349 
350 	REG_PIO_WRITE64(handle, offset, vlan_tbl_entry.value);
351 
352 	return (HPI_SUCCESS);
353 }
354 
355 hpi_status_t
356 hpi_pfc_cfg_vlan_table_entry_set(hpi_handle_t handle, vlan_id_t vlan_id)
357 {
358 	uint64_t		offset;
359 	pfc_vlan_table_t	vlan_tbl_entry;
360 	uint64_t		bit;
361 
362 	/*
363 	 * Assumes that the hardware will generate the new parity
364 	 * data.
365 	 */
366 	offset = PFC_VLAN_REG_OFFSET(vlan_id);
367 	REG_PIO_READ64(handle, offset, (uint64_t *)&vlan_tbl_entry.value);
368 
369 	bit = PFC_VLAN_BIT_OFFSET(vlan_id);
370 	bit = 1 << bit;
371 	vlan_tbl_entry.bits.member = vlan_tbl_entry.bits.member | bit;
372 
373 	REG_PIO_WRITE64(handle, offset, vlan_tbl_entry.value);
374 
375 	return (HPI_SUCCESS);
376 }
377 
378 hpi_status_t
379 hpi_pfc_cfg_vlan_control_set(hpi_handle_t handle, boolean_t parity,
380     boolean_t valid, vlan_id_t vlan_id)
381 {
382 	pfc_vlan_ctrl_t	vlan_control;
383 
384 	vlan_control.value = 0;
385 
386 	if (parity)
387 		vlan_control.bits.par_en = 1;
388 	else
389 		vlan_control.bits.par_en = 0;
390 
391 	if (valid)
392 		vlan_control.bits.valid = 1;
393 	else
394 		vlan_control.bits.valid = 0;
395 
396 	vlan_control.bits.id = vlan_id;
397 
398 	REG_PIO_WRITE64(handle, PFC_VLAN_CTRL, vlan_control.value);
399 
400 	return (HPI_SUCCESS);
401 }
402 
403 hpi_status_t
404 hpi_pfc_get_vlan_parity_log(hpi_handle_t handle, pfc_vlan_par_err_log_t *logp)
405 {
406 	uint64_t offset;
407 
408 	offset = PFC_VLAN_PAR_ERR_LOG;
409 	REG_PIO_READ64(handle, offset, &logp->value);
410 
411 	return (HPI_SUCCESS);
412 }
413 
414 hpi_status_t
415 hpi_pfc_set_mac_address(hpi_handle_t handle, uint32_t slot, uint64_t address)
416 {
417 	uint64_t		offset;
418 	uint64_t		moffset;
419 	pfc_mac_addr_mask_t	mask;
420 	pfc_mac_addr_t		addr;
421 
422 	if (slot >= PFC_N_MAC_ADDRESSES)
423 		return (HPI_FAILURE);
424 
425 	offset = PFC_MAC_ADDRESS(slot);
426 	moffset = PFC_MAC_ADDRESS_MASK(slot);
427 
428 	addr.bits.addr = address;
429 	mask.bits.mask = 0x0;
430 
431 	REG_PIO_WRITE64(handle, offset, addr.value);
432 	REG_PIO_WRITE64(handle, moffset, mask.value);
433 
434 	return (hpi_pfc_mac_addr_enable(handle, slot));
435 }
436 
437 hpi_status_t
438 hpi_pfc_clear_mac_address(hpi_handle_t handle, uint32_t slot)
439 {
440 	uint64_t offset, moffset;
441 	uint64_t zaddr = 0x0ULL;
442 	uint64_t zmask = 0x0ULL;
443 
444 	if (slot >= PFC_N_MAC_ADDRESSES)
445 		return (HPI_FAILURE);
446 
447 	(void) hpi_pfc_mac_addr_disable(handle, slot);
448 
449 	offset = PFC_MAC_ADDRESS(slot);
450 	moffset = PFC_MAC_ADDRESS_MASK(slot);
451 
452 	REG_PIO_WRITE64(handle, offset, zaddr);
453 	REG_PIO_WRITE64(handle, moffset, zmask);
454 
455 	return (HPI_SUCCESS);
456 }
457 
458 hpi_status_t
459 hpi_pfc_clear_multicast_hash_table(hpi_handle_t handle, uint32_t slot)
460 {
461 	uint64_t offset;
462 
463 	if (slot >= PFC_N_MAC_ADDRESSES)
464 		return (HPI_FAILURE);
465 
466 	offset = PFC_HASH_ADDR(slot);
467 	REG_PIO_WRITE64(handle, offset, 0ULL);
468 
469 	return (HPI_SUCCESS);
470 }
471 
472 hpi_status_t
473 hpi_pfc_set_multicast_hash_table(hpi_handle_t handle, uint32_t slot,
474 	uint64_t address)
475 {
476 	uint64_t offset;
477 
478 	if (slot >= PFC_N_MAC_ADDRESSES)
479 		return (HPI_FAILURE);
480 
481 	offset = PFC_HASH_ADDR(slot);
482 	REG_PIO_WRITE64(handle, offset, address);
483 
484 	return (HPI_SUCCESS);
485 }
486 
487 hpi_status_t
488 hpi_pfc_set_l2_class_slot(hpi_handle_t handle, uint16_t etype, boolean_t valid,
489     int slot)
490 {
491 	pfc_l2_class_config_t	l2_config;
492 	uint64_t		offset;
493 
494 	if (slot >= PFC_N_MAC_ADDRESSES)
495 		return (HPI_FAILURE);
496 
497 	l2_config.value = 0;
498 
499 	if (valid)
500 		l2_config.bits.valid = 1;
501 	else
502 		l2_config.bits.valid = 0;
503 
504 	l2_config.bits.etype = etype;
505 	l2_config.bits.rsrvd = 0;
506 
507 	offset = PFC_L2_CONFIG(slot);
508 	REG_PIO_WRITE64(handle, offset, l2_config.value);
509 
510 	return (HPI_SUCCESS);
511 }
512 
513 hpi_status_t
514 hpi_pfc_set_l3_class_config(hpi_handle_t handle, tcam_class_t slot,
515     tcam_key_cfg_t cfg)
516 {
517 	pfc_l3_class_config_t	l3_config;
518 	uint64_t		offset;
519 
520 	if (slot >= PFC_N_MAC_ADDRESSES)
521 		return (HPI_FAILURE);
522 
523 	l3_config.value = 0;
524 
525 	if (cfg.lookup_enable)
526 		l3_config.bits.tsel = 1;
527 	else
528 		l3_config.bits.tsel = 0;
529 
530 	if (cfg.discard)
531 		l3_config.bits.discard = 1;
532 	else
533 		l3_config.bits.discard = 0;
534 
535 	offset = PFC_L3_CONFIG(slot);
536 	REG_PIO_WRITE64(handle, offset, l3_config.value);
537 
538 	return (HPI_SUCCESS);
539 }
540 
541 hpi_status_t
542 hpi_pfc_get_l3_class_config(hpi_handle_t handle, tcam_class_t slot,
543     tcam_key_cfg_t *cfg)
544 {
545 	pfc_l3_class_config_t	l3_config;
546 	uint64_t		offset;
547 
548 	if (slot >= PFC_N_MAC_ADDRESSES)
549 		return (HPI_FAILURE);
550 
551 	offset = PFC_L3_CONFIG(slot);
552 	REG_PIO_READ64(handle, offset, &l3_config.value);
553 
554 	if (l3_config.bits.tsel)
555 		cfg->lookup_enable = 1;
556 	else
557 		cfg->lookup_enable = 0;
558 
559 	if (l3_config.bits.discard)
560 		cfg->discard = 1;
561 	else
562 		cfg->discard = 0;
563 
564 	return (HPI_SUCCESS);
565 }
566 
567 static hpi_status_t
568 hpi_pfc_set_tcam_control(hpi_handle_t handle, pfc_tcam_ctrl_t *tcontrolp)
569 {
570 	uint64_t offset;
571 
572 	offset = PFC_TCAM_CTRL;
573 	REG_PIO_WRITE64(handle, offset, tcontrolp->value);
574 
575 	return (HPI_SUCCESS);
576 }
577 
578 hpi_status_t
579 hpi_pfc_tcam_entry_invalidate(hpi_handle_t handle, uint32_t location)
580 {
581 	hxge_tcam_entry_t	tcam_ptr;
582 
583 	(void) memset(&tcam_ptr, 0, sizeof (hxge_tcam_entry_t));
584 	(void) hpi_pfc_tcam_entry_write(handle, location, &tcam_ptr);
585 
586 	return (HPI_SUCCESS);
587 }
588 
589 hpi_status_t
590 hpi_pfc_tcam_invalidate_all(hpi_handle_t handle)
591 {
592 	int		i;
593 	pfc_tcam_ctrl_t	tcontrol;
594 
595 	tcontrol.value = 0;
596 	for (i = 0; i < PFC_N_TCAM_ENTRIES; i++) {
597 		(void) hpi_pfc_set_tcam_control(handle, &tcontrol);
598 		(void) hpi_pfc_tcam_entry_invalidate(handle, i);
599 	}
600 
601 	return (HPI_SUCCESS);
602 }
603 
604 hpi_status_t
605 hpi_pfc_tcam_entry_write(hpi_handle_t handle, uint32_t location,
606     hxge_tcam_entry_t *tcam_ptr)
607 {
608 	uint64_t	tcam_stat;
609 	pfc_tcam_ctrl_t	tctl;
610 
611 	WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
612 	WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
613 
614 	WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
615 	WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
616 
617 	HPI_DEBUG_MSG((handle.function, HPI_PFC_CTL,
618 	    " tcam write: location %x\n key:  %llx %llx\n mask: %llx %llx\n",
619 	    location, tcam_ptr->key0, tcam_ptr->key1,
620 	    tcam_ptr->mask0, tcam_ptr->mask1));
621 
622 	tctl.value = 0;
623 	tctl.bits.addr = location;
624 	tctl.bits.cmd = TCAM_CTL_RWC_TCAM_WR;
625 
626 	HPI_DEBUG_MSG((handle.function, HPI_PFC_CTL,
627 	    " tcam write: ctl value %llx \n", tctl.value));
628 
629 	WRITE_TCAM_REG_CTL(handle, tctl.value);
630 
631 	tcam_stat = hpi_pfc_tcam_check_completion(handle, TCAM_RWC_STAT);
632 
633 	if (tcam_stat & HPI_FAILURE) {
634 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
635 		    "TCAM Write failed loc %d \n", location));
636 		return (HPI_PFC_TCAM_WR_ERROR);
637 	}
638 
639 	return (HPI_SUCCESS);
640 }
641 
642 hpi_status_t
643 hpi_pfc_get_tcam_parity_log(hpi_handle_t handle, pfc_tcam_par_err_log_t *logp)
644 {
645 	uint64_t offset;
646 
647 	offset = PFC_TCAM_PAR_ERR_LOG;
648 	REG_PIO_READ64(handle, offset, &logp->value);
649 
650 	return (HPI_SUCCESS);
651 }
652 
653 hpi_status_t
654 hpi_pfc_get_tcam_auto_init(hpi_handle_t handle, pfc_auto_init_t *autoinitp)
655 {
656 	uint64_t offset;
657 
658 	offset = PFC_AUTO_INIT;
659 	REG_PIO_READ64(handle, offset, &autoinitp->value);
660 
661 	return (HPI_SUCCESS);
662 }
663 
664 hpi_status_t
665 hpi_pfc_set_tcp_control_discard(hpi_handle_t handle, boolean_t discard)
666 {
667 	uint64_t	offset;
668 	tcp_ctrl_mask_t	tcp;
669 
670 	tcp.value = 0;
671 
672 	offset = TCP_CTRL_MASK;
673 	REG_PIO_READ64(handle, offset, &tcp.value);
674 
675 	if (discard)
676 		tcp.bits.discard = 1;
677 	else
678 		tcp.bits.discard = 0;
679 
680 	REG_PIO_WRITE64(handle, offset, tcp.value);
681 
682 	return (HPI_SUCCESS);
683 }
684 
685 hpi_status_t
686 hpi_pfc_set_tcp_control_fin(hpi_handle_t handle, boolean_t fin)
687 {
688 	uint64_t	offset;
689 	tcp_ctrl_mask_t	tcp;
690 
691 	tcp.value = 0;
692 
693 	offset = TCP_CTRL_MASK;
694 	REG_PIO_READ64(handle, offset, &tcp.value);
695 
696 	if (fin)
697 		tcp.bits.fin = 1;
698 	else
699 		tcp.bits.fin = 0;
700 
701 	REG_PIO_WRITE64(handle, offset, tcp.value);
702 	return (HPI_SUCCESS);
703 }
704 
705 hpi_status_t
706 hpi_pfc_set_tcp_control_syn(hpi_handle_t handle, boolean_t syn)
707 {
708 	uint64_t	offset;
709 	tcp_ctrl_mask_t	tcp;
710 
711 	tcp.value = 0;
712 
713 	offset = TCP_CTRL_MASK;
714 	REG_PIO_READ64(handle, offset, &tcp.value);
715 
716 	if (syn)
717 		tcp.bits.syn = 1;
718 	else
719 		tcp.bits.syn = 0;
720 
721 	REG_PIO_WRITE64(handle, offset, tcp.value);
722 	return (HPI_SUCCESS);
723 }
724 
725 hpi_status_t
726 hpi_pfc_set_tcp_control_rst(hpi_handle_t handle, boolean_t rst)
727 {
728 	uint64_t	offset;
729 	tcp_ctrl_mask_t	tcp;
730 
731 	tcp.value = 0;
732 
733 	offset = TCP_CTRL_MASK;
734 	REG_PIO_READ64(handle, offset, &tcp.value);
735 
736 	if (rst)
737 		tcp.bits.rst = 1;
738 	else
739 		tcp.bits.rst = 0;
740 
741 	REG_PIO_WRITE64(handle, offset, tcp.value);
742 	return (HPI_SUCCESS);
743 }
744 
745 hpi_status_t
746 hpi_pfc_set_tcp_control_psh(hpi_handle_t handle, boolean_t push)
747 {
748 	uint64_t	offset;
749 	tcp_ctrl_mask_t	tcp;
750 
751 	tcp.value = 0;
752 
753 	offset = TCP_CTRL_MASK;
754 	REG_PIO_READ64(handle, offset, &tcp.value);
755 
756 	if (push)
757 		tcp.bits.psh = 1;
758 	else
759 		tcp.bits.psh = 0;
760 
761 	REG_PIO_WRITE64(handle, offset, tcp.value);
762 	return (HPI_SUCCESS);
763 }
764 
765 hpi_status_t
766 hpi_pfc_set_tcp_control_ack(hpi_handle_t handle, boolean_t ack)
767 {
768 	uint64_t	offset;
769 	tcp_ctrl_mask_t	tcp;
770 
771 	tcp.value = 0;
772 
773 	offset = TCP_CTRL_MASK;
774 	REG_PIO_READ64(handle, offset, &tcp.value);
775 
776 	if (ack)
777 		tcp.bits.ack = 1;
778 	else
779 		tcp.bits.ack = 0;
780 
781 	REG_PIO_WRITE64(handle, offset, tcp.value);
782 	return (HPI_SUCCESS);
783 }
784 
785 hpi_status_t
786 hpi_pfc_set_hash_seed_value(hpi_handle_t handle, uint32_t seed)
787 {
788 	uint64_t	offset;
789 	src_hash_val_t	src_hash_seed;
790 
791 	src_hash_seed.value = 0;
792 	src_hash_seed.bits.seed = seed;
793 
794 	offset = SRC_HASH_VAL;
795 	REG_PIO_WRITE64(handle, offset, src_hash_seed.value);
796 
797 	return (HPI_SUCCESS);
798 }
799 
800 hpi_status_t
801 hpi_pfc_get_interrupt_status(hpi_handle_t handle, pfc_int_status_t *statusp)
802 {
803 	uint64_t offset;
804 
805 	offset = PFC_INT_STATUS;
806 	REG_PIO_READ64(handle, offset, &statusp->value);
807 
808 	return (HPI_SUCCESS);
809 }
810 
811 hpi_status_t
812 hpi_pfc_clear_interrupt_status(hpi_handle_t handle)
813 {
814 	uint64_t offset;
815 
816 	offset = PFC_INT_STATUS;
817 	REG_PIO_WRITE64(handle, offset, HXGE_PFC_INT_STATUS_CLEAR);
818 
819 	return (HPI_SUCCESS);
820 }
821 
822 hpi_status_t
823 hpi_pfc_set_interrupt_mask(hpi_handle_t handle, boolean_t drop,
824 	boolean_t tcam_parity_error, boolean_t vlan_parity_error)
825 {
826 	pfc_int_mask_t	mask;
827 	uint64_t	offset;
828 
829 	mask.value = 0;
830 
831 	if (drop)
832 		mask.bits.pkt_drop_mask = 1;
833 	else
834 		mask.bits.pkt_drop_mask = 0;
835 
836 	if (tcam_parity_error)
837 		mask.bits.tcam_parity_err_mask = 1;
838 	else
839 		mask.bits.tcam_parity_err_mask = 0;
840 
841 	if (vlan_parity_error)
842 		mask.bits.vlan_parity_err_mask = 1;
843 	else
844 		mask.bits.vlan_parity_err_mask = 0;
845 
846 	offset = PFC_INT_MASK;
847 	REG_PIO_WRITE64(handle, offset, mask.value);
848 
849 	return (HPI_SUCCESS);
850 }
851 
852 hpi_status_t
853 hpi_pfc_get_drop_log(hpi_handle_t handle, pfc_drop_log_t *logp)
854 {
855 	uint64_t offset;
856 
857 	offset = PFC_DROP_LOG;
858 	REG_PIO_READ64(handle, offset, &logp->value);
859 
860 	return (HPI_SUCCESS);
861 }
862 
863 hpi_status_t
864 hpi_pfc_set_drop_log_mask(hpi_handle_t handle, boolean_t vlan_drop,
865     boolean_t tcam_drop, boolean_t class_code_drop, boolean_t l2_addr_drop,
866     boolean_t tcp_ctrl_drop)
867 {
868 	uint64_t		offset;
869 	pfc_drop_log_mask_t	log;
870 
871 	log.value = 0;
872 
873 	if (vlan_drop)
874 		log.bits.vlan_drop_mask = 1;
875 	if (tcam_drop)
876 		log.bits.tcam_drop_mask = 1;
877 	if (class_code_drop)
878 		log.bits.class_code_drop_mask = 1;
879 	if (l2_addr_drop)
880 		log.bits.l2_addr_drop_mask = 1;
881 	if (tcp_ctrl_drop)
882 		log.bits.tcp_ctrl_drop_mask = 1;
883 
884 	offset = PFC_DROP_LOG_MASK;
885 	REG_PIO_WRITE64(handle, offset, log.value);
886 
887 	return (HPI_SUCCESS);
888 }
889 
890 hpi_status_t
891 hpi_pfc_get_bad_csum_counter(hpi_handle_t handle, uint64_t *countp)
892 {
893 	uint64_t offset;
894 
895 	offset = PFC_BAD_CS_COUNTER;
896 	REG_PIO_READ64(handle, offset, countp);
897 
898 	return (HPI_SUCCESS);
899 }
900 
901 hpi_status_t
902 hpi_pfc_get_drop_counter(hpi_handle_t handle, uint64_t *countp)
903 {
904 	uint64_t offset;
905 
906 	offset = PFC_DROP_COUNTER;
907 	REG_PIO_READ64(handle, offset, countp);
908 
909 	return (HPI_SUCCESS);
910 }
911 
912 hpi_status_t
913 hpi_pfc_get_number_mac_addrs(hpi_handle_t handle, uint32_t *n_of_addrs)
914 {
915 	HXGE_REG_RD32(handle, HCR_REG + HCR_N_MAC_ADDRS, n_of_addrs);
916 	return (HPI_SUCCESS);
917 }
918 
919 hpi_status_t
920 hpi_pfc_mac_addr_get_i(hpi_handle_t handle, uint8_t *data, int slot)
921 {
922 	uint32_t step = sizeof (uint32_t);
923 	uint32_t addr_hi = 0, addr_lo = 0;
924 
925 	if (slot >= PFC_N_MAC_ADDRESSES)
926 		return (HPI_FAILURE);
927 
928 	/*
929 	 * Read the MAC address out of the SPROM at the blade's
930 	 * specific location.
931 	 */
932 	HXGE_REG_RD32(handle, HCR_REG + HCR_ADDR_LO + slot * step, &addr_lo);
933 	HXGE_REG_RD32(handle, HCR_REG + HCR_ADDR_HI + slot * step, &addr_hi);
934 
935 	data[0] = addr_lo & 0x000000ff;
936 	data[1] = (addr_lo & 0x0000ff00) >> 8;
937 	data[2] = (addr_lo & 0x00ff0000) >> 16;
938 	data[3] = (addr_lo & 0xff000000) >> 24;
939 	data[4] = (addr_hi & 0x00000ff00) >> 8;
940 	data[5] = (addr_hi & 0x0000000ff);
941 
942 	return (HPI_SUCCESS);
943 }
944 
945 hpi_status_t
946 hpi_pfc_num_macs_get(hpi_handle_t handle, uint8_t *data)
947 {
948 	uint8_t	addr[6];
949 	uint8_t	num = 0;
950 	int	i;
951 
952 	for (i = 0; i < 16; i++) {
953 		(void) hpi_pfc_mac_addr_get_i(handle, addr, i);
954 		if (addr[0] || addr[1] || addr[2] ||
955 		    addr[3] || addr[4] || addr[5])
956 			num++;
957 	}
958 
959 	*data = num;
960 
961 	return (HPI_SUCCESS);
962 }
963