]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/grub-0.93-rtl8139.patch
Kernel-Update und umfassende Arbeiten daran.
[people/pmueller/ipfire-2.x.git] / src / patches / grub-0.93-rtl8139.patch
CommitLineData
cd1a2927
MT
1--- rtl8139.c.old 2004-01-25 17:49:38.000000000 +0000
2+++ rtl8139.c 2004-01-25 18:20:29.000000000 +0000
3@@ -161,19 +161,11 @@
4 /* The RTL8139 can only transmit from a contiguous, aligned memory block. */
5 static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
6
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)))
13-#else
14 static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
15-#endif
16
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);
24@@ -186,6 +178,8 @@
25 {
26 int i;
27 int speed10, fullduplex;
28+ int addr_len;
29+ unsigned short *ap = (unsigned short*)nic->node_addr;
30
31 /* There are enough "RTL8139" strings on the console already, so
32 * be brief and concentrate on the interesting pieces of info... */
33@@ -199,15 +193,9 @@
34 /* Bring the chip out of low-power mode. */
35 outb(0x00, ioaddr + Config1);
36
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);
41- } else {
42- unsigned char *ap = (unsigned char*)nic->node_addr;
43- for (i = 0; i < ETH_ALEN; i++)
44- *ap++ = inb(ioaddr + MAC0 + i);
45- }
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);
49
50 speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
51 fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
52@@ -217,6 +205,10 @@
53
54 rtl_reset(nic);
55
56+ if (inb(ioaddr + MediaStatus) & MSRLinkFail) {
57+ printf("Cable not connected or other link failure\n");
58+ return(0);
59+ }
60 nic->reset = rtl_reset;
61 nic->poll = rtl_poll;
62 nic->transmit = rtl_transmit;
63@@ -244,22 +236,23 @@
64 #define eeprom_delay() inl(ee_addr)
65
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)
73
74-static int read_eeprom(int location)
75+static int read_eeprom(int location, int addr_len)
76 {
77 int i;
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);
82
83 outb(EE_ENB & ~EE_CS, ee_addr);
84 outb(EE_ENB, ee_addr);
85+ eeprom_delay();
86
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);
92 eeprom_delay();
93@@ -279,9 +272,28 @@
94
95 /* Terminate the EEPROM access. */
96 outb(~EE_CS, ee_addr);
97+ eeprom_delay();
98 return retval;
99 }
100
101+static const unsigned int rtl8139_rx_config =
102+ (RX_BUF_LEN_IDX << 11) |
103+ (RX_FIFO_THRESH << 13) |
104+ (RX_DMA_BURST << 8);
105+
106+static void set_rx_mode(struct nic *nic) {
107+ unsigned int mc_filter[2];
108+ int rx_mode;
109+ /* !IFF_PROMISC */
110+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
111+ mc_filter[1] = mc_filter[0] = 0xffffffff;
112+
113+ outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig);
114+
115+ outl(mc_filter[0], ioaddr + MAR0 + 0);
116+ outl(mc_filter[1], ioaddr + MAR0 + 4);
117+}
118+
119 static void rtl_reset(struct nic* nic)
120 {
121 int i;
122@@ -316,17 +328,24 @@
123 #ifdef DEBUG_RX
124 printf("rx ring address is %X\n",(unsigned long)rx_ring);
125 #endif
126- outl((unsigned long)rx_ring, ioaddr + RxBuf);
127+ outl((unsigned long)rx_ring, ioaddr + RxBuf);
128+
129+
130
131- /* Start the chip's Tx and Rx process. */
132- outl(0, ioaddr + RxMissed);
133- /* set_rx_mode */
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. */
138+
139 outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
140+
141+ outl(rtl8139_rx_config, ioaddr + RxConfig);
142+
143+ /* Start the chip's Tx and Rx process. */
144+ outl(0, ioaddr + RxMissed);
145
146+ /* set_rx_mode */
147+ set_rx_mode(nic);
148+
149 /* Disable all known interrupts by setting the interrupt mask. */
150 outw(0, ioaddr + IntrMask);
151 }
152@@ -337,10 +356,11 @@
153 unsigned int status, to, nstype;
154 unsigned long txstatus;
155
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);
164
165 len += ETH_HLEN;
166@@ -354,7 +374,7 @@
167 tx_buffer[len++] = '\0';
168 }
169
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);
174
175@@ -448,6 +468,8 @@
176
177 static void rtl_disable(struct nic *nic)
178 {
179+ rtl_reset(nic);
180+
181 /* reset the chip */
182 outb(CmdReset, ioaddr + ChipCmd);
183