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