sun4i_emac.c revision 1.6 1 /* $NetBSD: sun4i_emac.c,v 1.6 2019/01/22 03:42:25 msaitoh Exp $ */
2
3 /*-
4 * Copyright (c) 2013-2017 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry and Jared McNeill.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33
34 __KERNEL_RCSID(1, "$NetBSD: sun4i_emac.c,v 1.6 2019/01/22 03:42:25 msaitoh Exp $");
35
36 #include <sys/param.h>
37 #include <sys/bus.h>
38 #include <sys/device.h>
39 #include <sys/intr.h>
40 #include <sys/ioctl.h>
41 #include <sys/mutex.h>
42 #include <sys/rndsource.h>
43 #include <sys/kernel.h>
44 #include <sys/systm.h>
45
46 #include <net/bpf.h>
47 #include <net/if.h>
48 #include <net/if_dl.h>
49 #include <net/if_ether.h>
50 #include <net/if_media.h>
51
52 #include <dev/mii/miivar.h>
53
54 #include <dev/fdt/fdtvar.h>
55
56 #include <arm/sunxi/sunxi_sramc.h>
57
58 #define EMAC_IFNAME "emac%d"
59
60 #define EMAC_CTL_REG 0x00
61 #define EMAC_CTL_RX_EN __BIT(2)
62 #define EMAC_CTL_TX_EN __BIT(1)
63 #define EMAC_CTL_RST __BIT(0)
64 #define EMAC_TX_MODE_REG 0x04
65 #define EMAC_TX_MODE_DMA __BIT(1)
66 #define EMAC_TX_MODE_ABF_ENA __BIT(0)
67 #define EMAC_TX_FLOW_REG 0x08
68 #define EMAC_TX_CTL0_REG 0x0c
69 #define EMAC_TX_CTL1_REG 0x10
70 #define EMAC_TX_CTL_REG(n) (EMAC_TX_CTL0_REG+4*(n))
71 #define EMAC_TX_CTL_START __BIT(0)
72 #define EMAC_TX_INS_REG 0x14
73 #define EMAC_TX_PL0_REG 0x18
74 #define EMAC_TX_PL1_REG 0x1c
75 #define EMAC_TX_PL_REG(n) (EMAC_TX_PL0_REG+4*(n))
76 #define EMAC_TX_STA_REG 0x20
77 #define EMAC_TX_IO_DATA0_REG 0x24
78 #define EMAC_TX_IO_DATA1_REG 0x28
79 #define EMAC_TX_IO_DATA_REG(n) (EMAC_TX_IO_DATA0_REG+4*(n))
80 #define EMAC_TX_TSVL0_REG 0x2c
81 #define EMAC_TX_TSVH0_REG 0x30
82 #define EMAC_TX_TSVL1_REG 0x34
83 #define EMAC_TX_TSVH1_REG 0x38
84 #define EMAC_RX_CTL_REG 0x3c
85 #define EMAC_RX_CTL_SA_IF __BIT(25)
86 #define EMAC_RX_CTL_SA __BIT(24)
87 #define EMAC_RX_CTL_BC0 __BIT(22)
88 #define EMAC_RX_CTL_MHF __BIT(21)
89 #define EMAC_RX_CTL_MC0 __BIT(20)
90 #define EMAC_RX_CTL_DAF __BIT(17)
91 #define EMAC_RX_CTL_UCAD __BIT(16)
92 #define EMAC_RX_CTL_POR __BIT(8)
93 #define EMAC_RX_CTL_PLE __BIT(7)
94 #define EMAC_RX_CTL_PCRCE __BIT(6)
95 #define EMAC_RX_CTL_PCF __BIT(5)
96 #define EMAC_RX_CTL_PROMISC __BIT(4)
97 #define EMAC_RX_CTL_FIFO_RESET __BIT(3)
98 #define EMAC_RX_CTL_DMA __BIT(2)
99 #define EMAC_RX_CTL_DRQ_MODE __BIT(1)
100 #define EMAC_RX_CTL_START __BIT(0)
101 #define EMAC_RX_HASH0_REG 0x40
102 #define EMAC_RX_HASH1_REG 0x44
103 #define EMAC_RX_STA_REG 0x48
104 #define EMAC_RX_STA_PKTOK __BIT(7)
105 #define EMAC_RX_STA_ALNERR __BIT(6)
106 #define EMAC_RX_STA_LENERR __BIT(5)
107 #define EMAC_RX_STA_CRCERR __BIT(4)
108 #define EMAC_RX_IO_DATA_REG 0x4c
109 #define EMAC_RX_FBC_REG 0x50
110 #define EMAC_INT_CTL_REG 0x54
111 #define EMAC_INT_STA_REG 0x58
112 #define EMAC_INT_RX __BIT(8)
113 #define EMAC_INT_TX1 __BIT(1)
114 #define EMAC_INT_TX0 __BIT(0)
115 #define EMAC_INT_ENABLE \
116 (EMAC_INT_RX|EMAC_INT_TX1|EMAC_INT_TX0)
117 #define EMAC_MAC_CTL0_REG 0x5c
118 #define EMAC_MAC_CTL0_SOFT_RESET __BIT(15)
119 #define EMAC_MAC_CTL0_TFC __BIT(3)
120 #define EMAC_MAC_CTL0_RFC __BIT(2)
121 #define EMAC_MAC_CTL1_REG 0x60
122 #define EMAC_MAC_CTL1_ED __BIT(15)
123 #define EMAC_MAC_CTL1_NB __BIT(13)
124 #define EMAC_MAC_CTL1_BNB __BIT(12)
125 #define EMAC_MAC_CTL1_LPE __BIT(9)
126 #define EMAC_MAC_CTL1_PRE __BIT(8)
127 #define EMAC_MAC_CTL1_ADP __BIT(7)
128 #define EMAC_MAC_CTL1_VC __BIT(6)
129 #define EMAC_MAC_CTL1_PC __BIT(5)
130 #define EMAC_MAC_CTL1_CRC __BIT(4)
131 #define EMAC_MAC_CTL1_DCRC __BIT(3)
132 #define EMAC_MAC_CTL1_HF __BIT(2)
133 #define EMAC_MAC_CTL1_FLC __BIT(1)
134 #define EMAC_MAC_CTL1_FD __BIT(0)
135 #define EMAC_MAC_IPGT_REG 0x64
136 #define EMAC_MAC_IPGT_FD 0x15
137 #define EMAC_MAC_IPGR_REG 0x68
138 #define EMAC_MAC_IPGR_IPG1 __BITS(15,8)
139 #define EMAC_MAC_IPGR_IPG2 __BITS(7,0)
140 #define EMAC_MAC_CLRT_REG 0x6c
141 #define EMAC_MAC_CLRT_CW __BITS(15,8)
142 #define EMAC_MAC_CLRT_RM __BITS(7,0)
143 #define EMAC_MAC_MAXF_REG 0x70
144 #define EMAC_MAC_SUPP_REG 0x74
145 #define EMAC_MAC_SUPP_100M __BIT(8)
146 #define EMAC_MAC_TEST_REG 0x78
147 #define EMAC_MAC_MCFG_REG 0x7c
148 #define EMAC_MAC_MCFG_CLK __BITS(5,2)
149 #define EMAC_MAC_MCMD_REG 0x80
150 #define EMAC_MAC_MADR_REG 0x84
151 #define EMAC_MAC_MWTD_REG 0x88
152 #define EMAC_MAC_MRDD_REG 0x8c
153 #define EMAC_MAC_MIND_REG 0x90
154 #define EMAC_MAC_SSRR_REG 0x94
155 #define EMAC_MAC_A0_REG 0x98
156 #define EMAC_MAC_A1_REG 0x9c
157 #define EMAC_MAC_A2_REG 0xa0
158
159 #define EMAC_RXHDR_STS __BITS(31,16)
160 #define EMAC_RXHDR_LEN __BITS(15,0)
161
162 #define EMAC_RX_MAGIC 0x0143414d /* M A C \001 */
163
164 #define EMAC_TXBUF_SIZE 4096
165
166 static int sun4i_emac_match(device_t, cfdata_t, void *);
167 static void sun4i_emac_attach(device_t, device_t, void *);
168
169 static int sun4i_emac_intr(void *);
170 static void sun4i_emac_tick(void *);
171
172 static int sun4i_emac_miibus_read_reg(device_t, int, int, uint16_t *);
173 static int sun4i_emac_miibus_write_reg(device_t, int, int, uint16_t);
174 static void sun4i_emac_miibus_statchg(struct ifnet *);
175
176 static void sun4i_emac_ifstart(struct ifnet *);
177 static int sun4i_emac_ifioctl(struct ifnet *, u_long, void *);
178 static int sun4i_emac_ifinit(struct ifnet *);
179 static void sun4i_emac_ifstop(struct ifnet *, int);
180 static void sun4i_emac_ifwatchdog(struct ifnet *);
181
182 struct sun4i_emac_softc;
183 static void sun4i_emac_rx_hash(struct sun4i_emac_softc *);
184
185 struct sun4i_emac_softc {
186 device_t sc_dev;
187 int sc_phandle;
188 bus_space_tag_t sc_bst;
189 bus_space_handle_t sc_bsh;
190 bus_dma_tag_t sc_dmat;
191 struct ethercom sc_ec;
192 struct mii_data sc_mii;
193 krndsource_t sc_rnd_source; /* random source */
194 kmutex_t sc_intr_lock;
195 uint8_t sc_tx_active;
196 callout_t sc_stat_ch;
197 void *sc_ih;
198 uint32_t sc_txbuf[EMAC_TXBUF_SIZE/4];
199 };
200
201 static const char * compatible[] = {
202 "allwinner,sun4i-a10-emac",
203 NULL
204 };
205
206 CFATTACH_DECL_NEW(sun4i_emac, sizeof(struct sun4i_emac_softc),
207 sun4i_emac_match, sun4i_emac_attach, NULL, NULL);
208
209 static inline uint32_t
210 sun4i_emac_read(struct sun4i_emac_softc *sc, bus_size_t o)
211 {
212 return bus_space_read_4(sc->sc_bst, sc->sc_bsh, o);
213 }
214
215 static inline void
216 sun4i_emac_write(struct sun4i_emac_softc *sc, bus_size_t o, uint32_t v)
217 {
218 return bus_space_write_4(sc->sc_bst, sc->sc_bsh, o, v);
219 }
220
221 static inline void
222 sun4i_emac_clear_set(struct sun4i_emac_softc *sc, bus_size_t o, uint32_t c,
223 uint32_t s)
224 {
225 uint32_t v = bus_space_read_4(sc->sc_bst, sc->sc_bsh, o);
226 return bus_space_write_4(sc->sc_bst, sc->sc_bsh, o, (v & ~c) | s);
227 }
228
229 static int
230 sun4i_emac_match(device_t parent, cfdata_t cf, void *aux)
231 {
232 struct fdt_attach_args * const faa = aux;
233
234 return of_match_compatible(faa->faa_phandle, compatible);
235 }
236
237 static void
238 sun4i_emac_attach(device_t parent, device_t self, void *aux)
239 {
240 struct sun4i_emac_softc * const sc = device_private(self);
241 struct fdt_attach_args * const faa = aux;
242 struct ifnet * const ifp = &sc->sc_ec.ec_if;
243 struct mii_data * const mii = &sc->sc_mii;
244 const int phandle = faa->faa_phandle;
245 char enaddr[ETHER_ADDR_LEN];
246 const uint8_t *local_addr;
247 char intrstr[128];
248 struct clk *clk;
249 bus_addr_t addr;
250 bus_size_t size;
251 int len;
252
253 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
254 aprint_error(": cannot get registers\n");
255 return;
256 }
257
258 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
259 aprint_error(": cannot decode interrupt\n");
260 return;
261 }
262
263 clk = fdtbus_clock_get_index(phandle, 0);
264 if (clk == NULL) {
265 aprint_error(": cannot acquire clock\n");
266 return;
267 }
268 if (clk_enable(clk) != 0) {
269 aprint_error(": cannot enable clock\n");
270 return;
271 }
272
273 if (sunxi_sramc_claim(phandle) != 0) {
274 aprint_error(": cannot map SRAM to EMAC\n");
275 return;
276 }
277
278 sc->sc_dev = self;
279 sc->sc_phandle = phandle;
280 sc->sc_ec.ec_mii = mii;
281 sc->sc_bst = faa->faa_bst;
282 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
283 aprint_error(": cannot map registers\n");
284 return;
285 }
286 sc->sc_dmat = faa->faa_dmat;
287
288 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NET);
289 callout_init(&sc->sc_stat_ch, 0);
290 callout_setfunc(&sc->sc_stat_ch, sun4i_emac_tick, sc);
291
292 aprint_naive("\n");
293 aprint_normal(": 10/100 Ethernet Controller\n");
294
295 /*
296 * Disable and then clear all interrupts
297 */
298 sun4i_emac_write(sc, EMAC_INT_CTL_REG, 0);
299 sun4i_emac_write(sc, EMAC_INT_STA_REG,
300 sun4i_emac_read(sc, EMAC_INT_STA_REG));
301
302 sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_NET, 0,
303 sun4i_emac_intr, sc);
304 if (sc->sc_ih == NULL) {
305 aprint_error_dev(self, "failed to establish interrupt on %s\n",
306 intrstr);
307 return;
308 }
309 aprint_normal_dev(self, "interrupting on %s\n", intrstr);
310
311 local_addr = fdtbus_get_prop(phandle, "local-mac-address", &len);
312 if (local_addr && len == ETHER_ADDR_LEN) {
313 memcpy(enaddr, local_addr, ETHER_ADDR_LEN);
314
315 uint32_t a1 = ((uint32_t)enaddr[0] << 16) |
316 ((uint32_t)enaddr[1] << 8) |
317 (uint32_t)enaddr[2];
318 uint32_t a0 = ((uint32_t)enaddr[3] << 16) |
319 ((uint32_t)enaddr[4] << 8) |
320 (uint32_t)enaddr[5];
321
322 sun4i_emac_write(sc, EMAC_MAC_A1_REG, a1);
323 sun4i_emac_write(sc, EMAC_MAC_A0_REG, a0);
324 }
325
326 uint32_t a1 = sun4i_emac_read(sc, EMAC_MAC_A1_REG);
327 uint32_t a0 = sun4i_emac_read(sc, EMAC_MAC_A0_REG);
328 if (a0 != 0 || a1 != 0) {
329 enaddr[0] = a1 >> 16;
330 enaddr[1] = a1 >> 8;
331 enaddr[2] = a1 >> 0;
332 enaddr[3] = a0 >> 16;
333 enaddr[4] = a0 >> 8;
334 enaddr[5] = a0 >> 0;
335 }
336 aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(enaddr));
337
338 snprintf(ifp->if_xname, IFNAMSIZ, EMAC_IFNAME, device_unit(self));
339 ifp->if_softc = sc;
340 ifp->if_capabilities = 0;
341 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
342 ifp->if_start = sun4i_emac_ifstart;
343 ifp->if_ioctl = sun4i_emac_ifioctl;
344 ifp->if_init = sun4i_emac_ifinit;
345 ifp->if_stop = sun4i_emac_ifstop;
346 ifp->if_watchdog = sun4i_emac_ifwatchdog;
347 IFQ_SET_READY(&ifp->if_snd);
348
349 /* 802.1Q VLAN-sized frames are supported */
350 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
351
352 ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
353
354 mii->mii_ifp = ifp;
355 mii->mii_readreg = sun4i_emac_miibus_read_reg;
356 mii->mii_writereg = sun4i_emac_miibus_write_reg;
357 mii->mii_statchg = sun4i_emac_miibus_statchg;
358
359 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
360
361 if (LIST_EMPTY(&mii->mii_phys)) {
362 aprint_error_dev(self, "no PHY found!\n");
363 ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
364 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_MANUAL);
365 } else {
366 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO);
367 }
368
369 /*
370 * Attach the interface.
371 */
372 if_attach(ifp);
373 if_deferred_start_init(ifp, NULL);
374 ether_ifattach(ifp, enaddr);
375 rnd_attach_source(&sc->sc_rnd_source, device_xname(self),
376 RND_TYPE_NET, RND_FLAG_DEFAULT);
377 }
378
379 static inline void
380 sun4i_emac_int_enable(struct sun4i_emac_softc *sc)
381 {
382 sun4i_emac_clear_set(sc, EMAC_INT_CTL_REG, 0,
383 EMAC_INT_ENABLE);
384 sun4i_emac_write(sc, EMAC_INT_STA_REG,
385 sun4i_emac_read(sc, EMAC_INT_STA_REG));
386 }
387
388 int
389 sun4i_emac_miibus_read_reg(device_t self, int phy, int reg, uint16_t *val)
390 {
391 struct sun4i_emac_softc * const sc = device_private(self);
392 int retry = 100;
393 int rv = 0;
394
395 sun4i_emac_write(sc, EMAC_MAC_MADR_REG, (phy << 8) | reg);
396 sun4i_emac_write(sc, EMAC_MAC_MCMD_REG, 1);
397
398 while (--retry > 0 && (sun4i_emac_read(sc, EMAC_MAC_MIND_REG) & 1) != 0)
399 delay(1000);
400 if (retry == 0) {
401 device_printf(self, "PHY read timeout\n");
402 rv = ETIMEDOUT;
403 }
404
405 sun4i_emac_write(sc, EMAC_MAC_MCMD_REG, 0);
406 *val = sun4i_emac_read(sc, EMAC_MAC_MRDD_REG) & 0xffff;
407
408 return rv;
409 }
410
411 int
412 sun4i_emac_miibus_write_reg(device_t self, int phy, int reg, uint16_t val)
413 {
414 struct sun4i_emac_softc * const sc = device_private(self);
415 int retry = 100;
416 int rv = 0;
417
418 sun4i_emac_write(sc, EMAC_MAC_MADR_REG, (phy << 8) | reg);
419 sun4i_emac_write(sc, EMAC_MAC_MCMD_REG, 1);
420
421 while (--retry > 0 && (sun4i_emac_read(sc, EMAC_MAC_MIND_REG) & 1) != 0)
422 delay(1000);
423 if (retry == 0) {
424 device_printf(self, "PHY write timeout\n");
425 rv = ETIMEDOUT;
426 }
427
428 sun4i_emac_write(sc, EMAC_MAC_MCMD_REG, 0);
429 sun4i_emac_write(sc, EMAC_MAC_MWTD_REG, val);
430
431 return rv;
432 }
433
434 void
435 sun4i_emac_miibus_statchg(struct ifnet *ifp)
436 {
437 struct sun4i_emac_softc * const sc = ifp->if_softc;
438 struct mii_data * const mii = &sc->sc_mii;
439 const u_int media = mii->mii_media_active;
440
441 /*
442 * Set MII interface based on the speed
443 * negotiated by the PHY.
444 */
445 switch (IFM_SUBTYPE(media)) {
446 case IFM_10_T:
447 sun4i_emac_clear_set(sc, EMAC_MAC_SUPP_REG,
448 EMAC_MAC_SUPP_100M, 0);
449 break;
450 case IFM_100_TX:
451 sun4i_emac_clear_set(sc, EMAC_MAC_SUPP_REG,
452 0, EMAC_MAC_SUPP_100M);
453 break;
454 }
455
456 const bool link = (IFM_SUBTYPE(media) & (IFM_10_T|IFM_100_TX)) != 0;
457 if (link) {
458 if (media & IFM_FDX) {
459 sun4i_emac_clear_set(sc, EMAC_MAC_CTL1_REG,
460 0, EMAC_MAC_CTL1_FD);
461 } else {
462 sun4i_emac_clear_set(sc, EMAC_MAC_CTL1_REG,
463 EMAC_MAC_CTL1_FD, 0);
464 }
465 }
466 }
467
468 static void
469 sun4i_emac_tick(void *softc)
470 {
471 struct sun4i_emac_softc * const sc = softc;
472 struct mii_data * const mii = &sc->sc_mii;
473 int s;
474
475 s = splnet();
476 mii_tick(mii);
477 callout_schedule(&sc->sc_stat_ch, hz);
478 splx(s);
479 }
480
481 static inline void
482 sun4i_emac_rxfifo_flush(struct sun4i_emac_softc *sc)
483 {
484 sun4i_emac_clear_set(sc, EMAC_CTL_REG, EMAC_CTL_RX_EN, 0);
485
486 sun4i_emac_clear_set(sc, EMAC_RX_CTL_REG, 0, EMAC_RX_CTL_FIFO_RESET);
487
488 for (;;) {
489 uint32_t v0 = sun4i_emac_read(sc, EMAC_RX_CTL_REG);
490 if ((v0 & EMAC_RX_CTL_FIFO_RESET) == 0)
491 break;
492 }
493
494 sun4i_emac_clear_set(sc, EMAC_CTL_REG, 0, EMAC_CTL_RX_EN);
495 }
496
497 static void
498 sun4i_emac_rxfifo_consume(struct sun4i_emac_softc *sc, size_t len)
499 {
500 for (len = (len + 3) >> 2; len > 0; len--) {
501 (void) sun4i_emac_read(sc, EMAC_RX_IO_DATA_REG);
502 }
503 }
504
505 static void
506 sun4i_emac_rxfifo_transfer(struct sun4i_emac_softc *sc, struct mbuf *m)
507 {
508 uint32_t *dp32 = mtod(m, uint32_t *);
509 const int len = roundup2(m->m_len, 4);
510
511 bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh,
512 EMAC_RX_IO_DATA_REG, dp32, len / 4);
513 }
514
515 static struct mbuf *
516 sun4i_emac_mgethdr(struct sun4i_emac_softc *sc, size_t rxlen)
517 {
518 struct mbuf *m = m_gethdr(M_DONTWAIT, MT_DATA);
519
520 if (m == NULL) {
521 return NULL;
522 }
523 if (rxlen + 2 > MHLEN) {
524 MCLGET(m, M_DONTWAIT);
525 if ((m->m_flags & M_EXT) == 0) {
526 m_free(m);
527 return NULL;
528 }
529 }
530
531 m_adj(m, 2);
532 m->m_len = rxlen;
533 m->m_pkthdr.len = rxlen;
534 m_set_rcvif(m, &sc->sc_ec.ec_if);
535 m->m_flags |= M_HASFCS;
536
537 return m;
538 }
539
540 static void
541 sun4i_emac_if_input(struct sun4i_emac_softc *sc, struct mbuf *m)
542 {
543 struct ifnet * const ifp = &sc->sc_ec.ec_if;
544
545 if_percpuq_enqueue(ifp->if_percpuq, m);
546 }
547
548 static void
549 sun4i_emac_rx_intr(struct sun4i_emac_softc *sc)
550 {
551 for (;;) {
552 uint32_t rx_count = sun4i_emac_read(sc, EMAC_RX_FBC_REG);
553 struct mbuf *m;
554
555 if (rx_count == 0) {
556 rx_count = sun4i_emac_read(sc, EMAC_RX_FBC_REG);
557 if (rx_count == 0)
558 return;
559 }
560
561 uint32_t v = sun4i_emac_read(sc, EMAC_RX_IO_DATA_REG);
562 if (v != EMAC_RX_MAGIC) {
563 sun4i_emac_rxfifo_flush(sc);
564 return;
565 }
566
567 uint32_t rxhdr = sun4i_emac_read(sc, EMAC_RX_IO_DATA_REG);
568 uint32_t rxlen = __SHIFTOUT(rxhdr, EMAC_RXHDR_LEN);
569 uint32_t rxsts = __SHIFTOUT(rxhdr, EMAC_RXHDR_STS);
570
571 if (rxlen < ETHER_MIN_LEN || (rxsts & EMAC_RX_STA_PKTOK) == 0) {
572 sc->sc_ec.ec_if.if_ierrors++;
573 continue;
574 }
575
576 m = sun4i_emac_mgethdr(sc, rxlen);
577 if (m == NULL) {
578 sc->sc_ec.ec_if.if_ierrors++;
579 sun4i_emac_rxfifo_consume(sc, rxlen);
580 return;
581 }
582
583 sun4i_emac_rxfifo_transfer(sc, m);
584 sun4i_emac_if_input(sc, m);
585 }
586 }
587
588 static int
589 sun4i_emac_txfifo_transfer(struct sun4i_emac_softc *sc, struct mbuf *m, u_int slot)
590 {
591 bus_size_t const io_data_reg = EMAC_TX_IO_DATA_REG(0);
592 const int len = m->m_pkthdr.len;
593 uint32_t *pktdata;
594
595 KASSERT(len > 0 && len <= sizeof(sc->sc_txbuf));
596
597 if (m->m_next != NULL) {
598 m_copydata(m, 0, len, sc->sc_txbuf);
599 pktdata = sc->sc_txbuf;
600 } else {
601 pktdata = mtod(m, uint32_t *);
602 }
603
604 bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, io_data_reg,
605 pktdata, roundup2(len, 4) / 4);
606
607 return len;
608 }
609
610 static void
611 sun4i_emac_tx_enqueue(struct sun4i_emac_softc *sc, struct mbuf *m, u_int slot)
612 {
613 struct ifnet * const ifp = &sc->sc_ec.ec_if;
614
615 sun4i_emac_write(sc, EMAC_TX_INS_REG, slot);
616
617 const int len = sun4i_emac_txfifo_transfer(sc, m, slot);
618
619 bus_size_t const pl_reg = EMAC_TX_PL_REG(slot);
620 bus_size_t const ctl_reg = EMAC_TX_CTL_REG(slot);
621
622 sun4i_emac_write(sc, pl_reg, len);
623 sun4i_emac_clear_set(sc, ctl_reg, 0, EMAC_TX_CTL_START);
624
625 bpf_mtap(ifp, m, BPF_D_OUT);
626
627 m_freem(m);
628 }
629
630 static void
631 sun4i_emac_tx_intr(struct sun4i_emac_softc *sc, u_int slot)
632 {
633 struct ifnet * const ifp = &sc->sc_ec.ec_if;
634
635 sc->sc_tx_active &= ~__BIT(slot);
636 ifp->if_flags &= ~IFF_OACTIVE;
637 }
638
639 int
640 sun4i_emac_intr(void *arg)
641 {
642 struct sun4i_emac_softc * const sc = arg;
643 struct ifnet * const ifp = &sc->sc_ec.ec_if;
644
645 mutex_enter(&sc->sc_intr_lock);
646
647 uint32_t sts = sun4i_emac_read(sc, EMAC_INT_STA_REG);
648 sun4i_emac_write(sc, EMAC_INT_STA_REG, sts);
649 rnd_add_uint32(&sc->sc_rnd_source, sts);
650
651 if (sts & EMAC_INT_RX) {
652 sun4i_emac_rx_intr(sc);
653 }
654 if (sts & EMAC_INT_TX0) {
655 sun4i_emac_tx_intr(sc, 0);
656 }
657 if (sts & EMAC_INT_TX1) {
658 sun4i_emac_tx_intr(sc, 1);
659 }
660 if (sts & (EMAC_INT_TX0|EMAC_INT_TX1)) {
661 if (sc->sc_tx_active == 0)
662 ifp->if_timer = 0;
663 if_schedule_deferred_start(ifp);
664 }
665
666 mutex_exit(&sc->sc_intr_lock);
667
668 return 1;
669 }
670
671 void
672 sun4i_emac_ifstart(struct ifnet *ifp)
673 {
674 struct sun4i_emac_softc * const sc = ifp->if_softc;
675
676 mutex_enter(&sc->sc_intr_lock);
677
678 if ((sc->sc_tx_active & 1) == 0) {
679 struct mbuf *m;
680 IFQ_DEQUEUE(&ifp->if_snd, m);
681 if (m == NULL) {
682 mutex_exit(&sc->sc_intr_lock);
683 return;
684 }
685 sun4i_emac_tx_enqueue(sc, m, 0);
686 sc->sc_tx_active |= 1;
687 }
688
689 if ((sc->sc_tx_active & 2) == 0) {
690 struct mbuf *m;
691 IFQ_DEQUEUE(&ifp->if_snd, m);
692 if (m == NULL) {
693 mutex_exit(&sc->sc_intr_lock);
694 return;
695 }
696 sun4i_emac_tx_enqueue(sc, m, 1);
697 sc->sc_tx_active |= 2;
698 }
699
700 if (sc->sc_tx_active == 3)
701 ifp->if_flags |= IFF_OACTIVE;
702
703 ifp->if_timer = 5;
704
705 mutex_exit(&sc->sc_intr_lock);
706 }
707
708
709 static int
710 sun4i_emac_ifioctl(struct ifnet *ifp, u_long cmd, void *data)
711 {
712 struct sun4i_emac_softc * const sc = ifp->if_softc;
713 struct ifreq *ifr = (struct ifreq *)data;
714 int error;
715
716 switch (cmd) {
717 case SIOCGIFMEDIA:
718 case SIOCSIFMEDIA:
719 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
720 break;
721 default:
722 if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET)
723 break;
724 error = 0;
725 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
726 break;
727 if (ifp->if_flags & IFF_RUNNING) {
728 /*
729 * Multicast list has changed; set the hardware filter
730 * accordingly.
731 */
732 mutex_enter(&sc->sc_intr_lock);
733 sun4i_emac_ifstop(ifp, 0);
734 error = sun4i_emac_ifinit(ifp);
735 mutex_exit(&sc->sc_intr_lock);
736 }
737 break;
738 }
739
740 return error;
741 }
742
743 static void
744 sun4i_emac_ifstop(struct ifnet *ifp, int discard)
745 {
746 struct sun4i_emac_softc * const sc = ifp->if_softc;
747 struct mii_data * const mii = &sc->sc_mii;
748
749 KASSERT(mutex_owned(&sc->sc_intr_lock));
750
751 callout_stop(&sc->sc_stat_ch);
752 mii_down(mii);
753
754 sun4i_emac_write(sc, EMAC_INT_CTL_REG, 0);
755 sun4i_emac_write(sc, EMAC_INT_STA_REG,
756 sun4i_emac_read(sc, EMAC_INT_STA_REG));
757
758 sun4i_emac_clear_set(sc, EMAC_CTL_REG,
759 EMAC_CTL_RST | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN, 0);
760
761 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
762 ifp->if_timer = 0;
763 }
764
765 int
766 sun4i_emac_ifinit(struct ifnet *ifp)
767 {
768 struct sun4i_emac_softc * const sc = ifp->if_softc;
769 struct mii_data * const mii = &sc->sc_mii;
770
771 sun4i_emac_clear_set(sc, EMAC_RX_CTL_REG,
772 0, EMAC_RX_CTL_FIFO_RESET);
773
774 delay(1);
775
776 sun4i_emac_clear_set(sc, EMAC_MAC_CTL0_REG,
777 EMAC_MAC_CTL0_SOFT_RESET, 0);
778
779 sun4i_emac_clear_set(sc, EMAC_MAC_MCFG_REG,
780 EMAC_MAC_MCFG_CLK, __SHIFTIN(0xd, EMAC_MAC_MCFG_CLK));
781
782 sun4i_emac_write(sc, EMAC_RX_FBC_REG, 0);
783
784 sun4i_emac_write(sc, EMAC_INT_CTL_REG, 0);
785 sun4i_emac_write(sc, EMAC_INT_STA_REG,
786 sun4i_emac_read(sc, EMAC_INT_STA_REG));
787
788 delay(1);
789
790 sun4i_emac_clear_set(sc, EMAC_TX_MODE_REG,
791 EMAC_TX_MODE_DMA, EMAC_TX_MODE_ABF_ENA);
792
793 sun4i_emac_clear_set(sc, EMAC_MAC_CTL0_REG,
794 0, EMAC_MAC_CTL0_TFC | EMAC_MAC_CTL0_RFC);
795
796 sun4i_emac_clear_set(sc, EMAC_RX_CTL_REG,
797 EMAC_RX_CTL_DMA, 0);
798
799 sun4i_emac_clear_set(sc, EMAC_MAC_CTL1_REG,
800 0,
801 EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC |
802 EMAC_MAC_CTL1_PC);
803
804 sun4i_emac_write(sc, EMAC_MAC_IPGT_REG, EMAC_MAC_IPGT_FD);
805 sun4i_emac_write(sc, EMAC_MAC_IPGR_REG,
806 __SHIFTIN(0x0c, EMAC_MAC_IPGR_IPG1) |
807 __SHIFTIN(0x12, EMAC_MAC_IPGR_IPG2));
808
809 sun4i_emac_write(sc, EMAC_MAC_CLRT_REG,
810 __SHIFTIN(0x0f, EMAC_MAC_CLRT_RM) |
811 __SHIFTIN(0x37, EMAC_MAC_CLRT_CW));
812
813 sun4i_emac_write(sc, EMAC_MAC_MAXF_REG, 0x600);
814
815 sun4i_emac_rx_hash(sc);
816
817 sun4i_emac_int_enable(sc);
818
819 ifp->if_flags |= IFF_RUNNING;
820 ifp->if_flags &= ~IFF_OACTIVE;
821
822 /* Enable RX/TX */
823 sun4i_emac_clear_set(sc, EMAC_CTL_REG,
824 0, EMAC_CTL_RST | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN);
825
826 mii_mediachg(mii);
827 callout_schedule(&sc->sc_stat_ch, hz);
828
829 return 0;
830 }
831
832 static void
833 sun4i_emac_ifwatchdog(struct ifnet *ifp)
834 {
835 struct sun4i_emac_softc * const sc = ifp->if_softc;
836
837 device_printf(sc->sc_dev, "device timeout\n");
838
839 ifp->if_oerrors++;
840 sun4i_emac_ifinit(ifp);
841 sun4i_emac_ifstart(ifp);
842 }
843
844 static void
845 sun4i_emac_rx_hash(struct sun4i_emac_softc *sc)
846 {
847 struct ifnet * const ifp = &sc->sc_ec.ec_if;
848 struct ether_multistep step;
849 struct ether_multi *enm;
850 uint32_t hash[2];
851 uint32_t rxctl;
852
853 rxctl = sun4i_emac_read(sc, EMAC_RX_CTL_REG);
854 rxctl &= ~EMAC_RX_CTL_MHF;
855 rxctl |= EMAC_RX_CTL_UCAD;
856 rxctl |= EMAC_RX_CTL_DAF;
857 rxctl |= EMAC_RX_CTL_MC0;
858 rxctl |= EMAC_RX_CTL_BC0;
859 rxctl |= EMAC_RX_CTL_POR;
860
861 hash[0] = hash[1] = ~0;
862 if (ifp->if_flags & IFF_PROMISC) {
863 ifp->if_flags |= IFF_ALLMULTI;
864 rxctl |= EMAC_RX_CTL_PROMISC;
865 } else {
866 rxctl &= ~EMAC_RX_CTL_PROMISC;
867 }
868
869 if ((ifp->if_flags & IFF_PROMISC) == 0) {
870 hash[0] = hash[1] = 0;
871
872 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
873 while (enm != NULL) {
874 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
875 /*
876 * We must listen to a range of multicast addresses.
877 * For now, just accept all multicasts, rather than
878 * trying to set only those filter bits needed to match
879 * the range. (At this time, the only use of address
880 * ranges is for IP multicast routing, for which the
881 * range is big enough to require all bits set.)
882 */
883 hash[0] = hash[1] = ~0;
884 ifp->if_flags |= IFF_ALLMULTI;
885 goto done;
886 }
887
888 u_int crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
889
890 /* Just want the 6 most significant bits. */
891 crc >>= 26;
892
893 /* Set the corresponding bit in the filter. */
894 hash[crc >> 5] |= __BIT(crc & 31);
895 ETHER_NEXT_MULTI(step, enm);
896 }
897 ifp->if_flags &= ~IFF_ALLMULTI;
898 rxctl |= EMAC_RX_CTL_MHF;
899 }
900
901 done:
902
903 sun4i_emac_write(sc, EMAC_RX_HASH0_REG, hash[0]);
904 sun4i_emac_write(sc, EMAC_RX_HASH1_REG, hash[1]);
905
906 sun4i_emac_write(sc, EMAC_RX_CTL_REG, rxctl);
907 }
908