3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * CDDL HEADER START
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The contents of this file are subject to the terms of the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Common Development and Distribution License (the "License").
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * You may not use this file except in compliance with the License.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * or http://www.opensolaris.org/os/licensing.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * See the License for the specific language governing permissions
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * and limitations under the License.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * When distributing Covered Code, include this CDDL HEADER in each
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * If applicable, add the following below this CDDL HEADER, with the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * fields enclosed by brackets "[]" replaced with your own identifying
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * information: Portions Copyright [yyyy] [name of copyright owner]
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * CDDL HEADER END
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Use is subject to license terms.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#include <hxge_impl.h>
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#include <hxge_rxdma.h>
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer#include <hpi.h>
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer#include <hpi_vir.h>
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer/*
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Number of blocks to accumulate before re-enabling DMA
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * when we get RBR empty.
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer */
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer#define HXGE_RBR_EMPTY_THRESHOLD 64
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Globals: tunable parameters (/etc/system or adb)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsextern uint32_t hxge_rbr_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsextern uint32_t hxge_rcr_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsextern uint32_t hxge_rbr_spare_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsextern uint32_t hxge_mblks_pending;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Tunables to manage the receive buffer blocks.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * hxge_rx_threshold_hi: copy all buffers.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * hxge_rx_bcopy_size_type: receive buffer block size type.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * hxge_rx_threshold_lo: copy only up to tunable block size type.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsextern hxge_rxbuf_threshold_t hxge_rx_threshold_hi;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsextern hxge_rxbuf_type_t hxge_rx_buf_size_type;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsextern hxge_rxbuf_threshold_t hxge_rx_threshold_lo;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer/*
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Static local functions.
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_map_rxdma(p_hxge_t hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_unmap_rxdma(p_hxge_t hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxdma_hw_start_common(p_hxge_t hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxdma_hw_start(p_hxge_t hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_rxdma_hw_stop(p_hxge_t hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_map_rxdma_channel(p_hxge_t hxgep, uint16_t channel,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_buf_p, p_rx_rbr_ring_t *rbr_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer uint32_t num_chunks, p_hxge_dma_common_t *dma_rbr_cntl_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_rcr_cntl_p, p_hxge_dma_common_t *dma_mbox_cntl_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_rx_rcr_ring_t *rcr_p, p_rx_mbox_t *rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_unmap_rxdma_channel(p_hxge_t hxgep, uint16_t channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_map_rxdma_channel_cfg_ring(p_hxge_t hxgep,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer uint16_t dma_channel, p_hxge_dma_common_t *dma_rbr_cntl_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_rcr_cntl_p, p_hxge_dma_common_t *dma_mbox_cntl_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_rx_rbr_ring_t *rbr_p, p_rx_rcr_ring_t *rcr_p, p_rx_mbox_t *rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_unmap_rxdma_channel_cfg_ring(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t rcr_p, p_rx_mbox_t rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_map_rxdma_channel_buf_ring(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel, p_hxge_dma_common_t *dma_buf_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t *rbr_p, uint32_t num_chunks);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_unmap_rxdma_channel_buf_ring(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rbr_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxdma_start_channel(p_hxge_t hxgep, uint16_t channel,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States int n_init_kick);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxdma_stop_channel(p_hxge_t hxgep, uint16_t channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic mblk_t *hxge_rx_pkts(p_hxge_t hxgep, uint_t vindex, p_hxge_ldv_t ldvp,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_rx_rcr_ring_t rcr_p, rdc_stat_t cs, int bytes_to_read);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United Statesstatic uint32_t hxge_scan_for_last_eop(p_rx_rcr_ring_t rcr_p,
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States p_rcr_entry_t rcr_desc_rd_head_p, uint32_t num_rcrs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_receive_packet(p_hxge_t hxgep, p_rx_rcr_ring_t rcr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rcr_entry_t rcr_desc_rd_head_p, boolean_t *multi_p,
fe930412c257f961ae67039de3b164b83717976aqs mblk_t ** mp, mblk_t ** mp_cont, uint32_t *invalid_rcr_entry);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_disable_rxdma_channel(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic p_rx_msg_t hxge_allocb(size_t, uint32_t, p_hxge_dma_common_t);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_freeb(p_rx_msg_t);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rx_err_evnts(p_hxge_t hxgep, uint_t index,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_ldv_t ldvp, rdc_stat_t cs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxbuf_index_info_init(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rx_dmap);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxdma_fatal_err_recover(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rx_port_fatal_err_recover(p_hxge_t hxgep);
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United Statesstatic void hxge_rbr_empty_restore(p_hxge_t hxgep,
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States p_rx_rbr_ring_t rx_rbr_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_init_rxdma_channels(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
fe930412c257f961ae67039de3b164b83717976aqs hxge_status_t status = HXGE_OK;
fe930412c257f961ae67039de3b164b83717976aqs block_reset_t reset_reg;
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer int i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_init_rxdma_channels"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer for (i = 0; i < HXGE_MAX_RDCS; i++)
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer hxgep->rdc_first_intr[i] = B_TRUE;
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer
fe930412c257f961ae67039de3b164b83717976aqs /* Reset RDC block from PEU to clear any previous state */
fe930412c257f961ae67039de3b164b83717976aqs reset_reg.value = 0;
fe930412c257f961ae67039de3b164b83717976aqs reset_reg.bits.rdc_rst = 1;
fe930412c257f961ae67039de3b164b83717976aqs HXGE_REG_WR32(hxgep->hpi_handle, BLOCK_RESET, reset_reg.value);
fe930412c257f961ae67039de3b164b83717976aqs HXGE_DELAY(1000);
fe930412c257f961ae67039de3b164b83717976aqs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_map_rxdma(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_init_rxdma: status 0x%x", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_rxdma_hw_start_common(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_unmap_rxdma(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_rxdma_hw_start(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_unmap_rxdma(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_init_rxdma_channels: status 0x%x", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_uninit_rxdma_channels(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_uninit_rxdma_channels"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_rxdma_hw_stop(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_unmap_rxdma(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_uinit_rxdma_channels"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_init_rxdma_channel_cntl_stat(p_hxge_t hxgep, uint16_t channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stat_t *cs_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_status_t rs = HPI_SUCCESS;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_init_rxdma_channel_cntl_stat"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_control_status(handle, OP_SET, channel, cs_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = HXGE_ERROR | rs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_enable_rxdma_channel(p_hxge_t hxgep, uint16_t channel,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States int n_init_kick)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc_cfg_t rdc_desc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rcr_cfg_b_t *cfgb_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_status_t rs = HPI_SUCCESS;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_enable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Use configuration data composed at init time. Write to hardware the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * receive ring configurations.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.mbox_enable = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.mbox_addr = mbox_p->mbox_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_enable_rxdma_channel: mboxp $%p($%p)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mbox_p->mbox_addr, rdc_desc.mbox_addr));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rbr_len = rbr_p->rbb_max;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rbr_addr = rbr_p->rbr_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs switch (hxgep->rx_bksize_code) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case RBR_BKSIZE_4K:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.page_size = SIZE_4KB;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case RBR_BKSIZE_8K:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.page_size = SIZE_8KB;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.size0 = rbr_p->hpi_pkt_buf_size0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.valid0 = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.size1 = rbr_p->hpi_pkt_buf_size1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.valid1 = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.size2 = rbr_p->hpi_pkt_buf_size2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.valid2 = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.full_hdr = rcr_p->full_hdr_flag;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.offset = rcr_p->sw_priv_hdr_len;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rcr_len = rcr_p->comp_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rcr_addr = rcr_p->rcr_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfgb_p = &(rcr_p->rcr_cfgb);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rcr_threshold = cfgb_p->bits.pthres;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rcr_timeout = cfgb_p->bits.timeout;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rcr_timeout_enable = cfgb_p->bits.entout;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_enable_rxdma_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rbr_len qlen %d pagesize code %d rcr_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rbr_len, rdc_desc.page_size, rdc_desc.rcr_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_enable_rxdma_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "size 0 %d size 1 %d size 2 %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_p->hpi_pkt_buf_size0, rbr_p->hpi_pkt_buf_size1,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_p->hpi_pkt_buf_size2));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_ring(handle, rbr_p->rdc, &rdc_desc);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Enable the timeout and threshold.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_rcr_threshold(handle, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rcr_threshold);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_rcr_timeout(handle, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_desc.rcr_timeout);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3a109ad9413b360a5bfa6fa5ddfacef5fd64fe5bQiyan Sun - Sun Microsystems - San Diego United States /* Kick the DMA engine */
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States hpi_rxdma_rdc_rbr_kick(handle, channel, n_init_kick);
dc10a9c2a5a49452cc30c6a110b64e5e074e37b3Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Clear the rbr empty bit */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hpi_rxdma_channel_rbr_empty_clear(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Enable the DMA
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer rs = hpi_rxdma_cfg_rdc_enable(handle, channel);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer if (rs != HPI_SUCCESS) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer return (HXGE_ERROR | rs);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer }
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_enable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_disable_rxdma_channel(p_hxge_t hxgep, uint16_t channel)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_status_t rs = HPI_SUCCESS;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_disable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* disable the DMA */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_disable(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_disable_rxdma_channel:failed (0x%x)", rs));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_disable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_channel_rcrflush(p_hxge_t hxgep, uint8_t channel)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_channel_rcrflush"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_rxdma_rdc_rcr_flush(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_channel_rcrflush"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#define MID_INDEX(l, r) ((r + l + 1) >> 1)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#define TO_LEFT -1
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#define TO_RIGHT 1
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#define BOTH_RIGHT (TO_RIGHT + TO_RIGHT)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#define BOTH_LEFT (TO_LEFT + TO_LEFT)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#define IN_MIDDLE (TO_RIGHT + TO_LEFT)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#define NO_HINT 0xffffffff
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxbuf_pp_to_vp(p_hxge_t hxgep, p_rx_rbr_ring_t rbr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint8_t pktbufsz_type, uint64_t *pkt_buf_addr_pp,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t **pkt_buf_addr_p, uint32_t *bufoffset, uint32_t *msg_index)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int bufsize;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t pktbuf_pp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t dvma_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxring_info_t *ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int base_side, end_side;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int r_index, l_index, anchor_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int found, search_done;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t offset, chunk_size, block_size, page_size_mask;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t chunk_index, block_index, total_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int max_iterations, iteration;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxbuf_index_info_t *bufinfo;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL, "==> hxge_rxbuf_pp_to_vp"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: buf_pp $%p btype %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs pktbuf_pp = (uint64_t)(uint32_t)pkt_buf_addr_pp;
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pktbuf_pp = (uint64_t)pkt_buf_addr_pp;
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs switch (pktbufsz_type) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case 0:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bufsize = rbr_p->pkt_buf_size0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case 1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bufsize = rbr_p->pkt_buf_size1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case 2:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bufsize = rbr_p->pkt_buf_size2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case RCR_SINGLE_BLOCK:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bufsize = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs anchor_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs default:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rbr_p->num_blocks == 1) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs anchor_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info = rbr_p->ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bufinfo = (rxbuf_index_info_t *)ring_info->buffer;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (found, 1 block) "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d bufinfo $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, anchor_index, bufinfo));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto found_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: buf_pp $%p btype %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, anchor_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info = rbr_p->ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs found = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bufinfo = (rxbuf_index_info_t *)ring_info->buffer;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs iteration = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs max_iterations = ring_info->max_iterations;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * First check if this block have been seen recently. This is indicated
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * by a hint which is initialized when the first buffer of the block is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * seen. The hint is reset when the last buffer of the block has been
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * processed. As three block sizes are supported, three hints are kept.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The idea behind the hints is that once the hardware uses a block
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * for a buffer of that size, it will use it exclusively for that size
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * and will use it until it is exhausted. It is assumed that there
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * would a single block being used for the same buffer sizes at any
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * given time.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (ring_info->hint[pktbufsz_type] != NO_HINT) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs anchor_index = ring_info->hint[pktbufsz_type];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dvma_addr = bufinfo[anchor_index].dvma_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs chunk_size = bufinfo[anchor_index].buf_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((pktbuf_pp >= dvma_addr) &&
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (pktbuf_pp < (dvma_addr + chunk_size))) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs found = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * check if this is the last buffer in the block If so,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * then reset the hint for the size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((pktbuf_pp + bufsize) >= (dvma_addr + chunk_size))
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->hint[pktbufsz_type] = NO_HINT;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (found == B_FALSE) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (!found)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, anchor_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * This is the first buffer of the block of this size. Need to
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * search the whole information array. the search algorithm
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * uses a binary tree search algorithm. It assumes that the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * information is already sorted with increasing order info[0]
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * < info[1] < info[2] .... < info[n-1] where n is the size of
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the information array
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs r_index = rbr_p->num_blocks - 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs search_done = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs anchor_index = MID_INDEX(r_index, l_index);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs while (search_done == B_FALSE) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((r_index == l_index) ||
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (iteration >= max_iterations))
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs search_done = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs end_side = TO_RIGHT; /* to the right */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs base_side = TO_LEFT; /* to the left */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* read the DVMA address information and sort it */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dvma_addr = bufinfo[anchor_index].dvma_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs chunk_size = bufinfo[anchor_index].buf_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (searching)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "anchor_index %d chunk_size %d dvmaaddr $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, anchor_index,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs chunk_size, dvma_addr));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (pktbuf_pp >= dvma_addr)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs base_side = TO_RIGHT; /* to the right */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (pktbuf_pp < (dvma_addr + chunk_size))
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs end_side = TO_LEFT; /* to the left */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs switch (base_side + end_side) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case IN_MIDDLE:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* found */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs found = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs search_done = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((pktbuf_pp + bufsize) <
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (dvma_addr + chunk_size))
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->hint[pktbufsz_type] =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bufinfo[anchor_index].buf_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case BOTH_RIGHT:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* not found: go to the right */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l_index = anchor_index + 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs anchor_index = MID_INDEX(r_index, l_index);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case BOTH_LEFT:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* not found: go to the left */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs r_index = anchor_index - 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs anchor_index = MID_INDEX(r_index, l_index);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs default: /* should not come here */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs iteration++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (search done)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, anchor_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (found == B_FALSE) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (search failed)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, anchor_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsfound_index:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (FOUND1)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d bufsize %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, bufsize, anchor_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* index of the first block in this chunk */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs chunk_index = bufinfo[anchor_index].start_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dvma_addr = bufinfo[anchor_index].dvma_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs page_size_mask = ring_info->block_size_mask;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (FOUND3), get chunk)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d bufsize %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "anchor_index %d chunk_index %d dvma $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, bufsize,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs anchor_index, chunk_index, dvma_addr));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs offset = pktbuf_pp - dvma_addr; /* offset within the chunk */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs block_size = rbr_p->block_size; /* System block(page) size */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (FOUND4), get chunk)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d bufsize %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "anchor_index %d chunk_index %d dvma $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "offset %d block_size %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp, pktbufsz_type, bufsize, anchor_index,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs chunk_index, dvma_addr, offset, block_size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL, "==> getting total index"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs block_index = (offset / block_size); /* index within chunk */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs total_index = chunk_index + block_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "total_index %d dvma_addr $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "offset %d block_size %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "block_index %d ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs total_index, dvma_addr, offset, block_size, block_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs *pkt_buf_addr_p = (uint64_t *)((uint32_t)bufinfo[anchor_index].kaddr +
fe930412c257f961ae67039de3b164b83717976aqs (uint32_t)offset);
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *pkt_buf_addr_p = (uint64_t *)((uint64_t)bufinfo[anchor_index].kaddr +
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs offset);
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "total_index %d dvma_addr $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "offset %d block_size %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "block_index %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "*pkt_buf_addr_p $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs total_index, dvma_addr, offset, block_size,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs block_index, *pkt_buf_addr_p));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *msg_index = total_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *bufoffset = (offset & page_size_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: get msg index: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "msg_index %d bufoffset_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *msg_index, *bufoffset));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL, "<== hxge_rxbuf_pp_to_vp"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * used by quick sort (qsort) function
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * to perform comparison
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic int
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_sort_compare(const void *p1, const void *p2)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxbuf_index_info_t *a, *b;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs a = (rxbuf_index_info_t *)p1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs b = (rxbuf_index_info_t *)p2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (a->dvma_addr > b->dvma_addr)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (a->dvma_addr < b->dvma_addr)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (-1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Grabbed this sort implementation from common/syscall/avl.c
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Generic shellsort, from K&R (1st ed, p 58.), somewhat modified.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * v = Ptr to array/vector of objs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * n = # objs in the array
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * s = size of each obj (must be multiples of a word size)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * f = ptr to function to compare two objs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * returns (-1 = less than, 0 = equal, 1 = greater than
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_ksort(caddr_t v, int n, int s, int (*f) ())
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int g, i, j, ii;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs unsigned int *p1, *p2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs unsigned int tmp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* No work to do */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (v == NULL || n <= 1)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Sanity check on arguments */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ASSERT(((uintptr_t)v & 0x3) == 0 && (s & 0x3) == 0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ASSERT(s > 0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (g = n / 2; g > 0; g /= 2) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = g; i < n; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (j = i - g; j >= 0 &&
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (*f) (v + j * s, v + (j + g) * s) == 1; j -= g) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p1 = (unsigned *)(v + j * s);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p2 = (unsigned *)(v + (j + g) * s);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (ii = 0; ii < s / 4; ii++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs tmp = *p1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *p1++ = *p2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *p2++ = tmp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Initialize data structures required for rxdma
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * buffer dvma->vmem address lookup
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxbuf_index_info_init(p_hxge_t hxgep, p_rx_rbr_ring_t rbrp)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxring_info_t *ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int max_iteration = 0, max_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_rxbuf_index_info_init"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info = rbrp->ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->hint[0] = NO_HINT;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->hint[1] = NO_HINT;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->hint[2] = NO_HINT;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer ring_info->hint[3] = NO_HINT;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs max_index = rbrp->num_blocks;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* read the DVMA address information and sort it */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* do init of the information array */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxbuf_index_info_init Sort ptrs"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* sort the array */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_ksort((void *) ring_info->buffer, max_index,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs sizeof (rxbuf_index_info_t), hxge_sort_compare);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (index = 0; index < max_index; index++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxbuf_index_info_init: sorted chunk %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " ioaddr $%p kaddr $%p size %x",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs index, ring_info->buffer[index].dvma_addr,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[index].kaddr,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[index].buf_size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs max_iteration = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs while (max_index >= (1ULL << max_iteration))
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs max_iteration++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->max_iterations = max_iteration + 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxbuf_index_info_init Find max iter %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->max_iterations));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_rxbuf_index_info_init"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_dump_rcr_entry(p_hxge_t hxgep, p_rcr_entry_t entry_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#ifdef HXGE_DEBUG
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t bptr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t pp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bptr = entry_p->bits.pkt_buf_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\trcr entry $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\trcr entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\trcr entry 0x%08x "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\trcr entry 0x%08x "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\tvalue 0x%0llx\n"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\tmulti = %d\n"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\tpkt_type = 0x%x\n"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\terror = 0x%04x\n"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\tl2_len = %d\n"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\tpktbufsize = %d\n"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\tpkt_buf_addr = $%p\n"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "\tpkt_buf_addr (<< 6) = $%p\n",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs entry_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *(int64_t *)entry_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *(int32_t *)entry_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *(int32_t *)((char *)entry_p + 32),
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs entry_p->value,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs entry_p->bits.multi,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs entry_p->bits.pkt_type,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs entry_p->bits.error,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs entry_p->bits.l2_len,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs entry_p->bits.pktbufsz,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bptr,
fe930412c257f961ae67039de3b164b83717976aqs entry_p->bits.pkt_buf_addr_l));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pp = (entry_p->value & RCR_PKT_BUF_ADDR_MASK) <<
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RCR_PKT_BUF_ADDR_SHIFT;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "rcr pp 0x%llx l2 len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pp, (*(int64_t *)entry_p >> 40) & 0x3fff));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_stop(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_stop"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_ENTER(&hxgep->vmac_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_rx_vmac_disable(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_rxdma_hw_mode(hxgep, HXGE_DMA_STOP);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&hxgep->vmac_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rxdma_stop"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_stop_reinit(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_stop_reinit"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_rxdma_stop(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_uninit_rxdma_channels(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_init_rxdma_channels(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_ENTER(&hxgep->vmac_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_rx_vmac_enable(hxgep);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&hxgep->vmac_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rxdma_stop_reinit"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_hw_mode(p_hxge_t hxgep, boolean_t enable)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i, ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_rings_t rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t *rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_status_t rs = HPI_SUCCESS;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_mode: mode %d", enable));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!(hxgep->drv_state & STATE_HW_INITIALIZED)) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: not initialized"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings = hxgep->rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_rbr_rings == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: NULL ring pointer"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_rbr_rings->rbr_rings == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: NULL rbr rings pointer"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas = rx_rbr_rings->ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!ndmas) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: no channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_mode (ndmas %d)", ndmas));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_rings = rx_rbr_rings->rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rbr_rings == NULL || rbr_rings[i] == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs continue;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = rbr_rings[i]->rdc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (enable) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_mode: channel %d (enable)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_enable(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_mode: channel %d (disable)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_disable(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = ((rs == HPI_SUCCESS) ? HXGE_OK : HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_mode: status 0x%x", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Static functions start here.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic p_rx_msg_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_allocb(size_t size, uint32_t pri, p_hxge_dma_common_t dmabuf_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t hxge_mp = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t dmamsg_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uchar_t *buffer;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp = KMEM_ZALLOC(sizeof (rx_msg_t), KM_NOSLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_mp == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Allocation of a rx msg failed."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_allocb_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->use_buf_pool = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (dmabuf_p) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->use_buf_pool = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmamsg_p = (p_hxge_dma_common_t)&hxge_mp->buf_dma;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *dmamsg_p = *dmabuf_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmamsg_p->nblocks = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmamsg_p->block_size = size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmamsg_p->alength = size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs buffer = (uchar_t *)dmabuf_p->kaddrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmabuf_p->kaddrp = (void *)((char *)dmabuf_p->kaddrp + size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmabuf_p->ioaddr_pp = (void *)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ((char *)dmabuf_p->ioaddr_pp + size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmabuf_p->alength -= size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmabuf_p->offset += size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmabuf_p->dma_cookie.dmac_laddress += size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmabuf_p->dma_cookie.dmac_size -= size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs buffer = KMEM_ALLOC(size, KM_NOSLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (buffer == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Allocation of a receive page failed."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_allocb_fail1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->rx_mblk_p = desballoc(buffer, size, pri, &hxge_mp->freeb);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_mp->rx_mblk_p == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL, "desballoc failed."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_allocb_fail2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->buffer = buffer;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->block_size = size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->freeb.free_func = (void (*) ()) hxge_freeb;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->freeb.free_arg = (caddr_t)hxge_mp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->ref_cnt = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->free = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->rx_use_bcopy = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
dc10a9c2a5a49452cc30c6a110b64e5e074e37b3Michael Speer atomic_inc_32(&hxge_mblks_pending);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_allocb_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_allocb_fail2:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!hxge_mp->use_buf_pool) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(buffer, size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_allocb_fail1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(hxge_mp, sizeof (rx_msg_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_allocb_exit:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (hxge_mp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsp_mblk_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_dupb(p_rx_msg_t hxge_mp, uint_t offset, size_t size)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_mblk_t mp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM_CTL, "==> hxge_dupb"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM_CTL, "hxge_mp = $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "offset = 0x%08X " "size = 0x%08X", hxge_mp, offset, size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mp = desballoc(&hxge_mp->buffer[offset], size, 0, &hxge_mp->freeb);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (mp == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, RX_CTL, "desballoc failed"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_dupb_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs atomic_inc_32(&hxge_mp->ref_cnt);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_dupb_exit:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM_CTL, "<== hxge_dupb mp = $%p", hxge_mp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (mp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsp_mblk_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_dupb_bcopy(p_rx_msg_t hxge_mp, uint_t offset, size_t size)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_mblk_t mp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uchar_t *dp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mp = allocb(size + HXGE_RXBUF_EXTRA, 0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (mp == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, RX_CTL, "desballoc failed"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_dupb_bcopy_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dp = mp->b_rptr = mp->b_rptr + HXGE_RXBUF_EXTRA;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bcopy((void *) &hxge_mp->buffer[offset], dp, size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mp->b_wptr = dp + size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_dupb_bcopy_exit:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM_CTL, "<== hxge_dupb mp = $%p", hxge_mp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (mp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid hxge_post_page(p_hxge_t hxgep, p_rx_rbr_ring_t rx_rbr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t rx_msg_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_post_page(p_hxge_t hxgep, p_rx_rbr_ring_t rx_rbr_p, p_rx_msg_t rx_msg_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_post_page"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reuse this buffer */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->free = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->cur_usage_cnt = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->max_usage_cnt = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->pkt_buf_size = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_rbr_p->rbr_use_bcopy) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->rx_use_bcopy = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs atomic_dec_32(&rx_rbr_p->rbr_consumed);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States atomic_dec_32(&rx_rbr_p->rbr_used);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Get the rbr header pointer and its offset index.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p->rbr_wr_index = ((rx_rbr_p->rbr_wr_index + 1) &
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p->rbr_wrap_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p->rbr_desc_vp[rx_rbr_p->rbr_wr_index] = rx_msg_p->shifted_addr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer /*
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Accumulate some buffers in the ring before re-enabling the
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * DMA channel, if rbr empty was signaled.
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer */
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hpi_rxdma_rdc_rbr_kick(HXGE_DEV_HPI_HANDLE(hxgep), rx_rbr_p->rdc, 1);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer if (rx_rbr_p->rbr_is_empty && (rx_rbr_p->rbb_max -
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rx_rbr_p->rbr_used) >= HXGE_RBR_EMPTY_THRESHOLD) {
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hxge_rbr_empty_restore(hxgep, rx_rbr_p);
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer }
3a109ad9413b360a5bfa6fa5ddfacef5fd64fe5bQiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_post_page (channel %d post_next_index %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p->rdc, rx_rbr_p->rbr_wr_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_post_page"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_freeb(p_rx_msg_t rx_msg_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs size_t size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uchar_t *buffer = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int ref_cnt;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs boolean_t free_state = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_ring_t *ring = rx_msg_p->rx_rbr_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM2_CTL, "==> hxge_freeb"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_freeb:rx_msg_p = $%p (block pending %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p, hxge_mblks_pending));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States if (ring == NULL)
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States return;
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States /*
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * This is to prevent posting activities while we are recovering
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * from fatal errors. This should not be a performance drag since
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * ref_cnt != 0 most times.
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States */
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States if (ring->rbr_state == RBR_POSTING)
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&ring->post_lock);
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * First we need to get the free state, then
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * atomic decrement the reference count to prevent
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the race condition with the interrupt thread that
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * is processing a loaned up buffer block.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs free_state = rx_msg_p->free;
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek ref_cnt = atomic_dec_32_nv(&rx_msg_p->ref_cnt);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!ref_cnt) {
dc10a9c2a5a49452cc30c6a110b64e5e074e37b3Michael Speer atomic_dec_32(&hxge_mblks_pending);
dc10a9c2a5a49452cc30c6a110b64e5e074e37b3Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs buffer = rx_msg_p->buffer;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs size = rx_msg_p->block_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM2_CTL, "hxge_freeb: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "will free: rx_msg_p = $%p (block pending %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p, hxge_mblks_pending));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!rx_msg_p->use_buf_pool) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(buffer, size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_msg_p, sizeof (rx_msg_t));
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States /*
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * Decrement the receive buffer ring's reference
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * count, too.
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States */
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States atomic_dec_32(&ring->rbr_ref_cnt);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States /*
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * Free the receive buffer ring, iff
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * 1. all the receive buffers have been freed
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * 2. and we are in the proper state (that is,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * we are not UNMAPPING).
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States */
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States if (ring->rbr_ref_cnt == 0 &&
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States ring->rbr_state == RBR_UNMAPPED) {
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States KMEM_FREE(ring, sizeof (*ring));
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States /* post_lock has been destroyed already */
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Repost buffer.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States if (free_state && (ref_cnt == 1)) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_freeb: post page $%p:", rx_msg_p));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (ring->rbr_state == RBR_POSTING)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_post_page(rx_msg_p->hxgep, ring, rx_msg_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States if (ring->rbr_state == RBR_POSTING)
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&ring->post_lock);
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM2_CTL, "<== hxge_freeb"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsuint_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rx_intr(caddr_t arg1, caddr_t arg2)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ring_handle_t rhp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_ldv_t ldvp = (p_hxge_ldv_t)arg1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_t hxgep = (p_hxge_t)arg2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_ldg_t ldgp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint8_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States rdc_stat_t cs;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_rx_rcr_ring_t ring;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer p_rx_rbr_ring_t rbrp;
4d9de298e3450682b12e54bf159023baf38c82ddMichael Speer mblk_t *mp = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (ldvp == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rx_intr: arg2 $%p arg1 $%p", hxgep, ldvp));
dc10a9c2a5a49452cc30c6a110b64e5e074e37b3Michael Speer return (DDI_INTR_UNCLAIMED);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (arg2 == NULL || (void *) ldvp->hxgep != arg2) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep = ldvp->hxgep;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_intr: arg2 $%p arg1 $%p", hxgep, ldvp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * This interrupt handler is for a specific receive dma channel.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Get the control and status for this channel.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer channel = ldvp->vdma_index;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[channel];
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rhp = &hxgep->rx_ring_handles[channel];
4d9de298e3450682b12e54bf159023baf38c82ddMichael Speer ldgp = ldvp->ldgp;
4d9de298e3450682b12e54bf159023baf38c82ddMichael Speer
4d9de298e3450682b12e54bf159023baf38c82ddMichael Speer ASSERT(ring != NULL);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer#if defined(DEBUG)
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer if (rhp->started) {
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer ASSERT(ring->ldgp == ldgp);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer ASSERT(ring->ldvp == ldvp);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer }
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer#endif
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_ENTER(&ring->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer if (!ring->poll_flag) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer cs.bits.ptrread = 0;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer cs.bits.pktread = 0;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Process packets, if we are not in polling mode, the ring is
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * started and the interface is started. The MAC layer under
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * load will be operating in polling mode for RX traffic.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer if ((rhp->started) &&
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (hxgep->hxge_mac_state == HXGE_MAC_STARTED)) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer mp = hxge_rx_pkts(hxgep, ldvp->vdma_index,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ldvp, ring, cs, -1);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /* Process error events. */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer if (cs.value & RDC_STAT_ERROR) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&ring->lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hxge_rx_err_evnts(hxgep, channel, ldvp, cs);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_ENTER(&ring->lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Enable the mailbox update interrupt if we want to use
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * mailbox. We probably don't need to use mailbox as it only
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * saves us one pio read. Also write 1 to rcrthres and
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * rcrto to clear these two edge triggered bits.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp = hxgep->rx_rbr_rings->rbr_rings[channel];
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer MUTEX_ENTER(&rbrp->post_lock);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer if (!rbrp->rbr_is_empty) {
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer cs.value = 0;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer cs.bits.mex = 1;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer cs.bits.ptrread = 0;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer cs.bits.pktread = 0;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer }
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer MUTEX_EXIT(&rbrp->post_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (ldgp->nldvs == 1) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Re-arm the group.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, B_TRUE,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ldgp->ldg_timer);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer } else if ((ldgp->nldvs == 1) && (ring->poll_flag)) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Disarm the group, if we are not a shared interrupt.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, B_FALSE, 0);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer } else if (ring->poll_flag) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Mask-off this device from the group.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_mask_set(handle, ldvp->ldv, 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_EXIT(&ring->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer /*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Send the packets up the stack.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (mp != NULL) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer mac_rx_ring(hxgep->mach, ring->rcr_mac_handle, mp,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ring->rcr_gen_num);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer HXGE_DEBUG_MSG((NULL, RX_INT_CTL, "<== hxge_rx_intr"));
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer return (DDI_INTR_CLAIMED);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer/*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Enable polling for a ring. Interrupt for the ring is disabled when
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * the hxge interrupt comes (see hxge_rx_intr).
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerint
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerhxge_enable_poll(void *arg)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ring_handle_t ring_handle = (p_hxge_ring_handle_t)arg;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_rx_rcr_ring_t ringp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_t hxgep;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ldg_t ldgp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (ring_handle == NULL) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ASSERT(ring_handle != NULL);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer return (1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer hxgep = ring_handle->hxgep;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ringp = hxgep->rx_rcr_rings->rcr_rings[ring_handle->index];
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_ENTER(&ringp->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Are we already polling ?
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer if (ringp->poll_flag) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&ringp->lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer return (1);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer }
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ldgp = ringp->ldgp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (ldgp == NULL) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_EXIT(&ringp->lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer return (1);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer /*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Enable polling
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ringp->poll_flag = B_TRUE;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_EXIT(&ringp->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer return (0);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer}
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer/*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Disable polling for a ring and enable its interrupt.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerint
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerhxge_disable_poll(void *arg)
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer{
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ring_handle_t ring_handle = (p_hxge_ring_handle_t)arg;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_rx_rcr_ring_t ringp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_t hxgep;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (ring_handle == NULL) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ASSERT(ring_handle != NULL);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer return (0);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer hxgep = ring_handle->hxgep;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ringp = hxgep->rx_rcr_rings->rcr_rings[ring_handle->index];
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_ENTER(&ringp->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer /*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Disable polling: enable interrupt
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (ringp->poll_flag) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer hpi_handle_t handle;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rdc_stat_t cs;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ldg_t ldgp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer /*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Get the control and status for this channel.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer handle = HXGE_DEV_HPI_HANDLE(hxgep);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer /*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Rearm this logical group if this is a single device
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * group.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ldgp = ringp->ldgp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (ldgp == NULL) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_EXIT(&ringp->lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer return (1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ringp->poll_flag = B_FALSE;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Enable mailbox update, to start interrupts again.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer cs.value = 0ULL;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer cs.bits.mex = 1;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer cs.bits.pktread = 0;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer cs.bits.ptrread = 0;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, ringp->rdc, cs.value);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer if (ldgp->nldvs == 1) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Re-arm the group, since it is the only member
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * of the group.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, B_TRUE,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ldgp->ldg_timer);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer } else {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Mask-on interrupts for the device and re-arm
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * the group.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_mask_set(handle, ringp->ldvp->ldv, 0);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, B_TRUE,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ldgp->ldg_timer);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_EXIT(&ringp->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer return (0);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer/*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Poll 'bytes_to_pickup' bytes of message from the rx ring.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speermblk_t *
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerhxge_rx_poll(void *arg, int bytes_to_pickup)
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer{
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)arg;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_rx_rcr_ring_t ring;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_t hxgep;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer hpi_handle_t handle;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rdc_stat_t cs;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer mblk_t *mblk;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ldv_t ldvp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer hxgep = rhp->hxgep;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer /*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Get the control and status for this channel.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer handle = HXGE_DEV_HPI_HANDLE(hxgep);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[rhp->index];
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_ENTER(&ring->lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer ASSERT(ring->poll_flag == B_TRUE);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ASSERT(rhp->started);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer if (!ring->poll_flag) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_EXIT(&ring->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer return ((mblk_t *)NULL);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Get the control and status bits for the ring.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer RXDMA_REG_READ64(handle, RDC_STAT, rhp->index, &cs.value);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer cs.bits.ptrread = 0;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer cs.bits.pktread = 0;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, rhp->index, cs.value);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Process packets.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer mblk = hxge_rx_pkts(hxgep, ring->ldvp->vdma_index,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ring->ldvp, ring, cs, bytes_to_pickup);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ldvp = ring->ldvp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer /*
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Process Error Events.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (ldvp && (cs.value & RDC_STAT_ERROR)) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Recovery routines will grab the RCR ring lock.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&ring->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer (void) hxge_rx_err_evnts(hxgep, ldvp->vdma_index, ldvp, cs);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_ENTER(&ring->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer MUTEX_EXIT(&ring->lock);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer return (mblk);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsmblk_t *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rx_pkts(p_hxge_t hxgep, uint_t vindex, p_hxge_ldv_t ldvp,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_rx_rcr_ring_t rcrp, rdc_stat_t cs, int bytes_to_read)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint8_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t comp_rd_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rcr_entry_t rcr_desc_rd_head_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rcr_entry_t rcr_desc_rd_head_pp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_mblk_t nmp, mp_cont, head_mp, *tail_mp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t qlen, nrcr_read, npkt_read;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer uint32_t qlen_hw, npkts, num_rcrs;
fe930412c257f961ae67039de3b164b83717976aqs uint32_t invalid_rcr_entry;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs boolean_t multi;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rdc_stat_t pktcs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rcr_cfg_b_t rcr_cfg_b;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States uint64_t rcr_head_index, rcr_tail_index;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States uint64_t rcr_tail;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States rdc_rcr_tail_t rcr_tail_reg;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_rx_ring_stats_t rdc_stats;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer int totallen = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL, "==> hxge_rx_pkts:vindex %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d", vindex, ldvp->channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer channel = rcrp->rdc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (channel != ldvp->channel) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL, "==> hxge_rx_pkts:index %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d, and rcr channel %d not matched.",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs vindex, ldvp->channel, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (NULL);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_pkts: START: rcr channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "head_p $%p head_pp $%p index %d ",
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer channel, rcrp->rcr_desc_rd_head_p,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_rd_head_pp, rcrp->comp_rd_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States (void) hpi_rxdma_rdc_rcr_qlen_get(handle, channel, &qlen);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States RXDMA_REG_READ64(handle, RDC_RCR_TAIL, channel, &rcr_tail_reg.value);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States rcr_tail = rcr_tail_reg.bits.tail;
fe930412c257f961ae67039de3b164b83717976aqs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!qlen) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rx_pkts:rcr channel %d qlen %d (no pkts)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, qlen));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (NULL);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rx_pkts:rcr channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "qlen %d", channel, qlen));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer comp_rd_index = rcrp->comp_rd_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcr_desc_rd_head_p = rcrp->rcr_desc_rd_head_p;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcr_desc_rd_head_pp = rcrp->rcr_desc_rd_head_pp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nrcr_read = npkt_read = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States if (hxgep->rdc_first_intr[channel])
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States qlen_hw = qlen;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States else
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States qlen_hw = qlen - 1;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs head_mp = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs tail_mp = &head_mp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp = mp_cont = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs multi = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcr_head_index = rcrp->rcr_desc_rd_head_p - rcrp->rcr_desc_first_p;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcr_tail_index = rcr_tail - rcrp->rcr_tail_begin;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States if (rcr_tail_index >= rcr_head_index) {
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States num_rcrs = rcr_tail_index - rcr_head_index;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States } else {
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States /* rcr_tail has wrapped around */
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer num_rcrs = (rcrp->comp_size - rcr_head_index) + rcr_tail_index;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States }
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer npkts = hxge_scan_for_last_eop(rcrp, rcr_desc_rd_head_p, num_rcrs);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer if (!npkts)
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States return (NULL);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer if (qlen_hw > npkts) {
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States "Channel %d, rcr_qlen from reg %d and from rcr_tail %d\n",
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States channel, qlen_hw, qlen_sw));
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer qlen_hw = npkts;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States }
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs while (qlen_hw) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#ifdef HXGE_DEBUG
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_dump_rcr_entry(hxgep, rcr_desc_rd_head_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Process one completion ring entry.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
fe930412c257f961ae67039de3b164b83717976aqs invalid_rcr_entry = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_receive_packet(hxgep,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp, rcr_desc_rd_head_p, &multi, &nmp, &mp_cont,
fe930412c257f961ae67039de3b164b83717976aqs &invalid_rcr_entry);
fe930412c257f961ae67039de3b164b83717976aqs if (invalid_rcr_entry != 0) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rdc_stats = rcrp->rdc_stats;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer rdc_stats->rcr_invalids++;
fe930412c257f961ae67039de3b164b83717976aqs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
fe930412c257f961ae67039de3b164b83717976aqs "Channel %d could only read 0x%x packets, "
fe930412c257f961ae67039de3b164b83717976aqs "but 0x%x pending\n", channel, npkt_read, qlen_hw));
fe930412c257f961ae67039de3b164b83717976aqs break;
fe930412c257f961ae67039de3b164b83717976aqs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * message chaining modes (nemo msg chaining)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (nmp) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp->b_next = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!multi && !mp_cont) { /* frame fits a partition */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *tail_mp = nmp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs tail_mp = &nmp->b_next;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else if (multi && !mp_cont) { /* first segment */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *tail_mp = nmp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs tail_mp = &nmp->b_cont;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else if (multi && mp_cont) { /* mid of multi segs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *tail_mp = mp_cont;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs tail_mp = &mp_cont->b_cont;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else if (!multi && mp_cont) { /* last segment */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *tail_mp = mp_cont;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs tail_mp = &nmp->b_next;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer totallen += MBLKL(mp_cont);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_pkts: loop: rcr channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "before updating: multi %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "nrcr_read %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "npk read %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "head_pp $%p index %d ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, multi,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nrcr_read, npkt_read, rcr_desc_rd_head_pp, comp_rd_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!multi) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs qlen_hw--;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs npkt_read++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Update the next read entry.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs comp_rd_index = NEXT_ENTRY(comp_rd_index,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->comp_wrap_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_desc_rd_head_p = NEXT_ENTRY_PTR(rcr_desc_rd_head_p,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_first_p, rcrp->rcr_desc_last_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nrcr_read++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rx_pkts: (SAM, process one packet) "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "nrcr_read %d", nrcr_read));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_pkts: loop: rcr channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "multi %d nrcr_read %d npk read %d head_pp $%p index %d ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, multi, nrcr_read, npkt_read, rcr_desc_rd_head_pp,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs comp_rd_index));
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if ((bytes_to_read != -1) &&
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer (totallen >= bytes_to_read)) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer break;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_rd_head_pp = rcr_desc_rd_head_pp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->comp_rd_index = comp_rd_index;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_rd_head_p = rcr_desc_rd_head_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if ((hxgep->intr_timeout != rcrp->intr_timeout) ||
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer (hxgep->intr_threshold != rcrp->intr_threshold)) {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->intr_timeout = hxgep->intr_timeout;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->intr_threshold = hxgep->intr_threshold;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_cfg_b.value = 0x0ULL;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if (rcrp->intr_timeout)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_cfg_b.bits.entout = 1;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcr_cfg_b.bits.timeout = rcrp->intr_timeout;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcr_cfg_b.bits.pthres = rcrp->intr_threshold;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, rcr_cfg_b.value);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer pktcs.value = 0;
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer if (hxgep->rdc_first_intr[channel] && (npkt_read > 0)) {
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer hxgep->rdc_first_intr[channel] = B_FALSE;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer pktcs.bits.pktread = npkt_read - 1;
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer } else
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer pktcs.bits.pktread = npkt_read;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer pktcs.bits.ptrread = nrcr_read;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, channel, pktcs.value);
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_pkts: EXIT: rcr channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "head_pp $%p index %016llx ",
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer channel, rcrp->rcr_desc_rd_head_pp, rcrp->comp_rd_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL, "<== hxge_rx_pkts"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (head_mp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fe930412c257f961ae67039de3b164b83717976aqs#define RCR_ENTRY_PATTERN 0x5a5a6b6b7c7c8d8dULL
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States#define NO_PORT_BIT 0x20
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States#define L4_CS_EQ_BIT 0x40
fe930412c257f961ae67039de3b164b83717976aqs
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerstatic uint32_t hxge_scan_for_last_eop(p_rx_rcr_ring_t rcrp,
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States p_rcr_entry_t rcr_desc_rd_head_p, uint32_t num_rcrs)
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States{
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States uint64_t rcr_entry;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States uint32_t rcrs = 0;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States uint32_t pkts = 0;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer while (rcrs < num_rcrs) {
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States rcr_entry = *((uint64_t *)rcr_desc_rd_head_p);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States if ((rcr_entry == 0x0) || (rcr_entry == RCR_ENTRY_PATTERN))
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States break;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States if (!(rcr_entry & RCR_MULTI_MASK))
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States pkts++;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States rcr_desc_rd_head_p = NEXT_ENTRY_PTR(rcr_desc_rd_head_p,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_first_p, rcrp->rcr_desc_last_p);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rcrs++;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States }
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States return (pkts);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States}
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerhxge_receive_packet(p_hxge_t hxgep, p_rx_rcr_ring_t rcr_p,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_rcr_entry_t rcr_desc_rd_head_p, boolean_t *multi_p, mblk_t **mp,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer mblk_t **mp_cont, uint32_t *invalid_rcr_entry)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_mblk_t nmp = NULL;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer uint64_t multi;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer uint8_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs boolean_t first_entry = B_TRUE;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States boolean_t is_tcp_udp = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs boolean_t buffer_free = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs boolean_t error_send_up = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint8_t error_type;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t l2_len;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t skip_len;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint8_t pktbufsz_type;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t rcr_entry;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t *pkt_buf_addr_pp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t *pkt_buf_addr_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t buf_offset;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t bsize;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t msg_index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rx_rbr_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t *rx_msg_ring_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t rx_msg_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t sw_offset_bytes = 0, hdr_size = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs boolean_t is_valid = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_rx_ring_stats_t rdc_stats;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t bytes_read;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States uint8_t header0 = 0;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States uint8_t header1 = 0;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States uint64_t pkt_type;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States uint8_t no_port_bit = 0;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States uint8_t l4_cs_eq_bit = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fe930412c257f961ae67039de3b164b83717976aqs channel = rcr_p->rdc;
fe930412c257f961ae67039de3b164b83717976aqs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL, "==> hxge_receive_packet"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs first_entry = (*mp == NULL) ? B_TRUE : B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_entry = *((uint64_t *)rcr_desc_rd_head_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fe930412c257f961ae67039de3b164b83717976aqs /* Verify the content of the rcr_entry for a hardware bug workaround */
fe930412c257f961ae67039de3b164b83717976aqs if ((rcr_entry == 0x0) || (rcr_entry == RCR_ENTRY_PATTERN)) {
fe930412c257f961ae67039de3b164b83717976aqs *invalid_rcr_entry = 1;
fe930412c257f961ae67039de3b164b83717976aqs HXGE_DEBUG_MSG((hxgep, RX2_CTL, "hxge_receive_packet "
fe930412c257f961ae67039de3b164b83717976aqs "Channel %d invalid RCR entry 0x%llx found, returning\n",
fe930412c257f961ae67039de3b164b83717976aqs channel, (long long) rcr_entry));
fe930412c257f961ae67039de3b164b83717976aqs return;
fe930412c257f961ae67039de3b164b83717976aqs }
fe930412c257f961ae67039de3b164b83717976aqs *((uint64_t *)rcr_desc_rd_head_p) = RCR_ENTRY_PATTERN;
fe930412c257f961ae67039de3b164b83717976aqs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs multi = (rcr_entry & RCR_MULTI_MASK);
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States pkt_type = (rcr_entry & RCR_PKT_TYPE_MASK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs error_type = ((rcr_entry & RCR_ERROR_MASK) >> RCR_ERROR_SHIFT);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l2_len = ((rcr_entry & RCR_L2_LEN_MASK) >> RCR_L2_LEN_SHIFT);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Hardware does not strip the CRC due bug ID 11451 where
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the hardware mis handles minimum size packets.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l2_len -= ETHERFCSL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pktbufsz_type = ((rcr_entry & RCR_PKTBUFSZ_MASK) >>
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RCR_PKTBUFSZ_SHIFT);
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs pkt_buf_addr_pp = (uint64_t *)(uint32_t)((rcr_entry &
fe930412c257f961ae67039de3b164b83717976aqs RCR_PKT_BUF_ADDR_MASK) << RCR_PKT_BUF_ADDR_SHIFT);
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp = (uint64_t *)((rcr_entry & RCR_PKT_BUF_ADDR_MASK) <<
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RCR_PKT_BUF_ADDR_SHIFT);
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: entryp $%p entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "pkt_buf_addr_pp $%p l2_len %d multi %d "
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States "error_type 0x%x pktbufsz_type %d ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_desc_rd_head_p, rcr_entry, pkt_buf_addr_pp, l2_len,
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States multi, error_type, pktbufsz_type));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: entryp $%p entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "pkt_buf_addr_pp $%p l2_len %d multi %d "
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States "error_type 0x%x ", rcr_desc_rd_head_p,
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States rcr_entry, pkt_buf_addr_pp, l2_len, multi, error_type));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_entry, pkt_buf_addr_pp, l2_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* get the stats ptr */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats = rcr_p->rdc_stats;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!l2_len) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_receive_packet: failed: l2 length is 0."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* shift 6 bits to get the full io address */
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs pkt_buf_addr_pp = (uint64_t *)((uint32_t)pkt_buf_addr_pp <<
fe930412c257f961ae67039de3b164b83717976aqs RCR_PKT_BUF_ADDR_SHIFT_FULL);
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp = (uint64_t *)((uint64_t)pkt_buf_addr_pp <<
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RCR_PKT_BUF_ADDR_SHIFT_FULL);
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_entry, pkt_buf_addr_pp, l2_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p = rcr_p->rx_rbr_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_ring_p = rx_rbr_p->rx_msg_ring;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (first_entry) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hdr_size = (rcr_p->full_hdr_flag ? RXDMA_HDR_SIZE_FULL :
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RXDMA_HDR_SIZE_DEFAULT);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: first entry 0x%016llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "pkt_buf_addr_pp $%p l2_len %d hdr %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_entry, pkt_buf_addr_pp, l2_len, hdr_size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_ENTER(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 1) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_entry, pkt_buf_addr_pp, l2_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Packet buffer address in the completion entry points to the starting
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * buffer address (offset 0). Use the starting buffer address to locate
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the corresponding kernel address.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_rxbuf_pp_to_vp(hxgep, rx_rbr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pktbufsz_type, pkt_buf_addr_pp, &pkt_buf_addr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs &buf_offset, &msg_index);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 2) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_entry, pkt_buf_addr_pp, l2_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_receive_packet: found vaddr failed %d", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 3) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_entry, pkt_buf_addr_pp, l2_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 4 msgindex %d) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs msg_index, rcr_entry, pkt_buf_addr_pp, l2_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (msg_index >= rx_rbr_p->tnblocks) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: FATAL msg_index (%d) "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "should be smaller than tnblocks (%d)\n",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs msg_index, rx_rbr_p->tnblocks));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p = rx_msg_ring_p[msg_index];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 4 msgindex %d) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs msg_index, rcr_entry, pkt_buf_addr_pp, l2_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs switch (pktbufsz_type) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case RCR_PKTBUFSZ_0:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bsize = rx_rbr_p->pkt_buf_size0_bytes;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: 0 buf %d", bsize));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case RCR_PKTBUFSZ_1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bsize = rx_rbr_p->pkt_buf_size1_bytes;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: 1 buf %d", bsize));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case RCR_PKTBUFSZ_2:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bsize = rx_rbr_p->pkt_buf_size2_bytes;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: 2 buf %d", bsize));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case RCR_SINGLE_BLOCK:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bsize = rx_msg_p->block_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: single %d", bsize));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs default:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs DMA_COMMON_SYNC_OFFSET(rx_msg_p->buf_dma,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (buf_offset + sw_offset_bytes), (hdr_size + l2_len),
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs DDI_DMA_SYNC_FORCPU);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: after first dump:usage count"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_p->cur_usage_cnt == 0) {
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States atomic_inc_32(&rx_rbr_p->rbr_used);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_rbr_p->rbr_use_bcopy) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs atomic_inc_32(&rx_rbr_p->rbr_consumed);
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States if (rx_rbr_p->rbr_consumed <
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p->rbr_threshold_hi) {
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States if (rx_rbr_p->rbr_threshold_lo == 0 ||
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States ((rx_rbr_p->rbr_consumed >=
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States rx_rbr_p->rbr_threshold_lo) &&
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States (rx_rbr_p->rbr_bufsize_type >=
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States pktbufsz_type))) {
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States rx_msg_p->rx_use_bcopy = B_TRUE;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States }
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->rx_use_bcopy = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: buf %d (new block) ", bsize));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->pkt_buf_size_code = pktbufsz_type;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->pkt_buf_size = bsize;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->cur_usage_cnt = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (pktbufsz_type == RCR_SINGLE_BLOCK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: buf %d (single block) ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bsize));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Buffer can be reused once the free function is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * called.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->max_usage_cnt = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs buffer_free = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->max_usage_cnt = rx_msg_p->block_size / bsize;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_p->max_usage_cnt == 1) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs buffer_free = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->cur_usage_cnt++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_p->cur_usage_cnt == rx_msg_p->max_usage_cnt) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs buffer_free = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "msgbuf index = %d l2len %d bytes usage %d max_usage %d ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs msg_index, l2_len,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->cur_usage_cnt, rx_msg_p->max_usage_cnt));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (error_type) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->ierrors++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Update error stats */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->errlog.compl_err_type = error_type;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, NULL, HXGE_FM_EREPORT_RDMC_RCR_ERR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (error_type & RCR_CTRL_FIFO_DED) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->ctrl_fifo_ecc_err++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_receive_packet: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " channel %d RCR ctrl_fifo_ded error", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else if (error_type & RCR_DATA_FIFO_DED) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->data_fifo_ecc_err++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_receive_packet: channel %d"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " RCR data_fifo_ded error", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Update and repost buffer block if max usage count is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * reached.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (error_send_up == B_FALSE) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs atomic_inc_32(&rx_msg_p->ref_cnt);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (buffer_free == B_TRUE) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->free = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_freeb(rx_msg_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: DMA sync second "));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bytes_read = rcr_p->rcvd_pkt_bytes;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs skip_len = sw_offset_bytes + hdr_size;
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States if (first_entry) {
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States header0 = rx_msg_p->buffer[buf_offset];
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States no_port_bit = header0 & NO_PORT_BIT;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States header1 = rx_msg_p->buffer[buf_offset + 1];
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States l4_cs_eq_bit = header1 & L4_CS_EQ_BIT;
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States }
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!rx_msg_p->rx_use_bcopy) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * For loaned up buffers, the driver reference count
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * will be incremented first and then the free state.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((nmp = hxge_dupb(rx_msg_p, buf_offset, bsize)) != NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (first_entry) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp->b_rptr = &nmp->b_rptr[skip_len];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (l2_len < bsize - skip_len) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp->b_wptr = &nmp->b_rptr[l2_len];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp->b_wptr = &nmp->b_rptr[bsize
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs - skip_len];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (l2_len - bytes_read < bsize) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp->b_wptr =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs &nmp->b_rptr[l2_len - bytes_read];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp->b_wptr = &nmp->b_rptr[bsize];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (first_entry) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp = hxge_dupb_bcopy(rx_msg_p, buf_offset + skip_len,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l2_len < bsize - skip_len ?
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l2_len : bsize - skip_len);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp = hxge_dupb_bcopy(rx_msg_p, buf_offset,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l2_len - bytes_read < bsize ?
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l2_len - bytes_read : bsize);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (nmp != NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (first_entry)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bytes_read = nmp->b_wptr - nmp->b_rptr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bytes_read += nmp->b_wptr - nmp->b_rptr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet after dupb: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rbr consumed %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "pktbufsz_type %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "nmp $%p rptr $%p wptr $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_offset %d bzise %d l2_len %d skip_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p->rbr_consumed,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pktbufsz_type,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp, nmp->b_rptr, nmp->b_wptr,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs buf_offset, bsize, l2_len, skip_len));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cmn_err(CE_WARN, "!hxge_receive_packet: update stats (error)");
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs atomic_inc_32(&rx_msg_p->ref_cnt);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (buffer_free == B_TRUE) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->free = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_freeb(rx_msg_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (buffer_free == B_TRUE) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->free = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * ERROR, FRAG and PKT_TYPE are only reported in the first entry. If a
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * packet is not fragmented and no error bit is set, then L4 checksum
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * is OK.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs is_valid = (nmp != NULL);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (first_entry) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->ipackets++; /* count only 1st seg for jumbo */
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States if (l2_len > (STD_FRAME_SIZE - ETHERFCSL))
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States rdc_stats->jumbo_pkts++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->ibytes += skip_len + l2_len < bsize ?
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs l2_len : bsize;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States /*
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States * Add the current portion of the packet to the kstats.
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States * The current portion of the packet is calculated by using
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States * length of the packet and the previously received portion.
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States */
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States rdc_stats->ibytes += l2_len - rcr_p->rcvd_pkt_bytes < bsize ?
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States l2_len - rcr_p->rcvd_pkt_bytes : bsize;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_p->rcvd_pkt_bytes = bytes_read;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_p->free && rx_msg_p->rx_use_bcopy) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs atomic_inc_32(&rx_msg_p->ref_cnt);
dc10a9c2a5a49452cc30c6a110b64e5e074e37b3Michael Speer MUTEX_EXIT(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_freeb(rx_msg_p);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer } else
dc10a9c2a5a49452cc30c6a110b64e5e074e37b3Michael Speer MUTEX_EXIT(&rx_rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (is_valid) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmp->b_cont = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (first_entry) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *mp = nmp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *mp_cont = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *mp_cont = nmp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Update stats and hardware checksuming.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (is_valid && !multi) {
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States is_tcp_udp = ((pkt_type == RCR_PKT_IS_TCP ||
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States pkt_type == RCR_PKT_IS_UDP) ? B_TRUE : B_FALSE);
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States if (!no_port_bit && l4_cs_eq_bit && is_tcp_udp && !error_type) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_hcksum_set(nmp, 0, 0, 0, 0, HCK_FULLCKSUM_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: Full tcp/udp cksum "
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States "is_valid 0x%x multi %d error %d",
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States is_valid, multi, error_type));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: *mp 0x%016llx", *mp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *multi_p = (multi == RCR_MULTI_MASK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_receive_packet: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "multi %d nmp 0x%016llx *mp 0x%016llx *mp_cont 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *multi_p, nmp, *mp, *mp_cont));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speerstatic void
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speerhxge_rx_rbr_empty_recover(p_hxge_t hxgep, uint8_t channel)
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer{
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer hpi_handle_t handle;
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer p_rx_rcr_ring_t rcrp;
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer p_rx_rbr_ring_t rbrp;
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer rcrp = hxgep->rx_rcr_rings->rcr_rings[channel];
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer rbrp = rcrp->rx_rbr_p;
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer handle = HXGE_DEV_HPI_HANDLE(hxgep);
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer /*
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Wait for the channel to be quiet
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer */
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer (void) hpi_rxdma_cfg_rdc_wait_for_qst(handle, channel);
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer /*
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Post page will accumulate some buffers before re-enabling
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * the DMA channel.
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer */
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer MUTEX_ENTER(&rbrp->post_lock);
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States if ((rbrp->rbb_max - rbrp->rbr_used) >= HXGE_RBR_EMPTY_THRESHOLD) {
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hxge_rbr_empty_restore(hxgep, rbrp);
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States } else {
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rbrp->rbr_is_empty = B_TRUE;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States }
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer MUTEX_EXIT(&rbrp->post_lock);
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer}
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rx_err_evnts(p_hxge_t hxgep, uint_t index, p_hxge_ldv_t ldvp,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stat_t cs)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_rx_ring_stats_t rdc_stats;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs boolean_t rxchan_fatal = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint8_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_rx_err_evnts"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ldvp->channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats = &hxgep->statsp->rdc_stats[ldvp->vdma_index];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rbr_cpl_to) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rbr_tmout++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_RBR_CPL_TO);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rx_rbr_timeout", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((cs.bits.rcr_shadow_par_err) || (cs.bits.rbr_prefetch_par_err)) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hpi_rxdma_ring_perr_stat_get(handle,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs &rdc_stats->errlog.pre_par, &rdc_stats->errlog.sha_par);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rcr_shadow_par_err) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rcr_sha_par++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_RCR_SHA_PAR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rcr_shadow_par_err", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rbr_prefetch_par_err) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rbr_pre_par++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_RBR_PRE_PAR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rbr_prefetch_par_err", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rbr_pre_empty) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rbr_pre_empty++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_RBR_PRE_EMPTY);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rbr_pre_empty", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.peu_resp_err) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->peu_resp_err++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_PEU_RESP_ERR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: peu_resp_err", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rcr_thres) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rcr_thres++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rcr_to) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rcr_to++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rcr_shadow_full) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rcr_shadow_full++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_RCR_SHA_FULL);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rcr_shadow_full", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rcr_full) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rcrfull++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_RCRFULL);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rcrfull error", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rbr_empty) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rbr_empty++;
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer hxge_rx_rbr_empty_recover(hxgep, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (cs.bits.rbr_full) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stats->rbrfull++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_RBRFULL);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxchan_fatal = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rbr_full error", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rxchan_fatal) {
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States p_rx_rcr_ring_t rcrp;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States p_rx_rbr_ring_t rbrp;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rcrp = hxgep->rx_rcr_rings->rcr_rings[channel];
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rbrp = rcrp->rx_rbr_p;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rx_err_evnts: fatal error on Channel #%d\n",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel));
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&rbrp->post_lock);
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States /* This function needs to be inside the post_lock */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_rxdma_fatal_err_recover(hxgep, channel);
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&rbrp->post_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status == HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs FM_SERVICE_RESTORED(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_rx_err_evnts"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i, ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_rings_t rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t *rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_rings_t rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t *rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_areas_t rx_mbox_areas_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_t *rx_mbox_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_pool_t dma_buf_poolp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t *dma_buf_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_pool_t dma_rbr_cntl_poolp;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_rbr_cntl_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_pool_t dma_rcr_cntl_poolp;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_rcr_cntl_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_pool_t dma_mbox_cntl_poolp;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_mbox_cntl_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t *num_chunks;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_map_rxdma"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_buf_poolp = hxgep->rx_buf_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rbr_cntl_poolp = hxgep->rx_rbr_cntl_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rcr_cntl_poolp = hxgep->rx_rcr_cntl_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_mbox_cntl_poolp = hxgep->rx_mbox_cntl_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer if (!dma_buf_poolp->buf_allocated ||
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer !dma_rbr_cntl_poolp->buf_allocated ||
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer !dma_rcr_cntl_poolp->buf_allocated ||
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer !dma_mbox_cntl_poolp->buf_allocated) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma: buf not allocated"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas = dma_buf_poolp->ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!ndmas) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma: no dma allocated"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs num_chunks = dma_buf_poolp->num_chunks;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_buf_p = dma_buf_poolp->dma_buf_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rbr_cntl_p = dma_rbr_cntl_poolp->dma_buf_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rcr_cntl_p = dma_rcr_cntl_poolp->dma_buf_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_mbox_cntl_p = dma_mbox_cntl_poolp->dma_buf_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings = (p_rx_rbr_rings_t)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_ZALLOC(sizeof (rx_rbr_rings_t), KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_rings = (p_rx_rbr_ring_t *)KMEM_ZALLOC(
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs sizeof (p_rx_rbr_ring_t) * ndmas, KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rcr_rings = (p_rx_rcr_rings_t)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_ZALLOC(sizeof (rx_rcr_rings_t), KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_rings = (p_rx_rcr_ring_t *)KMEM_ZALLOC(
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs sizeof (p_rx_rcr_ring_t) * ndmas, KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_mbox_areas_p = (p_rx_mbox_areas_t)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_ZALLOC(sizeof (rx_mbox_areas_t), KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_mbox_p = (p_rx_mbox_t *)KMEM_ZALLOC(
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs sizeof (p_rx_mbox_t) * ndmas, KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Timeout should be set based on the system clock divider.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The following timeout value of 1 assumes that the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * granularity (1000) is 3 microseconds running at 300MHz.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep->intr_threshold = RXDMA_RCR_PTHRES_DEFAULT;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep->intr_timeout = RXDMA_RCR_TO_DEFAULT;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Map descriptors from the buffer polls for each dam channel.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer if (((p_hxge_dma_common_t)dma_buf_p[i]) == NULL) {
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer status = HXGE_ERROR;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer goto hxge_map_rxdma_fail1;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer }
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Set up and prepare buffer blocks, descriptors and mailbox.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ((p_hxge_dma_common_t)dma_buf_p[i])->dma_channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_map_rxdma_channel(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_hxge_dma_common_t *)&dma_buf_p[i],
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_rbr_ring_t *)&rbr_rings[i],
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer num_chunks[i],
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer (p_hxge_dma_common_t *)&dma_rbr_cntl_p[i],
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer (p_hxge_dma_common_t *)&dma_rcr_cntl_p[i],
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer (p_hxge_dma_common_t *)&dma_mbox_cntl_p[i],
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_rcr_ring_t *)&rcr_rings[i],
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_mbox_t *)&rx_mbox_p[i]);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_fail1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_rings[i]->index = (uint16_t)i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_rings[i]->index = (uint16_t)i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_rings[i]->rdc_stats = &hxgep->statsp->rdc_stats[i];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings->ndmas = rx_rcr_rings->ndmas = ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings->rbr_rings = rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep->rx_rbr_rings = rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rcr_rings->rcr_rings = rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep->rx_rcr_rings = rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_mbox_areas_p->rxmbox_areas = rx_mbox_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep->rx_mbox_areas_p = rx_mbox_areas_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_fail1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma: unmap rbr,rcr (status 0x%x channel %d i %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel, i));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs i--;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (; i >= 0; i--) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ((p_hxge_dma_common_t)dma_buf_p[i])->dma_channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_unmap_rxdma_channel(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_rings[i], rcr_rings[i], rx_mbox_p[i]);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rbr_rings, sizeof (p_rx_rbr_ring_t) * ndmas);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_rbr_rings, sizeof (rx_rbr_rings_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rcr_rings, sizeof (p_rx_rcr_ring_t) * ndmas);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_rcr_rings, sizeof (rx_rcr_rings_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_mbox_p, sizeof (p_rx_mbox_t) * ndmas);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_mbox_areas_p, sizeof (rx_mbox_areas_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_exit:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma: (status 0x%x channel %d)", status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_unmap_rxdma(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i, ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_rings_t rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t *rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_rings_t rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t *rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_areas_t rx_mbox_areas_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_t *rx_mbox_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_pool_t dma_buf_poolp;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_pool_t dma_rbr_cntl_poolp;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_pool_t dma_rcr_cntl_poolp;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_pool_t dma_mbox_cntl_poolp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t *dma_buf_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_unmap_rxdma"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_buf_poolp = hxgep->rx_buf_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rbr_cntl_poolp = hxgep->rx_rbr_cntl_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rcr_cntl_poolp = hxgep->rx_rcr_cntl_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_mbox_cntl_poolp = hxgep->rx_mbox_cntl_pool_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer if (!dma_buf_poolp->buf_allocated ||
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer !dma_rbr_cntl_poolp->buf_allocated ||
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer !dma_rcr_cntl_poolp->buf_allocated ||
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer !dma_mbox_cntl_poolp->buf_allocated) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma: NULL buf pointers"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings = hxgep->rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rcr_rings = hxgep->rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_rbr_rings == NULL || rx_rcr_rings == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer "<== hxge_unmap_rxdma: NULL pointers"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas = rx_rbr_rings->ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!ndmas) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma: no channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma (ndmas %d)", ndmas));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_rings = rx_rbr_rings->rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_rings = rx_rcr_rings->rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_mbox_areas_p = hxgep->rx_mbox_areas_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_mbox_p = rx_mbox_areas_p->rxmbox_areas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_buf_p = dma_buf_poolp->dma_buf_pool_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ((p_hxge_dma_common_t)dma_buf_p[i])->dma_channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma (ndmas %d) channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_unmap_rxdma_channel(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_rbr_ring_t)rbr_rings[i],
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_rcr_ring_t)rcr_rings[i],
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_mbox_t)rx_mbox_p[i]);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_rbr_rings, sizeof (rx_rbr_rings_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rbr_rings, sizeof (p_rx_rbr_ring_t) * ndmas);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_rcr_rings, sizeof (rx_rcr_rings_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rcr_rings, sizeof (p_rx_rcr_ring_t) * ndmas);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_mbox_areas_p, sizeof (rx_mbox_areas_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_mbox_p, sizeof (p_rx_mbox_t) * ndmas);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_unmap_rxdma"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel(p_hxge_t hxgep, uint16_t channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t *dma_buf_p, p_rx_rbr_ring_t *rbr_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer uint32_t num_chunks, p_hxge_dma_common_t *dma_rbr_cntl_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_rcr_cntl_p, p_hxge_dma_common_t *dma_mbox_cntl_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t *rcr_p, p_rx_mbox_t *rx_mbox_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Set up and prepare buffer blocks, descriptors and mailbox.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel (channel %d)", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Receive buffer blocks
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_map_rxdma_channel_buf_ring(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_buf_p, rbr_p, num_chunks);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel (channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "map buffer failed 0x%x", channel, status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_channel_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Receive block ring, completion ring and mailbox.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_map_rxdma_channel_cfg_ring(hxgep, channel,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rbr_cntl_p, dma_rcr_cntl_p, dma_mbox_cntl_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer rbr_p, rcr_p, rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel (channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "map config failed 0x%x", channel, status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_channel_fail2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_channel_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_fail3:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Free rbr, rcr */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel: free rbr/rcr (status 0x%x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_unmap_rxdma_channel_cfg_ring(hxgep, *rcr_p, *rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_fail2:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Free buffer blocks */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel: free rx buffers"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "(hxgep 0x%x status 0x%x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep, status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_unmap_rxdma_channel_buf_ring(hxgep, *rbr_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = HXGE_ERROR;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_exit:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel: (hxgep 0x%x status 0x%x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep, status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_unmap_rxdma_channel(p_hxge_t hxgep, uint16_t channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t rx_mbox_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma_channel (channel %d)", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * unmap receive block ring, completion ring and mailbox.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_unmap_rxdma_channel_cfg_ring(hxgep, rcr_p, rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* unmap buffer blocks */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_unmap_rxdma_channel_buf_ring(hxgep, rbr_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_unmap_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_cfg_ring(p_hxge_t hxgep, uint16_t dma_channel,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_rbr_cntl_p, p_hxge_dma_common_t *dma_rcr_cntl_p,
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer p_hxge_dma_common_t *dma_mbox_cntl_p, p_rx_rbr_ring_t *rbr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t *rcr_p, p_rx_mbox_t *rx_mbox_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rbrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t rcrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_t mboxp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t cntl_dmap;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t dmap;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t *rx_msg_ring;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t rx_msg_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rbr_cfg_a_t *rcfga_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rbr_cfg_b_t *rcfgb_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rcr_cfg_a_t *cfga_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rcr_cfg_b_t *cfgb_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rx_cfg1_t *cfig1_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rx_cfg2_t *cfig2_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_rbr_kick_t *kick_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t dmaaddrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t *rbr_vaddrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t bkaddr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t hxge_port_rcr_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer cntl_dmap = *dma_rbr_cntl_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer /*
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer * Map in the receive block ring
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp = *rbr_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmap = (p_hxge_dma_common_t)&rbrp->rbr_desc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_setup_dma_common(dmap, cntl_dmap, rbrp->rbb_max, 4);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Zero out buffer block ring descriptors.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bzero((caddr_t)dmap->kaddrp, dmap->alength);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfga_p = &(rbrp->rbr_cfga);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p = &(rbrp->rbr_cfgb);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs kick_p = &(rbrp->rbr_kick);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfga_p->value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs kick_p->value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_addr = dmap->dma_cookie.dmac_laddress;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfga_p->value = (rbrp->rbr_addr &
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (RBR_CFIG_A_STDADDR_MASK | RBR_CFIG_A_STDADDR_BASE_MASK));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfga_p->value |= ((uint64_t)rbrp->rbb_max << RBR_CFIG_A_LEN_SHIFT);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* XXXX: how to choose packet buffer sizes */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->bits.bufsz0 = rbrp->pkt_buf_size0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->bits.vld0 = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->bits.bufsz1 = rbrp->pkt_buf_size1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->bits.vld1 = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->bits.bufsz2 = rbrp->pkt_buf_size2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->bits.vld2 = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcfgb_p->bits.bksize = hxgep->rx_bksize_code;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * For each buffer block, enter receive block address to the ring.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_vaddrp = (uint32_t *)dmap->kaddrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_desc_vp = (uint32_t *)dmap->kaddrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring: channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rbr_vaddrp $%p", dma_channel, rbr_vaddrp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_ring = rbrp->rx_msg_ring;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < rbrp->tnblocks; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p = rx_msg_ring[i];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->hxgep = hxgep;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->rx_rbr_p = rbrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bkaddr = (uint32_t)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ((rx_msg_p->buf_dma.dma_cookie.dmac_laddress >>
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RBR_BKADDR_SHIFT));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->free = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->max_usage_cnt = 0xbaddcafe;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *rbr_vaddrp++ = bkaddr;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs kick_p->bits.bkadd = rbrp->rbb_max;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_wr_index = (rbrp->rbb_max - 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_rd_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_consumed = 0;
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States rbrp->rbr_used = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_use_bcopy = B_TRUE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_bufsize_type = RCR_PKTBUFSZ_0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Do bcopy on packets greater than bcopy size once the lo threshold is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * reached. This lo threshold should be less than the hi threshold.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Do bcopy on every packet once the hi threshold is reached.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_rx_threshold_lo >= hxge_rx_threshold_hi) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* default it to use hi */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_rx_threshold_lo = hxge_rx_threshold_hi;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_rx_buf_size_type > HXGE_RBR_TYPE2) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_rx_buf_size_type = HXGE_RBR_TYPE2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_bufsize_type = hxge_rx_buf_size_type;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs switch (hxge_rx_threshold_hi) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs default:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_NONE:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Do not do bcopy at all */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_use_bcopy = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_threshold_hi = rbrp->rbb_max;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_2:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_3:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_4:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_5:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_6:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_7:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_threshold_hi =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbb_max * (hxge_rx_threshold_hi) /
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_RX_BCOPY_SCALE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_ALL:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_threshold_hi = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs switch (hxge_rx_threshold_lo) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs default:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_NONE:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Do not do bcopy at all */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rbrp->rbr_use_bcopy) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_use_bcopy = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_threshold_lo = rbrp->rbb_max;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_2:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_3:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_4:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_5:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_6:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_7:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_threshold_lo =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbb_max * (hxge_rx_threshold_lo) /
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_RX_BCOPY_SCALE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs case HXGE_RX_COPY_ALL:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_threshold_lo = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs break;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_map_rxdma_channel_cfg_ring: channel %d rbb_max %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rbrp->rbr_bufsize_type %d rbb_threshold_hi %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rbb_threshold_lo %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_channel, rbrp->rbb_max, rbrp->rbr_bufsize_type,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_threshold_hi, rbrp->rbr_threshold_lo));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Map in the receive completion ring */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp = (p_rx_rcr_ring_t)KMEM_ZALLOC(sizeof (rx_rcr_ring_t), KM_SLEEP);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_INIT(&rcrp->lock, NULL, MUTEX_DRIVER,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void *) hxgep->interrupt_cookie);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rdc = dma_channel;
069fd767a977699f506b76b0432a2c61709b90ecMichael Speer rcrp->hxgep = hxgep;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_port_rcr_size = hxgep->hxge_port_rcr_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->comp_size = hxge_port_rcr_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->comp_wrap_mask = hxge_port_rcr_size - 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer cntl_dmap = *dma_rcr_cntl_p;
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmap = (p_hxge_dma_common_t)&rcrp->rcr_desc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_setup_dma_common(dmap, cntl_dmap, rcrp->comp_size,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs sizeof (rcr_entry_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->comp_rd_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->comp_wt_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_rd_head_p = rcrp->rcr_desc_first_p =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rcr_entry_t)DMA_COMMON_VPTR(rcrp->rcr_desc);
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs rcrp->rcr_desc_rd_head_pp = rcrp->rcr_desc_first_pp =
fe930412c257f961ae67039de3b164b83717976aqs (p_rcr_entry_t)(uint32_t)DMA_COMMON_IOADDR(rcrp->rcr_desc);
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_rd_head_pp = rcrp->rcr_desc_first_pp =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rcr_entry_t)DMA_COMMON_IOADDR(rcrp->rcr_desc);
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_last_p = rcrp->rcr_desc_rd_head_p +
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (hxge_port_rcr_size - 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_last_pp = rcrp->rcr_desc_rd_head_pp +
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (hxge_port_rcr_size - 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States rcrp->rcr_tail_begin = DMA_COMMON_IOADDR(rcrp->rcr_desc);
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States rcrp->rcr_tail_begin = (rcrp->rcr_tail_begin & 0x7ffffULL) >> 3;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring: channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rbr_vaddrp $%p rcr_desc_rd_head_p $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rcr_desc_rd_head_pp $%p rcr_desc_rd_last_p $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rcr_desc_rd_last_pp $%p ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_channel, rbr_vaddrp, rcrp->rcr_desc_rd_head_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_rd_head_pp, rcrp->rcr_desc_last_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_last_pp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Zero out buffer block ring descriptors.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bzero((caddr_t)dmap->kaddrp, dmap->alength);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->intr_timeout = hxgep->intr_timeout;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->intr_threshold = hxgep->intr_threshold;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->full_hdr_flag = B_FALSE;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->sw_priv_hdr_len = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfga_p = &(rcrp->rcr_cfga);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfgb_p = &(rcrp->rcr_cfgb);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfga_p->value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfgb_p->value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_addr = dmap->dma_cookie.dmac_laddress;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfga_p->value = (rcrp->rcr_addr &
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (RCRCFIG_A_STADDR_MASK | RCRCFIG_A_STADDR_BASE_MASK));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfga_p->value |= ((uint64_t)rcrp->comp_size << RCRCFIG_A_LEN_SHIF);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Timeout should be set based on the system clock divider. The
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * following timeout value of 1 assumes that the granularity (1000) is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * 3 microseconds running at 300MHz.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfgb_p->bits.pthres = rcrp->intr_threshold;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfgb_p->bits.timeout = rcrp->intr_timeout;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfgb_p->bits.entout = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Map in the mailbox */
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer cntl_dmap = *dma_mbox_cntl_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mboxp = (p_rx_mbox_t)KMEM_ZALLOC(sizeof (rx_mbox_t), KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmap = (p_hxge_dma_common_t)&mboxp->rx_mbox;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_setup_dma_common(dmap, cntl_dmap, 1, sizeof (rxdma_mailbox_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig1_p = (rdc_rx_cfg1_t *)&mboxp->rx_cfg1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig2_p = (rdc_rx_cfg2_t *)&mboxp->rx_cfg2;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig1_p->value = cfig2_p->value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mboxp->mbox_addr = dmap->dma_cookie.dmac_laddress;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d cfg1 0x%016llx cfig2 0x%016llx cookie 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_channel, cfig1_p->value, cfig2_p->value,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mboxp->mbox_addr));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmaaddrp = (uint32_t)((dmap->dma_cookie.dmac_laddress >> 32) & 0xfff);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig1_p->bits.mbaddr_h = dmaaddrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmaaddrp = (uint32_t)(dmap->dma_cookie.dmac_laddress & 0xffffffff);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmaaddrp = (uint32_t)(dmap->dma_cookie.dmac_laddress &
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RXDMA_CFIG2_MBADDR_L_MASK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig2_p->bits.mbaddr_l = (dmaaddrp >> RXDMA_CFIG2_MBADDR_L_SHIFT);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring: channel %d damaddrp $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "cfg1 0x%016llx cfig2 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_channel, dmaaddrp, cfig1_p->value, cfig2_p->value));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig2_p->bits.full_hdr = rcrp->full_hdr_flag;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig2_p->bits.offset = rcrp->sw_priv_hdr_len;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rx_rcr_p = rcrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rx_rbr_p = rbrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *rcr_p = rcrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *rx_mbox_p = mboxp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel_cfg_ring status 0x%08x", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_unmap_rxdma_channel_cfg_ring(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t rcr_p, p_rx_mbox_t rx_mbox_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma_channel_cfg_ring: channel %d", rcr_p->rdc));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_DESTROY(&rcr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rcr_p, sizeof (rx_rcr_ring_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_mbox_p, sizeof (rx_mbox_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_cfg_ring"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_buf_ring(p_hxge_t hxgep, uint16_t channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t *dma_buf_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t *rbr_p, uint32_t num_chunks)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rbrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t dma_bufp, tmp_bufp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t *rx_msg_ring;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t rx_msg_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_mblk_t mblk_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxring_info_t *ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i, j, index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t size, bsize, nblocks, nmsgs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_buf_ring: channel %d", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_bufp = tmp_bufp = *dma_buf_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_map_rxdma_channel_buf_ring: channel %d to map %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "chunks bufp 0x%016llx", channel, num_chunks, dma_bufp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmsgs = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < num_chunks; i++, tmp_bufp++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_buf_ring: channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "bufp 0x%016llx nblocks %d nmsgs %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, tmp_bufp, tmp_bufp->nblocks, nmsgs));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nmsgs += tmp_bufp->nblocks;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!nmsgs) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel_buf_ring: channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "no msg blocks", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = HXGE_ERROR;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_channel_buf_ring_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp = (p_rx_rbr_ring_t)KMEM_ZALLOC(sizeof (rx_rbr_ring_t), KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs size = nmsgs * sizeof (p_rx_msg_t);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_ring = KMEM_ZALLOC(size, KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info = (rxring_info_t *)KMEM_ZALLOC(sizeof (rxring_info_t),
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_INIT(&rbrp->lock, NULL, MUTEX_DRIVER,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void *) hxgep->interrupt_cookie);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_INIT(&rbrp->post_lock, NULL, MUTEX_DRIVER,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void *) hxgep->interrupt_cookie);
069fd767a977699f506b76b0432a2c61709b90ecMichael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rdc = channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->num_blocks = num_chunks;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->tnblocks = nmsgs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbb_max = nmsgs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_max_size = nmsgs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_wrap_mask = (rbrp->rbb_max - 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Buffer sizes: 256, 1K, and 2K.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer *
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Blk 0 size.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->pkt_buf_size0 = RBR_BUFSZ0_256B;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->pkt_buf_size0_bytes = RBR_BUFSZ0_256_BYTES;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->hpi_pkt_buf_size0 = SIZE_256B;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer /*
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Blk 1 size.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->pkt_buf_size1 = RBR_BUFSZ1_1K;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->pkt_buf_size1_bytes = RBR_BUFSZ1_1K_BYTES;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->hpi_pkt_buf_size1 = SIZE_1KB;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer /*
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Blk 2 size.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer */
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->pkt_buf_size2 = RBR_BUFSZ2_2K;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->pkt_buf_size2_bytes = RBR_BUFSZ2_2K_BYTES;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->hpi_pkt_buf_size2 = SIZE_2KB;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->block_size = hxgep->rx_default_block_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_buf_ring: channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "actual rbr max %d rbb_max %d nmsgs %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rbrp->block_size %d default_block_size %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "(config hxge_rbr_size %d hxge_rbr_spare_size %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, rbrp->rbr_max_size, rbrp->rbb_max, nmsgs,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->block_size, hxgep->rx_default_block_size,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_rbr_size, hxge_rbr_spare_size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Map in buffers from the buffer pool.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Note that num_blocks is the num_chunks. For Sparc, there is likely
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * only one chunk. For x86, there will be many chunks.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Loop over chunks.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < rbrp->num_blocks; i++, dma_bufp++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bsize = dma_bufp->block_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs nblocks = dma_bufp->nblocks;
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs ring_info->buffer[i].dvma_addr = (uint32_t)dma_bufp->ioaddr_pp;
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].dvma_addr = (uint64_t)dma_bufp->ioaddr_pp;
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].buf_index = i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].buf_size = dma_bufp->alength;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].start_index = index;
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs ring_info->buffer[i].kaddr = (uint32_t)dma_bufp->kaddrp;
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].kaddr = (uint64_t)dma_bufp->kaddrp;
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_map_rxdma_channel_buf_ring: map channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "chunk %d nblocks %d chunk_size %x block_size 0x%x "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "dma_bufp $%p dvma_addr $%p", channel, i,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_bufp->nblocks,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].buf_size, bsize, dma_bufp,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].dvma_addr));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* loop over blocks within a chunk */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (j = 0; j < nblocks; j++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((rx_msg_p = hxge_allocb(bsize, BPRI_LO,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_bufp)) == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "allocb failed (index %d i %d j %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs index, i, j));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_channel_buf_ring_fail1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_ring[index] = rx_msg_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->block_index = index;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->shifted_addr = (uint32_t)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ((rx_msg_p->buf_dma.dma_cookie.dmac_laddress >>
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs RBR_BKADDR_SHIFT));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Too much output
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * "index %d j %d rx_msg_p $%p mblk %p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * index, j, rx_msg_p, rx_msg_p->rx_mblk_p));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mblk_p = rx_msg_p->rx_mblk_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mblk_p->b_wptr = mblk_p->b_rptr + bsize;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_ref_cnt++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs index++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p->buf_dma.dma_channel = channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (i < rbrp->num_blocks) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_channel_buf_ring_fail1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_map_rxdma_channel_buf_ring: done buf init "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d msg block entries %d", channel, index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->block_size_mask = bsize - 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rx_msg_ring = rx_msg_ring;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->dma_bufp = dma_buf_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->ring_info = ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_rxbuf_index_info_init(hxgep, rbrp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, " hxge_map_rxdma_channel_buf_ring: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d done buf info init", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Finally, permit hxge_freeb() to call hxge_post_page().
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_state = RBR_POSTING;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *rbr_p = rbrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_map_rxdma_channel_buf_ring_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_buf_ring_fail1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_map_rxdma_channel_buf_ring: failed channel (0x%x)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs index--;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (; index >= 0; index--) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p = rx_msg_ring[index];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_p != NULL) {
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States freeb(rx_msg_p->rx_mblk_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_ring[index] = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_buf_ring_fail:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_DESTROY(&rbrp->post_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_DESTROY(&rbrp->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(ring_info, sizeof (rxring_info_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_msg_ring, size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rbrp, sizeof (rx_rbr_ring_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = HXGE_ERROR;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_buf_ring_exit:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel_buf_ring status 0x%08x", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_unmap_rxdma_channel_buf_ring(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rbr_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t *rx_msg_ring;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t rx_msg_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rxring_info_t *ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma_channel_buf_ring"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rbr_p == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_buf_ring: NULL rbrp"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma_channel_buf_ring: channel %d", rbr_p->rdc));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_ring = rbr_p->rx_msg_ring;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info = rbr_p->ring_info;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_ring == NULL || ring_info == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_buf_ring: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_msg_ring $%p ring_info $%p", rx_msg_p, ring_info));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs size = rbr_p->tnblocks * sizeof (p_rx_msg_t);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_unmap_rxdma_channel_buf_ring: channel %d chunks %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "tnblocks %d (max %d) size ptrs %d ", rbr_p->rdc, rbr_p->num_blocks,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_p->tnblocks, rbr_p->rbr_max_size, size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < rbr_p->tnblocks; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p = rx_msg_ring[i];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_unmap_rxdma_channel_buf_ring: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_msg_p $%p", rx_msg_p));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_p != NULL) {
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States freeb(rx_msg_p->rx_mblk_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_ring[i] = NULL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * We no longer may use the mutex <post_lock>. By setting
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * <rbr_state> to anything but POSTING, we prevent
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * hxge_post_page() from accessing a dead mutex.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_p->rbr_state = RBR_UNMAPPING;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_DESTROY(&rbr_p->post_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_DESTROY(&rbr_p->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(ring_info, sizeof (rxring_info_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rx_msg_ring, size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rbr_p->rbr_ref_cnt == 0) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* This is the normal state of affairs. */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs KMEM_FREE(rbr_p, sizeof (*rbr_p));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Some of our buffers are still being used.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Therefore, tell hxge_freeb() this ring is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * unmapped, so it may free <rbr_p> for us.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_p->rbr_state = RBR_UNMAPPED;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "unmap_rxdma_buf_ring: %d %s outstanding.",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_p->rbr_ref_cnt,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_p->rbr_ref_cnt == 1 ? "msg" : "msgs"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_buf_ring"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_hw_start_common(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start_common"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Load the sharable parameters by writing to the function zero control
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * registers. These FZC registers should be initialized only once for
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the entire chip.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_init_fzc_rx_common(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start_common"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_hw_start(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i, ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_rings_t rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t *rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_rings_t rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t *rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_areas_t rx_mbox_areas_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_t *rx_mbox_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings = hxgep->rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rcr_rings = hxgep->rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_rbr_rings == NULL || rx_rcr_rings == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_start: NULL ring pointers"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas = rx_rbr_rings->ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (ndmas == 0) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_start: no dma channel allocated"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_start (ndmas %d)", ndmas));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub the RDC Rx DMA Prefetch Buffer Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 128; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_PREF_CMD, i);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub Rx DMA Shadow Tail Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 64; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_SHADOW_CMD, i);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub Rx DMA Control Fifo Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 512; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_CTRL_FIFO_CMD, i);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub Rx DMA Data Fifo Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 1536; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_DATA_FIFO_CMD, i);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Reset the FIFO Error Stat.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_FIFO_ERR_STAT, 0xFF);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Set the error mask to receive interrupts */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_FIFO_ERR_INT_MASK, 0x0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_rings = rx_rbr_rings->rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcr_rings = rx_rcr_rings->rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_mbox_areas_p = hxgep->rx_mbox_areas_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_mbox_areas_p) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_mbox_p = rx_mbox_areas_p->rxmbox_areas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = rbr_rings[i]->rdc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_start (ndmas %d) channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_rxdma_start_channel(hxgep, channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_rbr_ring_t)rbr_rings[i],
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rx_rcr_ring_t)rcr_rings[i],
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States (p_rx_mbox_t)rx_mbox_p[i], rbr_rings[i]->rbb_max);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_rxdma_hw_start_fail1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_rbr_rings 0x%016llx rings 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings, rx_rcr_rings));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto hxge_rxdma_hw_start_exit;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_hw_start_fail1:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_start: disable "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "(status 0x%x channel %d i %d)", status, channel, i));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (; i >= 0; i--) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = rbr_rings[i]->rdc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_rxdma_stop_channel(hxgep, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_hw_start_exit:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_start: (status 0x%x)", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_hw_stop(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i, ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_rings_t rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t *rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_rings_t rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_stop"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings = hxgep->rx_rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rcr_rings = hxgep->rx_rcr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_rbr_rings == NULL || rx_rcr_rings == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_stop: NULL ring pointers"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas = rx_rbr_rings->ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (!ndmas) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_stop: no dma channel allocated"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_stop (ndmas %d)", ndmas));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbr_rings = rx_rbr_rings->rbr_rings;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = rbr_rings[i]->rdc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_stop (ndmas %d) channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_rxdma_stop_channel(hxgep, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_stop: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_rbr_rings 0x%016llx rings 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_rings, rx_rcr_rings));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_rxdma_hw_stop"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_start_channel(p_hxge_t hxgep, uint16_t channel,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States int n_init_kick)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_status_t rs = HPI_SUCCESS;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stat_t cs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_int_mask_t ent_mask;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hpi handle addr $%p acc $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep->hpi_handle.regp, hxgep->hpi_handle.regh));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RXDMA channel */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_reset(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "reset rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: reset done: channel %d", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Initialize the RXDMA channel specific FZC control configurations.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * These FZC registers are pertaining to each RX channel (logical
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * pages).
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_init_fzc_rxdma_channel(hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, rbr_p, rcr_p, mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "init fzc rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: fzc done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Zero out the shadow and prefetch ram.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: ram done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Set up the interrupt event masks. */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ent_mask.value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_event_mask(handle, OP_SET, channel, &ent_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "init rxdma event masks failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "event done: channel %d (mask 0x%016llx)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel, ent_mask.value));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Load RXDMA descriptors, buffers, mailbox, initialise the receive DMA
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * channels and enable each DMA channel.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_enable_rxdma_channel(hxgep,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States channel, rbr_p, rcr_p, mbox_p, n_init_kick);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " init enable rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "control done - channel %d cs 0x%016llx", channel, cs.value));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Initialize the receive DMA control and status register
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Note that rdc_stat HAS to be set after RBR and RCR rings are set
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cs.value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cs.bits.mex = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cs.bits.rcr_thres = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cs.bits.rcr_to = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cs.bits.rbr_empty = 1;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_init_rxdma_channel_cntl_stat(hxgep, channel, &cs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d rx_dma_cntl_stat 0x%0016llx", channel, cs.value));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "init rxdma control register failed (0x%08x channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "control done - channel %d cs 0x%016llx", channel, cs.value));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: enable done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_rxdma_start_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_stop_channel(p_hxge_t hxgep, uint16_t channel)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_status_t rs = HPI_SUCCESS;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_stat_t cs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_int_mask_t ent_mask;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_stop_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hpi handle addr $%p acc $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxgep->hpi_handle.regp, hxgep->hpi_handle.regh));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RXDMA channel */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_reset(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " reset rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: reset done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Set up the interrupt event masks. */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ent_mask.value = RDC_INT_MASK_ALL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_event_mask(handle, OP_SET, channel, &ent_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "set rxdma event masks failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: event done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Initialize the receive DMA control and status register */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cs.value = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_init_rxdma_channel_cntl_stat(hxgep, channel, &cs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_stop_channel: control "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " to default (all 0s) 0x%08x", cs.value));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_stop_channel: init rxdma"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " control register failed (0x%08x channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: control done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* disable dma channel */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_disable_rxdma_channel(hxgep, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " init enable rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: disable done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rxdma_stop_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_handle_sys_errors(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_rdc_sys_stats_t statsp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_fifo_err_stat_t stat;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = hxgep->hpi_handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs statsp = (p_hxge_rdc_sys_stats_t)&hxgep->statsp->rdc_sys_stats;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Get the error status and clear the register */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_RD64(handle, RDC_FIFO_ERR_STAT, &stat.value);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(handle, RDC_FIFO_ERR_STAT, stat.value);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (stat.bits.rx_ctrl_fifo_sec) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs statsp->ctrl_fifo_sec++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (statsp->ctrl_fifo_sec == 1)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_ctrl_fifo_sec"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (stat.bits.rx_ctrl_fifo_ded) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Global fatal error encountered */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs statsp->ctrl_fifo_ded++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, NULL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_CTRL_FIFO_DED);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rx_ctrl_fifo_ded error"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (stat.bits.rx_data_fifo_sec) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs statsp->data_fifo_sec++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (statsp->data_fifo_sec == 1)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_data_fifo_sec"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (stat.bits.rx_data_fifo_ded) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Global fatal error encountered */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs statsp->data_fifo_ded++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, NULL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_EREPORT_RDMC_DATA_FIFO_DED);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rx_data_fifo_ded error"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (stat.bits.rx_ctrl_fifo_ded || stat.bits.rx_data_fifo_ded) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_handle_sys_errors: fatal error\n"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_rx_port_fatal_err_recover(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (status == HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs FM_SERVICE_RESTORED(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_fatal_err_recover(p_hxge_t hxgep, uint16_t channel)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_handle_t handle;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hpi_status_t rs = HPI_SUCCESS;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rbr_ring_t rbrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_rcr_ring_t rcrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_mbox_t mboxp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rdc_int_mask_t ent_mask;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t dmap;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_rx_msg_t rx_msg_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint32_t hxge_port_rcr_size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t tmp;
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States int n_init_kick = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_fatal_err_recover"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Stop the dma channel waits for the stop done. If the stop done bit
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * is not set, then create an error.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs handle = HXGE_DEV_HPI_HANDLE(hxgep);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Rx DMA stop..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp = (p_rx_rbr_ring_t)hxgep->rx_rbr_rings->rbr_rings[channel];
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rcrp = (p_rx_rcr_ring_t)hxgep->rx_rcr_rings->rcr_rings[channel];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_ENTER(&rcrp->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_ENTER(&rbrp->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Disable RxDMA channel..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_disable(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_disable_rxdma_channel:failed"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto fail;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Disable RxDMA interrupt..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Disable interrupt */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ent_mask.value = RDC_INT_MASK_ALL;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_event_mask(handle, OP_SET, channel, &ent_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Set rxdma event masks failed (channel %d)", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "RxDMA channel reset..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RXDMA channel */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_reset(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Reset rxdma failed (channel %d)", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto fail;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_port_rcr_size = hxgep->hxge_port_rcr_size;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer mboxp = (p_rx_mbox_t)hxgep->rx_mbox_areas_p->rxmbox_areas[channel];
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_wr_index = (rbrp->rbb_max - 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_rd_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->comp_rd_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->comp_wt_index = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_rd_head_p = rcrp->rcr_desc_first_p =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rcr_entry_t)DMA_COMMON_VPTR(rcrp->rcr_desc);
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs rcrp->rcr_desc_rd_head_pp = rcrp->rcr_desc_first_pp =
fe930412c257f961ae67039de3b164b83717976aqs (p_rcr_entry_t)(uint32_t)DMA_COMMON_IOADDR(rcrp->rcr_desc);
fe930412c257f961ae67039de3b164b83717976aqs#else
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_rd_head_pp = rcrp->rcr_desc_first_pp =
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (p_rcr_entry_t)DMA_COMMON_IOADDR(rcrp->rcr_desc);
fe930412c257f961ae67039de3b164b83717976aqs#endif
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_last_p = rcrp->rcr_desc_rd_head_p +
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (hxge_port_rcr_size - 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp->rcr_desc_last_pp = rcrp->rcr_desc_rd_head_pp +
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (hxge_port_rcr_size - 1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States rcrp->rcr_tail_begin = DMA_COMMON_IOADDR(rcrp->rcr_desc);
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States rcrp->rcr_tail_begin = (rcrp->rcr_tail_begin & 0x7ffffULL) >> 3;
a512c5d1f2908d965887ad5494954ba2cf904bd2Qiyan Sun - Sun Microsystems - San Diego United States
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmap = (p_hxge_dma_common_t)&rcrp->rcr_desc;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs bzero((caddr_t)dmap->kaddrp, dmap->alength);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "rbr entries = %d\n",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp->rbr_max_size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States /* Count the number of buffers owned by the hardware at this moment */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < rbrp->rbr_max_size; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_msg_p = rbrp->rx_msg_ring[i];
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States if (rx_msg_p->ref_cnt == 1) {
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States n_init_kick++;
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "RxDMA channel re-start..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States /*
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * This is error recover! Some buffers are owned by the hardware and
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * the rest are owned by the apps. We should only kick in those
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * owned by the hardware initially. The apps will post theirs
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States * eventually.
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hxge_rxdma_start_channel(hxgep, channel, rbrp, rcrp, mboxp,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States n_init_kick);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /*
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The DMA channel may disable itself automatically.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The following is a work-around.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_RD64(handle, RDC_RX_CFG1, &tmp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_cfg_rdc_enable(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rs != HPI_SUCCESS) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hpi_rxdma_cfg_rdc_enable (channel %d)", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /*
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Delay a bit of time by doing reads.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer for (i = 0; i < 1024; i++) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer uint64_t value;
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RXDMA_REG_READ64(HXGE_DEV_HPI_HANDLE(hxgep),
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RDC_INT_MASK, i & 3, &value);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer }
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rbrp->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rcrp->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rxdma_fatal_err_recover"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsfail:
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rbrp->lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs MUTEX_EXIT(&rcrp->lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer "Error Recovery failed for channel(%d)", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rx_port_fatal_err_recover(p_hxge_t hxgep)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs{
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_status_t status = HXGE_OK;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs p_hxge_dma_common_t *dma_buf_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint16_t channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs int i;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs block_reset_t reset_reg;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States p_rx_rcr_ring_t rcrp;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States p_rx_rbr_ring_t rbrp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rx_port_fatal_err_recover"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "Recovering from RDC error ..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Disable RxMAC */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Disable RxMAC...\n"));
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_ENTER(&hxgep->vmac_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_rx_vmac_disable(hxgep) != HXGE_OK)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto fail;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DELAY(1000);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer /*
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Reset RDC block from PEU for this fatal error
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer */
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer reset_reg.value = 0;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer reset_reg.bits.rdc_rst = 1;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer HXGE_REG_WR32(hxgep->hpi_handle, BLOCK_RESET, reset_reg.value);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer HXGE_DELAY(1000);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Restore any common settings after PEU reset */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_rxdma_hw_start_common(hxgep) != HXGE_OK)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto fail;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Stop all RxDMA channels..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ndmas = hxgep->rx_buf_pool_p->ndmas;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dma_buf_p = hxgep->rx_buf_pool_p->dma_buf_pool_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ((p_hxge_dma_common_t)dma_buf_p[i])->dma_channel;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rcrp = hxgep->rx_rcr_rings->rcr_rings[channel];
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rbrp = rcrp->rx_rbr_p;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&rbrp->post_lock);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer /*
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * This function needs to be inside the post_lock
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_rxdma_fatal_err_recover(hxgep, channel) != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Could not recover channel %d", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&rbrp->post_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Reset RxMAC..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RxMAC */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_rx_vmac_reset(hxgep) != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_rx_port_fatal_err_recover: Failed to reset RxMAC"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto fail;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Re-initialize RxMAC..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Re-Initialize RxMAC */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((status = hxge_rx_vmac_init(hxgep)) != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_rx_port_fatal_err_recover: Failed to reset RxMAC"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto fail;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Re-enable RxMAC..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Re-enable RxMAC */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((status = hxge_rx_vmac_enable(hxgep)) != HXGE_OK) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_rx_port_fatal_err_recover: Failed to enable RxMAC"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs goto fail;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs }
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&hxgep->vmac_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset the error mask since PEU reset cleared it */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_FIFO_ERR_INT_MASK, 0x0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Recovery Successful, RxPort Restored"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rx_port_fatal_err_recover"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (HXGE_OK);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsfail:
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&hxgep->vmac_lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer "Error Recovery failed for hxge(%d)", hxgep->instance));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (status);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs}
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United Statesstatic void
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United Stateshxge_rbr_empty_restore(p_hxge_t hxgep, p_rx_rbr_ring_t rx_rbr_p)
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States{
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hpi_status_t hpi_status;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hxge_status_t status;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rdc_stat_t cs;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States p_hxge_rx_ring_stats_t rdc_stats;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rdc_stats = &hxgep->statsp->rdc_stats[rx_rbr_p->rdc];
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States /*
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * Complete the processing for the RBR Empty by:
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * 0) kicking back HXGE_RBR_EMPTY_THRESHOLD
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * packets.
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * 1) Disable the RX vmac.
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * 2) Re-enable the affected DMA channel.
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * 3) Re-enable the RX vmac.
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States */
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States /*
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * Disable the RX VMAC, but setting the framelength
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * to 0, since there is a hardware bug when disabling
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * the vmac.
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_ENTER(&hxgep->vmac_lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hxge_rx_vmac_disable(hxgep);
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer /*
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Re-arm the mex bit for interrupts to be enabled.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer */
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer cs.value = 0;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer cs.bits.mex = 1;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer RXDMA_REG_WRITE64(HXGE_DEV_HPI_HANDLE(hxgep), RDC_STAT,
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rx_rbr_p->rdc, cs.value);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hpi_status = hpi_rxdma_cfg_rdc_enable(
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States HXGE_DEV_HPI_HANDLE(hxgep), rx_rbr_p->rdc);
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States if (hpi_status != HPI_SUCCESS) {
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rdc_stats->rbr_empty_fail++;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States /* Assume we are already inside the post_lock */
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States status = hxge_rxdma_fatal_err_recover(hxgep, rx_rbr_p->rdc);
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States if (status != HXGE_OK) {
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States "hxge(%d): channel(%d) is empty.",
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hxgep->instance, rx_rbr_p->rdc));
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States }
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States }
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States /*
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States * Re-enable the RX VMAC.
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hxge_rx_vmac_enable(hxgep);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer MUTEX_EXIT(&hxgep->vmac_lock);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rdc_stats->rbr_empty_restore++;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rx_rbr_p->rbr_is_empty = B_FALSE;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States}