Commit d75469d48c05795144f4b8ba76addbb4920a7bba
Committed by
Wolfgang Denk
1 parent
377151c817
Exists in
master
and in
54 other branches
net: rtl8169: Add processing when OWNbit did't enable in rtl_recv()
When rtl_recv() of rtl8169 is called, OWNbit of status register is not enable occasionally. rtl_recv() doesn't work normally when the driver doesn't do appropriate processing. This patch fix this problem. Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Showing 1 changed file with 14 additions and 0 deletions Inline Diff
drivers/net/rtl8169.c
1 | /* | 1 | /* |
2 | * rtl8169.c : U-Boot driver for the RealTek RTL8169 | 2 | * rtl8169.c : U-Boot driver for the RealTek RTL8169 |
3 | * | 3 | * |
4 | * Masami Komiya (mkomiya@sonare.it) | 4 | * Masami Komiya (mkomiya@sonare.it) |
5 | * | 5 | * |
6 | * Most part is taken from r8169.c of etherboot | 6 | * Most part is taken from r8169.c of etherboot |
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /************************************************************************** | 10 | /************************************************************************** |
11 | * r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit | 11 | * r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit |
12 | * Written 2003 by Timothy Legge <tlegge@rogers.com> | 12 | * Written 2003 by Timothy Legge <tlegge@rogers.com> |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
16 | * the Free Software Foundation; either version 2 of the License, or | 16 | * the Free Software Foundation; either version 2 of the License, or |
17 | * (at your option) any later version. | 17 | * (at your option) any later version. |
18 | * | 18 | * |
19 | * This program is distributed in the hope that it will be useful, | 19 | * This program is distributed in the hope that it will be useful, |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | * GNU General Public License for more details. | 22 | * GNU General Public License for more details. |
23 | * | 23 | * |
24 | * You should have received a copy of the GNU General Public License | 24 | * You should have received a copy of the GNU General Public License |
25 | * along with this program; if not, write to the Free Software | 25 | * along with this program; if not, write to the Free Software |
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
27 | * | 27 | * |
28 | * Portions of this code based on: | 28 | * Portions of this code based on: |
29 | * r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver | 29 | * r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver |
30 | * for Linux kernel 2.4.x. | 30 | * for Linux kernel 2.4.x. |
31 | * | 31 | * |
32 | * Written 2002 ShuChen <shuchen@realtek.com.tw> | 32 | * Written 2002 ShuChen <shuchen@realtek.com.tw> |
33 | * See Linux Driver for full information | 33 | * See Linux Driver for full information |
34 | * | 34 | * |
35 | * Linux Driver Version 1.27a, 10.02.2002 | 35 | * Linux Driver Version 1.27a, 10.02.2002 |
36 | * | 36 | * |
37 | * Thanks to: | 37 | * Thanks to: |
38 | * Jean Chen of RealTek Semiconductor Corp. for | 38 | * Jean Chen of RealTek Semiconductor Corp. for |
39 | * providing the evaluation NIC used to develop | 39 | * providing the evaluation NIC used to develop |
40 | * this driver. RealTek's support for Etherboot | 40 | * this driver. RealTek's support for Etherboot |
41 | * is appreciated. | 41 | * is appreciated. |
42 | * | 42 | * |
43 | * REVISION HISTORY: | 43 | * REVISION HISTORY: |
44 | * ================ | 44 | * ================ |
45 | * | 45 | * |
46 | * v1.0 11-26-2003 timlegge Initial port of Linux driver | 46 | * v1.0 11-26-2003 timlegge Initial port of Linux driver |
47 | * v1.5 01-17-2004 timlegge Initial driver output cleanup | 47 | * v1.5 01-17-2004 timlegge Initial driver output cleanup |
48 | * | 48 | * |
49 | * Indent Options: indent -kr -i8 | 49 | * Indent Options: indent -kr -i8 |
50 | ***************************************************************************/ | 50 | ***************************************************************************/ |
51 | /* | 51 | /* |
52 | * 26 August 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk> | 52 | * 26 August 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk> |
53 | * Modified to use le32_to_cpu and cpu_to_le32 properly | 53 | * Modified to use le32_to_cpu and cpu_to_le32 properly |
54 | */ | 54 | */ |
55 | #include <common.h> | 55 | #include <common.h> |
56 | #include <malloc.h> | 56 | #include <malloc.h> |
57 | #include <net.h> | 57 | #include <net.h> |
58 | #include <asm/io.h> | 58 | #include <asm/io.h> |
59 | #include <pci.h> | 59 | #include <pci.h> |
60 | 60 | ||
61 | #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ | 61 | #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ |
62 | defined(CONFIG_RTL8169) | 62 | defined(CONFIG_RTL8169) |
63 | 63 | ||
64 | #undef DEBUG_RTL8169 | 64 | #undef DEBUG_RTL8169 |
65 | #undef DEBUG_RTL8169_TX | 65 | #undef DEBUG_RTL8169_TX |
66 | #undef DEBUG_RTL8169_RX | 66 | #undef DEBUG_RTL8169_RX |
67 | 67 | ||
68 | #define drv_version "v1.5" | 68 | #define drv_version "v1.5" |
69 | #define drv_date "01-17-2004" | 69 | #define drv_date "01-17-2004" |
70 | 70 | ||
71 | static u32 ioaddr; | 71 | static u32 ioaddr; |
72 | 72 | ||
73 | /* Condensed operations for readability. */ | 73 | /* Condensed operations for readability. */ |
74 | #define currticks() get_timer(0) | 74 | #define currticks() get_timer(0) |
75 | 75 | ||
76 | /* media options */ | 76 | /* media options */ |
77 | #define MAX_UNITS 8 | 77 | #define MAX_UNITS 8 |
78 | static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; | 78 | static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; |
79 | 79 | ||
80 | /* MAC address length*/ | 80 | /* MAC address length*/ |
81 | #define MAC_ADDR_LEN 6 | 81 | #define MAC_ADDR_LEN 6 |
82 | 82 | ||
83 | /* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/ | 83 | /* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/ |
84 | #define MAX_ETH_FRAME_SIZE 1536 | 84 | #define MAX_ETH_FRAME_SIZE 1536 |
85 | 85 | ||
86 | #define TX_FIFO_THRESH 256 /* In bytes */ | 86 | #define TX_FIFO_THRESH 256 /* In bytes */ |
87 | 87 | ||
88 | #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ | 88 | #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ |
89 | #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ | 89 | #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ |
90 | #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ | 90 | #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ |
91 | #define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ | 91 | #define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ |
92 | #define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */ | 92 | #define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */ |
93 | #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ | 93 | #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ |
94 | 94 | ||
95 | #define NUM_TX_DESC 1 /* Number of Tx descriptor registers */ | 95 | #define NUM_TX_DESC 1 /* Number of Tx descriptor registers */ |
96 | #define NUM_RX_DESC 4 /* Number of Rx descriptor registers */ | 96 | #define NUM_RX_DESC 4 /* Number of Rx descriptor registers */ |
97 | #define RX_BUF_SIZE 1536 /* Rx Buffer size */ | 97 | #define RX_BUF_SIZE 1536 /* Rx Buffer size */ |
98 | #define RX_BUF_LEN 8192 | 98 | #define RX_BUF_LEN 8192 |
99 | 99 | ||
100 | #define RTL_MIN_IO_SIZE 0x80 | 100 | #define RTL_MIN_IO_SIZE 0x80 |
101 | #define TX_TIMEOUT (6*HZ) | 101 | #define TX_TIMEOUT (6*HZ) |
102 | 102 | ||
103 | /* write/read MMIO register. Notice: {read,write}[wl] do the necessary swapping */ | 103 | /* write/read MMIO register. Notice: {read,write}[wl] do the necessary swapping */ |
104 | #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) | 104 | #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) |
105 | #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) | 105 | #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) |
106 | #define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) | 106 | #define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) |
107 | #define RTL_R8(reg) readb (ioaddr + (reg)) | 107 | #define RTL_R8(reg) readb (ioaddr + (reg)) |
108 | #define RTL_R16(reg) readw (ioaddr + (reg)) | 108 | #define RTL_R16(reg) readw (ioaddr + (reg)) |
109 | #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) | 109 | #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) |
110 | 110 | ||
111 | #define ETH_FRAME_LEN MAX_ETH_FRAME_SIZE | 111 | #define ETH_FRAME_LEN MAX_ETH_FRAME_SIZE |
112 | #define ETH_ALEN MAC_ADDR_LEN | 112 | #define ETH_ALEN MAC_ADDR_LEN |
113 | #define ETH_ZLEN 60 | 113 | #define ETH_ZLEN 60 |
114 | 114 | ||
115 | enum RTL8169_registers { | 115 | enum RTL8169_registers { |
116 | MAC0 = 0, /* Ethernet hardware address. */ | 116 | MAC0 = 0, /* Ethernet hardware address. */ |
117 | MAR0 = 8, /* Multicast filter. */ | 117 | MAR0 = 8, /* Multicast filter. */ |
118 | TxDescStartAddr = 0x20, | 118 | TxDescStartAddr = 0x20, |
119 | TxHDescStartAddr = 0x28, | 119 | TxHDescStartAddr = 0x28, |
120 | FLASH = 0x30, | 120 | FLASH = 0x30, |
121 | ERSR = 0x36, | 121 | ERSR = 0x36, |
122 | ChipCmd = 0x37, | 122 | ChipCmd = 0x37, |
123 | TxPoll = 0x38, | 123 | TxPoll = 0x38, |
124 | IntrMask = 0x3C, | 124 | IntrMask = 0x3C, |
125 | IntrStatus = 0x3E, | 125 | IntrStatus = 0x3E, |
126 | TxConfig = 0x40, | 126 | TxConfig = 0x40, |
127 | RxConfig = 0x44, | 127 | RxConfig = 0x44, |
128 | RxMissed = 0x4C, | 128 | RxMissed = 0x4C, |
129 | Cfg9346 = 0x50, | 129 | Cfg9346 = 0x50, |
130 | Config0 = 0x51, | 130 | Config0 = 0x51, |
131 | Config1 = 0x52, | 131 | Config1 = 0x52, |
132 | Config2 = 0x53, | 132 | Config2 = 0x53, |
133 | Config3 = 0x54, | 133 | Config3 = 0x54, |
134 | Config4 = 0x55, | 134 | Config4 = 0x55, |
135 | Config5 = 0x56, | 135 | Config5 = 0x56, |
136 | MultiIntr = 0x5C, | 136 | MultiIntr = 0x5C, |
137 | PHYAR = 0x60, | 137 | PHYAR = 0x60, |
138 | TBICSR = 0x64, | 138 | TBICSR = 0x64, |
139 | TBI_ANAR = 0x68, | 139 | TBI_ANAR = 0x68, |
140 | TBI_LPAR = 0x6A, | 140 | TBI_LPAR = 0x6A, |
141 | PHYstatus = 0x6C, | 141 | PHYstatus = 0x6C, |
142 | RxMaxSize = 0xDA, | 142 | RxMaxSize = 0xDA, |
143 | CPlusCmd = 0xE0, | 143 | CPlusCmd = 0xE0, |
144 | RxDescStartAddr = 0xE4, | 144 | RxDescStartAddr = 0xE4, |
145 | EarlyTxThres = 0xEC, | 145 | EarlyTxThres = 0xEC, |
146 | FuncEvent = 0xF0, | 146 | FuncEvent = 0xF0, |
147 | FuncEventMask = 0xF4, | 147 | FuncEventMask = 0xF4, |
148 | FuncPresetState = 0xF8, | 148 | FuncPresetState = 0xF8, |
149 | FuncForceEvent = 0xFC, | 149 | FuncForceEvent = 0xFC, |
150 | }; | 150 | }; |
151 | 151 | ||
152 | enum RTL8169_register_content { | 152 | enum RTL8169_register_content { |
153 | /*InterruptStatusBits */ | 153 | /*InterruptStatusBits */ |
154 | SYSErr = 0x8000, | 154 | SYSErr = 0x8000, |
155 | PCSTimeout = 0x4000, | 155 | PCSTimeout = 0x4000, |
156 | SWInt = 0x0100, | 156 | SWInt = 0x0100, |
157 | TxDescUnavail = 0x80, | 157 | TxDescUnavail = 0x80, |
158 | RxFIFOOver = 0x40, | 158 | RxFIFOOver = 0x40, |
159 | RxUnderrun = 0x20, | 159 | RxUnderrun = 0x20, |
160 | RxOverflow = 0x10, | 160 | RxOverflow = 0x10, |
161 | TxErr = 0x08, | 161 | TxErr = 0x08, |
162 | TxOK = 0x04, | 162 | TxOK = 0x04, |
163 | RxErr = 0x02, | 163 | RxErr = 0x02, |
164 | RxOK = 0x01, | 164 | RxOK = 0x01, |
165 | 165 | ||
166 | /*RxStatusDesc */ | 166 | /*RxStatusDesc */ |
167 | RxRES = 0x00200000, | 167 | RxRES = 0x00200000, |
168 | RxCRC = 0x00080000, | 168 | RxCRC = 0x00080000, |
169 | RxRUNT = 0x00100000, | 169 | RxRUNT = 0x00100000, |
170 | RxRWT = 0x00400000, | 170 | RxRWT = 0x00400000, |
171 | 171 | ||
172 | /*ChipCmdBits */ | 172 | /*ChipCmdBits */ |
173 | CmdReset = 0x10, | 173 | CmdReset = 0x10, |
174 | CmdRxEnb = 0x08, | 174 | CmdRxEnb = 0x08, |
175 | CmdTxEnb = 0x04, | 175 | CmdTxEnb = 0x04, |
176 | RxBufEmpty = 0x01, | 176 | RxBufEmpty = 0x01, |
177 | 177 | ||
178 | /*Cfg9346Bits */ | 178 | /*Cfg9346Bits */ |
179 | Cfg9346_Lock = 0x00, | 179 | Cfg9346_Lock = 0x00, |
180 | Cfg9346_Unlock = 0xC0, | 180 | Cfg9346_Unlock = 0xC0, |
181 | 181 | ||
182 | /*rx_mode_bits */ | 182 | /*rx_mode_bits */ |
183 | AcceptErr = 0x20, | 183 | AcceptErr = 0x20, |
184 | AcceptRunt = 0x10, | 184 | AcceptRunt = 0x10, |
185 | AcceptBroadcast = 0x08, | 185 | AcceptBroadcast = 0x08, |
186 | AcceptMulticast = 0x04, | 186 | AcceptMulticast = 0x04, |
187 | AcceptMyPhys = 0x02, | 187 | AcceptMyPhys = 0x02, |
188 | AcceptAllPhys = 0x01, | 188 | AcceptAllPhys = 0x01, |
189 | 189 | ||
190 | /*RxConfigBits */ | 190 | /*RxConfigBits */ |
191 | RxCfgFIFOShift = 13, | 191 | RxCfgFIFOShift = 13, |
192 | RxCfgDMAShift = 8, | 192 | RxCfgDMAShift = 8, |
193 | 193 | ||
194 | /*TxConfigBits */ | 194 | /*TxConfigBits */ |
195 | TxInterFrameGapShift = 24, | 195 | TxInterFrameGapShift = 24, |
196 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ | 196 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ |
197 | 197 | ||
198 | /*rtl8169_PHYstatus */ | 198 | /*rtl8169_PHYstatus */ |
199 | TBI_Enable = 0x80, | 199 | TBI_Enable = 0x80, |
200 | TxFlowCtrl = 0x40, | 200 | TxFlowCtrl = 0x40, |
201 | RxFlowCtrl = 0x20, | 201 | RxFlowCtrl = 0x20, |
202 | _1000bpsF = 0x10, | 202 | _1000bpsF = 0x10, |
203 | _100bps = 0x08, | 203 | _100bps = 0x08, |
204 | _10bps = 0x04, | 204 | _10bps = 0x04, |
205 | LinkStatus = 0x02, | 205 | LinkStatus = 0x02, |
206 | FullDup = 0x01, | 206 | FullDup = 0x01, |
207 | 207 | ||
208 | /*GIGABIT_PHY_registers */ | 208 | /*GIGABIT_PHY_registers */ |
209 | PHY_CTRL_REG = 0, | 209 | PHY_CTRL_REG = 0, |
210 | PHY_STAT_REG = 1, | 210 | PHY_STAT_REG = 1, |
211 | PHY_AUTO_NEGO_REG = 4, | 211 | PHY_AUTO_NEGO_REG = 4, |
212 | PHY_1000_CTRL_REG = 9, | 212 | PHY_1000_CTRL_REG = 9, |
213 | 213 | ||
214 | /*GIGABIT_PHY_REG_BIT */ | 214 | /*GIGABIT_PHY_REG_BIT */ |
215 | PHY_Restart_Auto_Nego = 0x0200, | 215 | PHY_Restart_Auto_Nego = 0x0200, |
216 | PHY_Enable_Auto_Nego = 0x1000, | 216 | PHY_Enable_Auto_Nego = 0x1000, |
217 | 217 | ||
218 | /* PHY_STAT_REG = 1; */ | 218 | /* PHY_STAT_REG = 1; */ |
219 | PHY_Auto_Nego_Comp = 0x0020, | 219 | PHY_Auto_Nego_Comp = 0x0020, |
220 | 220 | ||
221 | /* PHY_AUTO_NEGO_REG = 4; */ | 221 | /* PHY_AUTO_NEGO_REG = 4; */ |
222 | PHY_Cap_10_Half = 0x0020, | 222 | PHY_Cap_10_Half = 0x0020, |
223 | PHY_Cap_10_Full = 0x0040, | 223 | PHY_Cap_10_Full = 0x0040, |
224 | PHY_Cap_100_Half = 0x0080, | 224 | PHY_Cap_100_Half = 0x0080, |
225 | PHY_Cap_100_Full = 0x0100, | 225 | PHY_Cap_100_Full = 0x0100, |
226 | 226 | ||
227 | /* PHY_1000_CTRL_REG = 9; */ | 227 | /* PHY_1000_CTRL_REG = 9; */ |
228 | PHY_Cap_1000_Full = 0x0200, | 228 | PHY_Cap_1000_Full = 0x0200, |
229 | 229 | ||
230 | PHY_Cap_Null = 0x0, | 230 | PHY_Cap_Null = 0x0, |
231 | 231 | ||
232 | /*_MediaType*/ | 232 | /*_MediaType*/ |
233 | _10_Half = 0x01, | 233 | _10_Half = 0x01, |
234 | _10_Full = 0x02, | 234 | _10_Full = 0x02, |
235 | _100_Half = 0x04, | 235 | _100_Half = 0x04, |
236 | _100_Full = 0x08, | 236 | _100_Full = 0x08, |
237 | _1000_Full = 0x10, | 237 | _1000_Full = 0x10, |
238 | 238 | ||
239 | /*_TBICSRBit*/ | 239 | /*_TBICSRBit*/ |
240 | TBILinkOK = 0x02000000, | 240 | TBILinkOK = 0x02000000, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | static struct { | 243 | static struct { |
244 | const char *name; | 244 | const char *name; |
245 | u8 version; /* depend on RTL8169 docs */ | 245 | u8 version; /* depend on RTL8169 docs */ |
246 | u32 RxConfigMask; /* should clear the bits supported by this chip */ | 246 | u32 RxConfigMask; /* should clear the bits supported by this chip */ |
247 | } rtl_chip_info[] = { | 247 | } rtl_chip_info[] = { |
248 | {"RTL-8169", 0x00, 0xff7e1880,}, | 248 | {"RTL-8169", 0x00, 0xff7e1880,}, |
249 | {"RTL-8169", 0x04, 0xff7e1880,}, | 249 | {"RTL-8169", 0x04, 0xff7e1880,}, |
250 | {"RTL-8169", 0x00, 0xff7e1880,}, | ||
251 | {"RTL-8169s/8110s", 0x02, 0xff7e1880,}, | ||
252 | {"RTL-8169s/8110s", 0x04, 0xff7e1880,}, | ||
253 | {"RTL-8169sb/8110sb", 0x10, 0xff7e1880,}, | ||
254 | {"RTL-8169sc/8110sc", 0x18, 0xff7e1880,}, | ||
255 | {"RTL-8168b/8111sb", 0x30, 0xff7e1880,}, | ||
256 | {"RTL-8168b/8111sb", 0x38, 0xff7e1880,}, | ||
257 | {"RTL-8101e", 0x34, 0xff7e1880,}, | ||
258 | {"RTL-8100e", 0x32, 0xff7e1880,}, | ||
250 | }; | 259 | }; |
251 | 260 | ||
252 | enum _DescStatusBit { | 261 | enum _DescStatusBit { |
253 | OWNbit = 0x80000000, | 262 | OWNbit = 0x80000000, |
254 | EORbit = 0x40000000, | 263 | EORbit = 0x40000000, |
255 | FSbit = 0x20000000, | 264 | FSbit = 0x20000000, |
256 | LSbit = 0x10000000, | 265 | LSbit = 0x10000000, |
257 | }; | 266 | }; |
258 | 267 | ||
259 | struct TxDesc { | 268 | struct TxDesc { |
260 | u32 status; | 269 | u32 status; |
261 | u32 vlan_tag; | 270 | u32 vlan_tag; |
262 | u32 buf_addr; | 271 | u32 buf_addr; |
263 | u32 buf_Haddr; | 272 | u32 buf_Haddr; |
264 | }; | 273 | }; |
265 | 274 | ||
266 | struct RxDesc { | 275 | struct RxDesc { |
267 | u32 status; | 276 | u32 status; |
268 | u32 vlan_tag; | 277 | u32 vlan_tag; |
269 | u32 buf_addr; | 278 | u32 buf_addr; |
270 | u32 buf_Haddr; | 279 | u32 buf_Haddr; |
271 | }; | 280 | }; |
272 | 281 | ||
273 | /* Define the TX Descriptor */ | 282 | /* Define the TX Descriptor */ |
274 | static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256]; | 283 | static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256]; |
275 | /* __attribute__ ((aligned(256))); */ | 284 | /* __attribute__ ((aligned(256))); */ |
276 | 285 | ||
277 | /* Create a static buffer of size RX_BUF_SZ for each | 286 | /* Create a static buffer of size RX_BUF_SZ for each |
278 | TX Descriptor. All descriptors point to a | 287 | TX Descriptor. All descriptors point to a |
279 | part of this buffer */ | 288 | part of this buffer */ |
280 | static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE]; | 289 | static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE]; |
281 | 290 | ||
282 | /* Define the RX Descriptor */ | 291 | /* Define the RX Descriptor */ |
283 | static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256]; | 292 | static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256]; |
284 | /* __attribute__ ((aligned(256))); */ | 293 | /* __attribute__ ((aligned(256))); */ |
285 | 294 | ||
286 | /* Create a static buffer of size RX_BUF_SZ for each | 295 | /* Create a static buffer of size RX_BUF_SZ for each |
287 | RX Descriptor All descriptors point to a | 296 | RX Descriptor All descriptors point to a |
288 | part of this buffer */ | 297 | part of this buffer */ |
289 | static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]; | 298 | static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]; |
290 | 299 | ||
291 | struct rtl8169_private { | 300 | struct rtl8169_private { |
292 | void *mmio_addr; /* memory map physical address */ | 301 | void *mmio_addr; /* memory map physical address */ |
293 | int chipset; | 302 | int chipset; |
294 | unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ | 303 | unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ |
295 | unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ | 304 | unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ |
296 | unsigned long dirty_tx; | 305 | unsigned long dirty_tx; |
297 | unsigned char *TxDescArrays; /* Index of Tx Descriptor buffer */ | 306 | unsigned char *TxDescArrays; /* Index of Tx Descriptor buffer */ |
298 | unsigned char *RxDescArrays; /* Index of Rx Descriptor buffer */ | 307 | unsigned char *RxDescArrays; /* Index of Rx Descriptor buffer */ |
299 | struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */ | 308 | struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */ |
300 | struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */ | 309 | struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */ |
301 | unsigned char *RxBufferRings; /* Index of Rx Buffer */ | 310 | unsigned char *RxBufferRings; /* Index of Rx Buffer */ |
302 | unsigned char *RxBufferRing[NUM_RX_DESC]; /* Index of Rx Buffer array */ | 311 | unsigned char *RxBufferRing[NUM_RX_DESC]; /* Index of Rx Buffer array */ |
303 | unsigned char *Tx_skbuff[NUM_TX_DESC]; | 312 | unsigned char *Tx_skbuff[NUM_TX_DESC]; |
304 | } tpx; | 313 | } tpx; |
305 | 314 | ||
306 | static struct rtl8169_private *tpc; | 315 | static struct rtl8169_private *tpc; |
307 | 316 | ||
308 | static const u16 rtl8169_intr_mask = | 317 | static const u16 rtl8169_intr_mask = |
309 | SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | | 318 | SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | |
310 | TxOK | RxErr | RxOK; | 319 | TxOK | RxErr | RxOK; |
311 | static const unsigned int rtl8169_rx_config = | 320 | static const unsigned int rtl8169_rx_config = |
312 | (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); | 321 | (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); |
313 | 322 | ||
314 | static struct pci_device_id supported[] = { | 323 | static struct pci_device_id supported[] = { |
324 | {PCI_VENDOR_ID_REALTEK, 0x8167}, | ||
315 | {PCI_VENDOR_ID_REALTEK, 0x8169}, | 325 | {PCI_VENDOR_ID_REALTEK, 0x8169}, |
316 | {} | 326 | {} |
317 | }; | 327 | }; |
318 | 328 | ||
319 | void mdio_write(int RegAddr, int value) | 329 | void mdio_write(int RegAddr, int value) |
320 | { | 330 | { |
321 | int i; | 331 | int i; |
322 | 332 | ||
323 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); | 333 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); |
324 | udelay(1000); | 334 | udelay(1000); |
325 | 335 | ||
326 | for (i = 2000; i > 0; i--) { | 336 | for (i = 2000; i > 0; i--) { |
327 | /* Check if the RTL8169 has completed writing to the specified MII register */ | 337 | /* Check if the RTL8169 has completed writing to the specified MII register */ |
328 | if (!(RTL_R32(PHYAR) & 0x80000000)) { | 338 | if (!(RTL_R32(PHYAR) & 0x80000000)) { |
329 | break; | 339 | break; |
330 | } else { | 340 | } else { |
331 | udelay(100); | 341 | udelay(100); |
332 | } | 342 | } |
333 | } | 343 | } |
334 | } | 344 | } |
335 | 345 | ||
336 | int mdio_read(int RegAddr) | 346 | int mdio_read(int RegAddr) |
337 | { | 347 | { |
338 | int i, value = -1; | 348 | int i, value = -1; |
339 | 349 | ||
340 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); | 350 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); |
341 | udelay(1000); | 351 | udelay(1000); |
342 | 352 | ||
343 | for (i = 2000; i > 0; i--) { | 353 | for (i = 2000; i > 0; i--) { |
344 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ | 354 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ |
345 | if (RTL_R32(PHYAR) & 0x80000000) { | 355 | if (RTL_R32(PHYAR) & 0x80000000) { |
346 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); | 356 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); |
347 | break; | 357 | break; |
348 | } else { | 358 | } else { |
349 | udelay(100); | 359 | udelay(100); |
350 | } | 360 | } |
351 | } | 361 | } |
352 | return value; | 362 | return value; |
353 | } | 363 | } |
354 | 364 | ||
355 | static int rtl8169_init_board(struct eth_device *dev) | 365 | static int rtl8169_init_board(struct eth_device *dev) |
356 | { | 366 | { |
357 | int i; | 367 | int i; |
358 | u32 tmp; | 368 | u32 tmp; |
359 | 369 | ||
360 | #ifdef DEBUG_RTL8169 | 370 | #ifdef DEBUG_RTL8169 |
361 | printf ("%s\n", __FUNCTION__); | 371 | printf ("%s\n", __FUNCTION__); |
362 | #endif | 372 | #endif |
363 | ioaddr = dev->iobase; | 373 | ioaddr = dev->iobase; |
364 | 374 | ||
365 | /* Soft reset the chip. */ | 375 | /* Soft reset the chip. */ |
366 | RTL_W8(ChipCmd, CmdReset); | 376 | RTL_W8(ChipCmd, CmdReset); |
367 | 377 | ||
368 | /* Check that the chip has finished the reset. */ | 378 | /* Check that the chip has finished the reset. */ |
369 | for (i = 1000; i > 0; i--) | 379 | for (i = 1000; i > 0; i--) |
370 | if ((RTL_R8(ChipCmd) & CmdReset) == 0) | 380 | if ((RTL_R8(ChipCmd) & CmdReset) == 0) |
371 | break; | 381 | break; |
372 | else | 382 | else |
373 | udelay(10); | 383 | udelay(10); |
374 | 384 | ||
375 | /* identify chip attached to board */ | 385 | /* identify chip attached to board */ |
376 | tmp = RTL_R32(TxConfig); | 386 | tmp = RTL_R32(TxConfig); |
377 | tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24; | 387 | tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24; |
378 | 388 | ||
379 | for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--){ | 389 | for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--){ |
380 | if (tmp == rtl_chip_info[i].version) { | 390 | if (tmp == rtl_chip_info[i].version) { |
381 | tpc->chipset = i; | 391 | tpc->chipset = i; |
382 | goto match; | 392 | goto match; |
383 | } | 393 | } |
384 | } | 394 | } |
385 | 395 | ||
386 | /* if unknown chip, assume array element #0, original RTL-8169 in this case */ | 396 | /* if unknown chip, assume array element #0, original RTL-8169 in this case */ |
387 | printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name); | 397 | printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name); |
388 | printf("PCI device: TxConfig = 0x%hX\n", (unsigned long) RTL_R32(TxConfig)); | 398 | printf("PCI device: TxConfig = 0x%hX\n", (unsigned long) RTL_R32(TxConfig)); |
389 | tpc->chipset = 0; | 399 | tpc->chipset = 0; |
390 | 400 | ||
391 | match: | 401 | match: |
392 | return 0; | 402 | return 0; |
393 | } | 403 | } |
394 | 404 | ||
395 | /************************************************************************** | 405 | /************************************************************************** |
396 | RECV - Receive a frame | 406 | RECV - Receive a frame |
397 | ***************************************************************************/ | 407 | ***************************************************************************/ |
398 | static int rtl_recv(struct eth_device *dev) | 408 | static int rtl_recv(struct eth_device *dev) |
399 | { | 409 | { |
400 | /* return true if there's an ethernet packet ready to read */ | 410 | /* return true if there's an ethernet packet ready to read */ |
401 | /* nic->packet should contain data on return */ | 411 | /* nic->packet should contain data on return */ |
402 | /* nic->packetlen should contain length of data */ | 412 | /* nic->packetlen should contain length of data */ |
403 | int cur_rx; | 413 | int cur_rx; |
404 | int length = 0; | 414 | int length = 0; |
405 | 415 | ||
406 | #ifdef DEBUG_RTL8169_RX | 416 | #ifdef DEBUG_RTL8169_RX |
407 | printf ("%s\n", __FUNCTION__); | 417 | printf ("%s\n", __FUNCTION__); |
408 | #endif | 418 | #endif |
409 | ioaddr = dev->iobase; | 419 | ioaddr = dev->iobase; |
410 | 420 | ||
411 | cur_rx = tpc->cur_rx; | 421 | cur_rx = tpc->cur_rx; |
412 | if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { | 422 | if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { |
413 | if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { | 423 | if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { |
414 | unsigned char rxdata[RX_BUF_LEN]; | 424 | unsigned char rxdata[RX_BUF_LEN]; |
415 | length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. | 425 | length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. |
416 | status) & 0x00001FFF) - 4; | 426 | status) & 0x00001FFF) - 4; |
417 | 427 | ||
418 | memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); | 428 | memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); |
419 | NetReceive(rxdata, length); | 429 | NetReceive(rxdata, length); |
420 | 430 | ||
421 | if (cur_rx == NUM_RX_DESC - 1) | 431 | if (cur_rx == NUM_RX_DESC - 1) |
422 | tpc->RxDescArray[cur_rx].status = | 432 | tpc->RxDescArray[cur_rx].status = |
423 | cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); | 433 | cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); |
424 | else | 434 | else |
425 | tpc->RxDescArray[cur_rx].status = | 435 | tpc->RxDescArray[cur_rx].status = |
426 | cpu_to_le32(OWNbit + RX_BUF_SIZE); | 436 | cpu_to_le32(OWNbit + RX_BUF_SIZE); |
427 | tpc->RxDescArray[cur_rx].buf_addr = | 437 | tpc->RxDescArray[cur_rx].buf_addr = |
428 | cpu_to_le32(tpc->RxBufferRing[cur_rx]); | 438 | cpu_to_le32(tpc->RxBufferRing[cur_rx]); |
429 | } else { | 439 | } else { |
430 | puts("Error Rx"); | 440 | puts("Error Rx"); |
431 | } | 441 | } |
432 | cur_rx = (cur_rx + 1) % NUM_RX_DESC; | 442 | cur_rx = (cur_rx + 1) % NUM_RX_DESC; |
433 | tpc->cur_rx = cur_rx; | 443 | tpc->cur_rx = cur_rx; |
434 | return 1; | 444 | return 1; |
435 | 445 | ||
446 | } else { | ||
447 | ushort sts = RTL_R8(IntrStatus); | ||
448 | RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); | ||
449 | udelay(100); /* wait */ | ||
436 | } | 450 | } |
437 | tpc->cur_rx = cur_rx; | 451 | tpc->cur_rx = cur_rx; |
438 | return (0); /* initially as this is called to flush the input */ | 452 | return (0); /* initially as this is called to flush the input */ |
439 | } | 453 | } |
440 | 454 | ||
441 | #define HZ 1000 | 455 | #define HZ 1000 |
442 | /************************************************************************** | 456 | /************************************************************************** |
443 | SEND - Transmit a frame | 457 | SEND - Transmit a frame |
444 | ***************************************************************************/ | 458 | ***************************************************************************/ |
445 | static int rtl_send(struct eth_device *dev, volatile void *packet, int length) | 459 | static int rtl_send(struct eth_device *dev, volatile void *packet, int length) |
446 | { | 460 | { |
447 | /* send the packet to destination */ | 461 | /* send the packet to destination */ |
448 | 462 | ||
449 | u32 to; | 463 | u32 to; |
450 | u8 *ptxb; | 464 | u8 *ptxb; |
451 | int entry = tpc->cur_tx % NUM_TX_DESC; | 465 | int entry = tpc->cur_tx % NUM_TX_DESC; |
452 | u32 len = length; | 466 | u32 len = length; |
453 | int ret; | 467 | int ret; |
454 | 468 | ||
455 | #ifdef DEBUG_RTL8169_TX | 469 | #ifdef DEBUG_RTL8169_TX |
456 | int stime = currticks(); | 470 | int stime = currticks(); |
457 | printf ("%s\n", __FUNCTION__); | 471 | printf ("%s\n", __FUNCTION__); |
458 | printf("sending %d bytes\n", len); | 472 | printf("sending %d bytes\n", len); |
459 | #endif | 473 | #endif |
460 | 474 | ||
461 | ioaddr = dev->iobase; | 475 | ioaddr = dev->iobase; |
462 | 476 | ||
463 | /* point to the current txb incase multiple tx_rings are used */ | 477 | /* point to the current txb incase multiple tx_rings are used */ |
464 | ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE]; | 478 | ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE]; |
465 | memcpy(ptxb, (char *)packet, (int)length); | 479 | memcpy(ptxb, (char *)packet, (int)length); |
466 | 480 | ||
467 | while (len < ETH_ZLEN) | 481 | while (len < ETH_ZLEN) |
468 | ptxb[len++] = '\0'; | 482 | ptxb[len++] = '\0'; |
469 | 483 | ||
470 | tpc->TxDescArray[entry].buf_addr = cpu_to_le32(ptxb); | 484 | tpc->TxDescArray[entry].buf_addr = cpu_to_le32(ptxb); |
471 | if (entry != (NUM_TX_DESC - 1)) { | 485 | if (entry != (NUM_TX_DESC - 1)) { |
472 | tpc->TxDescArray[entry].status = | 486 | tpc->TxDescArray[entry].status = |
473 | cpu_to_le32((OWNbit | FSbit | LSbit) | | 487 | cpu_to_le32((OWNbit | FSbit | LSbit) | |
474 | ((len > ETH_ZLEN) ? len : ETH_ZLEN)); | 488 | ((len > ETH_ZLEN) ? len : ETH_ZLEN)); |
475 | } else { | 489 | } else { |
476 | tpc->TxDescArray[entry].status = | 490 | tpc->TxDescArray[entry].status = |
477 | cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | | 491 | cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | |
478 | ((len > ETH_ZLEN) ? len : ETH_ZLEN)); | 492 | ((len > ETH_ZLEN) ? len : ETH_ZLEN)); |
479 | } | 493 | } |
480 | RTL_W8(TxPoll, 0x40); /* set polling bit */ | 494 | RTL_W8(TxPoll, 0x40); /* set polling bit */ |
481 | 495 | ||
482 | tpc->cur_tx++; | 496 | tpc->cur_tx++; |
483 | to = currticks() + TX_TIMEOUT; | 497 | to = currticks() + TX_TIMEOUT; |
484 | while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit) | 498 | while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit) |
485 | && (currticks() < to)); /* wait */ | 499 | && (currticks() < to)); /* wait */ |
486 | 500 | ||
487 | if (currticks() >= to) { | 501 | if (currticks() >= to) { |
488 | #ifdef DEBUG_RTL8169_TX | 502 | #ifdef DEBUG_RTL8169_TX |
489 | puts ("tx timeout/error\n"); | 503 | puts ("tx timeout/error\n"); |
490 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); | 504 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); |
491 | #endif | 505 | #endif |
492 | ret = 0; | 506 | ret = 0; |
493 | } else { | 507 | } else { |
494 | #ifdef DEBUG_RTL8169_TX | 508 | #ifdef DEBUG_RTL8169_TX |
495 | puts("tx done\n"); | 509 | puts("tx done\n"); |
496 | #endif | 510 | #endif |
497 | ret = length; | 511 | ret = length; |
498 | } | 512 | } |
499 | /* Delay to make net console (nc) work properly */ | 513 | /* Delay to make net console (nc) work properly */ |
500 | udelay(20); | 514 | udelay(20); |
501 | return ret; | 515 | return ret; |
502 | } | 516 | } |
503 | 517 | ||
504 | static void rtl8169_set_rx_mode(struct eth_device *dev) | 518 | static void rtl8169_set_rx_mode(struct eth_device *dev) |
505 | { | 519 | { |
506 | u32 mc_filter[2]; /* Multicast hash filter */ | 520 | u32 mc_filter[2]; /* Multicast hash filter */ |
507 | int rx_mode; | 521 | int rx_mode; |
508 | u32 tmp = 0; | 522 | u32 tmp = 0; |
509 | 523 | ||
510 | #ifdef DEBUG_RTL8169 | 524 | #ifdef DEBUG_RTL8169 |
511 | printf ("%s\n", __FUNCTION__); | 525 | printf ("%s\n", __FUNCTION__); |
512 | #endif | 526 | #endif |
513 | 527 | ||
514 | /* IFF_ALLMULTI */ | 528 | /* IFF_ALLMULTI */ |
515 | /* Too many to filter perfectly -- accept all multicasts. */ | 529 | /* Too many to filter perfectly -- accept all multicasts. */ |
516 | rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; | 530 | rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; |
517 | mc_filter[1] = mc_filter[0] = 0xffffffff; | 531 | mc_filter[1] = mc_filter[0] = 0xffffffff; |
518 | 532 | ||
519 | tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) & | 533 | tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) & |
520 | rtl_chip_info[tpc->chipset].RxConfigMask); | 534 | rtl_chip_info[tpc->chipset].RxConfigMask); |
521 | 535 | ||
522 | RTL_W32(RxConfig, tmp); | 536 | RTL_W32(RxConfig, tmp); |
523 | RTL_W32(MAR0 + 0, mc_filter[0]); | 537 | RTL_W32(MAR0 + 0, mc_filter[0]); |
524 | RTL_W32(MAR0 + 4, mc_filter[1]); | 538 | RTL_W32(MAR0 + 4, mc_filter[1]); |
525 | } | 539 | } |
526 | 540 | ||
527 | static void rtl8169_hw_start(struct eth_device *dev) | 541 | static void rtl8169_hw_start(struct eth_device *dev) |
528 | { | 542 | { |
529 | u32 i; | 543 | u32 i; |
530 | 544 | ||
531 | #ifdef DEBUG_RTL8169 | 545 | #ifdef DEBUG_RTL8169 |
532 | int stime = currticks(); | 546 | int stime = currticks(); |
533 | printf ("%s\n", __FUNCTION__); | 547 | printf ("%s\n", __FUNCTION__); |
534 | #endif | 548 | #endif |
535 | 549 | ||
536 | #if 0 | 550 | #if 0 |
537 | /* Soft reset the chip. */ | 551 | /* Soft reset the chip. */ |
538 | RTL_W8(ChipCmd, CmdReset); | 552 | RTL_W8(ChipCmd, CmdReset); |
539 | 553 | ||
540 | /* Check that the chip has finished the reset. */ | 554 | /* Check that the chip has finished the reset. */ |
541 | for (i = 1000; i > 0; i--) { | 555 | for (i = 1000; i > 0; i--) { |
542 | if ((RTL_R8(ChipCmd) & CmdReset) == 0) | 556 | if ((RTL_R8(ChipCmd) & CmdReset) == 0) |
543 | break; | 557 | break; |
544 | else | 558 | else |
545 | udelay(10); | 559 | udelay(10); |
546 | } | 560 | } |
547 | #endif | 561 | #endif |
548 | 562 | ||
549 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 563 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
550 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | 564 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); |
551 | RTL_W8(EarlyTxThres, EarlyTxThld); | 565 | RTL_W8(EarlyTxThres, EarlyTxThld); |
552 | 566 | ||
553 | /* For gigabit rtl8169 */ | 567 | /* For gigabit rtl8169 */ |
554 | RTL_W16(RxMaxSize, RxPacketMaxSize); | 568 | RTL_W16(RxMaxSize, RxPacketMaxSize); |
555 | 569 | ||
556 | /* Set Rx Config register */ | 570 | /* Set Rx Config register */ |
557 | i = rtl8169_rx_config | (RTL_R32(RxConfig) & | 571 | i = rtl8169_rx_config | (RTL_R32(RxConfig) & |
558 | rtl_chip_info[tpc->chipset].RxConfigMask); | 572 | rtl_chip_info[tpc->chipset].RxConfigMask); |
559 | RTL_W32(RxConfig, i); | 573 | RTL_W32(RxConfig, i); |
560 | 574 | ||
561 | /* Set DMA burst size and Interframe Gap Time */ | 575 | /* Set DMA burst size and Interframe Gap Time */ |
562 | RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | | 576 | RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | |
563 | (InterFrameGap << TxInterFrameGapShift)); | 577 | (InterFrameGap << TxInterFrameGapShift)); |
564 | 578 | ||
565 | 579 | ||
566 | tpc->cur_rx = 0; | 580 | tpc->cur_rx = 0; |
567 | 581 | ||
568 | RTL_W32(TxDescStartAddr, tpc->TxDescArray); | 582 | RTL_W32(TxDescStartAddr, tpc->TxDescArray); |
569 | RTL_W32(RxDescStartAddr, tpc->RxDescArray); | 583 | RTL_W32(RxDescStartAddr, tpc->RxDescArray); |
570 | RTL_W8(Cfg9346, Cfg9346_Lock); | 584 | RTL_W8(Cfg9346, Cfg9346_Lock); |
571 | udelay(10); | 585 | udelay(10); |
572 | 586 | ||
573 | RTL_W32(RxMissed, 0); | 587 | RTL_W32(RxMissed, 0); |
574 | 588 | ||
575 | rtl8169_set_rx_mode(dev); | 589 | rtl8169_set_rx_mode(dev); |
576 | 590 | ||
577 | /* no early-rx interrupts */ | 591 | /* no early-rx interrupts */ |
578 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); | 592 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); |
579 | 593 | ||
580 | #ifdef DEBUG_RTL8169 | 594 | #ifdef DEBUG_RTL8169 |
581 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); | 595 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); |
582 | #endif | 596 | #endif |
583 | } | 597 | } |
584 | 598 | ||
585 | static void rtl8169_init_ring(struct eth_device *dev) | 599 | static void rtl8169_init_ring(struct eth_device *dev) |
586 | { | 600 | { |
587 | int i; | 601 | int i; |
588 | 602 | ||
589 | #ifdef DEBUG_RTL8169 | 603 | #ifdef DEBUG_RTL8169 |
590 | int stime = currticks(); | 604 | int stime = currticks(); |
591 | printf ("%s\n", __FUNCTION__); | 605 | printf ("%s\n", __FUNCTION__); |
592 | #endif | 606 | #endif |
593 | 607 | ||
594 | tpc->cur_rx = 0; | 608 | tpc->cur_rx = 0; |
595 | tpc->cur_tx = 0; | 609 | tpc->cur_tx = 0; |
596 | tpc->dirty_tx = 0; | 610 | tpc->dirty_tx = 0; |
597 | memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc)); | 611 | memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc)); |
598 | memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc)); | 612 | memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc)); |
599 | 613 | ||
600 | for (i = 0; i < NUM_TX_DESC; i++) { | 614 | for (i = 0; i < NUM_TX_DESC; i++) { |
601 | tpc->Tx_skbuff[i] = &txb[i]; | 615 | tpc->Tx_skbuff[i] = &txb[i]; |
602 | } | 616 | } |
603 | 617 | ||
604 | for (i = 0; i < NUM_RX_DESC; i++) { | 618 | for (i = 0; i < NUM_RX_DESC; i++) { |
605 | if (i == (NUM_RX_DESC - 1)) | 619 | if (i == (NUM_RX_DESC - 1)) |
606 | tpc->RxDescArray[i].status = | 620 | tpc->RxDescArray[i].status = |
607 | cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); | 621 | cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); |
608 | else | 622 | else |
609 | tpc->RxDescArray[i].status = | 623 | tpc->RxDescArray[i].status = |
610 | cpu_to_le32(OWNbit + RX_BUF_SIZE); | 624 | cpu_to_le32(OWNbit + RX_BUF_SIZE); |
611 | 625 | ||
612 | tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; | 626 | tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; |
613 | tpc->RxDescArray[i].buf_addr = | 627 | tpc->RxDescArray[i].buf_addr = |
614 | cpu_to_le32(tpc->RxBufferRing[i]); | 628 | cpu_to_le32(tpc->RxBufferRing[i]); |
615 | } | 629 | } |
616 | 630 | ||
617 | #ifdef DEBUG_RTL8169 | 631 | #ifdef DEBUG_RTL8169 |
618 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); | 632 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); |
619 | #endif | 633 | #endif |
620 | } | 634 | } |
621 | 635 | ||
622 | /************************************************************************** | 636 | /************************************************************************** |
623 | RESET - Finish setting up the ethernet interface | 637 | RESET - Finish setting up the ethernet interface |
624 | ***************************************************************************/ | 638 | ***************************************************************************/ |
625 | static int rtl_reset(struct eth_device *dev, bd_t *bis) | 639 | static int rtl_reset(struct eth_device *dev, bd_t *bis) |
626 | { | 640 | { |
627 | int i; | 641 | int i; |
628 | 642 | ||
629 | #ifdef DEBUG_RTL8169 | 643 | #ifdef DEBUG_RTL8169 |
630 | int stime = currticks(); | 644 | int stime = currticks(); |
631 | printf ("%s\n", __FUNCTION__); | 645 | printf ("%s\n", __FUNCTION__); |
632 | #endif | 646 | #endif |
633 | 647 | ||
634 | tpc->TxDescArrays = tx_ring; | 648 | tpc->TxDescArrays = tx_ring; |
635 | /* Tx Desscriptor needs 256 bytes alignment; */ | 649 | /* Tx Desscriptor needs 256 bytes alignment; */ |
636 | tpc->TxDescArray = (struct TxDesc *) ((unsigned long)(tpc->TxDescArrays + | 650 | tpc->TxDescArray = (struct TxDesc *) ((unsigned long)(tpc->TxDescArrays + |
637 | 255) & ~255); | 651 | 255) & ~255); |
638 | 652 | ||
639 | tpc->RxDescArrays = rx_ring; | 653 | tpc->RxDescArrays = rx_ring; |
640 | /* Rx Desscriptor needs 256 bytes alignment; */ | 654 | /* Rx Desscriptor needs 256 bytes alignment; */ |
641 | tpc->RxDescArray = (struct RxDesc *) ((unsigned long)(tpc->RxDescArrays + | 655 | tpc->RxDescArray = (struct RxDesc *) ((unsigned long)(tpc->RxDescArrays + |
642 | 255) & ~255); | 656 | 255) & ~255); |
643 | 657 | ||
644 | rtl8169_init_ring(dev); | 658 | rtl8169_init_ring(dev); |
645 | rtl8169_hw_start(dev); | 659 | rtl8169_hw_start(dev); |
646 | /* Construct a perfect filter frame with the mac address as first match | 660 | /* Construct a perfect filter frame with the mac address as first match |
647 | * and broadcast for all others */ | 661 | * and broadcast for all others */ |
648 | for (i = 0; i < 192; i++) | 662 | for (i = 0; i < 192; i++) |
649 | txb[i] = 0xFF; | 663 | txb[i] = 0xFF; |
650 | 664 | ||
651 | txb[0] = dev->enetaddr[0]; | 665 | txb[0] = dev->enetaddr[0]; |
652 | txb[1] = dev->enetaddr[1]; | 666 | txb[1] = dev->enetaddr[1]; |
653 | txb[2] = dev->enetaddr[2]; | 667 | txb[2] = dev->enetaddr[2]; |
654 | txb[3] = dev->enetaddr[3]; | 668 | txb[3] = dev->enetaddr[3]; |
655 | txb[4] = dev->enetaddr[4]; | 669 | txb[4] = dev->enetaddr[4]; |
656 | txb[5] = dev->enetaddr[5]; | 670 | txb[5] = dev->enetaddr[5]; |
657 | 671 | ||
658 | #ifdef DEBUG_RTL8169 | 672 | #ifdef DEBUG_RTL8169 |
659 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); | 673 | printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); |
660 | #endif | 674 | #endif |
661 | return 0; | 675 | return 0; |
662 | } | 676 | } |
663 | 677 | ||
664 | /************************************************************************** | 678 | /************************************************************************** |
665 | HALT - Turn off ethernet interface | 679 | HALT - Turn off ethernet interface |
666 | ***************************************************************************/ | 680 | ***************************************************************************/ |
667 | static void rtl_halt(struct eth_device *dev) | 681 | static void rtl_halt(struct eth_device *dev) |
668 | { | 682 | { |
669 | int i; | 683 | int i; |
670 | 684 | ||
671 | #ifdef DEBUG_RTL8169 | 685 | #ifdef DEBUG_RTL8169 |
672 | printf ("%s\n", __FUNCTION__); | 686 | printf ("%s\n", __FUNCTION__); |
673 | #endif | 687 | #endif |
674 | 688 | ||
675 | ioaddr = dev->iobase; | 689 | ioaddr = dev->iobase; |
676 | 690 | ||
677 | /* Stop the chip's Tx and Rx DMA processes. */ | 691 | /* Stop the chip's Tx and Rx DMA processes. */ |
678 | RTL_W8(ChipCmd, 0x00); | 692 | RTL_W8(ChipCmd, 0x00); |
679 | 693 | ||
680 | /* Disable interrupts by clearing the interrupt mask. */ | 694 | /* Disable interrupts by clearing the interrupt mask. */ |
681 | RTL_W16(IntrMask, 0x0000); | 695 | RTL_W16(IntrMask, 0x0000); |
682 | 696 | ||
683 | RTL_W32(RxMissed, 0); | 697 | RTL_W32(RxMissed, 0); |
684 | 698 | ||
685 | tpc->TxDescArrays = NULL; | 699 | tpc->TxDescArrays = NULL; |
686 | tpc->RxDescArrays = NULL; | 700 | tpc->RxDescArrays = NULL; |
687 | tpc->TxDescArray = NULL; | 701 | tpc->TxDescArray = NULL; |
688 | tpc->RxDescArray = NULL; | 702 | tpc->RxDescArray = NULL; |
689 | for (i = 0; i < NUM_RX_DESC; i++) { | 703 | for (i = 0; i < NUM_RX_DESC; i++) { |
690 | tpc->RxBufferRing[i] = NULL; | 704 | tpc->RxBufferRing[i] = NULL; |
691 | } | 705 | } |
692 | } | 706 | } |
693 | 707 | ||
694 | /************************************************************************** | 708 | /************************************************************************** |
695 | INIT - Look for an adapter, this routine's visible to the outside | 709 | INIT - Look for an adapter, this routine's visible to the outside |
696 | ***************************************************************************/ | 710 | ***************************************************************************/ |
697 | 711 | ||
698 | #define board_found 1 | 712 | #define board_found 1 |
699 | #define valid_link 0 | 713 | #define valid_link 0 |
700 | static int rtl_init(struct eth_device *dev, bd_t *bis) | 714 | static int rtl_init(struct eth_device *dev, bd_t *bis) |
701 | { | 715 | { |
702 | static int board_idx = -1; | 716 | static int board_idx = -1; |
703 | static int printed_version = 0; | 717 | static int printed_version = 0; |
704 | int i, rc; | 718 | int i, rc; |
705 | int option = -1, Cap10_100 = 0, Cap1000 = 0; | 719 | int option = -1, Cap10_100 = 0, Cap1000 = 0; |
706 | 720 | ||
707 | #ifdef DEBUG_RTL8169 | 721 | #ifdef DEBUG_RTL8169 |
708 | printf ("%s\n", __FUNCTION__); | 722 | printf ("%s\n", __FUNCTION__); |
709 | #endif | 723 | #endif |
710 | 724 | ||
711 | ioaddr = dev->iobase; | 725 | ioaddr = dev->iobase; |
712 | 726 | ||
713 | board_idx++; | 727 | board_idx++; |
714 | 728 | ||
715 | printed_version = 1; | 729 | printed_version = 1; |
716 | 730 | ||
717 | /* point to private storage */ | 731 | /* point to private storage */ |
718 | tpc = &tpx; | 732 | tpc = &tpx; |
719 | 733 | ||
720 | rc = rtl8169_init_board(dev); | 734 | rc = rtl8169_init_board(dev); |
721 | if (rc) | 735 | if (rc) |
722 | return rc; | 736 | return rc; |
723 | 737 | ||
724 | /* Get MAC address. FIXME: read EEPROM */ | 738 | /* Get MAC address. FIXME: read EEPROM */ |
725 | for (i = 0; i < MAC_ADDR_LEN; i++) | 739 | for (i = 0; i < MAC_ADDR_LEN; i++) |
726 | bis->bi_enetaddr[i] = dev->enetaddr[i] = RTL_R8(MAC0 + i); | 740 | bis->bi_enetaddr[i] = dev->enetaddr[i] = RTL_R8(MAC0 + i); |
727 | 741 | ||
728 | #ifdef DEBUG_RTL8169 | 742 | #ifdef DEBUG_RTL8169 |
729 | printf("MAC Address"); | 743 | printf("MAC Address"); |
730 | for (i = 0; i < MAC_ADDR_LEN; i++) | 744 | for (i = 0; i < MAC_ADDR_LEN; i++) |
731 | printf(":%02x", dev->enetaddr[i]); | 745 | printf(":%02x", dev->enetaddr[i]); |
732 | putc('\n'); | 746 | putc('\n'); |
733 | #endif | 747 | #endif |
734 | 748 | ||
735 | #ifdef DEBUG_RTL8169 | 749 | #ifdef DEBUG_RTL8169 |
736 | /* Print out some hardware info */ | 750 | /* Print out some hardware info */ |
737 | printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr); | 751 | printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr); |
738 | #endif | 752 | #endif |
739 | 753 | ||
740 | /* if TBI is not endbled */ | 754 | /* if TBI is not endbled */ |
741 | if (!(RTL_R8(PHYstatus) & TBI_Enable)) { | 755 | if (!(RTL_R8(PHYstatus) & TBI_Enable)) { |
742 | int val = mdio_read(PHY_AUTO_NEGO_REG); | 756 | int val = mdio_read(PHY_AUTO_NEGO_REG); |
743 | 757 | ||
744 | option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx]; | 758 | option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx]; |
745 | /* Force RTL8169 in 10/100/1000 Full/Half mode. */ | 759 | /* Force RTL8169 in 10/100/1000 Full/Half mode. */ |
746 | if (option > 0) { | 760 | if (option > 0) { |
747 | #ifdef DEBUG_RTL8169 | 761 | #ifdef DEBUG_RTL8169 |
748 | printf("%s: Force-mode Enabled.\n", dev->name); | 762 | printf("%s: Force-mode Enabled.\n", dev->name); |
749 | #endif | 763 | #endif |
750 | Cap10_100 = 0, Cap1000 = 0; | 764 | Cap10_100 = 0, Cap1000 = 0; |
751 | switch (option) { | 765 | switch (option) { |
752 | case _10_Half: | 766 | case _10_Half: |
753 | Cap10_100 = PHY_Cap_10_Half; | 767 | Cap10_100 = PHY_Cap_10_Half; |
754 | Cap1000 = PHY_Cap_Null; | 768 | Cap1000 = PHY_Cap_Null; |
755 | break; | 769 | break; |
756 | case _10_Full: | 770 | case _10_Full: |
757 | Cap10_100 = PHY_Cap_10_Full; | 771 | Cap10_100 = PHY_Cap_10_Full; |
758 | Cap1000 = PHY_Cap_Null; | 772 | Cap1000 = PHY_Cap_Null; |
759 | break; | 773 | break; |
760 | case _100_Half: | 774 | case _100_Half: |
761 | Cap10_100 = PHY_Cap_100_Half; | 775 | Cap10_100 = PHY_Cap_100_Half; |
762 | Cap1000 = PHY_Cap_Null; | 776 | Cap1000 = PHY_Cap_Null; |
763 | break; | 777 | break; |
764 | case _100_Full: | 778 | case _100_Full: |
765 | Cap10_100 = PHY_Cap_100_Full; | 779 | Cap10_100 = PHY_Cap_100_Full; |
766 | Cap1000 = PHY_Cap_Null; | 780 | Cap1000 = PHY_Cap_Null; |
767 | break; | 781 | break; |
768 | case _1000_Full: | 782 | case _1000_Full: |
769 | Cap10_100 = PHY_Cap_Null; | 783 | Cap10_100 = PHY_Cap_Null; |
770 | Cap1000 = PHY_Cap_1000_Full; | 784 | Cap1000 = PHY_Cap_1000_Full; |
771 | break; | 785 | break; |
772 | default: | 786 | default: |
773 | break; | 787 | break; |
774 | } | 788 | } |
775 | mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F)); /* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */ | 789 | mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F)); /* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */ |
776 | mdio_write(PHY_1000_CTRL_REG, Cap1000); | 790 | mdio_write(PHY_1000_CTRL_REG, Cap1000); |
777 | } else { | 791 | } else { |
778 | #ifdef DEBUG_RTL8169 | 792 | #ifdef DEBUG_RTL8169 |
779 | printf("%s: Auto-negotiation Enabled.\n", | 793 | printf("%s: Auto-negotiation Enabled.\n", |
780 | dev->name); | 794 | dev->name); |
781 | #endif | 795 | #endif |
782 | /* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */ | 796 | /* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */ |
783 | mdio_write(PHY_AUTO_NEGO_REG, | 797 | mdio_write(PHY_AUTO_NEGO_REG, |
784 | PHY_Cap_10_Half | PHY_Cap_10_Full | | 798 | PHY_Cap_10_Half | PHY_Cap_10_Full | |
785 | PHY_Cap_100_Half | PHY_Cap_100_Full | | 799 | PHY_Cap_100_Half | PHY_Cap_100_Full | |
786 | (val & 0x1F)); | 800 | (val & 0x1F)); |
787 | 801 | ||
788 | /* enable 1000 Full Mode */ | 802 | /* enable 1000 Full Mode */ |
789 | mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full); | 803 | mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full); |
790 | 804 | ||
791 | } | 805 | } |
792 | 806 | ||
793 | /* Enable auto-negotiation and restart auto-nigotiation */ | 807 | /* Enable auto-negotiation and restart auto-nigotiation */ |
794 | mdio_write(PHY_CTRL_REG, | 808 | mdio_write(PHY_CTRL_REG, |
795 | PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego); | 809 | PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego); |
796 | udelay(100); | 810 | udelay(100); |
797 | 811 | ||
798 | /* wait for auto-negotiation process */ | 812 | /* wait for auto-negotiation process */ |
799 | for (i = 10000; i > 0; i--) { | 813 | for (i = 10000; i > 0; i--) { |
800 | /* check if auto-negotiation complete */ | 814 | /* check if auto-negotiation complete */ |
801 | if (mdio_read(PHY_STAT_REG) & PHY_Auto_Nego_Comp) { | 815 | if (mdio_read(PHY_STAT_REG) & PHY_Auto_Nego_Comp) { |
802 | udelay(100); | 816 | udelay(100); |
803 | option = RTL_R8(PHYstatus); | 817 | option = RTL_R8(PHYstatus); |
804 | if (option & _1000bpsF) { | 818 | if (option & _1000bpsF) { |
805 | #ifdef DEBUG_RTL8169 | 819 | #ifdef DEBUG_RTL8169 |
806 | printf("%s: 1000Mbps Full-duplex operation.\n", | 820 | printf("%s: 1000Mbps Full-duplex operation.\n", |
807 | dev->name); | 821 | dev->name); |
808 | #endif | 822 | #endif |
809 | } else { | 823 | } else { |
810 | #ifdef DEBUG_RTL8169 | 824 | #ifdef DEBUG_RTL8169 |
811 | printf("%s: %sMbps %s-duplex operation.\n", | 825 | printf("%s: %sMbps %s-duplex operation.\n", |
812 | dev->name, | 826 | dev->name, |
813 | (option & _100bps) ? "100" : | 827 | (option & _100bps) ? "100" : |
814 | "10", | 828 | "10", |
815 | (option & FullDup) ? "Full" : | 829 | (option & FullDup) ? "Full" : |
816 | "Half"); | 830 | "Half"); |
817 | #endif | 831 | #endif |
818 | } | 832 | } |
819 | break; | 833 | break; |
820 | } else { | 834 | } else { |
821 | udelay(100); | 835 | udelay(100); |
822 | } | 836 | } |
823 | } /* end for-loop to wait for auto-negotiation process */ | 837 | } /* end for-loop to wait for auto-negotiation process */ |
824 | 838 | ||
825 | } else { | 839 | } else { |
826 | udelay(100); | 840 | udelay(100); |
827 | #ifdef DEBUG_RTL8169 | 841 | #ifdef DEBUG_RTL8169 |
828 | printf | 842 | printf |
829 | ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n", | 843 | ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n", |
830 | dev->name, | 844 | dev->name, |
831 | (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed"); | 845 | (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed"); |
832 | #endif | 846 | #endif |
833 | } | 847 | } |
834 | 848 | ||
835 | return 1; | 849 | return 1; |
836 | } | 850 | } |
837 | 851 | ||
838 | int rtl8169_initialize(bd_t *bis) | 852 | int rtl8169_initialize(bd_t *bis) |
839 | { | 853 | { |
840 | pci_dev_t devno; | 854 | pci_dev_t devno; |
841 | int card_number = 0; | 855 | int card_number = 0; |
842 | struct eth_device *dev; | 856 | struct eth_device *dev; |
843 | u32 iobase; | 857 | u32 iobase; |
844 | int idx=0; | 858 | int idx=0; |
845 | 859 | ||
846 | while(1){ | 860 | while(1){ |
847 | /* Find RTL8169 */ | 861 | /* Find RTL8169 */ |
848 | if ((devno = pci_find_devices(supported, idx++)) < 0) | 862 | if ((devno = pci_find_devices(supported, idx++)) < 0) |
849 | break; | 863 | break; |
850 | 864 | ||
851 | pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); | 865 | pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); |
852 | iobase &= ~0xf; | 866 | iobase &= ~0xf; |
853 | 867 | ||
854 | debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase); | 868 | debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase); |
855 | 869 | ||
856 | dev = (struct eth_device *)malloc(sizeof *dev); | 870 | dev = (struct eth_device *)malloc(sizeof *dev); |
857 | 871 | ||
858 | sprintf (dev->name, "RTL8169#%d", card_number); | 872 | sprintf (dev->name, "RTL8169#%d", card_number); |
859 | 873 | ||
860 | dev->priv = (void *) devno; | 874 | dev->priv = (void *) devno; |
861 | dev->iobase = (int)pci_mem_to_phys(devno, iobase); | 875 | dev->iobase = (int)pci_mem_to_phys(devno, iobase); |
862 | 876 | ||
863 | dev->init = rtl_reset; | 877 | dev->init = rtl_reset; |
864 | dev->halt = rtl_halt; | 878 | dev->halt = rtl_halt; |
865 | dev->send = rtl_send; | 879 | dev->send = rtl_send; |
866 | dev->recv = rtl_recv; | 880 | dev->recv = rtl_recv; |
867 | 881 | ||
868 | eth_register (dev); | 882 | eth_register (dev); |
869 | 883 | ||
870 | rtl_init(dev, bis); | 884 | rtl_init(dev, bis); |
871 | 885 | ||
872 | card_number++; | 886 | card_number++; |
873 | } | 887 | } |
874 | return card_number; | 888 | return card_number; |
875 | } | 889 | } |
876 | 890 | ||
877 | #endif | 891 | #endif |
878 | 892 |