⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 receive.c

📁 QNX ADS BSP code for i.MX27 chips
💻 C
字号:
/* * $QNXLicenseC:  * Copyright 2007, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $ */#include <crys8900.h>#ifdef __X86__int cs8900_copy_data( void *handle, char *dst, int xoff, int xlen ){	int				iobase;	cs8900_dev_t	*cs8900	= (cs8900_dev_t *)handle;	iobase	= cs8900->iobase;	if (cs8900->mode & (CS8900_DMA | CS8900_SHARED)) {		int		rlen;		char	*src;		if (cs8900->mode & CS8900_DMA)			src	= cs8900->dmem_cptr + xoff;		else			src	= cs8900->smem + CS8900_RX_FRAME + xoff;		if (cs8900->mode & CS8900_DMA) {			rlen = ( cs8900->dmem + cs8900->dmem_size ) - src;			if (xlen > rlen) {					/* handle wrap */				if (rlen)					memcpy( dst, src, rlen );				xlen -= rlen;				src = cs8900->dmem;				dst += rlen;			}		}		else {			src	= cs8900->smem + CS8900_RX_FRAME;		}		memcpy( dst, src, xlen );	}	else {		in16s(dst, xlen >> 1, iobase + CS8900_PORT_RXTX);		if (xlen & 1)			dst[xlen-1] = in8(iobase + CS8900_PORT_RXTX);	}	return( EOK );}#endifint cs8900_receive( void *handle ){	cs8900_dev_t		*cs8900	= (cs8900_dev_t *)handle;	nic_stats_t			*gstats;	nic_ethernet_stats_t		*estats;	npkt_t				*npkt, *new;	ushort_t			status;	ushort_t			pkt_len;#ifdef __X86__	int					frame_cnt;#endif	uint32_t			iobase;	net_buf_t			*buf;	net_iov_t			*iov;	iobase	= cs8900->iobase;	gstats	= &cs8900->stats;	estats	= &cs8900->stats.un.estats;#ifdef __X86__	frame_cnt = ( cs8900->mode & CS8900_DMA ) ? cs8900_rpktpage( iobase, CS8900_DMA_FC ) : 1;	while( frame_cnt ) {		if( cs8900->mode & ( CS8900_DMA | CS8900_SHARED ) ) {			cs8900_copy_data( cs8900, (char *)&status, 0, 2 );			cs8900_copy_data( cs8900, (char *)&pkt_len, 2, 2 );		}		else {			status = inle16( iobase + CS8900_PORT_RXTX );			pkt_len	= inle16( iobase + CS8900_PORT_RXTX );		}#else		status = inle16( iobase + CS8900_PORT_RXTX );		pkt_len	= inle16( iobase + CS8900_PORT_RXTX );#endif		if( status & RXEVENT_RXOK ) {			/* grab a free pkt */			new = NULL;			npkt = cs8900->rx_pktq[cs8900->rx_cidx];			cs8900->rx_pktq[cs8900->rx_cidx] = NULL;			cs8900->rx_cidx = (cs8900->rx_cidx + 1) % cs8900->num_rx_pkts;            cs8900->stats.octets_rxed_ok += pkt_len;			npkt->framelen = pkt_len;			buf = TAILQ_FIRST(&npkt->buffers);			iov = buf->net_iov;#ifdef __X86__			cs8900_copy_data(cs8900, iov->iov_base, (cs8900->mode & CS8900_DMA) ? 4 : 0, pkt_len );#else			{				uint16_t *src = (uint16_t *)iov->iov_base;				while (pkt_len > 1) {					*src++ = inle16(iobase + CS8900_PORT_RXTX);					pkt_len -= 2;				}				if (pkt_len)					*(uint8_t *)src = inle16(iobase + CS8900_PORT_RXTX);			}#endif			gstats->rxed_ok++;			iov->iov_len = npkt->framelen;			if ((cs8900->rx_active + 1) < cs8900->rx_max) {								if(new = cs8900_alloc_npkt(cs8900, 1518)) {										atomic_add(&cs8900->rx_active, 1);				}				else {					npkt->flags |= _NPKT_NO_RES;				}			}			else {				npkt->flags |= _NPKT_NO_RES;			}			npkt->iface = 0;			if (cs8900->cfg.flags & NIC_FLAG_PROMISCUOUS)			        npkt->flags |= _NPKT_PROMISC;            pthread_mutex_unlock( &cs8900->mutex );			if (ion_add_done(cs8900->reg_hdl, npkt, cs8900) == -1) {                pthread_mutex_lock( &cs8900->mutex );				cs8900_receive_complete(npkt, cs8900, NULL);			}			else {				if(ion_rx_packets( cs8900->reg_hdl, npkt, 0, 0,						cs8900->cell, cs8900->cfg.lan, 0 ) == 0) {					ion_tx_complete( cs8900->reg_hdl, npkt) ;				}                pthread_mutex_lock( &cs8900->mutex );			}			if (new) {				npkt = new;			}			else {				npkt->flags = _NPKT_UP;				npkt->ref_cnt = 1;				npkt->req_complete = 0;			}			cs8900->rx_pktq[cs8900->rx_pidx] = npkt;			cs8900->rx_pidx = (cs8900->rx_pidx + 1) % cs8900->num_rx_pkts;		}		else {			pkt_len = 0;			if (status & RXEVENT_RUNT) 				estats->short_packets++;			if (status & RXEVENT_EXTRADATA) 				estats->oversized_packets++;			if (status & RXEVENT_CRCERR) {				if (!( status & (RXEVENT_EXTRADATA | RXEVENT_RUNT)))					estats->fcs_errors++;			}			if (status & RXEVENT_DRIBBLE)				estats->align_errors++;		}#ifdef __X86__		frame_cnt--;		if( cs8900->mode & CS8900_DMA ) {			cs8900->dmem_cptr += ( ( pkt_len + 3 + RBUF_HEAD_LEN ) & ~3 );			cs8900->dmem_cptr = cs8900->dmem + ( ( cs8900->dmem_cptr - cs8900->dmem ) % cs8900->dmem_size );			if( !frame_cnt ) {				/* release commited DMA memory */				frame_cnt = cs8900_rpktpage( iobase, CS8900_DMA_FC );			}		}	}#endif	return (1);}intcs8900_receive_complete(npkt_t *npkt, void *done_hdl, void *func_hdl){	cs8900_dev_t	*cs8900 = (cs8900_dev_t *)done_hdl;	if (npkt == NULL)		if ( cs8900->cfg.verbose )			nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "devn-crys8900: npkt is NULL");	if (npkt->org_data == NULL)		if ( cs8900->cfg.verbose )			nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "devn-crys8900: org_data is NULL");	/* Actual Rx Buffer "npkts", Only free if not low on resources */	if(!(npkt->flags & _NPKT_NO_RES)) {		ion_free(npkt->org_data);		ion_free(npkt);		atomic_sub(&cs8900->rx_active, 1);	}	return (0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -