1 /* $OpenBSD: if_lii.c,v 1.48 2024/08/31 16:23:09 deraadt Exp $ */
2
3 /*
4 * Copyright (c) 2007 The NetBSD Foundation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * Driver for Attansic/Atheros's L2 Fast Ethernet controller
31 */
32
33 #include "bpfilter.h"
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/sockio.h>
38 #include <sys/mbuf.h>
39 #include <sys/socket.h>
40 #include <sys/device.h>
41 #include <sys/timeout.h>
42
43 #include <machine/bus.h>
44
45 #include <net/if.h>
46 #include <net/if_media.h>
47
48 #if NBPFILTER > 0
49 #include <net/bpf.h>
50 #endif
51
52 #include <netinet/in.h>
53 #include <netinet/if_ether.h>
54
55 #include <dev/mii/miivar.h>
56
57 #include <dev/pci/pcireg.h>
58 #include <dev/pci/pcivar.h>
59 #include <dev/pci/pcidevs.h>
60
61 #include <dev/pci/if_liireg.h>
62
63 /*#define LII_DEBUG*/
64 #ifdef LII_DEBUG
65 #define DPRINTF(x) printf x
66 #else
67 #define DPRINTF(x)
68 #endif
69
70 struct lii_softc {
71 struct device sc_dev;
72 pci_chipset_tag_t sc_pc;
73 pcitag_t sc_tag;
74
75 bus_space_tag_t sc_mmiot;
76 bus_space_handle_t sc_mmioh;
77 bus_size_t sc_mmios;
78
79 /*
80 * We allocate a big chunk of DMA-safe memory for all data exchanges.
81 * It is unfortunate that this chip doesn't seem to do scatter-gather.
82 */
83 bus_dma_tag_t sc_dmat;
84 bus_dmamap_t sc_ringmap;
85 bus_dma_segment_t sc_ringseg;
86
87 uint8_t *sc_ring; /* the whole area */
88 size_t sc_ringsize;
89
90 struct rx_pkt *sc_rxp; /* the part used for RX */
91 struct tx_pkt_status *sc_txs; /* the parts used for TX */
92 bus_addr_t sc_txsp;
93 char *sc_txdbase;
94 bus_addr_t sc_txdp;
95
96 unsigned int sc_rxcur;
97 /* the active area is [ack; cur[ */
98 int sc_txs_cur;
99 int sc_txs_ack;
100 int sc_txd_cur;
101 int sc_txd_ack;
102 int sc_free_tx_slots;
103
104 void *sc_ih;
105
106 struct arpcom sc_ac;
107 struct mii_data sc_mii;
108 struct timeout sc_tick;
109
110 int (*sc_memread)(struct lii_softc *, uint32_t,
111 uint32_t *);
112 };
113
114 #define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
115
116 int lii_match(struct device *, void *, void *);
117 void lii_attach(struct device *, struct device *, void *);
118 int lii_activate(struct device *, int);
119
120 struct cfdriver lii_cd = {
121 0,
122 "lii",
123 DV_IFNET
124 };
125
126 const struct cfattach lii_ca = {
127 sizeof(struct lii_softc),
128 lii_match,
129 lii_attach,
130 NULL,
131 lii_activate
132 };
133
134 int lii_reset(struct lii_softc *);
135 int lii_eeprom_present(struct lii_softc *);
136 void lii_read_macaddr(struct lii_softc *, uint8_t *);
137 int lii_eeprom_read(struct lii_softc *, uint32_t, uint32_t *);
138 void lii_spi_configure(struct lii_softc *);
139 int lii_spi_read(struct lii_softc *, uint32_t, uint32_t *);
140 void lii_iff(struct lii_softc *);
141 void lii_tick(void *);
142
143 int lii_alloc_rings(struct lii_softc *);
144 int lii_free_tx_space(struct lii_softc *);
145 void lii_tx_put(struct lii_softc *, struct mbuf *);
146
147 int lii_mii_readreg(struct device *, int, int);
148 void lii_mii_writereg(struct device *, int, int, int);
149 void lii_mii_statchg(struct device *);
150
151 int lii_media_change(struct ifnet *);
152 void lii_media_status(struct ifnet *, struct ifmediareq *);
153
154 int lii_init(struct ifnet *);
155 void lii_start(struct ifnet *);
156 void lii_stop(struct ifnet *);
157 void lii_watchdog(struct ifnet *);
158 int lii_ioctl(struct ifnet *, u_long, caddr_t);
159
160 int lii_intr(void *);
161 void lii_rxintr(struct lii_softc *);
162 void lii_txintr(struct lii_softc *);
163
164 const struct pci_matchid lii_devices[] = {
165 { PCI_VENDOR_ATTANSIC, PCI_PRODUCT_ATTANSIC_L2 }
166 };
167
168 #define LII_READ_4(sc,reg) \
169 bus_space_read_4((sc)->sc_mmiot, (sc)->sc_mmioh, (reg))
170 #define LII_READ_2(sc,reg) \
171 bus_space_read_2((sc)->sc_mmiot, (sc)->sc_mmioh, (reg))
172 #define LII_READ_1(sc,reg) \
173 bus_space_read_1((sc)->sc_mmiot, (sc)->sc_mmioh, (reg))
174 #define LII_WRITE_4(sc,reg,val) \
175 bus_space_write_4((sc)->sc_mmiot, (sc)->sc_mmioh, (reg), (val))
176 #define LII_WRITE_2(sc,reg,val) \
177 bus_space_write_2((sc)->sc_mmiot, (sc)->sc_mmioh, (reg), (val))
178 #define LII_WRITE_1(sc,reg,val) \
179 bus_space_write_1((sc)->sc_mmiot, (sc)->sc_mmioh, (reg), (val))
180
181 /*
182 * Those are the default Linux parameters.
183 */
184
185 #define AT_TXD_NUM 64
186 #define AT_TXD_BUFFER_SIZE 8192
187 #define AT_RXD_NUM 64
188
189 /* Pad the RXD buffer so that the packets are on a 128-byte boundary. */
190 #define AT_RXD_PADDING 120
191
192 int
lii_match(struct device * parent,void * match,void * aux)193 lii_match(struct device *parent, void *match, void *aux)
194 {
195 return (pci_matchbyid((struct pci_attach_args *)aux, lii_devices,
196 nitems(lii_devices)));
197 }
198
199 void
lii_attach(struct device * parent,struct device * self,void * aux)200 lii_attach(struct device *parent, struct device *self, void *aux)
201 {
202 struct lii_softc *sc = (struct lii_softc *)self;
203 struct pci_attach_args *pa = aux;
204 struct ifnet *ifp = &sc->sc_ac.ac_if;
205 pci_intr_handle_t ih;
206 pcireg_t memtype;
207
208 sc->sc_pc = pa->pa_pc;
209 sc->sc_tag = pa->pa_tag;
210 sc->sc_dmat = pa->pa_dmat;
211
212 memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, PCI_MAPREG_START);
213 if (pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0, &sc->sc_mmiot,
214 &sc->sc_mmioh, NULL, &sc->sc_mmios, 0)) {
215 printf(": can't map mem space\n");
216 return;
217 }
218
219 if (lii_reset(sc))
220 goto unmap;
221
222 lii_spi_configure(sc);
223
224 if (lii_eeprom_present(sc))
225 sc->sc_memread = lii_eeprom_read;
226 else
227 sc->sc_memread = lii_spi_read;
228
229 lii_read_macaddr(sc, sc->sc_ac.ac_enaddr);
230
231 if (pci_intr_map(pa, &ih) != 0) {
232 printf(": can't map interrupt\n");
233 goto unmap;
234 }
235 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_NET,
236 lii_intr, sc, DEVNAME(sc));
237 if (sc->sc_ih == NULL) {
238 printf(": can't establish interrupt\n");
239 goto unmap;
240 }
241
242 if (lii_alloc_rings(sc))
243 goto deintr;
244
245 printf(": %s, address %s\n", pci_intr_string(sc->sc_pc, ih),
246 ether_sprintf(sc->sc_ac.ac_enaddr));
247
248 timeout_set(&sc->sc_tick, lii_tick, sc);
249
250 sc->sc_mii.mii_ifp = ifp;
251 sc->sc_mii.mii_readreg = lii_mii_readreg;
252 sc->sc_mii.mii_writereg = lii_mii_writereg;
253 sc->sc_mii.mii_statchg = lii_mii_statchg;
254 ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, lii_media_change,
255 lii_media_status);
256 mii_attach(self, &sc->sc_mii, 0xffffffff, 1,
257 MII_OFFSET_ANY, 0);
258 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
259
260 strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
261 ifp->if_softc = sc;
262 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
263 ifp->if_capabilities = IFCAP_VLAN_MTU;
264 ifp->if_ioctl = lii_ioctl;
265 ifp->if_start = lii_start;
266 ifp->if_watchdog = lii_watchdog;
267
268 if_attach(ifp);
269 ether_ifattach(ifp);
270
271 return;
272
273 deintr:
274 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
275 unmap:
276 bus_space_unmap(sc->sc_mmiot, sc->sc_mmioh, sc->sc_mmios);
277 return;
278 }
279
280 int
lii_activate(struct device * self,int act)281 lii_activate(struct device *self, int act)
282 {
283 struct lii_softc *sc = (struct lii_softc *)self;
284 struct ifnet *ifp = &sc->sc_ac.ac_if;
285
286 switch (act) {
287 case DVACT_SUSPEND:
288 if (ifp->if_flags & IFF_RUNNING)
289 lii_stop(ifp);
290 break;
291 case DVACT_RESUME:
292 if (ifp->if_flags & IFF_UP)
293 lii_init(ifp);
294 break;
295 }
296 return (0);
297 }
298
299 int
lii_reset(struct lii_softc * sc)300 lii_reset(struct lii_softc *sc)
301 {
302 int i;
303
304 DPRINTF(("lii_reset\n"));
305
306 LII_WRITE_4(sc, LII_SMC, SMC_SOFT_RST);
307 DELAY(1000);
308
309 for (i = 0; i < 10; ++i) {
310 if (LII_READ_4(sc, LII_BIS) == 0)
311 break;
312 DELAY(1000);
313 }
314
315 if (i == 10) {
316 printf("%s: reset failed\n", DEVNAME(sc));
317 return 1;
318 }
319
320 LII_WRITE_4(sc, LII_PHYC, PHYC_ENABLE);
321 DELAY(10);
322
323 /* Init PCI-Express module */
324 /* Magic Numbers Warning */
325 LII_WRITE_4(sc, 0x12fc, 0x00006500);
326 LII_WRITE_4(sc, 0x1008, 0x00008000 |
327 LII_READ_4(sc, 0x1008));
328
329 return 0;
330 }
331
332 int
lii_eeprom_present(struct lii_softc * sc)333 lii_eeprom_present(struct lii_softc *sc)
334 {
335 uint32_t val;
336
337 val = LII_READ_4(sc, LII_SFC);
338 if (val & SFC_EN_VPD)
339 LII_WRITE_4(sc, LII_SFC, val & ~(SFC_EN_VPD));
340
341 return pci_get_capability(sc->sc_pc, sc->sc_tag, PCI_CAP_VPD,
342 NULL, NULL) == 1;
343 }
344
345 int
lii_eeprom_read(struct lii_softc * sc,uint32_t reg,uint32_t * val)346 lii_eeprom_read(struct lii_softc *sc, uint32_t reg, uint32_t *val)
347 {
348 return pci_vpd_read(sc->sc_pc, sc->sc_tag, reg, 1, (pcireg_t *)val);
349 }
350
351 void
lii_spi_configure(struct lii_softc * sc)352 lii_spi_configure(struct lii_softc *sc)
353 {
354 /*
355 * We don't offer a way to configure the SPI Flash vendor parameter, so
356 * the table is given for reference
357 */
358 static const struct lii_spi_flash_vendor {
359 const char *sfv_name;
360 const uint8_t sfv_opcodes[9];
361 } lii_sfv[] = {
362 { "Atmel", { 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62 } },
363 { "SST", { 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60 } },
364 { "ST", { 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xab, 0xd8, 0xc7 } },
365 };
366 #define SF_OPCODE_WRSR 0
367 #define SF_OPCODE_READ 1
368 #define SF_OPCODE_PRGM 2
369 #define SF_OPCODE_WREN 3
370 #define SF_OPCODE_WRDI 4
371 #define SF_OPCODE_RDSR 5
372 #define SF_OPCODE_RDID 6
373 #define SF_OPCODE_SECT_ER 7
374 #define SF_OPCODE_CHIP_ER 8
375
376 #define SF_DEFAULT_VENDOR 0
377 static const uint8_t vendor = SF_DEFAULT_VENDOR;
378
379 /*
380 * Why isn't WRDI used? Heck if I know.
381 */
382
383 LII_WRITE_1(sc, LII_SFOP_WRSR,
384 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_WRSR]);
385 LII_WRITE_1(sc, LII_SFOP_READ,
386 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_READ]);
387 LII_WRITE_1(sc, LII_SFOP_PROGRAM,
388 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_PRGM]);
389 LII_WRITE_1(sc, LII_SFOP_WREN,
390 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_WREN]);
391 LII_WRITE_1(sc, LII_SFOP_RDSR,
392 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_RDSR]);
393 LII_WRITE_1(sc, LII_SFOP_RDID,
394 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_RDID]);
395 LII_WRITE_1(sc, LII_SFOP_SC_ERASE,
396 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_SECT_ER]);
397 LII_WRITE_1(sc, LII_SFOP_CHIP_ERASE,
398 lii_sfv[vendor].sfv_opcodes[SF_OPCODE_CHIP_ER]);
399 }
400
401 #define MAKE_SFC(cssetup, clkhi, clklo, cshold, cshi, ins) \
402 ( (((cssetup) & SFC_CS_SETUP_MASK) \
403 << SFC_CS_SETUP_SHIFT) \
404 | (((clkhi) & SFC_CLK_HI_MASK) \
405 << SFC_CLK_HI_SHIFT) \
406 | (((clklo) & SFC_CLK_LO_MASK) \
407 << SFC_CLK_LO_SHIFT) \
408 | (((cshold) & SFC_CS_HOLD_MASK) \
409 << SFC_CS_HOLD_SHIFT) \
410 | (((cshi) & SFC_CS_HI_MASK) \
411 << SFC_CS_HI_SHIFT) \
412 | (((ins) & SFC_INS_MASK) \
413 << SFC_INS_SHIFT))
414
415 #define CUSTOM_SPI_CS_SETUP 2
416 #define CUSTOM_SPI_CLK_HI 2
417 #define CUSTOM_SPI_CLK_LO 2
418 #define CUSTOM_SPI_CS_HOLD 2
419 #define CUSTOM_SPI_CS_HI 3
420
421 int
lii_spi_read(struct lii_softc * sc,uint32_t reg,uint32_t * val)422 lii_spi_read(struct lii_softc *sc, uint32_t reg, uint32_t *val)
423 {
424 uint32_t v;
425 int i;
426
427 LII_WRITE_4(sc, LII_SF_DATA, 0);
428 LII_WRITE_4(sc, LII_SF_ADDR, reg);
429
430 v = SFC_WAIT_READY |
431 MAKE_SFC(CUSTOM_SPI_CS_SETUP, CUSTOM_SPI_CLK_HI,
432 CUSTOM_SPI_CLK_LO, CUSTOM_SPI_CS_HOLD, CUSTOM_SPI_CS_HI, 1);
433
434 LII_WRITE_4(sc, LII_SFC, v);
435 v |= SFC_START;
436 LII_WRITE_4(sc, LII_SFC, v);
437
438 for (i = 0; i < 10; ++i) {
439 DELAY(1000);
440 if (!(LII_READ_4(sc, LII_SFC) & SFC_START))
441 break;
442 }
443 if (i == 10)
444 return EBUSY;
445
446 *val = LII_READ_4(sc, LII_SF_DATA);
447 return 0;
448 }
449
450 void
lii_read_macaddr(struct lii_softc * sc,uint8_t * ea)451 lii_read_macaddr(struct lii_softc *sc, uint8_t *ea)
452 {
453 uint32_t offset = 0x100;
454 uint32_t val, val1, addr0 = 0, addr1 = 0;
455 uint8_t found = 0;
456
457 while ((*sc->sc_memread)(sc, offset, &val) == 0) {
458 offset += 4;
459
460 /* Each chunk of data starts with a signature */
461 if ((val & 0xff) != 0x5a)
462 break;
463 if ((*sc->sc_memread)(sc, offset, &val1))
464 break;
465
466 offset += 4;
467
468 val >>= 16;
469 switch (val) {
470 case LII_MAC_ADDR_0:
471 addr0 = val1;
472 ++found;
473 break;
474 case LII_MAC_ADDR_1:
475 addr1 = val1;
476 ++found;
477 break;
478 default:
479 continue;
480 }
481 }
482
483 #ifdef LII_DEBUG
484 if (found < 2)
485 printf(": error reading MAC address, using registers...\n");
486 #endif
487
488 addr0 = htole32(addr0);
489 addr1 = htole32(addr1);
490
491 if ((addr0 == 0xffffff && (addr1 & 0xffff) == 0xffff) ||
492 (addr0 == 0 && (addr1 & 0xffff) == 0)) {
493 addr0 = htole32(LII_READ_4(sc, LII_MAC_ADDR_0));
494 addr1 = htole32(LII_READ_4(sc, LII_MAC_ADDR_1));
495 }
496
497 ea[0] = (addr1 & 0x0000ff00) >> 8;
498 ea[1] = (addr1 & 0x000000ff);
499 ea[2] = (addr0 & 0xff000000) >> 24;
500 ea[3] = (addr0 & 0x00ff0000) >> 16;
501 ea[4] = (addr0 & 0x0000ff00) >> 8;
502 ea[5] = (addr0 & 0x000000ff);
503 }
504
505 int
lii_mii_readreg(struct device * dev,int phy,int reg)506 lii_mii_readreg(struct device *dev, int phy, int reg)
507 {
508 struct lii_softc *sc = (struct lii_softc *)dev;
509 uint32_t val;
510 int i;
511
512 val = (reg & MDIOC_REG_MASK) << MDIOC_REG_SHIFT;
513
514 val |= MDIOC_START | MDIOC_SUP_PREAMBLE;
515 val |= MDIOC_CLK_25_4 << MDIOC_CLK_SEL_SHIFT;
516
517 val |= MDIOC_READ;
518
519 LII_WRITE_4(sc, LII_MDIOC, val);
520
521 for (i = 0; i < MDIO_WAIT_TIMES; ++i) {
522 DELAY(2);
523 val = LII_READ_4(sc, LII_MDIOC);
524 if ((val & (MDIOC_START | MDIOC_BUSY)) == 0)
525 break;
526 }
527
528 if (i == MDIO_WAIT_TIMES) {
529 printf("%s: timeout reading PHY %d reg %d\n", DEVNAME(sc), phy,
530 reg);
531 }
532
533 return (val & 0x0000ffff);
534 }
535
536 void
lii_mii_writereg(struct device * dev,int phy,int reg,int data)537 lii_mii_writereg(struct device *dev, int phy, int reg, int data)
538 {
539 struct lii_softc *sc = (struct lii_softc *)dev;
540 uint32_t val;
541 int i;
542
543 val = (reg & MDIOC_REG_MASK) << MDIOC_REG_SHIFT;
544 val |= (data & MDIOC_DATA_MASK) << MDIOC_DATA_SHIFT;
545
546 val |= MDIOC_START | MDIOC_SUP_PREAMBLE;
547 val |= MDIOC_CLK_25_4 << MDIOC_CLK_SEL_SHIFT;
548
549 /* val |= MDIOC_WRITE; */
550
551 LII_WRITE_4(sc, LII_MDIOC, val);
552
553 for (i = 0; i < MDIO_WAIT_TIMES; ++i) {
554 DELAY(2);
555 val = LII_READ_4(sc, LII_MDIOC);
556 if ((val & (MDIOC_START | MDIOC_BUSY)) == 0)
557 break;
558 }
559
560 if (i == MDIO_WAIT_TIMES) {
561 printf("%s: timeout writing PHY %d reg %d\n", DEVNAME(sc), phy,
562 reg);
563 }
564 }
565
566 void
lii_mii_statchg(struct device * dev)567 lii_mii_statchg(struct device *dev)
568 {
569 struct lii_softc *sc = (struct lii_softc *)dev;
570 uint32_t val;
571
572 DPRINTF(("lii_mii_statchg\n"));
573
574 val = LII_READ_4(sc, LII_MACC);
575
576 if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX)
577 val |= MACC_FDX;
578 else
579 val &= ~MACC_FDX;
580
581 LII_WRITE_4(sc, LII_MACC, val);
582 }
583
584 int
lii_media_change(struct ifnet * ifp)585 lii_media_change(struct ifnet *ifp)
586 {
587 struct lii_softc *sc = ifp->if_softc;
588
589 DPRINTF(("lii_media_change\n"));
590
591 if (ifp->if_flags & IFF_UP)
592 mii_mediachg(&sc->sc_mii);
593 return 0;
594 }
595
596 void
lii_media_status(struct ifnet * ifp,struct ifmediareq * imr)597 lii_media_status(struct ifnet *ifp, struct ifmediareq *imr)
598 {
599 struct lii_softc *sc = ifp->if_softc;
600
601 DPRINTF(("lii_media_status\n"));
602
603 mii_pollstat(&sc->sc_mii);
604 imr->ifm_status = sc->sc_mii.mii_media_status;
605 imr->ifm_active = sc->sc_mii.mii_media_active;
606 }
607
608 int
lii_init(struct ifnet * ifp)609 lii_init(struct ifnet *ifp)
610 {
611 struct lii_softc *sc = ifp->if_softc;
612 uint32_t val;
613 int error;
614
615 DPRINTF(("lii_init\n"));
616
617 lii_stop(ifp);
618
619 memset(sc->sc_ring, 0, sc->sc_ringsize);
620
621 /* Disable all interrupts */
622 LII_WRITE_4(sc, LII_ISR, 0xffffffff);
623
624 LII_WRITE_4(sc, LII_DESC_BASE_ADDR_HI, 0);
625 /* XXX
626 sc->sc_ringmap->dm_segs[0].ds_addr >> 32);
627 */
628 LII_WRITE_4(sc, LII_RXD_BASE_ADDR_LO,
629 (sc->sc_ringmap->dm_segs[0].ds_addr & 0xffffffff)
630 + AT_RXD_PADDING);
631 LII_WRITE_4(sc, LII_TXS_BASE_ADDR_LO,
632 sc->sc_txsp & 0xffffffff);
633 LII_WRITE_4(sc, LII_TXD_BASE_ADDR_LO,
634 sc->sc_txdp & 0xffffffff);
635
636 LII_WRITE_2(sc, LII_TXD_BUFFER_SIZE, AT_TXD_BUFFER_SIZE / 4);
637 LII_WRITE_2(sc, LII_TXS_NUM_ENTRIES, AT_TXD_NUM);
638 LII_WRITE_2(sc, LII_RXD_NUM_ENTRIES, AT_RXD_NUM);
639
640 /*
641 * Inter Packet Gap Time = 0x60 (IPGT)
642 * Minimum inter-frame gap for RX = 0x50 (MIFG)
643 * 64-bit Carrier-Sense window = 0x40 (IPGR1)
644 * 96-bit IPG window = 0x60 (IPGR2)
645 */
646 LII_WRITE_4(sc, LII_MIPFG, 0x60405060);
647
648 /*
649 * Collision window = 0x37 (LCOL)
650 * Maximum # of retrans = 0xf (RETRY)
651 * Maximum binary expansion # = 0xa (ABEBT)
652 * IPG to start jam = 0x7 (JAMIPG)
653 */
654 LII_WRITE_4(sc, LII_MHDC, 0x07a0f037 |
655 MHDC_EXC_DEF_EN);
656
657 /* 100 means 200us */
658 LII_WRITE_2(sc, LII_IMTIV, 100);
659 LII_WRITE_2(sc, LII_SMC, SMC_ITIMER_EN);
660
661 /* 500000 means 100ms */
662 LII_WRITE_2(sc, LII_IALTIV, 50000);
663
664 LII_WRITE_4(sc, LII_MTU, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
665
666 /* unit unknown for TX cur-through threshold */
667 LII_WRITE_4(sc, LII_TX_CUT_THRESH, 0x177);
668
669 LII_WRITE_2(sc, LII_PAUSE_ON_TH, AT_RXD_NUM * 7 / 8);
670 LII_WRITE_2(sc, LII_PAUSE_OFF_TH, AT_RXD_NUM / 12);
671
672 sc->sc_rxcur = 0;
673 sc->sc_txs_cur = sc->sc_txs_ack = 0;
674 sc->sc_txd_cur = sc->sc_txd_ack = 0;
675 sc->sc_free_tx_slots = 1;
676 LII_WRITE_2(sc, LII_MB_TXD_WR_IDX, sc->sc_txd_cur);
677 LII_WRITE_2(sc, LII_MB_RXD_RD_IDX, sc->sc_rxcur);
678
679 LII_WRITE_1(sc, LII_DMAR, DMAR_EN);
680 LII_WRITE_1(sc, LII_DMAW, DMAW_EN);
681
682 LII_WRITE_4(sc, LII_SMC, LII_READ_4(sc, LII_SMC) | SMC_MANUAL_INT);
683
684 error = ((LII_READ_4(sc, LII_ISR) & ISR_PHY_LINKDOWN) != 0);
685 LII_WRITE_4(sc, LII_ISR, 0x3fffffff);
686 LII_WRITE_4(sc, LII_ISR, 0);
687 if (error) {
688 printf("%s: init failed\n", DEVNAME(sc));
689 goto out;
690 }
691
692 /*
693 * Initialise MAC.
694 */
695 val = LII_READ_4(sc, LII_MACC) & MACC_FDX;
696
697 val |= MACC_RX_EN | MACC_TX_EN | MACC_MACLP_CLK_PHY |
698 MACC_TX_FLOW_EN | MACC_RX_FLOW_EN | MACC_ADD_CRC |
699 MACC_PAD;
700
701 val |= 7 << MACC_PREAMBLE_LEN_SHIFT;
702 val |= 2 << MACC_HDX_LEFT_BUF_SHIFT;
703
704 LII_WRITE_4(sc, LII_MACC, val);
705
706 /* Set the hardware MAC address. */
707 LII_WRITE_4(sc, LII_MAC_ADDR_0, letoh32((sc->sc_ac.ac_enaddr[2] << 24) |
708 (sc->sc_ac.ac_enaddr[3] << 16) | (sc->sc_ac.ac_enaddr[4] << 8) |
709 sc->sc_ac.ac_enaddr[5]));
710 LII_WRITE_4(sc, LII_MAC_ADDR_1,
711 letoh32((sc->sc_ac.ac_enaddr[0] << 8) | sc->sc_ac.ac_enaddr[1]));
712
713 /* Program promiscuous mode and multicast filters. */
714 lii_iff(sc);
715
716 mii_mediachg(&sc->sc_mii);
717
718 LII_WRITE_4(sc, LII_IMR, IMR_NORMAL_MASK);
719
720 timeout_add_sec(&sc->sc_tick, 1);
721
722 ifp->if_flags |= IFF_RUNNING;
723 ifq_clr_oactive(&ifp->if_snd);
724
725 out:
726 return error;
727 }
728
729 void
lii_tx_put(struct lii_softc * sc,struct mbuf * m)730 lii_tx_put(struct lii_softc *sc, struct mbuf *m)
731 {
732 int left;
733 struct tx_pkt_header *tph =
734 (struct tx_pkt_header *)(sc->sc_txdbase + sc->sc_txd_cur);
735
736 memset(tph, 0, sizeof *tph);
737 tph->txph_size = m->m_pkthdr.len;
738
739 sc->sc_txd_cur = (sc->sc_txd_cur + 4) % AT_TXD_BUFFER_SIZE;
740
741 /*
742 * We already know we have enough space, so if there is a part of the
743 * space ahead of txd_cur that is active, it doesn't matter because
744 * left will be large enough even without it.
745 */
746 left = AT_TXD_BUFFER_SIZE - sc->sc_txd_cur;
747
748 if (left > m->m_pkthdr.len) {
749 m_copydata(m, 0, m->m_pkthdr.len,
750 sc->sc_txdbase + sc->sc_txd_cur);
751 sc->sc_txd_cur += m->m_pkthdr.len;
752 } else {
753 m_copydata(m, 0, left, sc->sc_txdbase + sc->sc_txd_cur);
754 m_copydata(m, left, m->m_pkthdr.len - left, sc->sc_txdbase);
755 sc->sc_txd_cur = m->m_pkthdr.len - left;
756 }
757
758 /* Round to a 32-bit boundary */
759 sc->sc_txd_cur = ((sc->sc_txd_cur + 3) & ~3) % AT_TXD_BUFFER_SIZE;
760 if (sc->sc_txd_cur == sc->sc_txd_ack)
761 sc->sc_free_tx_slots = 0;
762 }
763
764 int
lii_free_tx_space(struct lii_softc * sc)765 lii_free_tx_space(struct lii_softc *sc)
766 {
767 int space;
768
769 if (sc->sc_txd_cur >= sc->sc_txd_ack)
770 space = (AT_TXD_BUFFER_SIZE - sc->sc_txd_cur) +
771 sc->sc_txd_ack;
772 else
773 space = sc->sc_txd_ack - sc->sc_txd_cur;
774
775 /* Account for the tx_pkt_header */
776 return (space - 4);
777 }
778
779 void
lii_start(struct ifnet * ifp)780 lii_start(struct ifnet *ifp)
781 {
782 struct lii_softc *sc = ifp->if_softc;
783 struct mbuf *m0;
784
785 DPRINTF(("lii_start\n"));
786
787 if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
788 return;
789
790 for (;;) {
791 m0 = ifq_deq_begin(&ifp->if_snd);
792 if (m0 == NULL)
793 break;
794
795 if (!sc->sc_free_tx_slots ||
796 lii_free_tx_space(sc) < m0->m_pkthdr.len) {
797 ifq_deq_rollback(&ifp->if_snd, m0);
798 ifq_set_oactive(&ifp->if_snd);
799 break;
800 }
801
802 lii_tx_put(sc, m0);
803
804 DPRINTF(("lii_start: put %d\n", sc->sc_txs_cur));
805
806 sc->sc_txs[sc->sc_txs_cur].txps_update = 0;
807 sc->sc_txs_cur = (sc->sc_txs_cur + 1) % AT_TXD_NUM;
808 if (sc->sc_txs_cur == sc->sc_txs_ack)
809 sc->sc_free_tx_slots = 0;
810
811 LII_WRITE_2(sc, LII_MB_TXD_WR_IDX, sc->sc_txd_cur/4);
812
813 ifq_deq_commit(&ifp->if_snd, m0);
814
815 #if NBPFILTER > 0
816 if (ifp->if_bpf != NULL)
817 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
818 #endif
819 m_freem(m0);
820 }
821 }
822
823 void
lii_stop(struct ifnet * ifp)824 lii_stop(struct ifnet *ifp)
825 {
826 struct lii_softc *sc = ifp->if_softc;
827
828 timeout_del(&sc->sc_tick);
829
830 ifp->if_timer = 0;
831 ifp->if_flags &= ~IFF_RUNNING;
832 ifq_clr_oactive(&ifp->if_snd);
833
834 mii_down(&sc->sc_mii);
835
836 lii_reset(sc);
837
838 LII_WRITE_4(sc, LII_IMR, 0);
839 }
840
841 int
lii_intr(void * v)842 lii_intr(void *v)
843 {
844 struct lii_softc *sc = v;
845 uint32_t status;
846
847 status = LII_READ_4(sc, LII_ISR);
848 if (status == 0)
849 return 0;
850
851 DPRINTF(("lii_intr (%x)\n", status));
852
853 /* Clear the interrupt and disable them */
854 LII_WRITE_4(sc, LII_ISR, status | ISR_DIS_INT);
855
856 if (status & (ISR_PHY | ISR_MANUAL)) {
857 /* Ack PHY interrupt. Magic register */
858 if (status & ISR_PHY)
859 (void)lii_mii_readreg(&sc->sc_dev, 1, 19);
860 mii_mediachg(&sc->sc_mii);
861 }
862
863 if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST | ISR_PHY_LINKDOWN)) {
864 lii_init(&sc->sc_ac.ac_if);
865 return 1;
866 }
867
868 if (status & ISR_RX_EVENT) {
869 #ifdef LII_DEBUG
870 if (!(status & ISR_RS_UPDATE))
871 printf("rxintr %08x\n", status);
872 #endif
873 lii_rxintr(sc);
874 }
875
876 if (status & ISR_TX_EVENT)
877 lii_txintr(sc);
878
879 /* Re-enable interrupts */
880 LII_WRITE_4(sc, LII_ISR, 0);
881
882 return 1;
883 }
884
885 void
lii_rxintr(struct lii_softc * sc)886 lii_rxintr(struct lii_softc *sc)
887 {
888 struct mbuf_list ml = MBUF_LIST_INITIALIZER();
889 struct ifnet *ifp = &sc->sc_ac.ac_if;
890 struct rx_pkt *rxp;
891 struct mbuf *m;
892 uint16_t size;
893
894 DPRINTF(("lii_rxintr\n"));
895
896 for (;;) {
897 rxp = &sc->sc_rxp[sc->sc_rxcur];
898 if (rxp->rxp_update == 0)
899 break;
900
901 DPRINTF(("lii_rxintr: getting %u (%u) [%x]\n", sc->sc_rxcur,
902 rxp->rxp_size, rxp->rxp_flags));
903 sc->sc_rxcur = (sc->sc_rxcur + 1) % AT_RXD_NUM;
904 rxp->rxp_update = 0;
905 if (!(rxp->rxp_flags & LII_RXF_SUCCESS)) {
906 ++ifp->if_ierrors;
907 continue;
908 }
909
910 MGETHDR(m, M_DONTWAIT, MT_DATA);
911 if (m == NULL) {
912 ++ifp->if_ierrors;
913 continue;
914 }
915 size = rxp->rxp_size - ETHER_CRC_LEN;
916 if (size > MHLEN) {
917 MCLGET(m, M_DONTWAIT);
918 if ((m->m_flags & M_EXT) == 0) {
919 m_freem(m);
920 ++ifp->if_ierrors;
921 continue;
922 }
923 }
924
925 /* Copy the packet without the FCS */
926 m->m_pkthdr.len = m->m_len = size;
927 memcpy(mtod(m, void *), &rxp->rxp_data[0], size);
928
929 ml_enqueue(&ml, m);
930 }
931
932 if_input(ifp, &ml);
933
934 LII_WRITE_4(sc, LII_MB_RXD_RD_IDX, sc->sc_rxcur);
935 }
936
937 void
lii_txintr(struct lii_softc * sc)938 lii_txintr(struct lii_softc *sc)
939 {
940 struct ifnet *ifp = &sc->sc_ac.ac_if;
941 struct tx_pkt_status *txs;
942 struct tx_pkt_header *txph;
943
944 DPRINTF(("lii_txintr\n"));
945
946 for (;;) {
947 txs = &sc->sc_txs[sc->sc_txs_ack];
948 if (txs->txps_update == 0)
949 break;
950 DPRINTF(("lii_txintr: ack'd %d\n", sc->sc_txs_ack));
951 sc->sc_txs_ack = (sc->sc_txs_ack + 1) % AT_TXD_NUM;
952 sc->sc_free_tx_slots = 1;
953
954 txs->txps_update = 0;
955
956 txph = (struct tx_pkt_header *)
957 (sc->sc_txdbase + sc->sc_txd_ack);
958
959 if (txph->txph_size != txs->txps_size) {
960 printf("%s: mismatched status and packet\n",
961 DEVNAME(sc));
962 }
963
964 /*
965 * Move ack by the packet size, taking the packet header in
966 * account and round to the next 32-bit boundary
967 * (7 = sizeof(header) + 3)
968 */
969 sc->sc_txd_ack = (sc->sc_txd_ack + txph->txph_size + 7 ) & ~3;
970 sc->sc_txd_ack %= AT_TXD_BUFFER_SIZE;
971
972 if (!ISSET(txs->txps_flags, LII_TXF_SUCCESS))
973 ++ifp->if_oerrors;
974 ifq_clr_oactive(&ifp->if_snd);
975 }
976
977 if (sc->sc_free_tx_slots)
978 lii_start(ifp);
979 }
980
981 int
lii_alloc_rings(struct lii_softc * sc)982 lii_alloc_rings(struct lii_softc *sc)
983 {
984 int nsegs;
985 bus_size_t bs;
986
987 /*
988 * We need a big chunk of DMA-friendly memory because descriptors
989 * are not separate from data on that crappy hardware, which means
990 * we'll have to copy data from and to that memory zone to and from
991 * the mbufs.
992 *
993 * How lame is that? Using the default values from the Linux driver,
994 * we allocate space for receiving up to 64 full-size Ethernet frames,
995 * and only 8kb for transmitting up to 64 Ethernet frames.
996 */
997
998 sc->sc_ringsize = bs = AT_RXD_PADDING
999 + AT_RXD_NUM * sizeof(struct rx_pkt)
1000 + AT_TXD_NUM * sizeof(struct tx_pkt_status)
1001 + AT_TXD_BUFFER_SIZE;
1002
1003 if (bus_dmamap_create(sc->sc_dmat, bs, 1, bs, (1<<30),
1004 BUS_DMA_NOWAIT, &sc->sc_ringmap) != 0) {
1005 printf(": failed to create DMA map\n");
1006 return 1;
1007 }
1008
1009 if (bus_dmamem_alloc(sc->sc_dmat, bs, PAGE_SIZE, (1<<30),
1010 &sc->sc_ringseg, 1, &nsegs, BUS_DMA_NOWAIT) != 0) {
1011 printf(": failed to allocate DMA memory\n");
1012 goto destroy;
1013 }
1014
1015 if (bus_dmamem_map(sc->sc_dmat, &sc->sc_ringseg, nsegs, bs,
1016 (caddr_t *)&sc->sc_ring, BUS_DMA_NOWAIT) != 0) {
1017 printf(": failed to map DMA memory\n");
1018 goto free;
1019 }
1020
1021 if (bus_dmamap_load(sc->sc_dmat, sc->sc_ringmap, sc->sc_ring,
1022 bs, NULL, BUS_DMA_NOWAIT) != 0) {
1023 printf(": failed to load DMA memory\n");
1024 goto unmap;
1025 }
1026
1027 sc->sc_rxp = (void *)(sc->sc_ring + AT_RXD_PADDING);
1028 sc->sc_txs = (void *)(sc->sc_ring + AT_RXD_PADDING
1029 + AT_RXD_NUM * sizeof(struct rx_pkt));
1030 sc->sc_txdbase = ((char *)sc->sc_txs)
1031 + AT_TXD_NUM * sizeof(struct tx_pkt_status);
1032 sc->sc_txsp = sc->sc_ringmap->dm_segs[0].ds_addr
1033 + ((char *)sc->sc_txs - (char *)sc->sc_ring);
1034 sc->sc_txdp = sc->sc_ringmap->dm_segs[0].ds_addr
1035 + ((char *)sc->sc_txdbase - (char *)sc->sc_ring);
1036
1037 return 0;
1038
1039 unmap:
1040 bus_dmamem_unmap(sc->sc_dmat, sc->sc_ring, bs);
1041 free:
1042 bus_dmamem_free(sc->sc_dmat, &sc->sc_ringseg, nsegs);
1043 destroy:
1044 bus_dmamap_destroy(sc->sc_dmat, sc->sc_ringmap);
1045 return 1;
1046 }
1047
1048 void
lii_watchdog(struct ifnet * ifp)1049 lii_watchdog(struct ifnet *ifp)
1050 {
1051 struct lii_softc *sc = ifp->if_softc;
1052
1053 printf("%s: watchdog timeout\n", DEVNAME(sc));
1054 ++ifp->if_oerrors;
1055 lii_init(ifp);
1056 }
1057
1058 int
lii_ioctl(struct ifnet * ifp,u_long cmd,caddr_t addr)1059 lii_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
1060 {
1061 struct lii_softc *sc = ifp->if_softc;
1062 struct ifreq *ifr = (struct ifreq *)addr;
1063 int s, error = 0;
1064
1065 s = splnet();
1066
1067 switch(cmd) {
1068 case SIOCSIFADDR:
1069 SET(ifp->if_flags, IFF_UP);
1070 /* FALLTHROUGH */
1071
1072 case SIOCSIFFLAGS:
1073 if (ISSET(ifp->if_flags, IFF_UP)) {
1074 if (ISSET(ifp->if_flags, IFF_RUNNING))
1075 error = ENETRESET;
1076 else
1077 lii_init(ifp);
1078 } else {
1079 if (ISSET(ifp->if_flags, IFF_RUNNING))
1080 lii_stop(ifp);
1081 }
1082 break;
1083
1084 case SIOCSIFMEDIA:
1085 case SIOCGIFMEDIA:
1086 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1087 break;
1088
1089 default:
1090 error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr);
1091 }
1092
1093 if (error == ENETRESET) {
1094 if (ifp->if_flags & IFF_RUNNING)
1095 lii_iff(sc);
1096 error = 0;
1097 }
1098
1099 splx(s);
1100 return error;
1101 }
1102
1103 void
lii_iff(struct lii_softc * sc)1104 lii_iff(struct lii_softc *sc)
1105 {
1106 struct ifnet *ifp = &sc->sc_ac.ac_if;
1107 struct arpcom *ac = &sc->sc_ac;
1108 struct ether_multi *enm;
1109 struct ether_multistep step;
1110 uint32_t hashes[2];
1111 uint32_t crc, val;
1112
1113 val = LII_READ_4(sc, LII_MACC);
1114 val &= ~(MACC_ALLMULTI_EN | MACC_BCAST_EN | MACC_PROMISC_EN);
1115 ifp->if_flags &= ~IFF_ALLMULTI;
1116
1117 /*
1118 * Always accept broadcast frames.
1119 */
1120 val |= MACC_BCAST_EN;
1121
1122 if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
1123 ifp->if_flags |= IFF_ALLMULTI;
1124 if (ifp->if_flags & IFF_PROMISC)
1125 val |= MACC_PROMISC_EN;
1126 else
1127 val |= MACC_ALLMULTI_EN;
1128 hashes[0] = hashes[1] = 0xFFFFFFFF;
1129 } else {
1130 /* Program new filter. */
1131 bzero(hashes, sizeof(hashes));
1132
1133 ETHER_FIRST_MULTI(step, ac, enm);
1134 while (enm != NULL) {
1135 crc = ether_crc32_be(enm->enm_addrlo,
1136 ETHER_ADDR_LEN);
1137
1138 hashes[((crc >> 31) & 0x1)] |=
1139 (1 << ((crc >> 26) & 0x1f));
1140
1141 ETHER_NEXT_MULTI(step, enm);
1142 }
1143 }
1144
1145 LII_WRITE_4(sc, LII_MHT, hashes[0]);
1146 LII_WRITE_4(sc, LII_MHT + 4, hashes[1]);
1147 LII_WRITE_4(sc, LII_MACC, val);
1148 }
1149
1150 void
lii_tick(void * v)1151 lii_tick(void *v)
1152 {
1153 struct lii_softc *sc = v;
1154 int s;
1155
1156 s = splnet();
1157 mii_tick(&sc->sc_mii);
1158 splx(s);
1159
1160 timeout_add_sec(&sc->sc_tick, 1);
1161 }
1162