1 --- rtl8139.c.old 2004-01-25 17:49:38.000000000 +0000
2 +++ rtl8139.c 2004-01-25 18:20:29.000000000 +0000
4 /* The RTL8139 can only transmit from a contiguous, aligned memory block. */
5 static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
7 -/* I know that this is a MEGA HACK, but the tagged boot image specification
8 - * states that we can do whatever we want below 0x10000 - so we do! */
9 -/* But we still give the user the choice of using an internal buffer
10 - just in case - Ken */
11 -#ifdef USE_LOWMEM_BUFFER
12 -#define rx_ring ((unsigned char *)(0x10000 - (RX_BUF_LEN + 16)))
14 static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
17 struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
18 struct pci_device *pci);
19 -static int read_eeprom(int location);
20 +static int read_eeprom(int location, int addr_len);
21 static void rtl_reset(struct nic *nic);
22 static void rtl_transmit(struct nic *nic, const char *destaddr,
23 unsigned int type, unsigned int len, const char *data);
27 int speed10, fullduplex;
29 + unsigned short *ap = (unsigned short*)nic->node_addr;
31 /* There are enough "RTL8139" strings on the console already, so
32 * be brief and concentrate on the interesting pieces of info... */
34 /* Bring the chip out of low-power mode. */
35 outb(0x00, ioaddr + Config1);
37 - if (read_eeprom(0) != 0xffff) {
38 - unsigned short *ap = (unsigned short*)nic->node_addr;
39 - for (i = 0; i < 3; i++)
40 - *ap++ = read_eeprom(i + 7);
42 - unsigned char *ap = (unsigned char*)nic->node_addr;
43 - for (i = 0; i < ETH_ALEN; i++)
44 - *ap++ = inb(ioaddr + MAC0 + i);
46 + addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6;
47 + for (i = 0; i < 3; i++)
48 + *ap++ = read_eeprom(i + 7,addr_len);
50 speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
51 fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
56 + if (inb(ioaddr + MediaStatus) & MSRLinkFail) {
57 + printf("Cable not connected or other link failure\n");
60 nic->reset = rtl_reset;
62 nic->transmit = rtl_transmit;
64 #define eeprom_delay() inl(ee_addr)
66 /* The EEPROM commands include the alway-set leading bit. */
67 -#define EE_WRITE_CMD (5 << 6)
68 -#define EE_READ_CMD (6 << 6)
69 -#define EE_ERASE_CMD (7 << 6)
70 +#define EE_WRITE_CMD (5)
71 +#define EE_READ_CMD (6)
72 +#define EE_ERASE_CMD (7)
74 -static int read_eeprom(int location)
75 +static int read_eeprom(int location, int addr_len)
78 unsigned int retval = 0;
79 long ee_addr = ioaddr + Cfg9346;
80 - int read_cmd = location | EE_READ_CMD;
81 + int read_cmd = location | (EE_READ_CMD << addr_len);
83 outb(EE_ENB & ~EE_CS, ee_addr);
84 outb(EE_ENB, ee_addr);
87 /* Shift the read command bits out. */
88 - for (i = 10; i >= 0; i--) {
89 + for (i = 4 + addr_len; i >= 0; i--) {
90 int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
91 outb(EE_ENB | dataval, ee_addr);
95 /* Terminate the EEPROM access. */
96 outb(~EE_CS, ee_addr);
101 +static const unsigned int rtl8139_rx_config =
102 + (RX_BUF_LEN_IDX << 11) |
103 + (RX_FIFO_THRESH << 13) |
104 + (RX_DMA_BURST << 8);
106 +static void set_rx_mode(struct nic *nic) {
107 + unsigned int mc_filter[2];
110 + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
111 + mc_filter[1] = mc_filter[0] = 0xffffffff;
113 + outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig);
115 + outl(mc_filter[0], ioaddr + MAR0 + 0);
116 + outl(mc_filter[1], ioaddr + MAR0 + 4);
119 static void rtl_reset(struct nic* nic)
122 @@ -316,17 +328,24 @@
124 printf("rx ring address is %X\n",(unsigned long)rx_ring);
126 - outl((unsigned long)rx_ring, ioaddr + RxBuf);
127 + outl((unsigned long)rx_ring, ioaddr + RxBuf);
131 - /* Start the chip's Tx and Rx process. */
132 - outl(0, ioaddr + RxMissed);
134 - outb(AcceptBroadcast|AcceptMyPhys, ioaddr + RxConfig);
135 /* If we add multicast support, the MAR0 register would have to be
136 * initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot
137 * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */
139 outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
141 + outl(rtl8139_rx_config, ioaddr + RxConfig);
143 + /* Start the chip's Tx and Rx process. */
144 + outl(0, ioaddr + RxMissed);
149 /* Disable all known interrupts by setting the interrupt mask. */
150 outw(0, ioaddr + IntrMask);
152 @@ -337,10 +356,11 @@
153 unsigned int status, to, nstype;
154 unsigned long txstatus;
156 + /* nstype assignment moved up here to avoid gcc 3.0.3 compiler bug */
157 + nstype = htons(type);
158 memcpy(tx_buffer, destaddr, ETH_ALEN);
159 memcpy(tx_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);
160 - nstype = htons(type);
161 - memcpy(tx_buffer + 2 * ETH_ALEN, (char*)&nstype, 2);
162 + memcpy(tx_buffer + 2 * ETH_ALEN, &nstype, 2);
163 memcpy(tx_buffer + ETH_HLEN, data, len);
167 tx_buffer[len++] = '\0';
170 - outl((unsigned long)tx_buffer, ioaddr + TxAddr0 + cur_tx*4);
171 + outl((unsigned long)tx_buffer, ioaddr + TxAddr0 + cur_tx*4);
172 outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
173 ioaddr + TxStatus0 + cur_tx*4);
177 static void rtl_disable(struct nic *nic)
182 outb(CmdReset, ioaddr + ChipCmd);