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  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <hxge_impl.h>
     27 #include <hxge_vmac.h>
     28 
     29 hxge_status_t hxge_vmac_init(p_hxge_t hxgep);
     30 hxge_status_t hxge_tx_vmac_init(p_hxge_t hxgep);
     31 hxge_status_t hxge_rx_vmac_init(p_hxge_t hxgep);
     32 hxge_status_t hxge_tx_vmac_enable(p_hxge_t hxgep);
     33 hxge_status_t hxge_tx_vmac_disable(p_hxge_t hxgep);
     34 hxge_status_t hxge_rx_vmac_enable(p_hxge_t hxgep);
     35 hxge_status_t hxge_rx_vmac_disable(p_hxge_t hxgep);
     36 hxge_status_t hxge_tx_vmac_reset(p_hxge_t hxgep);
     37 hxge_status_t hxge_rx_vmac_reset(p_hxge_t hxgep);
     38 uint_t hxge_vmac_intr(caddr_t arg1, caddr_t arg2);
     39 hxge_status_t hxge_set_promisc(p_hxge_t hxgep, boolean_t on);
     40 
     41 hxge_status_t
     42 hxge_link_init(p_hxge_t hxgep)
     43 {
     44 	p_hxge_stats_t		statsp;
     45 
     46 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_link_init>"));
     47 
     48 	statsp = hxgep->statsp;
     49 
     50 	statsp->mac_stats.cap_10gfdx = 1;
     51 	statsp->mac_stats.lp_cap_10gfdx = 1;
     52 
     53 	/*
     54 	 * The driver doesn't control the link.
     55 	 * It is always 10Gb full duplex.
     56 	 */
     57 	statsp->mac_stats.link_duplex = 2;
     58 	statsp->mac_stats.link_speed = 10000;
     59 
     60 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_link_init"));
     61 	return (HXGE_OK);
     62 }
     63 
     64 hxge_status_t
     65 hxge_vmac_init(p_hxge_t hxgep)
     66 {
     67 	hxge_status_t status = HXGE_OK;
     68 
     69 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_vmac_init:"));
     70 
     71 	if ((status = hxge_tx_vmac_reset(hxgep)) != HXGE_OK)
     72 		goto fail;
     73 
     74 	if ((status = hxge_rx_vmac_reset(hxgep)) != HXGE_OK)
     75 		goto fail;
     76 
     77 	if ((status = hxge_tx_vmac_enable(hxgep)) != HXGE_OK)
     78 		goto fail;
     79 
     80 	if ((status = hxge_rx_vmac_enable(hxgep)) != HXGE_OK)
     81 		goto fail;
     82 
     83 	/* Clear the interrupt status registers */
     84 	(void) hpi_vmac_clear_rx_int_stat(hxgep->hpi_handle);
     85 	(void) hpi_vmac_clear_tx_int_stat(hxgep->hpi_handle);
     86 
     87 	/*
     88 	 * Take the masks off the overflow counters. Interrupt the system when
     89 	 * any counts overflow. Don't interrupt the system for each frame.
     90 	 * The current counts are retrieved when the "kstat" command is used.
     91 	 */
     92 	(void) hpi_pfc_set_rx_int_stat_mask(hxgep->hpi_handle, 0, 1);
     93 	(void) hpi_pfc_set_tx_int_stat_mask(hxgep->hpi_handle, 0, 1);
     94 
     95 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_vmac_init:"));
     96 
     97 	return (HXGE_OK);
     98 fail:
     99 	HXGE_DEBUG_MSG((hxgep, MAC_CTL,
    100 	    "hxge_vmac_init: failed to initialize VMAC>"));
    101 
    102 	return (status);
    103 }
    104 
    105 
    106 /* Initialize the TxVMAC sub-block */
    107 
    108 hxge_status_t
    109 hxge_tx_vmac_init(p_hxge_t hxgep)
    110 {
    111 	uint64_t	config;
    112 	hpi_handle_t	handle = hxgep->hpi_handle;
    113 
    114 	/* CFG_VMAC_TX_EN is done separately */
    115 	config = CFG_VMAC_TX_CRC_INSERT | CFG_VMAC_TX_PAD;
    116 
    117 	if (hpi_vmac_tx_config(handle, INIT, config,
    118 	    hxgep->vmac.maxframesize) != HPI_SUCCESS)
    119 		return (HXGE_ERROR);
    120 
    121 	hxgep->vmac.tx_config = config;
    122 
    123 	return (HXGE_OK);
    124 }
    125 
    126 /* Initialize the RxVMAC sub-block */
    127 
    128 hxge_status_t
    129 hxge_rx_vmac_init(p_hxge_t hxgep)
    130 {
    131 	uint64_t	xconfig;
    132 	hpi_handle_t	handle = hxgep->hpi_handle;
    133 	uint16_t	max_frame_length = hxgep->vmac.maxframesize;
    134 
    135 	/*
    136 	 * NOTE: CFG_VMAC_RX_ENABLE is done separately. Do not enable
    137 	 * strip CRC.  Bug ID 11451 -- enable strip CRC will cause
    138 	 * rejection on minimum sized packets.
    139 	 */
    140 	xconfig = CFG_VMAC_RX_PASS_FLOW_CTRL_FR;
    141 
    142 	if (hxgep->filter.all_phys_cnt != 0)
    143 		xconfig |= CFG_VMAC_RX_PROMISCUOUS_MODE;
    144 
    145 	if (hxgep->filter.all_multicast_cnt != 0)
    146 		xconfig |= CFG_VMAC_RX_PROMIXCUOUS_GROUP;
    147 
    148 	if (hxgep->statsp->port_stats.lb_mode != hxge_lb_normal)
    149 		xconfig |= CFG_VMAC_RX_LOOP_BACK;
    150 
    151 	if (hpi_vmac_rx_config(handle, INIT, xconfig, max_frame_length)
    152 	    != HPI_SUCCESS)
    153 		return (HXGE_ERROR);
    154 
    155 	hxgep->vmac.rx_config = xconfig;
    156 
    157 	return (HXGE_OK);
    158 }
    159 
    160 /* Enable TxVMAC */
    161 
    162 hxge_status_t
    163 hxge_tx_vmac_enable(p_hxge_t hxgep)
    164 {
    165 	hpi_status_t	rv;
    166 	hxge_status_t	status = HXGE_OK;
    167 	hpi_handle_t	handle = hxgep->hpi_handle;
    168 
    169 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_tx_vmac_enable"));
    170 
    171 	rv = hxge_tx_vmac_init(hxgep);
    172 	if (rv != HXGE_OK)
    173 		return (rv);
    174 
    175 	/* Based on speed */
    176 	hxgep->msg_min = ETHERMIN;
    177 
    178 	rv = hpi_vmac_tx_config(handle, ENABLE, CFG_VMAC_TX_EN, 0);
    179 
    180 	status = (rv == HPI_SUCCESS) ? HXGE_OK : HXGE_ERROR;
    181 
    182 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_tx_vmac_enable"));
    183 
    184 	return (status);
    185 }
    186 
    187 /* Disable TxVMAC */
    188 
    189 hxge_status_t
    190 hxge_tx_vmac_disable(p_hxge_t hxgep)
    191 {
    192 	hpi_status_t	rv;
    193 	hxge_status_t	status = HXGE_OK;
    194 	hpi_handle_t	handle = hxgep->hpi_handle;
    195 
    196 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_tx_vmac_disable"));
    197 
    198 	rv = hpi_vmac_tx_config(handle, DISABLE, CFG_VMAC_TX_EN, 0);
    199 
    200 	status = (rv == HPI_SUCCESS) ? HXGE_OK : HXGE_ERROR;
    201 
    202 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_tx_vmac_disable"));
    203 
    204 	return (status);
    205 }
    206 
    207 /* Enable RxVMAC */
    208 
    209 hxge_status_t
    210 hxge_rx_vmac_enable(p_hxge_t hxgep)
    211 {
    212 	hpi_status_t	rv;
    213 	hxge_status_t	status = HXGE_OK;
    214 	hpi_handle_t	handle = hxgep->hpi_handle;
    215 
    216 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_rx_vmac_enable"));
    217 
    218 	/*
    219 	 * Because of hardware bug document with CR6770577, need
    220 	 * reprogram max framesize when enabling/disabling RX
    221 	 * vmac.  Max framesize is programed here in
    222 	 * hxge_rx_vmac_init().
    223 	 */
    224 	rv = hxge_rx_vmac_init(hxgep);
    225 	if (rv != HXGE_OK)
    226 		return (rv);
    227 
    228 	rv = hpi_vmac_rx_config(handle, ENABLE, CFG_VMAC_RX_EN, 0);
    229 
    230 	status = (rv == HPI_SUCCESS) ? HXGE_OK : HXGE_ERROR;
    231 
    232 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_rx_vmac_enable"));
    233 
    234 	return (status);
    235 }
    236 
    237 /* Disable RxVMAC */
    238 
    239 hxge_status_t
    240 hxge_rx_vmac_disable(p_hxge_t hxgep)
    241 {
    242 	hpi_status_t	rv;
    243 	hxge_status_t	status = HXGE_OK;
    244 	hpi_handle_t	handle = hxgep->hpi_handle;
    245 
    246 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_rx_vmac_disable"));
    247 
    248 	/*
    249 	 * Because of hardware bug document with CR6770577, need
    250 	 * reprogram max framesize when enabling/disabling RX
    251 	 * vmac.  Max framesize is programed here in
    252 	 * hxge_rx_vmac_init().
    253 	 */
    254 	(void) hpi_vmac_rx_set_framesize(HXGE_DEV_HPI_HANDLE(hxgep),
    255 	    (uint16_t)0);
    256 
    257 	rv = hpi_vmac_rx_config(handle, DISABLE, CFG_VMAC_RX_EN, 0);
    258 
    259 	status = (rv == HPI_SUCCESS) ? HXGE_OK : HXGE_ERROR;
    260 
    261 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_rx_vmac_disable"));
    262 
    263 	return (status);
    264 }
    265 
    266 /* Reset TxVMAC */
    267 
    268 hxge_status_t
    269 hxge_tx_vmac_reset(p_hxge_t hxgep)
    270 {
    271 	hpi_handle_t	handle = hxgep->hpi_handle;
    272 
    273 	(void) hpi_tx_vmac_reset(handle);
    274 
    275 	return (HXGE_OK);
    276 }
    277 
    278 /* Reset RxVMAC */
    279 
    280 hxge_status_t
    281 hxge_rx_vmac_reset(p_hxge_t hxgep)
    282 {
    283 	hpi_handle_t	handle = hxgep->hpi_handle;
    284 
    285 	(void) hpi_rx_vmac_reset(handle);
    286 
    287 	return (HXGE_OK);
    288 }
    289 
    290 /*ARGSUSED*/
    291 uint_t
    292 hxge_vmac_intr(caddr_t arg1, caddr_t arg2)
    293 {
    294 	p_hxge_t	hxgep = (p_hxge_t)arg2;
    295 	hpi_handle_t	handle;
    296 
    297 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_vmac_intr"));
    298 
    299 	handle = HXGE_DEV_HPI_HANDLE(hxgep);
    300 
    301 	hxge_save_cntrs(hxgep);
    302 
    303 	/* Clear the interrupt status registers */
    304 	(void) hpi_vmac_clear_rx_int_stat(handle);
    305 	(void) hpi_vmac_clear_tx_int_stat(handle);
    306 
    307 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_vmac_intr"));
    308 	return (DDI_INTR_CLAIMED);
    309 }
    310 
    311 /*
    312  * Set promiscous mode
    313  */
    314 hxge_status_t
    315 hxge_set_promisc(p_hxge_t hxgep, boolean_t on)
    316 {
    317 	hxge_status_t status = HXGE_OK;
    318 
    319 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_set_promisc: on %d", on));
    320 
    321 	hxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
    322 
    323 	RW_ENTER_WRITER(&hxgep->filter_lock);
    324 	if ((status = hxge_rx_vmac_disable(hxgep)) != HXGE_OK)
    325 		goto fail;
    326 	if ((status = hxge_rx_vmac_enable(hxgep)) != HXGE_OK)
    327 		goto fail;
    328 	RW_EXIT(&hxgep->filter_lock);
    329 
    330 	if (on)
    331 		hxgep->statsp->mac_stats.promisc = B_TRUE;
    332 	else
    333 		hxgep->statsp->mac_stats.promisc = B_FALSE;
    334 
    335 	HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_set_promisc"));
    336 	return (HXGE_OK);
    337 
    338 fail:
    339 	RW_EXIT(&hxgep->filter_lock);
    340 
    341 	HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "hxge_set_promisc: "
    342 	    "Unable to set promisc (%d)", on));
    343 	return (status);
    344 }
    345 
    346 void
    347 hxge_save_cntrs(p_hxge_t hxgep)
    348 {
    349 	p_hxge_stats_t	statsp;
    350 	hpi_handle_t	handle;
    351 
    352 	vmac_tx_frame_cnt_t tx_frame_cnt;
    353 	vmac_tx_byte_cnt_t tx_byte_cnt;
    354 	vmac_rx_frame_cnt_t rx_frame_cnt;
    355 	vmac_rx_byte_cnt_t rx_byte_cnt;
    356 	vmac_rx_drop_fr_cnt_t rx_drop_fr_cnt;
    357 	vmac_rx_drop_byte_cnt_t rx_drop_byte_cnt;
    358 	vmac_rx_crc_cnt_t rx_crc_cnt;
    359 	vmac_rx_pause_cnt_t rx_pause_cnt;
    360 	vmac_rx_bcast_fr_cnt_t rx_bcast_fr_cnt;
    361 	vmac_rx_mcast_fr_cnt_t rx_mcast_fr_cnt;
    362 
    363 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_save_cntrs"));
    364 
    365 	statsp = (p_hxge_stats_t)hxgep->statsp;
    366 	handle = hxgep->hpi_handle;
    367 
    368 	HXGE_REG_RD64(handle, VMAC_TX_FRAME_CNT, &tx_frame_cnt.value);
    369 	HXGE_REG_RD64(handle, VMAC_TX_BYTE_CNT, &tx_byte_cnt.value);
    370 	HXGE_REG_RD64(handle, VMAC_RX_FRAME_CNT, &rx_frame_cnt.value);
    371 	HXGE_REG_RD64(handle, VMAC_RX_BYTE_CNT, &rx_byte_cnt.value);
    372 	HXGE_REG_RD64(handle, VMAC_RX_DROP_FR_CNT, &rx_drop_fr_cnt.value);
    373 	HXGE_REG_RD64(handle, VMAC_RX_DROP_BYTE_CNT, &rx_drop_byte_cnt.value);
    374 	HXGE_REG_RD64(handle, VMAC_RX_CRC_CNT, &rx_crc_cnt.value);
    375 	HXGE_REG_RD64(handle, VMAC_RX_PAUSE_CNT, &rx_pause_cnt.value);
    376 	HXGE_REG_RD64(handle, VMAC_RX_BCAST_FR_CNT, &rx_bcast_fr_cnt.value);
    377 	HXGE_REG_RD64(handle, VMAC_RX_MCAST_FR_CNT, &rx_mcast_fr_cnt.value);
    378 
    379 	statsp->vmac_stats.tx_frame_cnt += tx_frame_cnt.bits.tx_frame_cnt;
    380 	statsp->vmac_stats.tx_byte_cnt += tx_byte_cnt.bits.tx_byte_cnt;
    381 	statsp->vmac_stats.rx_frame_cnt += rx_frame_cnt.bits.rx_frame_cnt;
    382 	statsp->vmac_stats.rx_byte_cnt += rx_byte_cnt.bits.rx_byte_cnt;
    383 	statsp->vmac_stats.rx_drop_frame_cnt +=
    384 	    rx_drop_fr_cnt.bits.rx_drop_frame_cnt;
    385 	statsp->vmac_stats.rx_drop_byte_cnt +=
    386 	    rx_drop_byte_cnt.bits.rx_drop_byte_cnt;
    387 	statsp->vmac_stats.rx_crc_cnt += rx_crc_cnt.bits.rx_crc_cnt;
    388 	statsp->vmac_stats.rx_pause_cnt += rx_pause_cnt.bits.rx_pause_cnt;
    389 	statsp->vmac_stats.rx_bcast_fr_cnt +=
    390 	    rx_bcast_fr_cnt.bits.rx_bcast_fr_cnt;
    391 	statsp->vmac_stats.rx_mcast_fr_cnt +=
    392 	    rx_mcast_fr_cnt.bits.rx_mcast_fr_cnt;
    393 
    394 hxge_save_cntrs_exit:
    395 	HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_save_cntrs"));
    396 }
    397 
    398 int
    399 hxge_vmac_set_framesize(p_hxge_t hxgep)
    400 {
    401 	int	status = 0;
    402 
    403 	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_vmac_set_framesize"));
    404 
    405 	RW_ENTER_WRITER(&hxgep->filter_lock);
    406 	(void) hxge_rx_vmac_disable(hxgep);
    407 	(void) hxge_tx_vmac_disable(hxgep);
    408 
    409 	/*
    410 	 * Apply the new jumbo parameter here which is contained in hxgep
    411 	 * data structure (hxgep->vmac.maxframesize);
    412 	 * The order of the following two calls is important.
    413 	 */
    414 	(void) hxge_tx_vmac_enable(hxgep);
    415 	(void) hxge_rx_vmac_enable(hxgep);
    416 	RW_EXIT(&hxgep->filter_lock);
    417 
    418 	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_vmac_set_framesize"));
    419 	return (status);
    420 }
    421