xref: /rk3399_rockchip-uboot/drivers/net/smc911x.c (revision c2f02da21a3f37f0878554eebc785e04fdc4e128)
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 */
681