Home | History | Annotate | Download | only in hxge
      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