]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/grub-0.93-rtl8139.patch
git-svn-id: http://svn.ipfire.org/svn/ipfire/IPFire/source@16 ea5c0bd1-69bd-2848...
[people/pmueller/ipfire-2.x.git] / src / patches / grub-0.93-rtl8139.patch
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