OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Atheros AR71xx built-in ethernet mac driver |
||
3 | * |
||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> |
||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
||
6 | * |
||
7 | * Based on Atheros' AG7100 driver |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or modify it |
||
10 | * under the terms of the GNU General Public License version 2 as published |
||
11 | * by the Free Software Foundation. |
||
12 | */ |
||
13 | |||
14 | #ifndef __AG71XX_H |
||
15 | #define __AG71XX_H |
||
16 | |||
17 | #include <linux/types.h> |
||
18 | #include <linux/bitops.h> |
||
19 | |||
20 | #include <asm/ar71xx.h> |
||
21 | |||
22 | // controller has 2 ports |
||
23 | #define MAX_AG71XX_DEVS 2 |
||
24 | |||
25 | #define ETH_FCS_LEN 4 |
||
26 | |||
27 | #define SPEED_10 10 |
||
28 | #define SPEED_100 100 |
||
29 | #define SPEED_1000 1000 |
||
30 | |||
31 | |||
32 | #define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) |
||
33 | #define AG71XX_INT_TX (AG71XX_INT_TX_PS) |
||
34 | #define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) |
||
35 | |||
36 | #define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) |
||
37 | #define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) |
||
38 | |||
39 | #define AG71XX_TX_FIFO_LEN 2048 |
||
40 | #define AG71XX_TX_MTU_LEN 1536 |
||
41 | #define AG71XX_RX_PKT_RESERVE 64 |
||
42 | #define AG71XX_RX_PKT_SIZE \ |
||
43 | (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN) |
||
44 | |||
45 | #ifndef CONFIG_SYS_RX_ETH_BUFFER |
||
46 | #define AG71XX_TX_RING_SIZE 4 |
||
47 | #define AG71XX_RX_RING_SIZE 4 |
||
48 | #else |
||
49 | #define AG71XX_TX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER |
||
50 | #define AG71XX_RX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER |
||
51 | #endif |
||
52 | |||
53 | #define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4) |
||
54 | #define AG71XX_TX_THRES_WAKEUP \ |
||
55 | (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4)) |
||
56 | |||
57 | |||
58 | |||
59 | |||
60 | struct ag71xx_desc { |
||
61 | u32 data; |
||
62 | u32 ctrl; |
||
63 | #define DESC_EMPTY BIT(31) |
||
64 | #define DESC_MORE BIT(24) |
||
65 | #define DESC_PKTLEN_M 0xfff |
||
66 | u32 next; |
||
67 | u32 pad; |
||
68 | } __attribute__((aligned(4))); |
||
69 | |||
70 | struct ag71xx_buf { |
||
71 | struct sk_buff *skb; |
||
72 | struct ag71xx_desc *desc; |
||
73 | dma_addr_t dma_addr; |
||
74 | u32 pad; |
||
75 | }; |
||
76 | |||
77 | struct ag71xx_ring { |
||
78 | struct ag71xx_buf *buf; |
||
79 | u8 *descs_cpu; |
||
80 | u8 *descs_dma; |
||
81 | unsigned int desc_size; |
||
82 | unsigned int curr; |
||
83 | unsigned int size; |
||
84 | }; |
||
85 | |||
86 | struct ag71xx { |
||
87 | uint32_t mac_base; |
||
88 | uint32_t mii_ctrl; |
||
89 | |||
90 | struct eth_device *dev; |
||
91 | |||
92 | struct ag71xx_ring rx_ring; |
||
93 | struct ag71xx_ring tx_ring; |
||
94 | |||
95 | char *phyname; |
||
96 | u16 phyid; |
||
97 | u16 phyfixed; |
||
98 | uint32_t link; |
||
99 | uint32_t speed; |
||
100 | int32_t duplex; |
||
101 | uint32_t macNum; |
||
102 | uint32_t mii_if; |
||
103 | }; |
||
104 | |||
105 | void ag71xx_link_adjust(struct ag71xx *ag); |
||
106 | |||
107 | int ag71xx_phy_connect(struct ag71xx *ag); |
||
108 | void ag71xx_phy_disconnect(struct ag71xx *ag); |
||
109 | void ag71xx_phy_start(struct ag71xx *ag); |
||
110 | void ag71xx_phy_stop(struct ag71xx *ag); |
||
111 | |||
112 | static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) |
||
113 | { |
||
114 | return ((desc->ctrl & DESC_EMPTY) != 0); |
||
115 | } |
||
116 | |||
117 | static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) |
||
118 | { |
||
119 | return (desc->ctrl & DESC_PKTLEN_M); |
||
120 | } |
||
121 | |||
122 | /* Register offsets */ |
||
123 | #define AG71XX_REG_MAC_CFG1 0x0000 |
||
124 | #define AG71XX_REG_MAC_CFG2 0x0004 |
||
125 | #define AG71XX_REG_MAC_IPG 0x0008 |
||
126 | #define AG71XX_REG_MAC_HDX 0x000c |
||
127 | #define AG71XX_REG_MAC_MFL 0x0010 |
||
128 | #define AG71XX_REG_MII_CFG 0x0020 |
||
129 | #define AG71XX_REG_MII_CMD 0x0024 |
||
130 | #define AG71XX_REG_MII_ADDR 0x0028 |
||
131 | #define AG71XX_REG_MII_CTRL 0x002c |
||
132 | #define AG71XX_REG_MII_STATUS 0x0030 |
||
133 | #define AG71XX_REG_MII_IND 0x0034 |
||
134 | #define AG71XX_REG_MAC_IFCTL 0x0038 |
||
135 | #define AG71XX_REG_MAC_ADDR1 0x0040 |
||
136 | #define AG71XX_REG_MAC_ADDR2 0x0044 |
||
137 | #define AG71XX_REG_FIFO_CFG0 0x0048 |
||
138 | #define AG71XX_REG_FIFO_CFG1 0x004c |
||
139 | #define AG71XX_REG_FIFO_CFG2 0x0050 |
||
140 | #define AG71XX_REG_FIFO_CFG3 0x0054 |
||
141 | #define AG71XX_REG_FIFO_CFG4 0x0058 |
||
142 | #define AG71XX_REG_FIFO_CFG5 0x005c |
||
143 | #define AG71XX_REG_FIFO_RAM0 0x0060 |
||
144 | #define AG71XX_REG_FIFO_RAM1 0x0064 |
||
145 | #define AG71XX_REG_FIFO_RAM2 0x0068 |
||
146 | #define AG71XX_REG_FIFO_RAM3 0x006c |
||
147 | #define AG71XX_REG_FIFO_RAM4 0x0070 |
||
148 | #define AG71XX_REG_FIFO_RAM5 0x0074 |
||
149 | #define AG71XX_REG_FIFO_RAM6 0x0078 |
||
150 | #define AG71XX_REG_FIFO_RAM7 0x007c |
||
151 | |||
152 | #define AG71XX_REG_TX_CTRL 0x0180 |
||
153 | #define AG71XX_REG_TX_DESC 0x0184 |
||
154 | #define AG71XX_REG_TX_STATUS 0x0188 |
||
155 | #define AG71XX_REG_RX_CTRL 0x018c |
||
156 | #define AG71XX_REG_RX_DESC 0x0190 |
||
157 | #define AG71XX_REG_RX_STATUS 0x0194 |
||
158 | #define AG71XX_REG_INT_ENABLE 0x0198 |
||
159 | #define AG71XX_REG_INT_STATUS 0x019c |
||
160 | |||
161 | #define MAC_CFG1_TXE BIT(0) /* Tx Enable */ |
||
162 | #define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ |
||
163 | #define MAC_CFG1_RXE BIT(2) /* Rx Enable */ |
||
164 | #define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ |
||
165 | #define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ |
||
166 | #define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ |
||
167 | #define MAC_CFG1_LB BIT(8) /* Loopback mode */ |
||
168 | #define MAC_CFG1_SR BIT(31) /* Soft Reset */ |
||
169 | |||
170 | #define MAC_CFG2_FDX BIT(0) |
||
171 | #define MAC_CFG2_CRC_EN BIT(1) |
||
172 | #define MAC_CFG2_PAD_CRC_EN BIT(2) |
||
173 | #define MAC_CFG2_LEN_CHECK BIT(4) |
||
174 | #define MAC_CFG2_HUGE_FRAME_EN BIT(5) |
||
175 | #define MAC_CFG2_IF_1000 BIT(9) |
||
176 | #define MAC_CFG2_IF_10_100 BIT(8) |
||
177 | |||
178 | #define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ |
||
179 | #define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ |
||
180 | #define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ |
||
181 | #define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ |
||
182 | #define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ |
||
183 | #define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ |
||
184 | | FIFO_CFG0_TXS | FIFO_CFG0_TXF) |
||
185 | |||
186 | #define FIFO_CFG0_ENABLE_SHIFT 8 |
||
187 | |||
188 | #define FIFO_CFG4_DE BIT(0) /* Drop Event */ |
||
189 | #define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ |
||
190 | #define FIFO_CFG4_FC BIT(2) /* False Carrier */ |
||
191 | #define FIFO_CFG4_CE BIT(3) /* Code Error */ |
||
192 | #define FIFO_CFG4_CR BIT(4) /* CRC error */ |
||
193 | #define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ |
||
194 | #define FIFO_CFG4_LO BIT(6) /* Length out of range */ |
||
195 | #define FIFO_CFG4_OK BIT(7) /* Packet is OK */ |
||
196 | #define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ |
||
197 | #define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ |
||
198 | #define FIFO_CFG4_DR BIT(10) /* Dribble */ |
||
199 | #define FIFO_CFG4_LE BIT(11) /* Long Event */ |
||
200 | #define FIFO_CFG4_CF BIT(12) /* Control Frame */ |
||
201 | #define FIFO_CFG4_PF BIT(13) /* Pause Frame */ |
||
202 | #define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ |
||
203 | #define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ |
||
204 | #define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ |
||
205 | #define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ |
||
206 | |||
207 | #define FIFO_CFG5_DE BIT(0) /* Drop Event */ |
||
208 | #define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ |
||
209 | #define FIFO_CFG5_FC BIT(2) /* False Carrier */ |
||
210 | #define FIFO_CFG5_CE BIT(3) /* Code Error */ |
||
211 | #define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ |
||
212 | #define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ |
||
213 | #define FIFO_CFG5_OK BIT(6) /* Packet is OK */ |
||
214 | #define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ |
||
215 | #define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ |
||
216 | #define FIFO_CFG5_DR BIT(9) /* Dribble */ |
||
217 | #define FIFO_CFG5_CF BIT(10) /* Control Frame */ |
||
218 | #define FIFO_CFG5_PF BIT(11) /* Pause Frame */ |
||
219 | #define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ |
||
220 | #define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ |
||
221 | #define FIFO_CFG5_LE BIT(14) /* Long Event */ |
||
222 | #define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ |
||
223 | #define FIFO_CFG5_16 BIT(16) /* unknown */ |
||
224 | #define FIFO_CFG5_17 BIT(17) /* unknown */ |
||
225 | #define FIFO_CFG5_SF BIT(18) /* Short Frame */ |
||
226 | #define FIFO_CFG5_BM BIT(19) /* Byte Mode */ |
||
227 | |||
228 | #define AG71XX_INT_TX_PS BIT(0) |
||
229 | #define AG71XX_INT_TX_UR BIT(1) |
||
230 | #define AG71XX_INT_TX_BE BIT(3) |
||
231 | #define AG71XX_INT_RX_PR BIT(4) |
||
232 | #define AG71XX_INT_RX_OF BIT(6) |
||
233 | #define AG71XX_INT_RX_BE BIT(7) |
||
234 | |||
235 | #define MAC_IFCTL_SPEED BIT(16) |
||
236 | |||
237 | #define MII_CFG_CLK_DIV_4 0 |
||
238 | #define MII_CFG_CLK_DIV_6 2 |
||
239 | #define MII_CFG_CLK_DIV_8 3 |
||
240 | #define MII_CFG_CLK_DIV_10 4 |
||
241 | #define MII_CFG_CLK_DIV_14 5 |
||
242 | #define MII_CFG_CLK_DIV_20 6 |
||
243 | #define MII_CFG_CLK_DIV_28 7 |
||
244 | #define MII_CFG_RESET BIT(31) |
||
245 | |||
246 | #define MII_CMD_WRITE 0x0 |
||
247 | #define MII_CMD_READ 0x1 |
||
248 | #define MII_ADDR_SHIFT 8 |
||
249 | #define MII_IND_BUSY BIT(0) |
||
250 | #define MII_IND_INVALID BIT(2) |
||
251 | |||
252 | #define TX_CTRL_TXE BIT(0) /* Tx Enable */ |
||
253 | |||
254 | #define TX_STATUS_PS BIT(0) /* Packet Sent */ |
||
255 | #define TX_STATUS_UR BIT(1) /* Tx Underrun */ |
||
256 | #define TX_STATUS_BE BIT(3) /* Bus Error */ |
||
257 | |||
258 | #define RX_CTRL_RXE BIT(0) /* Rx Enable */ |
||
259 | |||
260 | #define RX_STATUS_PR BIT(0) /* Packet Received */ |
||
261 | #define RX_STATUS_OF BIT(2) /* Rx Overflow */ |
||
262 | #define RX_STATUS_BE BIT(3) /* Bus Error */ |
||
263 | |||
264 | #define MII_CTRL_IF_MASK 3 |
||
265 | #define MII_CTRL_SPEED_SHIFT 4 |
||
266 | #define MII_CTRL_SPEED_MASK 3 |
||
267 | #define MII_CTRL_SPEED_10 0 |
||
268 | #define MII_CTRL_SPEED_100 1 |
||
269 | #define MII_CTRL_SPEED_1000 2 |
||
270 | |||
271 | static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) |
||
272 | { |
||
273 | __raw_writel(value, ag->mac_base + reg); |
||
274 | /* flush write */ |
||
275 | (void) __raw_readl(ag->mac_base + reg); |
||
276 | } |
||
277 | |||
278 | static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) |
||
279 | { |
||
280 | return __raw_readl(ag->mac_base + reg); |
||
281 | } |
||
282 | |||
283 | static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) |
||
284 | { |
||
285 | uint32_t r; |
||
286 | |||
287 | r = ag->mac_base + reg; |
||
288 | __raw_writel(__raw_readl(r) | mask, r); |
||
289 | /* flush write */ |
||
290 | (void)__raw_readl(r); |
||
291 | } |
||
292 | |||
293 | static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) |
||
294 | { |
||
295 | uint32_t r; |
||
296 | |||
297 | r = ag->mac_base + reg; |
||
298 | __raw_writel(__raw_readl(r) & ~mask, r); |
||
299 | /* flush write */ |
||
300 | (void) __raw_readl(r); |
||
301 | } |
||
302 | |||
303 | static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) |
||
304 | { |
||
305 | ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); |
||
306 | } |
||
307 | |||
308 | static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) |
||
309 | { |
||
310 | ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); |
||
311 | } |
||
312 | |||
313 | static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) |
||
314 | { |
||
315 | __raw_writel(value, ag->mii_ctrl); |
||
316 | |||
317 | /* flush write */ |
||
318 | __raw_readl(ag->mii_ctrl); |
||
319 | } |
||
320 | |||
321 | static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) |
||
322 | { |
||
323 | return __raw_readl(ag->mii_ctrl); |
||
324 | } |
||
325 | |||
326 | static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag, |
||
327 | unsigned int mii_if) |
||
328 | { |
||
329 | u32 t; |
||
330 | |||
331 | t = ag71xx_mii_ctrl_rr(ag); |
||
332 | t &= ~(MII_CTRL_IF_MASK); |
||
333 | t |= (mii_if & MII_CTRL_IF_MASK); |
||
334 | ag71xx_mii_ctrl_wr(ag, t); |
||
335 | } |
||
336 | |||
337 | static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, |
||
338 | unsigned int speed) |
||
339 | { |
||
340 | u32 t; |
||
341 | |||
342 | t = ag71xx_mii_ctrl_rr(ag); |
||
343 | t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); |
||
344 | t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; |
||
345 | ag71xx_mii_ctrl_wr(ag, t); |
||
346 | } |
||
347 | |||
348 | #ifdef CONFIG_AG71XX_AR8216_SUPPORT |
||
349 | void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); |
||
350 | int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, |
||
351 | int pktlen); |
||
352 | static inline int ag71xx_has_ar8216(struct ag71xx *ag) |
||
353 | { |
||
354 | return ag71xx_get_pdata(ag)->has_ar8216; |
||
355 | } |
||
356 | #else |
||
357 | static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, |
||
358 | struct sk_buff *skb) |
||
359 | { |
||
360 | } |
||
361 | |||
362 | static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, |
||
363 | struct sk_buff *skb, |
||
364 | int pktlen) |
||
365 | { |
||
366 | return 0; |
||
367 | } |
||
368 | static inline int ag71xx_has_ar8216(struct ag71xx *ag) |
||
369 | { |
||
370 | return 0; |
||
371 | } |
||
372 | #endif |
||
373 | |||
374 | #endif /* _AG71XX_H */ |