<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=ks_c_5601-1987">
<META content="MSHTML 6.00.2600.0" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT size=2>Hello...<BR> <BR>I copy FreeBSD's RTL8139C(not C+) driver 
and paste to RTEMS.<BR>It's looks like working, but I can't say 
positively.<BR>Anyone who want run RTEMS(in pc386 target) with RTL8139C(not C+) 
network interface is, please help me.<BR>I attach code.<BR> <BR>PS.<BR>I 
must use LonWorks PC104 card & IEEE1394 PC104 card in my SBC. So I have not 
enough space in my SBC & must use RTL 8139C(not C+) network 
interface(--).<BR> <BR>***** code start *****<BR> <BR>/*<BR> * 
Copyright (c) 1997, 1998<BR> * Bill Paul <<A 
href="mailto:wpaul@ctr.columbia.edu">wpaul@ctr.columbia.edu</A>>.  All 
rights reserved.<BR> *<BR> * Redistribution and use in source and 
binary forms, with or without<BR> * modification, are permitted provided 
that the following conditions<BR> * are met:<BR> * 1. Redistributions 
of source code must retain the above copyright<BR> *    
notice, this list of conditions and the following disclaimer.<BR> * 2. 
Redistributions in binary form must reproduce the above 
copyright<BR> *    notice, this list of conditions and the 
following disclaimer in the<BR> *    documentation and/or 
other materials provided with the distribution.<BR> * 3. All advertising 
materials mentioning features or use of this 
software<BR> *    must display the following 
acknowledgement:<BR> * This product includes software developed by Bill 
Paul.<BR> * 4. Neither the name of the author nor the names of any 
co-contributors<BR> *    may be used to endorse or promote 
products derived from this software<BR> *    without 
specific prior written permission.<BR> *<BR> * THIS SOFTWARE IS 
PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND<BR> * ANY EXPRESS OR 
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<BR> * IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<BR> * 
ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS 
HEAD<BR> * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR<BR> * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT OF<BR> * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
PROFITS; OR BUSINESS<BR> * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
OF LIABILITY, WHETHER IN<BR> * CONTRACT, STRICT LIABILITY, OR TORT 
(INCLUDING NEGLIGENCE OR OTHERWISE)<BR> * ARISING IN ANY WAY OUT OF THE USE 
OF THIS SOFTWARE, EVEN IF ADVISED OF<BR> * THE POSSIBILITY OF SUCH 
DAMAGE.<BR> *<BR> * $FreeBSD: src/sys/pci/if_rl.c,v 1.38.2.10 
2002/02/15 04:21:20 silby Exp $<BR> */<BR> <BR>/*<BR> * RealTek 
8129/8139 PCI NIC driver<BR> *<BR> * Supports several extremely cheap 
PCI 10/100 adapters based on<BR> * the RealTek chipset. Datasheets can be 
obtained from<BR> * <A 
href="http://www.realtek.com.tw">www.realtek.com.tw</A>.<BR> *<BR> * 
Written by Bill Paul <<A 
href="mailto:wpaul@ctr.columbia.edu">wpaul@ctr.columbia.edu</A>><BR> * 
Electrical Engineering Department<BR> * Columbia University, New York 
City<BR> */<BR> <BR>/*<BR> * The RealTek 8139 PCI NIC redefines 
the meaning of 'low end.' This is<BR> * probably the worst PCI ethernet 
controller ever made, with the possible<BR> * exception of the FEAST chip 
made by SMC. The 8139 supports bus-master<BR> * DMA, but it has a terrible 
interface that nullifies any performance<BR> * gains that bus-master DMA 
usually offers.<BR> *<BR> * For transmission, the chip offers a series 
of four TX descriptor<BR> * registers. Each transmit frame must be in a 
contiguous buffer, aligned<BR> * on a longword (32-bit) boundary. This 
means we almost always have to<BR> * do mbuf copies in order to transmit a 
frame, except in the unlikely<BR> * case where a) the packet fits into a 
single mbuf, and b) the packet<BR> * is 32-bit aligned within the mbuf's 
data area. The presence of only<BR> * four descriptor registers means that 
we can never have more than four<BR> * packets queued for transmission at 
any one time.<BR> *<BR> * Reception is not much better. The driver has 
to allocate a single large<BR> * buffer area (up to 64K in size) into which 
the chip will DMA received<BR> * frames. Because we don't know where within 
this region received packets<BR> * will begin or end, we have no choice but 
to copy data from the buffer<BR> * area into mbufs in order to pass the 
packets up to the higher protocol<BR> * levels.<BR> *<BR> * It's 
impossible given this rotten design to really achieve decent<BR> * 
performance at 100Mbps, unless you happen to have a 400Mhz PII or<BR> * 
some equally overmuscled CPU to drive it.<BR> *<BR> * On the bright 
side, the 8139 does have a built-in PHY, although<BR> * rather than using 
an MDIO serial interface like most other NICs, the<BR> * PHY registers are 
directly accessible through the 8139's register<BR> * space. The 8139 
supports autonegotiation, as well as a 64-bit multicast<BR> * 
filter.<BR> *<BR> * The 8129 chip is an older version of the 8139 that 
uses an external PHY<BR> * chip. The 8129 has a serial MDIO interface for 
accessing the MII where<BR> * the 8139 lets you directly access the 
on-board PHY registers. We need<BR> * to select which interface to use 
depending on the chip type.<BR> */<BR> <BR>/* <BR> * RTL8139C(not 
C+) RTEMS driver<BR> * It's only TEST!!! <BR> * Bae daeho <<A 
href="mailto:baedo@palgong.knu.ac.kr">baedo@palgong.knu.ac.kr</A>><BR> */<BR> <BR>#include 
<bsp.h><BR> <BR>#include <pcibios.h><BR> <BR>#include 
<stdio.h><BR>#include <assert.h><BR> <BR>#include 
<rtems/error.h><BR>#include 
<rtems/rtems_bsdnet.h><BR> <BR>#include 
<sys/param.h><BR>#include <sys/mbuf.h><BR>#include 
<sys/socket.h><BR>#include <sys/sockio.h><BR> <BR>#include 
<net/if.h><BR> <BR>#include <netinet/in.h><BR>#include 
<netinet/if_ether.h><BR> <BR>#include <irq.h><BR> <BR>/* 
from NetBSD RTK8139 driver */<BR>#define PCI_VENDOR_ID_RTK  
0x10EC<BR>#define PCI_DEVICE_ID_RTK_8139 0x8139<BR> <BR>#define RTK_IDR0 
0x0000  /* ID register 0 (station addr) */<BR>#define RTK_IDR1 0x0001  
/* Must use 32-bit accesses (?) */<BR>#define RTK_IDR2 0x0002<BR>#define 
RTK_IDR3 0x0003<BR>#define RTK_IDR4 0x0004<BR>#define RTK_IDR5 
0x0005<BR>     /* 0006-0007 reserved */<BR>#define RTK_MAR0 
0x0008  /* Multicast hash table */<BR>#define RTK_MAR1 0x0009<BR>#define 
RTK_MAR2 0x000A<BR>#define RTK_MAR3 0x000B<BR>#define RTK_MAR4 0x000C<BR>#define 
RTK_MAR5 0x000D<BR>#define RTK_MAR6 0x000E<BR>#define RTK_MAR7 
0x000F<BR> <BR>#define RTK_TXSTAT0 0x0010  /* status of TX descriptor 
0 */<BR>#define RTK_TXSTAT1 0x0014  /* status of TX descriptor 1 
*/<BR>#define RTK_TXSTAT2 0x0018  /* status of TX descriptor 2 
*/<BR>#define RTK_TXSTAT3 0x001C  /* status of TX descriptor 3 
*/<BR> <BR>#define RTK_TXADDR0 0x0020  /* address of TX descriptor 0 
*/<BR>#define RTK_TXADDR1 0x0024  /* address of TX descriptor 1 
*/<BR>#define RTK_TXADDR2 0x0028  /* address of TX descriptor 2 
*/<BR>#define RTK_TXADDR3 0x002C  /* address of TX descriptor 3 
*/<BR> <BR>#define RTK_RXADDR  0x0030 /* RX ring start address 
*/<BR>#define RTK_RX_EARLY_BYTES 0x0034 /* RX early byte count */<BR>#define 
RTK_RX_EARLY_STAT 0x0036 /* RX early status */<BR>#define RTK_COMMAND 
0x0037  /* command register */<BR>#define RTK_CURRXADDR 0x0038  /* 
current address of packet read */<BR>#define RTK_CURRXBUF 0x003A  /* 
current RX buffer address */<BR>#define RTK_IMR  0x003C  /* interrupt 
mask register */<BR>#define RTK_ISR  0x003E  /* interrupt status 
register */<BR>#define RTK_TXCFG 0x0040  /* transmit config */<BR>#define 
RTK_RXCFG 0x0044  /* receive config */<BR>#define RTK_TIMERCNT 0x0048  
/* timer count register */<BR>#define RTK_MISSEDPKT 0x004C  /* missed 
packet counter */<BR>#define RTK_EECMD 0x0050  /* EEPROM command register 
*/<BR>#define RTK_CFG0 0x0051  /* config register #0 */<BR>#define RTK_CFG1 
0x0052  /* config register #1 */<BR>     /* 0053-0057 
reserved */<BR>#define RTK_MEDIASTAT 0x0058  /* media status register 
(8139) */<BR>     /* 0059-005A reserved */<BR>#define 
RTK_MII  0x005A  /* 8129 chip only */<BR>#define RTK_HALTCLK 
0x005B<BR>#define RTK_MULTIINTR 0x005C  /* multiple interrupt */<BR>#define 
RTK_PCIREV 0x005E  /* PCI revision value */<BR>     /* 
005F reserved */<BR>#define RTK_TXSTAT_ALL 0x0060  /* TX status of all 
descriptors */<BR> <BR>/* Direct PHY access registers only available on 
8139 */<BR>#define RTK_BMCR 0x0062  /* PHY basic mode control */<BR>#define 
RTK_BMSR 0x0064  /* PHY basic mode status */<BR>#define RTK_ANAR 
0x0066  /* PHY autoneg advert */<BR>#define RTK_LPAR 0x0068  /* PHY 
link partner ability */<BR>#define RTK_ANER 0x006A  /* PHY autoneg 
expansion */<BR> <BR>#define RTK_DISCCNT 0x006C  /* disconnect counter 
*/<BR>#define RTK_FALSECAR 0x006E  /* false carrier counter */<BR>#define 
RTK_NWAYTST 0x0070  /* NWAY test register */<BR>#define RTK_RX_ER 
0x0072  /* RX_ER counter */<BR>#define RTK_CSCFG 0x0074  /* CS 
configuration register */<BR> </FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>/*<BR> * TX config register bits<BR> */<BR>#define 
RTK_TXCFG_CLRABRT 0x00000001 /* retransmit aborted pkt */<BR>#define 
RTK_TXCFG_MAXDMA 0x00000700 /* max DMA burst size */<BR>#define 
RTK_TXCFG_CRCAPPEND 0x00010000 /* CRC append (0 = yes) */<BR>#define 
RTK_TXCFG_LOOPBKTST 0x00060000 /* loopback test */<BR>#define 
RTK_TXCFG_IFG  0x03000000 /* interframe gap */<BR> <BR>#define 
RTK_TXDMA_16BYTES 0x00000000<BR>#define RTK_TXDMA_32BYTES 0x00000100<BR>#define 
RTK_TXDMA_64BYTES 0x00000200<BR>#define RTK_TXDMA_128BYTES 0x00000300<BR>#define 
RTK_TXDMA_256BYTES 0x00000400<BR>#define RTK_TXDMA_512BYTES 
0x00000500<BR>#define RTK_TXDMA_1024BYTES 0x00000600<BR>#define 
RTK_TXDMA_2048BYTES 0x00000700<BR> <BR>/*<BR> * Transmit descriptor 
status register bits.<BR> */<BR>#define RTK_TXSTAT_LENMASK 
0x00001FFF<BR>#define RTK_TXSTAT_OWN  0x00002000<BR>#define 
RTK_TXSTAT_TX_UNDERRUN 0x00004000<BR>#define RTK_TXSTAT_TX_OK 
0x00008000<BR>#define RTK_TXSTAT_EARLY_THRESH 0x003F0000<BR>#define 
RTK_TXSTAT_COLLCNT 0x0F000000<BR>#define RTK_TXSTAT_CARR_HBEAT 
0x10000000<BR>#define RTK_TXSTAT_OUTOFWIN 0x20000000<BR>#define 
RTK_TXSTAT_TXABRT 0x40000000<BR>#define RTK_TXSTAT_CARRLOSS 
0x80000000<BR> <BR>/*<BR> * Interrupt status register 
bits.<BR> */<BR>#define RTK_ISR_RX_OK  0x0001<BR>#define 
RTK_ISR_RX_ERR  0x0002<BR>#define RTK_ISR_TX_OK  0x0004<BR>#define 
RTK_ISR_TX_ERR  0x0008<BR>#define RTK_ISR_RX_OVERRUN 0x0010<BR>#define 
RTK_ISR_PKT_UNDERRUN 0x0020<BR>#define RTK_ISR_FIFO_OFLOW 0x0040 /* 8139 only 
*/<BR>#define RTK_ISR_PCS_TIMEOUT 0x4000 /* 8129 only */<BR>#define 
RTK_ISR_SYSTEM_ERR 0x8000<BR> <BR>#define RTK_INTRS 
\<BR> (RTK_ISR_TX_OK|RTK_ISR_RX_OK|RTK_ISR_RX_ERR|RTK_ISR_TX_ERR| 
\<BR> RTK_ISR_RX_OVERRUN|RTK_ISR_PKT_UNDERRUN|RTK_ISR_FIFO_OFLOW| 
\<BR> RTK_ISR_PCS_TIMEOUT|RTK_ISR_SYSTEM_ERR)<BR> <BR>/*<BR> * 
Media status register. (8139 only)<BR> */<BR>#define RTK_MEDIASTAT_RXPAUSE 
0x01<BR>#define RTK_MEDIASTAT_TXPAUSE 0x02<BR>#define RTK_MEDIASTAT_LINK 
0x04<BR>#define RTK_MEDIASTAT_SPEED10 0x08<BR>#define RTK_MEDIASTAT_RXFLOWCTL 
0x40 /* duplex mode */<BR>#define RTK_MEDIASTAT_TXFLOWCTL 0x80 /* duplex mode 
*/<BR> <BR>/*<BR> * Receive config register.<BR> */<BR>#define 
RTK_RXCFG_RX_ALLPHYS 0x00000001 /* accept all nodes */<BR>#define 
RTK_RXCFG_RX_INDIV 0x00000002 /* match filter */<BR>#define RTK_RXCFG_RX_MULTI 
0x00000004 /* accept all multicast */<BR>#define RTK_RXCFG_RX_BROAD 0x00000008 
/* accept all broadcast */<BR>#define RTK_RXCFG_RX_RUNT 0x00000010<BR>#define 
RTK_RXCFG_RX_ERRPKT 0x00000020<BR>#define RTK_RXCFG_WRAP  
0x00000080<BR>#define RTK_RXCFG_MAXDMA 0x00000700<BR>#define 
RTK_RXCFG_BUFSZ  0x00001800<BR>#define RTK_RXCFG_FIFOTHRESH 
0x0000E000<BR>#define RTK_RXCFG_EARLYTHRESH 0x07000000<BR> <BR>#define 
RTK_RXDMA_16BYTES 0x00000000<BR>#define RTK_RXDMA_32BYTES 0x00000100<BR>#define 
RTK_RXDMA_64BYTES 0x00000200<BR>#define RTK_RXDMA_128BYTES 0x00000300<BR>#define 
RTK_RXDMA_256BYTES 0x00000400<BR>#define RTK_RXDMA_512BYTES 
0x00000500<BR>#define RTK_RXDMA_1024BYTES 0x00000600<BR>#define 
RTK_RXDMA_UNLIMITED 0x00000700<BR> <BR>#define RTK_RXBUF_8  
0x00000000<BR>#define RTK_RXBUF_16  0x00000800<BR>#define 
RTK_RXBUF_32  0x00001000<BR>#define RTK_RXBUF_64  
0x00001800<BR> <BR>#define RTK_RXFIFO_16BYTES 0x00000000<BR>#define 
RTK_RXFIFO_32BYTES 0x00002000<BR>#define RTK_RXFIFO_64BYTES 
0x00004000<BR>#define RTK_RXFIFO_128BYTES 0x00006000<BR>#define 
RTK_RXFIFO_256BYTES 0x00008000<BR>#define RTK_RXFIFO_512BYTES 
0x0000A000<BR>#define RTK_RXFIFO_1024BYTES 0x0000C000<BR>#define 
RTK_RXFIFO_NOTHRESH 0x0000E000<BR> <BR>/*<BR> * Bits in RX status 
header (included with RX'ed packet<BR> * in ring 
buffer).<BR> */<BR>#define RTK_RXSTAT_RXOK  0x00000001<BR>#define 
RTK_RXSTAT_ALIGNERR 0x00000002<BR>#define RTK_RXSTAT_CRCERR 
0x00000004<BR>#define RTK_RXSTAT_GIANT 0x00000008<BR>#define 
RTK_RXSTAT_RUNT  0x00000010<BR>#define RTK_RXSTAT_BADSYM 
0x00000020<BR>#define RTK_RXSTAT_BROAD 0x00002000<BR>#define RTK_RXSTAT_INDIV 
0x00004000<BR>#define RTK_RXSTAT_MULTI 0x00008000<BR>#define RTK_RXSTAT_LENMASK 
0xFFFF0000<BR> <BR>#define RTK_RXSTAT_UNFINISHED 0xFFF0  /* DMA still 
in progress */<BR>/*<BR> * Command register.<BR> */<BR>#define 
RTK_CMD_EMPTY_RXBUF 0x0001<BR>#define RTK_CMD_TX_ENB  0x0004<BR>#define 
RTK_CMD_RX_ENB  0x0008<BR>#define RTK_CMD_RESET  
0x0010<BR> <BR>/*<BR> * EEPROM control register<BR> */<BR>#define 
RTK_EE_DATAOUT  0x01 /* Data out */<BR>#define RTK_EE_DATAIN  0x02 /* 
Data in */<BR>#define RTK_EE_CLK  0x04 /* clock */<BR>#define 
RTK_EE_SEL  0x08 /* chip select */<BR>#define RTK_EE_MODE  
(0x40|0x80)<BR> <BR>#define RTK_EEMODE_OFF  0x00<BR>#define 
RTK_EEMODE_AUTOLOAD 0x40<BR>#define RTK_EEMODE_PROGRAM 0x80<BR>#define 
RTK_EEMODE_WRITECFG (0x80|0x40)<BR> <BR>/* 9346/9356 EEPROM commands 
*/<BR>#define RTK_EEADDR_LEN0  6 /* 9346 */<BR>#define 
RTK_EEADDR_LEN1  8 /* 9356 */<BR>#define RTK_EECMD_LEN  
4<BR> <BR>#define RTK_EECMD_WRITE  0x5 /* 0101b */<BR>#define 
RTK_EECMD_READ  0x6 /* 0110b */<BR>#define RTK_EECMD_ERASE  0x7 /* 
0111b */<BR> <BR>#define RTK_EE_ID  0x00<BR>#define 
RTK_EE_PCI_VID  0x01<BR>#define RTK_EE_PCI_DID  0x02<BR>/* Location of 
station address inside EEPROM */<BR>#define RTK_EE_EADDR0  0x07<BR>#define 
RTK_EE_EADDR1  0x08<BR>#define RTK_EE_EADDR2  
0x09<BR> <BR>/*<BR> * MII register (8129 only)<BR> */<BR>#define 
RTK_MII_CLK  0x01<BR>#define RTK_MII_DATAIN  0x02<BR>#define 
RTK_MII_DATAOUT  0x04<BR>#define RTK_MII_DIR  0x80 /* 0 == input, 1 == 
output */<BR> <BR>/*<BR> * Config 0 register<BR> */<BR>#define 
RTK_CFG0_ROM0  0x01<BR>#define RTK_CFG0_ROM1  0x02<BR>#define 
RTK_CFG0_ROM2  0x04<BR>#define RTK_CFG0_PL0  0x08<BR>#define 
RTK_CFG0_PL1  0x10<BR>#define RTK_CFG0_10MBPS  0x20 /* 10 Mbps 
internal mode */<BR>#define RTK_CFG0_PCS  0x40<BR>#define 
RTK_CFG0_SCR  0x80<BR> <BR>/*<BR> * Config 1 
register<BR> */<BR>#define RTK_CFG1_PWRDWN  0x01<BR>#define 
RTK_CFG1_SLEEP  0x02<BR>#define RTK_CFG1_IOMAP  0x04<BR>#define 
RTK_CFG1_MEMMAP  0x08<BR>#define RTK_CFG1_RSVD  0x10<BR>#define 
RTK_CFG1_DRVLOAD 0x20<BR>#define RTK_CFG1_LED0  0x40<BR>#define 
RTK_CFG1_FULLDUPLEX 0x40 /* 8129 only */<BR>#define RTK_CFG1_LED1  
0x80<BR> <BR>/*<BR> * The RealTek doesn't use a fragment-based 
descriptor mechanism.<BR> * Instead, there are only four register sets, 
each or which represents<BR> * one 'descriptor.' Basically, each TX 
descriptor is just a contiguous<BR> * packet buffer (32-bit aligned!) and 
we place the buffer addresses in<BR> * the registers so the chip knows 
where they are.<BR> *<BR> * We can sort of kludge together the same 
kind of buffer management<BR> * used in previous drivers, but we have to do 
buffer copies almost all<BR> * the time, so it doesn't really buy us 
much.<BR> *<BR> * For reception, there's just one large buffer where 
the chip stores<BR> * all received 
packets.<BR> */<BR> <BR>#define RTK_RX_BUF_SZ  
RTK_RXBUF_64<BR>#define RTK_RXBUFLEN  (1 << ((RTK_RX_BUF_SZ >> 
11) + 13))<BR>#define RTK_TX_LIST_CNT  4<BR>#define RTK_RX_BUF_NUM  
64  /* Yves: Rx buffer number */<BR>#define RTK_TX_EARLYTHRESH ((256 / 32) 
<< 16)<BR>#define RTK_RX_FIFOTHRESH RTK_RXFIFO_256BYTES<BR>#define 
RTK_RX_MAXDMA  RTK_RXDMA_UNLIMITED<BR>#define RTK_TX_MAXDMA  
RTK_TXDMA_2048BYTES<BR> <BR>#define RTK_RXCFG_CONFIG  
(RTK_RX_FIFOTHRESH|RTK_RX_MAXDMA|RTK_RX_BUF_SZ)<BR>#define RTK_TXCFG_CONFIG 
(RTK_TXCFG_IFG|RTK_TX_MAXDMA)<BR>#define RTK_TXCFG_CONFIG 
RTK_TX_MAXDMA<BR> <BR>/*<BR> * PCI low memory base and low I/O base 
register, and<BR> * other PCI registers.<BR> */<BR>#define 
RTK_PCI_COMMAND  0x04<BR>#define RTK_PCI_LOIO  0x10<BR>#define 
RTK_PCI_LOMEM  0x14<BR> <BR>#define RTK_PSTATE_MASK  
0x0003<BR>#define RTK_PSTATE_D0  0x0000<BR>#define RTK_PSTATE_D1  
0x0002<BR>#define RTK_PSTATE_D2  0x0002<BR>#define RTK_PSTATE_D3  
0x0003<BR>#define RTK_PME_EN  0x0010<BR>#define RTK_PME_STATUS  
0x8000<BR>#define RTK_PCI_REVISION_ID 0x08 /* Yves: 8 bits */<BR>#define 
RTK_TIMEOUT  1000<BR>#define RTK_PCI_CAPID  0x50 /* 8 bits 
*/<BR>#define RTK_PCI_PWRMGMTCAP 0x52 /* 16 bits */<BR>#define 
RTK_PCI_PWRMGMTCTRL 0x54 /* 16 bits */<BR> <BR>struct rl_chain_data 
{<BR> u_int16_t  cur_rx;<BR> caddr_t   
rl_rx_buf;<BR> <BR> struct mbuf  
*rl_tx_chain[RTK_TX_LIST_CNT];<BR> u_int8_t  
last_tx;<BR> u_int8_t  cur_tx;<BR>};<BR> <BR>#define 
RL_INC(x)  (x = (x + 1) % RTK_TX_LIST_CNT)<BR>#define RL_CUR_TXADDR(x) 
((x->rl_cdata.cur_tx * 4) + RTK_TXADDR0)<BR>#define RL_CUR_TXSTAT(x) 
((x->rl_cdata.cur_tx * 4) + RTK_TXSTAT0)<BR>#define RL_CUR_TXMBUF(x) 
(x->rl_cdata.rl_tx_chain[x->rl_cdata.cur_tx])<BR>#define RL_LAST_TXADDR(x) 
((x->rl_cdata.last_tx * 4) + RTK_TXADDR0)<BR>#define RL_LAST_TXSTAT(x) 
((x->rl_cdata.last_tx * 4) + RTK_TXSTAT0)<BR>#define RL_LAST_TXMBUF(x) 
(x->rl_cdata.rl_tx_chain[x->rl_cdata.last_tx])<BR>#define 
RL_MIN_FRAMELEN  60<BR>#define RL_TXTHRESH(x)  ((x) << 
11)<BR>#define RL_TX_THRESH_INIT 96<BR>#define RL_ETHER_ALIGN 2<BR> <BR>/* 
from BSD header */<BR>/* PCI config header registers for all devices 
*/<BR>#define PCIR_DEVVENDOR 0x00<BR>#define PCIR_VENDOR 0x00<BR>#define 
PCIR_DEVICE 0x02<BR>#define PCIR_COMMAND 0x04<BR>#define PCIM_CMD_PORTEN  
0x0001<BR>#define PCIM_CMD_MEMEN  0x0002<BR>#define PCIM_CMD_BUSMASTEREN 
0x0004<BR>#define PCIM_CMD_MWRICEN 0x0010<BR>#define PCIM_CMD_PERRESPEN 
0x0040<BR>#define PCIM_CMD_SERRESPEN 0x0100<BR>#define PCIR_STATUS 
0x06<BR>#define PCIM_STATUS_CAPPRESENT 0x0010<BR>#define PCIM_STATUS_66CAPABLE 
0x0020<BR>#define PCIM_STATUS_BACKTOBACK 0x0080<BR>#define 
PCIM_STATUS_PERRREPORT 0x0100<BR>#define PCIM_STATUS_SEL_FAST 0x0000<BR>#define 
PCIM_STATUS_SEL_MEDIMUM 0x0200<BR>#define PCIM_STATUS_SEL_SLOW 0x0400<BR>#define 
PCIM_STATUS_SEL_MASK 0x0600<BR>#define PCIM_STATUS_STABORT 0x0800<BR>#define 
PCIM_STATUS_RTABORT 0x1000<BR>#define PCIM_STATUS_RMABORT 0x2000<BR>#define 
PCIM_STATUS_SERR 0x4000<BR>#define PCIM_STATUS_PERR 0x8000<BR>#define PCIR_REVID 
0x08<BR>#define PCIR_PROGIF 0x09<BR>#define PCIR_SUBCLASS 0x0a<BR>#define 
PCIR_CLASS 0x0b<BR>#define PCIR_CACHELNSZ 0x0c<BR>#define PCIR_LATTIMER 
0x0d<BR>#define PCIR_HEADERTYPE 0x0e<BR>#define PCIM_MFDEV  0x80<BR>#define 
PCIR_BIST 0x0f<BR> <BR>/* from RTEMS NE2000 driver */<BR>#define 
NRTKDRIVER    1<BR>#define phys_to_bus(address) ((unsigned int) 
((address)))<BR>#define bus_to_phys(address) ((unsigned int) 
((address)))<BR>#define delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 
)<BR>#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZE<BR> <BR>#define 
INTERRUPT_EVENT RTEMS_EVENT_1<BR>#define START_TRANSMIT_EVENT 
RTEMS_EVENT_2<BR> <BR>struct rtk8139_softc {<BR> <BR>   
struct arpcom   arpcom;<BR> <BR>   
rtems_irq_connect_data irqInfo;<BR> <BR>   volatile unsigned char 
*bufferBase;<BR>   int    
acceptBroadcast;<BR>   rtems_id   
rxDaemonTid;<BR>   rtems_id   txDaemonTid;<BR>   
<BR>   int         
PendingTxCount;<BR>   
int         
TxSuspended;<BR> <BR>  unsigned int    port;<BR>  
volatile unsigned int  *base;<BR>  int    
rl_txthresh;<BR> <BR>  struct rl_chain_data 
rl_cdata;<BR> <BR>  /*<BR>   * Statistics<BR>   
*/<BR>  unsigned long rxInterrupts;<BR>  unsigned long 
rxNotFirst;<BR>  unsigned long rxNotLast;<BR>  unsigned long 
rxGiant;<BR>  unsigned long rxNonOctet;<BR>  unsigned long 
rxRunt;<BR>  unsigned long rxBadCRC;<BR>  unsigned long 
rxOverrun;<BR>  unsigned long rxCollision;<BR>  <BR>  unsigned 
long txInterrupts;<BR>  unsigned long txDeferred;<BR>  unsigned long 
txHeartbeat;<BR>  unsigned long txLateCollision;<BR>  unsigned long 
txRetryLimit;<BR>  unsigned long txUnderrun;<BR>  unsigned long 
txLostCarrier;<BR>  unsigned long txRawWait;<BR>};<BR> <BR>static 
struct rtk8139_softc rtk8139_softc[NRTKDRIVER];<BR> <BR>#define DELAY(x) 
Wait_X_ms(x)<BR> <BR>static __inline void outl( unsigned short io_addr, 
unsigned int out_data )<BR>{<BR>  outport_long( io_addr, out_data 
);<BR>}<BR> <BR>static __inline void outw( unsigned short io_addr, unsigned 
short out_data )<BR>{<BR>  outport_word( io_addr, out_data 
);<BR>}<BR> <BR>void __inline outb( unsigned short io_addr, unsigned char 
out_data )<BR>{<BR>  outport_byte( io_addr, out_data 
);<BR>}<BR> <BR>static __inline unsigned int inl( unsigned short io_addr 
)<BR>{<BR>  unsigned int in_data;<BR>  inport_long( io_addr, in_data 
);<BR>  return in_data;<BR>}<BR> <BR>static __inline unsigned short 
inw( unsigned short io_addr )<BR>{<BR>  unsigned short in_data;<BR>  
inport_word( io_addr, in_data );<BR>  return 
in_data;<BR>}<BR> <BR>static __inline unsigned char inb( unsigned short 
io_addr )<BR>{<BR>  unsigned char in_data;<BR>  inport_byte( io_addr, 
in_data );<BR>  return in_data;<BR>}<BR> </FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>static int rl_encap(struct rtk8139_softc *sc, struct mbuf 
*m_head)  /* Only used in ~C+ mode */<BR>{<BR> struct mbuf  
*m_new = NULL;<BR> <BR> MGETHDR(m_new, M_DONTWAIT, 
MT_DATA);<BR> if (m_new == NULL) {<BR>  printf("rk1 no memory for tx 
list");<BR>  return(1);<BR> }<BR> if (m_head->m_pkthdr.len 
> MHLEN) {<BR>  MCLGET(m_new, M_DONTWAIT);<BR>  if 
(!(m_new->m_flags & M_EXT)) {<BR>   
m_freem(m_new);<BR>   printf("rk1: no memory for tx 
list");<BR>   return(1);<BR>  
}<BR> }<BR> m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, 
caddr_t));<BR> m_new->m_pkthdr.len = m_new->m_len = 
m_head->m_pkthdr.len;<BR> m_freem(m_head);<BR> m_head = 
m_new;<BR> <BR> /* Pad frames to at least 60 bytes. */<BR> if 
(m_head->m_pkthdr.len < RL_MIN_FRAMELEN) { /* Yves: Case length < 60 
bytes */<BR>  /*<BR>   * Make security concious people happy: 
zero out the<BR>   * bytes in the pad area, since we don't know 
what<BR>   * this mbuf cluster buffer's previous user 
might<BR>   * have left in it.<BR>    */<BR>  
bzero(mtod(m_head, char *) + 
m_head->m_pkthdr.len,<BR>       RL_MIN_FRAMELEN 
- m_head->m_pkthdr.len);<BR>  m_head->m_pkthdr.len 
+=<BR>      (RL_MIN_FRAMELEN - 
m_head->m_pkthdr.len);<BR>  m_head->m_len = 
m_head->m_pkthdr.len;<BR> }<BR> RL_CUR_TXMBUF(sc) = m_head;  
/* Yves: Save pointer of buffer to sc 
*/<BR> <BR> return(0);<BR>}<BR> <BR>static void<BR>rtk8139_start 
(struct ifnet *ifp)<BR>{<BR> struct rtk8139_softc *sc = 
ifp->if_softc;<BR> struct mbuf  *m = 
NULL;<BR> <BR>    while(RL_CUR_TXMBUF(sc) == 
NULL)<BR>    {<BR>      
IF_DEQUEUE(&ifp->if_snd, m);<BR>      if 
(!m)<BR>  break;<BR> <BR>      if 
(rl_encap(sc, m))<BR>      
{<BR>         
IF_PREPEND(&ifp->if_snd, m); /* Yves: Case encap fail 
*/<BR>         ifp->if_flags |= 
IFF_OACTIVE;<BR>         
break;<BR>      
}<BR> <BR>      outl(sc->port + 
RL_CUR_TXADDR(sc), mtod(RL_CUR_TXMBUF(sc), 
caddr_t));<BR>      outl(sc->port + 
RL_CUR_TXSTAT(sc), RL_TXTHRESH(sc->rl_txthresh) | 
RL_CUR_TXMBUF(sc)->m_pkthdr.len);<BR>      
RL_INC(sc->rl_cdata.cur_tx);   /* Yves: Move current Tx index 
*/<BR>    }<BR>    if (RL_CUR_TXMBUF(sc) != 
NULL)    /* Tx buffer chain full 
*/<BR>       ifp->if_flags |= 
IFF_OACTIVE;<BR> <BR> ifp->if_timer = 5;<BR>}<BR> <BR>static 
void<BR>rtk8139_reset(struct rtk8139_softc *sc)<BR>{<BR> register int 
i;<BR> outb(sc->port + RTK_COMMAND, 
RTK_CMD_RESET);<BR> <BR> for(i = 0; i < RTK_TIMEOUT; 
i++)<BR> {<BR>  DELAY(10);<BR>  if(!(inb(sc->port + 
RTK_COMMAND) & RTK_CMD_RESET))<BR>   
break;<BR> }<BR> if(i == RTK_TIMEOUT)<BR>  printk("rtk8139 reset 
never completed !!\n");<BR> return;<BR>}<BR> <BR>static rtems_isr 
rtk8139_intr(rtems_vector_number v)<BR>{<BR> struct rtk8139_softc  
*sc;<BR> struct ifnet  *ifp;<BR> u_int16_t  
status;<BR> <BR>    sc = 
&rtk8139_softc[0];<BR>    ifp = 
&sc->arpcom.ac_if;<BR> <BR> /* Disable interrupts. 
*/<BR> outw(sc->port + RTK_IMR, 0x0000);<BR> <BR> for (;;) 
{<BR>  status = inw(sc->port + RTK_ISR);<BR>  if 
(status)<BR>   outw(sc->port + RTK_ISR, 
status);<BR> <BR>  if ((status & RTK_INTRS) == 0)<BR>   
break;<BR> <BR>  if (status & RTK_ISR_RX_OK)<BR>   
rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);<BR>  <BR>  if 
(status & RTK_ISR_RX_ERR)<BR>   rtems_event_send 
(sc->rxDaemonTid, INTERRUPT_EVENT);<BR> <BR>  if ((status & 
RTK_ISR_TX_OK) || (status & RTK_ISR_TX_ERR))<BR>   
rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);<BR> <BR>  
if (status & RTK_ISR_SYSTEM_ERR)<BR>  {<BR>   
rtk8139_reset(sc);<BR>   rtk8139_init(sc);<BR>  
}<BR> }<BR> <BR> /* Re-enable interrupts. 
*/<BR> outw(sc->port + RTK_IMR, RTK_INTRS);<BR> <BR> if 
(ifp->if_snd.ifq_head != NULL)  /* Yves : Data in Tx buffer waiting for 
transimission */<BR>  
rtk8139_start(ifp);<BR> <BR> return;<BR>}<BR> <BR>static void 
nopOn(const rtems_irq_connect_data* notUsed)<BR>{<BR>  /*<BR>   * 
code should be moved from dec21140Enet_initialize_hardware<BR>   * to 
this location<BR>   */<BR>}<BR> <BR>static int rtk8139IsOn(const 
rtems_irq_connect_data* irq)<BR>{<BR>  return BSP_irq_enabled_at_i8259s 
(irq->name);<BR>}<BR> <BR>static int rl_var_init(struct rtk8139_softc 
*sc)<BR>{<BR> int   i;<BR> struct rl_chain_data 
*cd;<BR>  <BR> cd = &sc->rl_cdata;<BR> for (i = 0; i < 
RTK_TX_LIST_CNT; i++) {<BR>  cd->rl_tx_chain[i] = NULL;<BR>  
outl(sc->port + RTK_TXADDR0 + (i * sizeof(u_int32_t)), 
0x00000000);<BR> }<BR> sc->rl_cdata.cur_tx = 
0;<BR> sc->rl_cdata.last_tx = 
0;<BR> <BR> return(0);<BR>}<BR> <BR>/*<BR> * Initialize the 
ethernet hardware<BR> */<BR>unsigned char rxbuffer[RTK_RXBUFLEN + 
1518];<BR> <BR>static void<BR>rtk8139_initialize_hardware (struct 
rtk8139_softc *sc)<BR>{<BR>  rtems_status_code st;<BR>  volatile 
unsigned int *tbase;<BR>  int i;<BR>  volatile unsigned char *cp = 
(volatile unsigned char *)rxbuffer; /* Please check this code : from 
baedo*/<BR>  u_int32_t rxcfg = 0;<BR> <BR>  tbase = 
sc->base;<BR> <BR>  <BR>  /*<BR>   * Init RX 
ring<BR>   */<BR>/*  cp = (volatile unsigned char 
*)malloc(RTK_RXBUFLEN + 1518, 0, M_NOWAIT); */<BR>  sc->bufferBase = 
cp;<BR>  sc->bufferBase += sizeof(u_int64_t);<BR>  
sc->rl_cdata.rl_rx_buf = sc->bufferBase;  /* It looks like a goose : 
=.= */<BR> <BR>  sc->irqInfo.hdl = 
(rtems_irq_hdl)rtk8139_intr;<BR>  sc->irqInfo.on  = 
nopOn;<BR>  sc->irqInfo.off = nopOn;<BR>  sc->irqInfo.isOn = 
rtk8139IsOn;<BR>  st = BSP_install_rtems_irq_handler 
(&sc->irqInfo);<BR>  if (!st)<BR>    rtems_panic 
("Can't attach rtk8139 interrupt handler for irq %d\n", 
sc->irqInfo.name);<BR>  <BR>  rl_var_init(sc);<BR>  <BR>  
sc->rl_txthresh = RL_TX_THRESH_INIT;<BR>  <BR>  
rtk8139_reset(sc);<BR> <BR>  outb(sc->port + RTK_COMMAND, 
RTK_CMD_TX_ENB|RTK_CMD_RX_ENB);<BR>  outl(sc->port + RTK_RXCFG, 
RTK_RXCFG_CONFIG);<BR>  outl(sc->port + RTK_TXCFG, 
RTK_TXCFG_CONFIG);<BR> <BR>  outl(sc->port + RTK_RXADDR, (unsigned 
long)sc->bufferBase);<BR> <BR>  rxcfg |= 
RTK_RXCFG_RX_INDIV;<BR>  rxcfg |= RTK_RXCFG_RX_BROAD;<BR>  rxcfg |= 
RTK_RXCFG_RX_MULTI;<BR> <BR>  outl(sc->port + RTK_MISSEDPKT, 
0);<BR> <BR>  outl(sc->port + RTK_RXCFG, rxcfg);<BR>  
outl(sc->port + RTK_MAR0, 0xFFFFFFFF);<BR>  outl(sc->port + RTK_MAR0 
+ 4, 0xFFFFFFFF);<BR>  <BR>  outw(sc->port + RTK_IMR, 
RTK_INTRS);<BR>  outb(sc->port + RTK_COMMAND, 
RTK_CMD_TX_ENB|RTK_CMD_RX_ENB);<BR>  outb(sc->port + RTK_CFG1, 
RTK_CFG1_DRVLOAD|RTK_CFG1_FULLDUPLEX);<BR> <BR>  
printk("rtk8139_initialize_hardware !!\n");<BR>  
return;<BR>}<BR> <BR>static void<BR>rtk8139_hw_init(struct rtk8139_softc 
*sc)<BR>{<BR>  rtems_status_code st;<BR>  volatile unsigned int 
*tbase;<BR>  int i;<BR>  volatile unsigned char *cp = (volatile 
unsigned char *)rxbuffer;<BR>  u_int32_t rxcfg = 0;<BR> <BR>  
tbase = sc->base;<BR>  <BR>  /*<BR>   * Init RX 
ring<BR>   */<BR>  sc->bufferBase = cp;<BR>  
sc->bufferBase += sizeof(u_int64_t);<BR>  sc->rl_cdata.rl_rx_buf = 
sc->bufferBase; /* It looks like a goose : =.= */<BR> <BR>  
rl_var_init(sc);<BR>      <BR>  sc->rl_txthresh 
= RL_TX_THRESH_INIT;<BR>  <BR>  rtk8139_reset(sc);<BR> <BR>  
outb(sc->port + RTK_COMMAND, RTK_CMD_TX_ENB|RTK_CMD_RX_ENB);<BR>  
outl(sc->port + RTK_RXCFG, RTK_RXCFG_CONFIG);<BR>  outl(sc->port + 
RTK_TXCFG, RTK_TXCFG_CONFIG);<BR> <BR>  outl(sc->port + RTK_RXADDR, 
(unsigned long)sc->bufferBase);<BR> <BR>  rxcfg |= 
RTK_RXCFG_RX_INDIV;<BR>  rxcfg |= RTK_RXCFG_RX_BROAD;<BR>  rxcfg |= 
RTK_RXCFG_RX_MULTI;<BR> <BR>  outl(sc->port + RTK_MISSEDPKT, 
0);<BR> <BR>  outl(sc->port + RTK_RXCFG, rxcfg);<BR>  
outl(sc->port + RTK_MAR0, 0xFFFFFFFF);<BR>  outl(sc->port + RTK_MAR0 
+ 4, 0xFFFFFFFF);<BR>  <BR>  outw(sc->port + RTK_IMR, 
RTK_INTRS);<BR>  outb(sc->port + RTK_COMMAND, 
RTK_CMD_TX_ENB|RTK_CMD_RX_ENB);<BR>  outb(sc->port + RTK_CFG1, 
RTK_CFG1_DRVLOAD|RTK_CFG1_FULLDUPLEX);<BR> <BR>  
return;<BR>}<BR> <BR>static void<BR>rtk8139_rxDaemon (void 
*arg)<BR>{<BR>  struct ether_header *eh;<BR>  struct mbuf  
*m;<BR>  int   total_len = 0;<BR>  u_int32_t  
rxstat;<BR>  caddr_t   rxbufpos;<BR>  int   wrap = 
0;<BR>  u_int16_t  cur_rx;<BR>  u_int16_t  limit;<BR>  
u_int16_t  rx_bytes = 0, max_bytes;<BR>  struct rtk8139_softc *sc = 
(struct rtk8139_softc *)&rtk8139_softc[0];<BR>  struct ifnet *ifp = 
&sc->arpcom.ac_if;<BR>  u_int32_t     
value32;<BR>  <BR>  printk("rtk8139_rxDaemon !!\n");<BR>  
<BR>  cur_rx = inw(sc->port + RTK_CURRXADDR);<BR>  printk("cur_rx 
0x%x\n", cur_rx);<BR>  value32 = inl(sc->port + RTK_RXADDR);<BR>  
printk("RTK_RXADDR 0x%x\n", value32);<BR>  <BR>  while (1)<BR>  
{<BR>    rtems_event_set events;<BR> <BR>    
/* Wait for the interrupt handler to tell us that there is 
a<BR>       packet ready to receive.  
*/<BR>    rtems_bsdnet_event_receive 
(INTERRUPT_EVENT,<BR>    RTEMS_WAIT | 
RTEMS_EVENT_ANY,<BR>    RTEMS_NO_TIMEOUT,<BR>    
&events);<BR> <BR>  cur_rx = (inw(sc->port + RTK_CURRXADDR) + 
16) % RTK_RXBUFLEN;<BR> <BR>  /* Do not try to read past this point. 
*/<BR>  limit = inw(sc->port + RTK_CURRXBUF) % 
RTK_RXBUFLEN;<BR> <BR>  if (limit < cur_rx)<BR>   
max_bytes = (RTK_RXBUFLEN - cur_rx) + limit;<BR>  else<BR>   
max_bytes = limit - cur_rx;<BR> <BR>  while((inb(sc->port + 
RTK_COMMAND) & RTK_CMD_EMPTY_RXBUF) == 0) {<BR>   rxbufpos = 
sc->rl_cdata.rl_rx_buf + cur_rx;<BR>   rxstat = *(u_int32_t 
*)rxbufpos;<BR> <BR>   /*<BR>    * Here's a 
totally undocumented fact for you. When the<BR>    * RealTek chip 
is in the process of copying a packet into<BR>    * RAM for you, 
the length will be 0xfff0. If you spot a<BR>    * packet header 
with this value, you need to stop. The<BR>    * datasheet makes 
absolutely no mention of this and<BR>    * RealTek should be shot 
for this.<BR>    */<BR>   if ((u_int16_t)(rxstat 
>> 16) == RTK_RXSTAT_UNFINISHED)<BR>    
break;<BR> <BR>   if (!(rxstat & RTK_RXSTAT_RXOK)) 
{<BR>    ifp->if_ierrors++;<BR>    
rtk8139_hw_init(sc);<BR>    break;<BR>    /* 
return; */<BR>   }<BR> <BR>   /* No errors; receive the 
packet. */ <BR>   total_len = rxstat >> 16;<BR>   
rx_bytes += total_len + 4;<BR> <BR>   /*<BR>    * 
XXX The RealTek chip includes the CRC with every<BR>    * 
received frame, and there's no way to turn this<BR>    * behavior 
off (at least, I can't find anything in<BR>     * the manual 
that explains how to do it) so we have<BR>    * to trim off the 
CRC manually.<BR>    */<BR>   total_len -= 
ETHER_CRC_LEN;<BR> <BR>   /*<BR>    * Avoid trying 
to read more bytes than we know<BR>    * the chip has prepared 
for us.<BR>    */<BR>/*<BR>   if (rx_bytes > 
max_bytes)<BR>    break; */  /* Please check this code : 
from baedo*/<BR>   <BR>   rxbufpos = 
sc->rl_cdata.rl_rx_buf +<BR>    ((cur_rx + sizeof(u_int32_t)) 
% RTK_RXBUFLEN);<BR> <BR>   if (rxbufpos == 
(sc->rl_cdata.rl_rx_buf + RTK_RXBUFLEN))<BR>    rxbufpos = 
sc->rl_cdata.rl_rx_buf;<BR> <BR>   wrap = 
(sc->rl_cdata.rl_rx_buf + RTK_RXBUFLEN) - rxbufpos;<BR> <BR>   
if (total_len > wrap) {<BR>    /*<BR>     
* Fool m_devget() into thinking we want to copy<BR>     * 
the whole buffer so we don't end up fragmenting<BR>     * 
the data.<BR>     */<BR>    m = 
m_devget(rxbufpos - 
RL_ETHER_ALIGN,<BR>        total_len + 
RL_ETHER_ALIGN, 0, ifp, NULL);<BR>    if (m == NULL) 
{<BR>     ifp->if_ierrors++;<BR>     
printf("rk1: out of mbufs, tried to 
"<BR>         "copy %d bytes\n", 
wrap);<BR>    } else {<BR>     m_adj(m, 
RL_ETHER_ALIGN);<BR>     m_copyback(m, wrap, total_len - 
wrap,<BR>      
sc->rl_cdata.rl_rx_buf);<BR>    }<BR>    cur_rx 
= (total_len - wrap + ETHER_CRC_LEN);<BR>   } else 
{<BR>    m = m_devget(rxbufpos - 
RL_ETHER_ALIGN,<BR>        total_len + 
RL_ETHER_ALIGN, 0, ifp, NULL);<BR>    if (m == NULL) 
{<BR>     ifp->if_ierrors++;<BR>     
printf("rk1: out of mbufs, tried to 
"<BR>         "copy %d bytes\n", 
total_len);<BR>    } else<BR>     m_adj(m, 
RL_ETHER_ALIGN);<BR>    cur_rx += total_len + 4 + 
ETHER_CRC_LEN;<BR>   }<BR> <BR>   
/*<BR>    * Round up to 32-bit boundary.<BR>    
*/<BR>   cur_rx = (cur_rx + 3) & ~3;<BR>   
outw(sc->port + RTK_CURRXADDR, cur_rx - 16);<BR> <BR>   if (m 
== NULL)<BR>    continue;<BR> <BR>   eh = mtod(m, 
struct ether_header *);<BR>   
ifp->if_ipackets++;<BR> <BR>   /* Remove header from mbuf and 
pass it on. */<BR>   m_adj(m, sizeof(struct 
ether_header));<BR>   ether_input(ifp, eh, m);<BR>  
}<BR> <BR>  }<BR>}<BR> <BR>/*<BR> * Driver transmit 
daemon<BR> */<BR>void<BR>rtk8139_txDaemon (void *arg)<BR>{<BR>  struct 
rtk8139_softc *sc = (struct rtk8139_softc *)arg;<BR>  struct ifnet *ifp = 
&sc->arpcom.ac_if;<BR>  u_int32_t  txstat;<BR>  
rtems_event_set events;<BR> <BR>  for (;;) <BR>  {<BR>  
rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, 
RTEMS_NO_TIMEOUT, &events);<BR> <BR>  /* Clear the timeout timer. 
*/<BR>  ifp->if_timer = 0;<BR> <BR>  /*<BR>   * Go 
through our tx list and free mbufs for those<BR>   * frames that have 
been uploaded.<BR>   */<BR>  do {<BR>   txstat = 
inl(sc->port + RL_LAST_TXSTAT(sc));<BR>   if (!(txstat & 
(RTK_TXSTAT_TX_OK|<BR>       
RTK_TXSTAT_TX_UNDERRUN|RTK_TXSTAT_TXABRT)))<BR>    
break;<BR>   <BR>   ifp->if_collisions += (txstat & 
RTK_TXSTAT_COLLCNT) >> 24; /* Yves: Add collision counter 
*/<BR> <BR>   if (RL_LAST_TXMBUF(sc) != NULL) { /* Yves: Free 
Buffer */<BR>    m_freem(RL_LAST_TXMBUF(sc)); /* Yves: 
RL_LAST_TXMBUF(x)==>(x->rl_cdata.rl_tx_chain[x->rl_cdata.last_tx]) 
*/<BR>    RL_LAST_TXMBUF(sc) = NULL;<BR>   
}<BR>   if (txstat & RTK_TXSTAT_TX_OK)  /* Yves: Case Tx OK 
*/<BR>    ifp->if_opackets++;<BR>   else 
{     /* Yves: Case Tx ERR */<BR>    
int   oldthresh;<BR>    
ifp->if_oerrors++;<BR>    if ((txstat & RTK_TXSTAT_TXABRT) 
||<BR>        (txstat & 
RTK_TXSTAT_OUTOFWIN))<BR>     outl(sc->port + RTK_TXCFG, 
RTK_TXCFG_CONFIG);<BR>    oldthresh = 
sc->rl_txthresh;<BR>    /* error recovery 
*/<BR>    rtk8139_reset(sc);<BR>    
rtk8139_init(sc);<BR>    /*<BR>     * If 
there was a transmit underrun,<BR>     * bump the TX 
threshold.<BR>     */<BR>    if (txstat & 
RTK_TXSTAT_TX_UNDERRUN)<BR>     sc->rl_txthresh = 
oldthresh + 32;<BR>    printk("RTK8139 tx 
underrun\n");<BR>    break;<BR>   }<BR>   
RL_INC(sc->rl_cdata.last_tx);<BR>   ifp->if_flags &= 
~IFF_OACTIVE;<BR>  } while (sc->rl_cdata.last_tx != 
sc->rl_cdata.cur_tx);<BR> <BR>  ifp->if_timer = 
(sc->rl_cdata.last_tx == sc->rl_cdata.cur_tx) ? 0 : 5;<BR>  }<BR>} 
<BR> <BR>static void<BR>rtk8139_init (void *arg)<BR>{<BR>  struct 
rtk8139_softc *sc = arg;<BR>  struct ifnet *ifp = 
&sc->arpcom.ac_if;<BR> <BR>  if (sc->txDaemonTid == 0) 
{<BR>    <BR>    rtk8139_initialize_hardware 
(sc);<BR> <BR>    sc->rxDaemonTid = rtems_bsdnet_newproc 
("RLrx", 4096,<BR>         
rtk8139_rxDaemon, sc);<BR>    sc->txDaemonTid = 
rtems_bsdnet_newproc ("RLtx", 
4096,<BR>         rtk8139_txDaemon, 
sc);<BR>  }<BR>  else<BR>    
rtk8139_hw_init(sc);<BR>  /*<BR>   * Tell the world that we're 
running.<BR>   */<BR>  ifp->if_flags |= IFF_RUNNING;<BR>  
ifp->if_flags &= ~IFF_OACTIVE;<BR>}<BR> <BR>/*<BR> * Stop the 
device<BR> */<BR>static void<BR>rtk8139_stop (struct rtk8139_softc 
*sc)<BR>{<BR> register int  i;<BR> struct ifnet  
*ifp;<BR> <BR> ifp = 
&sc->arpcom.ac_if;<BR> ifp->if_timer = 
0;<BR> <BR> outb(sc->port + RTK_COMMAND, 
0x00);<BR> outw(sc->port + RTK_IMR, 
0x0000);<BR> <BR> /*<BR>  * Free the TX list buffers.<BR>  
*/<BR> for (i = 0; i < RTK_TX_LIST_CNT; i++) <BR> {<BR>  if 
(sc->rl_cdata.rl_tx_chain[i] != NULL) {<BR>   
m_freem(sc->rl_cdata.rl_tx_chain[i]);<BR>   
sc->rl_cdata.rl_tx_chain[i] = NULL;<BR>   outl(sc->port + 
RTK_TXADDR0 + i, 0x00000000);<BR>  
}<BR> }<BR> <BR> ifp->if_flags &= ~(IFF_RUNNING | 
IFF_OACTIVE);<BR> <BR> printk("rtk8139_stop()\n");<BR> return;<BR>}<BR> </FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>/*<BR> * Show interface statistics<BR> */<BR>static 
void<BR>rtk8139_stats (struct rtk8139_softc *sc)<BR>{<BR> printf 
("      Rx Interrupts:%-8lu", 
sc->rxInterrupts);<BR> printf ("       Not 
First:%-8lu", sc->rxNotFirst);<BR> printf 
("        Not Last:%-8lu\n", 
sc->rxNotLast);<BR> printf 
("              
Giant:%-8lu", sc->rxGiant);<BR> printf 
("            
Runt:%-8lu", sc->rxRunt);<BR> printf 
("       Non-octet:%-8lu\n", 
sc->rxNonOctet);<BR> printf 
("            Bad 
CRC:%-8lu", sc->rxBadCRC);<BR> printf 
("         Overrun:%-8lu", 
sc->rxOverrun);<BR> printf ("       
Collision:%-8lu\n", sc->rxCollision);<BR> <BR> printf 
("      Tx Interrupts:%-8lu", 
sc->txInterrupts);<BR> printf 
("        Deferred:%-8lu", 
sc->txDeferred);<BR> printf (" Missed Hearbeat:%-8lu\n", 
sc->txHeartbeat);<BR> printf 
("         No Carrier:%-8lu", 
sc->txLostCarrier);<BR> printf ("Retransmit Limit:%-8lu", 
sc->txRetryLimit);<BR> printf ("  Late Collision:%-8lu\n", 
sc->txLateCollision);<BR> printf 
("           Underrun:%-8lu", 
sc->txUnderrun);<BR> printf (" Raw output wait:%-8lu\n", 
sc->txRawWait);<BR>}<BR> <BR>/*<BR> * Driver ioctl 
handler<BR> */<BR>static int<BR>rtk8139_ioctl (struct ifnet *ifp, int 
command, caddr_t data)<BR>{<BR> struct rtk8139_softc *sc = 
ifp->if_softc;<BR> int error = 0;<BR> <BR> switch (command) 
{<BR> case SIOCGIFADDR:<BR> case SIOCSIFADDR:<BR>  ether_ioctl 
(ifp, command, data);<BR>  break;<BR> <BR> case 
SIOCSIFFLAGS:<BR>  switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) 
{<BR>  case IFF_RUNNING:<BR>   rtk8139_stop (sc);<BR>   
break;<BR> <BR>  case IFF_UP:<BR>   rtk8139_init 
(sc);<BR>   break;<BR> <BR>  case IFF_UP | 
IFF_RUNNING:<BR>   rtk8139_stop (sc);<BR>   rtk8139_init 
(sc);<BR>   break;<BR> <BR>  default:<BR>   
break;<BR>  }<BR>  break;<BR> <BR> case 
SIO_RTEMS_SHOW_STATS:<BR>  rtk8139_stats (sc);<BR>  break;<BR>  
<BR> /*<BR>  * FIXME: All sorts of multicast commands need to be added 
here!<BR>  */<BR> default:<BR>  error = EINVAL;<BR>  
break;<BR> }<BR> <BR> return error;<BR>}<BR> <BR>/* Attach 
an RTK 8139 driver to the system.  
*/<BR> <BR>int<BR>rtems_rtk8139_driver_attach (struct rtems_bsdnet_ifconfig 
*config)<BR>{<BR> struct rtk8139_softc *sc;<BR> struct ifnet 
*ifp;<BR> int mtu;<BR> int i;<BR>    int deviceID = 
PCI_DEVICE_ID_RTK_8139; /* network card device ID */<BR> <BR> int 
signature;<BR> u_int32_t value;<BR> char interrupt;<BR> int 
diag;<BR> int addr_len;<BR> u_int16_t val;<BR> u_int8_t 
val8;<BR> u_int32_t command;<BR> u_int8_t 
eaddr[ETHER_ADDR_LEN];<BR> <BR> if (pcib_init() == 
PCIB_ERR_NOTPRESENT)<BR>  rtems_panic("PCI BIOS not found 
!!");<BR> <BR> diag = pcib_find_by_devid(PCI_VENDOR_ID_RTK, deviceID, 
0, &signature);<BR> <BR> if(diag == PCIB_ERR_SUCCESS)<BR>  
printk("RTK 8139 network card found !!\n");<BR> else<BR>  
rtems_panic("RTK 8139 network card not found !!\n");<BR> <BR> for(i = 
0; i < NRTKDRIVER; i++)<BR> {<BR>  sc = 
&rtk8139_softc[i];<BR>  ifp = &sc->arpcom.ac_if;<BR>  
if(ifp->if_softc == NULL)<BR>   break; <BR> }<BR> if(i 
>= NRTKDRIVER)<BR> {<BR>  printk("Too many RTK 
drivers.\n");<BR>  return 
0;<BR> }<BR> <BR> pcib_conf_read32(signature, RTK_PCI_CAPID, 
&command);<BR> command &= 0x000000FF;<BR> printk("rtk8139 
command 0x%x\n", command);<BR> <BR> if(command == 
0x01)<BR> {<BR>  pcib_conf_read32(signature, RTK_PCI_PWRMGMTCTRL, 
&command);<BR>  command &= 0xFFFFFFFC;<BR>  
pcib_conf_write32(signature, RTK_PCI_PWRMGMTCTRL, 
command);<BR> }<BR> <BR> pcib_conf_read32(signature, 
PCIR_COMMAND, &command);<BR> command |= 
(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);<BR> pcib_conf_write32(signature, 
PCIR_COMMAND, command);<BR> pcib_conf_read32(signature, PCIR_COMMAND, 
&command);<BR> <BR> pcib_conf_read8(signature, RTK_PCI_COMMAND, 
&val8);<BR> val8 |= 0x03;<BR> pcib_conf_write8(signature, 
RTK_PCI_COMMAND, val8);<BR> <BR> pcib_conf_read32(signature, 
RTK_PCI_LOIO, &value);<BR> sc->port = value & 0xfff0;  /* 
Please check this code : from 
baedo*/<BR> <BR> pcib_conf_read32(signature, RTK_PCI_LOMEM, 
&value);<BR> sc->base = (unsigned int 
*)value;<BR> <BR> pcib_conf_read8(signature, RTK_IMR, 
&interrupt);<BR> sc->irqInfo.name = 
(rtems_irq_symbolic_name)interrupt;<BR> <BR> /* check rtk 8139C+ 
*/<BR> pcib_conf_read8(signature, RTK_PCI_REVISION_ID, 
&val8);<BR> <BR> printk("RTK 8139 port 0x%x mem base 0x%x irq %d 
revision %d\n", sc->port, sc->base, sc->irqInfo.name, 
val8);<BR> <BR> if(config->hardware_address)<BR> {<BR>  
memcpy(sc->arpcom.ac_enaddr, config->hardware_address, 
ETHER_ADDR_LEN);<BR> }<BR> else<BR> {<BR>  
/*<BR>   * Get station address.<BR>   */<BR>  eaddr[0] 
= inb(sc->port + RTK_IDR0);<BR>  eaddr[1] = inb(sc->port + 
RTK_IDR1);<BR>  eaddr[2] = inb(sc->port + RTK_IDR2);<BR>  eaddr[3] 
= inb(sc->port + RTK_IDR3);<BR>  eaddr[4] = inb(sc->port + 
RTK_IDR4);<BR>  eaddr[5] = inb(sc->port + RTK_IDR5);<BR>  
<BR>  memcpy(sc->arpcom.ac_enaddr, eaddr, ETHER_ADDR_LEN);<BR>  
<BR>  printk("RTK 8139 mac addr 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", eaddr[0], 
eaddr[1], eaddr[2], eaddr[3], eaddr[4], 
eaddr[5]);<BR> }<BR> <BR> rtk8139_reset(sc);<BR> <BR> if 
(config->mtu)<BR>  mtu = config->mtu;<BR> else<BR>  mtu = 
ETHERMTU;<BR> <BR> sc->acceptBroadcast = 
!config->ignore_broadcast;<BR> <BR> /*<BR>  * Set up network 
interface values<BR>  */<BR> ifp->if_softc = 
sc;<BR> ifp->if_unit = i + 1;<BR> ifp->if_name = 
"rk";<BR> ifp->if_mtu = mtu;<BR> ifp->if_init = 
rtk8139_init;<BR> ifp->if_ioctl = 
rtk8139_ioctl;<BR> ifp->if_start = 
rtk8139_start;<BR> ifp->if_output = 
ether_output;<BR> ifp->if_flags = IFF_BROADCAST | 
IFF_SIMPLEX;<BR> if (ifp->if_snd.ifq_maxlen == 
0)<BR> ifp->if_snd.ifq_maxlen = ifqmaxlen;<BR> <BR>  
/*<BR>  * Attach the interface<BR>  */<BR> if_attach 
(ifp);<BR> ether_ifattach (ifp);<BR> <BR> printk( "RTK 8139 
driver has been attached\n" );<BR> return 1;<BR>}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>***** code end *****</FONT></DIV>
<DIV><FONT size=2></FONT> </DIV></BODY></HTML>