hpi_pfc.c revision 6349:b4971e04f83d
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
36static uint64_t
37hpi_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
88hpi_status_t
89hpi_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
118hpi_status_t
119hpi_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
144hpi_status_t
145hpi_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
172static hpi_status_t
173hpi_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
183static hpi_status_t
184hpi_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
194hpi_status_t
195hpi_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
212hpi_status_t
213hpi_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
230hpi_status_t
231hpi_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
248hpi_status_t
249hpi_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
263hpi_status_t
264hpi_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
281hpi_status_t
282hpi_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
299hpi_status_t
300hpi_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
314hpi_status_t
315hpi_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
332hpi_status_t
333hpi_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
355hpi_status_t
356hpi_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
378hpi_status_t
379hpi_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
403hpi_status_t
404hpi_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
414hpi_status_t
415hpi_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
437hpi_status_t
438hpi_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
458hpi_status_t
459hpi_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
472hpi_status_t
473hpi_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
487hpi_status_t
488hpi_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
513hpi_status_t
514hpi_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
541hpi_status_t
542hpi_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
567static hpi_status_t
568hpi_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
578hpi_status_t
579hpi_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
589hpi_status_t
590hpi_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
604hpi_status_t
605hpi_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
642hpi_status_t
643hpi_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
653hpi_status_t
654hpi_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
664hpi_status_t
665hpi_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
685hpi_status_t
686hpi_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
705hpi_status_t
706hpi_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
725hpi_status_t
726hpi_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
745hpi_status_t
746hpi_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
765hpi_status_t
766hpi_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
785hpi_status_t
786hpi_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
800hpi_status_t
801hpi_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
811hpi_status_t
812hpi_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
822hpi_status_t
823hpi_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
852hpi_status_t
853hpi_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
863hpi_status_t
864hpi_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
890hpi_status_t
891hpi_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
901hpi_status_t
902hpi_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
912hpi_status_t
913hpi_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
919hpi_status_t
920hpi_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
945hpi_status_t
946hpi_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