]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/smc911x.c
Merge branch 'master' of git://www.denx.de/git/u-boot-at91
[karo-tx-uboot.git] / drivers / net / smc911x.c
1 /*
2  * SMSC LAN9[12]1[567] Network driver
3  *
4  * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26
27 #ifdef CONFIG_DRIVER_SMC911X
28
29 #include <command.h>
30 #include <net.h>
31 #include <miiphy.h>
32
33 #define mdelay(n)       udelay((n)*1000)
34
35 #define __REG(x)     (*((volatile u32 *)(x)))
36
37 /* Below are the register offsets and bit definitions
38  * of the Lan911x memory space
39  */
40 #define RX_DATA_FIFO             __REG(CONFIG_DRIVER_SMC911X_BASE + 0x00)
41
42 #define TX_DATA_FIFO             __REG(CONFIG_DRIVER_SMC911X_BASE + 0x20)
43 #define TX_CMD_A_INT_ON_COMP                    (0x80000000)
44 #define TX_CMD_A_INT_BUF_END_ALGN               (0x03000000)
45 #define TX_CMD_A_INT_4_BYTE_ALGN                (0x00000000)
46 #define TX_CMD_A_INT_16_BYTE_ALGN               (0x01000000)
47 #define TX_CMD_A_INT_32_BYTE_ALGN               (0x02000000)
48 #define TX_CMD_A_INT_DATA_OFFSET                (0x001F0000)
49 #define TX_CMD_A_INT_FIRST_SEG                  (0x00002000)
50 #define TX_CMD_A_INT_LAST_SEG                   (0x00001000)
51 #define TX_CMD_A_BUF_SIZE                       (0x000007FF)
52 #define TX_CMD_B_PKT_TAG                        (0xFFFF0000)
53 #define TX_CMD_B_ADD_CRC_DISABLE                (0x00002000)
54 #define TX_CMD_B_DISABLE_PADDING                (0x00001000)
55 #define TX_CMD_B_PKT_BYTE_LENGTH                (0x000007FF)
56
57 #define RX_STATUS_FIFO          __REG(CONFIG_DRIVER_SMC911X_BASE + 0x40)
58 #define RX_STS_PKT_LEN                          (0x3FFF0000)
59 #define RX_STS_ES                               (0x00008000)
60 #define RX_STS_BCST                             (0x00002000)
61 #define RX_STS_LEN_ERR                          (0x00001000)
62 #define RX_STS_RUNT_ERR                         (0x00000800)
63 #define RX_STS_MCAST                            (0x00000400)
64 #define RX_STS_TOO_LONG                         (0x00000080)
65 #define RX_STS_COLL                             (0x00000040)
66 #define RX_STS_ETH_TYPE                         (0x00000020)
67 #define RX_STS_WDOG_TMT                         (0x00000010)
68 #define RX_STS_MII_ERR                          (0x00000008)
69 #define RX_STS_DRIBBLING                        (0x00000004)
70 #define RX_STS_CRC_ERR                          (0x00000002)
71 #define RX_STATUS_FIFO_PEEK     __REG(CONFIG_DRIVER_SMC911X_BASE + 0x44)
72 #define TX_STATUS_FIFO          __REG(CONFIG_DRIVER_SMC911X_BASE + 0x48)
73 #define TX_STS_TAG                              (0xFFFF0000)
74 #define TX_STS_ES                               (0x00008000)
75 #define TX_STS_LOC                              (0x00000800)
76 #define TX_STS_NO_CARR                          (0x00000400)
77 #define TX_STS_LATE_COLL                        (0x00000200)
78 #define TX_STS_MANY_COLL                        (0x00000100)
79 #define TX_STS_COLL_CNT                         (0x00000078)
80 #define TX_STS_MANY_DEFER                       (0x00000004)
81 #define TX_STS_UNDERRUN                         (0x00000002)
82 #define TX_STS_DEFERRED                         (0x00000001)
83 #define TX_STATUS_FIFO_PEEK     __REG(CONFIG_DRIVER_SMC911X_BASE + 0x4C)
84 #define ID_REV                  __REG(CONFIG_DRIVER_SMC911X_BASE + 0x50)
85 #define ID_REV_CHIP_ID                          (0xFFFF0000)  /* RO */
86 #define ID_REV_REV_ID                           (0x0000FFFF)  /* RO */
87
88 #define INT_CFG                 __REG(CONFIG_DRIVER_SMC911X_BASE + 0x54)
89 #define INT_CFG_INT_DEAS                        (0xFF000000)  /* R/W */
90 #define INT_CFG_INT_DEAS_CLR                    (0x00004000)
91 #define INT_CFG_INT_DEAS_STS                    (0x00002000)
92 #define INT_CFG_IRQ_INT                         (0x00001000)  /* RO */
93 #define INT_CFG_IRQ_EN                          (0x00000100)  /* R/W */
94 #define INT_CFG_IRQ_POL                         (0x00000010)  /* R/W */
95                                                 /* Not Affected by SW Reset */
96 #define INT_CFG_IRQ_TYPE                        (0x00000001)  /* R/W */
97                                                 /* Not Affected by SW Reset */
98
99 #define INT_STS                 __REG(CONFIG_DRIVER_SMC911X_BASE + 0x58)
100 #define INT_STS_SW_INT                          (0x80000000)  /* R/WC */
101 #define INT_STS_TXSTOP_INT                      (0x02000000)  /* R/WC */
102 #define INT_STS_RXSTOP_INT                      (0x01000000)  /* R/WC */
103 #define INT_STS_RXDFH_INT                       (0x00800000)  /* R/WC */
104 #define INT_STS_RXDF_INT                        (0x00400000)  /* R/WC */
105 #define INT_STS_TX_IOC                          (0x00200000)  /* R/WC */
106 #define INT_STS_RXD_INT                         (0x00100000)  /* R/WC */
107 #define INT_STS_GPT_INT                         (0x00080000)  /* R/WC */
108 #define INT_STS_PHY_INT                         (0x00040000)  /* RO */
109 #define INT_STS_PME_INT                         (0x00020000)  /* R/WC */
110 #define INT_STS_TXSO                            (0x00010000)  /* R/WC */
111 #define INT_STS_RWT                             (0x00008000)  /* R/WC */
112 #define INT_STS_RXE                             (0x00004000)  /* R/WC */
113 #define INT_STS_TXE                             (0x00002000)  /* R/WC */
114 /*#define       INT_STS_ERX             (0x00001000)*/  /* R/WC */
115 #define INT_STS_TDFU                            (0x00000800)  /* R/WC */
116 #define INT_STS_TDFO                            (0x00000400)  /* R/WC */
117 #define INT_STS_TDFA                            (0x00000200)  /* R/WC */
118 #define INT_STS_TSFF                            (0x00000100)  /* R/WC */
119 #define INT_STS_TSFL                            (0x00000080)  /* R/WC */
120 /*#define       INT_STS_RXDF            (0x00000040)*/  /* R/WC */
121 #define INT_STS_RDFO                            (0x00000040)  /* R/WC */
122 #define INT_STS_RDFL                            (0x00000020)  /* R/WC */
123 #define INT_STS_RSFF                            (0x00000010)  /* R/WC */
124 #define INT_STS_RSFL                            (0x00000008)  /* R/WC */
125 #define INT_STS_GPIO2_INT                       (0x00000004)  /* R/WC */
126 #define INT_STS_GPIO1_INT                       (0x00000002)  /* R/WC */
127 #define INT_STS_GPIO0_INT                       (0x00000001)  /* R/WC */
128 #define INT_EN                  __REG(CONFIG_DRIVER_SMC911X_BASE + 0x5C)
129 #define INT_EN_SW_INT_EN                        (0x80000000)  /* R/W */
130 #define INT_EN_TXSTOP_INT_EN                    (0x02000000)  /* R/W */
131 #define INT_EN_RXSTOP_INT_EN                    (0x01000000)  /* R/W */
132 #define INT_EN_RXDFH_INT_EN                     (0x00800000)  /* R/W */
133 /*#define       INT_EN_RXDF_INT_EN              (0x00400000)*/  /* R/W */
134 #define INT_EN_TIOC_INT_EN                      (0x00200000)  /* R/W */
135 #define INT_EN_RXD_INT_EN                       (0x00100000)  /* R/W */
136 #define INT_EN_GPT_INT_EN                       (0x00080000)  /* R/W */
137 #define INT_EN_PHY_INT_EN                       (0x00040000)  /* R/W */
138 #define INT_EN_PME_INT_EN                       (0x00020000)  /* R/W */
139 #define INT_EN_TXSO_EN                          (0x00010000)  /* R/W */
140 #define INT_EN_RWT_EN                           (0x00008000)  /* R/W */
141 #define INT_EN_RXE_EN                           (0x00004000)  /* R/W */
142 #define INT_EN_TXE_EN                           (0x00002000)  /* R/W */
143 /*#define       INT_EN_ERX_EN                   (0x00001000)*/  /* R/W */
144 #define INT_EN_TDFU_EN                          (0x00000800)  /* R/W */
145 #define INT_EN_TDFO_EN                          (0x00000400)  /* R/W */
146 #define INT_EN_TDFA_EN                          (0x00000200)  /* R/W */
147 #define INT_EN_TSFF_EN                          (0x00000100)  /* R/W */
148 #define INT_EN_TSFL_EN                          (0x00000080)  /* R/W */
149 /*#define       INT_EN_RXDF_EN                  (0x00000040)*/  /* R/W */
150 #define INT_EN_RDFO_EN                          (0x00000040)  /* R/W */
151 #define INT_EN_RDFL_EN                          (0x00000020)  /* R/W */
152 #define INT_EN_RSFF_EN                          (0x00000010)  /* R/W */
153 #define INT_EN_RSFL_EN                          (0x00000008)  /* R/W */
154 #define INT_EN_GPIO2_INT                        (0x00000004)  /* R/W */
155 #define INT_EN_GPIO1_INT                        (0x00000002)  /* R/W */
156 #define INT_EN_GPIO0_INT                        (0x00000001)  /* R/W */
157
158 #define BYTE_TEST               __REG(CONFIG_DRIVER_SMC911X_BASE + 0x64)
159 #define FIFO_INT                __REG(CONFIG_DRIVER_SMC911X_BASE + 0x68)
160 #define FIFO_INT_TX_AVAIL_LEVEL                 (0xFF000000)  /* R/W */
161 #define FIFO_INT_TX_STS_LEVEL                   (0x00FF0000)  /* R/W */
162 #define FIFO_INT_RX_AVAIL_LEVEL                 (0x0000FF00)  /* R/W */
163 #define FIFO_INT_RX_STS_LEVEL                   (0x000000FF)  /* R/W */
164
165 #define RX_CFG                  __REG(CONFIG_DRIVER_SMC911X_BASE + 0x6C)
166 #define RX_CFG_RX_END_ALGN                      (0xC0000000)  /* R/W */
167 #define         RX_CFG_RX_END_ALGN4             (0x00000000)  /* R/W */
168 #define         RX_CFG_RX_END_ALGN16            (0x40000000)  /* R/W */
169 #define         RX_CFG_RX_END_ALGN32            (0x80000000)  /* R/W */
170 #define RX_CFG_RX_DMA_CNT                       (0x0FFF0000)  /* R/W */
171 #define RX_CFG_RX_DUMP                          (0x00008000)  /* R/W */
172 #define RX_CFG_RXDOFF                           (0x00001F00)  /* R/W */
173 /*#define       RX_CFG_RXBAD                    (0x00000001)*/  /* R/W */
174
175 #define TX_CFG                  __REG(CONFIG_DRIVER_SMC911X_BASE + 0x70)
176 /*#define       TX_CFG_TX_DMA_LVL               (0xE0000000)*/   /* R/W */
177 /*#define       TX_CFG_TX_DMA_CNT               (0x0FFF0000)*/   /* R/W */
178                                                         /* Self Clearing */
179 #define TX_CFG_TXS_DUMP                         (0x00008000)
180                                                         /* Self Clearing */
181 #define TX_CFG_TXD_DUMP                         (0x00004000)
182                                                         /* Self Clearing */
183 #define TX_CFG_TXSAO                            (0x00000004)  /* R/W */
184 #define TX_CFG_TX_ON                            (0x00000002)  /* R/W */
185 #define TX_CFG_STOP_TX                          (0x00000001)
186                                                         /* Self Clearing */
187
188 #define HW_CFG                  __REG(CONFIG_DRIVER_SMC911X_BASE + 0x74)
189 #define HW_CFG_TTM                              (0x00200000)  /* R/W */
190 #define HW_CFG_SF                               (0x00100000)  /* R/W */
191 #define HW_CFG_TX_FIF_SZ                        (0x000F0000)  /* R/W */
192 #define HW_CFG_TR                               (0x00003000)  /* R/W */
193 #define HW_CFG_PHY_CLK_SEL                      (0x00000060)  /* R/W */
194 #define HW_CFG_PHY_CLK_SEL_INT_PHY              (0x00000000) /* R/W */
195 #define HW_CFG_PHY_CLK_SEL_EXT_PHY              (0x00000020) /* R/W */
196 #define HW_CFG_PHY_CLK_SEL_CLK_DIS              (0x00000040) /* R/W */
197 #define HW_CFG_SMI_SEL                          (0x00000010)  /* R/W */
198 #define HW_CFG_EXT_PHY_DET                      (0x00000008)  /* RO */
199 #define HW_CFG_EXT_PHY_EN                       (0x00000004)  /* R/W */
200 #define HW_CFG_32_16_BIT_MODE                   (0x00000004)  /* RO */
201 #define HW_CFG_SRST_TO                          (0x00000002)  /* RO */
202 #define HW_CFG_SRST                             (0x00000001)
203                                                         /* Self Clearing */
204
205 #define RX_DP_CTRL              __REG(CONFIG_DRIVER_SMC911X_BASE + 0x78)
206 #define RX_DP_CTRL_RX_FFWD                      (0x80000000)  /* R/W */
207 #define RX_DP_CTRL_FFWD_BUSY                    (0x80000000)  /* RO */
208
209 #define RX_FIFO_INF             __REG(CONFIG_DRIVER_SMC911X_BASE + 0x7C)
210 #define  RX_FIFO_INF_RXSUSED                    (0x00FF0000)  /* RO */
211 #define  RX_FIFO_INF_RXDUSED                    (0x0000FFFF)  /* RO */
212
213 #define TX_FIFO_INF             __REG(CONFIG_DRIVER_SMC911X_BASE + 0x80)
214 #define TX_FIFO_INF_TSUSED                      (0x00FF0000)  /* RO */
215 #define TX_FIFO_INF_TDFREE                      (0x0000FFFF)  /* RO */
216
217 #define PMT_CTRL                __REG(CONFIG_DRIVER_SMC911X_BASE + 0x84)
218 #define PMT_CTRL_PM_MODE                        (0x00003000)
219                                                         /* Self Clearing */
220 #define PMT_CTRL_PHY_RST                        (0x00000400)
221                                                         /* Self Clearing */
222 #define PMT_CTRL_WOL_EN                         (0x00000200)  /* R/W */
223 #define PMT_CTRL_ED_EN                          (0x00000100)  /* R/W */
224 #define PMT_CTRL_PME_TYPE                       (0x00000040)  /* R/W */
225                                                 /* Not Affected by SW Reset */
226 #define PMT_CTRL_WUPS                           (0x00000030)  /* R/WC */
227 #define PMT_CTRL_WUPS_NOWAKE                    (0x00000000)  /* R/WC */
228 #define PMT_CTRL_WUPS_ED                        (0x00000010)  /* R/WC */
229 #define PMT_CTRL_WUPS_WOL                       (0x00000020)  /* R/WC */
230 #define PMT_CTRL_WUPS_MULTI                     (0x00000030)  /* R/WC */
231 #define PMT_CTRL_PME_IND                        (0x00000008)  /* R/W */
232 #define PMT_CTRL_PME_POL                        (0x00000004)  /* R/W */
233 #define PMT_CTRL_PME_EN                         (0x00000002)  /* R/W */
234                                                 /* Not Affected by SW Reset */
235 #define PMT_CTRL_READY                          (0x00000001)  /* RO */
236
237 #define GPIO_CFG                __REG(CONFIG_DRIVER_SMC911X_BASE + 0x88)
238 #define GPIO_CFG_LED3_EN                        (0x40000000)  /* R/W */
239 #define GPIO_CFG_LED2_EN                        (0x20000000)  /* R/W */
240 #define GPIO_CFG_LED1_EN                        (0x10000000)  /* R/W */
241 #define GPIO_CFG_GPIO2_INT_POL                  (0x04000000)  /* R/W */
242 #define GPIO_CFG_GPIO1_INT_POL                  (0x02000000)  /* R/W */
243 #define GPIO_CFG_GPIO0_INT_POL                  (0x01000000)  /* R/W */
244 #define GPIO_CFG_EEPR_EN                        (0x00700000)  /* R/W */
245 #define GPIO_CFG_GPIOBUF2                       (0x00040000)  /* R/W */
246 #define GPIO_CFG_GPIOBUF1                       (0x00020000)  /* R/W */
247 #define GPIO_CFG_GPIOBUF0                       (0x00010000)  /* R/W */
248 #define GPIO_CFG_GPIODIR2                       (0x00000400)  /* R/W */
249 #define GPIO_CFG_GPIODIR1                       (0x00000200)  /* R/W */
250 #define GPIO_CFG_GPIODIR0                       (0x00000100)  /* R/W */
251 #define GPIO_CFG_GPIOD4                         (0x00000010)  /* R/W */
252 #define GPIO_CFG_GPIOD3                         (0x00000008)  /* R/W */
253 #define GPIO_CFG_GPIOD2                         (0x00000004)  /* R/W */
254 #define GPIO_CFG_GPIOD1                         (0x00000002)  /* R/W */
255 #define GPIO_CFG_GPIOD0                         (0x00000001)  /* R/W */
256
257 #define GPT_CFG                 __REG(CONFIG_DRIVER_SMC911X_BASE + 0x8C)
258 #define GPT_CFG_TIMER_EN                        (0x20000000)  /* R/W */
259 #define GPT_CFG_GPT_LOAD                        (0x0000FFFF)  /* R/W */
260
261 #define GPT_CNT                 __REG(CONFIG_DRIVER_SMC911X_BASE + 0x90)
262 #define GPT_CNT_GPT_CNT                         (0x0000FFFF)  /* RO */
263
264 #define ENDIAN                  __REG(CONFIG_DRIVER_SMC911X_BASE + 0x98)
265 #define FREE_RUN                __REG(CONFIG_DRIVER_SMC911X_BASE + 0x9C)
266 #define RX_DROP                 __REG(CONFIG_DRIVER_SMC911X_BASE + 0xA0)
267 #define MAC_CSR_CMD             __REG(CONFIG_DRIVER_SMC911X_BASE + 0xA4)
268 #define  MAC_CSR_CMD_CSR_BUSY                   (0x80000000)
269                                                         /* Self Clearing */
270 #define  MAC_CSR_CMD_R_NOT_W                    (0x40000000)  /* R/W */
271 #define  MAC_CSR_CMD_CSR_ADDR                   (0x000000FF)  /* R/W */
272
273 #define MAC_CSR_DATA            __REG(CONFIG_DRIVER_SMC911X_BASE + 0xA8)
274 #define AFC_CFG                 __REG(CONFIG_DRIVER_SMC911X_BASE + 0xAC)
275 #define         AFC_CFG_AFC_HI                  (0x00FF0000)  /* R/W */
276 #define         AFC_CFG_AFC_LO                  (0x0000FF00)  /* R/W */
277 #define         AFC_CFG_BACK_DUR                (0x000000F0)  /* R/W */
278 #define         AFC_CFG_FCMULT                  (0x00000008)  /* R/W */
279 #define         AFC_CFG_FCBRD                   (0x00000004)  /* R/W */
280 #define         AFC_CFG_FCADD                   (0x00000002)  /* R/W */
281 #define         AFC_CFG_FCANY                   (0x00000001)  /* R/W */
282
283 #define E2P_CMD                 __REG(CONFIG_DRIVER_SMC911X_BASE + 0xB0)
284 #define         E2P_CMD_EPC_BUSY                (0x80000000)
285                                                         /* Self Clearing */
286 #define         E2P_CMD_EPC_CMD                 (0x70000000)  /* R/W */
287 #define         E2P_CMD_EPC_CMD_READ            (0x00000000)  /* R/W */
288 #define         E2P_CMD_EPC_CMD_EWDS            (0x10000000)  /* R/W */
289 #define         E2P_CMD_EPC_CMD_EWEN            (0x20000000)  /* R/W */
290 #define         E2P_CMD_EPC_CMD_WRITE           (0x30000000)  /* R/W */
291 #define         E2P_CMD_EPC_CMD_WRAL            (0x40000000)  /* R/W */
292 #define         E2P_CMD_EPC_CMD_ERASE           (0x50000000)  /* R/W */
293 #define         E2P_CMD_EPC_CMD_ERAL            (0x60000000)  /* R/W */
294 #define         E2P_CMD_EPC_CMD_RELOAD          (0x70000000)  /* R/W */
295 #define         E2P_CMD_EPC_TIMEOUT             (0x00000200)  /* RO */
296 #define         E2P_CMD_MAC_ADDR_LOADED         (0x00000100)  /* RO */
297 #define         E2P_CMD_EPC_ADDR                (0x000000FF)  /* R/W */
298
299 #define E2P_DATA                __REG(CONFIG_DRIVER_SMC911X_BASE + 0xB4)
300 #define E2P_DATA_EEPROM_DATA                    (0x000000FF)  /* R/W */
301 /* end of LAN register offsets and bit definitions */
302
303 /* MAC Control and Status registers */
304 #define MAC_CR                  (0x01)  /* R/W */
305
306 /* MAC_CR - MAC Control Register */
307 #define MAC_CR_RXALL                    (0x80000000)
308 /* TODO: delete this bit? It is not described in the data sheet. */
309 #define MAC_CR_HBDIS                    (0x10000000)
310 #define MAC_CR_RCVOWN                   (0x00800000)
311 #define MAC_CR_LOOPBK                   (0x00200000)
312 #define MAC_CR_FDPX                     (0x00100000)
313 #define MAC_CR_MCPAS                    (0x00080000)
314 #define MAC_CR_PRMS                     (0x00040000)
315 #define MAC_CR_INVFILT                  (0x00020000)
316 #define MAC_CR_PASSBAD                  (0x00010000)
317 #define MAC_CR_HFILT                    (0x00008000)
318 #define MAC_CR_HPFILT                   (0x00002000)
319 #define MAC_CR_LCOLL                    (0x00001000)
320 #define MAC_CR_BCAST                    (0x00000800)
321 #define MAC_CR_DISRTY                   (0x00000400)
322 #define MAC_CR_PADSTR                   (0x00000100)
323 #define MAC_CR_BOLMT_MASK               (0x000000C0)
324 #define MAC_CR_DFCHK                    (0x00000020)
325 #define MAC_CR_TXEN                     (0x00000008)
326 #define MAC_CR_RXEN                     (0x00000004)
327
328 #define ADDRH                   (0x02)    /* R/W mask 0x0000FFFFUL */
329 #define ADDRL                   (0x03)    /* R/W mask 0xFFFFFFFFUL */
330 #define HASHH                   (0x04)    /* R/W */
331 #define HASHL                   (0x05)    /* R/W */
332
333 #define MII_ACC                 (0x06)    /* R/W */
334 #define MII_ACC_PHY_ADDR                (0x0000F800)
335 #define MII_ACC_MIIRINDA                (0x000007C0)
336 #define MII_ACC_MII_WRITE               (0x00000002)
337 #define MII_ACC_MII_BUSY                (0x00000001)
338
339 #define MII_DATA                (0x07)    /* R/W mask 0x0000FFFFUL */
340
341 #define FLOW                    (0x08)    /* R/W */
342 #define FLOW_FCPT                       (0xFFFF0000)
343 #define FLOW_FCPASS                     (0x00000004)
344 #define FLOW_FCEN                       (0x00000002)
345 #define FLOW_FCBSY                      (0x00000001)
346
347 #define VLAN1                   (0x09)    /* R/W mask 0x0000FFFFUL */
348 #define VLAN1_VTI1                      (0x0000ffff)
349
350 #define VLAN2                   (0x0A)    /* R/W mask 0x0000FFFFUL */
351 #define VLAN2_VTI2                      (0x0000ffff)
352
353 #define WUFF                    (0x0B)    /* WO */
354
355 #define WUCSR                   (0x0C)    /* R/W */
356 #define WUCSR_GUE                       (0x00000200)
357 #define WUCSR_WUFR                      (0x00000040)
358 #define WUCSR_MPR                       (0x00000020)
359 #define WUCSR_WAKE_EN                   (0x00000004)
360 #define WUCSR_MPEN                      (0x00000002)
361
362 /* Chip ID values */
363 #define CHIP_9115       0x115
364 #define CHIP_9116       0x116
365 #define CHIP_9117       0x117
366 #define CHIP_9118       0x118
367 #define CHIP_9215       0x115a
368 #define CHIP_9216       0x116a
369 #define CHIP_9217       0x117a
370 #define CHIP_9218       0x118a
371
372 struct chip_id {
373         u16 id;
374         char *name;
375 };
376
377 static const struct chip_id chip_ids[] =  {
378         { CHIP_9115, "LAN9115" },
379         { CHIP_9116, "LAN9116" },
380         { CHIP_9117, "LAN9117" },
381         { CHIP_9118, "LAN9118" },
382         { CHIP_9215, "LAN9215" },
383         { CHIP_9216, "LAN9216" },
384         { CHIP_9217, "LAN9217" },
385         { CHIP_9218, "LAN9218" },
386         { 0, NULL },
387 };
388
389 #define DRIVERNAME "smc911x"
390
391 u32 smc911x_get_mac_csr(u8 reg)
392 {
393         while (MAC_CSR_CMD & MAC_CSR_CMD_CSR_BUSY);
394         MAC_CSR_CMD = MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg;
395         while (MAC_CSR_CMD & MAC_CSR_CMD_CSR_BUSY);
396
397         return MAC_CSR_DATA;
398 }
399
400 void smc911x_set_mac_csr(u8 reg, u32 data)
401 {
402         while (MAC_CSR_CMD & MAC_CSR_CMD_CSR_BUSY);
403         MAC_CSR_DATA = data;
404         MAC_CSR_CMD = MAC_CSR_CMD_CSR_BUSY | reg;
405         while (MAC_CSR_CMD & MAC_CSR_CMD_CSR_BUSY); }
406
407 static int smx911x_handle_mac_address(bd_t *bd)
408 {
409         unsigned long addrh, addrl;
410         unsigned char *m = bd->bi_enetaddr;
411
412         /* if the environment has a valid mac address then use it */
413         if ((m[0] | m[1] | m[2] | m[3] | m[4] | m[5])) {
414                 addrl = m[0] | m[1] << 8 | m[2] << 16 | m[3] << 24;
415                 addrh = m[4] | m[5] << 8;
416                 smc911x_set_mac_csr(ADDRH, addrh);
417                 smc911x_set_mac_csr(ADDRL, addrl);
418         } else {
419                 /* if not, try to get one from the eeprom */
420                 addrh = smc911x_get_mac_csr(ADDRH);
421                 addrl = smc911x_get_mac_csr(ADDRL);
422
423                 m[0] = (addrl) & 0xff;
424                 m[1] = (addrl >>  8) & 0xff;
425                 m[2] = (addrl >> 16) & 0xff;
426                 m[3] = (addrl >> 24) & 0xff;
427                 m[4] = (addrh) & 0xff;
428                 m[5] = (addrh >>  8) & 0xff;
429
430                 /* we get 0xff when there is no eeprom connected */
431                 if ((m[0] & m[1] & m[2] & m[3] & m[4] & m[5]) == 0xff) {
432                         printf(DRIVERNAME ": no valid mac address "
433                                 "in environment "
434                                 "and no eeprom found\n");
435                         return -1;
436                 }
437         }
438
439         printf(DRIVERNAME ": MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
440                 m[0], m[1], m[2], m[3], m[4], m[5]);
441
442         return 0;
443 }
444
445 static int smc911x_miiphy_read(u8 phy, u8 reg, u16 *val)
446 {
447         while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY);
448
449         smc911x_set_mac_csr(MII_ACC, phy << 11 | reg << 6 | MII_ACC_MII_BUSY);
450
451         while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY);
452
453         *val = smc911x_get_mac_csr(MII_DATA);
454
455         return 0;
456 }
457
458 static int smc911x_miiphy_write(u8 phy, u8 reg, u16  val)
459 {
460         while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY);
461
462         smc911x_set_mac_csr(MII_DATA, val);
463         smc911x_set_mac_csr(MII_ACC,
464                 phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE);
465
466         while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY);
467         return 0;
468 }
469
470 static int smc911x_phy_reset(void)
471 {
472         u32 reg;
473
474         reg = PMT_CTRL;
475         reg &= ~0xfffff030;
476         reg |= PMT_CTRL_PHY_RST;
477         PMT_CTRL = reg;
478
479         mdelay(100);
480
481         return 0;
482 }
483
484 static void smc911x_phy_configure(void)
485 {
486         int timeout;
487         u16 status;
488
489         smc911x_phy_reset();
490
491         smc911x_miiphy_write(1, PHY_BMCR, PHY_BMCR_RESET);
492         mdelay(1);
493         smc911x_miiphy_write(1, PHY_ANAR, 0x01e1);
494         smc911x_miiphy_write(1, PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
495
496         timeout = 5000;
497         do {
498                 mdelay(1);
499                 if ((timeout--) == 0)
500                         goto err_out;
501
502                 if (smc911x_miiphy_read(1, PHY_BMSR, &status) != 0)
503                         goto err_out;
504         } while (!(status & PHY_BMSR_LS));
505
506         printf(DRIVERNAME ": phy initialized\n");
507
508         return;
509
510 err_out:
511         printf(DRIVERNAME ": autonegotiation timed out\n"); }
512
513 static void smc911x_reset(void)
514 {
515         int timeout;
516
517         /* Take out of PM setting first */
518         if (PMT_CTRL & PMT_CTRL_READY) {
519                 /* Write to the bytetest will take out of powerdown */
520                 BYTE_TEST = 0x0;
521
522                 timeout = 10;
523
524                 while (timeout-- && !(PMT_CTRL & PMT_CTRL_READY))
525                         udelay(10);
526                 if (!timeout) {
527                         printf(DRIVERNAME
528                                 ": timeout waiting for PM restore\n");
529                         return;
530                 }
531         }
532
533         /* Disable interrupts */
534         INT_EN = 0;
535
536         HW_CFG = HW_CFG_SRST;
537
538         timeout = 1000;
539         while (timeout-- && E2P_CMD & E2P_CMD_EPC_BUSY)
540                 udelay(10);
541
542         if (!timeout) {
543                 printf(DRIVERNAME ": reset timeout\n");
544                 return;
545         }
546
547         /* Reset the FIFO level and flow control settings */
548         smc911x_set_mac_csr(FLOW, FLOW_FCPT | FLOW_FCEN);
549         AFC_CFG = 0x0050287F;
550
551         /* Set to LED outputs */
552         GPIO_CFG = 0x70070000;
553 }
554
555 static void smc911x_enable(void)
556 {
557         /* Enable TX */
558         HW_CFG = 8 << 16 | HW_CFG_SF;
559
560         GPT_CFG = GPT_CFG_TIMER_EN | 10000;
561
562         TX_CFG = TX_CFG_TX_ON;
563
564         /* no padding to start of packets */
565         RX_CFG = 0;
566
567         smc911x_set_mac_csr(MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS);
568
569 }
570
571 int eth_init(bd_t *bd)
572 {
573         unsigned long val, i;
574
575         printf(DRIVERNAME ": initializing\n");
576
577         val = BYTE_TEST;
578         if (val != 0x87654321) {
579                 printf(DRIVERNAME ": Invalid chip endian 0x08%x\n", val);
580                 goto err_out;
581         }
582
583         val = ID_REV >> 16;
584         for (i = 0; chip_ids[i].id != 0; i++) {
585                 if (chip_ids[i].id == val)
586                         break;
587         }
588         if (!chip_ids[i].id) {
589                 printf(DRIVERNAME ": Unknown chip ID %04x\n", val);
590                 goto err_out;
591         }
592
593         printf(DRIVERNAME ": detected %s controller\n", chip_ids[i].name);
594
595         smc911x_reset();
596
597         /* Configure the PHY, initialize the link state */
598         smc911x_phy_configure();
599
600         if (smx911x_handle_mac_address(bd))
601                 goto err_out;
602
603         /* Turn on Tx + Rx */
604         smc911x_enable();
605
606         return 0;
607
608 err_out:
609         return -1;
610 }
611
612 int eth_send(volatile void *packet, int length)
613 {
614         u32 *data = (u32 *)packet;
615         u32 tmplen;
616         u32 status;
617
618         TX_DATA_FIFO = TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length;
619         TX_DATA_FIFO = length;
620
621         tmplen = (length + 3) / 4;
622
623         while (tmplen--)
624                 TX_DATA_FIFO = *data++;
625
626         /* wait for transmission */
627         while (!((TX_FIFO_INF & TX_FIFO_INF_TSUSED) >> 16));
628
629         /* get status. Ignore 'no carrier' error, it has no meaning for
630          * full duplex operation
631          */
632         status = TX_STATUS_FIFO & (TX_STS_LOC | TX_STS_LATE_COLL |
633                 TX_STS_MANY_COLL | TX_STS_MANY_DEFER | TX_STS_UNDERRUN);
634
635         if (!status)
636                 return 0;
637
638         printf(DRIVERNAME ": failed to send packet: %s%s%s%s%s\n",
639                 status & TX_STS_LOC ? "TX_STS_LOC " : "",
640                 status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "",
641                 status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "",
642                 status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "",
643                 status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : "");
644
645         return -1;
646 }
647
648 void eth_halt(void)
649 {
650         smc911x_reset();
651 }
652
653 int eth_rx(void)
654 {
655         u32 *data = (u32 *)NetRxPackets[0];
656         u32 pktlen, tmplen;
657         u32 status;
658
659         if ((RX_FIFO_INF & RX_FIFO_INF_RXSUSED) >> 16) {
660                 status = RX_STATUS_FIFO;
661                 pktlen = (status & RX_STS_PKT_LEN) >> 16;
662
663                 RX_CFG = 0;
664
665                 tmplen = (pktlen + 2 + 3) / 4;
666                 while (tmplen--)
667                         *data++ = RX_DATA_FIFO;
668
669                 if (status & RX_STS_ES)
670                         printf(DRIVERNAME
671                                 ": dropped bad packet. Status: 0x%08x\n",
672                                 status);
673                 else
674                         NetReceive(NetRxPackets[0], pktlen);
675         }
676
677         return 0;
678 }
679
680 #endif                          /* CONFIG_DRIVER_SMC911X */