/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #define HXGE_VMAC_RX_STAT_CLEAR 0x1ffULL #define HXGE_VMAC_TX_STAT_CLEAR 0x7ULL #define HXGE_VMAC_RX_MASK_OVERFLOW 0x1fe #define HXGE_VMAC_RX_MASK_FRAME 0x1 hpi_status_t hpi_tx_vmac_reset(hpi_handle_t handle) { vmac_rst_t reset; HXGE_REG_RD64(handle, VMAC_RST, &(reset.value)); reset.bits.tx_reset = 1; HXGE_REG_WR64(handle, VMAC_RST, reset.value); return (HPI_SUCCESS); } hpi_status_t hpi_rx_vmac_reset(hpi_handle_t handle) { vmac_rst_t reset; HXGE_REG_RD64(handle, VMAC_RST, &(reset.value)); reset.bits.rx_reset = 1; HXGE_REG_WR64(handle, VMAC_RST, reset.value); return (HPI_SUCCESS); } hpi_status_t hpi_vmac_tx_config(hpi_handle_t handle, config_op_t op, uint64_t config, uint16_t max_frame_length) { vmac_tx_cfg_t cfg; if (config == 0) { HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, " hpi_vmac_tx_config Invalid Input: config <0x%x>", config)); return (HPI_FAILURE); } HXGE_REG_RD64(handle, VMAC_TX_CFG, &cfg.value); switch (op) { case ENABLE: if (config & CFG_VMAC_TX_EN) cfg.bits.tx_en = 1; if (config & CFG_VMAC_TX_CRC_INSERT) cfg.bits.crc_insert = 1; if (config & CFG_VMAC_TX_PAD) cfg.bits.tx_pad = 1; if (max_frame_length) cfg.bits.tx_max_frame_length = max_frame_length; break; case DISABLE: if (config & CFG_VMAC_TX_EN) cfg.bits.tx_en = 0; if (config & CFG_VMAC_TX_CRC_INSERT) cfg.bits.crc_insert = 0; if (config & CFG_VMAC_TX_PAD) cfg.bits.tx_pad = 0; break; case INIT: if (config & CFG_VMAC_TX_EN) cfg.bits.tx_en = 1; else cfg.bits.tx_en = 0; if (config & CFG_VMAC_TX_CRC_INSERT) cfg.bits.crc_insert = 1; else cfg.bits.crc_insert = 0; if (config & CFG_VMAC_TX_PAD) cfg.bits.tx_pad = 1; else cfg.bits.tx_pad = 0; if (max_frame_length) cfg.bits.tx_max_frame_length = max_frame_length; break; default: HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, " hpi_vmac_tx_config Invalid Input: op <0x%x>", op)); return (HPI_FAILURE); } HXGE_REG_WR64(handle, VMAC_TX_CFG, cfg.value); return (HPI_SUCCESS); } hpi_status_t hpi_vmac_rx_set_framesize(hpi_handle_t handle, uint16_t max_frame_length) { vmac_rx_cfg_t cfg; uint16_t fsize; HXGE_REG_RD64(handle, VMAC_RX_CFG, &cfg.value); /* * HW team not sure setting framesize to 0 is problematic * or not. */ if (max_frame_length == 0) fsize = 1; else fsize = max_frame_length; cfg.bits.rx_max_frame_length = fsize; HXGE_REG_WR64(handle, VMAC_RX_CFG, cfg.value); return (HPI_SUCCESS); } hpi_status_t hpi_vmac_rx_config(hpi_handle_t handle, config_op_t op, uint64_t config, uint16_t max_frame_length) { vmac_rx_cfg_t cfg; if (config == 0) { HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, " hpi_vmac_rx_config Invalid Input: config <0x%x>", config)); return (HPI_FAILURE); } HXGE_REG_RD64(handle, VMAC_RX_CFG, &cfg.value); switch (op) { case ENABLE: if (config & CFG_VMAC_RX_EN) cfg.bits.rx_en = 1; if (config & CFG_VMAC_RX_CRC_CHECK_DISABLE) cfg.bits.crc_check_disable = 1; if (config & CFG_VMAC_RX_STRIP_CRC) cfg.bits.strip_crc = 1; if (config & CFG_VMAC_RX_PASS_FLOW_CTRL_FR) cfg.bits.pass_flow_ctrl_fr = 1; if (config & CFG_VMAC_RX_PROMIXCUOUS_GROUP) cfg.bits.promiscuous_group = 1; if (config & CFG_VMAC_RX_PROMISCUOUS_MODE) cfg.bits.promiscuous_mode = 1; if (config & CFG_VMAC_RX_LOOP_BACK) cfg.bits.loopback = 1; break; case DISABLE: if (config & CFG_VMAC_RX_EN) cfg.bits.rx_en = 0; if (config & CFG_VMAC_RX_CRC_CHECK_DISABLE) cfg.bits.crc_check_disable = 0; if (config & CFG_VMAC_RX_STRIP_CRC) cfg.bits.strip_crc = 0; if (config & CFG_VMAC_RX_PASS_FLOW_CTRL_FR) cfg.bits.pass_flow_ctrl_fr = 0; if (config & CFG_VMAC_RX_PROMIXCUOUS_GROUP) cfg.bits.promiscuous_group = 0; if (config & CFG_VMAC_RX_PROMISCUOUS_MODE) cfg.bits.promiscuous_mode = 0; if (config & CFG_VMAC_RX_LOOP_BACK) cfg.bits.loopback = 0; break; case INIT: if (config & CFG_VMAC_RX_EN) cfg.bits.rx_en = 1; else cfg.bits.rx_en = 0; if (config & CFG_VMAC_RX_CRC_CHECK_DISABLE) cfg.bits.crc_check_disable = 1; else cfg.bits.crc_check_disable = 0; if (config & CFG_VMAC_RX_STRIP_CRC) cfg.bits.strip_crc = 1; else cfg.bits.strip_crc = 0; if (config & CFG_VMAC_RX_PASS_FLOW_CTRL_FR) cfg.bits.pass_flow_ctrl_fr = 1; else cfg.bits.pass_flow_ctrl_fr = 0; if (config & CFG_VMAC_RX_PROMIXCUOUS_GROUP) cfg.bits.promiscuous_group = 1; else cfg.bits.promiscuous_group = 0; if (config & CFG_VMAC_RX_PROMISCUOUS_MODE) cfg.bits.promiscuous_mode = 1; else cfg.bits.promiscuous_mode = 0; if (config & CFG_VMAC_RX_LOOP_BACK) cfg.bits.loopback = 1; else cfg.bits.loopback = 0; break; default: HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, " hpi_vmac_rx_config Invalid Input: op <0x%x>", op)); return (HPI_FAILURE); } if (max_frame_length) cfg.bits.rx_max_frame_length = max_frame_length; HXGE_REG_WR64(handle, VMAC_RX_CFG, cfg.value); return (HPI_SUCCESS); } hpi_status_t hpi_vmac_clear_rx_int_stat(hpi_handle_t handle) { uint64_t offset; offset = VMAC_RX_STAT; REG_PIO_WRITE64(handle, offset, HXGE_VMAC_RX_STAT_CLEAR); return (HPI_SUCCESS); } hpi_status_t hpi_vmac_clear_tx_int_stat(hpi_handle_t handle) { uint64_t offset; offset = VMAC_TX_STAT; REG_PIO_WRITE64(handle, offset, HXGE_VMAC_TX_STAT_CLEAR); return (HPI_SUCCESS); } hpi_status_t hpi_pfc_set_rx_int_stat_mask(hpi_handle_t handle, boolean_t overflow_cnt, boolean_t frame_cnt) { uint64_t offset; uint64_t value = 0; if (overflow_cnt) value |= HXGE_VMAC_RX_MASK_OVERFLOW; if (frame_cnt) value |= HXGE_VMAC_RX_MASK_FRAME; offset = VMAC_RX_MSK; REG_PIO_WRITE64(handle, offset, value); return (HPI_SUCCESS); } hpi_status_t hpi_pfc_set_tx_int_stat_mask(hpi_handle_t handle, boolean_t overflow_cnt, boolean_t frame_cnt) { uint64_t offset; uint64_t value = 0; uint64_t overflow_mask = 0x6; uint64_t frame_mask = 0x1; if (overflow_cnt) value |= overflow_mask; if (frame_cnt) value |= frame_mask; offset = VMAC_TX_MSK; REG_PIO_WRITE64(handle, offset, value); return (HPI_SUCCESS); }