3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * See the License for the specific language governing permissions
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * and limitations under the License.
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 * CDDL HEADER END
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Use is subject to license terms.
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Number of blocks to accumulate before re-enabling DMA
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * when we get RBR empty.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Globals: tunable parameters (/etc/system or adb)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Tunables to manage the receive buffer blocks.
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.
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Static local functions.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxdma_hw_start_common(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,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_map_rxdma_channel_buf_ring(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void hxge_unmap_rxdma_channel_buf_ring(p_hxge_t hxgep,
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,
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,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic p_rx_msg_t hxge_allocb(size_t, uint32_t, p_hxge_dma_common_t);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rx_err_evnts(p_hxge_t hxgep, uint_t index,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxbuf_index_info_init(p_hxge_t hxgep,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic hxge_status_t hxge_rxdma_fatal_err_recover(p_hxge_t hxgep,
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 HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_init_rxdma_channels"));
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer for (i = 0; i < HXGE_MAX_RDCS; i++)
fe930412c257f961ae67039de3b164b83717976aqs /* Reset RDC block from PEU to clear any previous state */
fe930412c257f961ae67039de3b164b83717976aqs HXGE_REG_WR32(hxgep->hpi_handle, BLOCK_RESET, reset_reg.value);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_uninit_rxdma_channels"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_uinit_rxdma_channels"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_init_rxdma_channel_cntl_stat(p_hxge_t hxgep, uint16_t channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_init_rxdma_channel_cntl_stat"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_control_status(handle, OP_SET, channel, cs_p);
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 HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_enable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Use configuration data composed at init time. Write to hardware the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * receive ring configurations.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_enable_rxdma_channel: mboxp $%p($%p)",
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 rs = hpi_rxdma_cfg_rdc_ring(handle, rbr_p->rdc, &rdc_desc);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Enable the timeout and threshold.
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);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Clear the rbr empty bit */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hpi_rxdma_channel_rbr_empty_clear(handle, channel);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Enable the DMA
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer rs = hpi_rxdma_cfg_rdc_enable(handle, channel);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_enable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_disable_rxdma_channel(p_hxge_t hxgep, uint16_t channel)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_disable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* disable the DMA */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_disable_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_channel_rcrflush(p_hxge_t hxgep, uint8_t channel)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_channel_rcrflush"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_channel_rcrflush"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxbuf_pp_to_vp(p_hxge_t hxgep, p_rx_rbr_ring_t rbr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs uint64_t **pkt_buf_addr_p, uint32_t *bufoffset, uint32_t *msg_index)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL, "==> hxge_rxbuf_pp_to_vp"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: buf_pp $%p btype %d",
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (found, 1 block) "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d bufinfo $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: buf_pp $%p btype %d anchor_index %d",
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 * check if this is the last buffer in the block If so,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * then reset the hint for the size;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (!found)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d",
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 /* read the DVMA address information and sort it */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (searching)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "anchor_index %d chunk_size %d dvmaaddr $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* found */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* not found: go to the right */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* not found: go to the left */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs default: /* should not come here */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (search done)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (search failed)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxbuf_pp_to_vp: (FOUND1)"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "buf_pp $%p btype %d bufsize %d anchor_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* index of the first block in this chunk */
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 offset = pktbuf_pp - dvma_addr; /* offset within the chunk */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs block_size = rbr_p->block_size; /* System block(page) size */
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 HXGE_DEBUG_MSG((hxgep, RX2_CTL, "==> getting total index"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs block_index = (offset / block_size); /* index within chunk */
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));
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs *pkt_buf_addr_p = (uint64_t *)((uint32_t)bufinfo[anchor_index].kaddr +
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs *pkt_buf_addr_p = (uint64_t *)((uint64_t)bufinfo[anchor_index].kaddr +
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 "==> hxge_rxbuf_pp_to_vp: get msg index: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "msg_index %d bufoffset_index %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX2_CTL, "<== hxge_rxbuf_pp_to_vp"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * used by quick sort (qsort) function
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * to perform comparison
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (-1);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Grabbed this sort implementation from common/syscall/avl.c
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 /* No work to do */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Sanity check on arguments */
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 * Initialize data structures required for rxdma
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * buffer dvma->vmem address lookup
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxbuf_index_info_init(p_hxge_t hxgep, p_rx_rbr_ring_t rbrp)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_rxbuf_index_info_init"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* read the DVMA address information and sort it */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* do init of the information array */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxbuf_index_info_init Sort ptrs"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* sort the array */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxbuf_index_info_init: sorted chunk %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " ioaddr $%p kaddr $%p size %x",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxbuf_index_info_init Find max iter %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_rxbuf_index_info_init"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_dump_rcr_entry(p_hxge_t hxgep, p_rcr_entry_t entry_p)
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 HXGE_DEBUG_MSG((hxgep, RX_CTL, "rcr pp 0x%llx l2 len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_stop_reinit"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rxdma_stop_reinit"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: not initialized"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: NULL ring pointer"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: NULL rbr rings pointer"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_mode: no channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_mode: channel %d (enable)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_mode: channel %d (disable)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = ((rs == HPI_SUCCESS) ? HXGE_OK : HXGE_ERROR | rs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Static functions start here.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_allocb(size_t size, uint32_t pri, p_hxge_dma_common_t dmabuf_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Allocation of a rx msg failed."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmabuf_p->kaddrp = (void *)((char *)dmabuf_p->kaddrp + size);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Allocation of a receive page failed."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_mp->rx_mblk_p = desballoc(buffer, size, pri, &hxge_mp->freeb);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL, "desballoc failed."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "offset = 0x%08X " "size = 0x%08X", hxge_mp, offset, size));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mp = desballoc(&hxge_mp->buffer[offset], size, 0, &hxge_mp->freeb);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM_CTL, "<== hxge_dupb mp = $%p", hxge_mp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (mp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_dupb_bcopy(p_rx_msg_t hxge_mp, uint_t offset, size_t size)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((NULL, MEM_CTL, "<== hxge_dupb mp = $%p", hxge_mp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs return (mp);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsvoid hxge_post_page(p_hxge_t hxgep, p_rx_rbr_ring_t rx_rbr_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_post_page(p_hxge_t hxgep, p_rx_rbr_ring_t rx_rbr_p, p_rx_msg_t rx_msg_p)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reuse this buffer */
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States atomic_dec_32(&rx_rbr_p->rbr_used);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Get the rbr header pointer and its offset index.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rx_rbr_p->rbr_desc_vp[rx_rbr_p->rbr_wr_index] = rx_msg_p->shifted_addr;
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Accumulate some buffers in the ring before re-enabling the
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * DMA channel, if rbr empty was signaled.
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);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_post_page (channel %d post_next_index %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_freeb:rx_msg_p = $%p (block pending %d)",
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 * 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.
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);
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.
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek ref_cnt = atomic_dec_32_nv(&rx_msg_p->ref_cnt);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "will free: rx_msg_p = $%p (block pending %d)",
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 atomic_dec_32(&ring->rbr_ref_cnt);
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 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 * Repost buffer.
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States if (free_state && (ref_cnt == 1)) {
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);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States rdc_stat_t cs;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * This interrupt handler is for a specific receive dma channel.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Get the control and status for this channel.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[channel];
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value);
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 (hxgep->hxge_mac_state == HXGE_MAC_STARTED)) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer /* Process error events. */
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hxge_rx_err_evnts(hxgep, channel, ldvp, cs);
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.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp = hxgep->rx_rbr_rings->rbr_rings[channel];
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Re-arm the group.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, B_TRUE,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer } else if ((ldgp->nldvs == 1) && (ring->poll_flag)) {
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Disarm the group, if we are not a shared interrupt.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, B_FALSE, 0);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Mask-off this device from the group.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_mask_set(handle, ldvp->ldv, 1);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Send the packets up the stack.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer mac_rx_ring(hxgep->mach, ring->rcr_mac_handle, mp,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer HXGE_DEBUG_MSG((NULL, RX_INT_CTL, "<== hxge_rx_intr"));
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 p_hxge_ring_handle_t ring_handle = (p_hxge_ring_handle_t)arg;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ringp = hxgep->rx_rcr_rings->rcr_rings[ring_handle->index];
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Are we already polling ?
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Enable polling
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Disable polling for a ring and enable its interrupt.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ring_handle_t ring_handle = (p_hxge_ring_handle_t)arg;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ringp = hxgep->rx_rcr_rings->rcr_rings[ring_handle->index];
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Disable polling: enable interrupt
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Get the control and status for this channel.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Rearm this logical group if this is a single device
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Enable mailbox update, to start interrupts again.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, ringp->rdc, cs.value);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Re-arm the group, since it is the only member
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * of the group.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, B_TRUE,
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Mask-on interrupts for the device and re-arm
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,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Poll 'bytes_to_pickup' bytes of message from the rx ring.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)arg;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Get the control and status for this channel.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[rhp->index];
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Get the control and status bits for the ring.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer RXDMA_REG_READ64(handle, RDC_STAT, rhp->index, &cs.value);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, rhp->index, cs.value);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Process packets.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer mblk = hxge_rx_pkts(hxgep, ring->ldvp->vdma_index,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Process Error Events.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Recovery routines will grab the RCR ring lock.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer (void) hxge_rx_err_evnts(hxgep, ldvp->vdma_index, ldvp, cs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
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)
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;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL, "==> hxge_rx_pkts:vindex %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_INT_CTL, "==> hxge_rx_pkts:index %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d, and rcr channel %d not matched.",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_pkts: START: rcr channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "head_p $%p head_pp $%p index %d ",
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_rd_head_pp, rcrp->comp_rd_index));
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;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rx_pkts:rcr channel %d qlen %d (no pkts)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rx_pkts:rcr channel %d "
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;
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;
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States qlen_hw = qlen - 1;
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 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;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer npkts = hxge_scan_for_last_eop(rcrp, rcr_desc_rd_head_p, num_rcrs);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States return (NULL);
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));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Process one completion ring entry.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp, rcr_desc_rd_head_p, &multi, &nmp, &mp_cont,
fe930412c257f961ae67039de3b164b83717976aqs "Channel %d could only read 0x%x packets, "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * message chaining modes (nemo msg chaining)
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 nrcr_read, npkt_read, rcr_desc_rd_head_pp, comp_rd_index));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Update the next read entry.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_first_p, rcrp->rcr_desc_last_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rx_pkts: (SAM, process one packet) "
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,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_rd_head_pp = rcr_desc_rd_head_pp;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer rcrp->rcr_desc_rd_head_p = rcr_desc_rd_head_p;
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer if ((hxgep->intr_timeout != rcrp->intr_timeout) ||
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer (hxgep->intr_threshold != rcrp->intr_threshold)) {
676f04004b15fc2872dfb0b7349d2d821a6eaa31Michael Speer if (hxgep->rdc_first_intr[channel] && (npkt_read > 0)) {
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer RXDMA_REG_WRITE64(handle, RDC_STAT, channel, pktcs.value);
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));
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
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 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 rcr_entry = *((uint64_t *)rcr_desc_rd_head_p);
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 if (!(rcr_entry & RCR_MULTI_MASK))
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States pkts++;
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);
41307000fb6264427cd9b68419c13b879e83e7d3Qiyan Sun - Sun Microsystems - San Diego United States return (pkts);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
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)
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States boolean_t is_tcp_udp = B_FALSE;
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 HXGE_DEBUG_MSG((hxgep, RX2_CTL, "==> hxge_receive_packet"));
fe930412c257f961ae67039de3b164b83717976aqs /* Verify the content of the rcr_entry for a hardware bug workaround */
fe930412c257f961ae67039de3b164b83717976aqs if ((rcr_entry == 0x0) || (rcr_entry == RCR_ENTRY_PATTERN)) {
fe930412c257f961ae67039de3b164b83717976aqs "Channel %d invalid RCR entry 0x%llx found, returning\n",
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States pkt_type = (rcr_entry & RCR_PKT_TYPE_MASK);
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 * Hardware does not strip the CRC due bug ID 11451 where
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the hardware mis handles minimum size packets.
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp = (uint64_t *)((rcr_entry & RCR_PKT_BUF_ADDR_MASK) <<
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 ",
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States multi, error_type, pktbufsz_type));
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 "==> (rbr) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* get the stats ptr */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_receive_packet: failed: l2 length is 0."));
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 <<
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pkt_buf_addr_pp = (uint64_t *)((uint64_t)pkt_buf_addr_pp <<
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: first entry 0x%016llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "pkt_buf_addr_pp $%p l2_len %d hdr %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 1) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
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 "==> (rbr 2) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_receive_packet: found vaddr failed %d", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 3) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 4 msgindex %d) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: FATAL msg_index (%d) "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "should be smaller than tnblocks (%d)\n",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> (rbr 4 msgindex %d) hxge_receive_packet: entry 0x%0llx "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "full pkt_buf_addr_pp $%p l2_len %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: after first dump:usage count"));
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States atomic_inc_32(&rx_rbr_p->rbr_used);
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States if (rx_rbr_p->rbr_consumed <
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 } else {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: buf %d (single block) ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Buffer can be reused once the free function is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (rx_msg_p->cur_usage_cnt == rx_msg_p->max_usage_cnt) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "msgbuf index = %d l2len %d bytes usage %d max_usage %d ",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Update error stats */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_FM_REPORT_ERROR(hxgep, NULL, HXGE_FM_EREPORT_RDMC_RCR_ERR);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_receive_packet: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_receive_packet: channel %d"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Update and repost buffer block if max usage count is
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * reached.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_receive_packet: DMA sync second "));
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;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * For loaned up buffers, the driver reference count
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * will be incremented first and then the free state.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((nmp = hxge_dupb(rx_msg_p, buf_offset, bsize)) != NULL) {
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 cmn_err(CE_WARN, "!hxge_receive_packet: update stats (error)");
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 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++;
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 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 * Update stats and hardware checksuming.
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 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 "==> 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 HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_receive_packet: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "multi %d nmp 0x%016llx *mp 0x%016llx *mp_cont 0x%016llx",
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speerhxge_rx_rbr_empty_recover(p_hxge_t hxgep, uint8_t channel)
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer rcrp = hxgep->rx_rcr_rings->rcr_rings[channel];
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Wait for the channel to be quiet
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer (void) hpi_rxdma_cfg_rdc_wait_for_qst(handle, channel);
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * Post page will accumulate some buffers before re-enabling
b83cd2c35abe58abb09c73f2ef35426f1384ad46Michael Speer * the DMA channel.
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;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rx_err_evnts(p_hxge_t hxgep, uint_t index, p_hxge_ldv_t ldvp,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_rx_err_evnts"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if ((cs.bits.rcr_shadow_par_err) || (cs.bits.rbr_prefetch_par_err)) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rx_err_evnts(channel %d): "
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 rcrp = hxgep->rx_rcr_rings->rcr_rings[channel];
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States rbrp = rcrp->rx_rbr_p;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rx_err_evnts: fatal error on Channel #%d\n",
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 */
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&rbrp->post_lock);
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_rx_err_evnts"));
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;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma: buf not allocated"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma: no dma allocated"));
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;
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 * Map descriptors from the buffer polls for each dam channel.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer if (((p_hxge_dma_common_t)dma_buf_p[i]) == NULL) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Set up and prepare buffer blocks, descriptors and mailbox.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ((p_hxge_dma_common_t)dma_buf_p[i])->dma_channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma: unmap rbr,rcr (status 0x%x channel %d i %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (; i >= 0; i--) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ((p_hxge_dma_common_t)dma_buf_p[i])->dma_channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma: (status 0x%x channel %d)", status, channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_unmap_rxdma"));
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;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma: NULL buf pointers"));
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer "<== hxge_unmap_rxdma: NULL pointers"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma: no channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs channel = ((p_hxge_dma_common_t)dma_buf_p[i])->dma_channel;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma (ndmas %d) channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_unmap_rxdma"));
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 * Set up and prepare buffer blocks, descriptors and mailbox.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Receive buffer blocks
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel (channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Receive block ring, completion ring and mailbox.
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer dma_rbr_cntl_p, dma_rcr_cntl_p, dma_mbox_cntl_p,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel (channel %d): "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Free rbr, rcr */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel: free rbr/rcr (status 0x%x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_unmap_rxdma_channel_cfg_ring(hxgep, *rcr_p, *rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Free buffer blocks */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel: free rx buffers"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "(hxgep 0x%x status 0x%x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel: (hxgep 0x%x status 0x%x channel %d)",
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 * unmap receive block ring, completion ring and mailbox.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (void) hxge_unmap_rxdma_channel_cfg_ring(hxgep, rcr_p, rx_mbox_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* unmap buffer blocks */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_unmap_rxdma_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
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 "==> hxge_map_rxdma_channel_cfg_ring"));
8ad8db65d4781f61f1fd519144f555e6045100e1Michael Speer * Map in the receive block ring
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_setup_dma_common(dmap, cntl_dmap, rbrp->rbb_max, 4);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Zero out buffer block ring descriptors.
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 /* XXXX: how to choose packet buffer sizes */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * For each buffer block, enter receive block address to the ring.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring: channel %d "
57c5371a68b0454ec94109f38027ab6099bad130Qiyan Sun - Sun Microsystems - San Diego United States rbrp->rbr_used = 0;
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 * Do bcopy on every packet once the hi threshold is reached.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* default it to use hi */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Do not do bcopy at all */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Do not do bcopy at all */
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 /* Map in the receive completion ring */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rcrp = (p_rx_rcr_ring_t)KMEM_ZALLOC(sizeof (rx_rcr_ring_t), KM_SLEEP);
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs (p_rcr_entry_t)(uint32_t)DMA_COMMON_IOADDR(rcrp->rcr_desc);
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;
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 * Zero out buffer block ring descriptors.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfga_p->value |= ((uint64_t)rcrp->comp_size << RCRCFIG_A_LEN_SHIF);
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 /* Map in the mailbox */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mboxp = (p_rx_mbox_t)KMEM_ZALLOC(sizeof (rx_mbox_t), KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs hxge_setup_dma_common(dmap, cntl_dmap, 1, sizeof (rxdma_mailbox_t));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "channel %d cfg1 0x%016llx cfig2 0x%016llx cookie 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmaaddrp = (uint32_t)((dmap->dma_cookie.dmac_laddress >> 32) & 0xfff);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs dmaaddrp = (uint32_t)(dmap->dma_cookie.dmac_laddress & 0xffffffff);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs cfig2_p->bits.mbaddr_l = (dmaaddrp >> RXDMA_CFIG2_MBADDR_L_SHIFT);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_cfg_ring: channel %d damaddrp $%p "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "cfg1 0x%016llx cfig2 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel_cfg_ring status 0x%08x", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma_channel_cfg_ring: channel %d", rcr_p->rdc));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_cfg_ring"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_map_rxdma_channel_buf_ring(p_hxge_t hxgep, uint16_t channel,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_buf_ring: channel %d", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_map_rxdma_channel_buf_ring: channel %d to map %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "chunks bufp 0x%016llx", channel, num_chunks, dma_bufp));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_map_rxdma_channel_buf_ring: channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "bufp 0x%016llx nblocks %d nmsgs %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel_buf_ring: channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rbrp = (p_rx_rbr_ring_t)KMEM_ZALLOC(sizeof (rx_rbr_ring_t), KM_SLEEP);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info = (rxring_info_t *)KMEM_ZALLOC(sizeof (rxring_info_t),
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Buffer sizes: 256, 1K, and 2K.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Blk 0 size.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->pkt_buf_size0_bytes = RBR_BUFSZ0_256_BYTES;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Blk 1 size.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Blk 2 size.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->pkt_buf_size2_bytes = RBR_BUFSZ2_2K_BYTES;
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer rbrp->block_size = hxgep->rx_default_block_size;
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 * 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.
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs ring_info->buffer[i].dvma_addr = (uint32_t)dma_bufp->ioaddr_pp;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ring_info->buffer[i].dvma_addr = (uint64_t)dma_bufp->ioaddr_pp;
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_map_rxdma_channel_buf_ring: map channel %d "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "chunk %d nblocks %d chunk_size %x block_size 0x%x "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* loop over blocks within a chunk */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (j = 0; j < nblocks; j++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "allocb failed (index %d i %d j %d)",
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 "hxge_map_rxdma_channel_buf_ring: done buf init "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, " hxge_map_rxdma_channel_buf_ring: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Finally, permit hxge_freeb() to call hxge_post_page().
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_map_rxdma_channel_buf_ring: failed channel (0x%x)",
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States freeb(rx_msg_p->rx_mblk_p);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_map_rxdma_channel_buf_ring status 0x%08x", status));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma_channel_buf_ring"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_buf_ring: NULL rbrp"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_unmap_rxdma_channel_buf_ring: channel %d", rbr_p->rdc));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_buf_ring: "
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 " hxge_unmap_rxdma_channel_buf_ring: "
14648441d6138f071fa68189d8b67500158ef61dQiyan Sun - Sun Microsystems - San Diego United States freeb(rx_msg_p->rx_mblk_p);
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 /* This is the normal state of affairs. */
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 "unmap_rxdma_buf_ring: %d %s outstanding.",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_unmap_rxdma_channel_buf_ring"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start_common"));
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 HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start_common"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_start: NULL ring pointers"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (ndmas == 0) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_start: no dma channel allocated"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub the RDC Rx DMA Prefetch Buffer Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 128; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub Rx DMA Shadow Tail Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 64; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub Rx DMA Control Fifo Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 512; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Scrub Rx DMA Data Fifo Command.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < 1536; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Reset the FIFO Error Stat.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_FIFO_ERR_STAT, 0xFF);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Set the error mask to receive interrupts */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_FIFO_ERR_INT_MASK, 0x0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_start (ndmas %d) channel %d",
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States (p_rx_mbox_t)rx_mbox_p[i], rbr_rings[i]->rbb_max);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_start: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_rbr_rings 0x%016llx rings 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_start: disable "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (; i >= 0; i--) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qsstatic void
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_stop"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_stop: NULL ring pointers"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "<== hxge_rxdma_hw_stop: no dma channel allocated"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs for (i = 0; i < ndmas; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_hw_stop (ndmas %d) channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_hw_stop: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_rbr_rings 0x%016llx rings 0x%016llx",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_rxdma_hw_stop"));
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 HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hpi handle addr $%p acc $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RXDMA channel */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "reset rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: reset done: channel %d", channel));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Initialize the RXDMA channel specific FZC control configurations.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * These FZC registers are pertaining to each RX channel (logical
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "init fzc rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: fzc done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Zero out the shadow and prefetch ram.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: ram done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Set up the interrupt event masks. */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_event_mask(handle, OP_SET, channel, &ent_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "init rxdma event masks failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "event done: channel %d (mask 0x%016llx)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Load RXDMA descriptors, buffers, mailbox, initialise the receive DMA
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * channels and enable each DMA channel.
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States channel, rbr_p, rcr_p, mbox_p, n_init_kick);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " init enable rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "control done - channel %d cs 0x%016llx", channel, cs.value));
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 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 "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "init rxdma control register failed (0x%08x channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_rxdma_start_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "control done - channel %d cs 0x%016llx", channel, cs.value));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_start_channel: enable done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_rxdma_start_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_stop_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hpi handle addr $%p acc $%p",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RXDMA channel */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " reset rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: reset done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Set up the interrupt event masks. */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_event_mask(handle, OP_SET, channel, &ent_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "set rxdma event masks failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: event done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Initialize the receive DMA control and status register */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs status = hxge_init_rxdma_channel_cntl_stat(hxgep, channel, &cs);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_stop_channel: control "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_stop_channel: init rxdma"
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " control register failed (0x%08x channel %d",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: control done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* disable dma channel */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_stop_channel: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " init enable rxdma failed (0x%08x channel %d)",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_stop_channel: disable done"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rxdma_stop_channel"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs statsp = (p_hxge_rdc_sys_stats_t)&hxgep->statsp->rdc_sys_stats;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Get the error status and clear the register */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_ctrl_fifo_sec"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Global fatal error encountered */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rx_ctrl_fifo_ded error"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "rx_data_fifo_sec"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Global fatal error encountered */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "==> hxge_rxdma_handle_sys_errors: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "fatal error: rx_data_fifo_ded error"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (stat.bits.rx_ctrl_fifo_ded || stat.bits.rx_data_fifo_ded) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs " hxge_rxdma_handle_sys_errors: fatal error\n"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qshxge_rxdma_fatal_err_recover(p_hxge_t hxgep, uint16_t channel)
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States int n_init_kick = 0;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_rxdma_fatal_err_recover"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Stop the dma channel waits for the stop done. If the stop done bit
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * is not set, then create an error.
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 HXGE_DEBUG_MSG((hxgep, RX_CTL, "Disable RxDMA channel..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_disable_rxdma_channel:failed"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Disable RxDMA interrupt..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Disable interrupt */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs rs = hpi_rxdma_event_mask(handle, OP_SET, channel, &ent_mask);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "RxDMA channel reset..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RXDMA channel */
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer mboxp = (p_rx_mbox_t)hxgep->rx_mbox_areas_p->rxmbox_areas[channel];
fe930412c257f961ae67039de3b164b83717976aqs#if defined(__i386)
fe930412c257f961ae67039de3b164b83717976aqs (p_rcr_entry_t)(uint32_t)DMA_COMMON_IOADDR(rcrp->rcr_desc);
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;
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States /* Count the number of buffers owned by the hardware at this moment */
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++;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "RxDMA channel re-start..."));
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.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer (void) hxge_rxdma_start_channel(hxgep, channel, rbrp, rcrp, mboxp,
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States n_init_kick);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The DMA channel may disable itself automatically.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The following is a work-around.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer * Delay a bit of time by doing reads.
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer for (i = 0; i < 1024; i++) {
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rxdma_fatal_err_recover"));
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer "Error Recovery failed for channel(%d)", channel));
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 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 /* Disable RxMAC */
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Reset RDC block from PEU for this fatal error
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer HXGE_REG_WR32(hxgep->hpi_handle, BLOCK_RESET, reset_reg.value);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Restore any common settings after PEU reset */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Stop all RxDMA channels..."));
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 MUTEX_ENTER(&rbrp->post_lock);
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * This function needs to be inside the post_lock
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (hxge_rxdma_fatal_err_recover(hxgep, channel) != HXGE_OK) {
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&rbrp->post_lock);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset RxMAC */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_rx_port_fatal_err_recover: Failed to reset RxMAC"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "Re-initialize RxMAC..."));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Re-Initialize RxMAC */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_rx_port_fatal_err_recover: Failed to reset RxMAC"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Re-enable RxMAC */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "hxge_rx_port_fatal_err_recover: Failed to enable RxMAC"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs /* Reset the error mask since PEU reset cleared it */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_REG_WR64(hxgep->hpi_handle, RDC_FIFO_ERR_INT_MASK, 0x0);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "Recovery Successful, RxPort Restored"));
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_rx_port_fatal_err_recover"));
6ffca240bba331a8b22ff3ce47de58da6a205843Michael Speer "Error Recovery failed for hxge(%d)", hxgep->instance));
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 hpi_status_t hpi_status;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States hxge_status_t status;
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States p_hxge_rx_ring_stats_t rdc_stats;
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 * 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 * 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.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer * Re-arm the mex bit for interrupts to be enabled.
f043ebed17bd76d258204de498eeedb6f8f7eebfMichael Speer RXDMA_REG_WRITE64(HXGE_DEV_HPI_HANDLE(hxgep), RDC_STAT,
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 /* 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 * Re-enable the RX VMAC.