📄 transmit.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>extern int cs8900_variant_load(void *handle);#if 0npkt_t *cs8900_defrag(void *handle, npkt_t *npkt){ npkt_t *dpkt; char *dst; net_iov_t *iov; net_buf_t *dov, *buf; int totalLen; int i, len; cs8900_dev_t *cs8900 = (cs8900_dev_t *)handle; dpkt = NULL; /* Do some checks */ for( totalLen = 0, buf = TAILQ_FIRST(&npkt->buffers); buf != NULL; buf = TAILQ_NEXT( buf, ptrs ) ) { for( i = 0, iov = buf->net_iov; i < buf->niov; i++, iov++ ) { totalLen += iov->iov_len; } } if( totalLen <= 1520 ) { if((dpkt = cs8900_alloc_npkt(cs8900, npkt->framelen)) != NULL) { dpkt->framelen = npkt->framelen; dpkt->next = NULL; dov = TAILQ_FIRST(&dpkt->buffers); dst = dov->net_iov->iov_base; for( len = 0, buf = TAILQ_FIRST( &npkt->buffers ); buf != NULL; buf = TAILQ_NEXT( buf, ptrs ) ) { for( i = 0, iov = buf->net_iov; i < buf->niov; i++, iov++ ) { memcpy( dst, iov->iov_base, iov->iov_len ); dst += iov->iov_len; len += iov->iov_len; } } dov->net_iov->iov_len = len; } } if( npkt->flags & _NPKT_NO_RES ) { ion_free( npkt->org_data ); ion_free( npkt ); } else { pthread_mutex_unlock( &cs8900->mutex ); ion_tx_complete( cs8900->reg_hdl, npkt ); pthread_mutex_lock( &cs8900->mutex ); } return (dpkt);}#endifint cs8900_send( void *handle ){ int iobase; cs8900_dev_t *cs8900 = (cs8900_dev_t *)handle; iobase = cs8900->iobase; /* load up the card */ while( cs8900->nhead && !cs8900->tx_bid && !cs8900->tx_active ) { outle16( iobase + CS8900_PORT_TXCMD, TXCMD_AFTER_1021 ); outle16( iobase + CS8900_PORT_TXLEN, cs8900->nhead->framelen ); /* see if the chip has allocated memory for the packet */ if( ( cs8900_rpktpage( iobase, CS8900_BUSST ) & BUSSTAT_RDY4TXNOW ) == 0 ) { cs8900->tx_bid = 1; break; } cs8900_variant_load( cs8900 ); } return( 0 ); }/* entry from netio */int cs8900_send_packets( npkt_t *npkt, void *hdl ){ cs8900_dev_t *cs8900 = (cs8900_dev_t *)hdl; net_buf_t *buf; io_net_msg_join_mcast_t *msg; uint32_t crc; if( npkt->flags & _NPKT_MSG ) { buf = TAILQ_FIRST( &npkt->buffers ); if( buf != NULL ) { /* If selective multicasting worked on this card this is where it would happen */ msg = (io_net_msg_join_mcast_t *)buf->net_iov->iov_base; if( msg ) { pthread_mutex_lock( &cs8900->mutex ); switch( msg->type ) { case _IO_NET_JOIN_MCAST: crc = nic_calc_crc_le( LLADDR( &msg->mc_min.addr_dl ), 6 ); crc = crc >> 26; cs8900->multicast_counts[crc] ++; if( cs8900->multicast_counts[crc] == 1 ) { cs8900_setup_multicast( cs8900 ); } break; case _IO_NET_REMOVE_MCAST: crc = nic_calc_crc_le( LLADDR( &msg->mc_min.addr_dl ), 6 ); crc = crc >> 26; if( cs8900->multicast_counts[crc] > 0 ) { cs8900->multicast_counts[crc] --; } if( cs8900->multicast_counts[crc] == 0 ) { cs8900_setup_multicast( cs8900 ); } break; default: if( cs8900->cfg.verbose ) { nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "devn-crys8900: Message type not supported." ); } break; } pthread_mutex_unlock( &cs8900->mutex ); } } if( npkt->flags & _NPKT_NO_RES ) { ion_free(npkt->org_data); ion_free( npkt ); } else { ion_tx_complete(cs8900->reg_hdl, npkt); } } else { pthread_mutex_lock( &cs8900->mutex ); if( cs8900->ntail ) { cs8900->ntail->next = npkt; } else { cs8900->nhead = npkt; } while( npkt->next ) { npkt = npkt->next; } cs8900->ntail = npkt; cs8900_send( cs8900 ); pthread_mutex_unlock( &cs8900->mutex ); } return( EOK );}int cs8900_transmit_complete( void *handle ){ int status; cs8900_dev_t *cs8900 = (cs8900_dev_t *)handle; nic_stats_t *gstats; nic_ethernet_stats_t *estats; status = cs8900->istat; gstats = &cs8900->stats; estats = &cs8900->stats.un.estats; cs8900->tx_active = 0; if( status & TXEVENT_TXOK ) { gstats->txed_ok++; } if( status & TXEVENT_NOCAR ) { estats->no_carrier++; } if( status & TXEVENT_SQEERR ) { estats->sqe_errors++; } if( status & TXEVENT_OOWC ) { estats->single_collisions++; } if( status & TXEVENT_MAXCOL ) { estats->xcoll_aborted++; } cs8900_send( cs8900 ); return( 0 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -