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