Commit b13ad8f498793dc582b7f42f27b8f44490bd608d
1 parent
63d24a0eb7
Exists in
master
and in
6 other branches
xilinx/ll_temac: Move the Xilinx drivers
Move the Xilinx drivers into drivers/net/ethernet/xilinx/ and make the necessary Kconfig and Makefile changes. CC: John Williams <john.williams@petalogix.com> CC: "David H. Lynch Jr." <dhlii@dlasys.net> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Showing 14 changed files with 3035 additions and 3010 deletions Side-by-side Diff
- drivers/net/Kconfig
- drivers/net/Makefile
- drivers/net/ethernet/Kconfig
- drivers/net/ethernet/Makefile
- drivers/net/ethernet/xilinx/Kconfig
- drivers/net/ethernet/xilinx/Makefile
- drivers/net/ethernet/xilinx/ll_temac.h
- drivers/net/ethernet/xilinx/ll_temac_main.c
- drivers/net/ethernet/xilinx/ll_temac_mdio.c
- drivers/net/ethernet/xilinx/xilinx_emaclite.c
- drivers/net/ll_temac.h
- drivers/net/ll_temac_main.c
- drivers/net/ll_temac_mdio.c
- drivers/net/xilinx_emaclite.c
drivers/net/Kconfig
... | ... | @@ -493,13 +493,6 @@ |
493 | 493 | the questions about this class of network devices. If you say Y, you |
494 | 494 | will be asked for your specific device in the following questions. |
495 | 495 | |
496 | -config XILINX_EMACLITE | |
497 | - tristate "Xilinx 10/100 Ethernet Lite support" | |
498 | - depends on PPC32 || MICROBLAZE | |
499 | - select PHYLIB | |
500 | - help | |
501 | - This driver supports the 10/100 Ethernet Lite from Xilinx. | |
502 | - | |
503 | 496 | config LANTIQ_ETOP |
504 | 497 | tristate "Lantiq SoC ETOP driver" |
505 | 498 | depends on SOC_TYPE_XWAY |
... | ... | @@ -538,14 +531,6 @@ |
538 | 531 | |
539 | 532 | To compile this driver as a module, choose M here: the module |
540 | 533 | will be called ipg. This is recommended. |
541 | - | |
542 | -config XILINX_LL_TEMAC | |
543 | - tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" | |
544 | - depends on PPC || MICROBLAZE | |
545 | - select PHYLIB | |
546 | - help | |
547 | - This driver supports the Xilinx 10/100/1000 LocalLink TEMAC | |
548 | - core used in Xilinx Spartan and Virtex FPGAs | |
549 | 534 | |
550 | 535 | endif # NETDEV_1000 |
551 | 536 |
drivers/net/Makefile
... | ... | @@ -33,10 +33,6 @@ |
33 | 33 | obj-$(CONFIG_HP100) += hp100.o |
34 | 34 | obj-$(CONFIG_FORCEDETH) += forcedeth.o |
35 | 35 | |
36 | -ll_temac-objs := ll_temac_main.o ll_temac_mdio.o | |
37 | -obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o | |
38 | -obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o | |
39 | - | |
40 | 36 | obj-$(CONFIG_PPP) += ppp_generic.o |
41 | 37 | obj-$(CONFIG_PPP_ASYNC) += ppp_async.o |
42 | 38 | obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o |
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/xilinx/Kconfig
1 | +# | |
2 | +# Xilink device configuration | |
3 | +# | |
4 | + | |
5 | +config NET_VENDOR_XILINX | |
6 | + bool "Xilinx devices" | |
7 | + depends on PPC || PPC32 || MICROBLAZE | |
8 | + ---help--- | |
9 | + If you have a network (Ethernet) card belonging to this class, say Y | |
10 | + and read the Ethernet-HOWTO, available from | |
11 | + <http://www.tldp.org/docs.html#howto>. | |
12 | + | |
13 | + Note that the answer to this question doesn't directly affect the | |
14 | + kernel: saying N will just cause the configurator to skip all | |
15 | + the questions about Xilinx devices. If you say Y, you will be asked | |
16 | + for your specific card in the following questions. | |
17 | + | |
18 | +if NET_VENDOR_XILINX | |
19 | + | |
20 | +config XILINX_EMACLITE | |
21 | + tristate "Xilinx 10/100 Ethernet Lite support" | |
22 | + depends on (PPC32 || MICROBLAZE) | |
23 | + select PHYLIB | |
24 | + ---help--- | |
25 | + This driver supports the 10/100 Ethernet Lite from Xilinx. | |
26 | + | |
27 | +config XILINX_LL_TEMAC | |
28 | + tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" | |
29 | + depends on (PPC || MICROBLAZE) | |
30 | + select PHYLIB | |
31 | + ---help--- | |
32 | + This driver supports the Xilinx 10/100/1000 LocalLink TEMAC | |
33 | + core used in Xilinx Spartan and Virtex FPGAs | |
34 | + | |
35 | +endif # NET_VENDOR_XILINX |
drivers/net/ethernet/xilinx/Makefile
drivers/net/ethernet/xilinx/ll_temac.h
1 | + | |
2 | +#ifndef XILINX_LL_TEMAC_H | |
3 | +#define XILINX_LL_TEMAC_H | |
4 | + | |
5 | +#include <linux/netdevice.h> | |
6 | +#include <linux/of.h> | |
7 | +#include <linux/spinlock.h> | |
8 | + | |
9 | +#ifdef CONFIG_PPC_DCR | |
10 | +#include <asm/dcr.h> | |
11 | +#include <asm/dcr-regs.h> | |
12 | +#endif | |
13 | + | |
14 | +/* packet size info */ | |
15 | +#define XTE_HDR_SIZE 14 /* size of Ethernet header */ | |
16 | +#define XTE_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */ | |
17 | +#define XTE_JUMBO_MTU 9000 | |
18 | +#define XTE_MAX_JUMBO_FRAME_SIZE (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE) | |
19 | + | |
20 | +/* Configuration options */ | |
21 | + | |
22 | +/* Accept all incoming packets. | |
23 | + * This option defaults to disabled (cleared) */ | |
24 | +#define XTE_OPTION_PROMISC (1 << 0) | |
25 | +/* Jumbo frame support for Tx & Rx. | |
26 | + * This option defaults to disabled (cleared) */ | |
27 | +#define XTE_OPTION_JUMBO (1 << 1) | |
28 | +/* VLAN Rx & Tx frame support. | |
29 | + * This option defaults to disabled (cleared) */ | |
30 | +#define XTE_OPTION_VLAN (1 << 2) | |
31 | +/* Enable recognition of flow control frames on Rx | |
32 | + * This option defaults to enabled (set) */ | |
33 | +#define XTE_OPTION_FLOW_CONTROL (1 << 4) | |
34 | +/* Strip FCS and PAD from incoming frames. | |
35 | + * Note: PAD from VLAN frames is not stripped. | |
36 | + * This option defaults to disabled (set) */ | |
37 | +#define XTE_OPTION_FCS_STRIP (1 << 5) | |
38 | +/* Generate FCS field and add PAD automatically for outgoing frames. | |
39 | + * This option defaults to enabled (set) */ | |
40 | +#define XTE_OPTION_FCS_INSERT (1 << 6) | |
41 | +/* Enable Length/Type error checking for incoming frames. When this option is | |
42 | +set, the MAC will filter frames that have a mismatched type/length field | |
43 | +and if XTE_OPTION_REPORT_RXERR is set, the user is notified when these | |
44 | +types of frames are encountered. When this option is cleared, the MAC will | |
45 | +allow these types of frames to be received. | |
46 | +This option defaults to enabled (set) */ | |
47 | +#define XTE_OPTION_LENTYPE_ERR (1 << 7) | |
48 | +/* Enable the transmitter. | |
49 | + * This option defaults to enabled (set) */ | |
50 | +#define XTE_OPTION_TXEN (1 << 11) | |
51 | +/* Enable the receiver | |
52 | +* This option defaults to enabled (set) */ | |
53 | +#define XTE_OPTION_RXEN (1 << 12) | |
54 | + | |
55 | +/* Default options set when device is initialized or reset */ | |
56 | +#define XTE_OPTION_DEFAULTS \ | |
57 | + (XTE_OPTION_TXEN | \ | |
58 | + XTE_OPTION_FLOW_CONTROL | \ | |
59 | + XTE_OPTION_RXEN) | |
60 | + | |
61 | +/* XPS_LL_TEMAC SDMA registers definition */ | |
62 | + | |
63 | +#define TX_NXTDESC_PTR 0x00 /* r */ | |
64 | +#define TX_CURBUF_ADDR 0x01 /* r */ | |
65 | +#define TX_CURBUF_LENGTH 0x02 /* r */ | |
66 | +#define TX_CURDESC_PTR 0x03 /* rw */ | |
67 | +#define TX_TAILDESC_PTR 0x04 /* rw */ | |
68 | +#define TX_CHNL_CTRL 0x05 /* rw */ | |
69 | +/* | |
70 | + 0:7 24:31 IRQTimeout | |
71 | + 8:15 16:23 IRQCount | |
72 | + 16:20 11:15 Reserved | |
73 | + 21 10 0 | |
74 | + 22 9 UseIntOnEnd | |
75 | + 23 8 LdIRQCnt | |
76 | + 24 7 IRQEn | |
77 | + 25:28 3:6 Reserved | |
78 | + 29 2 IrqErrEn | |
79 | + 30 1 IrqDlyEn | |
80 | + 31 0 IrqCoalEn | |
81 | +*/ | |
82 | +#define CHNL_CTRL_IRQ_IOE (1 << 9) | |
83 | +#define CHNL_CTRL_IRQ_EN (1 << 7) | |
84 | +#define CHNL_CTRL_IRQ_ERR_EN (1 << 2) | |
85 | +#define CHNL_CTRL_IRQ_DLY_EN (1 << 1) | |
86 | +#define CHNL_CTRL_IRQ_COAL_EN (1 << 0) | |
87 | +#define TX_IRQ_REG 0x06 /* rw */ | |
88 | +/* | |
89 | + 0:7 24:31 DltTmrValue | |
90 | + 8:15 16:23 ClscCntrValue | |
91 | + 16:17 14:15 Reserved | |
92 | + 18:21 10:13 ClscCnt | |
93 | + 22:23 8:9 DlyCnt | |
94 | + 24:28 3::7 Reserved | |
95 | + 29 2 ErrIrq | |
96 | + 30 1 DlyIrq | |
97 | + 31 0 CoalIrq | |
98 | + */ | |
99 | +#define TX_CHNL_STS 0x07 /* r */ | |
100 | +/* | |
101 | + 0:9 22:31 Reserved | |
102 | + 10 21 TailPErr | |
103 | + 11 20 CmpErr | |
104 | + 12 19 AddrErr | |
105 | + 13 18 NxtPErr | |
106 | + 14 17 CurPErr | |
107 | + 15 16 BsyWr | |
108 | + 16:23 8:15 Reserved | |
109 | + 24 7 Error | |
110 | + 25 6 IOE | |
111 | + 26 5 SOE | |
112 | + 27 4 Cmplt | |
113 | + 28 3 SOP | |
114 | + 29 2 EOP | |
115 | + 30 1 EngBusy | |
116 | + 31 0 Reserved | |
117 | +*/ | |
118 | + | |
119 | +#define RX_NXTDESC_PTR 0x08 /* r */ | |
120 | +#define RX_CURBUF_ADDR 0x09 /* r */ | |
121 | +#define RX_CURBUF_LENGTH 0x0a /* r */ | |
122 | +#define RX_CURDESC_PTR 0x0b /* rw */ | |
123 | +#define RX_TAILDESC_PTR 0x0c /* rw */ | |
124 | +#define RX_CHNL_CTRL 0x0d /* rw */ | |
125 | +/* | |
126 | + 0:7 24:31 IRQTimeout | |
127 | + 8:15 16:23 IRQCount | |
128 | + 16:20 11:15 Reserved | |
129 | + 21 10 0 | |
130 | + 22 9 UseIntOnEnd | |
131 | + 23 8 LdIRQCnt | |
132 | + 24 7 IRQEn | |
133 | + 25:28 3:6 Reserved | |
134 | + 29 2 IrqErrEn | |
135 | + 30 1 IrqDlyEn | |
136 | + 31 0 IrqCoalEn | |
137 | + */ | |
138 | +#define RX_IRQ_REG 0x0e /* rw */ | |
139 | +#define IRQ_COAL (1 << 0) | |
140 | +#define IRQ_DLY (1 << 1) | |
141 | +#define IRQ_ERR (1 << 2) | |
142 | +#define IRQ_DMAERR (1 << 7) /* this is not documented ??? */ | |
143 | +/* | |
144 | + 0:7 24:31 DltTmrValue | |
145 | + 8:15 16:23 ClscCntrValue | |
146 | + 16:17 14:15 Reserved | |
147 | + 18:21 10:13 ClscCnt | |
148 | + 22:23 8:9 DlyCnt | |
149 | + 24:28 3::7 Reserved | |
150 | +*/ | |
151 | +#define RX_CHNL_STS 0x0f /* r */ | |
152 | +#define CHNL_STS_ENGBUSY (1 << 1) | |
153 | +#define CHNL_STS_EOP (1 << 2) | |
154 | +#define CHNL_STS_SOP (1 << 3) | |
155 | +#define CHNL_STS_CMPLT (1 << 4) | |
156 | +#define CHNL_STS_SOE (1 << 5) | |
157 | +#define CHNL_STS_IOE (1 << 6) | |
158 | +#define CHNL_STS_ERR (1 << 7) | |
159 | + | |
160 | +#define CHNL_STS_BSYWR (1 << 16) | |
161 | +#define CHNL_STS_CURPERR (1 << 17) | |
162 | +#define CHNL_STS_NXTPERR (1 << 18) | |
163 | +#define CHNL_STS_ADDRERR (1 << 19) | |
164 | +#define CHNL_STS_CMPERR (1 << 20) | |
165 | +#define CHNL_STS_TAILERR (1 << 21) | |
166 | +/* | |
167 | + 0:9 22:31 Reserved | |
168 | + 10 21 TailPErr | |
169 | + 11 20 CmpErr | |
170 | + 12 19 AddrErr | |
171 | + 13 18 NxtPErr | |
172 | + 14 17 CurPErr | |
173 | + 15 16 BsyWr | |
174 | + 16:23 8:15 Reserved | |
175 | + 24 7 Error | |
176 | + 25 6 IOE | |
177 | + 26 5 SOE | |
178 | + 27 4 Cmplt | |
179 | + 28 3 SOP | |
180 | + 29 2 EOP | |
181 | + 30 1 EngBusy | |
182 | + 31 0 Reserved | |
183 | +*/ | |
184 | + | |
185 | +#define DMA_CONTROL_REG 0x10 /* rw */ | |
186 | +#define DMA_CONTROL_RST (1 << 0) | |
187 | +#define DMA_TAIL_ENABLE (1 << 2) | |
188 | + | |
189 | +/* XPS_LL_TEMAC direct registers definition */ | |
190 | + | |
191 | +#define XTE_RAF0_OFFSET 0x00 | |
192 | +#define RAF0_RST (1 << 0) | |
193 | +#define RAF0_MCSTREJ (1 << 1) | |
194 | +#define RAF0_BCSTREJ (1 << 2) | |
195 | +#define XTE_TPF0_OFFSET 0x04 | |
196 | +#define XTE_IFGP0_OFFSET 0x08 | |
197 | +#define XTE_ISR0_OFFSET 0x0c | |
198 | +#define ISR0_HARDACSCMPLT (1 << 0) | |
199 | +#define ISR0_AUTONEG (1 << 1) | |
200 | +#define ISR0_RXCMPLT (1 << 2) | |
201 | +#define ISR0_RXREJ (1 << 3) | |
202 | +#define ISR0_RXFIFOOVR (1 << 4) | |
203 | +#define ISR0_TXCMPLT (1 << 5) | |
204 | +#define ISR0_RXDCMLCK (1 << 6) | |
205 | + | |
206 | +#define XTE_IPR0_OFFSET 0x10 | |
207 | +#define XTE_IER0_OFFSET 0x14 | |
208 | + | |
209 | +#define XTE_MSW0_OFFSET 0x20 | |
210 | +#define XTE_LSW0_OFFSET 0x24 | |
211 | +#define XTE_CTL0_OFFSET 0x28 | |
212 | +#define XTE_RDY0_OFFSET 0x2c | |
213 | + | |
214 | +#define XTE_RSE_MIIM_RR_MASK 0x0002 | |
215 | +#define XTE_RSE_MIIM_WR_MASK 0x0004 | |
216 | +#define XTE_RSE_CFG_RR_MASK 0x0020 | |
217 | +#define XTE_RSE_CFG_WR_MASK 0x0040 | |
218 | +#define XTE_RDY0_HARD_ACS_RDY_MASK (0x10000) | |
219 | + | |
220 | +/* XPS_LL_TEMAC indirect registers offset definition */ | |
221 | + | |
222 | +#define XTE_RXC0_OFFSET 0x00000200 /* Rx configuration word 0 */ | |
223 | +#define XTE_RXC1_OFFSET 0x00000240 /* Rx configuration word 1 */ | |
224 | +#define XTE_RXC1_RXRST_MASK (1 << 31) /* Receiver reset */ | |
225 | +#define XTE_RXC1_RXJMBO_MASK (1 << 30) /* Jumbo frame enable */ | |
226 | +#define XTE_RXC1_RXFCS_MASK (1 << 29) /* FCS not stripped */ | |
227 | +#define XTE_RXC1_RXEN_MASK (1 << 28) /* Receiver enable */ | |
228 | +#define XTE_RXC1_RXVLAN_MASK (1 << 27) /* VLAN enable */ | |
229 | +#define XTE_RXC1_RXHD_MASK (1 << 26) /* Half duplex */ | |
230 | +#define XTE_RXC1_RXLT_MASK (1 << 25) /* Length/type check disable */ | |
231 | + | |
232 | +#define XTE_TXC_OFFSET 0x00000280 /* Tx configuration */ | |
233 | +#define XTE_TXC_TXRST_MASK (1 << 31) /* Transmitter reset */ | |
234 | +#define XTE_TXC_TXJMBO_MASK (1 << 30) /* Jumbo frame enable */ | |
235 | +#define XTE_TXC_TXFCS_MASK (1 << 29) /* Generate FCS */ | |
236 | +#define XTE_TXC_TXEN_MASK (1 << 28) /* Transmitter enable */ | |
237 | +#define XTE_TXC_TXVLAN_MASK (1 << 27) /* VLAN enable */ | |
238 | +#define XTE_TXC_TXHD_MASK (1 << 26) /* Half duplex */ | |
239 | + | |
240 | +#define XTE_FCC_OFFSET 0x000002C0 /* Flow control config */ | |
241 | +#define XTE_FCC_RXFLO_MASK (1 << 29) /* Rx flow control enable */ | |
242 | +#define XTE_FCC_TXFLO_MASK (1 << 30) /* Tx flow control enable */ | |
243 | + | |
244 | +#define XTE_EMCFG_OFFSET 0x00000300 /* EMAC configuration */ | |
245 | +#define XTE_EMCFG_LINKSPD_MASK 0xC0000000 /* Link speed */ | |
246 | +#define XTE_EMCFG_HOSTEN_MASK (1 << 26) /* Host interface enable */ | |
247 | +#define XTE_EMCFG_LINKSPD_10 0x00000000 /* 10 Mbit LINKSPD_MASK */ | |
248 | +#define XTE_EMCFG_LINKSPD_100 (1 << 30) /* 100 Mbit LINKSPD_MASK */ | |
249 | +#define XTE_EMCFG_LINKSPD_1000 (1 << 31) /* 1000 Mbit LINKSPD_MASK */ | |
250 | + | |
251 | +#define XTE_GMIC_OFFSET 0x00000320 /* RGMII/SGMII config */ | |
252 | +#define XTE_MC_OFFSET 0x00000340 /* MDIO configuration */ | |
253 | +#define XTE_UAW0_OFFSET 0x00000380 /* Unicast address word 0 */ | |
254 | +#define XTE_UAW1_OFFSET 0x00000384 /* Unicast address word 1 */ | |
255 | + | |
256 | +#define XTE_MAW0_OFFSET 0x00000388 /* Multicast addr word 0 */ | |
257 | +#define XTE_MAW1_OFFSET 0x0000038C /* Multicast addr word 1 */ | |
258 | +#define XTE_AFM_OFFSET 0x00000390 /* Promiscuous mode */ | |
259 | +#define XTE_AFM_EPPRM_MASK (1 << 31) /* Promiscuous mode enable */ | |
260 | + | |
261 | +/* Interrupt Request status */ | |
262 | +#define XTE_TIS_OFFSET 0x000003A0 | |
263 | +#define TIS_FRIS (1 << 0) | |
264 | +#define TIS_MRIS (1 << 1) | |
265 | +#define TIS_MWIS (1 << 2) | |
266 | +#define TIS_ARIS (1 << 3) | |
267 | +#define TIS_AWIS (1 << 4) | |
268 | +#define TIS_CRIS (1 << 5) | |
269 | +#define TIS_CWIS (1 << 6) | |
270 | + | |
271 | +#define XTE_TIE_OFFSET 0x000003A4 /* Interrupt enable */ | |
272 | + | |
273 | +/** MII Mamagement Control register (MGTCR) */ | |
274 | +#define XTE_MGTDR_OFFSET 0x000003B0 /* MII data */ | |
275 | +#define XTE_MIIMAI_OFFSET 0x000003B4 /* MII control */ | |
276 | + | |
277 | +#define CNTLREG_WRITE_ENABLE_MASK 0x8000 | |
278 | +#define CNTLREG_EMAC1SEL_MASK 0x0400 | |
279 | +#define CNTLREG_ADDRESSCODE_MASK 0x03ff | |
280 | + | |
281 | +/* CDMAC descriptor status bit definitions */ | |
282 | + | |
283 | +#define STS_CTRL_APP0_ERR (1 << 31) | |
284 | +#define STS_CTRL_APP0_IRQONEND (1 << 30) | |
285 | +/* undoccumented */ | |
286 | +#define STS_CTRL_APP0_STOPONEND (1 << 29) | |
287 | +#define STS_CTRL_APP0_CMPLT (1 << 28) | |
288 | +#define STS_CTRL_APP0_SOP (1 << 27) | |
289 | +#define STS_CTRL_APP0_EOP (1 << 26) | |
290 | +#define STS_CTRL_APP0_ENGBUSY (1 << 25) | |
291 | +/* undocumented */ | |
292 | +#define STS_CTRL_APP0_ENGRST (1 << 24) | |
293 | + | |
294 | +#define TX_CONTROL_CALC_CSUM_MASK 1 | |
295 | + | |
296 | +#define MULTICAST_CAM_TABLE_NUM 4 | |
297 | + | |
298 | +/* TEMAC Synthesis features */ | |
299 | +#define TEMAC_FEATURE_RX_CSUM (1 << 0) | |
300 | +#define TEMAC_FEATURE_TX_CSUM (1 << 1) | |
301 | + | |
302 | +/* TX/RX CURDESC_PTR points to first descriptor */ | |
303 | +/* TX/RX TAILDESC_PTR points to last descriptor in linked list */ | |
304 | + | |
305 | +/** | |
306 | + * struct cdmac_bd - LocalLink buffer descriptor format | |
307 | + * | |
308 | + * app0 bits: | |
309 | + * 0 Error | |
310 | + * 1 IrqOnEnd generate an interrupt at completion of DMA op | |
311 | + * 2 reserved | |
312 | + * 3 completed Current descriptor completed | |
313 | + * 4 SOP TX - marks first desc/ RX marks first desct | |
314 | + * 5 EOP TX marks last desc/RX marks last desc | |
315 | + * 6 EngBusy DMA is processing | |
316 | + * 7 reserved | |
317 | + * 8:31 application specific | |
318 | + */ | |
319 | +struct cdmac_bd { | |
320 | + u32 next; /* Physical address of next buffer descriptor */ | |
321 | + u32 phys; | |
322 | + u32 len; | |
323 | + u32 app0; | |
324 | + u32 app1; /* TX start << 16 | insert */ | |
325 | + u32 app2; /* TX csum */ | |
326 | + u32 app3; | |
327 | + u32 app4; /* skb for TX length for RX */ | |
328 | +}; | |
329 | + | |
330 | +struct temac_local { | |
331 | + struct net_device *ndev; | |
332 | + struct device *dev; | |
333 | + | |
334 | + /* Connection to PHY device */ | |
335 | + struct phy_device *phy_dev; /* Pointer to PHY device */ | |
336 | + struct device_node *phy_node; | |
337 | + | |
338 | + /* MDIO bus data */ | |
339 | + struct mii_bus *mii_bus; /* MII bus reference */ | |
340 | + int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ | |
341 | + | |
342 | + /* IO registers, dma functions and IRQs */ | |
343 | + void __iomem *regs; | |
344 | + void __iomem *sdma_regs; | |
345 | +#ifdef CONFIG_PPC_DCR | |
346 | + dcr_host_t sdma_dcrs; | |
347 | +#endif | |
348 | + u32 (*dma_in)(struct temac_local *, int); | |
349 | + void (*dma_out)(struct temac_local *, int, u32); | |
350 | + | |
351 | + int tx_irq; | |
352 | + int rx_irq; | |
353 | + int emac_num; | |
354 | + | |
355 | + struct sk_buff **rx_skb; | |
356 | + spinlock_t rx_lock; | |
357 | + struct mutex indirect_mutex; | |
358 | + u32 options; /* Current options word */ | |
359 | + int last_link; | |
360 | + unsigned int temac_features; | |
361 | + | |
362 | + /* Buffer descriptors */ | |
363 | + struct cdmac_bd *tx_bd_v; | |
364 | + dma_addr_t tx_bd_p; | |
365 | + struct cdmac_bd *rx_bd_v; | |
366 | + dma_addr_t rx_bd_p; | |
367 | + int tx_bd_ci; | |
368 | + int tx_bd_next; | |
369 | + int tx_bd_tail; | |
370 | + int rx_bd_ci; | |
371 | +}; | |
372 | + | |
373 | +/* xilinx_temac.c */ | |
374 | +u32 temac_ior(struct temac_local *lp, int offset); | |
375 | +void temac_iow(struct temac_local *lp, int offset, u32 value); | |
376 | +int temac_indirect_busywait(struct temac_local *lp); | |
377 | +u32 temac_indirect_in32(struct temac_local *lp, int reg); | |
378 | +void temac_indirect_out32(struct temac_local *lp, int reg, u32 value); | |
379 | + | |
380 | + | |
381 | +/* xilinx_temac_mdio.c */ | |
382 | +int temac_mdio_setup(struct temac_local *lp, struct device_node *np); | |
383 | +void temac_mdio_teardown(struct temac_local *lp); | |
384 | + | |
385 | +#endif /* XILINX_LL_TEMAC_H */ |
drivers/net/ethernet/xilinx/ll_temac_main.c
Changes suppressed. Click to show
1 | +/* | |
2 | + * Driver for Xilinx TEMAC Ethernet device | |
3 | + * | |
4 | + * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi | |
5 | + * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. <dhlii@dlasys.net> | |
6 | + * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. | |
7 | + * | |
8 | + * This is a driver for the Xilinx ll_temac ipcore which is often used | |
9 | + * in the Virtex and Spartan series of chips. | |
10 | + * | |
11 | + * Notes: | |
12 | + * - The ll_temac hardware uses indirect access for many of the TEMAC | |
13 | + * registers, include the MDIO bus. However, indirect access to MDIO | |
14 | + * registers take considerably more clock cycles than to TEMAC registers. | |
15 | + * MDIO accesses are long, so threads doing them should probably sleep | |
16 | + * rather than busywait. However, since only one indirect access can be | |
17 | + * in progress at any given time, that means that *all* indirect accesses | |
18 | + * could end up sleeping (to wait for an MDIO access to complete). | |
19 | + * Fortunately none of the indirect accesses are on the 'hot' path for tx | |
20 | + * or rx, so this should be okay. | |
21 | + * | |
22 | + * TODO: | |
23 | + * - Factor out locallink DMA code into separate driver | |
24 | + * - Fix multicast assignment. | |
25 | + * - Fix support for hardware checksumming. | |
26 | + * - Testing. Lots and lots of testing. | |
27 | + * | |
28 | + */ | |
29 | + | |
30 | +#include <linux/delay.h> | |
31 | +#include <linux/etherdevice.h> | |
32 | +#include <linux/init.h> | |
33 | +#include <linux/mii.h> | |
34 | +#include <linux/module.h> | |
35 | +#include <linux/mutex.h> | |
36 | +#include <linux/netdevice.h> | |
37 | +#include <linux/of.h> | |
38 | +#include <linux/of_device.h> | |
39 | +#include <linux/of_mdio.h> | |
40 | +#include <linux/of_platform.h> | |
41 | +#include <linux/of_address.h> | |
42 | +#include <linux/skbuff.h> | |
43 | +#include <linux/spinlock.h> | |
44 | +#include <linux/tcp.h> /* needed for sizeof(tcphdr) */ | |
45 | +#include <linux/udp.h> /* needed for sizeof(udphdr) */ | |
46 | +#include <linux/phy.h> | |
47 | +#include <linux/in.h> | |
48 | +#include <linux/io.h> | |
49 | +#include <linux/ip.h> | |
50 | +#include <linux/slab.h> | |
51 | +#include <linux/interrupt.h> | |
52 | +#include <linux/dma-mapping.h> | |
53 | + | |
54 | +#include "ll_temac.h" | |
55 | + | |
56 | +#define TX_BD_NUM 64 | |
57 | +#define RX_BD_NUM 128 | |
58 | + | |
59 | +/* --------------------------------------------------------------------- | |
60 | + * Low level register access functions | |
61 | + */ | |
62 | + | |
63 | +u32 temac_ior(struct temac_local *lp, int offset) | |
64 | +{ | |
65 | + return in_be32((u32 *)(lp->regs + offset)); | |
66 | +} | |
67 | + | |
68 | +void temac_iow(struct temac_local *lp, int offset, u32 value) | |
69 | +{ | |
70 | + out_be32((u32 *) (lp->regs + offset), value); | |
71 | +} | |
72 | + | |
73 | +int temac_indirect_busywait(struct temac_local *lp) | |
74 | +{ | |
75 | + long end = jiffies + 2; | |
76 | + | |
77 | + while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) { | |
78 | + if (end - jiffies <= 0) { | |
79 | + WARN_ON(1); | |
80 | + return -ETIMEDOUT; | |
81 | + } | |
82 | + msleep(1); | |
83 | + } | |
84 | + return 0; | |
85 | +} | |
86 | + | |
87 | +/** | |
88 | + * temac_indirect_in32 | |
89 | + * | |
90 | + * lp->indirect_mutex must be held when calling this function | |
91 | + */ | |
92 | +u32 temac_indirect_in32(struct temac_local *lp, int reg) | |
93 | +{ | |
94 | + u32 val; | |
95 | + | |
96 | + if (temac_indirect_busywait(lp)) | |
97 | + return -ETIMEDOUT; | |
98 | + temac_iow(lp, XTE_CTL0_OFFSET, reg); | |
99 | + if (temac_indirect_busywait(lp)) | |
100 | + return -ETIMEDOUT; | |
101 | + val = temac_ior(lp, XTE_LSW0_OFFSET); | |
102 | + | |
103 | + return val; | |
104 | +} | |
105 | + | |
106 | +/** | |
107 | + * temac_indirect_out32 | |
108 | + * | |
109 | + * lp->indirect_mutex must be held when calling this function | |
110 | + */ | |
111 | +void temac_indirect_out32(struct temac_local *lp, int reg, u32 value) | |
112 | +{ | |
113 | + if (temac_indirect_busywait(lp)) | |
114 | + return; | |
115 | + temac_iow(lp, XTE_LSW0_OFFSET, value); | |
116 | + temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); | |
117 | +} | |
118 | + | |
119 | +/** | |
120 | + * temac_dma_in32 - Memory mapped DMA read, this function expects a | |
121 | + * register input that is based on DCR word addresses which | |
122 | + * are then converted to memory mapped byte addresses | |
123 | + */ | |
124 | +static u32 temac_dma_in32(struct temac_local *lp, int reg) | |
125 | +{ | |
126 | + return in_be32((u32 *)(lp->sdma_regs + (reg << 2))); | |
127 | +} | |
128 | + | |
129 | +/** | |
130 | + * temac_dma_out32 - Memory mapped DMA read, this function expects a | |
131 | + * register input that is based on DCR word addresses which | |
132 | + * are then converted to memory mapped byte addresses | |
133 | + */ | |
134 | +static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) | |
135 | +{ | |
136 | + out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value); | |
137 | +} | |
138 | + | |
139 | +/* DMA register access functions can be DCR based or memory mapped. | |
140 | + * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both | |
141 | + * memory mapped. | |
142 | + */ | |
143 | +#ifdef CONFIG_PPC_DCR | |
144 | + | |
145 | +/** | |
146 | + * temac_dma_dcr_in32 - DCR based DMA read | |
147 | + */ | |
148 | +static u32 temac_dma_dcr_in(struct temac_local *lp, int reg) | |
149 | +{ | |
150 | + return dcr_read(lp->sdma_dcrs, reg); | |
151 | +} | |
152 | + | |
153 | +/** | |
154 | + * temac_dma_dcr_out32 - DCR based DMA write | |
155 | + */ | |
156 | +static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value) | |
157 | +{ | |
158 | + dcr_write(lp->sdma_dcrs, reg, value); | |
159 | +} | |
160 | + | |
161 | +/** | |
162 | + * temac_dcr_setup - If the DMA is DCR based, then setup the address and | |
163 | + * I/O functions | |
164 | + */ | |
165 | +static int temac_dcr_setup(struct temac_local *lp, struct platform_device *op, | |
166 | + struct device_node *np) | |
167 | +{ | |
168 | + unsigned int dcrs; | |
169 | + | |
170 | + /* setup the dcr address mapping if it's in the device tree */ | |
171 | + | |
172 | + dcrs = dcr_resource_start(np, 0); | |
173 | + if (dcrs != 0) { | |
174 | + lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); | |
175 | + lp->dma_in = temac_dma_dcr_in; | |
176 | + lp->dma_out = temac_dma_dcr_out; | |
177 | + dev_dbg(&op->dev, "DCR base: %x\n", dcrs); | |
178 | + return 0; | |
179 | + } | |
180 | + /* no DCR in the device tree, indicate a failure */ | |
181 | + return -1; | |
182 | +} | |
183 | + | |
184 | +#else | |
185 | + | |
186 | +/* | |
187 | + * temac_dcr_setup - This is a stub for when DCR is not supported, | |
188 | + * such as with MicroBlaze | |
189 | + */ | |
190 | +static int temac_dcr_setup(struct temac_local *lp, struct platform_device *op, | |
191 | + struct device_node *np) | |
192 | +{ | |
193 | + return -1; | |
194 | +} | |
195 | + | |
196 | +#endif | |
197 | + | |
198 | +/** | |
199 | + * * temac_dma_bd_release - Release buffer descriptor rings | |
200 | + */ | |
201 | +static void temac_dma_bd_release(struct net_device *ndev) | |
202 | +{ | |
203 | + struct temac_local *lp = netdev_priv(ndev); | |
204 | + int i; | |
205 | + | |
206 | + for (i = 0; i < RX_BD_NUM; i++) { | |
207 | + if (!lp->rx_skb[i]) | |
208 | + break; | |
209 | + else { | |
210 | + dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys, | |
211 | + XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); | |
212 | + dev_kfree_skb(lp->rx_skb[i]); | |
213 | + } | |
214 | + } | |
215 | + if (lp->rx_bd_v) | |
216 | + dma_free_coherent(ndev->dev.parent, | |
217 | + sizeof(*lp->rx_bd_v) * RX_BD_NUM, | |
218 | + lp->rx_bd_v, lp->rx_bd_p); | |
219 | + if (lp->tx_bd_v) | |
220 | + dma_free_coherent(ndev->dev.parent, | |
221 | + sizeof(*lp->tx_bd_v) * TX_BD_NUM, | |
222 | + lp->tx_bd_v, lp->tx_bd_p); | |
223 | + if (lp->rx_skb) | |
224 | + kfree(lp->rx_skb); | |
225 | +} | |
226 | + | |
227 | +/** | |
228 | + * temac_dma_bd_init - Setup buffer descriptor rings | |
229 | + */ | |
230 | +static int temac_dma_bd_init(struct net_device *ndev) | |
231 | +{ | |
232 | + struct temac_local *lp = netdev_priv(ndev); | |
233 | + struct sk_buff *skb; | |
234 | + int i; | |
235 | + | |
236 | + lp->rx_skb = kzalloc(sizeof(*lp->rx_skb) * RX_BD_NUM, GFP_KERNEL); | |
237 | + if (!lp->rx_skb) { | |
238 | + dev_err(&ndev->dev, | |
239 | + "can't allocate memory for DMA RX buffer\n"); | |
240 | + goto out; | |
241 | + } | |
242 | + /* allocate the tx and rx ring buffer descriptors. */ | |
243 | + /* returns a virtual address and a physical address. */ | |
244 | + lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, | |
245 | + sizeof(*lp->tx_bd_v) * TX_BD_NUM, | |
246 | + &lp->tx_bd_p, GFP_KERNEL); | |
247 | + if (!lp->tx_bd_v) { | |
248 | + dev_err(&ndev->dev, | |
249 | + "unable to allocate DMA TX buffer descriptors"); | |
250 | + goto out; | |
251 | + } | |
252 | + lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, | |
253 | + sizeof(*lp->rx_bd_v) * RX_BD_NUM, | |
254 | + &lp->rx_bd_p, GFP_KERNEL); | |
255 | + if (!lp->rx_bd_v) { | |
256 | + dev_err(&ndev->dev, | |
257 | + "unable to allocate DMA RX buffer descriptors"); | |
258 | + goto out; | |
259 | + } | |
260 | + | |
261 | + memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); | |
262 | + for (i = 0; i < TX_BD_NUM; i++) { | |
263 | + lp->tx_bd_v[i].next = lp->tx_bd_p + | |
264 | + sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM); | |
265 | + } | |
266 | + | |
267 | + memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM); | |
268 | + for (i = 0; i < RX_BD_NUM; i++) { | |
269 | + lp->rx_bd_v[i].next = lp->rx_bd_p + | |
270 | + sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); | |
271 | + | |
272 | + skb = netdev_alloc_skb_ip_align(ndev, | |
273 | + XTE_MAX_JUMBO_FRAME_SIZE); | |
274 | + | |
275 | + if (skb == 0) { | |
276 | + dev_err(&ndev->dev, "alloc_skb error %d\n", i); | |
277 | + goto out; | |
278 | + } | |
279 | + lp->rx_skb[i] = skb; | |
280 | + /* returns physical address of skb->data */ | |
281 | + lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, | |
282 | + skb->data, | |
283 | + XTE_MAX_JUMBO_FRAME_SIZE, | |
284 | + DMA_FROM_DEVICE); | |
285 | + lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE; | |
286 | + lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; | |
287 | + } | |
288 | + | |
289 | + lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 | | |
290 | + CHNL_CTRL_IRQ_EN | | |
291 | + CHNL_CTRL_IRQ_DLY_EN | | |
292 | + CHNL_CTRL_IRQ_COAL_EN); | |
293 | + /* 0x10220483 */ | |
294 | + /* 0x00100483 */ | |
295 | + lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 | | |
296 | + CHNL_CTRL_IRQ_EN | | |
297 | + CHNL_CTRL_IRQ_DLY_EN | | |
298 | + CHNL_CTRL_IRQ_COAL_EN | | |
299 | + CHNL_CTRL_IRQ_IOE); | |
300 | + /* 0xff010283 */ | |
301 | + | |
302 | + lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); | |
303 | + lp->dma_out(lp, RX_TAILDESC_PTR, | |
304 | + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); | |
305 | + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); | |
306 | + | |
307 | + return 0; | |
308 | + | |
309 | +out: | |
310 | + temac_dma_bd_release(ndev); | |
311 | + return -ENOMEM; | |
312 | +} | |
313 | + | |
314 | +/* --------------------------------------------------------------------- | |
315 | + * net_device_ops | |
316 | + */ | |
317 | + | |
318 | +static int temac_set_mac_address(struct net_device *ndev, void *address) | |
319 | +{ | |
320 | + struct temac_local *lp = netdev_priv(ndev); | |
321 | + | |
322 | + if (address) | |
323 | + memcpy(ndev->dev_addr, address, ETH_ALEN); | |
324 | + | |
325 | + if (!is_valid_ether_addr(ndev->dev_addr)) | |
326 | + random_ether_addr(ndev->dev_addr); | |
327 | + | |
328 | + /* set up unicast MAC address filter set its mac address */ | |
329 | + mutex_lock(&lp->indirect_mutex); | |
330 | + temac_indirect_out32(lp, XTE_UAW0_OFFSET, | |
331 | + (ndev->dev_addr[0]) | | |
332 | + (ndev->dev_addr[1] << 8) | | |
333 | + (ndev->dev_addr[2] << 16) | | |
334 | + (ndev->dev_addr[3] << 24)); | |
335 | + /* There are reserved bits in EUAW1 | |
336 | + * so don't affect them Set MAC bits [47:32] in EUAW1 */ | |
337 | + temac_indirect_out32(lp, XTE_UAW1_OFFSET, | |
338 | + (ndev->dev_addr[4] & 0x000000ff) | | |
339 | + (ndev->dev_addr[5] << 8)); | |
340 | + mutex_unlock(&lp->indirect_mutex); | |
341 | + | |
342 | + return 0; | |
343 | +} | |
344 | + | |
345 | +static int netdev_set_mac_address(struct net_device *ndev, void *p) | |
346 | +{ | |
347 | + struct sockaddr *addr = p; | |
348 | + | |
349 | + return temac_set_mac_address(ndev, addr->sa_data); | |
350 | +} | |
351 | + | |
352 | +static void temac_set_multicast_list(struct net_device *ndev) | |
353 | +{ | |
354 | + struct temac_local *lp = netdev_priv(ndev); | |
355 | + u32 multi_addr_msw, multi_addr_lsw, val; | |
356 | + int i; | |
357 | + | |
358 | + mutex_lock(&lp->indirect_mutex); | |
359 | + if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) || | |
360 | + netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) { | |
361 | + /* | |
362 | + * We must make the kernel realise we had to move | |
363 | + * into promisc mode or we start all out war on | |
364 | + * the cable. If it was a promisc request the | |
365 | + * flag is already set. If not we assert it. | |
366 | + */ | |
367 | + ndev->flags |= IFF_PROMISC; | |
368 | + temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK); | |
369 | + dev_info(&ndev->dev, "Promiscuous mode enabled.\n"); | |
370 | + } else if (!netdev_mc_empty(ndev)) { | |
371 | + struct netdev_hw_addr *ha; | |
372 | + | |
373 | + i = 0; | |
374 | + netdev_for_each_mc_addr(ha, ndev) { | |
375 | + if (i >= MULTICAST_CAM_TABLE_NUM) | |
376 | + break; | |
377 | + multi_addr_msw = ((ha->addr[3] << 24) | | |
378 | + (ha->addr[2] << 16) | | |
379 | + (ha->addr[1] << 8) | | |
380 | + (ha->addr[0])); | |
381 | + temac_indirect_out32(lp, XTE_MAW0_OFFSET, | |
382 | + multi_addr_msw); | |
383 | + multi_addr_lsw = ((ha->addr[5] << 8) | | |
384 | + (ha->addr[4]) | (i << 16)); | |
385 | + temac_indirect_out32(lp, XTE_MAW1_OFFSET, | |
386 | + multi_addr_lsw); | |
387 | + i++; | |
388 | + } | |
389 | + } else { | |
390 | + val = temac_indirect_in32(lp, XTE_AFM_OFFSET); | |
391 | + temac_indirect_out32(lp, XTE_AFM_OFFSET, | |
392 | + val & ~XTE_AFM_EPPRM_MASK); | |
393 | + temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0); | |
394 | + temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0); | |
395 | + dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); | |
396 | + } | |
397 | + mutex_unlock(&lp->indirect_mutex); | |
398 | +} | |
399 | + | |
400 | +struct temac_option { | |
401 | + int flg; | |
402 | + u32 opt; | |
403 | + u32 reg; | |
404 | + u32 m_or; | |
405 | + u32 m_and; | |
406 | +} temac_options[] = { | |
407 | + /* Turn on jumbo packet support for both Rx and Tx */ | |
408 | + { | |
409 | + .opt = XTE_OPTION_JUMBO, | |
410 | + .reg = XTE_TXC_OFFSET, | |
411 | + .m_or = XTE_TXC_TXJMBO_MASK, | |
412 | + }, | |
413 | + { | |
414 | + .opt = XTE_OPTION_JUMBO, | |
415 | + .reg = XTE_RXC1_OFFSET, | |
416 | + .m_or =XTE_RXC1_RXJMBO_MASK, | |
417 | + }, | |
418 | + /* Turn on VLAN packet support for both Rx and Tx */ | |
419 | + { | |
420 | + .opt = XTE_OPTION_VLAN, | |
421 | + .reg = XTE_TXC_OFFSET, | |
422 | + .m_or =XTE_TXC_TXVLAN_MASK, | |
423 | + }, | |
424 | + { | |
425 | + .opt = XTE_OPTION_VLAN, | |
426 | + .reg = XTE_RXC1_OFFSET, | |
427 | + .m_or =XTE_RXC1_RXVLAN_MASK, | |
428 | + }, | |
429 | + /* Turn on FCS stripping on receive packets */ | |
430 | + { | |
431 | + .opt = XTE_OPTION_FCS_STRIP, | |
432 | + .reg = XTE_RXC1_OFFSET, | |
433 | + .m_or =XTE_RXC1_RXFCS_MASK, | |
434 | + }, | |
435 | + /* Turn on FCS insertion on transmit packets */ | |
436 | + { | |
437 | + .opt = XTE_OPTION_FCS_INSERT, | |
438 | + .reg = XTE_TXC_OFFSET, | |
439 | + .m_or =XTE_TXC_TXFCS_MASK, | |
440 | + }, | |
441 | + /* Turn on length/type field checking on receive packets */ | |
442 | + { | |
443 | + .opt = XTE_OPTION_LENTYPE_ERR, | |
444 | + .reg = XTE_RXC1_OFFSET, | |
445 | + .m_or =XTE_RXC1_RXLT_MASK, | |
446 | + }, | |
447 | + /* Turn on flow control */ | |
448 | + { | |
449 | + .opt = XTE_OPTION_FLOW_CONTROL, | |
450 | + .reg = XTE_FCC_OFFSET, | |
451 | + .m_or =XTE_FCC_RXFLO_MASK, | |
452 | + }, | |
453 | + /* Turn on flow control */ | |
454 | + { | |
455 | + .opt = XTE_OPTION_FLOW_CONTROL, | |
456 | + .reg = XTE_FCC_OFFSET, | |
457 | + .m_or =XTE_FCC_TXFLO_MASK, | |
458 | + }, | |
459 | + /* Turn on promiscuous frame filtering (all frames are received ) */ | |
460 | + { | |
461 | + .opt = XTE_OPTION_PROMISC, | |
462 | + .reg = XTE_AFM_OFFSET, | |
463 | + .m_or =XTE_AFM_EPPRM_MASK, | |
464 | + }, | |
465 | + /* Enable transmitter if not already enabled */ | |
466 | + { | |
467 | + .opt = XTE_OPTION_TXEN, | |
468 | + .reg = XTE_TXC_OFFSET, | |
469 | + .m_or =XTE_TXC_TXEN_MASK, | |
470 | + }, | |
471 | + /* Enable receiver? */ | |
472 | + { | |
473 | + .opt = XTE_OPTION_RXEN, | |
474 | + .reg = XTE_RXC1_OFFSET, | |
475 | + .m_or =XTE_RXC1_RXEN_MASK, | |
476 | + }, | |
477 | + {} | |
478 | +}; | |
479 | + | |
480 | +/** | |
481 | + * temac_setoptions | |
482 | + */ | |
483 | +static u32 temac_setoptions(struct net_device *ndev, u32 options) | |
484 | +{ | |
485 | + struct temac_local *lp = netdev_priv(ndev); | |
486 | + struct temac_option *tp = &temac_options[0]; | |
487 | + int reg; | |
488 | + | |
489 | + mutex_lock(&lp->indirect_mutex); | |
490 | + while (tp->opt) { | |
491 | + reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or; | |
492 | + if (options & tp->opt) | |
493 | + reg |= tp->m_or; | |
494 | + temac_indirect_out32(lp, tp->reg, reg); | |
495 | + tp++; | |
496 | + } | |
497 | + lp->options |= options; | |
498 | + mutex_unlock(&lp->indirect_mutex); | |
499 | + | |
500 | + return 0; | |
501 | +} | |
502 | + | |
503 | +/* Initialize temac */ | |
504 | +static void temac_device_reset(struct net_device *ndev) | |
505 | +{ | |
506 | + struct temac_local *lp = netdev_priv(ndev); | |
507 | + u32 timeout; | |
508 | + u32 val; | |
509 | + | |
510 | + /* Perform a software reset */ | |
511 | + | |
512 | + /* 0x300 host enable bit ? */ | |
513 | + /* reset PHY through control register ?:1 */ | |
514 | + | |
515 | + dev_dbg(&ndev->dev, "%s()\n", __func__); | |
516 | + | |
517 | + mutex_lock(&lp->indirect_mutex); | |
518 | + /* Reset the receiver and wait for it to finish reset */ | |
519 | + temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK); | |
520 | + timeout = 1000; | |
521 | + while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) { | |
522 | + udelay(1); | |
523 | + if (--timeout == 0) { | |
524 | + dev_err(&ndev->dev, | |
525 | + "temac_device_reset RX reset timeout!!\n"); | |
526 | + break; | |
527 | + } | |
528 | + } | |
529 | + | |
530 | + /* Reset the transmitter and wait for it to finish reset */ | |
531 | + temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK); | |
532 | + timeout = 1000; | |
533 | + while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) { | |
534 | + udelay(1); | |
535 | + if (--timeout == 0) { | |
536 | + dev_err(&ndev->dev, | |
537 | + "temac_device_reset TX reset timeout!!\n"); | |
538 | + break; | |
539 | + } | |
540 | + } | |
541 | + | |
542 | + /* Disable the receiver */ | |
543 | + val = temac_indirect_in32(lp, XTE_RXC1_OFFSET); | |
544 | + temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); | |
545 | + | |
546 | + /* Reset Local Link (DMA) */ | |
547 | + lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); | |
548 | + timeout = 1000; | |
549 | + while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { | |
550 | + udelay(1); | |
551 | + if (--timeout == 0) { | |
552 | + dev_err(&ndev->dev, | |
553 | + "temac_device_reset DMA reset timeout!!\n"); | |
554 | + break; | |
555 | + } | |
556 | + } | |
557 | + lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); | |
558 | + | |
559 | + if (temac_dma_bd_init(ndev)) { | |
560 | + dev_err(&ndev->dev, | |
561 | + "temac_device_reset descriptor allocation failed\n"); | |
562 | + } | |
563 | + | |
564 | + temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0); | |
565 | + temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0); | |
566 | + temac_indirect_out32(lp, XTE_TXC_OFFSET, 0); | |
567 | + temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK); | |
568 | + | |
569 | + mutex_unlock(&lp->indirect_mutex); | |
570 | + | |
571 | + /* Sync default options with HW | |
572 | + * but leave receiver and transmitter disabled. */ | |
573 | + temac_setoptions(ndev, | |
574 | + lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN)); | |
575 | + | |
576 | + temac_set_mac_address(ndev, NULL); | |
577 | + | |
578 | + /* Set address filter table */ | |
579 | + temac_set_multicast_list(ndev); | |
580 | + if (temac_setoptions(ndev, lp->options)) | |
581 | + dev_err(&ndev->dev, "Error setting TEMAC options\n"); | |
582 | + | |
583 | + /* Init Driver variable */ | |
584 | + ndev->trans_start = jiffies; /* prevent tx timeout */ | |
585 | +} | |
586 | + | |
587 | +void temac_adjust_link(struct net_device *ndev) | |
588 | +{ | |
589 | + struct temac_local *lp = netdev_priv(ndev); | |
590 | + struct phy_device *phy = lp->phy_dev; | |
591 | + u32 mii_speed; | |
592 | + int link_state; | |
593 | + | |
594 | + /* hash together the state values to decide if something has changed */ | |
595 | + link_state = phy->speed | (phy->duplex << 1) | phy->link; | |
596 | + | |
597 | + mutex_lock(&lp->indirect_mutex); | |
598 | + if (lp->last_link != link_state) { | |
599 | + mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET); | |
600 | + mii_speed &= ~XTE_EMCFG_LINKSPD_MASK; | |
601 | + | |
602 | + switch (phy->speed) { | |
603 | + case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break; | |
604 | + case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break; | |
605 | + case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break; | |
606 | + } | |
607 | + | |
608 | + /* Write new speed setting out to TEMAC */ | |
609 | + temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed); | |
610 | + lp->last_link = link_state; | |
611 | + phy_print_status(phy); | |
612 | + } | |
613 | + mutex_unlock(&lp->indirect_mutex); | |
614 | +} | |
615 | + | |
616 | +static void temac_start_xmit_done(struct net_device *ndev) | |
617 | +{ | |
618 | + struct temac_local *lp = netdev_priv(ndev); | |
619 | + struct cdmac_bd *cur_p; | |
620 | + unsigned int stat = 0; | |
621 | + | |
622 | + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; | |
623 | + stat = cur_p->app0; | |
624 | + | |
625 | + while (stat & STS_CTRL_APP0_CMPLT) { | |
626 | + dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len, | |
627 | + DMA_TO_DEVICE); | |
628 | + if (cur_p->app4) | |
629 | + dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); | |
630 | + cur_p->app0 = 0; | |
631 | + cur_p->app1 = 0; | |
632 | + cur_p->app2 = 0; | |
633 | + cur_p->app3 = 0; | |
634 | + cur_p->app4 = 0; | |
635 | + | |
636 | + ndev->stats.tx_packets++; | |
637 | + ndev->stats.tx_bytes += cur_p->len; | |
638 | + | |
639 | + lp->tx_bd_ci++; | |
640 | + if (lp->tx_bd_ci >= TX_BD_NUM) | |
641 | + lp->tx_bd_ci = 0; | |
642 | + | |
643 | + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; | |
644 | + stat = cur_p->app0; | |
645 | + } | |
646 | + | |
647 | + netif_wake_queue(ndev); | |
648 | +} | |
649 | + | |
650 | +static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) | |
651 | +{ | |
652 | + struct cdmac_bd *cur_p; | |
653 | + int tail; | |
654 | + | |
655 | + tail = lp->tx_bd_tail; | |
656 | + cur_p = &lp->tx_bd_v[tail]; | |
657 | + | |
658 | + do { | |
659 | + if (cur_p->app0) | |
660 | + return NETDEV_TX_BUSY; | |
661 | + | |
662 | + tail++; | |
663 | + if (tail >= TX_BD_NUM) | |
664 | + tail = 0; | |
665 | + | |
666 | + cur_p = &lp->tx_bd_v[tail]; | |
667 | + num_frag--; | |
668 | + } while (num_frag >= 0); | |
669 | + | |
670 | + return 0; | |
671 | +} | |
672 | + | |
673 | +static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |
674 | +{ | |
675 | + struct temac_local *lp = netdev_priv(ndev); | |
676 | + struct cdmac_bd *cur_p; | |
677 | + dma_addr_t start_p, tail_p; | |
678 | + int ii; | |
679 | + unsigned long num_frag; | |
680 | + skb_frag_t *frag; | |
681 | + | |
682 | + num_frag = skb_shinfo(skb)->nr_frags; | |
683 | + frag = &skb_shinfo(skb)->frags[0]; | |
684 | + start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | |
685 | + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | |
686 | + | |
687 | + if (temac_check_tx_bd_space(lp, num_frag)) { | |
688 | + if (!netif_queue_stopped(ndev)) { | |
689 | + netif_stop_queue(ndev); | |
690 | + return NETDEV_TX_BUSY; | |
691 | + } | |
692 | + return NETDEV_TX_BUSY; | |
693 | + } | |
694 | + | |
695 | + cur_p->app0 = 0; | |
696 | + if (skb->ip_summed == CHECKSUM_PARTIAL) { | |
697 | + unsigned int csum_start_off = skb_checksum_start_offset(skb); | |
698 | + unsigned int csum_index_off = csum_start_off + skb->csum_offset; | |
699 | + | |
700 | + cur_p->app0 |= 1; /* TX Checksum Enabled */ | |
701 | + cur_p->app1 = (csum_start_off << 16) | csum_index_off; | |
702 | + cur_p->app2 = 0; /* initial checksum seed */ | |
703 | + } | |
704 | + | |
705 | + cur_p->app0 |= STS_CTRL_APP0_SOP; | |
706 | + cur_p->len = skb_headlen(skb); | |
707 | + cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, | |
708 | + DMA_TO_DEVICE); | |
709 | + cur_p->app4 = (unsigned long)skb; | |
710 | + | |
711 | + for (ii = 0; ii < num_frag; ii++) { | |
712 | + lp->tx_bd_tail++; | |
713 | + if (lp->tx_bd_tail >= TX_BD_NUM) | |
714 | + lp->tx_bd_tail = 0; | |
715 | + | |
716 | + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | |
717 | + cur_p->phys = dma_map_single(ndev->dev.parent, | |
718 | + (void *)page_address(frag->page) + | |
719 | + frag->page_offset, | |
720 | + frag->size, DMA_TO_DEVICE); | |
721 | + cur_p->len = frag->size; | |
722 | + cur_p->app0 = 0; | |
723 | + frag++; | |
724 | + } | |
725 | + cur_p->app0 |= STS_CTRL_APP0_EOP; | |
726 | + | |
727 | + tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | |
728 | + lp->tx_bd_tail++; | |
729 | + if (lp->tx_bd_tail >= TX_BD_NUM) | |
730 | + lp->tx_bd_tail = 0; | |
731 | + | |
732 | + skb_tx_timestamp(skb); | |
733 | + | |
734 | + /* Kick off the transfer */ | |
735 | + lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ | |
736 | + | |
737 | + return NETDEV_TX_OK; | |
738 | +} | |
739 | + | |
740 | + | |
741 | +static void ll_temac_recv(struct net_device *ndev) | |
742 | +{ | |
743 | + struct temac_local *lp = netdev_priv(ndev); | |
744 | + struct sk_buff *skb, *new_skb; | |
745 | + unsigned int bdstat; | |
746 | + struct cdmac_bd *cur_p; | |
747 | + dma_addr_t tail_p; | |
748 | + int length; | |
749 | + unsigned long flags; | |
750 | + | |
751 | + spin_lock_irqsave(&lp->rx_lock, flags); | |
752 | + | |
753 | + tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; | |
754 | + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | |
755 | + | |
756 | + bdstat = cur_p->app0; | |
757 | + while ((bdstat & STS_CTRL_APP0_CMPLT)) { | |
758 | + | |
759 | + skb = lp->rx_skb[lp->rx_bd_ci]; | |
760 | + length = cur_p->app4 & 0x3FFF; | |
761 | + | |
762 | + dma_unmap_single(ndev->dev.parent, cur_p->phys, length, | |
763 | + DMA_FROM_DEVICE); | |
764 | + | |
765 | + skb_put(skb, length); | |
766 | + skb->dev = ndev; | |
767 | + skb->protocol = eth_type_trans(skb, ndev); | |
768 | + skb_checksum_none_assert(skb); | |
769 | + | |
770 | + /* if we're doing rx csum offload, set it up */ | |
771 | + if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && | |
772 | + (skb->protocol == __constant_htons(ETH_P_IP)) && | |
773 | + (skb->len > 64)) { | |
774 | + | |
775 | + skb->csum = cur_p->app3 & 0xFFFF; | |
776 | + skb->ip_summed = CHECKSUM_COMPLETE; | |
777 | + } | |
778 | + | |
779 | + if (!skb_defer_rx_timestamp(skb)) | |
780 | + netif_rx(skb); | |
781 | + | |
782 | + ndev->stats.rx_packets++; | |
783 | + ndev->stats.rx_bytes += length; | |
784 | + | |
785 | + new_skb = netdev_alloc_skb_ip_align(ndev, | |
786 | + XTE_MAX_JUMBO_FRAME_SIZE); | |
787 | + | |
788 | + if (new_skb == 0) { | |
789 | + dev_err(&ndev->dev, "no memory for new sk_buff\n"); | |
790 | + spin_unlock_irqrestore(&lp->rx_lock, flags); | |
791 | + return; | |
792 | + } | |
793 | + | |
794 | + cur_p->app0 = STS_CTRL_APP0_IRQONEND; | |
795 | + cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, | |
796 | + XTE_MAX_JUMBO_FRAME_SIZE, | |
797 | + DMA_FROM_DEVICE); | |
798 | + cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE; | |
799 | + lp->rx_skb[lp->rx_bd_ci] = new_skb; | |
800 | + | |
801 | + lp->rx_bd_ci++; | |
802 | + if (lp->rx_bd_ci >= RX_BD_NUM) | |
803 | + lp->rx_bd_ci = 0; | |
804 | + | |
805 | + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | |
806 | + bdstat = cur_p->app0; | |
807 | + } | |
808 | + lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); | |
809 | + | |
810 | + spin_unlock_irqrestore(&lp->rx_lock, flags); | |
811 | +} | |
812 | + | |
813 | +static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) | |
814 | +{ | |
815 | + struct net_device *ndev = _ndev; | |
816 | + struct temac_local *lp = netdev_priv(ndev); | |
817 | + unsigned int status; | |
818 | + | |
819 | + status = lp->dma_in(lp, TX_IRQ_REG); | |
820 | + lp->dma_out(lp, TX_IRQ_REG, status); | |
821 | + | |
822 | + if (status & (IRQ_COAL | IRQ_DLY)) | |
823 | + temac_start_xmit_done(lp->ndev); | |
824 | + if (status & 0x080) | |
825 | + dev_err(&ndev->dev, "DMA error 0x%x\n", status); | |
826 | + | |
827 | + return IRQ_HANDLED; | |
828 | +} | |
829 | + | |
830 | +static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev) | |
831 | +{ | |
832 | + struct net_device *ndev = _ndev; | |
833 | + struct temac_local *lp = netdev_priv(ndev); | |
834 | + unsigned int status; | |
835 | + | |
836 | + /* Read and clear the status registers */ | |
837 | + status = lp->dma_in(lp, RX_IRQ_REG); | |
838 | + lp->dma_out(lp, RX_IRQ_REG, status); | |
839 | + | |
840 | + if (status & (IRQ_COAL | IRQ_DLY)) | |
841 | + ll_temac_recv(lp->ndev); | |
842 | + | |
843 | + return IRQ_HANDLED; | |
844 | +} | |
845 | + | |
846 | +static int temac_open(struct net_device *ndev) | |
847 | +{ | |
848 | + struct temac_local *lp = netdev_priv(ndev); | |
849 | + int rc; | |
850 | + | |
851 | + dev_dbg(&ndev->dev, "temac_open()\n"); | |
852 | + | |
853 | + if (lp->phy_node) { | |
854 | + lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, | |
855 | + temac_adjust_link, 0, 0); | |
856 | + if (!lp->phy_dev) { | |
857 | + dev_err(lp->dev, "of_phy_connect() failed\n"); | |
858 | + return -ENODEV; | |
859 | + } | |
860 | + | |
861 | + phy_start(lp->phy_dev); | |
862 | + } | |
863 | + | |
864 | + rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev); | |
865 | + if (rc) | |
866 | + goto err_tx_irq; | |
867 | + rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev); | |
868 | + if (rc) | |
869 | + goto err_rx_irq; | |
870 | + | |
871 | + temac_device_reset(ndev); | |
872 | + return 0; | |
873 | + | |
874 | + err_rx_irq: | |
875 | + free_irq(lp->tx_irq, ndev); | |
876 | + err_tx_irq: | |
877 | + if (lp->phy_dev) | |
878 | + phy_disconnect(lp->phy_dev); | |
879 | + lp->phy_dev = NULL; | |
880 | + dev_err(lp->dev, "request_irq() failed\n"); | |
881 | + return rc; | |
882 | +} | |
883 | + | |
884 | +static int temac_stop(struct net_device *ndev) | |
885 | +{ | |
886 | + struct temac_local *lp = netdev_priv(ndev); | |
887 | + | |
888 | + dev_dbg(&ndev->dev, "temac_close()\n"); | |
889 | + | |
890 | + free_irq(lp->tx_irq, ndev); | |
891 | + free_irq(lp->rx_irq, ndev); | |
892 | + | |
893 | + if (lp->phy_dev) | |
894 | + phy_disconnect(lp->phy_dev); | |
895 | + lp->phy_dev = NULL; | |
896 | + | |
897 | + temac_dma_bd_release(ndev); | |
898 | + | |
899 | + return 0; | |
900 | +} | |
901 | + | |
902 | +#ifdef CONFIG_NET_POLL_CONTROLLER | |
903 | +static void | |
904 | +temac_poll_controller(struct net_device *ndev) | |
905 | +{ | |
906 | + struct temac_local *lp = netdev_priv(ndev); | |
907 | + | |
908 | + disable_irq(lp->tx_irq); | |
909 | + disable_irq(lp->rx_irq); | |
910 | + | |
911 | + ll_temac_rx_irq(lp->tx_irq, ndev); | |
912 | + ll_temac_tx_irq(lp->rx_irq, ndev); | |
913 | + | |
914 | + enable_irq(lp->tx_irq); | |
915 | + enable_irq(lp->rx_irq); | |
916 | +} | |
917 | +#endif | |
918 | + | |
919 | +static const struct net_device_ops temac_netdev_ops = { | |
920 | + .ndo_open = temac_open, | |
921 | + .ndo_stop = temac_stop, | |
922 | + .ndo_start_xmit = temac_start_xmit, | |
923 | + .ndo_set_mac_address = netdev_set_mac_address, | |
924 | + .ndo_validate_addr = eth_validate_addr, | |
925 | + //.ndo_set_multicast_list = temac_set_multicast_list, | |
926 | +#ifdef CONFIG_NET_POLL_CONTROLLER | |
927 | + .ndo_poll_controller = temac_poll_controller, | |
928 | +#endif | |
929 | +}; | |
930 | + | |
931 | +/* --------------------------------------------------------------------- | |
932 | + * SYSFS device attributes | |
933 | + */ | |
934 | +static ssize_t temac_show_llink_regs(struct device *dev, | |
935 | + struct device_attribute *attr, char *buf) | |
936 | +{ | |
937 | + struct net_device *ndev = dev_get_drvdata(dev); | |
938 | + struct temac_local *lp = netdev_priv(ndev); | |
939 | + int i, len = 0; | |
940 | + | |
941 | + for (i = 0; i < 0x11; i++) | |
942 | + len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i), | |
943 | + (i % 8) == 7 ? "\n" : " "); | |
944 | + len += sprintf(buf + len, "\n"); | |
945 | + | |
946 | + return len; | |
947 | +} | |
948 | + | |
949 | +static DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL); | |
950 | + | |
951 | +static struct attribute *temac_device_attrs[] = { | |
952 | + &dev_attr_llink_regs.attr, | |
953 | + NULL, | |
954 | +}; | |
955 | + | |
956 | +static const struct attribute_group temac_attr_group = { | |
957 | + .attrs = temac_device_attrs, | |
958 | +}; | |
959 | + | |
960 | +static int __devinit temac_of_probe(struct platform_device *op) | |
961 | +{ | |
962 | + struct device_node *np; | |
963 | + struct temac_local *lp; | |
964 | + struct net_device *ndev; | |
965 | + const void *addr; | |
966 | + __be32 *p; | |
967 | + int size, rc = 0; | |
968 | + | |
969 | + /* Init network device structure */ | |
970 | + ndev = alloc_etherdev(sizeof(*lp)); | |
971 | + if (!ndev) { | |
972 | + dev_err(&op->dev, "could not allocate device.\n"); | |
973 | + return -ENOMEM; | |
974 | + } | |
975 | + ether_setup(ndev); | |
976 | + dev_set_drvdata(&op->dev, ndev); | |
977 | + SET_NETDEV_DEV(ndev, &op->dev); | |
978 | + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ | |
979 | + ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; | |
980 | + ndev->netdev_ops = &temac_netdev_ops; | |
981 | +#if 0 | |
982 | + ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */ | |
983 | + ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */ | |
984 | + ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */ | |
985 | + ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */ | |
986 | + ndev->features |= NETIF_F_HW_VLAN_TX; /* Transmit VLAN hw accel */ | |
987 | + ndev->features |= NETIF_F_HW_VLAN_RX; /* Receive VLAN hw acceleration */ | |
988 | + ndev->features |= NETIF_F_HW_VLAN_FILTER; /* Receive VLAN filtering */ | |
989 | + ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */ | |
990 | + ndev->features |= NETIF_F_GSO; /* Enable software GSO. */ | |
991 | + ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */ | |
992 | + ndev->features |= NETIF_F_LRO; /* large receive offload */ | |
993 | +#endif | |
994 | + | |
995 | + /* setup temac private info structure */ | |
996 | + lp = netdev_priv(ndev); | |
997 | + lp->ndev = ndev; | |
998 | + lp->dev = &op->dev; | |
999 | + lp->options = XTE_OPTION_DEFAULTS; | |
1000 | + spin_lock_init(&lp->rx_lock); | |
1001 | + mutex_init(&lp->indirect_mutex); | |
1002 | + | |
1003 | + /* map device registers */ | |
1004 | + lp->regs = of_iomap(op->dev.of_node, 0); | |
1005 | + if (!lp->regs) { | |
1006 | + dev_err(&op->dev, "could not map temac regs.\n"); | |
1007 | + goto nodev; | |
1008 | + } | |
1009 | + | |
1010 | + /* Setup checksum offload, but default to off if not specified */ | |
1011 | + lp->temac_features = 0; | |
1012 | + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); | |
1013 | + if (p && be32_to_cpu(*p)) { | |
1014 | + lp->temac_features |= TEMAC_FEATURE_TX_CSUM; | |
1015 | + /* Can checksum TCP/UDP over IPv4. */ | |
1016 | + ndev->features |= NETIF_F_IP_CSUM; | |
1017 | + } | |
1018 | + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); | |
1019 | + if (p && be32_to_cpu(*p)) | |
1020 | + lp->temac_features |= TEMAC_FEATURE_RX_CSUM; | |
1021 | + | |
1022 | + /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ | |
1023 | + np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); | |
1024 | + if (!np) { | |
1025 | + dev_err(&op->dev, "could not find DMA node\n"); | |
1026 | + goto err_iounmap; | |
1027 | + } | |
1028 | + | |
1029 | + /* Setup the DMA register accesses, could be DCR or memory mapped */ | |
1030 | + if (temac_dcr_setup(lp, op, np)) { | |
1031 | + | |
1032 | + /* no DCR in the device tree, try non-DCR */ | |
1033 | + lp->sdma_regs = of_iomap(np, 0); | |
1034 | + if (lp->sdma_regs) { | |
1035 | + lp->dma_in = temac_dma_in32; | |
1036 | + lp->dma_out = temac_dma_out32; | |
1037 | + dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs); | |
1038 | + } else { | |
1039 | + dev_err(&op->dev, "unable to map DMA registers\n"); | |
1040 | + of_node_put(np); | |
1041 | + goto err_iounmap; | |
1042 | + } | |
1043 | + } | |
1044 | + | |
1045 | + lp->rx_irq = irq_of_parse_and_map(np, 0); | |
1046 | + lp->tx_irq = irq_of_parse_and_map(np, 1); | |
1047 | + | |
1048 | + of_node_put(np); /* Finished with the DMA node; drop the reference */ | |
1049 | + | |
1050 | + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { | |
1051 | + dev_err(&op->dev, "could not determine irqs\n"); | |
1052 | + rc = -ENOMEM; | |
1053 | + goto err_iounmap_2; | |
1054 | + } | |
1055 | + | |
1056 | + | |
1057 | + /* Retrieve the MAC address */ | |
1058 | + addr = of_get_property(op->dev.of_node, "local-mac-address", &size); | |
1059 | + if ((!addr) || (size != 6)) { | |
1060 | + dev_err(&op->dev, "could not find MAC address\n"); | |
1061 | + rc = -ENODEV; | |
1062 | + goto err_iounmap_2; | |
1063 | + } | |
1064 | + temac_set_mac_address(ndev, (void *)addr); | |
1065 | + | |
1066 | + rc = temac_mdio_setup(lp, op->dev.of_node); | |
1067 | + if (rc) | |
1068 | + dev_warn(&op->dev, "error registering MDIO bus\n"); | |
1069 | + | |
1070 | + lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); | |
1071 | + if (lp->phy_node) | |
1072 | + dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np); | |
1073 | + | |
1074 | + /* Add the device attributes */ | |
1075 | + rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group); | |
1076 | + if (rc) { | |
1077 | + dev_err(lp->dev, "Error creating sysfs files\n"); | |
1078 | + goto err_iounmap_2; | |
1079 | + } | |
1080 | + | |
1081 | + rc = register_netdev(lp->ndev); | |
1082 | + if (rc) { | |
1083 | + dev_err(lp->dev, "register_netdev() error (%i)\n", rc); | |
1084 | + goto err_register_ndev; | |
1085 | + } | |
1086 | + | |
1087 | + return 0; | |
1088 | + | |
1089 | + err_register_ndev: | |
1090 | + sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); | |
1091 | + err_iounmap_2: | |
1092 | + if (lp->sdma_regs) | |
1093 | + iounmap(lp->sdma_regs); | |
1094 | + err_iounmap: | |
1095 | + iounmap(lp->regs); | |
1096 | + nodev: | |
1097 | + free_netdev(ndev); | |
1098 | + ndev = NULL; | |
1099 | + return rc; | |
1100 | +} | |
1101 | + | |
1102 | +static int __devexit temac_of_remove(struct platform_device *op) | |
1103 | +{ | |
1104 | + struct net_device *ndev = dev_get_drvdata(&op->dev); | |
1105 | + struct temac_local *lp = netdev_priv(ndev); | |
1106 | + | |
1107 | + temac_mdio_teardown(lp); | |
1108 | + unregister_netdev(ndev); | |
1109 | + sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); | |
1110 | + if (lp->phy_node) | |
1111 | + of_node_put(lp->phy_node); | |
1112 | + lp->phy_node = NULL; | |
1113 | + dev_set_drvdata(&op->dev, NULL); | |
1114 | + iounmap(lp->regs); | |
1115 | + if (lp->sdma_regs) | |
1116 | + iounmap(lp->sdma_regs); | |
1117 | + free_netdev(ndev); | |
1118 | + return 0; | |
1119 | +} | |
1120 | + | |
1121 | +static struct of_device_id temac_of_match[] __devinitdata = { | |
1122 | + { .compatible = "xlnx,xps-ll-temac-1.01.b", }, | |
1123 | + { .compatible = "xlnx,xps-ll-temac-2.00.a", }, | |
1124 | + { .compatible = "xlnx,xps-ll-temac-2.02.a", }, | |
1125 | + { .compatible = "xlnx,xps-ll-temac-2.03.a", }, | |
1126 | + {}, | |
1127 | +}; | |
1128 | +MODULE_DEVICE_TABLE(of, temac_of_match); | |
1129 | + | |
1130 | +static struct platform_driver temac_of_driver = { | |
1131 | + .probe = temac_of_probe, | |
1132 | + .remove = __devexit_p(temac_of_remove), | |
1133 | + .driver = { | |
1134 | + .owner = THIS_MODULE, | |
1135 | + .name = "xilinx_temac", | |
1136 | + .of_match_table = temac_of_match, | |
1137 | + }, | |
1138 | +}; | |
1139 | + | |
1140 | +static int __init temac_init(void) | |
1141 | +{ | |
1142 | + return platform_driver_register(&temac_of_driver); | |
1143 | +} | |
1144 | +module_init(temac_init); | |
1145 | + | |
1146 | +static void __exit temac_exit(void) | |
1147 | +{ | |
1148 | + platform_driver_unregister(&temac_of_driver); | |
1149 | +} | |
1150 | +module_exit(temac_exit); | |
1151 | + | |
1152 | +MODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver"); | |
1153 | +MODULE_AUTHOR("Yoshio Kashiwagi"); | |
1154 | +MODULE_LICENSE("GPL"); |
drivers/net/ethernet/xilinx/ll_temac_mdio.c
1 | +/* | |
2 | + * MDIO bus driver for the Xilinx TEMAC device | |
3 | + * | |
4 | + * Copyright (c) 2009 Secret Lab Technologies, Ltd. | |
5 | + */ | |
6 | + | |
7 | +#include <linux/io.h> | |
8 | +#include <linux/netdevice.h> | |
9 | +#include <linux/mutex.h> | |
10 | +#include <linux/phy.h> | |
11 | +#include <linux/of.h> | |
12 | +#include <linux/of_device.h> | |
13 | +#include <linux/of_address.h> | |
14 | +#include <linux/slab.h> | |
15 | +#include <linux/of_mdio.h> | |
16 | + | |
17 | +#include "ll_temac.h" | |
18 | + | |
19 | +/* --------------------------------------------------------------------- | |
20 | + * MDIO Bus functions | |
21 | + */ | |
22 | +static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg) | |
23 | +{ | |
24 | + struct temac_local *lp = bus->priv; | |
25 | + u32 rc; | |
26 | + | |
27 | + /* Write the PHY address to the MIIM Access Initiator register. | |
28 | + * When the transfer completes, the PHY register value will appear | |
29 | + * in the LSW0 register */ | |
30 | + mutex_lock(&lp->indirect_mutex); | |
31 | + temac_iow(lp, XTE_LSW0_OFFSET, (phy_id << 5) | reg); | |
32 | + rc = temac_indirect_in32(lp, XTE_MIIMAI_OFFSET); | |
33 | + mutex_unlock(&lp->indirect_mutex); | |
34 | + | |
35 | + dev_dbg(lp->dev, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n", | |
36 | + phy_id, reg, rc); | |
37 | + | |
38 | + return rc; | |
39 | +} | |
40 | + | |
41 | +static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val) | |
42 | +{ | |
43 | + struct temac_local *lp = bus->priv; | |
44 | + | |
45 | + dev_dbg(lp->dev, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n", | |
46 | + phy_id, reg, val); | |
47 | + | |
48 | + /* First write the desired value into the write data register | |
49 | + * and then write the address into the access initiator register | |
50 | + */ | |
51 | + mutex_lock(&lp->indirect_mutex); | |
52 | + temac_indirect_out32(lp, XTE_MGTDR_OFFSET, val); | |
53 | + temac_indirect_out32(lp, XTE_MIIMAI_OFFSET, (phy_id << 5) | reg); | |
54 | + mutex_unlock(&lp->indirect_mutex); | |
55 | + | |
56 | + return 0; | |
57 | +} | |
58 | + | |
59 | +int temac_mdio_setup(struct temac_local *lp, struct device_node *np) | |
60 | +{ | |
61 | + struct mii_bus *bus; | |
62 | + const u32 *bus_hz; | |
63 | + int clk_div; | |
64 | + int rc, size; | |
65 | + struct resource res; | |
66 | + | |
67 | + /* Calculate a reasonable divisor for the clock rate */ | |
68 | + clk_div = 0x3f; /* worst-case default setting */ | |
69 | + bus_hz = of_get_property(np, "clock-frequency", &size); | |
70 | + if (bus_hz && size >= sizeof(*bus_hz)) { | |
71 | + clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1; | |
72 | + if (clk_div < 1) | |
73 | + clk_div = 1; | |
74 | + if (clk_div > 0x3f) | |
75 | + clk_div = 0x3f; | |
76 | + } | |
77 | + | |
78 | + /* Enable the MDIO bus by asserting the enable bit and writing | |
79 | + * in the clock config */ | |
80 | + mutex_lock(&lp->indirect_mutex); | |
81 | + temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div); | |
82 | + mutex_unlock(&lp->indirect_mutex); | |
83 | + | |
84 | + bus = mdiobus_alloc(); | |
85 | + if (!bus) | |
86 | + return -ENOMEM; | |
87 | + | |
88 | + of_address_to_resource(np, 0, &res); | |
89 | + snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", | |
90 | + (unsigned long long)res.start); | |
91 | + bus->priv = lp; | |
92 | + bus->name = "Xilinx TEMAC MDIO"; | |
93 | + bus->read = temac_mdio_read; | |
94 | + bus->write = temac_mdio_write; | |
95 | + bus->parent = lp->dev; | |
96 | + bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ | |
97 | + | |
98 | + lp->mii_bus = bus; | |
99 | + | |
100 | + rc = of_mdiobus_register(bus, np); | |
101 | + if (rc) | |
102 | + goto err_register; | |
103 | + | |
104 | + mutex_lock(&lp->indirect_mutex); | |
105 | + dev_dbg(lp->dev, "MDIO bus registered; MC:%x\n", | |
106 | + temac_indirect_in32(lp, XTE_MC_OFFSET)); | |
107 | + mutex_unlock(&lp->indirect_mutex); | |
108 | + return 0; | |
109 | + | |
110 | + err_register: | |
111 | + mdiobus_free(bus); | |
112 | + return rc; | |
113 | +} | |
114 | + | |
115 | +void temac_mdio_teardown(struct temac_local *lp) | |
116 | +{ | |
117 | + mdiobus_unregister(lp->mii_bus); | |
118 | + kfree(lp->mii_bus->irq); | |
119 | + mdiobus_free(lp->mii_bus); | |
120 | + lp->mii_bus = NULL; | |
121 | +} |
drivers/net/ethernet/xilinx/xilinx_emaclite.c
Changes suppressed. Click to show
1 | +/* | |
2 | + * Xilinx EmacLite Linux driver for the Xilinx Ethernet MAC Lite device. | |
3 | + * | |
4 | + * This is a new flat driver which is based on the original emac_lite | |
5 | + * driver from John Williams <john.williams@petalogix.com>. | |
6 | + * | |
7 | + * 2007-2009 (c) Xilinx, Inc. | |
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 as published by the | |
11 | + * Free Software Foundation; either version 2 of the License, or (at your | |
12 | + * option) any later version. | |
13 | + */ | |
14 | + | |
15 | +#include <linux/module.h> | |
16 | +#include <linux/uaccess.h> | |
17 | +#include <linux/init.h> | |
18 | +#include <linux/netdevice.h> | |
19 | +#include <linux/etherdevice.h> | |
20 | +#include <linux/skbuff.h> | |
21 | +#include <linux/io.h> | |
22 | +#include <linux/slab.h> | |
23 | +#include <linux/of_address.h> | |
24 | +#include <linux/of_device.h> | |
25 | +#include <linux/of_platform.h> | |
26 | +#include <linux/of_mdio.h> | |
27 | +#include <linux/of_net.h> | |
28 | +#include <linux/phy.h> | |
29 | +#include <linux/interrupt.h> | |
30 | + | |
31 | +#define DRIVER_NAME "xilinx_emaclite" | |
32 | + | |
33 | +/* Register offsets for the EmacLite Core */ | |
34 | +#define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ | |
35 | +#define XEL_MDIOADDR_OFFSET 0x07E4 /* MDIO Address Register */ | |
36 | +#define XEL_MDIOWR_OFFSET 0x07E8 /* MDIO Write Data Register */ | |
37 | +#define XEL_MDIORD_OFFSET 0x07EC /* MDIO Read Data Register */ | |
38 | +#define XEL_MDIOCTRL_OFFSET 0x07F0 /* MDIO Control Register */ | |
39 | +#define XEL_GIER_OFFSET 0x07F8 /* GIE Register */ | |
40 | +#define XEL_TSR_OFFSET 0x07FC /* Tx status */ | |
41 | +#define XEL_TPLR_OFFSET 0x07F4 /* Tx packet length */ | |
42 | + | |
43 | +#define XEL_RXBUFF_OFFSET 0x1000 /* Receive Buffer */ | |
44 | +#define XEL_RPLR_OFFSET 0x100C /* Rx packet length */ | |
45 | +#define XEL_RSR_OFFSET 0x17FC /* Rx status */ | |
46 | + | |
47 | +#define XEL_BUFFER_OFFSET 0x0800 /* Next Tx/Rx buffer's offset */ | |
48 | + | |
49 | +/* MDIO Address Register Bit Masks */ | |
50 | +#define XEL_MDIOADDR_REGADR_MASK 0x0000001F /* Register Address */ | |
51 | +#define XEL_MDIOADDR_PHYADR_MASK 0x000003E0 /* PHY Address */ | |
52 | +#define XEL_MDIOADDR_PHYADR_SHIFT 5 | |
53 | +#define XEL_MDIOADDR_OP_MASK 0x00000400 /* RD/WR Operation */ | |
54 | + | |
55 | +/* MDIO Write Data Register Bit Masks */ | |
56 | +#define XEL_MDIOWR_WRDATA_MASK 0x0000FFFF /* Data to be Written */ | |
57 | + | |
58 | +/* MDIO Read Data Register Bit Masks */ | |
59 | +#define XEL_MDIORD_RDDATA_MASK 0x0000FFFF /* Data to be Read */ | |
60 | + | |
61 | +/* MDIO Control Register Bit Masks */ | |
62 | +#define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001 /* MDIO Status Mask */ | |
63 | +#define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */ | |
64 | + | |
65 | +/* Global Interrupt Enable Register (GIER) Bit Masks */ | |
66 | +#define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ | |
67 | + | |
68 | +/* Transmit Status Register (TSR) Bit Masks */ | |
69 | +#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /* Tx complete */ | |
70 | +#define XEL_TSR_PROGRAM_MASK 0x00000002 /* Program the MAC address */ | |
71 | +#define XEL_TSR_XMIT_IE_MASK 0x00000008 /* Tx interrupt enable bit */ | |
72 | +#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /* Buffer is active, SW bit | |
73 | + * only. This is not documented | |
74 | + * in the HW spec */ | |
75 | + | |
76 | +/* Define for programming the MAC address into the EmacLite */ | |
77 | +#define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK) | |
78 | + | |
79 | +/* Receive Status Register (RSR) */ | |
80 | +#define XEL_RSR_RECV_DONE_MASK 0x00000001 /* Rx complete */ | |
81 | +#define XEL_RSR_RECV_IE_MASK 0x00000008 /* Rx interrupt enable bit */ | |
82 | + | |
83 | +/* Transmit Packet Length Register (TPLR) */ | |
84 | +#define XEL_TPLR_LENGTH_MASK 0x0000FFFF /* Tx packet length */ | |
85 | + | |
86 | +/* Receive Packet Length Register (RPLR) */ | |
87 | +#define XEL_RPLR_LENGTH_MASK 0x0000FFFF /* Rx packet length */ | |
88 | + | |
89 | +#define XEL_HEADER_OFFSET 12 /* Offset to length field */ | |
90 | +#define XEL_HEADER_SHIFT 16 /* Shift value for length */ | |
91 | + | |
92 | +/* General Ethernet Definitions */ | |
93 | +#define XEL_ARP_PACKET_SIZE 28 /* Max ARP packet size */ | |
94 | +#define XEL_HEADER_IP_LENGTH_OFFSET 16 /* IP Length Offset */ | |
95 | + | |
96 | + | |
97 | + | |
98 | +#define TX_TIMEOUT (60*HZ) /* Tx timeout is 60 seconds. */ | |
99 | +#define ALIGNMENT 4 | |
100 | + | |
101 | +/* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */ | |
102 | +#define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT) | |
103 | + | |
104 | +/** | |
105 | + * struct net_local - Our private per device data | |
106 | + * @ndev: instance of the network device | |
107 | + * @tx_ping_pong: indicates whether Tx Pong buffer is configured in HW | |
108 | + * @rx_ping_pong: indicates whether Rx Pong buffer is configured in HW | |
109 | + * @next_tx_buf_to_use: next Tx buffer to write to | |
110 | + * @next_rx_buf_to_use: next Rx buffer to read from | |
111 | + * @base_addr: base address of the Emaclite device | |
112 | + * @reset_lock: lock used for synchronization | |
113 | + * @deferred_skb: holds an skb (for transmission at a later time) when the | |
114 | + * Tx buffer is not free | |
115 | + * @phy_dev: pointer to the PHY device | |
116 | + * @phy_node: pointer to the PHY device node | |
117 | + * @mii_bus: pointer to the MII bus | |
118 | + * @mdio_irqs: IRQs table for MDIO bus | |
119 | + * @last_link: last link status | |
120 | + * @has_mdio: indicates whether MDIO is included in the HW | |
121 | + */ | |
122 | +struct net_local { | |
123 | + | |
124 | + struct net_device *ndev; | |
125 | + | |
126 | + bool tx_ping_pong; | |
127 | + bool rx_ping_pong; | |
128 | + u32 next_tx_buf_to_use; | |
129 | + u32 next_rx_buf_to_use; | |
130 | + void __iomem *base_addr; | |
131 | + | |
132 | + spinlock_t reset_lock; | |
133 | + struct sk_buff *deferred_skb; | |
134 | + | |
135 | + struct phy_device *phy_dev; | |
136 | + struct device_node *phy_node; | |
137 | + | |
138 | + struct mii_bus *mii_bus; | |
139 | + int mdio_irqs[PHY_MAX_ADDR]; | |
140 | + | |
141 | + int last_link; | |
142 | + bool has_mdio; | |
143 | +}; | |
144 | + | |
145 | + | |
146 | +/*************************/ | |
147 | +/* EmacLite driver calls */ | |
148 | +/*************************/ | |
149 | + | |
150 | +/** | |
151 | + * xemaclite_enable_interrupts - Enable the interrupts for the EmacLite device | |
152 | + * @drvdata: Pointer to the Emaclite device private data | |
153 | + * | |
154 | + * This function enables the Tx and Rx interrupts for the Emaclite device along | |
155 | + * with the Global Interrupt Enable. | |
156 | + */ | |
157 | +static void xemaclite_enable_interrupts(struct net_local *drvdata) | |
158 | +{ | |
159 | + u32 reg_data; | |
160 | + | |
161 | + /* Enable the Tx interrupts for the first Buffer */ | |
162 | + reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET); | |
163 | + out_be32(drvdata->base_addr + XEL_TSR_OFFSET, | |
164 | + reg_data | XEL_TSR_XMIT_IE_MASK); | |
165 | + | |
166 | + /* Enable the Tx interrupts for the second Buffer if | |
167 | + * configured in HW */ | |
168 | + if (drvdata->tx_ping_pong != 0) { | |
169 | + reg_data = in_be32(drvdata->base_addr + | |
170 | + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); | |
171 | + out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
172 | + XEL_TSR_OFFSET, | |
173 | + reg_data | XEL_TSR_XMIT_IE_MASK); | |
174 | + } | |
175 | + | |
176 | + /* Enable the Rx interrupts for the first buffer */ | |
177 | + out_be32(drvdata->base_addr + XEL_RSR_OFFSET, | |
178 | + XEL_RSR_RECV_IE_MASK); | |
179 | + | |
180 | + /* Enable the Rx interrupts for the second Buffer if | |
181 | + * configured in HW */ | |
182 | + if (drvdata->rx_ping_pong != 0) { | |
183 | + out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
184 | + XEL_RSR_OFFSET, | |
185 | + XEL_RSR_RECV_IE_MASK); | |
186 | + } | |
187 | + | |
188 | + /* Enable the Global Interrupt Enable */ | |
189 | + out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK); | |
190 | +} | |
191 | + | |
192 | +/** | |
193 | + * xemaclite_disable_interrupts - Disable the interrupts for the EmacLite device | |
194 | + * @drvdata: Pointer to the Emaclite device private data | |
195 | + * | |
196 | + * This function disables the Tx and Rx interrupts for the Emaclite device, | |
197 | + * along with the Global Interrupt Enable. | |
198 | + */ | |
199 | +static void xemaclite_disable_interrupts(struct net_local *drvdata) | |
200 | +{ | |
201 | + u32 reg_data; | |
202 | + | |
203 | + /* Disable the Global Interrupt Enable */ | |
204 | + out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK); | |
205 | + | |
206 | + /* Disable the Tx interrupts for the first buffer */ | |
207 | + reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET); | |
208 | + out_be32(drvdata->base_addr + XEL_TSR_OFFSET, | |
209 | + reg_data & (~XEL_TSR_XMIT_IE_MASK)); | |
210 | + | |
211 | + /* Disable the Tx interrupts for the second Buffer | |
212 | + * if configured in HW */ | |
213 | + if (drvdata->tx_ping_pong != 0) { | |
214 | + reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
215 | + XEL_TSR_OFFSET); | |
216 | + out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
217 | + XEL_TSR_OFFSET, | |
218 | + reg_data & (~XEL_TSR_XMIT_IE_MASK)); | |
219 | + } | |
220 | + | |
221 | + /* Disable the Rx interrupts for the first buffer */ | |
222 | + reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET); | |
223 | + out_be32(drvdata->base_addr + XEL_RSR_OFFSET, | |
224 | + reg_data & (~XEL_RSR_RECV_IE_MASK)); | |
225 | + | |
226 | + /* Disable the Rx interrupts for the second buffer | |
227 | + * if configured in HW */ | |
228 | + if (drvdata->rx_ping_pong != 0) { | |
229 | + | |
230 | + reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
231 | + XEL_RSR_OFFSET); | |
232 | + out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
233 | + XEL_RSR_OFFSET, | |
234 | + reg_data & (~XEL_RSR_RECV_IE_MASK)); | |
235 | + } | |
236 | +} | |
237 | + | |
238 | +/** | |
239 | + * xemaclite_aligned_write - Write from 16-bit aligned to 32-bit aligned address | |
240 | + * @src_ptr: Void pointer to the 16-bit aligned source address | |
241 | + * @dest_ptr: Pointer to the 32-bit aligned destination address | |
242 | + * @length: Number bytes to write from source to destination | |
243 | + * | |
244 | + * This function writes data from a 16-bit aligned buffer to a 32-bit aligned | |
245 | + * address in the EmacLite device. | |
246 | + */ | |
247 | +static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr, | |
248 | + unsigned length) | |
249 | +{ | |
250 | + u32 align_buffer; | |
251 | + u32 *to_u32_ptr; | |
252 | + u16 *from_u16_ptr, *to_u16_ptr; | |
253 | + | |
254 | + to_u32_ptr = dest_ptr; | |
255 | + from_u16_ptr = src_ptr; | |
256 | + align_buffer = 0; | |
257 | + | |
258 | + for (; length > 3; length -= 4) { | |
259 | + to_u16_ptr = (u16 *)&align_buffer; | |
260 | + *to_u16_ptr++ = *from_u16_ptr++; | |
261 | + *to_u16_ptr++ = *from_u16_ptr++; | |
262 | + | |
263 | + /* Output a word */ | |
264 | + *to_u32_ptr++ = align_buffer; | |
265 | + } | |
266 | + if (length) { | |
267 | + u8 *from_u8_ptr, *to_u8_ptr; | |
268 | + | |
269 | + /* Set up to output the remaining data */ | |
270 | + align_buffer = 0; | |
271 | + to_u8_ptr = (u8 *) &align_buffer; | |
272 | + from_u8_ptr = (u8 *) from_u16_ptr; | |
273 | + | |
274 | + /* Output the remaining data */ | |
275 | + for (; length > 0; length--) | |
276 | + *to_u8_ptr++ = *from_u8_ptr++; | |
277 | + | |
278 | + *to_u32_ptr = align_buffer; | |
279 | + } | |
280 | +} | |
281 | + | |
282 | +/** | |
283 | + * xemaclite_aligned_read - Read from 32-bit aligned to 16-bit aligned buffer | |
284 | + * @src_ptr: Pointer to the 32-bit aligned source address | |
285 | + * @dest_ptr: Pointer to the 16-bit aligned destination address | |
286 | + * @length: Number bytes to read from source to destination | |
287 | + * | |
288 | + * This function reads data from a 32-bit aligned address in the EmacLite device | |
289 | + * to a 16-bit aligned buffer. | |
290 | + */ | |
291 | +static void xemaclite_aligned_read(u32 *src_ptr, u8 *dest_ptr, | |
292 | + unsigned length) | |
293 | +{ | |
294 | + u16 *to_u16_ptr, *from_u16_ptr; | |
295 | + u32 *from_u32_ptr; | |
296 | + u32 align_buffer; | |
297 | + | |
298 | + from_u32_ptr = src_ptr; | |
299 | + to_u16_ptr = (u16 *) dest_ptr; | |
300 | + | |
301 | + for (; length > 3; length -= 4) { | |
302 | + /* Copy each word into the temporary buffer */ | |
303 | + align_buffer = *from_u32_ptr++; | |
304 | + from_u16_ptr = (u16 *)&align_buffer; | |
305 | + | |
306 | + /* Read data from source */ | |
307 | + *to_u16_ptr++ = *from_u16_ptr++; | |
308 | + *to_u16_ptr++ = *from_u16_ptr++; | |
309 | + } | |
310 | + | |
311 | + if (length) { | |
312 | + u8 *to_u8_ptr, *from_u8_ptr; | |
313 | + | |
314 | + /* Set up to read the remaining data */ | |
315 | + to_u8_ptr = (u8 *) to_u16_ptr; | |
316 | + align_buffer = *from_u32_ptr++; | |
317 | + from_u8_ptr = (u8 *) &align_buffer; | |
318 | + | |
319 | + /* Read the remaining data */ | |
320 | + for (; length > 0; length--) | |
321 | + *to_u8_ptr = *from_u8_ptr; | |
322 | + } | |
323 | +} | |
324 | + | |
325 | +/** | |
326 | + * xemaclite_send_data - Send an Ethernet frame | |
327 | + * @drvdata: Pointer to the Emaclite device private data | |
328 | + * @data: Pointer to the data to be sent | |
329 | + * @byte_count: Total frame size, including header | |
330 | + * | |
331 | + * This function checks if the Tx buffer of the Emaclite device is free to send | |
332 | + * data. If so, it fills the Tx buffer with data for transmission. Otherwise, it | |
333 | + * returns an error. | |
334 | + * | |
335 | + * Return: 0 upon success or -1 if the buffer(s) are full. | |
336 | + * | |
337 | + * Note: The maximum Tx packet size can not be more than Ethernet header | |
338 | + * (14 Bytes) + Maximum MTU (1500 bytes). This is excluding FCS. | |
339 | + */ | |
340 | +static int xemaclite_send_data(struct net_local *drvdata, u8 *data, | |
341 | + unsigned int byte_count) | |
342 | +{ | |
343 | + u32 reg_data; | |
344 | + void __iomem *addr; | |
345 | + | |
346 | + /* Determine the expected Tx buffer address */ | |
347 | + addr = drvdata->base_addr + drvdata->next_tx_buf_to_use; | |
348 | + | |
349 | + /* If the length is too large, truncate it */ | |
350 | + if (byte_count > ETH_FRAME_LEN) | |
351 | + byte_count = ETH_FRAME_LEN; | |
352 | + | |
353 | + /* Check if the expected buffer is available */ | |
354 | + reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
355 | + if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | | |
356 | + XEL_TSR_XMIT_ACTIVE_MASK)) == 0) { | |
357 | + | |
358 | + /* Switch to next buffer if configured */ | |
359 | + if (drvdata->tx_ping_pong != 0) | |
360 | + drvdata->next_tx_buf_to_use ^= XEL_BUFFER_OFFSET; | |
361 | + } else if (drvdata->tx_ping_pong != 0) { | |
362 | + /* If the expected buffer is full, try the other buffer, | |
363 | + * if it is configured in HW */ | |
364 | + | |
365 | + addr = (void __iomem __force *)((u32 __force)addr ^ | |
366 | + XEL_BUFFER_OFFSET); | |
367 | + reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
368 | + | |
369 | + if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | | |
370 | + XEL_TSR_XMIT_ACTIVE_MASK)) != 0) | |
371 | + return -1; /* Buffers were full, return failure */ | |
372 | + } else | |
373 | + return -1; /* Buffer was full, return failure */ | |
374 | + | |
375 | + /* Write the frame to the buffer */ | |
376 | + xemaclite_aligned_write(data, (u32 __force *) addr, byte_count); | |
377 | + | |
378 | + out_be32(addr + XEL_TPLR_OFFSET, (byte_count & XEL_TPLR_LENGTH_MASK)); | |
379 | + | |
380 | + /* Update the Tx Status Register to indicate that there is a | |
381 | + * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which | |
382 | + * is used by the interrupt handler to check whether a frame | |
383 | + * has been transmitted */ | |
384 | + reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
385 | + reg_data |= (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK); | |
386 | + out_be32(addr + XEL_TSR_OFFSET, reg_data); | |
387 | + | |
388 | + return 0; | |
389 | +} | |
390 | + | |
391 | +/** | |
392 | + * xemaclite_recv_data - Receive a frame | |
393 | + * @drvdata: Pointer to the Emaclite device private data | |
394 | + * @data: Address where the data is to be received | |
395 | + * | |
396 | + * This function is intended to be called from the interrupt context or | |
397 | + * with a wrapper which waits for the receive frame to be available. | |
398 | + * | |
399 | + * Return: Total number of bytes received | |
400 | + */ | |
401 | +static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) | |
402 | +{ | |
403 | + void __iomem *addr; | |
404 | + u16 length, proto_type; | |
405 | + u32 reg_data; | |
406 | + | |
407 | + /* Determine the expected buffer address */ | |
408 | + addr = (drvdata->base_addr + drvdata->next_rx_buf_to_use); | |
409 | + | |
410 | + /* Verify which buffer has valid data */ | |
411 | + reg_data = in_be32(addr + XEL_RSR_OFFSET); | |
412 | + | |
413 | + if ((reg_data & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) { | |
414 | + if (drvdata->rx_ping_pong != 0) | |
415 | + drvdata->next_rx_buf_to_use ^= XEL_BUFFER_OFFSET; | |
416 | + } else { | |
417 | + /* The instance is out of sync, try other buffer if other | |
418 | + * buffer is configured, return 0 otherwise. If the instance is | |
419 | + * out of sync, do not update the 'next_rx_buf_to_use' since it | |
420 | + * will correct on subsequent calls */ | |
421 | + if (drvdata->rx_ping_pong != 0) | |
422 | + addr = (void __iomem __force *)((u32 __force)addr ^ | |
423 | + XEL_BUFFER_OFFSET); | |
424 | + else | |
425 | + return 0; /* No data was available */ | |
426 | + | |
427 | + /* Verify that buffer has valid data */ | |
428 | + reg_data = in_be32(addr + XEL_RSR_OFFSET); | |
429 | + if ((reg_data & XEL_RSR_RECV_DONE_MASK) != | |
430 | + XEL_RSR_RECV_DONE_MASK) | |
431 | + return 0; /* No data was available */ | |
432 | + } | |
433 | + | |
434 | + /* Get the protocol type of the ethernet frame that arrived */ | |
435 | + proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET + | |
436 | + XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & | |
437 | + XEL_RPLR_LENGTH_MASK); | |
438 | + | |
439 | + /* Check if received ethernet frame is a raw ethernet frame | |
440 | + * or an IP packet or an ARP packet */ | |
441 | + if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) { | |
442 | + | |
443 | + if (proto_type == ETH_P_IP) { | |
444 | + length = ((ntohl(in_be32(addr + | |
445 | + XEL_HEADER_IP_LENGTH_OFFSET + | |
446 | + XEL_RXBUFF_OFFSET)) >> | |
447 | + XEL_HEADER_SHIFT) & | |
448 | + XEL_RPLR_LENGTH_MASK); | |
449 | + length += ETH_HLEN + ETH_FCS_LEN; | |
450 | + | |
451 | + } else if (proto_type == ETH_P_ARP) | |
452 | + length = XEL_ARP_PACKET_SIZE + ETH_HLEN + ETH_FCS_LEN; | |
453 | + else | |
454 | + /* Field contains type other than IP or ARP, use max | |
455 | + * frame size and let user parse it */ | |
456 | + length = ETH_FRAME_LEN + ETH_FCS_LEN; | |
457 | + } else | |
458 | + /* Use the length in the frame, plus the header and trailer */ | |
459 | + length = proto_type + ETH_HLEN + ETH_FCS_LEN; | |
460 | + | |
461 | + /* Read from the EmacLite device */ | |
462 | + xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET), | |
463 | + data, length); | |
464 | + | |
465 | + /* Acknowledge the frame */ | |
466 | + reg_data = in_be32(addr + XEL_RSR_OFFSET); | |
467 | + reg_data &= ~XEL_RSR_RECV_DONE_MASK; | |
468 | + out_be32(addr + XEL_RSR_OFFSET, reg_data); | |
469 | + | |
470 | + return length; | |
471 | +} | |
472 | + | |
473 | +/** | |
474 | + * xemaclite_update_address - Update the MAC address in the device | |
475 | + * @drvdata: Pointer to the Emaclite device private data | |
476 | + * @address_ptr:Pointer to the MAC address (MAC address is a 48-bit value) | |
477 | + * | |
478 | + * Tx must be idle and Rx should be idle for deterministic results. | |
479 | + * It is recommended that this function should be called after the | |
480 | + * initialization and before transmission of any packets from the device. | |
481 | + * The MAC address can be programmed using any of the two transmit | |
482 | + * buffers (if configured). | |
483 | + */ | |
484 | +static void xemaclite_update_address(struct net_local *drvdata, | |
485 | + u8 *address_ptr) | |
486 | +{ | |
487 | + void __iomem *addr; | |
488 | + u32 reg_data; | |
489 | + | |
490 | + /* Determine the expected Tx buffer address */ | |
491 | + addr = drvdata->base_addr + drvdata->next_tx_buf_to_use; | |
492 | + | |
493 | + xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN); | |
494 | + | |
495 | + out_be32(addr + XEL_TPLR_OFFSET, ETH_ALEN); | |
496 | + | |
497 | + /* Update the MAC address in the EmacLite */ | |
498 | + reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
499 | + out_be32(addr + XEL_TSR_OFFSET, reg_data | XEL_TSR_PROG_MAC_ADDR); | |
500 | + | |
501 | + /* Wait for EmacLite to finish with the MAC address update */ | |
502 | + while ((in_be32(addr + XEL_TSR_OFFSET) & | |
503 | + XEL_TSR_PROG_MAC_ADDR) != 0) | |
504 | + ; | |
505 | +} | |
506 | + | |
507 | +/** | |
508 | + * xemaclite_set_mac_address - Set the MAC address for this device | |
509 | + * @dev: Pointer to the network device instance | |
510 | + * @addr: Void pointer to the sockaddr structure | |
511 | + * | |
512 | + * This function copies the HW address from the sockaddr strucutre to the | |
513 | + * net_device structure and updates the address in HW. | |
514 | + * | |
515 | + * Return: Error if the net device is busy or 0 if the addr is set | |
516 | + * successfully | |
517 | + */ | |
518 | +static int xemaclite_set_mac_address(struct net_device *dev, void *address) | |
519 | +{ | |
520 | + struct net_local *lp = netdev_priv(dev); | |
521 | + struct sockaddr *addr = address; | |
522 | + | |
523 | + if (netif_running(dev)) | |
524 | + return -EBUSY; | |
525 | + | |
526 | + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | |
527 | + xemaclite_update_address(lp, dev->dev_addr); | |
528 | + return 0; | |
529 | +} | |
530 | + | |
531 | +/** | |
532 | + * xemaclite_tx_timeout - Callback for Tx Timeout | |
533 | + * @dev: Pointer to the network device | |
534 | + * | |
535 | + * This function is called when Tx time out occurs for Emaclite device. | |
536 | + */ | |
537 | +static void xemaclite_tx_timeout(struct net_device *dev) | |
538 | +{ | |
539 | + struct net_local *lp = netdev_priv(dev); | |
540 | + unsigned long flags; | |
541 | + | |
542 | + dev_err(&lp->ndev->dev, "Exceeded transmit timeout of %lu ms\n", | |
543 | + TX_TIMEOUT * 1000UL / HZ); | |
544 | + | |
545 | + dev->stats.tx_errors++; | |
546 | + | |
547 | + /* Reset the device */ | |
548 | + spin_lock_irqsave(&lp->reset_lock, flags); | |
549 | + | |
550 | + /* Shouldn't really be necessary, but shouldn't hurt */ | |
551 | + netif_stop_queue(dev); | |
552 | + | |
553 | + xemaclite_disable_interrupts(lp); | |
554 | + xemaclite_enable_interrupts(lp); | |
555 | + | |
556 | + if (lp->deferred_skb) { | |
557 | + dev_kfree_skb(lp->deferred_skb); | |
558 | + lp->deferred_skb = NULL; | |
559 | + dev->stats.tx_errors++; | |
560 | + } | |
561 | + | |
562 | + /* To exclude tx timeout */ | |
563 | + dev->trans_start = jiffies; /* prevent tx timeout */ | |
564 | + | |
565 | + /* We're all ready to go. Start the queue */ | |
566 | + netif_wake_queue(dev); | |
567 | + spin_unlock_irqrestore(&lp->reset_lock, flags); | |
568 | +} | |
569 | + | |
570 | +/**********************/ | |
571 | +/* Interrupt Handlers */ | |
572 | +/**********************/ | |
573 | + | |
574 | +/** | |
575 | + * xemaclite_tx_handler - Interrupt handler for frames sent | |
576 | + * @dev: Pointer to the network device | |
577 | + * | |
578 | + * This function updates the number of packets transmitted and handles the | |
579 | + * deferred skb, if there is one. | |
580 | + */ | |
581 | +static void xemaclite_tx_handler(struct net_device *dev) | |
582 | +{ | |
583 | + struct net_local *lp = netdev_priv(dev); | |
584 | + | |
585 | + dev->stats.tx_packets++; | |
586 | + if (lp->deferred_skb) { | |
587 | + if (xemaclite_send_data(lp, | |
588 | + (u8 *) lp->deferred_skb->data, | |
589 | + lp->deferred_skb->len) != 0) | |
590 | + return; | |
591 | + else { | |
592 | + dev->stats.tx_bytes += lp->deferred_skb->len; | |
593 | + dev_kfree_skb_irq(lp->deferred_skb); | |
594 | + lp->deferred_skb = NULL; | |
595 | + dev->trans_start = jiffies; /* prevent tx timeout */ | |
596 | + netif_wake_queue(dev); | |
597 | + } | |
598 | + } | |
599 | +} | |
600 | + | |
601 | +/** | |
602 | + * xemaclite_rx_handler- Interrupt handler for frames received | |
603 | + * @dev: Pointer to the network device | |
604 | + * | |
605 | + * This function allocates memory for a socket buffer, fills it with data | |
606 | + * received and hands it over to the TCP/IP stack. | |
607 | + */ | |
608 | +static void xemaclite_rx_handler(struct net_device *dev) | |
609 | +{ | |
610 | + struct net_local *lp = netdev_priv(dev); | |
611 | + struct sk_buff *skb; | |
612 | + unsigned int align; | |
613 | + u32 len; | |
614 | + | |
615 | + len = ETH_FRAME_LEN + ETH_FCS_LEN; | |
616 | + skb = dev_alloc_skb(len + ALIGNMENT); | |
617 | + if (!skb) { | |
618 | + /* Couldn't get memory. */ | |
619 | + dev->stats.rx_dropped++; | |
620 | + dev_err(&lp->ndev->dev, "Could not allocate receive buffer\n"); | |
621 | + return; | |
622 | + } | |
623 | + | |
624 | + /* | |
625 | + * A new skb should have the data halfword aligned, but this code is | |
626 | + * here just in case that isn't true. Calculate how many | |
627 | + * bytes we should reserve to get the data to start on a word | |
628 | + * boundary */ | |
629 | + align = BUFFER_ALIGN(skb->data); | |
630 | + if (align) | |
631 | + skb_reserve(skb, align); | |
632 | + | |
633 | + skb_reserve(skb, 2); | |
634 | + | |
635 | + len = xemaclite_recv_data(lp, (u8 *) skb->data); | |
636 | + | |
637 | + if (!len) { | |
638 | + dev->stats.rx_errors++; | |
639 | + dev_kfree_skb_irq(skb); | |
640 | + return; | |
641 | + } | |
642 | + | |
643 | + skb_put(skb, len); /* Tell the skb how much data we got */ | |
644 | + | |
645 | + skb->protocol = eth_type_trans(skb, dev); | |
646 | + skb_checksum_none_assert(skb); | |
647 | + | |
648 | + dev->stats.rx_packets++; | |
649 | + dev->stats.rx_bytes += len; | |
650 | + | |
651 | + if (!skb_defer_rx_timestamp(skb)) | |
652 | + netif_rx(skb); /* Send the packet upstream */ | |
653 | +} | |
654 | + | |
655 | +/** | |
656 | + * xemaclite_interrupt - Interrupt handler for this driver | |
657 | + * @irq: Irq of the Emaclite device | |
658 | + * @dev_id: Void pointer to the network device instance used as callback | |
659 | + * reference | |
660 | + * | |
661 | + * This function handles the Tx and Rx interrupts of the EmacLite device. | |
662 | + */ | |
663 | +static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) | |
664 | +{ | |
665 | + bool tx_complete = 0; | |
666 | + struct net_device *dev = dev_id; | |
667 | + struct net_local *lp = netdev_priv(dev); | |
668 | + void __iomem *base_addr = lp->base_addr; | |
669 | + u32 tx_status; | |
670 | + | |
671 | + /* Check if there is Rx Data available */ | |
672 | + if ((in_be32(base_addr + XEL_RSR_OFFSET) & XEL_RSR_RECV_DONE_MASK) || | |
673 | + (in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) | |
674 | + & XEL_RSR_RECV_DONE_MASK)) | |
675 | + | |
676 | + xemaclite_rx_handler(dev); | |
677 | + | |
678 | + /* Check if the Transmission for the first buffer is completed */ | |
679 | + tx_status = in_be32(base_addr + XEL_TSR_OFFSET); | |
680 | + if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && | |
681 | + (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { | |
682 | + | |
683 | + tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; | |
684 | + out_be32(base_addr + XEL_TSR_OFFSET, tx_status); | |
685 | + | |
686 | + tx_complete = 1; | |
687 | + } | |
688 | + | |
689 | + /* Check if the Transmission for the second buffer is completed */ | |
690 | + tx_status = in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); | |
691 | + if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && | |
692 | + (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { | |
693 | + | |
694 | + tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; | |
695 | + out_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, | |
696 | + tx_status); | |
697 | + | |
698 | + tx_complete = 1; | |
699 | + } | |
700 | + | |
701 | + /* If there was a Tx interrupt, call the Tx Handler */ | |
702 | + if (tx_complete != 0) | |
703 | + xemaclite_tx_handler(dev); | |
704 | + | |
705 | + return IRQ_HANDLED; | |
706 | +} | |
707 | + | |
708 | +/**********************/ | |
709 | +/* MDIO Bus functions */ | |
710 | +/**********************/ | |
711 | + | |
712 | +/** | |
713 | + * xemaclite_mdio_wait - Wait for the MDIO to be ready to use | |
714 | + * @lp: Pointer to the Emaclite device private data | |
715 | + * | |
716 | + * This function waits till the device is ready to accept a new MDIO | |
717 | + * request. | |
718 | + * | |
719 | + * Return: 0 for success or ETIMEDOUT for a timeout | |
720 | + */ | |
721 | + | |
722 | +static int xemaclite_mdio_wait(struct net_local *lp) | |
723 | +{ | |
724 | + long end = jiffies + 2; | |
725 | + | |
726 | + /* wait for the MDIO interface to not be busy or timeout | |
727 | + after some time. | |
728 | + */ | |
729 | + while (in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET) & | |
730 | + XEL_MDIOCTRL_MDIOSTS_MASK) { | |
731 | + if (end - jiffies <= 0) { | |
732 | + WARN_ON(1); | |
733 | + return -ETIMEDOUT; | |
734 | + } | |
735 | + msleep(1); | |
736 | + } | |
737 | + return 0; | |
738 | +} | |
739 | + | |
740 | +/** | |
741 | + * xemaclite_mdio_read - Read from a given MII management register | |
742 | + * @bus: the mii_bus struct | |
743 | + * @phy_id: the phy address | |
744 | + * @reg: register number to read from | |
745 | + * | |
746 | + * This function waits till the device is ready to accept a new MDIO | |
747 | + * request and then writes the phy address to the MDIO Address register | |
748 | + * and reads data from MDIO Read Data register, when its available. | |
749 | + * | |
750 | + * Return: Value read from the MII management register | |
751 | + */ | |
752 | +static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg) | |
753 | +{ | |
754 | + struct net_local *lp = bus->priv; | |
755 | + u32 ctrl_reg; | |
756 | + u32 rc; | |
757 | + | |
758 | + if (xemaclite_mdio_wait(lp)) | |
759 | + return -ETIMEDOUT; | |
760 | + | |
761 | + /* Write the PHY address, register number and set the OP bit in the | |
762 | + * MDIO Address register. Set the Status bit in the MDIO Control | |
763 | + * register to start a MDIO read transaction. | |
764 | + */ | |
765 | + ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); | |
766 | + out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, | |
767 | + XEL_MDIOADDR_OP_MASK | | |
768 | + ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); | |
769 | + out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | |
770 | + ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); | |
771 | + | |
772 | + if (xemaclite_mdio_wait(lp)) | |
773 | + return -ETIMEDOUT; | |
774 | + | |
775 | + rc = in_be32(lp->base_addr + XEL_MDIORD_OFFSET); | |
776 | + | |
777 | + dev_dbg(&lp->ndev->dev, | |
778 | + "xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n", | |
779 | + phy_id, reg, rc); | |
780 | + | |
781 | + return rc; | |
782 | +} | |
783 | + | |
784 | +/** | |
785 | + * xemaclite_mdio_write - Write to a given MII management register | |
786 | + * @bus: the mii_bus struct | |
787 | + * @phy_id: the phy address | |
788 | + * @reg: register number to write to | |
789 | + * @val: value to write to the register number specified by reg | |
790 | + * | |
791 | + * This function waits till the device is ready to accept a new MDIO | |
792 | + * request and then writes the val to the MDIO Write Data register. | |
793 | + */ | |
794 | +static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg, | |
795 | + u16 val) | |
796 | +{ | |
797 | + struct net_local *lp = bus->priv; | |
798 | + u32 ctrl_reg; | |
799 | + | |
800 | + dev_dbg(&lp->ndev->dev, | |
801 | + "xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n", | |
802 | + phy_id, reg, val); | |
803 | + | |
804 | + if (xemaclite_mdio_wait(lp)) | |
805 | + return -ETIMEDOUT; | |
806 | + | |
807 | + /* Write the PHY address, register number and clear the OP bit in the | |
808 | + * MDIO Address register and then write the value into the MDIO Write | |
809 | + * Data register. Finally, set the Status bit in the MDIO Control | |
810 | + * register to start a MDIO write transaction. | |
811 | + */ | |
812 | + ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); | |
813 | + out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, | |
814 | + ~XEL_MDIOADDR_OP_MASK & | |
815 | + ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); | |
816 | + out_be32(lp->base_addr + XEL_MDIOWR_OFFSET, val); | |
817 | + out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | |
818 | + ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); | |
819 | + | |
820 | + return 0; | |
821 | +} | |
822 | + | |
823 | +/** | |
824 | + * xemaclite_mdio_reset - Reset the mdio bus. | |
825 | + * @bus: Pointer to the MII bus | |
826 | + * | |
827 | + * This function is required(?) as per Documentation/networking/phy.txt. | |
828 | + * There is no reset in this device; this function always returns 0. | |
829 | + */ | |
830 | +static int xemaclite_mdio_reset(struct mii_bus *bus) | |
831 | +{ | |
832 | + return 0; | |
833 | +} | |
834 | + | |
835 | +/** | |
836 | + * xemaclite_mdio_setup - Register mii_bus for the Emaclite device | |
837 | + * @lp: Pointer to the Emaclite device private data | |
838 | + * @ofdev: Pointer to OF device structure | |
839 | + * | |
840 | + * This function enables MDIO bus in the Emaclite device and registers a | |
841 | + * mii_bus. | |
842 | + * | |
843 | + * Return: 0 upon success or a negative error upon failure | |
844 | + */ | |
845 | +static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) | |
846 | +{ | |
847 | + struct mii_bus *bus; | |
848 | + int rc; | |
849 | + struct resource res; | |
850 | + struct device_node *np = of_get_parent(lp->phy_node); | |
851 | + | |
852 | + /* Don't register the MDIO bus if the phy_node or its parent node | |
853 | + * can't be found. | |
854 | + */ | |
855 | + if (!np) | |
856 | + return -ENODEV; | |
857 | + | |
858 | + /* Enable the MDIO bus by asserting the enable bit in MDIO Control | |
859 | + * register. | |
860 | + */ | |
861 | + out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | |
862 | + XEL_MDIOCTRL_MDIOEN_MASK); | |
863 | + | |
864 | + bus = mdiobus_alloc(); | |
865 | + if (!bus) | |
866 | + return -ENOMEM; | |
867 | + | |
868 | + of_address_to_resource(np, 0, &res); | |
869 | + snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", | |
870 | + (unsigned long long)res.start); | |
871 | + bus->priv = lp; | |
872 | + bus->name = "Xilinx Emaclite MDIO"; | |
873 | + bus->read = xemaclite_mdio_read; | |
874 | + bus->write = xemaclite_mdio_write; | |
875 | + bus->reset = xemaclite_mdio_reset; | |
876 | + bus->parent = dev; | |
877 | + bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ | |
878 | + | |
879 | + lp->mii_bus = bus; | |
880 | + | |
881 | + rc = of_mdiobus_register(bus, np); | |
882 | + if (rc) | |
883 | + goto err_register; | |
884 | + | |
885 | + return 0; | |
886 | + | |
887 | +err_register: | |
888 | + mdiobus_free(bus); | |
889 | + return rc; | |
890 | +} | |
891 | + | |
892 | +/** | |
893 | + * xemaclite_adjust_link - Link state callback for the Emaclite device | |
894 | + * @ndev: pointer to net_device struct | |
895 | + * | |
896 | + * There's nothing in the Emaclite device to be configured when the link | |
897 | + * state changes. We just print the status. | |
898 | + */ | |
899 | +void xemaclite_adjust_link(struct net_device *ndev) | |
900 | +{ | |
901 | + struct net_local *lp = netdev_priv(ndev); | |
902 | + struct phy_device *phy = lp->phy_dev; | |
903 | + int link_state; | |
904 | + | |
905 | + /* hash together the state values to decide if something has changed */ | |
906 | + link_state = phy->speed | (phy->duplex << 1) | phy->link; | |
907 | + | |
908 | + if (lp->last_link != link_state) { | |
909 | + lp->last_link = link_state; | |
910 | + phy_print_status(phy); | |
911 | + } | |
912 | +} | |
913 | + | |
914 | +/** | |
915 | + * xemaclite_open - Open the network device | |
916 | + * @dev: Pointer to the network device | |
917 | + * | |
918 | + * This function sets the MAC address, requests an IRQ and enables interrupts | |
919 | + * for the Emaclite device and starts the Tx queue. | |
920 | + * It also connects to the phy device, if MDIO is included in Emaclite device. | |
921 | + */ | |
922 | +static int xemaclite_open(struct net_device *dev) | |
923 | +{ | |
924 | + struct net_local *lp = netdev_priv(dev); | |
925 | + int retval; | |
926 | + | |
927 | + /* Just to be safe, stop the device first */ | |
928 | + xemaclite_disable_interrupts(lp); | |
929 | + | |
930 | + if (lp->phy_node) { | |
931 | + u32 bmcr; | |
932 | + | |
933 | + lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, | |
934 | + xemaclite_adjust_link, 0, | |
935 | + PHY_INTERFACE_MODE_MII); | |
936 | + if (!lp->phy_dev) { | |
937 | + dev_err(&lp->ndev->dev, "of_phy_connect() failed\n"); | |
938 | + return -ENODEV; | |
939 | + } | |
940 | + | |
941 | + /* EmacLite doesn't support giga-bit speeds */ | |
942 | + lp->phy_dev->supported &= (PHY_BASIC_FEATURES); | |
943 | + lp->phy_dev->advertising = lp->phy_dev->supported; | |
944 | + | |
945 | + /* Don't advertise 1000BASE-T Full/Half duplex speeds */ | |
946 | + phy_write(lp->phy_dev, MII_CTRL1000, 0); | |
947 | + | |
948 | + /* Advertise only 10 and 100mbps full/half duplex speeds */ | |
949 | + phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL); | |
950 | + | |
951 | + /* Restart auto negotiation */ | |
952 | + bmcr = phy_read(lp->phy_dev, MII_BMCR); | |
953 | + bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); | |
954 | + phy_write(lp->phy_dev, MII_BMCR, bmcr); | |
955 | + | |
956 | + phy_start(lp->phy_dev); | |
957 | + } | |
958 | + | |
959 | + /* Set the MAC address each time opened */ | |
960 | + xemaclite_update_address(lp, dev->dev_addr); | |
961 | + | |
962 | + /* Grab the IRQ */ | |
963 | + retval = request_irq(dev->irq, xemaclite_interrupt, 0, dev->name, dev); | |
964 | + if (retval) { | |
965 | + dev_err(&lp->ndev->dev, "Could not allocate interrupt %d\n", | |
966 | + dev->irq); | |
967 | + if (lp->phy_dev) | |
968 | + phy_disconnect(lp->phy_dev); | |
969 | + lp->phy_dev = NULL; | |
970 | + | |
971 | + return retval; | |
972 | + } | |
973 | + | |
974 | + /* Enable Interrupts */ | |
975 | + xemaclite_enable_interrupts(lp); | |
976 | + | |
977 | + /* We're ready to go */ | |
978 | + netif_start_queue(dev); | |
979 | + | |
980 | + return 0; | |
981 | +} | |
982 | + | |
983 | +/** | |
984 | + * xemaclite_close - Close the network device | |
985 | + * @dev: Pointer to the network device | |
986 | + * | |
987 | + * This function stops the Tx queue, disables interrupts and frees the IRQ for | |
988 | + * the Emaclite device. | |
989 | + * It also disconnects the phy device associated with the Emaclite device. | |
990 | + */ | |
991 | +static int xemaclite_close(struct net_device *dev) | |
992 | +{ | |
993 | + struct net_local *lp = netdev_priv(dev); | |
994 | + | |
995 | + netif_stop_queue(dev); | |
996 | + xemaclite_disable_interrupts(lp); | |
997 | + free_irq(dev->irq, dev); | |
998 | + | |
999 | + if (lp->phy_dev) | |
1000 | + phy_disconnect(lp->phy_dev); | |
1001 | + lp->phy_dev = NULL; | |
1002 | + | |
1003 | + return 0; | |
1004 | +} | |
1005 | + | |
1006 | +/** | |
1007 | + * xemaclite_send - Transmit a frame | |
1008 | + * @orig_skb: Pointer to the socket buffer to be transmitted | |
1009 | + * @dev: Pointer to the network device | |
1010 | + * | |
1011 | + * This function checks if the Tx buffer of the Emaclite device is free to send | |
1012 | + * data. If so, it fills the Tx buffer with data from socket buffer data, | |
1013 | + * updates the stats and frees the socket buffer. The Tx completion is signaled | |
1014 | + * by an interrupt. If the Tx buffer isn't free, then the socket buffer is | |
1015 | + * deferred and the Tx queue is stopped so that the deferred socket buffer can | |
1016 | + * be transmitted when the Emaclite device is free to transmit data. | |
1017 | + * | |
1018 | + * Return: 0, always. | |
1019 | + */ | |
1020 | +static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) | |
1021 | +{ | |
1022 | + struct net_local *lp = netdev_priv(dev); | |
1023 | + struct sk_buff *new_skb; | |
1024 | + unsigned int len; | |
1025 | + unsigned long flags; | |
1026 | + | |
1027 | + len = orig_skb->len; | |
1028 | + | |
1029 | + new_skb = orig_skb; | |
1030 | + | |
1031 | + spin_lock_irqsave(&lp->reset_lock, flags); | |
1032 | + if (xemaclite_send_data(lp, (u8 *) new_skb->data, len) != 0) { | |
1033 | + /* If the Emaclite Tx buffer is busy, stop the Tx queue and | |
1034 | + * defer the skb for transmission during the ISR, after the | |
1035 | + * current transmission is complete */ | |
1036 | + netif_stop_queue(dev); | |
1037 | + lp->deferred_skb = new_skb; | |
1038 | + /* Take the time stamp now, since we can't do this in an ISR. */ | |
1039 | + skb_tx_timestamp(new_skb); | |
1040 | + spin_unlock_irqrestore(&lp->reset_lock, flags); | |
1041 | + return 0; | |
1042 | + } | |
1043 | + spin_unlock_irqrestore(&lp->reset_lock, flags); | |
1044 | + | |
1045 | + skb_tx_timestamp(new_skb); | |
1046 | + | |
1047 | + dev->stats.tx_bytes += len; | |
1048 | + dev_kfree_skb(new_skb); | |
1049 | + | |
1050 | + return 0; | |
1051 | +} | |
1052 | + | |
1053 | +/** | |
1054 | + * xemaclite_remove_ndev - Free the network device | |
1055 | + * @ndev: Pointer to the network device to be freed | |
1056 | + * | |
1057 | + * This function un maps the IO region of the Emaclite device and frees the net | |
1058 | + * device. | |
1059 | + */ | |
1060 | +static void xemaclite_remove_ndev(struct net_device *ndev) | |
1061 | +{ | |
1062 | + if (ndev) { | |
1063 | + struct net_local *lp = netdev_priv(ndev); | |
1064 | + | |
1065 | + if (lp->base_addr) | |
1066 | + iounmap((void __iomem __force *) (lp->base_addr)); | |
1067 | + free_netdev(ndev); | |
1068 | + } | |
1069 | +} | |
1070 | + | |
1071 | +/** | |
1072 | + * get_bool - Get a parameter from the OF device | |
1073 | + * @ofdev: Pointer to OF device structure | |
1074 | + * @s: Property to be retrieved | |
1075 | + * | |
1076 | + * This function looks for a property in the device node and returns the value | |
1077 | + * of the property if its found or 0 if the property is not found. | |
1078 | + * | |
1079 | + * Return: Value of the parameter if the parameter is found, or 0 otherwise | |
1080 | + */ | |
1081 | +static bool get_bool(struct platform_device *ofdev, const char *s) | |
1082 | +{ | |
1083 | + u32 *p = (u32 *)of_get_property(ofdev->dev.of_node, s, NULL); | |
1084 | + | |
1085 | + if (p) { | |
1086 | + return (bool)*p; | |
1087 | + } else { | |
1088 | + dev_warn(&ofdev->dev, "Parameter %s not found," | |
1089 | + "defaulting to false\n", s); | |
1090 | + return 0; | |
1091 | + } | |
1092 | +} | |
1093 | + | |
1094 | +static struct net_device_ops xemaclite_netdev_ops; | |
1095 | + | |
1096 | +/** | |
1097 | + * xemaclite_of_probe - Probe method for the Emaclite device. | |
1098 | + * @ofdev: Pointer to OF device structure | |
1099 | + * @match: Pointer to the structure used for matching a device | |
1100 | + * | |
1101 | + * This function probes for the Emaclite device in the device tree. | |
1102 | + * It initializes the driver data structure and the hardware, sets the MAC | |
1103 | + * address and registers the network device. | |
1104 | + * It also registers a mii_bus for the Emaclite device, if MDIO is included | |
1105 | + * in the device. | |
1106 | + * | |
1107 | + * Return: 0, if the driver is bound to the Emaclite device, or | |
1108 | + * a negative error if there is failure. | |
1109 | + */ | |
1110 | +static int __devinit xemaclite_of_probe(struct platform_device *ofdev) | |
1111 | +{ | |
1112 | + struct resource r_irq; /* Interrupt resources */ | |
1113 | + struct resource r_mem; /* IO mem resources */ | |
1114 | + struct net_device *ndev = NULL; | |
1115 | + struct net_local *lp = NULL; | |
1116 | + struct device *dev = &ofdev->dev; | |
1117 | + const void *mac_address; | |
1118 | + | |
1119 | + int rc = 0; | |
1120 | + | |
1121 | + dev_info(dev, "Device Tree Probing\n"); | |
1122 | + | |
1123 | + /* Get iospace for the device */ | |
1124 | + rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); | |
1125 | + if (rc) { | |
1126 | + dev_err(dev, "invalid address\n"); | |
1127 | + return rc; | |
1128 | + } | |
1129 | + | |
1130 | + /* Get IRQ for the device */ | |
1131 | + rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); | |
1132 | + if (rc == NO_IRQ) { | |
1133 | + dev_err(dev, "no IRQ found\n"); | |
1134 | + return rc; | |
1135 | + } | |
1136 | + | |
1137 | + /* Create an ethernet device instance */ | |
1138 | + ndev = alloc_etherdev(sizeof(struct net_local)); | |
1139 | + if (!ndev) { | |
1140 | + dev_err(dev, "Could not allocate network device\n"); | |
1141 | + return -ENOMEM; | |
1142 | + } | |
1143 | + | |
1144 | + dev_set_drvdata(dev, ndev); | |
1145 | + SET_NETDEV_DEV(ndev, &ofdev->dev); | |
1146 | + | |
1147 | + ndev->irq = r_irq.start; | |
1148 | + ndev->mem_start = r_mem.start; | |
1149 | + ndev->mem_end = r_mem.end; | |
1150 | + | |
1151 | + lp = netdev_priv(ndev); | |
1152 | + lp->ndev = ndev; | |
1153 | + | |
1154 | + if (!request_mem_region(ndev->mem_start, | |
1155 | + ndev->mem_end - ndev->mem_start + 1, | |
1156 | + DRIVER_NAME)) { | |
1157 | + dev_err(dev, "Couldn't lock memory region at %p\n", | |
1158 | + (void *)ndev->mem_start); | |
1159 | + rc = -EBUSY; | |
1160 | + goto error2; | |
1161 | + } | |
1162 | + | |
1163 | + /* Get the virtual base address for the device */ | |
1164 | + lp->base_addr = ioremap(r_mem.start, resource_size(&r_mem)); | |
1165 | + if (NULL == lp->base_addr) { | |
1166 | + dev_err(dev, "EmacLite: Could not allocate iomem\n"); | |
1167 | + rc = -EIO; | |
1168 | + goto error1; | |
1169 | + } | |
1170 | + | |
1171 | + spin_lock_init(&lp->reset_lock); | |
1172 | + lp->next_tx_buf_to_use = 0x0; | |
1173 | + lp->next_rx_buf_to_use = 0x0; | |
1174 | + lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong"); | |
1175 | + lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong"); | |
1176 | + mac_address = of_get_mac_address(ofdev->dev.of_node); | |
1177 | + | |
1178 | + if (mac_address) | |
1179 | + /* Set the MAC address. */ | |
1180 | + memcpy(ndev->dev_addr, mac_address, 6); | |
1181 | + else | |
1182 | + dev_warn(dev, "No MAC address found\n"); | |
1183 | + | |
1184 | + /* Clear the Tx CSR's in case this is a restart */ | |
1185 | + out_be32(lp->base_addr + XEL_TSR_OFFSET, 0); | |
1186 | + out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0); | |
1187 | + | |
1188 | + /* Set the MAC address in the EmacLite device */ | |
1189 | + xemaclite_update_address(lp, ndev->dev_addr); | |
1190 | + | |
1191 | + lp->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); | |
1192 | + rc = xemaclite_mdio_setup(lp, &ofdev->dev); | |
1193 | + if (rc) | |
1194 | + dev_warn(&ofdev->dev, "error registering MDIO bus\n"); | |
1195 | + | |
1196 | + dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr); | |
1197 | + | |
1198 | + ndev->netdev_ops = &xemaclite_netdev_ops; | |
1199 | + ndev->flags &= ~IFF_MULTICAST; | |
1200 | + ndev->watchdog_timeo = TX_TIMEOUT; | |
1201 | + | |
1202 | + /* Finally, register the device */ | |
1203 | + rc = register_netdev(ndev); | |
1204 | + if (rc) { | |
1205 | + dev_err(dev, | |
1206 | + "Cannot register network device, aborting\n"); | |
1207 | + goto error1; | |
1208 | + } | |
1209 | + | |
1210 | + dev_info(dev, | |
1211 | + "Xilinx EmacLite at 0x%08X mapped to 0x%08X, irq=%d\n", | |
1212 | + (unsigned int __force)ndev->mem_start, | |
1213 | + (unsigned int __force)lp->base_addr, ndev->irq); | |
1214 | + return 0; | |
1215 | + | |
1216 | +error1: | |
1217 | + release_mem_region(ndev->mem_start, resource_size(&r_mem)); | |
1218 | + | |
1219 | +error2: | |
1220 | + xemaclite_remove_ndev(ndev); | |
1221 | + return rc; | |
1222 | +} | |
1223 | + | |
1224 | +/** | |
1225 | + * xemaclite_of_remove - Unbind the driver from the Emaclite device. | |
1226 | + * @of_dev: Pointer to OF device structure | |
1227 | + * | |
1228 | + * This function is called if a device is physically removed from the system or | |
1229 | + * if the driver module is being unloaded. It frees any resources allocated to | |
1230 | + * the device. | |
1231 | + * | |
1232 | + * Return: 0, always. | |
1233 | + */ | |
1234 | +static int __devexit xemaclite_of_remove(struct platform_device *of_dev) | |
1235 | +{ | |
1236 | + struct device *dev = &of_dev->dev; | |
1237 | + struct net_device *ndev = dev_get_drvdata(dev); | |
1238 | + | |
1239 | + struct net_local *lp = netdev_priv(ndev); | |
1240 | + | |
1241 | + /* Un-register the mii_bus, if configured */ | |
1242 | + if (lp->has_mdio) { | |
1243 | + mdiobus_unregister(lp->mii_bus); | |
1244 | + kfree(lp->mii_bus->irq); | |
1245 | + mdiobus_free(lp->mii_bus); | |
1246 | + lp->mii_bus = NULL; | |
1247 | + } | |
1248 | + | |
1249 | + unregister_netdev(ndev); | |
1250 | + | |
1251 | + if (lp->phy_node) | |
1252 | + of_node_put(lp->phy_node); | |
1253 | + lp->phy_node = NULL; | |
1254 | + | |
1255 | + release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1); | |
1256 | + | |
1257 | + xemaclite_remove_ndev(ndev); | |
1258 | + dev_set_drvdata(dev, NULL); | |
1259 | + | |
1260 | + return 0; | |
1261 | +} | |
1262 | + | |
1263 | +#ifdef CONFIG_NET_POLL_CONTROLLER | |
1264 | +static void | |
1265 | +xemaclite_poll_controller(struct net_device *ndev) | |
1266 | +{ | |
1267 | + disable_irq(ndev->irq); | |
1268 | + xemaclite_interrupt(ndev->irq, ndev); | |
1269 | + enable_irq(ndev->irq); | |
1270 | +} | |
1271 | +#endif | |
1272 | + | |
1273 | +static struct net_device_ops xemaclite_netdev_ops = { | |
1274 | + .ndo_open = xemaclite_open, | |
1275 | + .ndo_stop = xemaclite_close, | |
1276 | + .ndo_start_xmit = xemaclite_send, | |
1277 | + .ndo_set_mac_address = xemaclite_set_mac_address, | |
1278 | + .ndo_tx_timeout = xemaclite_tx_timeout, | |
1279 | +#ifdef CONFIG_NET_POLL_CONTROLLER | |
1280 | + .ndo_poll_controller = xemaclite_poll_controller, | |
1281 | +#endif | |
1282 | +}; | |
1283 | + | |
1284 | +/* Match table for OF platform binding */ | |
1285 | +static struct of_device_id xemaclite_of_match[] __devinitdata = { | |
1286 | + { .compatible = "xlnx,opb-ethernetlite-1.01.a", }, | |
1287 | + { .compatible = "xlnx,opb-ethernetlite-1.01.b", }, | |
1288 | + { .compatible = "xlnx,xps-ethernetlite-1.00.a", }, | |
1289 | + { .compatible = "xlnx,xps-ethernetlite-2.00.a", }, | |
1290 | + { .compatible = "xlnx,xps-ethernetlite-2.01.a", }, | |
1291 | + { .compatible = "xlnx,xps-ethernetlite-3.00.a", }, | |
1292 | + { /* end of list */ }, | |
1293 | +}; | |
1294 | +MODULE_DEVICE_TABLE(of, xemaclite_of_match); | |
1295 | + | |
1296 | +static struct platform_driver xemaclite_of_driver = { | |
1297 | + .driver = { | |
1298 | + .name = DRIVER_NAME, | |
1299 | + .owner = THIS_MODULE, | |
1300 | + .of_match_table = xemaclite_of_match, | |
1301 | + }, | |
1302 | + .probe = xemaclite_of_probe, | |
1303 | + .remove = __devexit_p(xemaclite_of_remove), | |
1304 | +}; | |
1305 | + | |
1306 | +/** | |
1307 | + * xgpiopss_init - Initial driver registration call | |
1308 | + * | |
1309 | + * Return: 0 upon success, or a negative error upon failure. | |
1310 | + */ | |
1311 | +static int __init xemaclite_init(void) | |
1312 | +{ | |
1313 | + /* No kernel boot options used, we just need to register the driver */ | |
1314 | + return platform_driver_register(&xemaclite_of_driver); | |
1315 | +} | |
1316 | + | |
1317 | +/** | |
1318 | + * xemaclite_cleanup - Driver un-registration call | |
1319 | + */ | |
1320 | +static void __exit xemaclite_cleanup(void) | |
1321 | +{ | |
1322 | + platform_driver_unregister(&xemaclite_of_driver); | |
1323 | +} | |
1324 | + | |
1325 | +module_init(xemaclite_init); | |
1326 | +module_exit(xemaclite_cleanup); | |
1327 | + | |
1328 | +MODULE_AUTHOR("Xilinx, Inc."); | |
1329 | +MODULE_DESCRIPTION("Xilinx Ethernet MAC Lite driver"); | |
1330 | +MODULE_LICENSE("GPL"); |
drivers/net/ll_temac.h
1 | - | |
2 | -#ifndef XILINX_LL_TEMAC_H | |
3 | -#define XILINX_LL_TEMAC_H | |
4 | - | |
5 | -#include <linux/netdevice.h> | |
6 | -#include <linux/of.h> | |
7 | -#include <linux/spinlock.h> | |
8 | - | |
9 | -#ifdef CONFIG_PPC_DCR | |
10 | -#include <asm/dcr.h> | |
11 | -#include <asm/dcr-regs.h> | |
12 | -#endif | |
13 | - | |
14 | -/* packet size info */ | |
15 | -#define XTE_HDR_SIZE 14 /* size of Ethernet header */ | |
16 | -#define XTE_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */ | |
17 | -#define XTE_JUMBO_MTU 9000 | |
18 | -#define XTE_MAX_JUMBO_FRAME_SIZE (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE) | |
19 | - | |
20 | -/* Configuration options */ | |
21 | - | |
22 | -/* Accept all incoming packets. | |
23 | - * This option defaults to disabled (cleared) */ | |
24 | -#define XTE_OPTION_PROMISC (1 << 0) | |
25 | -/* Jumbo frame support for Tx & Rx. | |
26 | - * This option defaults to disabled (cleared) */ | |
27 | -#define XTE_OPTION_JUMBO (1 << 1) | |
28 | -/* VLAN Rx & Tx frame support. | |
29 | - * This option defaults to disabled (cleared) */ | |
30 | -#define XTE_OPTION_VLAN (1 << 2) | |
31 | -/* Enable recognition of flow control frames on Rx | |
32 | - * This option defaults to enabled (set) */ | |
33 | -#define XTE_OPTION_FLOW_CONTROL (1 << 4) | |
34 | -/* Strip FCS and PAD from incoming frames. | |
35 | - * Note: PAD from VLAN frames is not stripped. | |
36 | - * This option defaults to disabled (set) */ | |
37 | -#define XTE_OPTION_FCS_STRIP (1 << 5) | |
38 | -/* Generate FCS field and add PAD automatically for outgoing frames. | |
39 | - * This option defaults to enabled (set) */ | |
40 | -#define XTE_OPTION_FCS_INSERT (1 << 6) | |
41 | -/* Enable Length/Type error checking for incoming frames. When this option is | |
42 | -set, the MAC will filter frames that have a mismatched type/length field | |
43 | -and if XTE_OPTION_REPORT_RXERR is set, the user is notified when these | |
44 | -types of frames are encountered. When this option is cleared, the MAC will | |
45 | -allow these types of frames to be received. | |
46 | -This option defaults to enabled (set) */ | |
47 | -#define XTE_OPTION_LENTYPE_ERR (1 << 7) | |
48 | -/* Enable the transmitter. | |
49 | - * This option defaults to enabled (set) */ | |
50 | -#define XTE_OPTION_TXEN (1 << 11) | |
51 | -/* Enable the receiver | |
52 | -* This option defaults to enabled (set) */ | |
53 | -#define XTE_OPTION_RXEN (1 << 12) | |
54 | - | |
55 | -/* Default options set when device is initialized or reset */ | |
56 | -#define XTE_OPTION_DEFAULTS \ | |
57 | - (XTE_OPTION_TXEN | \ | |
58 | - XTE_OPTION_FLOW_CONTROL | \ | |
59 | - XTE_OPTION_RXEN) | |
60 | - | |
61 | -/* XPS_LL_TEMAC SDMA registers definition */ | |
62 | - | |
63 | -#define TX_NXTDESC_PTR 0x00 /* r */ | |
64 | -#define TX_CURBUF_ADDR 0x01 /* r */ | |
65 | -#define TX_CURBUF_LENGTH 0x02 /* r */ | |
66 | -#define TX_CURDESC_PTR 0x03 /* rw */ | |
67 | -#define TX_TAILDESC_PTR 0x04 /* rw */ | |
68 | -#define TX_CHNL_CTRL 0x05 /* rw */ | |
69 | -/* | |
70 | - 0:7 24:31 IRQTimeout | |
71 | - 8:15 16:23 IRQCount | |
72 | - 16:20 11:15 Reserved | |
73 | - 21 10 0 | |
74 | - 22 9 UseIntOnEnd | |
75 | - 23 8 LdIRQCnt | |
76 | - 24 7 IRQEn | |
77 | - 25:28 3:6 Reserved | |
78 | - 29 2 IrqErrEn | |
79 | - 30 1 IrqDlyEn | |
80 | - 31 0 IrqCoalEn | |
81 | -*/ | |
82 | -#define CHNL_CTRL_IRQ_IOE (1 << 9) | |
83 | -#define CHNL_CTRL_IRQ_EN (1 << 7) | |
84 | -#define CHNL_CTRL_IRQ_ERR_EN (1 << 2) | |
85 | -#define CHNL_CTRL_IRQ_DLY_EN (1 << 1) | |
86 | -#define CHNL_CTRL_IRQ_COAL_EN (1 << 0) | |
87 | -#define TX_IRQ_REG 0x06 /* rw */ | |
88 | -/* | |
89 | - 0:7 24:31 DltTmrValue | |
90 | - 8:15 16:23 ClscCntrValue | |
91 | - 16:17 14:15 Reserved | |
92 | - 18:21 10:13 ClscCnt | |
93 | - 22:23 8:9 DlyCnt | |
94 | - 24:28 3::7 Reserved | |
95 | - 29 2 ErrIrq | |
96 | - 30 1 DlyIrq | |
97 | - 31 0 CoalIrq | |
98 | - */ | |
99 | -#define TX_CHNL_STS 0x07 /* r */ | |
100 | -/* | |
101 | - 0:9 22:31 Reserved | |
102 | - 10 21 TailPErr | |
103 | - 11 20 CmpErr | |
104 | - 12 19 AddrErr | |
105 | - 13 18 NxtPErr | |
106 | - 14 17 CurPErr | |
107 | - 15 16 BsyWr | |
108 | - 16:23 8:15 Reserved | |
109 | - 24 7 Error | |
110 | - 25 6 IOE | |
111 | - 26 5 SOE | |
112 | - 27 4 Cmplt | |
113 | - 28 3 SOP | |
114 | - 29 2 EOP | |
115 | - 30 1 EngBusy | |
116 | - 31 0 Reserved | |
117 | -*/ | |
118 | - | |
119 | -#define RX_NXTDESC_PTR 0x08 /* r */ | |
120 | -#define RX_CURBUF_ADDR 0x09 /* r */ | |
121 | -#define RX_CURBUF_LENGTH 0x0a /* r */ | |
122 | -#define RX_CURDESC_PTR 0x0b /* rw */ | |
123 | -#define RX_TAILDESC_PTR 0x0c /* rw */ | |
124 | -#define RX_CHNL_CTRL 0x0d /* rw */ | |
125 | -/* | |
126 | - 0:7 24:31 IRQTimeout | |
127 | - 8:15 16:23 IRQCount | |
128 | - 16:20 11:15 Reserved | |
129 | - 21 10 0 | |
130 | - 22 9 UseIntOnEnd | |
131 | - 23 8 LdIRQCnt | |
132 | - 24 7 IRQEn | |
133 | - 25:28 3:6 Reserved | |
134 | - 29 2 IrqErrEn | |
135 | - 30 1 IrqDlyEn | |
136 | - 31 0 IrqCoalEn | |
137 | - */ | |
138 | -#define RX_IRQ_REG 0x0e /* rw */ | |
139 | -#define IRQ_COAL (1 << 0) | |
140 | -#define IRQ_DLY (1 << 1) | |
141 | -#define IRQ_ERR (1 << 2) | |
142 | -#define IRQ_DMAERR (1 << 7) /* this is not documented ??? */ | |
143 | -/* | |
144 | - 0:7 24:31 DltTmrValue | |
145 | - 8:15 16:23 ClscCntrValue | |
146 | - 16:17 14:15 Reserved | |
147 | - 18:21 10:13 ClscCnt | |
148 | - 22:23 8:9 DlyCnt | |
149 | - 24:28 3::7 Reserved | |
150 | -*/ | |
151 | -#define RX_CHNL_STS 0x0f /* r */ | |
152 | -#define CHNL_STS_ENGBUSY (1 << 1) | |
153 | -#define CHNL_STS_EOP (1 << 2) | |
154 | -#define CHNL_STS_SOP (1 << 3) | |
155 | -#define CHNL_STS_CMPLT (1 << 4) | |
156 | -#define CHNL_STS_SOE (1 << 5) | |
157 | -#define CHNL_STS_IOE (1 << 6) | |
158 | -#define CHNL_STS_ERR (1 << 7) | |
159 | - | |
160 | -#define CHNL_STS_BSYWR (1 << 16) | |
161 | -#define CHNL_STS_CURPERR (1 << 17) | |
162 | -#define CHNL_STS_NXTPERR (1 << 18) | |
163 | -#define CHNL_STS_ADDRERR (1 << 19) | |
164 | -#define CHNL_STS_CMPERR (1 << 20) | |
165 | -#define CHNL_STS_TAILERR (1 << 21) | |
166 | -/* | |
167 | - 0:9 22:31 Reserved | |
168 | - 10 21 TailPErr | |
169 | - 11 20 CmpErr | |
170 | - 12 19 AddrErr | |
171 | - 13 18 NxtPErr | |
172 | - 14 17 CurPErr | |
173 | - 15 16 BsyWr | |
174 | - 16:23 8:15 Reserved | |
175 | - 24 7 Error | |
176 | - 25 6 IOE | |
177 | - 26 5 SOE | |
178 | - 27 4 Cmplt | |
179 | - 28 3 SOP | |
180 | - 29 2 EOP | |
181 | - 30 1 EngBusy | |
182 | - 31 0 Reserved | |
183 | -*/ | |
184 | - | |
185 | -#define DMA_CONTROL_REG 0x10 /* rw */ | |
186 | -#define DMA_CONTROL_RST (1 << 0) | |
187 | -#define DMA_TAIL_ENABLE (1 << 2) | |
188 | - | |
189 | -/* XPS_LL_TEMAC direct registers definition */ | |
190 | - | |
191 | -#define XTE_RAF0_OFFSET 0x00 | |
192 | -#define RAF0_RST (1 << 0) | |
193 | -#define RAF0_MCSTREJ (1 << 1) | |
194 | -#define RAF0_BCSTREJ (1 << 2) | |
195 | -#define XTE_TPF0_OFFSET 0x04 | |
196 | -#define XTE_IFGP0_OFFSET 0x08 | |
197 | -#define XTE_ISR0_OFFSET 0x0c | |
198 | -#define ISR0_HARDACSCMPLT (1 << 0) | |
199 | -#define ISR0_AUTONEG (1 << 1) | |
200 | -#define ISR0_RXCMPLT (1 << 2) | |
201 | -#define ISR0_RXREJ (1 << 3) | |
202 | -#define ISR0_RXFIFOOVR (1 << 4) | |
203 | -#define ISR0_TXCMPLT (1 << 5) | |
204 | -#define ISR0_RXDCMLCK (1 << 6) | |
205 | - | |
206 | -#define XTE_IPR0_OFFSET 0x10 | |
207 | -#define XTE_IER0_OFFSET 0x14 | |
208 | - | |
209 | -#define XTE_MSW0_OFFSET 0x20 | |
210 | -#define XTE_LSW0_OFFSET 0x24 | |
211 | -#define XTE_CTL0_OFFSET 0x28 | |
212 | -#define XTE_RDY0_OFFSET 0x2c | |
213 | - | |
214 | -#define XTE_RSE_MIIM_RR_MASK 0x0002 | |
215 | -#define XTE_RSE_MIIM_WR_MASK 0x0004 | |
216 | -#define XTE_RSE_CFG_RR_MASK 0x0020 | |
217 | -#define XTE_RSE_CFG_WR_MASK 0x0040 | |
218 | -#define XTE_RDY0_HARD_ACS_RDY_MASK (0x10000) | |
219 | - | |
220 | -/* XPS_LL_TEMAC indirect registers offset definition */ | |
221 | - | |
222 | -#define XTE_RXC0_OFFSET 0x00000200 /* Rx configuration word 0 */ | |
223 | -#define XTE_RXC1_OFFSET 0x00000240 /* Rx configuration word 1 */ | |
224 | -#define XTE_RXC1_RXRST_MASK (1 << 31) /* Receiver reset */ | |
225 | -#define XTE_RXC1_RXJMBO_MASK (1 << 30) /* Jumbo frame enable */ | |
226 | -#define XTE_RXC1_RXFCS_MASK (1 << 29) /* FCS not stripped */ | |
227 | -#define XTE_RXC1_RXEN_MASK (1 << 28) /* Receiver enable */ | |
228 | -#define XTE_RXC1_RXVLAN_MASK (1 << 27) /* VLAN enable */ | |
229 | -#define XTE_RXC1_RXHD_MASK (1 << 26) /* Half duplex */ | |
230 | -#define XTE_RXC1_RXLT_MASK (1 << 25) /* Length/type check disable */ | |
231 | - | |
232 | -#define XTE_TXC_OFFSET 0x00000280 /* Tx configuration */ | |
233 | -#define XTE_TXC_TXRST_MASK (1 << 31) /* Transmitter reset */ | |
234 | -#define XTE_TXC_TXJMBO_MASK (1 << 30) /* Jumbo frame enable */ | |
235 | -#define XTE_TXC_TXFCS_MASK (1 << 29) /* Generate FCS */ | |
236 | -#define XTE_TXC_TXEN_MASK (1 << 28) /* Transmitter enable */ | |
237 | -#define XTE_TXC_TXVLAN_MASK (1 << 27) /* VLAN enable */ | |
238 | -#define XTE_TXC_TXHD_MASK (1 << 26) /* Half duplex */ | |
239 | - | |
240 | -#define XTE_FCC_OFFSET 0x000002C0 /* Flow control config */ | |
241 | -#define XTE_FCC_RXFLO_MASK (1 << 29) /* Rx flow control enable */ | |
242 | -#define XTE_FCC_TXFLO_MASK (1 << 30) /* Tx flow control enable */ | |
243 | - | |
244 | -#define XTE_EMCFG_OFFSET 0x00000300 /* EMAC configuration */ | |
245 | -#define XTE_EMCFG_LINKSPD_MASK 0xC0000000 /* Link speed */ | |
246 | -#define XTE_EMCFG_HOSTEN_MASK (1 << 26) /* Host interface enable */ | |
247 | -#define XTE_EMCFG_LINKSPD_10 0x00000000 /* 10 Mbit LINKSPD_MASK */ | |
248 | -#define XTE_EMCFG_LINKSPD_100 (1 << 30) /* 100 Mbit LINKSPD_MASK */ | |
249 | -#define XTE_EMCFG_LINKSPD_1000 (1 << 31) /* 1000 Mbit LINKSPD_MASK */ | |
250 | - | |
251 | -#define XTE_GMIC_OFFSET 0x00000320 /* RGMII/SGMII config */ | |
252 | -#define XTE_MC_OFFSET 0x00000340 /* MDIO configuration */ | |
253 | -#define XTE_UAW0_OFFSET 0x00000380 /* Unicast address word 0 */ | |
254 | -#define XTE_UAW1_OFFSET 0x00000384 /* Unicast address word 1 */ | |
255 | - | |
256 | -#define XTE_MAW0_OFFSET 0x00000388 /* Multicast addr word 0 */ | |
257 | -#define XTE_MAW1_OFFSET 0x0000038C /* Multicast addr word 1 */ | |
258 | -#define XTE_AFM_OFFSET 0x00000390 /* Promiscuous mode */ | |
259 | -#define XTE_AFM_EPPRM_MASK (1 << 31) /* Promiscuous mode enable */ | |
260 | - | |
261 | -/* Interrupt Request status */ | |
262 | -#define XTE_TIS_OFFSET 0x000003A0 | |
263 | -#define TIS_FRIS (1 << 0) | |
264 | -#define TIS_MRIS (1 << 1) | |
265 | -#define TIS_MWIS (1 << 2) | |
266 | -#define TIS_ARIS (1 << 3) | |
267 | -#define TIS_AWIS (1 << 4) | |
268 | -#define TIS_CRIS (1 << 5) | |
269 | -#define TIS_CWIS (1 << 6) | |
270 | - | |
271 | -#define XTE_TIE_OFFSET 0x000003A4 /* Interrupt enable */ | |
272 | - | |
273 | -/** MII Mamagement Control register (MGTCR) */ | |
274 | -#define XTE_MGTDR_OFFSET 0x000003B0 /* MII data */ | |
275 | -#define XTE_MIIMAI_OFFSET 0x000003B4 /* MII control */ | |
276 | - | |
277 | -#define CNTLREG_WRITE_ENABLE_MASK 0x8000 | |
278 | -#define CNTLREG_EMAC1SEL_MASK 0x0400 | |
279 | -#define CNTLREG_ADDRESSCODE_MASK 0x03ff | |
280 | - | |
281 | -/* CDMAC descriptor status bit definitions */ | |
282 | - | |
283 | -#define STS_CTRL_APP0_ERR (1 << 31) | |
284 | -#define STS_CTRL_APP0_IRQONEND (1 << 30) | |
285 | -/* undoccumented */ | |
286 | -#define STS_CTRL_APP0_STOPONEND (1 << 29) | |
287 | -#define STS_CTRL_APP0_CMPLT (1 << 28) | |
288 | -#define STS_CTRL_APP0_SOP (1 << 27) | |
289 | -#define STS_CTRL_APP0_EOP (1 << 26) | |
290 | -#define STS_CTRL_APP0_ENGBUSY (1 << 25) | |
291 | -/* undocumented */ | |
292 | -#define STS_CTRL_APP0_ENGRST (1 << 24) | |
293 | - | |
294 | -#define TX_CONTROL_CALC_CSUM_MASK 1 | |
295 | - | |
296 | -#define MULTICAST_CAM_TABLE_NUM 4 | |
297 | - | |
298 | -/* TEMAC Synthesis features */ | |
299 | -#define TEMAC_FEATURE_RX_CSUM (1 << 0) | |
300 | -#define TEMAC_FEATURE_TX_CSUM (1 << 1) | |
301 | - | |
302 | -/* TX/RX CURDESC_PTR points to first descriptor */ | |
303 | -/* TX/RX TAILDESC_PTR points to last descriptor in linked list */ | |
304 | - | |
305 | -/** | |
306 | - * struct cdmac_bd - LocalLink buffer descriptor format | |
307 | - * | |
308 | - * app0 bits: | |
309 | - * 0 Error | |
310 | - * 1 IrqOnEnd generate an interrupt at completion of DMA op | |
311 | - * 2 reserved | |
312 | - * 3 completed Current descriptor completed | |
313 | - * 4 SOP TX - marks first desc/ RX marks first desct | |
314 | - * 5 EOP TX marks last desc/RX marks last desc | |
315 | - * 6 EngBusy DMA is processing | |
316 | - * 7 reserved | |
317 | - * 8:31 application specific | |
318 | - */ | |
319 | -struct cdmac_bd { | |
320 | - u32 next; /* Physical address of next buffer descriptor */ | |
321 | - u32 phys; | |
322 | - u32 len; | |
323 | - u32 app0; | |
324 | - u32 app1; /* TX start << 16 | insert */ | |
325 | - u32 app2; /* TX csum */ | |
326 | - u32 app3; | |
327 | - u32 app4; /* skb for TX length for RX */ | |
328 | -}; | |
329 | - | |
330 | -struct temac_local { | |
331 | - struct net_device *ndev; | |
332 | - struct device *dev; | |
333 | - | |
334 | - /* Connection to PHY device */ | |
335 | - struct phy_device *phy_dev; /* Pointer to PHY device */ | |
336 | - struct device_node *phy_node; | |
337 | - | |
338 | - /* MDIO bus data */ | |
339 | - struct mii_bus *mii_bus; /* MII bus reference */ | |
340 | - int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ | |
341 | - | |
342 | - /* IO registers, dma functions and IRQs */ | |
343 | - void __iomem *regs; | |
344 | - void __iomem *sdma_regs; | |
345 | -#ifdef CONFIG_PPC_DCR | |
346 | - dcr_host_t sdma_dcrs; | |
347 | -#endif | |
348 | - u32 (*dma_in)(struct temac_local *, int); | |
349 | - void (*dma_out)(struct temac_local *, int, u32); | |
350 | - | |
351 | - int tx_irq; | |
352 | - int rx_irq; | |
353 | - int emac_num; | |
354 | - | |
355 | - struct sk_buff **rx_skb; | |
356 | - spinlock_t rx_lock; | |
357 | - struct mutex indirect_mutex; | |
358 | - u32 options; /* Current options word */ | |
359 | - int last_link; | |
360 | - unsigned int temac_features; | |
361 | - | |
362 | - /* Buffer descriptors */ | |
363 | - struct cdmac_bd *tx_bd_v; | |
364 | - dma_addr_t tx_bd_p; | |
365 | - struct cdmac_bd *rx_bd_v; | |
366 | - dma_addr_t rx_bd_p; | |
367 | - int tx_bd_ci; | |
368 | - int tx_bd_next; | |
369 | - int tx_bd_tail; | |
370 | - int rx_bd_ci; | |
371 | -}; | |
372 | - | |
373 | -/* xilinx_temac.c */ | |
374 | -u32 temac_ior(struct temac_local *lp, int offset); | |
375 | -void temac_iow(struct temac_local *lp, int offset, u32 value); | |
376 | -int temac_indirect_busywait(struct temac_local *lp); | |
377 | -u32 temac_indirect_in32(struct temac_local *lp, int reg); | |
378 | -void temac_indirect_out32(struct temac_local *lp, int reg, u32 value); | |
379 | - | |
380 | - | |
381 | -/* xilinx_temac_mdio.c */ | |
382 | -int temac_mdio_setup(struct temac_local *lp, struct device_node *np); | |
383 | -void temac_mdio_teardown(struct temac_local *lp); | |
384 | - | |
385 | -#endif /* XILINX_LL_TEMAC_H */ |
drivers/net/ll_temac_main.c
Changes suppressed. Click to show
1 | -/* | |
2 | - * Driver for Xilinx TEMAC Ethernet device | |
3 | - * | |
4 | - * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi | |
5 | - * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. <dhlii@dlasys.net> | |
6 | - * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. | |
7 | - * | |
8 | - * This is a driver for the Xilinx ll_temac ipcore which is often used | |
9 | - * in the Virtex and Spartan series of chips. | |
10 | - * | |
11 | - * Notes: | |
12 | - * - The ll_temac hardware uses indirect access for many of the TEMAC | |
13 | - * registers, include the MDIO bus. However, indirect access to MDIO | |
14 | - * registers take considerably more clock cycles than to TEMAC registers. | |
15 | - * MDIO accesses are long, so threads doing them should probably sleep | |
16 | - * rather than busywait. However, since only one indirect access can be | |
17 | - * in progress at any given time, that means that *all* indirect accesses | |
18 | - * could end up sleeping (to wait for an MDIO access to complete). | |
19 | - * Fortunately none of the indirect accesses are on the 'hot' path for tx | |
20 | - * or rx, so this should be okay. | |
21 | - * | |
22 | - * TODO: | |
23 | - * - Factor out locallink DMA code into separate driver | |
24 | - * - Fix multicast assignment. | |
25 | - * - Fix support for hardware checksumming. | |
26 | - * - Testing. Lots and lots of testing. | |
27 | - * | |
28 | - */ | |
29 | - | |
30 | -#include <linux/delay.h> | |
31 | -#include <linux/etherdevice.h> | |
32 | -#include <linux/init.h> | |
33 | -#include <linux/mii.h> | |
34 | -#include <linux/module.h> | |
35 | -#include <linux/mutex.h> | |
36 | -#include <linux/netdevice.h> | |
37 | -#include <linux/of.h> | |
38 | -#include <linux/of_device.h> | |
39 | -#include <linux/of_mdio.h> | |
40 | -#include <linux/of_platform.h> | |
41 | -#include <linux/of_address.h> | |
42 | -#include <linux/skbuff.h> | |
43 | -#include <linux/spinlock.h> | |
44 | -#include <linux/tcp.h> /* needed for sizeof(tcphdr) */ | |
45 | -#include <linux/udp.h> /* needed for sizeof(udphdr) */ | |
46 | -#include <linux/phy.h> | |
47 | -#include <linux/in.h> | |
48 | -#include <linux/io.h> | |
49 | -#include <linux/ip.h> | |
50 | -#include <linux/slab.h> | |
51 | -#include <linux/interrupt.h> | |
52 | -#include <linux/dma-mapping.h> | |
53 | - | |
54 | -#include "ll_temac.h" | |
55 | - | |
56 | -#define TX_BD_NUM 64 | |
57 | -#define RX_BD_NUM 128 | |
58 | - | |
59 | -/* --------------------------------------------------------------------- | |
60 | - * Low level register access functions | |
61 | - */ | |
62 | - | |
63 | -u32 temac_ior(struct temac_local *lp, int offset) | |
64 | -{ | |
65 | - return in_be32((u32 *)(lp->regs + offset)); | |
66 | -} | |
67 | - | |
68 | -void temac_iow(struct temac_local *lp, int offset, u32 value) | |
69 | -{ | |
70 | - out_be32((u32 *) (lp->regs + offset), value); | |
71 | -} | |
72 | - | |
73 | -int temac_indirect_busywait(struct temac_local *lp) | |
74 | -{ | |
75 | - long end = jiffies + 2; | |
76 | - | |
77 | - while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) { | |
78 | - if (end - jiffies <= 0) { | |
79 | - WARN_ON(1); | |
80 | - return -ETIMEDOUT; | |
81 | - } | |
82 | - msleep(1); | |
83 | - } | |
84 | - return 0; | |
85 | -} | |
86 | - | |
87 | -/** | |
88 | - * temac_indirect_in32 | |
89 | - * | |
90 | - * lp->indirect_mutex must be held when calling this function | |
91 | - */ | |
92 | -u32 temac_indirect_in32(struct temac_local *lp, int reg) | |
93 | -{ | |
94 | - u32 val; | |
95 | - | |
96 | - if (temac_indirect_busywait(lp)) | |
97 | - return -ETIMEDOUT; | |
98 | - temac_iow(lp, XTE_CTL0_OFFSET, reg); | |
99 | - if (temac_indirect_busywait(lp)) | |
100 | - return -ETIMEDOUT; | |
101 | - val = temac_ior(lp, XTE_LSW0_OFFSET); | |
102 | - | |
103 | - return val; | |
104 | -} | |
105 | - | |
106 | -/** | |
107 | - * temac_indirect_out32 | |
108 | - * | |
109 | - * lp->indirect_mutex must be held when calling this function | |
110 | - */ | |
111 | -void temac_indirect_out32(struct temac_local *lp, int reg, u32 value) | |
112 | -{ | |
113 | - if (temac_indirect_busywait(lp)) | |
114 | - return; | |
115 | - temac_iow(lp, XTE_LSW0_OFFSET, value); | |
116 | - temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); | |
117 | -} | |
118 | - | |
119 | -/** | |
120 | - * temac_dma_in32 - Memory mapped DMA read, this function expects a | |
121 | - * register input that is based on DCR word addresses which | |
122 | - * are then converted to memory mapped byte addresses | |
123 | - */ | |
124 | -static u32 temac_dma_in32(struct temac_local *lp, int reg) | |
125 | -{ | |
126 | - return in_be32((u32 *)(lp->sdma_regs + (reg << 2))); | |
127 | -} | |
128 | - | |
129 | -/** | |
130 | - * temac_dma_out32 - Memory mapped DMA read, this function expects a | |
131 | - * register input that is based on DCR word addresses which | |
132 | - * are then converted to memory mapped byte addresses | |
133 | - */ | |
134 | -static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) | |
135 | -{ | |
136 | - out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value); | |
137 | -} | |
138 | - | |
139 | -/* DMA register access functions can be DCR based or memory mapped. | |
140 | - * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both | |
141 | - * memory mapped. | |
142 | - */ | |
143 | -#ifdef CONFIG_PPC_DCR | |
144 | - | |
145 | -/** | |
146 | - * temac_dma_dcr_in32 - DCR based DMA read | |
147 | - */ | |
148 | -static u32 temac_dma_dcr_in(struct temac_local *lp, int reg) | |
149 | -{ | |
150 | - return dcr_read(lp->sdma_dcrs, reg); | |
151 | -} | |
152 | - | |
153 | -/** | |
154 | - * temac_dma_dcr_out32 - DCR based DMA write | |
155 | - */ | |
156 | -static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value) | |
157 | -{ | |
158 | - dcr_write(lp->sdma_dcrs, reg, value); | |
159 | -} | |
160 | - | |
161 | -/** | |
162 | - * temac_dcr_setup - If the DMA is DCR based, then setup the address and | |
163 | - * I/O functions | |
164 | - */ | |
165 | -static int temac_dcr_setup(struct temac_local *lp, struct platform_device *op, | |
166 | - struct device_node *np) | |
167 | -{ | |
168 | - unsigned int dcrs; | |
169 | - | |
170 | - /* setup the dcr address mapping if it's in the device tree */ | |
171 | - | |
172 | - dcrs = dcr_resource_start(np, 0); | |
173 | - if (dcrs != 0) { | |
174 | - lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); | |
175 | - lp->dma_in = temac_dma_dcr_in; | |
176 | - lp->dma_out = temac_dma_dcr_out; | |
177 | - dev_dbg(&op->dev, "DCR base: %x\n", dcrs); | |
178 | - return 0; | |
179 | - } | |
180 | - /* no DCR in the device tree, indicate a failure */ | |
181 | - return -1; | |
182 | -} | |
183 | - | |
184 | -#else | |
185 | - | |
186 | -/* | |
187 | - * temac_dcr_setup - This is a stub for when DCR is not supported, | |
188 | - * such as with MicroBlaze | |
189 | - */ | |
190 | -static int temac_dcr_setup(struct temac_local *lp, struct platform_device *op, | |
191 | - struct device_node *np) | |
192 | -{ | |
193 | - return -1; | |
194 | -} | |
195 | - | |
196 | -#endif | |
197 | - | |
198 | -/** | |
199 | - * * temac_dma_bd_release - Release buffer descriptor rings | |
200 | - */ | |
201 | -static void temac_dma_bd_release(struct net_device *ndev) | |
202 | -{ | |
203 | - struct temac_local *lp = netdev_priv(ndev); | |
204 | - int i; | |
205 | - | |
206 | - for (i = 0; i < RX_BD_NUM; i++) { | |
207 | - if (!lp->rx_skb[i]) | |
208 | - break; | |
209 | - else { | |
210 | - dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys, | |
211 | - XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); | |
212 | - dev_kfree_skb(lp->rx_skb[i]); | |
213 | - } | |
214 | - } | |
215 | - if (lp->rx_bd_v) | |
216 | - dma_free_coherent(ndev->dev.parent, | |
217 | - sizeof(*lp->rx_bd_v) * RX_BD_NUM, | |
218 | - lp->rx_bd_v, lp->rx_bd_p); | |
219 | - if (lp->tx_bd_v) | |
220 | - dma_free_coherent(ndev->dev.parent, | |
221 | - sizeof(*lp->tx_bd_v) * TX_BD_NUM, | |
222 | - lp->tx_bd_v, lp->tx_bd_p); | |
223 | - if (lp->rx_skb) | |
224 | - kfree(lp->rx_skb); | |
225 | -} | |
226 | - | |
227 | -/** | |
228 | - * temac_dma_bd_init - Setup buffer descriptor rings | |
229 | - */ | |
230 | -static int temac_dma_bd_init(struct net_device *ndev) | |
231 | -{ | |
232 | - struct temac_local *lp = netdev_priv(ndev); | |
233 | - struct sk_buff *skb; | |
234 | - int i; | |
235 | - | |
236 | - lp->rx_skb = kzalloc(sizeof(*lp->rx_skb) * RX_BD_NUM, GFP_KERNEL); | |
237 | - if (!lp->rx_skb) { | |
238 | - dev_err(&ndev->dev, | |
239 | - "can't allocate memory for DMA RX buffer\n"); | |
240 | - goto out; | |
241 | - } | |
242 | - /* allocate the tx and rx ring buffer descriptors. */ | |
243 | - /* returns a virtual address and a physical address. */ | |
244 | - lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, | |
245 | - sizeof(*lp->tx_bd_v) * TX_BD_NUM, | |
246 | - &lp->tx_bd_p, GFP_KERNEL); | |
247 | - if (!lp->tx_bd_v) { | |
248 | - dev_err(&ndev->dev, | |
249 | - "unable to allocate DMA TX buffer descriptors"); | |
250 | - goto out; | |
251 | - } | |
252 | - lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, | |
253 | - sizeof(*lp->rx_bd_v) * RX_BD_NUM, | |
254 | - &lp->rx_bd_p, GFP_KERNEL); | |
255 | - if (!lp->rx_bd_v) { | |
256 | - dev_err(&ndev->dev, | |
257 | - "unable to allocate DMA RX buffer descriptors"); | |
258 | - goto out; | |
259 | - } | |
260 | - | |
261 | - memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); | |
262 | - for (i = 0; i < TX_BD_NUM; i++) { | |
263 | - lp->tx_bd_v[i].next = lp->tx_bd_p + | |
264 | - sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM); | |
265 | - } | |
266 | - | |
267 | - memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM); | |
268 | - for (i = 0; i < RX_BD_NUM; i++) { | |
269 | - lp->rx_bd_v[i].next = lp->rx_bd_p + | |
270 | - sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); | |
271 | - | |
272 | - skb = netdev_alloc_skb_ip_align(ndev, | |
273 | - XTE_MAX_JUMBO_FRAME_SIZE); | |
274 | - | |
275 | - if (skb == 0) { | |
276 | - dev_err(&ndev->dev, "alloc_skb error %d\n", i); | |
277 | - goto out; | |
278 | - } | |
279 | - lp->rx_skb[i] = skb; | |
280 | - /* returns physical address of skb->data */ | |
281 | - lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, | |
282 | - skb->data, | |
283 | - XTE_MAX_JUMBO_FRAME_SIZE, | |
284 | - DMA_FROM_DEVICE); | |
285 | - lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE; | |
286 | - lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; | |
287 | - } | |
288 | - | |
289 | - lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 | | |
290 | - CHNL_CTRL_IRQ_EN | | |
291 | - CHNL_CTRL_IRQ_DLY_EN | | |
292 | - CHNL_CTRL_IRQ_COAL_EN); | |
293 | - /* 0x10220483 */ | |
294 | - /* 0x00100483 */ | |
295 | - lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 | | |
296 | - CHNL_CTRL_IRQ_EN | | |
297 | - CHNL_CTRL_IRQ_DLY_EN | | |
298 | - CHNL_CTRL_IRQ_COAL_EN | | |
299 | - CHNL_CTRL_IRQ_IOE); | |
300 | - /* 0xff010283 */ | |
301 | - | |
302 | - lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); | |
303 | - lp->dma_out(lp, RX_TAILDESC_PTR, | |
304 | - lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); | |
305 | - lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); | |
306 | - | |
307 | - return 0; | |
308 | - | |
309 | -out: | |
310 | - temac_dma_bd_release(ndev); | |
311 | - return -ENOMEM; | |
312 | -} | |
313 | - | |
314 | -/* --------------------------------------------------------------------- | |
315 | - * net_device_ops | |
316 | - */ | |
317 | - | |
318 | -static int temac_set_mac_address(struct net_device *ndev, void *address) | |
319 | -{ | |
320 | - struct temac_local *lp = netdev_priv(ndev); | |
321 | - | |
322 | - if (address) | |
323 | - memcpy(ndev->dev_addr, address, ETH_ALEN); | |
324 | - | |
325 | - if (!is_valid_ether_addr(ndev->dev_addr)) | |
326 | - random_ether_addr(ndev->dev_addr); | |
327 | - | |
328 | - /* set up unicast MAC address filter set its mac address */ | |
329 | - mutex_lock(&lp->indirect_mutex); | |
330 | - temac_indirect_out32(lp, XTE_UAW0_OFFSET, | |
331 | - (ndev->dev_addr[0]) | | |
332 | - (ndev->dev_addr[1] << 8) | | |
333 | - (ndev->dev_addr[2] << 16) | | |
334 | - (ndev->dev_addr[3] << 24)); | |
335 | - /* There are reserved bits in EUAW1 | |
336 | - * so don't affect them Set MAC bits [47:32] in EUAW1 */ | |
337 | - temac_indirect_out32(lp, XTE_UAW1_OFFSET, | |
338 | - (ndev->dev_addr[4] & 0x000000ff) | | |
339 | - (ndev->dev_addr[5] << 8)); | |
340 | - mutex_unlock(&lp->indirect_mutex); | |
341 | - | |
342 | - return 0; | |
343 | -} | |
344 | - | |
345 | -static int netdev_set_mac_address(struct net_device *ndev, void *p) | |
346 | -{ | |
347 | - struct sockaddr *addr = p; | |
348 | - | |
349 | - return temac_set_mac_address(ndev, addr->sa_data); | |
350 | -} | |
351 | - | |
352 | -static void temac_set_multicast_list(struct net_device *ndev) | |
353 | -{ | |
354 | - struct temac_local *lp = netdev_priv(ndev); | |
355 | - u32 multi_addr_msw, multi_addr_lsw, val; | |
356 | - int i; | |
357 | - | |
358 | - mutex_lock(&lp->indirect_mutex); | |
359 | - if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) || | |
360 | - netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) { | |
361 | - /* | |
362 | - * We must make the kernel realise we had to move | |
363 | - * into promisc mode or we start all out war on | |
364 | - * the cable. If it was a promisc request the | |
365 | - * flag is already set. If not we assert it. | |
366 | - */ | |
367 | - ndev->flags |= IFF_PROMISC; | |
368 | - temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK); | |
369 | - dev_info(&ndev->dev, "Promiscuous mode enabled.\n"); | |
370 | - } else if (!netdev_mc_empty(ndev)) { | |
371 | - struct netdev_hw_addr *ha; | |
372 | - | |
373 | - i = 0; | |
374 | - netdev_for_each_mc_addr(ha, ndev) { | |
375 | - if (i >= MULTICAST_CAM_TABLE_NUM) | |
376 | - break; | |
377 | - multi_addr_msw = ((ha->addr[3] << 24) | | |
378 | - (ha->addr[2] << 16) | | |
379 | - (ha->addr[1] << 8) | | |
380 | - (ha->addr[0])); | |
381 | - temac_indirect_out32(lp, XTE_MAW0_OFFSET, | |
382 | - multi_addr_msw); | |
383 | - multi_addr_lsw = ((ha->addr[5] << 8) | | |
384 | - (ha->addr[4]) | (i << 16)); | |
385 | - temac_indirect_out32(lp, XTE_MAW1_OFFSET, | |
386 | - multi_addr_lsw); | |
387 | - i++; | |
388 | - } | |
389 | - } else { | |
390 | - val = temac_indirect_in32(lp, XTE_AFM_OFFSET); | |
391 | - temac_indirect_out32(lp, XTE_AFM_OFFSET, | |
392 | - val & ~XTE_AFM_EPPRM_MASK); | |
393 | - temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0); | |
394 | - temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0); | |
395 | - dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); | |
396 | - } | |
397 | - mutex_unlock(&lp->indirect_mutex); | |
398 | -} | |
399 | - | |
400 | -struct temac_option { | |
401 | - int flg; | |
402 | - u32 opt; | |
403 | - u32 reg; | |
404 | - u32 m_or; | |
405 | - u32 m_and; | |
406 | -} temac_options[] = { | |
407 | - /* Turn on jumbo packet support for both Rx and Tx */ | |
408 | - { | |
409 | - .opt = XTE_OPTION_JUMBO, | |
410 | - .reg = XTE_TXC_OFFSET, | |
411 | - .m_or = XTE_TXC_TXJMBO_MASK, | |
412 | - }, | |
413 | - { | |
414 | - .opt = XTE_OPTION_JUMBO, | |
415 | - .reg = XTE_RXC1_OFFSET, | |
416 | - .m_or =XTE_RXC1_RXJMBO_MASK, | |
417 | - }, | |
418 | - /* Turn on VLAN packet support for both Rx and Tx */ | |
419 | - { | |
420 | - .opt = XTE_OPTION_VLAN, | |
421 | - .reg = XTE_TXC_OFFSET, | |
422 | - .m_or =XTE_TXC_TXVLAN_MASK, | |
423 | - }, | |
424 | - { | |
425 | - .opt = XTE_OPTION_VLAN, | |
426 | - .reg = XTE_RXC1_OFFSET, | |
427 | - .m_or =XTE_RXC1_RXVLAN_MASK, | |
428 | - }, | |
429 | - /* Turn on FCS stripping on receive packets */ | |
430 | - { | |
431 | - .opt = XTE_OPTION_FCS_STRIP, | |
432 | - .reg = XTE_RXC1_OFFSET, | |
433 | - .m_or =XTE_RXC1_RXFCS_MASK, | |
434 | - }, | |
435 | - /* Turn on FCS insertion on transmit packets */ | |
436 | - { | |
437 | - .opt = XTE_OPTION_FCS_INSERT, | |
438 | - .reg = XTE_TXC_OFFSET, | |
439 | - .m_or =XTE_TXC_TXFCS_MASK, | |
440 | - }, | |
441 | - /* Turn on length/type field checking on receive packets */ | |
442 | - { | |
443 | - .opt = XTE_OPTION_LENTYPE_ERR, | |
444 | - .reg = XTE_RXC1_OFFSET, | |
445 | - .m_or =XTE_RXC1_RXLT_MASK, | |
446 | - }, | |
447 | - /* Turn on flow control */ | |
448 | - { | |
449 | - .opt = XTE_OPTION_FLOW_CONTROL, | |
450 | - .reg = XTE_FCC_OFFSET, | |
451 | - .m_or =XTE_FCC_RXFLO_MASK, | |
452 | - }, | |
453 | - /* Turn on flow control */ | |
454 | - { | |
455 | - .opt = XTE_OPTION_FLOW_CONTROL, | |
456 | - .reg = XTE_FCC_OFFSET, | |
457 | - .m_or =XTE_FCC_TXFLO_MASK, | |
458 | - }, | |
459 | - /* Turn on promiscuous frame filtering (all frames are received ) */ | |
460 | - { | |
461 | - .opt = XTE_OPTION_PROMISC, | |
462 | - .reg = XTE_AFM_OFFSET, | |
463 | - .m_or =XTE_AFM_EPPRM_MASK, | |
464 | - }, | |
465 | - /* Enable transmitter if not already enabled */ | |
466 | - { | |
467 | - .opt = XTE_OPTION_TXEN, | |
468 | - .reg = XTE_TXC_OFFSET, | |
469 | - .m_or =XTE_TXC_TXEN_MASK, | |
470 | - }, | |
471 | - /* Enable receiver? */ | |
472 | - { | |
473 | - .opt = XTE_OPTION_RXEN, | |
474 | - .reg = XTE_RXC1_OFFSET, | |
475 | - .m_or =XTE_RXC1_RXEN_MASK, | |
476 | - }, | |
477 | - {} | |
478 | -}; | |
479 | - | |
480 | -/** | |
481 | - * temac_setoptions | |
482 | - */ | |
483 | -static u32 temac_setoptions(struct net_device *ndev, u32 options) | |
484 | -{ | |
485 | - struct temac_local *lp = netdev_priv(ndev); | |
486 | - struct temac_option *tp = &temac_options[0]; | |
487 | - int reg; | |
488 | - | |
489 | - mutex_lock(&lp->indirect_mutex); | |
490 | - while (tp->opt) { | |
491 | - reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or; | |
492 | - if (options & tp->opt) | |
493 | - reg |= tp->m_or; | |
494 | - temac_indirect_out32(lp, tp->reg, reg); | |
495 | - tp++; | |
496 | - } | |
497 | - lp->options |= options; | |
498 | - mutex_unlock(&lp->indirect_mutex); | |
499 | - | |
500 | - return 0; | |
501 | -} | |
502 | - | |
503 | -/* Initialize temac */ | |
504 | -static void temac_device_reset(struct net_device *ndev) | |
505 | -{ | |
506 | - struct temac_local *lp = netdev_priv(ndev); | |
507 | - u32 timeout; | |
508 | - u32 val; | |
509 | - | |
510 | - /* Perform a software reset */ | |
511 | - | |
512 | - /* 0x300 host enable bit ? */ | |
513 | - /* reset PHY through control register ?:1 */ | |
514 | - | |
515 | - dev_dbg(&ndev->dev, "%s()\n", __func__); | |
516 | - | |
517 | - mutex_lock(&lp->indirect_mutex); | |
518 | - /* Reset the receiver and wait for it to finish reset */ | |
519 | - temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK); | |
520 | - timeout = 1000; | |
521 | - while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) { | |
522 | - udelay(1); | |
523 | - if (--timeout == 0) { | |
524 | - dev_err(&ndev->dev, | |
525 | - "temac_device_reset RX reset timeout!!\n"); | |
526 | - break; | |
527 | - } | |
528 | - } | |
529 | - | |
530 | - /* Reset the transmitter and wait for it to finish reset */ | |
531 | - temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK); | |
532 | - timeout = 1000; | |
533 | - while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) { | |
534 | - udelay(1); | |
535 | - if (--timeout == 0) { | |
536 | - dev_err(&ndev->dev, | |
537 | - "temac_device_reset TX reset timeout!!\n"); | |
538 | - break; | |
539 | - } | |
540 | - } | |
541 | - | |
542 | - /* Disable the receiver */ | |
543 | - val = temac_indirect_in32(lp, XTE_RXC1_OFFSET); | |
544 | - temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); | |
545 | - | |
546 | - /* Reset Local Link (DMA) */ | |
547 | - lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); | |
548 | - timeout = 1000; | |
549 | - while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { | |
550 | - udelay(1); | |
551 | - if (--timeout == 0) { | |
552 | - dev_err(&ndev->dev, | |
553 | - "temac_device_reset DMA reset timeout!!\n"); | |
554 | - break; | |
555 | - } | |
556 | - } | |
557 | - lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); | |
558 | - | |
559 | - if (temac_dma_bd_init(ndev)) { | |
560 | - dev_err(&ndev->dev, | |
561 | - "temac_device_reset descriptor allocation failed\n"); | |
562 | - } | |
563 | - | |
564 | - temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0); | |
565 | - temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0); | |
566 | - temac_indirect_out32(lp, XTE_TXC_OFFSET, 0); | |
567 | - temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK); | |
568 | - | |
569 | - mutex_unlock(&lp->indirect_mutex); | |
570 | - | |
571 | - /* Sync default options with HW | |
572 | - * but leave receiver and transmitter disabled. */ | |
573 | - temac_setoptions(ndev, | |
574 | - lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN)); | |
575 | - | |
576 | - temac_set_mac_address(ndev, NULL); | |
577 | - | |
578 | - /* Set address filter table */ | |
579 | - temac_set_multicast_list(ndev); | |
580 | - if (temac_setoptions(ndev, lp->options)) | |
581 | - dev_err(&ndev->dev, "Error setting TEMAC options\n"); | |
582 | - | |
583 | - /* Init Driver variable */ | |
584 | - ndev->trans_start = jiffies; /* prevent tx timeout */ | |
585 | -} | |
586 | - | |
587 | -void temac_adjust_link(struct net_device *ndev) | |
588 | -{ | |
589 | - struct temac_local *lp = netdev_priv(ndev); | |
590 | - struct phy_device *phy = lp->phy_dev; | |
591 | - u32 mii_speed; | |
592 | - int link_state; | |
593 | - | |
594 | - /* hash together the state values to decide if something has changed */ | |
595 | - link_state = phy->speed | (phy->duplex << 1) | phy->link; | |
596 | - | |
597 | - mutex_lock(&lp->indirect_mutex); | |
598 | - if (lp->last_link != link_state) { | |
599 | - mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET); | |
600 | - mii_speed &= ~XTE_EMCFG_LINKSPD_MASK; | |
601 | - | |
602 | - switch (phy->speed) { | |
603 | - case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break; | |
604 | - case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break; | |
605 | - case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break; | |
606 | - } | |
607 | - | |
608 | - /* Write new speed setting out to TEMAC */ | |
609 | - temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed); | |
610 | - lp->last_link = link_state; | |
611 | - phy_print_status(phy); | |
612 | - } | |
613 | - mutex_unlock(&lp->indirect_mutex); | |
614 | -} | |
615 | - | |
616 | -static void temac_start_xmit_done(struct net_device *ndev) | |
617 | -{ | |
618 | - struct temac_local *lp = netdev_priv(ndev); | |
619 | - struct cdmac_bd *cur_p; | |
620 | - unsigned int stat = 0; | |
621 | - | |
622 | - cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; | |
623 | - stat = cur_p->app0; | |
624 | - | |
625 | - while (stat & STS_CTRL_APP0_CMPLT) { | |
626 | - dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len, | |
627 | - DMA_TO_DEVICE); | |
628 | - if (cur_p->app4) | |
629 | - dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); | |
630 | - cur_p->app0 = 0; | |
631 | - cur_p->app1 = 0; | |
632 | - cur_p->app2 = 0; | |
633 | - cur_p->app3 = 0; | |
634 | - cur_p->app4 = 0; | |
635 | - | |
636 | - ndev->stats.tx_packets++; | |
637 | - ndev->stats.tx_bytes += cur_p->len; | |
638 | - | |
639 | - lp->tx_bd_ci++; | |
640 | - if (lp->tx_bd_ci >= TX_BD_NUM) | |
641 | - lp->tx_bd_ci = 0; | |
642 | - | |
643 | - cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; | |
644 | - stat = cur_p->app0; | |
645 | - } | |
646 | - | |
647 | - netif_wake_queue(ndev); | |
648 | -} | |
649 | - | |
650 | -static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) | |
651 | -{ | |
652 | - struct cdmac_bd *cur_p; | |
653 | - int tail; | |
654 | - | |
655 | - tail = lp->tx_bd_tail; | |
656 | - cur_p = &lp->tx_bd_v[tail]; | |
657 | - | |
658 | - do { | |
659 | - if (cur_p->app0) | |
660 | - return NETDEV_TX_BUSY; | |
661 | - | |
662 | - tail++; | |
663 | - if (tail >= TX_BD_NUM) | |
664 | - tail = 0; | |
665 | - | |
666 | - cur_p = &lp->tx_bd_v[tail]; | |
667 | - num_frag--; | |
668 | - } while (num_frag >= 0); | |
669 | - | |
670 | - return 0; | |
671 | -} | |
672 | - | |
673 | -static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |
674 | -{ | |
675 | - struct temac_local *lp = netdev_priv(ndev); | |
676 | - struct cdmac_bd *cur_p; | |
677 | - dma_addr_t start_p, tail_p; | |
678 | - int ii; | |
679 | - unsigned long num_frag; | |
680 | - skb_frag_t *frag; | |
681 | - | |
682 | - num_frag = skb_shinfo(skb)->nr_frags; | |
683 | - frag = &skb_shinfo(skb)->frags[0]; | |
684 | - start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | |
685 | - cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | |
686 | - | |
687 | - if (temac_check_tx_bd_space(lp, num_frag)) { | |
688 | - if (!netif_queue_stopped(ndev)) { | |
689 | - netif_stop_queue(ndev); | |
690 | - return NETDEV_TX_BUSY; | |
691 | - } | |
692 | - return NETDEV_TX_BUSY; | |
693 | - } | |
694 | - | |
695 | - cur_p->app0 = 0; | |
696 | - if (skb->ip_summed == CHECKSUM_PARTIAL) { | |
697 | - unsigned int csum_start_off = skb_checksum_start_offset(skb); | |
698 | - unsigned int csum_index_off = csum_start_off + skb->csum_offset; | |
699 | - | |
700 | - cur_p->app0 |= 1; /* TX Checksum Enabled */ | |
701 | - cur_p->app1 = (csum_start_off << 16) | csum_index_off; | |
702 | - cur_p->app2 = 0; /* initial checksum seed */ | |
703 | - } | |
704 | - | |
705 | - cur_p->app0 |= STS_CTRL_APP0_SOP; | |
706 | - cur_p->len = skb_headlen(skb); | |
707 | - cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, | |
708 | - DMA_TO_DEVICE); | |
709 | - cur_p->app4 = (unsigned long)skb; | |
710 | - | |
711 | - for (ii = 0; ii < num_frag; ii++) { | |
712 | - lp->tx_bd_tail++; | |
713 | - if (lp->tx_bd_tail >= TX_BD_NUM) | |
714 | - lp->tx_bd_tail = 0; | |
715 | - | |
716 | - cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | |
717 | - cur_p->phys = dma_map_single(ndev->dev.parent, | |
718 | - (void *)page_address(frag->page) + | |
719 | - frag->page_offset, | |
720 | - frag->size, DMA_TO_DEVICE); | |
721 | - cur_p->len = frag->size; | |
722 | - cur_p->app0 = 0; | |
723 | - frag++; | |
724 | - } | |
725 | - cur_p->app0 |= STS_CTRL_APP0_EOP; | |
726 | - | |
727 | - tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | |
728 | - lp->tx_bd_tail++; | |
729 | - if (lp->tx_bd_tail >= TX_BD_NUM) | |
730 | - lp->tx_bd_tail = 0; | |
731 | - | |
732 | - skb_tx_timestamp(skb); | |
733 | - | |
734 | - /* Kick off the transfer */ | |
735 | - lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ | |
736 | - | |
737 | - return NETDEV_TX_OK; | |
738 | -} | |
739 | - | |
740 | - | |
741 | -static void ll_temac_recv(struct net_device *ndev) | |
742 | -{ | |
743 | - struct temac_local *lp = netdev_priv(ndev); | |
744 | - struct sk_buff *skb, *new_skb; | |
745 | - unsigned int bdstat; | |
746 | - struct cdmac_bd *cur_p; | |
747 | - dma_addr_t tail_p; | |
748 | - int length; | |
749 | - unsigned long flags; | |
750 | - | |
751 | - spin_lock_irqsave(&lp->rx_lock, flags); | |
752 | - | |
753 | - tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; | |
754 | - cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | |
755 | - | |
756 | - bdstat = cur_p->app0; | |
757 | - while ((bdstat & STS_CTRL_APP0_CMPLT)) { | |
758 | - | |
759 | - skb = lp->rx_skb[lp->rx_bd_ci]; | |
760 | - length = cur_p->app4 & 0x3FFF; | |
761 | - | |
762 | - dma_unmap_single(ndev->dev.parent, cur_p->phys, length, | |
763 | - DMA_FROM_DEVICE); | |
764 | - | |
765 | - skb_put(skb, length); | |
766 | - skb->dev = ndev; | |
767 | - skb->protocol = eth_type_trans(skb, ndev); | |
768 | - skb_checksum_none_assert(skb); | |
769 | - | |
770 | - /* if we're doing rx csum offload, set it up */ | |
771 | - if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && | |
772 | - (skb->protocol == __constant_htons(ETH_P_IP)) && | |
773 | - (skb->len > 64)) { | |
774 | - | |
775 | - skb->csum = cur_p->app3 & 0xFFFF; | |
776 | - skb->ip_summed = CHECKSUM_COMPLETE; | |
777 | - } | |
778 | - | |
779 | - if (!skb_defer_rx_timestamp(skb)) | |
780 | - netif_rx(skb); | |
781 | - | |
782 | - ndev->stats.rx_packets++; | |
783 | - ndev->stats.rx_bytes += length; | |
784 | - | |
785 | - new_skb = netdev_alloc_skb_ip_align(ndev, | |
786 | - XTE_MAX_JUMBO_FRAME_SIZE); | |
787 | - | |
788 | - if (new_skb == 0) { | |
789 | - dev_err(&ndev->dev, "no memory for new sk_buff\n"); | |
790 | - spin_unlock_irqrestore(&lp->rx_lock, flags); | |
791 | - return; | |
792 | - } | |
793 | - | |
794 | - cur_p->app0 = STS_CTRL_APP0_IRQONEND; | |
795 | - cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, | |
796 | - XTE_MAX_JUMBO_FRAME_SIZE, | |
797 | - DMA_FROM_DEVICE); | |
798 | - cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE; | |
799 | - lp->rx_skb[lp->rx_bd_ci] = new_skb; | |
800 | - | |
801 | - lp->rx_bd_ci++; | |
802 | - if (lp->rx_bd_ci >= RX_BD_NUM) | |
803 | - lp->rx_bd_ci = 0; | |
804 | - | |
805 | - cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | |
806 | - bdstat = cur_p->app0; | |
807 | - } | |
808 | - lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); | |
809 | - | |
810 | - spin_unlock_irqrestore(&lp->rx_lock, flags); | |
811 | -} | |
812 | - | |
813 | -static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) | |
814 | -{ | |
815 | - struct net_device *ndev = _ndev; | |
816 | - struct temac_local *lp = netdev_priv(ndev); | |
817 | - unsigned int status; | |
818 | - | |
819 | - status = lp->dma_in(lp, TX_IRQ_REG); | |
820 | - lp->dma_out(lp, TX_IRQ_REG, status); | |
821 | - | |
822 | - if (status & (IRQ_COAL | IRQ_DLY)) | |
823 | - temac_start_xmit_done(lp->ndev); | |
824 | - if (status & 0x080) | |
825 | - dev_err(&ndev->dev, "DMA error 0x%x\n", status); | |
826 | - | |
827 | - return IRQ_HANDLED; | |
828 | -} | |
829 | - | |
830 | -static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev) | |
831 | -{ | |
832 | - struct net_device *ndev = _ndev; | |
833 | - struct temac_local *lp = netdev_priv(ndev); | |
834 | - unsigned int status; | |
835 | - | |
836 | - /* Read and clear the status registers */ | |
837 | - status = lp->dma_in(lp, RX_IRQ_REG); | |
838 | - lp->dma_out(lp, RX_IRQ_REG, status); | |
839 | - | |
840 | - if (status & (IRQ_COAL | IRQ_DLY)) | |
841 | - ll_temac_recv(lp->ndev); | |
842 | - | |
843 | - return IRQ_HANDLED; | |
844 | -} | |
845 | - | |
846 | -static int temac_open(struct net_device *ndev) | |
847 | -{ | |
848 | - struct temac_local *lp = netdev_priv(ndev); | |
849 | - int rc; | |
850 | - | |
851 | - dev_dbg(&ndev->dev, "temac_open()\n"); | |
852 | - | |
853 | - if (lp->phy_node) { | |
854 | - lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, | |
855 | - temac_adjust_link, 0, 0); | |
856 | - if (!lp->phy_dev) { | |
857 | - dev_err(lp->dev, "of_phy_connect() failed\n"); | |
858 | - return -ENODEV; | |
859 | - } | |
860 | - | |
861 | - phy_start(lp->phy_dev); | |
862 | - } | |
863 | - | |
864 | - rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev); | |
865 | - if (rc) | |
866 | - goto err_tx_irq; | |
867 | - rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev); | |
868 | - if (rc) | |
869 | - goto err_rx_irq; | |
870 | - | |
871 | - temac_device_reset(ndev); | |
872 | - return 0; | |
873 | - | |
874 | - err_rx_irq: | |
875 | - free_irq(lp->tx_irq, ndev); | |
876 | - err_tx_irq: | |
877 | - if (lp->phy_dev) | |
878 | - phy_disconnect(lp->phy_dev); | |
879 | - lp->phy_dev = NULL; | |
880 | - dev_err(lp->dev, "request_irq() failed\n"); | |
881 | - return rc; | |
882 | -} | |
883 | - | |
884 | -static int temac_stop(struct net_device *ndev) | |
885 | -{ | |
886 | - struct temac_local *lp = netdev_priv(ndev); | |
887 | - | |
888 | - dev_dbg(&ndev->dev, "temac_close()\n"); | |
889 | - | |
890 | - free_irq(lp->tx_irq, ndev); | |
891 | - free_irq(lp->rx_irq, ndev); | |
892 | - | |
893 | - if (lp->phy_dev) | |
894 | - phy_disconnect(lp->phy_dev); | |
895 | - lp->phy_dev = NULL; | |
896 | - | |
897 | - temac_dma_bd_release(ndev); | |
898 | - | |
899 | - return 0; | |
900 | -} | |
901 | - | |
902 | -#ifdef CONFIG_NET_POLL_CONTROLLER | |
903 | -static void | |
904 | -temac_poll_controller(struct net_device *ndev) | |
905 | -{ | |
906 | - struct temac_local *lp = netdev_priv(ndev); | |
907 | - | |
908 | - disable_irq(lp->tx_irq); | |
909 | - disable_irq(lp->rx_irq); | |
910 | - | |
911 | - ll_temac_rx_irq(lp->tx_irq, ndev); | |
912 | - ll_temac_tx_irq(lp->rx_irq, ndev); | |
913 | - | |
914 | - enable_irq(lp->tx_irq); | |
915 | - enable_irq(lp->rx_irq); | |
916 | -} | |
917 | -#endif | |
918 | - | |
919 | -static const struct net_device_ops temac_netdev_ops = { | |
920 | - .ndo_open = temac_open, | |
921 | - .ndo_stop = temac_stop, | |
922 | - .ndo_start_xmit = temac_start_xmit, | |
923 | - .ndo_set_mac_address = netdev_set_mac_address, | |
924 | - .ndo_validate_addr = eth_validate_addr, | |
925 | - //.ndo_set_multicast_list = temac_set_multicast_list, | |
926 | -#ifdef CONFIG_NET_POLL_CONTROLLER | |
927 | - .ndo_poll_controller = temac_poll_controller, | |
928 | -#endif | |
929 | -}; | |
930 | - | |
931 | -/* --------------------------------------------------------------------- | |
932 | - * SYSFS device attributes | |
933 | - */ | |
934 | -static ssize_t temac_show_llink_regs(struct device *dev, | |
935 | - struct device_attribute *attr, char *buf) | |
936 | -{ | |
937 | - struct net_device *ndev = dev_get_drvdata(dev); | |
938 | - struct temac_local *lp = netdev_priv(ndev); | |
939 | - int i, len = 0; | |
940 | - | |
941 | - for (i = 0; i < 0x11; i++) | |
942 | - len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i), | |
943 | - (i % 8) == 7 ? "\n" : " "); | |
944 | - len += sprintf(buf + len, "\n"); | |
945 | - | |
946 | - return len; | |
947 | -} | |
948 | - | |
949 | -static DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL); | |
950 | - | |
951 | -static struct attribute *temac_device_attrs[] = { | |
952 | - &dev_attr_llink_regs.attr, | |
953 | - NULL, | |
954 | -}; | |
955 | - | |
956 | -static const struct attribute_group temac_attr_group = { | |
957 | - .attrs = temac_device_attrs, | |
958 | -}; | |
959 | - | |
960 | -static int __devinit temac_of_probe(struct platform_device *op) | |
961 | -{ | |
962 | - struct device_node *np; | |
963 | - struct temac_local *lp; | |
964 | - struct net_device *ndev; | |
965 | - const void *addr; | |
966 | - __be32 *p; | |
967 | - int size, rc = 0; | |
968 | - | |
969 | - /* Init network device structure */ | |
970 | - ndev = alloc_etherdev(sizeof(*lp)); | |
971 | - if (!ndev) { | |
972 | - dev_err(&op->dev, "could not allocate device.\n"); | |
973 | - return -ENOMEM; | |
974 | - } | |
975 | - ether_setup(ndev); | |
976 | - dev_set_drvdata(&op->dev, ndev); | |
977 | - SET_NETDEV_DEV(ndev, &op->dev); | |
978 | - ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ | |
979 | - ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; | |
980 | - ndev->netdev_ops = &temac_netdev_ops; | |
981 | -#if 0 | |
982 | - ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */ | |
983 | - ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */ | |
984 | - ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */ | |
985 | - ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */ | |
986 | - ndev->features |= NETIF_F_HW_VLAN_TX; /* Transmit VLAN hw accel */ | |
987 | - ndev->features |= NETIF_F_HW_VLAN_RX; /* Receive VLAN hw acceleration */ | |
988 | - ndev->features |= NETIF_F_HW_VLAN_FILTER; /* Receive VLAN filtering */ | |
989 | - ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */ | |
990 | - ndev->features |= NETIF_F_GSO; /* Enable software GSO. */ | |
991 | - ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */ | |
992 | - ndev->features |= NETIF_F_LRO; /* large receive offload */ | |
993 | -#endif | |
994 | - | |
995 | - /* setup temac private info structure */ | |
996 | - lp = netdev_priv(ndev); | |
997 | - lp->ndev = ndev; | |
998 | - lp->dev = &op->dev; | |
999 | - lp->options = XTE_OPTION_DEFAULTS; | |
1000 | - spin_lock_init(&lp->rx_lock); | |
1001 | - mutex_init(&lp->indirect_mutex); | |
1002 | - | |
1003 | - /* map device registers */ | |
1004 | - lp->regs = of_iomap(op->dev.of_node, 0); | |
1005 | - if (!lp->regs) { | |
1006 | - dev_err(&op->dev, "could not map temac regs.\n"); | |
1007 | - goto nodev; | |
1008 | - } | |
1009 | - | |
1010 | - /* Setup checksum offload, but default to off if not specified */ | |
1011 | - lp->temac_features = 0; | |
1012 | - p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); | |
1013 | - if (p && be32_to_cpu(*p)) { | |
1014 | - lp->temac_features |= TEMAC_FEATURE_TX_CSUM; | |
1015 | - /* Can checksum TCP/UDP over IPv4. */ | |
1016 | - ndev->features |= NETIF_F_IP_CSUM; | |
1017 | - } | |
1018 | - p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); | |
1019 | - if (p && be32_to_cpu(*p)) | |
1020 | - lp->temac_features |= TEMAC_FEATURE_RX_CSUM; | |
1021 | - | |
1022 | - /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ | |
1023 | - np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); | |
1024 | - if (!np) { | |
1025 | - dev_err(&op->dev, "could not find DMA node\n"); | |
1026 | - goto err_iounmap; | |
1027 | - } | |
1028 | - | |
1029 | - /* Setup the DMA register accesses, could be DCR or memory mapped */ | |
1030 | - if (temac_dcr_setup(lp, op, np)) { | |
1031 | - | |
1032 | - /* no DCR in the device tree, try non-DCR */ | |
1033 | - lp->sdma_regs = of_iomap(np, 0); | |
1034 | - if (lp->sdma_regs) { | |
1035 | - lp->dma_in = temac_dma_in32; | |
1036 | - lp->dma_out = temac_dma_out32; | |
1037 | - dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs); | |
1038 | - } else { | |
1039 | - dev_err(&op->dev, "unable to map DMA registers\n"); | |
1040 | - of_node_put(np); | |
1041 | - goto err_iounmap; | |
1042 | - } | |
1043 | - } | |
1044 | - | |
1045 | - lp->rx_irq = irq_of_parse_and_map(np, 0); | |
1046 | - lp->tx_irq = irq_of_parse_and_map(np, 1); | |
1047 | - | |
1048 | - of_node_put(np); /* Finished with the DMA node; drop the reference */ | |
1049 | - | |
1050 | - if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { | |
1051 | - dev_err(&op->dev, "could not determine irqs\n"); | |
1052 | - rc = -ENOMEM; | |
1053 | - goto err_iounmap_2; | |
1054 | - } | |
1055 | - | |
1056 | - | |
1057 | - /* Retrieve the MAC address */ | |
1058 | - addr = of_get_property(op->dev.of_node, "local-mac-address", &size); | |
1059 | - if ((!addr) || (size != 6)) { | |
1060 | - dev_err(&op->dev, "could not find MAC address\n"); | |
1061 | - rc = -ENODEV; | |
1062 | - goto err_iounmap_2; | |
1063 | - } | |
1064 | - temac_set_mac_address(ndev, (void *)addr); | |
1065 | - | |
1066 | - rc = temac_mdio_setup(lp, op->dev.of_node); | |
1067 | - if (rc) | |
1068 | - dev_warn(&op->dev, "error registering MDIO bus\n"); | |
1069 | - | |
1070 | - lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); | |
1071 | - if (lp->phy_node) | |
1072 | - dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np); | |
1073 | - | |
1074 | - /* Add the device attributes */ | |
1075 | - rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group); | |
1076 | - if (rc) { | |
1077 | - dev_err(lp->dev, "Error creating sysfs files\n"); | |
1078 | - goto err_iounmap_2; | |
1079 | - } | |
1080 | - | |
1081 | - rc = register_netdev(lp->ndev); | |
1082 | - if (rc) { | |
1083 | - dev_err(lp->dev, "register_netdev() error (%i)\n", rc); | |
1084 | - goto err_register_ndev; | |
1085 | - } | |
1086 | - | |
1087 | - return 0; | |
1088 | - | |
1089 | - err_register_ndev: | |
1090 | - sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); | |
1091 | - err_iounmap_2: | |
1092 | - if (lp->sdma_regs) | |
1093 | - iounmap(lp->sdma_regs); | |
1094 | - err_iounmap: | |
1095 | - iounmap(lp->regs); | |
1096 | - nodev: | |
1097 | - free_netdev(ndev); | |
1098 | - ndev = NULL; | |
1099 | - return rc; | |
1100 | -} | |
1101 | - | |
1102 | -static int __devexit temac_of_remove(struct platform_device *op) | |
1103 | -{ | |
1104 | - struct net_device *ndev = dev_get_drvdata(&op->dev); | |
1105 | - struct temac_local *lp = netdev_priv(ndev); | |
1106 | - | |
1107 | - temac_mdio_teardown(lp); | |
1108 | - unregister_netdev(ndev); | |
1109 | - sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); | |
1110 | - if (lp->phy_node) | |
1111 | - of_node_put(lp->phy_node); | |
1112 | - lp->phy_node = NULL; | |
1113 | - dev_set_drvdata(&op->dev, NULL); | |
1114 | - iounmap(lp->regs); | |
1115 | - if (lp->sdma_regs) | |
1116 | - iounmap(lp->sdma_regs); | |
1117 | - free_netdev(ndev); | |
1118 | - return 0; | |
1119 | -} | |
1120 | - | |
1121 | -static struct of_device_id temac_of_match[] __devinitdata = { | |
1122 | - { .compatible = "xlnx,xps-ll-temac-1.01.b", }, | |
1123 | - { .compatible = "xlnx,xps-ll-temac-2.00.a", }, | |
1124 | - { .compatible = "xlnx,xps-ll-temac-2.02.a", }, | |
1125 | - { .compatible = "xlnx,xps-ll-temac-2.03.a", }, | |
1126 | - {}, | |
1127 | -}; | |
1128 | -MODULE_DEVICE_TABLE(of, temac_of_match); | |
1129 | - | |
1130 | -static struct platform_driver temac_of_driver = { | |
1131 | - .probe = temac_of_probe, | |
1132 | - .remove = __devexit_p(temac_of_remove), | |
1133 | - .driver = { | |
1134 | - .owner = THIS_MODULE, | |
1135 | - .name = "xilinx_temac", | |
1136 | - .of_match_table = temac_of_match, | |
1137 | - }, | |
1138 | -}; | |
1139 | - | |
1140 | -static int __init temac_init(void) | |
1141 | -{ | |
1142 | - return platform_driver_register(&temac_of_driver); | |
1143 | -} | |
1144 | -module_init(temac_init); | |
1145 | - | |
1146 | -static void __exit temac_exit(void) | |
1147 | -{ | |
1148 | - platform_driver_unregister(&temac_of_driver); | |
1149 | -} | |
1150 | -module_exit(temac_exit); | |
1151 | - | |
1152 | -MODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver"); | |
1153 | -MODULE_AUTHOR("Yoshio Kashiwagi"); | |
1154 | -MODULE_LICENSE("GPL"); |
drivers/net/ll_temac_mdio.c
1 | -/* | |
2 | - * MDIO bus driver for the Xilinx TEMAC device | |
3 | - * | |
4 | - * Copyright (c) 2009 Secret Lab Technologies, Ltd. | |
5 | - */ | |
6 | - | |
7 | -#include <linux/io.h> | |
8 | -#include <linux/netdevice.h> | |
9 | -#include <linux/mutex.h> | |
10 | -#include <linux/phy.h> | |
11 | -#include <linux/of.h> | |
12 | -#include <linux/of_device.h> | |
13 | -#include <linux/of_address.h> | |
14 | -#include <linux/slab.h> | |
15 | -#include <linux/of_mdio.h> | |
16 | - | |
17 | -#include "ll_temac.h" | |
18 | - | |
19 | -/* --------------------------------------------------------------------- | |
20 | - * MDIO Bus functions | |
21 | - */ | |
22 | -static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg) | |
23 | -{ | |
24 | - struct temac_local *lp = bus->priv; | |
25 | - u32 rc; | |
26 | - | |
27 | - /* Write the PHY address to the MIIM Access Initiator register. | |
28 | - * When the transfer completes, the PHY register value will appear | |
29 | - * in the LSW0 register */ | |
30 | - mutex_lock(&lp->indirect_mutex); | |
31 | - temac_iow(lp, XTE_LSW0_OFFSET, (phy_id << 5) | reg); | |
32 | - rc = temac_indirect_in32(lp, XTE_MIIMAI_OFFSET); | |
33 | - mutex_unlock(&lp->indirect_mutex); | |
34 | - | |
35 | - dev_dbg(lp->dev, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n", | |
36 | - phy_id, reg, rc); | |
37 | - | |
38 | - return rc; | |
39 | -} | |
40 | - | |
41 | -static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val) | |
42 | -{ | |
43 | - struct temac_local *lp = bus->priv; | |
44 | - | |
45 | - dev_dbg(lp->dev, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n", | |
46 | - phy_id, reg, val); | |
47 | - | |
48 | - /* First write the desired value into the write data register | |
49 | - * and then write the address into the access initiator register | |
50 | - */ | |
51 | - mutex_lock(&lp->indirect_mutex); | |
52 | - temac_indirect_out32(lp, XTE_MGTDR_OFFSET, val); | |
53 | - temac_indirect_out32(lp, XTE_MIIMAI_OFFSET, (phy_id << 5) | reg); | |
54 | - mutex_unlock(&lp->indirect_mutex); | |
55 | - | |
56 | - return 0; | |
57 | -} | |
58 | - | |
59 | -int temac_mdio_setup(struct temac_local *lp, struct device_node *np) | |
60 | -{ | |
61 | - struct mii_bus *bus; | |
62 | - const u32 *bus_hz; | |
63 | - int clk_div; | |
64 | - int rc, size; | |
65 | - struct resource res; | |
66 | - | |
67 | - /* Calculate a reasonable divisor for the clock rate */ | |
68 | - clk_div = 0x3f; /* worst-case default setting */ | |
69 | - bus_hz = of_get_property(np, "clock-frequency", &size); | |
70 | - if (bus_hz && size >= sizeof(*bus_hz)) { | |
71 | - clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1; | |
72 | - if (clk_div < 1) | |
73 | - clk_div = 1; | |
74 | - if (clk_div > 0x3f) | |
75 | - clk_div = 0x3f; | |
76 | - } | |
77 | - | |
78 | - /* Enable the MDIO bus by asserting the enable bit and writing | |
79 | - * in the clock config */ | |
80 | - mutex_lock(&lp->indirect_mutex); | |
81 | - temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div); | |
82 | - mutex_unlock(&lp->indirect_mutex); | |
83 | - | |
84 | - bus = mdiobus_alloc(); | |
85 | - if (!bus) | |
86 | - return -ENOMEM; | |
87 | - | |
88 | - of_address_to_resource(np, 0, &res); | |
89 | - snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", | |
90 | - (unsigned long long)res.start); | |
91 | - bus->priv = lp; | |
92 | - bus->name = "Xilinx TEMAC MDIO"; | |
93 | - bus->read = temac_mdio_read; | |
94 | - bus->write = temac_mdio_write; | |
95 | - bus->parent = lp->dev; | |
96 | - bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ | |
97 | - | |
98 | - lp->mii_bus = bus; | |
99 | - | |
100 | - rc = of_mdiobus_register(bus, np); | |
101 | - if (rc) | |
102 | - goto err_register; | |
103 | - | |
104 | - mutex_lock(&lp->indirect_mutex); | |
105 | - dev_dbg(lp->dev, "MDIO bus registered; MC:%x\n", | |
106 | - temac_indirect_in32(lp, XTE_MC_OFFSET)); | |
107 | - mutex_unlock(&lp->indirect_mutex); | |
108 | - return 0; | |
109 | - | |
110 | - err_register: | |
111 | - mdiobus_free(bus); | |
112 | - return rc; | |
113 | -} | |
114 | - | |
115 | -void temac_mdio_teardown(struct temac_local *lp) | |
116 | -{ | |
117 | - mdiobus_unregister(lp->mii_bus); | |
118 | - kfree(lp->mii_bus->irq); | |
119 | - mdiobus_free(lp->mii_bus); | |
120 | - lp->mii_bus = NULL; | |
121 | -} |
drivers/net/xilinx_emaclite.c
Changes suppressed. Click to show
1 | -/* | |
2 | - * Xilinx EmacLite Linux driver for the Xilinx Ethernet MAC Lite device. | |
3 | - * | |
4 | - * This is a new flat driver which is based on the original emac_lite | |
5 | - * driver from John Williams <john.williams@petalogix.com>. | |
6 | - * | |
7 | - * 2007-2009 (c) Xilinx, Inc. | |
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 as published by the | |
11 | - * Free Software Foundation; either version 2 of the License, or (at your | |
12 | - * option) any later version. | |
13 | - */ | |
14 | - | |
15 | -#include <linux/module.h> | |
16 | -#include <linux/uaccess.h> | |
17 | -#include <linux/init.h> | |
18 | -#include <linux/netdevice.h> | |
19 | -#include <linux/etherdevice.h> | |
20 | -#include <linux/skbuff.h> | |
21 | -#include <linux/io.h> | |
22 | -#include <linux/slab.h> | |
23 | -#include <linux/of_address.h> | |
24 | -#include <linux/of_device.h> | |
25 | -#include <linux/of_platform.h> | |
26 | -#include <linux/of_mdio.h> | |
27 | -#include <linux/of_net.h> | |
28 | -#include <linux/phy.h> | |
29 | -#include <linux/interrupt.h> | |
30 | - | |
31 | -#define DRIVER_NAME "xilinx_emaclite" | |
32 | - | |
33 | -/* Register offsets for the EmacLite Core */ | |
34 | -#define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ | |
35 | -#define XEL_MDIOADDR_OFFSET 0x07E4 /* MDIO Address Register */ | |
36 | -#define XEL_MDIOWR_OFFSET 0x07E8 /* MDIO Write Data Register */ | |
37 | -#define XEL_MDIORD_OFFSET 0x07EC /* MDIO Read Data Register */ | |
38 | -#define XEL_MDIOCTRL_OFFSET 0x07F0 /* MDIO Control Register */ | |
39 | -#define XEL_GIER_OFFSET 0x07F8 /* GIE Register */ | |
40 | -#define XEL_TSR_OFFSET 0x07FC /* Tx status */ | |
41 | -#define XEL_TPLR_OFFSET 0x07F4 /* Tx packet length */ | |
42 | - | |
43 | -#define XEL_RXBUFF_OFFSET 0x1000 /* Receive Buffer */ | |
44 | -#define XEL_RPLR_OFFSET 0x100C /* Rx packet length */ | |
45 | -#define XEL_RSR_OFFSET 0x17FC /* Rx status */ | |
46 | - | |
47 | -#define XEL_BUFFER_OFFSET 0x0800 /* Next Tx/Rx buffer's offset */ | |
48 | - | |
49 | -/* MDIO Address Register Bit Masks */ | |
50 | -#define XEL_MDIOADDR_REGADR_MASK 0x0000001F /* Register Address */ | |
51 | -#define XEL_MDIOADDR_PHYADR_MASK 0x000003E0 /* PHY Address */ | |
52 | -#define XEL_MDIOADDR_PHYADR_SHIFT 5 | |
53 | -#define XEL_MDIOADDR_OP_MASK 0x00000400 /* RD/WR Operation */ | |
54 | - | |
55 | -/* MDIO Write Data Register Bit Masks */ | |
56 | -#define XEL_MDIOWR_WRDATA_MASK 0x0000FFFF /* Data to be Written */ | |
57 | - | |
58 | -/* MDIO Read Data Register Bit Masks */ | |
59 | -#define XEL_MDIORD_RDDATA_MASK 0x0000FFFF /* Data to be Read */ | |
60 | - | |
61 | -/* MDIO Control Register Bit Masks */ | |
62 | -#define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001 /* MDIO Status Mask */ | |
63 | -#define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */ | |
64 | - | |
65 | -/* Global Interrupt Enable Register (GIER) Bit Masks */ | |
66 | -#define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ | |
67 | - | |
68 | -/* Transmit Status Register (TSR) Bit Masks */ | |
69 | -#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /* Tx complete */ | |
70 | -#define XEL_TSR_PROGRAM_MASK 0x00000002 /* Program the MAC address */ | |
71 | -#define XEL_TSR_XMIT_IE_MASK 0x00000008 /* Tx interrupt enable bit */ | |
72 | -#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /* Buffer is active, SW bit | |
73 | - * only. This is not documented | |
74 | - * in the HW spec */ | |
75 | - | |
76 | -/* Define for programming the MAC address into the EmacLite */ | |
77 | -#define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK) | |
78 | - | |
79 | -/* Receive Status Register (RSR) */ | |
80 | -#define XEL_RSR_RECV_DONE_MASK 0x00000001 /* Rx complete */ | |
81 | -#define XEL_RSR_RECV_IE_MASK 0x00000008 /* Rx interrupt enable bit */ | |
82 | - | |
83 | -/* Transmit Packet Length Register (TPLR) */ | |
84 | -#define XEL_TPLR_LENGTH_MASK 0x0000FFFF /* Tx packet length */ | |
85 | - | |
86 | -/* Receive Packet Length Register (RPLR) */ | |
87 | -#define XEL_RPLR_LENGTH_MASK 0x0000FFFF /* Rx packet length */ | |
88 | - | |
89 | -#define XEL_HEADER_OFFSET 12 /* Offset to length field */ | |
90 | -#define XEL_HEADER_SHIFT 16 /* Shift value for length */ | |
91 | - | |
92 | -/* General Ethernet Definitions */ | |
93 | -#define XEL_ARP_PACKET_SIZE 28 /* Max ARP packet size */ | |
94 | -#define XEL_HEADER_IP_LENGTH_OFFSET 16 /* IP Length Offset */ | |
95 | - | |
96 | - | |
97 | - | |
98 | -#define TX_TIMEOUT (60*HZ) /* Tx timeout is 60 seconds. */ | |
99 | -#define ALIGNMENT 4 | |
100 | - | |
101 | -/* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */ | |
102 | -#define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT) | |
103 | - | |
104 | -/** | |
105 | - * struct net_local - Our private per device data | |
106 | - * @ndev: instance of the network device | |
107 | - * @tx_ping_pong: indicates whether Tx Pong buffer is configured in HW | |
108 | - * @rx_ping_pong: indicates whether Rx Pong buffer is configured in HW | |
109 | - * @next_tx_buf_to_use: next Tx buffer to write to | |
110 | - * @next_rx_buf_to_use: next Rx buffer to read from | |
111 | - * @base_addr: base address of the Emaclite device | |
112 | - * @reset_lock: lock used for synchronization | |
113 | - * @deferred_skb: holds an skb (for transmission at a later time) when the | |
114 | - * Tx buffer is not free | |
115 | - * @phy_dev: pointer to the PHY device | |
116 | - * @phy_node: pointer to the PHY device node | |
117 | - * @mii_bus: pointer to the MII bus | |
118 | - * @mdio_irqs: IRQs table for MDIO bus | |
119 | - * @last_link: last link status | |
120 | - * @has_mdio: indicates whether MDIO is included in the HW | |
121 | - */ | |
122 | -struct net_local { | |
123 | - | |
124 | - struct net_device *ndev; | |
125 | - | |
126 | - bool tx_ping_pong; | |
127 | - bool rx_ping_pong; | |
128 | - u32 next_tx_buf_to_use; | |
129 | - u32 next_rx_buf_to_use; | |
130 | - void __iomem *base_addr; | |
131 | - | |
132 | - spinlock_t reset_lock; | |
133 | - struct sk_buff *deferred_skb; | |
134 | - | |
135 | - struct phy_device *phy_dev; | |
136 | - struct device_node *phy_node; | |
137 | - | |
138 | - struct mii_bus *mii_bus; | |
139 | - int mdio_irqs[PHY_MAX_ADDR]; | |
140 | - | |
141 | - int last_link; | |
142 | - bool has_mdio; | |
143 | -}; | |
144 | - | |
145 | - | |
146 | -/*************************/ | |
147 | -/* EmacLite driver calls */ | |
148 | -/*************************/ | |
149 | - | |
150 | -/** | |
151 | - * xemaclite_enable_interrupts - Enable the interrupts for the EmacLite device | |
152 | - * @drvdata: Pointer to the Emaclite device private data | |
153 | - * | |
154 | - * This function enables the Tx and Rx interrupts for the Emaclite device along | |
155 | - * with the Global Interrupt Enable. | |
156 | - */ | |
157 | -static void xemaclite_enable_interrupts(struct net_local *drvdata) | |
158 | -{ | |
159 | - u32 reg_data; | |
160 | - | |
161 | - /* Enable the Tx interrupts for the first Buffer */ | |
162 | - reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET); | |
163 | - out_be32(drvdata->base_addr + XEL_TSR_OFFSET, | |
164 | - reg_data | XEL_TSR_XMIT_IE_MASK); | |
165 | - | |
166 | - /* Enable the Tx interrupts for the second Buffer if | |
167 | - * configured in HW */ | |
168 | - if (drvdata->tx_ping_pong != 0) { | |
169 | - reg_data = in_be32(drvdata->base_addr + | |
170 | - XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); | |
171 | - out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
172 | - XEL_TSR_OFFSET, | |
173 | - reg_data | XEL_TSR_XMIT_IE_MASK); | |
174 | - } | |
175 | - | |
176 | - /* Enable the Rx interrupts for the first buffer */ | |
177 | - out_be32(drvdata->base_addr + XEL_RSR_OFFSET, | |
178 | - XEL_RSR_RECV_IE_MASK); | |
179 | - | |
180 | - /* Enable the Rx interrupts for the second Buffer if | |
181 | - * configured in HW */ | |
182 | - if (drvdata->rx_ping_pong != 0) { | |
183 | - out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
184 | - XEL_RSR_OFFSET, | |
185 | - XEL_RSR_RECV_IE_MASK); | |
186 | - } | |
187 | - | |
188 | - /* Enable the Global Interrupt Enable */ | |
189 | - out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK); | |
190 | -} | |
191 | - | |
192 | -/** | |
193 | - * xemaclite_disable_interrupts - Disable the interrupts for the EmacLite device | |
194 | - * @drvdata: Pointer to the Emaclite device private data | |
195 | - * | |
196 | - * This function disables the Tx and Rx interrupts for the Emaclite device, | |
197 | - * along with the Global Interrupt Enable. | |
198 | - */ | |
199 | -static void xemaclite_disable_interrupts(struct net_local *drvdata) | |
200 | -{ | |
201 | - u32 reg_data; | |
202 | - | |
203 | - /* Disable the Global Interrupt Enable */ | |
204 | - out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK); | |
205 | - | |
206 | - /* Disable the Tx interrupts for the first buffer */ | |
207 | - reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET); | |
208 | - out_be32(drvdata->base_addr + XEL_TSR_OFFSET, | |
209 | - reg_data & (~XEL_TSR_XMIT_IE_MASK)); | |
210 | - | |
211 | - /* Disable the Tx interrupts for the second Buffer | |
212 | - * if configured in HW */ | |
213 | - if (drvdata->tx_ping_pong != 0) { | |
214 | - reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
215 | - XEL_TSR_OFFSET); | |
216 | - out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
217 | - XEL_TSR_OFFSET, | |
218 | - reg_data & (~XEL_TSR_XMIT_IE_MASK)); | |
219 | - } | |
220 | - | |
221 | - /* Disable the Rx interrupts for the first buffer */ | |
222 | - reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET); | |
223 | - out_be32(drvdata->base_addr + XEL_RSR_OFFSET, | |
224 | - reg_data & (~XEL_RSR_RECV_IE_MASK)); | |
225 | - | |
226 | - /* Disable the Rx interrupts for the second buffer | |
227 | - * if configured in HW */ | |
228 | - if (drvdata->rx_ping_pong != 0) { | |
229 | - | |
230 | - reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
231 | - XEL_RSR_OFFSET); | |
232 | - out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + | |
233 | - XEL_RSR_OFFSET, | |
234 | - reg_data & (~XEL_RSR_RECV_IE_MASK)); | |
235 | - } | |
236 | -} | |
237 | - | |
238 | -/** | |
239 | - * xemaclite_aligned_write - Write from 16-bit aligned to 32-bit aligned address | |
240 | - * @src_ptr: Void pointer to the 16-bit aligned source address | |
241 | - * @dest_ptr: Pointer to the 32-bit aligned destination address | |
242 | - * @length: Number bytes to write from source to destination | |
243 | - * | |
244 | - * This function writes data from a 16-bit aligned buffer to a 32-bit aligned | |
245 | - * address in the EmacLite device. | |
246 | - */ | |
247 | -static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr, | |
248 | - unsigned length) | |
249 | -{ | |
250 | - u32 align_buffer; | |
251 | - u32 *to_u32_ptr; | |
252 | - u16 *from_u16_ptr, *to_u16_ptr; | |
253 | - | |
254 | - to_u32_ptr = dest_ptr; | |
255 | - from_u16_ptr = src_ptr; | |
256 | - align_buffer = 0; | |
257 | - | |
258 | - for (; length > 3; length -= 4) { | |
259 | - to_u16_ptr = (u16 *)&align_buffer; | |
260 | - *to_u16_ptr++ = *from_u16_ptr++; | |
261 | - *to_u16_ptr++ = *from_u16_ptr++; | |
262 | - | |
263 | - /* Output a word */ | |
264 | - *to_u32_ptr++ = align_buffer; | |
265 | - } | |
266 | - if (length) { | |
267 | - u8 *from_u8_ptr, *to_u8_ptr; | |
268 | - | |
269 | - /* Set up to output the remaining data */ | |
270 | - align_buffer = 0; | |
271 | - to_u8_ptr = (u8 *) &align_buffer; | |
272 | - from_u8_ptr = (u8 *) from_u16_ptr; | |
273 | - | |
274 | - /* Output the remaining data */ | |
275 | - for (; length > 0; length--) | |
276 | - *to_u8_ptr++ = *from_u8_ptr++; | |
277 | - | |
278 | - *to_u32_ptr = align_buffer; | |
279 | - } | |
280 | -} | |
281 | - | |
282 | -/** | |
283 | - * xemaclite_aligned_read - Read from 32-bit aligned to 16-bit aligned buffer | |
284 | - * @src_ptr: Pointer to the 32-bit aligned source address | |
285 | - * @dest_ptr: Pointer to the 16-bit aligned destination address | |
286 | - * @length: Number bytes to read from source to destination | |
287 | - * | |
288 | - * This function reads data from a 32-bit aligned address in the EmacLite device | |
289 | - * to a 16-bit aligned buffer. | |
290 | - */ | |
291 | -static void xemaclite_aligned_read(u32 *src_ptr, u8 *dest_ptr, | |
292 | - unsigned length) | |
293 | -{ | |
294 | - u16 *to_u16_ptr, *from_u16_ptr; | |
295 | - u32 *from_u32_ptr; | |
296 | - u32 align_buffer; | |
297 | - | |
298 | - from_u32_ptr = src_ptr; | |
299 | - to_u16_ptr = (u16 *) dest_ptr; | |
300 | - | |
301 | - for (; length > 3; length -= 4) { | |
302 | - /* Copy each word into the temporary buffer */ | |
303 | - align_buffer = *from_u32_ptr++; | |
304 | - from_u16_ptr = (u16 *)&align_buffer; | |
305 | - | |
306 | - /* Read data from source */ | |
307 | - *to_u16_ptr++ = *from_u16_ptr++; | |
308 | - *to_u16_ptr++ = *from_u16_ptr++; | |
309 | - } | |
310 | - | |
311 | - if (length) { | |
312 | - u8 *to_u8_ptr, *from_u8_ptr; | |
313 | - | |
314 | - /* Set up to read the remaining data */ | |
315 | - to_u8_ptr = (u8 *) to_u16_ptr; | |
316 | - align_buffer = *from_u32_ptr++; | |
317 | - from_u8_ptr = (u8 *) &align_buffer; | |
318 | - | |
319 | - /* Read the remaining data */ | |
320 | - for (; length > 0; length--) | |
321 | - *to_u8_ptr = *from_u8_ptr; | |
322 | - } | |
323 | -} | |
324 | - | |
325 | -/** | |
326 | - * xemaclite_send_data - Send an Ethernet frame | |
327 | - * @drvdata: Pointer to the Emaclite device private data | |
328 | - * @data: Pointer to the data to be sent | |
329 | - * @byte_count: Total frame size, including header | |
330 | - * | |
331 | - * This function checks if the Tx buffer of the Emaclite device is free to send | |
332 | - * data. If so, it fills the Tx buffer with data for transmission. Otherwise, it | |
333 | - * returns an error. | |
334 | - * | |
335 | - * Return: 0 upon success or -1 if the buffer(s) are full. | |
336 | - * | |
337 | - * Note: The maximum Tx packet size can not be more than Ethernet header | |
338 | - * (14 Bytes) + Maximum MTU (1500 bytes). This is excluding FCS. | |
339 | - */ | |
340 | -static int xemaclite_send_data(struct net_local *drvdata, u8 *data, | |
341 | - unsigned int byte_count) | |
342 | -{ | |
343 | - u32 reg_data; | |
344 | - void __iomem *addr; | |
345 | - | |
346 | - /* Determine the expected Tx buffer address */ | |
347 | - addr = drvdata->base_addr + drvdata->next_tx_buf_to_use; | |
348 | - | |
349 | - /* If the length is too large, truncate it */ | |
350 | - if (byte_count > ETH_FRAME_LEN) | |
351 | - byte_count = ETH_FRAME_LEN; | |
352 | - | |
353 | - /* Check if the expected buffer is available */ | |
354 | - reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
355 | - if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | | |
356 | - XEL_TSR_XMIT_ACTIVE_MASK)) == 0) { | |
357 | - | |
358 | - /* Switch to next buffer if configured */ | |
359 | - if (drvdata->tx_ping_pong != 0) | |
360 | - drvdata->next_tx_buf_to_use ^= XEL_BUFFER_OFFSET; | |
361 | - } else if (drvdata->tx_ping_pong != 0) { | |
362 | - /* If the expected buffer is full, try the other buffer, | |
363 | - * if it is configured in HW */ | |
364 | - | |
365 | - addr = (void __iomem __force *)((u32 __force)addr ^ | |
366 | - XEL_BUFFER_OFFSET); | |
367 | - reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
368 | - | |
369 | - if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | | |
370 | - XEL_TSR_XMIT_ACTIVE_MASK)) != 0) | |
371 | - return -1; /* Buffers were full, return failure */ | |
372 | - } else | |
373 | - return -1; /* Buffer was full, return failure */ | |
374 | - | |
375 | - /* Write the frame to the buffer */ | |
376 | - xemaclite_aligned_write(data, (u32 __force *) addr, byte_count); | |
377 | - | |
378 | - out_be32(addr + XEL_TPLR_OFFSET, (byte_count & XEL_TPLR_LENGTH_MASK)); | |
379 | - | |
380 | - /* Update the Tx Status Register to indicate that there is a | |
381 | - * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which | |
382 | - * is used by the interrupt handler to check whether a frame | |
383 | - * has been transmitted */ | |
384 | - reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
385 | - reg_data |= (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK); | |
386 | - out_be32(addr + XEL_TSR_OFFSET, reg_data); | |
387 | - | |
388 | - return 0; | |
389 | -} | |
390 | - | |
391 | -/** | |
392 | - * xemaclite_recv_data - Receive a frame | |
393 | - * @drvdata: Pointer to the Emaclite device private data | |
394 | - * @data: Address where the data is to be received | |
395 | - * | |
396 | - * This function is intended to be called from the interrupt context or | |
397 | - * with a wrapper which waits for the receive frame to be available. | |
398 | - * | |
399 | - * Return: Total number of bytes received | |
400 | - */ | |
401 | -static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) | |
402 | -{ | |
403 | - void __iomem *addr; | |
404 | - u16 length, proto_type; | |
405 | - u32 reg_data; | |
406 | - | |
407 | - /* Determine the expected buffer address */ | |
408 | - addr = (drvdata->base_addr + drvdata->next_rx_buf_to_use); | |
409 | - | |
410 | - /* Verify which buffer has valid data */ | |
411 | - reg_data = in_be32(addr + XEL_RSR_OFFSET); | |
412 | - | |
413 | - if ((reg_data & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) { | |
414 | - if (drvdata->rx_ping_pong != 0) | |
415 | - drvdata->next_rx_buf_to_use ^= XEL_BUFFER_OFFSET; | |
416 | - } else { | |
417 | - /* The instance is out of sync, try other buffer if other | |
418 | - * buffer is configured, return 0 otherwise. If the instance is | |
419 | - * out of sync, do not update the 'next_rx_buf_to_use' since it | |
420 | - * will correct on subsequent calls */ | |
421 | - if (drvdata->rx_ping_pong != 0) | |
422 | - addr = (void __iomem __force *)((u32 __force)addr ^ | |
423 | - XEL_BUFFER_OFFSET); | |
424 | - else | |
425 | - return 0; /* No data was available */ | |
426 | - | |
427 | - /* Verify that buffer has valid data */ | |
428 | - reg_data = in_be32(addr + XEL_RSR_OFFSET); | |
429 | - if ((reg_data & XEL_RSR_RECV_DONE_MASK) != | |
430 | - XEL_RSR_RECV_DONE_MASK) | |
431 | - return 0; /* No data was available */ | |
432 | - } | |
433 | - | |
434 | - /* Get the protocol type of the ethernet frame that arrived */ | |
435 | - proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET + | |
436 | - XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & | |
437 | - XEL_RPLR_LENGTH_MASK); | |
438 | - | |
439 | - /* Check if received ethernet frame is a raw ethernet frame | |
440 | - * or an IP packet or an ARP packet */ | |
441 | - if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) { | |
442 | - | |
443 | - if (proto_type == ETH_P_IP) { | |
444 | - length = ((ntohl(in_be32(addr + | |
445 | - XEL_HEADER_IP_LENGTH_OFFSET + | |
446 | - XEL_RXBUFF_OFFSET)) >> | |
447 | - XEL_HEADER_SHIFT) & | |
448 | - XEL_RPLR_LENGTH_MASK); | |
449 | - length += ETH_HLEN + ETH_FCS_LEN; | |
450 | - | |
451 | - } else if (proto_type == ETH_P_ARP) | |
452 | - length = XEL_ARP_PACKET_SIZE + ETH_HLEN + ETH_FCS_LEN; | |
453 | - else | |
454 | - /* Field contains type other than IP or ARP, use max | |
455 | - * frame size and let user parse it */ | |
456 | - length = ETH_FRAME_LEN + ETH_FCS_LEN; | |
457 | - } else | |
458 | - /* Use the length in the frame, plus the header and trailer */ | |
459 | - length = proto_type + ETH_HLEN + ETH_FCS_LEN; | |
460 | - | |
461 | - /* Read from the EmacLite device */ | |
462 | - xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET), | |
463 | - data, length); | |
464 | - | |
465 | - /* Acknowledge the frame */ | |
466 | - reg_data = in_be32(addr + XEL_RSR_OFFSET); | |
467 | - reg_data &= ~XEL_RSR_RECV_DONE_MASK; | |
468 | - out_be32(addr + XEL_RSR_OFFSET, reg_data); | |
469 | - | |
470 | - return length; | |
471 | -} | |
472 | - | |
473 | -/** | |
474 | - * xemaclite_update_address - Update the MAC address in the device | |
475 | - * @drvdata: Pointer to the Emaclite device private data | |
476 | - * @address_ptr:Pointer to the MAC address (MAC address is a 48-bit value) | |
477 | - * | |
478 | - * Tx must be idle and Rx should be idle for deterministic results. | |
479 | - * It is recommended that this function should be called after the | |
480 | - * initialization and before transmission of any packets from the device. | |
481 | - * The MAC address can be programmed using any of the two transmit | |
482 | - * buffers (if configured). | |
483 | - */ | |
484 | -static void xemaclite_update_address(struct net_local *drvdata, | |
485 | - u8 *address_ptr) | |
486 | -{ | |
487 | - void __iomem *addr; | |
488 | - u32 reg_data; | |
489 | - | |
490 | - /* Determine the expected Tx buffer address */ | |
491 | - addr = drvdata->base_addr + drvdata->next_tx_buf_to_use; | |
492 | - | |
493 | - xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN); | |
494 | - | |
495 | - out_be32(addr + XEL_TPLR_OFFSET, ETH_ALEN); | |
496 | - | |
497 | - /* Update the MAC address in the EmacLite */ | |
498 | - reg_data = in_be32(addr + XEL_TSR_OFFSET); | |
499 | - out_be32(addr + XEL_TSR_OFFSET, reg_data | XEL_TSR_PROG_MAC_ADDR); | |
500 | - | |
501 | - /* Wait for EmacLite to finish with the MAC address update */ | |
502 | - while ((in_be32(addr + XEL_TSR_OFFSET) & | |
503 | - XEL_TSR_PROG_MAC_ADDR) != 0) | |
504 | - ; | |
505 | -} | |
506 | - | |
507 | -/** | |
508 | - * xemaclite_set_mac_address - Set the MAC address for this device | |
509 | - * @dev: Pointer to the network device instance | |
510 | - * @addr: Void pointer to the sockaddr structure | |
511 | - * | |
512 | - * This function copies the HW address from the sockaddr strucutre to the | |
513 | - * net_device structure and updates the address in HW. | |
514 | - * | |
515 | - * Return: Error if the net device is busy or 0 if the addr is set | |
516 | - * successfully | |
517 | - */ | |
518 | -static int xemaclite_set_mac_address(struct net_device *dev, void *address) | |
519 | -{ | |
520 | - struct net_local *lp = netdev_priv(dev); | |
521 | - struct sockaddr *addr = address; | |
522 | - | |
523 | - if (netif_running(dev)) | |
524 | - return -EBUSY; | |
525 | - | |
526 | - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | |
527 | - xemaclite_update_address(lp, dev->dev_addr); | |
528 | - return 0; | |
529 | -} | |
530 | - | |
531 | -/** | |
532 | - * xemaclite_tx_timeout - Callback for Tx Timeout | |
533 | - * @dev: Pointer to the network device | |
534 | - * | |
535 | - * This function is called when Tx time out occurs for Emaclite device. | |
536 | - */ | |
537 | -static void xemaclite_tx_timeout(struct net_device *dev) | |
538 | -{ | |
539 | - struct net_local *lp = netdev_priv(dev); | |
540 | - unsigned long flags; | |
541 | - | |
542 | - dev_err(&lp->ndev->dev, "Exceeded transmit timeout of %lu ms\n", | |
543 | - TX_TIMEOUT * 1000UL / HZ); | |
544 | - | |
545 | - dev->stats.tx_errors++; | |
546 | - | |
547 | - /* Reset the device */ | |
548 | - spin_lock_irqsave(&lp->reset_lock, flags); | |
549 | - | |
550 | - /* Shouldn't really be necessary, but shouldn't hurt */ | |
551 | - netif_stop_queue(dev); | |
552 | - | |
553 | - xemaclite_disable_interrupts(lp); | |
554 | - xemaclite_enable_interrupts(lp); | |
555 | - | |
556 | - if (lp->deferred_skb) { | |
557 | - dev_kfree_skb(lp->deferred_skb); | |
558 | - lp->deferred_skb = NULL; | |
559 | - dev->stats.tx_errors++; | |
560 | - } | |
561 | - | |
562 | - /* To exclude tx timeout */ | |
563 | - dev->trans_start = jiffies; /* prevent tx timeout */ | |
564 | - | |
565 | - /* We're all ready to go. Start the queue */ | |
566 | - netif_wake_queue(dev); | |
567 | - spin_unlock_irqrestore(&lp->reset_lock, flags); | |
568 | -} | |
569 | - | |
570 | -/**********************/ | |
571 | -/* Interrupt Handlers */ | |
572 | -/**********************/ | |
573 | - | |
574 | -/** | |
575 | - * xemaclite_tx_handler - Interrupt handler for frames sent | |
576 | - * @dev: Pointer to the network device | |
577 | - * | |
578 | - * This function updates the number of packets transmitted and handles the | |
579 | - * deferred skb, if there is one. | |
580 | - */ | |
581 | -static void xemaclite_tx_handler(struct net_device *dev) | |
582 | -{ | |
583 | - struct net_local *lp = netdev_priv(dev); | |
584 | - | |
585 | - dev->stats.tx_packets++; | |
586 | - if (lp->deferred_skb) { | |
587 | - if (xemaclite_send_data(lp, | |
588 | - (u8 *) lp->deferred_skb->data, | |
589 | - lp->deferred_skb->len) != 0) | |
590 | - return; | |
591 | - else { | |
592 | - dev->stats.tx_bytes += lp->deferred_skb->len; | |
593 | - dev_kfree_skb_irq(lp->deferred_skb); | |
594 | - lp->deferred_skb = NULL; | |
595 | - dev->trans_start = jiffies; /* prevent tx timeout */ | |
596 | - netif_wake_queue(dev); | |
597 | - } | |
598 | - } | |
599 | -} | |
600 | - | |
601 | -/** | |
602 | - * xemaclite_rx_handler- Interrupt handler for frames received | |
603 | - * @dev: Pointer to the network device | |
604 | - * | |
605 | - * This function allocates memory for a socket buffer, fills it with data | |
606 | - * received and hands it over to the TCP/IP stack. | |
607 | - */ | |
608 | -static void xemaclite_rx_handler(struct net_device *dev) | |
609 | -{ | |
610 | - struct net_local *lp = netdev_priv(dev); | |
611 | - struct sk_buff *skb; | |
612 | - unsigned int align; | |
613 | - u32 len; | |
614 | - | |
615 | - len = ETH_FRAME_LEN + ETH_FCS_LEN; | |
616 | - skb = dev_alloc_skb(len + ALIGNMENT); | |
617 | - if (!skb) { | |
618 | - /* Couldn't get memory. */ | |
619 | - dev->stats.rx_dropped++; | |
620 | - dev_err(&lp->ndev->dev, "Could not allocate receive buffer\n"); | |
621 | - return; | |
622 | - } | |
623 | - | |
624 | - /* | |
625 | - * A new skb should have the data halfword aligned, but this code is | |
626 | - * here just in case that isn't true. Calculate how many | |
627 | - * bytes we should reserve to get the data to start on a word | |
628 | - * boundary */ | |
629 | - align = BUFFER_ALIGN(skb->data); | |
630 | - if (align) | |
631 | - skb_reserve(skb, align); | |
632 | - | |
633 | - skb_reserve(skb, 2); | |
634 | - | |
635 | - len = xemaclite_recv_data(lp, (u8 *) skb->data); | |
636 | - | |
637 | - if (!len) { | |
638 | - dev->stats.rx_errors++; | |
639 | - dev_kfree_skb_irq(skb); | |
640 | - return; | |
641 | - } | |
642 | - | |
643 | - skb_put(skb, len); /* Tell the skb how much data we got */ | |
644 | - | |
645 | - skb->protocol = eth_type_trans(skb, dev); | |
646 | - skb_checksum_none_assert(skb); | |
647 | - | |
648 | - dev->stats.rx_packets++; | |
649 | - dev->stats.rx_bytes += len; | |
650 | - | |
651 | - if (!skb_defer_rx_timestamp(skb)) | |
652 | - netif_rx(skb); /* Send the packet upstream */ | |
653 | -} | |
654 | - | |
655 | -/** | |
656 | - * xemaclite_interrupt - Interrupt handler for this driver | |
657 | - * @irq: Irq of the Emaclite device | |
658 | - * @dev_id: Void pointer to the network device instance used as callback | |
659 | - * reference | |
660 | - * | |
661 | - * This function handles the Tx and Rx interrupts of the EmacLite device. | |
662 | - */ | |
663 | -static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) | |
664 | -{ | |
665 | - bool tx_complete = 0; | |
666 | - struct net_device *dev = dev_id; | |
667 | - struct net_local *lp = netdev_priv(dev); | |
668 | - void __iomem *base_addr = lp->base_addr; | |
669 | - u32 tx_status; | |
670 | - | |
671 | - /* Check if there is Rx Data available */ | |
672 | - if ((in_be32(base_addr + XEL_RSR_OFFSET) & XEL_RSR_RECV_DONE_MASK) || | |
673 | - (in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) | |
674 | - & XEL_RSR_RECV_DONE_MASK)) | |
675 | - | |
676 | - xemaclite_rx_handler(dev); | |
677 | - | |
678 | - /* Check if the Transmission for the first buffer is completed */ | |
679 | - tx_status = in_be32(base_addr + XEL_TSR_OFFSET); | |
680 | - if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && | |
681 | - (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { | |
682 | - | |
683 | - tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; | |
684 | - out_be32(base_addr + XEL_TSR_OFFSET, tx_status); | |
685 | - | |
686 | - tx_complete = 1; | |
687 | - } | |
688 | - | |
689 | - /* Check if the Transmission for the second buffer is completed */ | |
690 | - tx_status = in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); | |
691 | - if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && | |
692 | - (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { | |
693 | - | |
694 | - tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; | |
695 | - out_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, | |
696 | - tx_status); | |
697 | - | |
698 | - tx_complete = 1; | |
699 | - } | |
700 | - | |
701 | - /* If there was a Tx interrupt, call the Tx Handler */ | |
702 | - if (tx_complete != 0) | |
703 | - xemaclite_tx_handler(dev); | |
704 | - | |
705 | - return IRQ_HANDLED; | |
706 | -} | |
707 | - | |
708 | -/**********************/ | |
709 | -/* MDIO Bus functions */ | |
710 | -/**********************/ | |
711 | - | |
712 | -/** | |
713 | - * xemaclite_mdio_wait - Wait for the MDIO to be ready to use | |
714 | - * @lp: Pointer to the Emaclite device private data | |
715 | - * | |
716 | - * This function waits till the device is ready to accept a new MDIO | |
717 | - * request. | |
718 | - * | |
719 | - * Return: 0 for success or ETIMEDOUT for a timeout | |
720 | - */ | |
721 | - | |
722 | -static int xemaclite_mdio_wait(struct net_local *lp) | |
723 | -{ | |
724 | - long end = jiffies + 2; | |
725 | - | |
726 | - /* wait for the MDIO interface to not be busy or timeout | |
727 | - after some time. | |
728 | - */ | |
729 | - while (in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET) & | |
730 | - XEL_MDIOCTRL_MDIOSTS_MASK) { | |
731 | - if (end - jiffies <= 0) { | |
732 | - WARN_ON(1); | |
733 | - return -ETIMEDOUT; | |
734 | - } | |
735 | - msleep(1); | |
736 | - } | |
737 | - return 0; | |
738 | -} | |
739 | - | |
740 | -/** | |
741 | - * xemaclite_mdio_read - Read from a given MII management register | |
742 | - * @bus: the mii_bus struct | |
743 | - * @phy_id: the phy address | |
744 | - * @reg: register number to read from | |
745 | - * | |
746 | - * This function waits till the device is ready to accept a new MDIO | |
747 | - * request and then writes the phy address to the MDIO Address register | |
748 | - * and reads data from MDIO Read Data register, when its available. | |
749 | - * | |
750 | - * Return: Value read from the MII management register | |
751 | - */ | |
752 | -static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg) | |
753 | -{ | |
754 | - struct net_local *lp = bus->priv; | |
755 | - u32 ctrl_reg; | |
756 | - u32 rc; | |
757 | - | |
758 | - if (xemaclite_mdio_wait(lp)) | |
759 | - return -ETIMEDOUT; | |
760 | - | |
761 | - /* Write the PHY address, register number and set the OP bit in the | |
762 | - * MDIO Address register. Set the Status bit in the MDIO Control | |
763 | - * register to start a MDIO read transaction. | |
764 | - */ | |
765 | - ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); | |
766 | - out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, | |
767 | - XEL_MDIOADDR_OP_MASK | | |
768 | - ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); | |
769 | - out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | |
770 | - ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); | |
771 | - | |
772 | - if (xemaclite_mdio_wait(lp)) | |
773 | - return -ETIMEDOUT; | |
774 | - | |
775 | - rc = in_be32(lp->base_addr + XEL_MDIORD_OFFSET); | |
776 | - | |
777 | - dev_dbg(&lp->ndev->dev, | |
778 | - "xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n", | |
779 | - phy_id, reg, rc); | |
780 | - | |
781 | - return rc; | |
782 | -} | |
783 | - | |
784 | -/** | |
785 | - * xemaclite_mdio_write - Write to a given MII management register | |
786 | - * @bus: the mii_bus struct | |
787 | - * @phy_id: the phy address | |
788 | - * @reg: register number to write to | |
789 | - * @val: value to write to the register number specified by reg | |
790 | - * | |
791 | - * This function waits till the device is ready to accept a new MDIO | |
792 | - * request and then writes the val to the MDIO Write Data register. | |
793 | - */ | |
794 | -static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg, | |
795 | - u16 val) | |
796 | -{ | |
797 | - struct net_local *lp = bus->priv; | |
798 | - u32 ctrl_reg; | |
799 | - | |
800 | - dev_dbg(&lp->ndev->dev, | |
801 | - "xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n", | |
802 | - phy_id, reg, val); | |
803 | - | |
804 | - if (xemaclite_mdio_wait(lp)) | |
805 | - return -ETIMEDOUT; | |
806 | - | |
807 | - /* Write the PHY address, register number and clear the OP bit in the | |
808 | - * MDIO Address register and then write the value into the MDIO Write | |
809 | - * Data register. Finally, set the Status bit in the MDIO Control | |
810 | - * register to start a MDIO write transaction. | |
811 | - */ | |
812 | - ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); | |
813 | - out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, | |
814 | - ~XEL_MDIOADDR_OP_MASK & | |
815 | - ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); | |
816 | - out_be32(lp->base_addr + XEL_MDIOWR_OFFSET, val); | |
817 | - out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | |
818 | - ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); | |
819 | - | |
820 | - return 0; | |
821 | -} | |
822 | - | |
823 | -/** | |
824 | - * xemaclite_mdio_reset - Reset the mdio bus. | |
825 | - * @bus: Pointer to the MII bus | |
826 | - * | |
827 | - * This function is required(?) as per Documentation/networking/phy.txt. | |
828 | - * There is no reset in this device; this function always returns 0. | |
829 | - */ | |
830 | -static int xemaclite_mdio_reset(struct mii_bus *bus) | |
831 | -{ | |
832 | - return 0; | |
833 | -} | |
834 | - | |
835 | -/** | |
836 | - * xemaclite_mdio_setup - Register mii_bus for the Emaclite device | |
837 | - * @lp: Pointer to the Emaclite device private data | |
838 | - * @ofdev: Pointer to OF device structure | |
839 | - * | |
840 | - * This function enables MDIO bus in the Emaclite device and registers a | |
841 | - * mii_bus. | |
842 | - * | |
843 | - * Return: 0 upon success or a negative error upon failure | |
844 | - */ | |
845 | -static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) | |
846 | -{ | |
847 | - struct mii_bus *bus; | |
848 | - int rc; | |
849 | - struct resource res; | |
850 | - struct device_node *np = of_get_parent(lp->phy_node); | |
851 | - | |
852 | - /* Don't register the MDIO bus if the phy_node or its parent node | |
853 | - * can't be found. | |
854 | - */ | |
855 | - if (!np) | |
856 | - return -ENODEV; | |
857 | - | |
858 | - /* Enable the MDIO bus by asserting the enable bit in MDIO Control | |
859 | - * register. | |
860 | - */ | |
861 | - out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | |
862 | - XEL_MDIOCTRL_MDIOEN_MASK); | |
863 | - | |
864 | - bus = mdiobus_alloc(); | |
865 | - if (!bus) | |
866 | - return -ENOMEM; | |
867 | - | |
868 | - of_address_to_resource(np, 0, &res); | |
869 | - snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", | |
870 | - (unsigned long long)res.start); | |
871 | - bus->priv = lp; | |
872 | - bus->name = "Xilinx Emaclite MDIO"; | |
873 | - bus->read = xemaclite_mdio_read; | |
874 | - bus->write = xemaclite_mdio_write; | |
875 | - bus->reset = xemaclite_mdio_reset; | |
876 | - bus->parent = dev; | |
877 | - bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ | |
878 | - | |
879 | - lp->mii_bus = bus; | |
880 | - | |
881 | - rc = of_mdiobus_register(bus, np); | |
882 | - if (rc) | |
883 | - goto err_register; | |
884 | - | |
885 | - return 0; | |
886 | - | |
887 | -err_register: | |
888 | - mdiobus_free(bus); | |
889 | - return rc; | |
890 | -} | |
891 | - | |
892 | -/** | |
893 | - * xemaclite_adjust_link - Link state callback for the Emaclite device | |
894 | - * @ndev: pointer to net_device struct | |
895 | - * | |
896 | - * There's nothing in the Emaclite device to be configured when the link | |
897 | - * state changes. We just print the status. | |
898 | - */ | |
899 | -void xemaclite_adjust_link(struct net_device *ndev) | |
900 | -{ | |
901 | - struct net_local *lp = netdev_priv(ndev); | |
902 | - struct phy_device *phy = lp->phy_dev; | |
903 | - int link_state; | |
904 | - | |
905 | - /* hash together the state values to decide if something has changed */ | |
906 | - link_state = phy->speed | (phy->duplex << 1) | phy->link; | |
907 | - | |
908 | - if (lp->last_link != link_state) { | |
909 | - lp->last_link = link_state; | |
910 | - phy_print_status(phy); | |
911 | - } | |
912 | -} | |
913 | - | |
914 | -/** | |
915 | - * xemaclite_open - Open the network device | |
916 | - * @dev: Pointer to the network device | |
917 | - * | |
918 | - * This function sets the MAC address, requests an IRQ and enables interrupts | |
919 | - * for the Emaclite device and starts the Tx queue. | |
920 | - * It also connects to the phy device, if MDIO is included in Emaclite device. | |
921 | - */ | |
922 | -static int xemaclite_open(struct net_device *dev) | |
923 | -{ | |
924 | - struct net_local *lp = netdev_priv(dev); | |
925 | - int retval; | |
926 | - | |
927 | - /* Just to be safe, stop the device first */ | |
928 | - xemaclite_disable_interrupts(lp); | |
929 | - | |
930 | - if (lp->phy_node) { | |
931 | - u32 bmcr; | |
932 | - | |
933 | - lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, | |
934 | - xemaclite_adjust_link, 0, | |
935 | - PHY_INTERFACE_MODE_MII); | |
936 | - if (!lp->phy_dev) { | |
937 | - dev_err(&lp->ndev->dev, "of_phy_connect() failed\n"); | |
938 | - return -ENODEV; | |
939 | - } | |
940 | - | |
941 | - /* EmacLite doesn't support giga-bit speeds */ | |
942 | - lp->phy_dev->supported &= (PHY_BASIC_FEATURES); | |
943 | - lp->phy_dev->advertising = lp->phy_dev->supported; | |
944 | - | |
945 | - /* Don't advertise 1000BASE-T Full/Half duplex speeds */ | |
946 | - phy_write(lp->phy_dev, MII_CTRL1000, 0); | |
947 | - | |
948 | - /* Advertise only 10 and 100mbps full/half duplex speeds */ | |
949 | - phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL); | |
950 | - | |
951 | - /* Restart auto negotiation */ | |
952 | - bmcr = phy_read(lp->phy_dev, MII_BMCR); | |
953 | - bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); | |
954 | - phy_write(lp->phy_dev, MII_BMCR, bmcr); | |
955 | - | |
956 | - phy_start(lp->phy_dev); | |
957 | - } | |
958 | - | |
959 | - /* Set the MAC address each time opened */ | |
960 | - xemaclite_update_address(lp, dev->dev_addr); | |
961 | - | |
962 | - /* Grab the IRQ */ | |
963 | - retval = request_irq(dev->irq, xemaclite_interrupt, 0, dev->name, dev); | |
964 | - if (retval) { | |
965 | - dev_err(&lp->ndev->dev, "Could not allocate interrupt %d\n", | |
966 | - dev->irq); | |
967 | - if (lp->phy_dev) | |
968 | - phy_disconnect(lp->phy_dev); | |
969 | - lp->phy_dev = NULL; | |
970 | - | |
971 | - return retval; | |
972 | - } | |
973 | - | |
974 | - /* Enable Interrupts */ | |
975 | - xemaclite_enable_interrupts(lp); | |
976 | - | |
977 | - /* We're ready to go */ | |
978 | - netif_start_queue(dev); | |
979 | - | |
980 | - return 0; | |
981 | -} | |
982 | - | |
983 | -/** | |
984 | - * xemaclite_close - Close the network device | |
985 | - * @dev: Pointer to the network device | |
986 | - * | |
987 | - * This function stops the Tx queue, disables interrupts and frees the IRQ for | |
988 | - * the Emaclite device. | |
989 | - * It also disconnects the phy device associated with the Emaclite device. | |
990 | - */ | |
991 | -static int xemaclite_close(struct net_device *dev) | |
992 | -{ | |
993 | - struct net_local *lp = netdev_priv(dev); | |
994 | - | |
995 | - netif_stop_queue(dev); | |
996 | - xemaclite_disable_interrupts(lp); | |
997 | - free_irq(dev->irq, dev); | |
998 | - | |
999 | - if (lp->phy_dev) | |
1000 | - phy_disconnect(lp->phy_dev); | |
1001 | - lp->phy_dev = NULL; | |
1002 | - | |
1003 | - return 0; | |
1004 | -} | |
1005 | - | |
1006 | -/** | |
1007 | - * xemaclite_send - Transmit a frame | |
1008 | - * @orig_skb: Pointer to the socket buffer to be transmitted | |
1009 | - * @dev: Pointer to the network device | |
1010 | - * | |
1011 | - * This function checks if the Tx buffer of the Emaclite device is free to send | |
1012 | - * data. If so, it fills the Tx buffer with data from socket buffer data, | |
1013 | - * updates the stats and frees the socket buffer. The Tx completion is signaled | |
1014 | - * by an interrupt. If the Tx buffer isn't free, then the socket buffer is | |
1015 | - * deferred and the Tx queue is stopped so that the deferred socket buffer can | |
1016 | - * be transmitted when the Emaclite device is free to transmit data. | |
1017 | - * | |
1018 | - * Return: 0, always. | |
1019 | - */ | |
1020 | -static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) | |
1021 | -{ | |
1022 | - struct net_local *lp = netdev_priv(dev); | |
1023 | - struct sk_buff *new_skb; | |
1024 | - unsigned int len; | |
1025 | - unsigned long flags; | |
1026 | - | |
1027 | - len = orig_skb->len; | |
1028 | - | |
1029 | - new_skb = orig_skb; | |
1030 | - | |
1031 | - spin_lock_irqsave(&lp->reset_lock, flags); | |
1032 | - if (xemaclite_send_data(lp, (u8 *) new_skb->data, len) != 0) { | |
1033 | - /* If the Emaclite Tx buffer is busy, stop the Tx queue and | |
1034 | - * defer the skb for transmission during the ISR, after the | |
1035 | - * current transmission is complete */ | |
1036 | - netif_stop_queue(dev); | |
1037 | - lp->deferred_skb = new_skb; | |
1038 | - /* Take the time stamp now, since we can't do this in an ISR. */ | |
1039 | - skb_tx_timestamp(new_skb); | |
1040 | - spin_unlock_irqrestore(&lp->reset_lock, flags); | |
1041 | - return 0; | |
1042 | - } | |
1043 | - spin_unlock_irqrestore(&lp->reset_lock, flags); | |
1044 | - | |
1045 | - skb_tx_timestamp(new_skb); | |
1046 | - | |
1047 | - dev->stats.tx_bytes += len; | |
1048 | - dev_kfree_skb(new_skb); | |
1049 | - | |
1050 | - return 0; | |
1051 | -} | |
1052 | - | |
1053 | -/** | |
1054 | - * xemaclite_remove_ndev - Free the network device | |
1055 | - * @ndev: Pointer to the network device to be freed | |
1056 | - * | |
1057 | - * This function un maps the IO region of the Emaclite device and frees the net | |
1058 | - * device. | |
1059 | - */ | |
1060 | -static void xemaclite_remove_ndev(struct net_device *ndev) | |
1061 | -{ | |
1062 | - if (ndev) { | |
1063 | - struct net_local *lp = netdev_priv(ndev); | |
1064 | - | |
1065 | - if (lp->base_addr) | |
1066 | - iounmap((void __iomem __force *) (lp->base_addr)); | |
1067 | - free_netdev(ndev); | |
1068 | - } | |
1069 | -} | |
1070 | - | |
1071 | -/** | |
1072 | - * get_bool - Get a parameter from the OF device | |
1073 | - * @ofdev: Pointer to OF device structure | |
1074 | - * @s: Property to be retrieved | |
1075 | - * | |
1076 | - * This function looks for a property in the device node and returns the value | |
1077 | - * of the property if its found or 0 if the property is not found. | |
1078 | - * | |
1079 | - * Return: Value of the parameter if the parameter is found, or 0 otherwise | |
1080 | - */ | |
1081 | -static bool get_bool(struct platform_device *ofdev, const char *s) | |
1082 | -{ | |
1083 | - u32 *p = (u32 *)of_get_property(ofdev->dev.of_node, s, NULL); | |
1084 | - | |
1085 | - if (p) { | |
1086 | - return (bool)*p; | |
1087 | - } else { | |
1088 | - dev_warn(&ofdev->dev, "Parameter %s not found," | |
1089 | - "defaulting to false\n", s); | |
1090 | - return 0; | |
1091 | - } | |
1092 | -} | |
1093 | - | |
1094 | -static struct net_device_ops xemaclite_netdev_ops; | |
1095 | - | |
1096 | -/** | |
1097 | - * xemaclite_of_probe - Probe method for the Emaclite device. | |
1098 | - * @ofdev: Pointer to OF device structure | |
1099 | - * @match: Pointer to the structure used for matching a device | |
1100 | - * | |
1101 | - * This function probes for the Emaclite device in the device tree. | |
1102 | - * It initializes the driver data structure and the hardware, sets the MAC | |
1103 | - * address and registers the network device. | |
1104 | - * It also registers a mii_bus for the Emaclite device, if MDIO is included | |
1105 | - * in the device. | |
1106 | - * | |
1107 | - * Return: 0, if the driver is bound to the Emaclite device, or | |
1108 | - * a negative error if there is failure. | |
1109 | - */ | |
1110 | -static int __devinit xemaclite_of_probe(struct platform_device *ofdev) | |
1111 | -{ | |
1112 | - struct resource r_irq; /* Interrupt resources */ | |
1113 | - struct resource r_mem; /* IO mem resources */ | |
1114 | - struct net_device *ndev = NULL; | |
1115 | - struct net_local *lp = NULL; | |
1116 | - struct device *dev = &ofdev->dev; | |
1117 | - const void *mac_address; | |
1118 | - | |
1119 | - int rc = 0; | |
1120 | - | |
1121 | - dev_info(dev, "Device Tree Probing\n"); | |
1122 | - | |
1123 | - /* Get iospace for the device */ | |
1124 | - rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); | |
1125 | - if (rc) { | |
1126 | - dev_err(dev, "invalid address\n"); | |
1127 | - return rc; | |
1128 | - } | |
1129 | - | |
1130 | - /* Get IRQ for the device */ | |
1131 | - rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); | |
1132 | - if (rc == NO_IRQ) { | |
1133 | - dev_err(dev, "no IRQ found\n"); | |
1134 | - return rc; | |
1135 | - } | |
1136 | - | |
1137 | - /* Create an ethernet device instance */ | |
1138 | - ndev = alloc_etherdev(sizeof(struct net_local)); | |
1139 | - if (!ndev) { | |
1140 | - dev_err(dev, "Could not allocate network device\n"); | |
1141 | - return -ENOMEM; | |
1142 | - } | |
1143 | - | |
1144 | - dev_set_drvdata(dev, ndev); | |
1145 | - SET_NETDEV_DEV(ndev, &ofdev->dev); | |
1146 | - | |
1147 | - ndev->irq = r_irq.start; | |
1148 | - ndev->mem_start = r_mem.start; | |
1149 | - ndev->mem_end = r_mem.end; | |
1150 | - | |
1151 | - lp = netdev_priv(ndev); | |
1152 | - lp->ndev = ndev; | |
1153 | - | |
1154 | - if (!request_mem_region(ndev->mem_start, | |
1155 | - ndev->mem_end - ndev->mem_start + 1, | |
1156 | - DRIVER_NAME)) { | |
1157 | - dev_err(dev, "Couldn't lock memory region at %p\n", | |
1158 | - (void *)ndev->mem_start); | |
1159 | - rc = -EBUSY; | |
1160 | - goto error2; | |
1161 | - } | |
1162 | - | |
1163 | - /* Get the virtual base address for the device */ | |
1164 | - lp->base_addr = ioremap(r_mem.start, resource_size(&r_mem)); | |
1165 | - if (NULL == lp->base_addr) { | |
1166 | - dev_err(dev, "EmacLite: Could not allocate iomem\n"); | |
1167 | - rc = -EIO; | |
1168 | - goto error1; | |
1169 | - } | |
1170 | - | |
1171 | - spin_lock_init(&lp->reset_lock); | |
1172 | - lp->next_tx_buf_to_use = 0x0; | |
1173 | - lp->next_rx_buf_to_use = 0x0; | |
1174 | - lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong"); | |
1175 | - lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong"); | |
1176 | - mac_address = of_get_mac_address(ofdev->dev.of_node); | |
1177 | - | |
1178 | - if (mac_address) | |
1179 | - /* Set the MAC address. */ | |
1180 | - memcpy(ndev->dev_addr, mac_address, 6); | |
1181 | - else | |
1182 | - dev_warn(dev, "No MAC address found\n"); | |
1183 | - | |
1184 | - /* Clear the Tx CSR's in case this is a restart */ | |
1185 | - out_be32(lp->base_addr + XEL_TSR_OFFSET, 0); | |
1186 | - out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0); | |
1187 | - | |
1188 | - /* Set the MAC address in the EmacLite device */ | |
1189 | - xemaclite_update_address(lp, ndev->dev_addr); | |
1190 | - | |
1191 | - lp->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); | |
1192 | - rc = xemaclite_mdio_setup(lp, &ofdev->dev); | |
1193 | - if (rc) | |
1194 | - dev_warn(&ofdev->dev, "error registering MDIO bus\n"); | |
1195 | - | |
1196 | - dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr); | |
1197 | - | |
1198 | - ndev->netdev_ops = &xemaclite_netdev_ops; | |
1199 | - ndev->flags &= ~IFF_MULTICAST; | |
1200 | - ndev->watchdog_timeo = TX_TIMEOUT; | |
1201 | - | |
1202 | - /* Finally, register the device */ | |
1203 | - rc = register_netdev(ndev); | |
1204 | - if (rc) { | |
1205 | - dev_err(dev, | |
1206 | - "Cannot register network device, aborting\n"); | |
1207 | - goto error1; | |
1208 | - } | |
1209 | - | |
1210 | - dev_info(dev, | |
1211 | - "Xilinx EmacLite at 0x%08X mapped to 0x%08X, irq=%d\n", | |
1212 | - (unsigned int __force)ndev->mem_start, | |
1213 | - (unsigned int __force)lp->base_addr, ndev->irq); | |
1214 | - return 0; | |
1215 | - | |
1216 | -error1: | |
1217 | - release_mem_region(ndev->mem_start, resource_size(&r_mem)); | |
1218 | - | |
1219 | -error2: | |
1220 | - xemaclite_remove_ndev(ndev); | |
1221 | - return rc; | |
1222 | -} | |
1223 | - | |
1224 | -/** | |
1225 | - * xemaclite_of_remove - Unbind the driver from the Emaclite device. | |
1226 | - * @of_dev: Pointer to OF device structure | |
1227 | - * | |
1228 | - * This function is called if a device is physically removed from the system or | |
1229 | - * if the driver module is being unloaded. It frees any resources allocated to | |
1230 | - * the device. | |
1231 | - * | |
1232 | - * Return: 0, always. | |
1233 | - */ | |
1234 | -static int __devexit xemaclite_of_remove(struct platform_device *of_dev) | |
1235 | -{ | |
1236 | - struct device *dev = &of_dev->dev; | |
1237 | - struct net_device *ndev = dev_get_drvdata(dev); | |
1238 | - | |
1239 | - struct net_local *lp = netdev_priv(ndev); | |
1240 | - | |
1241 | - /* Un-register the mii_bus, if configured */ | |
1242 | - if (lp->has_mdio) { | |
1243 | - mdiobus_unregister(lp->mii_bus); | |
1244 | - kfree(lp->mii_bus->irq); | |
1245 | - mdiobus_free(lp->mii_bus); | |
1246 | - lp->mii_bus = NULL; | |
1247 | - } | |
1248 | - | |
1249 | - unregister_netdev(ndev); | |
1250 | - | |
1251 | - if (lp->phy_node) | |
1252 | - of_node_put(lp->phy_node); | |
1253 | - lp->phy_node = NULL; | |
1254 | - | |
1255 | - release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1); | |
1256 | - | |
1257 | - xemaclite_remove_ndev(ndev); | |
1258 | - dev_set_drvdata(dev, NULL); | |
1259 | - | |
1260 | - return 0; | |
1261 | -} | |
1262 | - | |
1263 | -#ifdef CONFIG_NET_POLL_CONTROLLER | |
1264 | -static void | |
1265 | -xemaclite_poll_controller(struct net_device *ndev) | |
1266 | -{ | |
1267 | - disable_irq(ndev->irq); | |
1268 | - xemaclite_interrupt(ndev->irq, ndev); | |
1269 | - enable_irq(ndev->irq); | |
1270 | -} | |
1271 | -#endif | |
1272 | - | |
1273 | -static struct net_device_ops xemaclite_netdev_ops = { | |
1274 | - .ndo_open = xemaclite_open, | |
1275 | - .ndo_stop = xemaclite_close, | |
1276 | - .ndo_start_xmit = xemaclite_send, | |
1277 | - .ndo_set_mac_address = xemaclite_set_mac_address, | |
1278 | - .ndo_tx_timeout = xemaclite_tx_timeout, | |
1279 | -#ifdef CONFIG_NET_POLL_CONTROLLER | |
1280 | - .ndo_poll_controller = xemaclite_poll_controller, | |
1281 | -#endif | |
1282 | -}; | |
1283 | - | |
1284 | -/* Match table for OF platform binding */ | |
1285 | -static struct of_device_id xemaclite_of_match[] __devinitdata = { | |
1286 | - { .compatible = "xlnx,opb-ethernetlite-1.01.a", }, | |
1287 | - { .compatible = "xlnx,opb-ethernetlite-1.01.b", }, | |
1288 | - { .compatible = "xlnx,xps-ethernetlite-1.00.a", }, | |
1289 | - { .compatible = "xlnx,xps-ethernetlite-2.00.a", }, | |
1290 | - { .compatible = "xlnx,xps-ethernetlite-2.01.a", }, | |
1291 | - { .compatible = "xlnx,xps-ethernetlite-3.00.a", }, | |
1292 | - { /* end of list */ }, | |
1293 | -}; | |
1294 | -MODULE_DEVICE_TABLE(of, xemaclite_of_match); | |
1295 | - | |
1296 | -static struct platform_driver xemaclite_of_driver = { | |
1297 | - .driver = { | |
1298 | - .name = DRIVER_NAME, | |
1299 | - .owner = THIS_MODULE, | |
1300 | - .of_match_table = xemaclite_of_match, | |
1301 | - }, | |
1302 | - .probe = xemaclite_of_probe, | |
1303 | - .remove = __devexit_p(xemaclite_of_remove), | |
1304 | -}; | |
1305 | - | |
1306 | -/** | |
1307 | - * xgpiopss_init - Initial driver registration call | |
1308 | - * | |
1309 | - * Return: 0 upon success, or a negative error upon failure. | |
1310 | - */ | |
1311 | -static int __init xemaclite_init(void) | |
1312 | -{ | |
1313 | - /* No kernel boot options used, we just need to register the driver */ | |
1314 | - return platform_driver_register(&xemaclite_of_driver); | |
1315 | -} | |
1316 | - | |
1317 | -/** | |
1318 | - * xemaclite_cleanup - Driver un-registration call | |
1319 | - */ | |
1320 | -static void __exit xemaclite_cleanup(void) | |
1321 | -{ | |
1322 | - platform_driver_unregister(&xemaclite_of_driver); | |
1323 | -} | |
1324 | - | |
1325 | -module_init(xemaclite_init); | |
1326 | -module_exit(xemaclite_cleanup); | |
1327 | - | |
1328 | -MODULE_AUTHOR("Xilinx, Inc."); | |
1329 | -MODULE_DESCRIPTION("Xilinx Ethernet MAC Lite driver"); | |
1330 | -MODULE_LICENSE("GPL"); |