1 /* Attansic/Atheros L2 FastEthernet driver, by D.C. van Moolenbroek */
2 /*
3 * No documentation is available for this card. The FreeBSD driver is based
4 * heavily on the official Linux driver; this driver is based heavily on both.
5 */
6
7 #include <minix/drivers.h>
8 #include <minix/netdriver.h>
9
10 #include <machine/pci.h>
11 #include <sys/mman.h>
12 #include <assert.h>
13
14 #include "atl2.h"
15
16 #define VERBOSE 0 /* Verbose debugging output */
17
18 #if VERBOSE
19 #define ATL2_DEBUG(x) printf x
20 #else
21 #define ATL2_DEBUG(x)
22 #endif
23
24 typedef struct {
25 uint32_t hdr;
26 uint32_t vtag;
27 uint8_t data[ATL2_RXD_SIZE - sizeof(uint32_t) * 2];
28 } rxd_t;
29
30 static struct {
31 int devind; /* PCI device index */
32 int irq; /* IRQ number */
33 int hook_id; /* IRQ hook ID */
34 uint8_t *base; /* base address of memory-mapped registers */
35 uint32_t size; /* size of memory-mapped area */
36 uint32_t hwaddr[2]; /* MAC address, in register representation */
37
38 uint8_t *txd_base; /* local address of TxD ring buffer base */
39 uint32_t *txs_base; /* local address of TxS ring buffer base */
40 uint8_t *rxd_base_u; /* unaligned base address of RxD ring buffer */
41 rxd_t *rxd_base; /* local address of RxD ring buffer base */
42
43 int rxd_align; /* alignment offset of RxD ring buffer */
44
45 vir_bytes txd_phys; /* physical address of TxD ring buffer */
46 vir_bytes txs_phys; /* physical address of TxS ring buffer */
47 vir_bytes rxd_phys; /* physical address of RxD ring buffer */
48
49 int txd_tail; /* tail index into TxD, in bytes */
50 int txd_num; /* head-tail offset into TxD, in bytes */
51 int txs_tail; /* tail index into TxS, in elements */
52 int txs_num; /* head-tail offset into TxS, in elements */
53 int rxd_tail; /* tail index into RxD, in elements */
54
55 int rx_avail; /* is there a packet available for receipt? */
56 } state;
57
58 #define ATL2_READ_U8(off) (*(volatile uint8_t *)(state.base + (off)))
59 #define ATL2_READ_U16(off) (*(volatile uint16_t *)(state.base + (off)))
60 #define ATL2_READ_U32(off) (*(volatile uint32_t *)(state.base + (off)))
61 #define ATL2_WRITE_U8(off, val) \
62 *(volatile uint8_t *)(state.base + (off)) = (val)
63 #define ATL2_WRITE_U16(off, val) \
64 *(volatile uint16_t *)(state.base + (off)) = (val)
65 #define ATL2_WRITE_U32(off, val) \
66 *(volatile uint32_t *)(state.base + (off)) = (val)
67
68 #define ATL2_ALIGN_32(n) (((n) + 3) & ~3)
69
70 static int atl2_init(unsigned int, netdriver_addr_t *, uint32_t *,
71 unsigned int *);
72 static void atl2_stop(void);
73 static void atl2_set_mode(unsigned int, const netdriver_addr_t *,
74 unsigned int);
75 static int atl2_send(struct netdriver_data *, size_t);
76 static ssize_t atl2_recv(struct netdriver_data *, size_t);
77 static void atl2_intr(unsigned int mask);
78
79 static const struct netdriver atl2_table = {
80 .ndr_name = "lii",
81 .ndr_init = atl2_init,
82 .ndr_stop = atl2_stop,
83 .ndr_set_mode = atl2_set_mode,
84 .ndr_recv = atl2_recv,
85 .ndr_send = atl2_send,
86 .ndr_intr = atl2_intr,
87 };
88
89 /*
90 * Read a value from the VPD register area.
91 */
92 static int
atl2_read_vpd(int index,uint32_t * res)93 atl2_read_vpd(int index, uint32_t * res)
94 {
95 uint32_t off, val;
96 int i;
97
98 ATL2_WRITE_U32(ATL2_VPD_DATA_REG, 0);
99
100 off = ATL2_VPD_REGBASE + index * sizeof(uint32_t);
101
102 ATL2_WRITE_U32(ATL2_VPD_CAP_REG,
103 (off << ATL2_VPD_CAP_ADDR_SHIFT) & ATL2_VPD_CAP_ADDR_MASK);
104
105 for (i = 0; i < ATL2_VPD_NTRIES; i++) {
106 micro_delay(ATL2_VPD_DELAY);
107
108 val = ATL2_READ_U32(ATL2_VPD_CAP_REG);
109 if (val & ATL2_VPD_CAP_DONE)
110 break;
111 }
112
113 if (i == ATL2_VPD_NTRIES) {
114 printf("%s: timeout reading EEPROM register %d\n",
115 netdriver_name(), index);
116 return FALSE;
117 }
118
119 *res = ATL2_READ_U32(ATL2_VPD_DATA_REG);
120 return TRUE;
121 }
122
123 /*
124 * Read the MAC address from the EEPROM, using the Vital Product Data register
125 * interface.
126 */
127 static int
atl2_get_vpd_hwaddr(void)128 atl2_get_vpd_hwaddr(void)
129 {
130 uint32_t key, val;
131 int i, n, found[2];
132
133 /* No idea, copied from FreeBSD which copied it from Linux. */
134 val = ATL2_READ_U32(ATL2_SPICTL_REG);
135 if (val & ATL2_SPICTL_VPD_EN) {
136 val &= ~ATL2_SPICTL_VPD_EN;
137 ATL2_WRITE_U32(ATL2_SPICTL_REG, val);
138 }
139
140 /* Is VPD supported? */
141 #ifdef PCI_CAP_VPD /* FIXME: just a guess at the future name */
142 if (!pci_find_cap(state.devind, PCI_CAP_VPD, &n))
143 return FALSE;
144 #endif
145
146 /*
147 * Read out the set of key/value pairs. Look for the two parts that
148 * make up the MAC address.
149 */
150 found[0] = found[1] = FALSE;
151 for (i = 0; i < ATL2_VPD_NREGS; i += 2) {
152 if (!atl2_read_vpd(i, &key))
153 break;
154
155 if ((key & ATL2_VPD_SIG_MASK) != ATL2_VPD_SIG)
156 break;
157
158 key >>= ATL2_VPD_REG_SHIFT;
159
160 if (key != ATL2_HWADDR0_REG && key != ATL2_HWADDR1_REG)
161 continue;
162
163 if (!atl2_read_vpd(i + 1, &val))
164 break;
165
166 n = (key == ATL2_HWADDR1_REG);
167 state.hwaddr[n] = val;
168 found[n] = TRUE;
169
170 if (found[1 - n]) break;
171 }
172
173 return found[0] && found[1];
174 }
175
176 /*
177 * Get the MAC address of the card. First try the EEPROM; if that fails, just
178 * use whatever the card was already set to.
179 */
180 static void
atl2_get_hwaddr(netdriver_addr_t * addr)181 atl2_get_hwaddr(netdriver_addr_t * addr)
182 {
183
184 if (!atl2_get_vpd_hwaddr()) {
185 printf("%s: unable to read from VPD\n", netdriver_name());
186
187 state.hwaddr[0] = ATL2_READ_U32(ATL2_HWADDR0_REG);
188 state.hwaddr[1] = ATL2_READ_U32(ATL2_HWADDR1_REG) & 0xffff;
189 }
190
191 ATL2_DEBUG(("%s: MAC address %04x%08x\n",
192 netdriver_name(), state.hwaddr[1], state.hwaddr[0]));
193
194 addr->na_addr[0] = state.hwaddr[1] >> 8;
195 addr->na_addr[1] = state.hwaddr[1] & 0xff;
196 addr->na_addr[2] = state.hwaddr[0] >> 24;
197 addr->na_addr[3] = (state.hwaddr[0] >> 16) & 0xff;
198 addr->na_addr[4] = (state.hwaddr[0] >> 8) & 0xff;
199 addr->na_addr[5] = state.hwaddr[0] & 0xff;
200 }
201
202 #if 0 /* TODO: link status */
203 /*
204 * Read a MII PHY register using MDIO.
205 */
206 static int
207 atl2_read_mdio(int addr, uint16_t * res)
208 {
209 uint32_t rval;
210 int i;
211
212 rval = ((addr << ATL2_MDIO_ADDR_SHIFT) & ATL2_MDIO_ADDR_MASK) |
213 ATL2_MDIO_START | ATL2_MDIO_READ | ATL2_MDIO_SUP_PREAMBLE |
214 ATL2_MDIO_CLK_25_4;
215
216 ATL2_WRITE_U32(ATL2_MDIO_REG, rval);
217
218 for (i = 0; i < ATL2_MDIO_NTRIES; i++) {
219 micro_delay(ATL2_MDIO_DELAY);
220
221 rval = ATL2_READ_U32(ATL2_MDIO_REG);
222
223 if (!(rval & (ATL2_MDIO_START | ATL2_MDIO_BUSY)))
224 break;
225 }
226
227 if (i == ATL2_MDIO_NTRIES) return FALSE;
228
229 *res = (uint16_t)(rval & ATL2_MDIO_DATA_MASK);
230 return TRUE;
231 }
232 #endif
233
234 /*
235 * Allocate DMA ring buffers.
236 */
237 static int
atl2_alloc_dma(void)238 atl2_alloc_dma(void)
239 {
240
241 state.txd_base = alloc_contig(ATL2_TXD_BUFSIZE, AC_ALIGN4K,
242 &state.txd_phys);
243 state.txs_base = alloc_contig(ATL2_TXS_COUNT * sizeof(uint32_t),
244 AC_ALIGN4K, &state.txs_phys);
245
246 /*
247 * The data buffer in each RxD descriptor must be 128-byte aligned.
248 * The two Tx buffers merely require a 4-byte start alignment.
249 */
250 state.rxd_align = 128 - offsetof(rxd_t, data);
251 state.rxd_base_u = alloc_contig(state.rxd_align +
252 ATL2_RXD_COUNT * ATL2_RXD_SIZE, AC_ALIGN4K, &state.rxd_phys);
253
254 /* Unlike mmap, alloc_contig returns NULL on failure. */
255 if (!state.txd_base || !state.txs_base || !state.rxd_base_u)
256 return ENOMEM;
257
258 state.rxd_base = (rxd_t *)(state.rxd_base_u + state.rxd_align);
259 state.rxd_phys += state.rxd_align;
260
261 /* Zero out just in case. */
262 memset(state.txd_base, 0, ATL2_TXD_BUFSIZE);
263 memset(state.txs_base, 0, ATL2_TXS_COUNT * sizeof(uint32_t));
264 memset(state.rxd_base, 0, ATL2_RXD_COUNT * ATL2_RXD_SIZE);
265
266 return OK;
267 }
268
269 /*
270 * Stop the device.
271 */
272 static void
atl2_stop(void)273 atl2_stop(void)
274 {
275 uint32_t val;
276 int i;
277
278 /* Clear and disable interrupts. */
279 ATL2_WRITE_U32(ATL2_IMR_REG, 0);
280 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff);
281
282 /* Stop Rx/Tx MACs. */
283 val = ATL2_READ_U32(ATL2_MAC_REG);
284 if (val & (ATL2_MAC_RX_EN | ATL2_MAC_TX_EN)) {
285 val &= ~(ATL2_MAC_RX_EN | ATL2_MAC_TX_EN);
286 ATL2_WRITE_U32(ATL2_MAC_REG, val);
287 }
288
289 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, 0);
290 ATL2_WRITE_U8(ATL2_DMAREAD_REG, 0);
291
292 /* Wait until everything is idle. */
293 for (i = 0; i < ATL2_IDLE_NTRIES; i++) {
294 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0)
295 break;
296
297 micro_delay(ATL2_IDLE_DELAY);
298 }
299
300 assert(i < ATL2_IDLE_NTRIES);
301 }
302
303 /*
304 * Reset the device to a known good state.
305 */
306 static int
atl2_reset(void)307 atl2_reset(void)
308 {
309 uint32_t val;
310 int i;
311
312 /* Issue a soft reset, and wait for the device to respond. */
313 ATL2_WRITE_U32(ATL2_MASTER_REG, ATL2_MASTER_SOFT_RESET);
314
315 for (i = 0; i < ATL2_RESET_NTRIES; i++) {
316 val = ATL2_READ_U32(ATL2_MASTER_REG);
317 if (!(val & ATL2_MASTER_SOFT_RESET))
318 break;
319
320 micro_delay(ATL2_RESET_DELAY);
321 }
322
323 if (i == ATL2_RESET_NTRIES)
324 return FALSE;
325
326 /* Wait until everything is idle. */
327 for (i = 0; i < ATL2_IDLE_NTRIES; i++) {
328 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0)
329 break;
330
331 micro_delay(ATL2_IDLE_DELAY);
332 }
333
334 return (i < ATL2_IDLE_NTRIES);
335 }
336
337 /*
338 * Reconfigure the device's promiscuity, multicast, and broadcast mode
339 * settings.
340 */
341 static void
atl2_set_mode(unsigned int mode,const netdriver_addr_t * mcast_list __unused,unsigned int mcast_count __unused)342 atl2_set_mode(unsigned int mode, const netdriver_addr_t * mcast_list __unused,
343 unsigned int mcast_count __unused)
344 {
345 uint32_t val;
346
347 val = ATL2_READ_U32(ATL2_MAC_REG);
348 val &= ~(ATL2_MAC_PROMISC_EN | ATL2_MAC_MCAST_EN | ATL2_MAC_BCAST_EN);
349
350 if (mode & NDEV_MODE_PROMISC)
351 val |= ATL2_MAC_PROMISC_EN;
352 if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL))
353 val |= ATL2_MAC_MCAST_EN;
354 if (mode & NDEV_MODE_BCAST)
355 val |= ATL2_MAC_BCAST_EN;
356
357 ATL2_WRITE_U32(ATL2_MAC_REG, val);
358 }
359
360 /*
361 * Set up the device for normal operation.
362 */
363 static int
atl2_setup(void)364 atl2_setup(void)
365 {
366 uint32_t val;
367
368 atl2_stop();
369
370 if (!atl2_reset())
371 return FALSE;
372
373 /* Initialize PCIe module. Magic. */
374 ATL2_WRITE_U32(ATL2_LTSSM_TESTMODE_REG, ATL2_LTSSM_TESTMODE_DEFAULT);
375 ATL2_WRITE_U32(ATL2_DLL_TX_CTRL_REG, ATL2_DLL_TX_CTRL_DEFAULT);
376
377 /* Enable PHY. */
378 ATL2_WRITE_U32(ATL2_PHY_ENABLE_REG, ATL2_PHY_ENABLE);
379 micro_delay(1000);
380
381 /* Clear and disable interrupts. */
382 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff);
383
384 /* Set the MAC address. */
385 ATL2_WRITE_U32(ATL2_HWADDR0_REG, state.hwaddr[0]);
386 ATL2_WRITE_U32(ATL2_HWADDR1_REG, state.hwaddr[1]);
387
388 /* Initialize ring buffer addresses and sizes. */
389 ATL2_WRITE_U32(ATL2_DESC_ADDR_HI_REG, 0); /* no 64 bit */
390 ATL2_WRITE_U32(ATL2_TXD_ADDR_LO_REG, state.txd_phys);
391 ATL2_WRITE_U32(ATL2_TXS_ADDR_LO_REG, state.txs_phys);
392 ATL2_WRITE_U32(ATL2_RXD_ADDR_LO_REG, state.rxd_phys);
393
394 ATL2_WRITE_U16(ATL2_RXD_COUNT_REG, ATL2_RXD_COUNT);
395 ATL2_WRITE_U16(ATL2_TXD_BUFSIZE_REG,
396 ATL2_TXD_BUFSIZE / sizeof(uint32_t));
397 ATL2_WRITE_U16(ATL2_TXS_COUNT_REG, ATL2_TXS_COUNT);
398
399 /* A whole lot of other initialization copied from Linux/FreeBSD. */
400 ATL2_WRITE_U32(ATL2_IFG_REG, ATL2_IFG_DEFAULT);
401
402 ATL2_WRITE_U32(ATL2_HDPX_REG, ATL2_HDPX_DEFAULT);
403
404 ATL2_WRITE_U16(ATL2_IMT_REG, ATL2_IMT_DEFAULT);
405 val = ATL2_READ_U32(ATL2_MASTER_REG);
406 ATL2_WRITE_U32(ATL2_MASTER_REG, val | ATL2_MASTER_IMT_EN);
407
408 ATL2_WRITE_U16(ATL2_ICT_REG, ATL2_ICT_DEFAULT);
409
410 ATL2_WRITE_U32(ATL2_CUT_THRESH_REG, ATL2_CUT_THRESH_DEFAULT);
411
412 ATL2_WRITE_U16(ATL2_FLOW_THRESH_HI_REG, (ATL2_RXD_COUNT / 8) * 7);
413 ATL2_WRITE_U16(ATL2_FLOW_THRESH_LO_REG, ATL2_RXD_COUNT / 12);
414
415 /* Set MTU. */
416 ATL2_WRITE_U16(ATL2_MTU_REG, ATL2_MTU_DEFAULT);
417
418 /* Reset descriptors, and enable DMA. */
419 state.txd_tail = state.txs_tail = state.rxd_tail = 0;
420 state.txd_num = state.txs_num = 0;
421 state.rx_avail = FALSE;
422 ATL2_WRITE_U16(ATL2_TXD_IDX_REG, 0);
423 ATL2_WRITE_U16(ATL2_RXD_IDX_REG, 0);
424
425 ATL2_WRITE_U8(ATL2_DMAREAD_REG, ATL2_DMAREAD_EN);
426 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, ATL2_DMAWRITE_EN);
427
428 /* Did everything go alright? */
429 val = ATL2_READ_U32(ATL2_ISR_REG);
430 if (val & ATL2_ISR_PHY_LINKDOWN) {
431 printf("%s: initialization failed\n", netdriver_name());
432 return FALSE;
433 }
434
435 /* Clear interrupt status. */
436 ATL2_WRITE_U32(ATL2_ISR_REG, 0x3fffffff);
437 ATL2_WRITE_U32(ATL2_ISR_REG, 0);
438
439 /* Enable interrupts. */
440 ATL2_WRITE_U32(ATL2_IMR_REG, ATL2_IMR_DEFAULT);
441
442 /* Configure MAC. */
443 ATL2_WRITE_U32(ATL2_MAC_REG, ATL2_MAC_DEFAULT);
444
445 /* TODO: multicast lists. */
446 ATL2_WRITE_U32(ATL2_MHT0_REG, 0xffffffff);
447 ATL2_WRITE_U32(ATL2_MHT1_REG, 0xffffffff);
448
449 /* Enable Tx/Rx. */
450 val = ATL2_READ_U32(ATL2_MAC_REG);
451 ATL2_WRITE_U32(ATL2_MAC_REG, val | ATL2_MAC_TX_EN | ATL2_MAC_RX_EN);
452
453 return TRUE;
454 }
455
456 /*
457 * Find a matching PCI device.
458 */
459 static int
atl2_probe(int skip)460 atl2_probe(int skip)
461 {
462 uint16_t vid, did;
463 #if VERBOSE
464 const char *dname;
465 #endif
466 int r, devind;
467
468 pci_init();
469
470 r = pci_first_dev(&devind, &vid, &did);
471 if (r <= 0)
472 return -1;
473
474 while (skip--) {
475 r = pci_next_dev(&devind, &vid, &did);
476 if (r <= 0)
477 return -1;
478 }
479
480 #if VERBOSE
481 dname = pci_dev_name(vid, did);
482 ATL2_DEBUG(("%s: found %s (%x/%x) at %s\n", netdriver_name(),
483 dname ? dname : "<unknown>", vid, did, pci_slot_name(devind)));
484 #endif
485
486 pci_reserve(devind);
487
488 return devind;
489 }
490
491 /*
492 * Initialize the device.
493 */
494 static void
atl2_init_hw(int devind,netdriver_addr_t * addr)495 atl2_init_hw(int devind, netdriver_addr_t * addr)
496 {
497 uint32_t bar;
498 int r, flag;
499
500 /* Initialize global state. */
501 state.devind = devind;
502
503 if ((r = pci_get_bar(devind, PCI_BAR, &bar, &state.size, &flag)) != OK)
504 panic("unable to retrieve bar: %d", r);
505
506 if (state.size < ATL2_MIN_MMAP_SIZE || flag)
507 panic("invalid register bar");
508
509 state.base = vm_map_phys(SELF, (void *)bar, state.size);
510 if (state.base == MAP_FAILED)
511 panic("unable to map in registers");
512
513 if ((r = atl2_alloc_dma()) != OK)
514 panic("unable to allocate DMA buffers: %d", r);
515
516 state.irq = pci_attr_r8(devind, PCI_ILR);
517 state.hook_id = 0;
518
519 if ((r = sys_irqsetpolicy(state.irq, 0, &state.hook_id)) != OK)
520 panic("unable to register IRQ: %d", r);
521
522 if (!atl2_reset())
523 panic("unable to reset hardware");
524
525 if ((r = sys_irqenable(&state.hook_id)) != OK)
526 panic("unable to enable IRQ: %d", r);
527
528 atl2_get_hwaddr(addr);
529
530 atl2_setup();
531 }
532
533 /*
534 * Update statistics for packet transmission.
535 */
536 static void
atl2_tx_stat(uint32_t stat)537 atl2_tx_stat(uint32_t stat)
538 {
539
540 if (stat & ATL2_TXS_SUCCESS)
541 return;
542
543 if (stat & (ATL2_TXS_SINGLECOL | ATL2_TXS_MULTICOL | ATL2_TXS_LATECOL))
544 netdriver_stat_coll(1);
545 else
546 netdriver_stat_oerror(1);
547 }
548
549 /*
550 * Update statistics for packet receipt.
551 */
552 static void
atl2_rx_stat(uint32_t stat)553 atl2_rx_stat(uint32_t stat)
554 {
555
556 if (!(stat & ATL2_RXD_SUCCESS))
557 netdriver_stat_ierror(1);
558 }
559
560 /*
561 * Advance the TxD/TxS tails by as many sent packets as found.
562 */
563 static int
atl2_tx_advance(void)564 atl2_tx_advance(void)
565 {
566 uint32_t stat, size, dsize;
567 int advanced;
568
569 advanced = FALSE;
570
571 while (state.txs_num > 0) {
572 /* Has the tail packet been processed by the driver? */
573 stat = state.txs_base[state.txs_tail];
574
575 if (!(stat & ATL2_TXS_UPDATE))
576 break;
577
578 /*
579 * The packet size from the status must match the packet size
580 * we put in. If they don't, there's not much we can do..
581 */
582 size = stat & ATL2_TXS_SIZE_MASK;
583
584 assert((uint32_t)state.txd_tail <=
585 ATL2_TXD_BUFSIZE - sizeof(uint32_t));
586 dsize =
587 *(volatile uint32_t *)(state.txd_base + state.txd_tail);
588 if (size != dsize)
589 printf("%s: TxD/TxS size mismatch (%x vs %x)\n",
590 netdriver_name(), size, dsize);
591
592 /* Advance tails accordingly. */
593 size = sizeof(uint32_t) + ATL2_ALIGN_32(dsize);
594 assert((uint32_t)state.txd_num >= size);
595 state.txd_tail = (state.txd_tail + size) % ATL2_TXD_BUFSIZE;
596 state.txd_num -= size;
597
598 state.txs_tail = (state.txs_tail + 1) % ATL2_TXS_COUNT;
599 state.txs_num--;
600
601 if (stat & ATL2_TXS_SUCCESS)
602 ATL2_DEBUG(("%s: successfully sent packet\n",
603 netdriver_name()));
604 else
605 ATL2_DEBUG(("%s: failed to send packet\n",
606 netdriver_name()));
607
608 /* Update statistics. */
609 atl2_tx_stat(stat);
610
611 advanced = TRUE;
612 }
613
614 return advanced;
615 }
616
617 /*
618 * Advance the RxD tail by as many failed receipts as possible, and see if
619 * there is an actual packet left to receive. If 'next' is set, the packet at
620 * the current tail has been processed.
621 */
622 static void
atl2_rx_advance(int next)623 atl2_rx_advance(int next)
624 {
625 int update_tail;
626 rxd_t *rxd;
627 uint32_t hdr;
628 size_t size;
629
630 update_tail = FALSE;
631
632 if (next) {
633 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT;
634 update_tail = TRUE;
635
636 ATL2_DEBUG(("%s: successfully received packet\n",
637 netdriver_name()));
638
639 state.rx_avail = FALSE;
640 }
641
642 assert(!state.rx_avail);
643
644 for (;;) {
645 /* Check the RxD tail for updates. */
646 rxd = &state.rxd_base[state.rxd_tail];
647
648 hdr = rxd->hdr;
649
650 if (!(hdr & ATL2_RXD_UPDATE))
651 break;
652
653 rxd->hdr = hdr & ~ATL2_RXD_UPDATE;
654
655 /* Update statistics. */
656 atl2_rx_stat(hdr);
657
658 /*
659 * Stop at the first successful receipt. The packet will be
660 * picked up by Inet later.
661 */
662 size = hdr & ATL2_RXD_SIZE_MASK;
663
664 if ((hdr & ATL2_RXD_SUCCESS) &&
665 size >= NDEV_ETH_PACKET_MIN + NDEV_ETH_PACKET_CRC) {
666 ATL2_DEBUG(("%s: packet available, size %zu\n",
667 netdriver_name(), size));
668
669 state.rx_avail = TRUE;
670 break;
671 }
672
673 ATL2_DEBUG(("%s: packet receipt failed\n", netdriver_name()));
674
675 /* Advance tail. */
676 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT;
677 update_tail = TRUE;
678 }
679
680 /* If new RxD descriptors are now up for reuse, tell the device. */
681 if (update_tail) {
682 __insn_barrier();
683
684 ATL2_WRITE_U32(ATL2_RXD_IDX_REG, state.rxd_tail);
685 }
686 }
687
688 /*
689 * Receive a packet.
690 */
691 static ssize_t
atl2_recv(struct netdriver_data * data,size_t max)692 atl2_recv(struct netdriver_data * data, size_t max)
693 {
694 rxd_t *rxd;
695 size_t size;
696
697 /* Are there any packets available at all? */
698 if (!state.rx_avail)
699 return SUSPEND;
700
701 /* Get the first available packet's size. Cut off the CRC. */
702 rxd = &state.rxd_base[state.rxd_tail];
703
704 size = rxd->hdr & ATL2_RXD_SIZE_MASK;
705 size -= NDEV_ETH_PACKET_CRC;
706
707 ATL2_DEBUG(("%s: receiving packet with length %zu\n",
708 netdriver_name(), size));
709
710 /* Truncate large packets. */
711 if (size > max)
712 size = max;
713
714 /* Copy out the packet. */
715 netdriver_copyout(data, 0, rxd->data, size);
716
717 /* We are done with this packet. Move on to the next. */
718 atl2_rx_advance(TRUE /*next*/);
719
720 return size;
721 }
722
723 /*
724 * Send a packet.
725 */
726 static int
atl2_send(struct netdriver_data * data,size_t size)727 atl2_send(struct netdriver_data * data, size_t size)
728 {
729 size_t pos, chunk;
730 uint8_t *sizep;
731
732 /*
733 * If the packet won't fit, bail out. Keep at least some space between
734 * TxD head and tail, as it is not clear whether the device deals well
735 * with the case that they collide.
736 */
737 if (state.txs_num >= ATL2_TXS_COUNT)
738 return SUSPEND;
739
740 if (state.txd_num + sizeof(uint32_t) + ATL2_ALIGN_32(size) >=
741 ATL2_TXD_BUFSIZE)
742 return SUSPEND;
743
744 /* Copy in the packet. */
745 pos = (state.txd_tail + state.txd_num +
746 sizeof(uint32_t)) % ATL2_TXD_BUFSIZE;
747 chunk = ATL2_TXD_BUFSIZE - pos;
748 if (size > chunk) {
749 netdriver_copyin(data, 0, state.txd_base + pos, chunk);
750 netdriver_copyin(data, chunk, state.txd_base, size - chunk);
751 } else
752 netdriver_copyin(data, 0, state.txd_base + pos, size);
753
754 /* Write the length to the DWORD right before the packet. */
755 sizep = state.txd_base +
756 (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE;
757 *(volatile uint32_t *)sizep = size;
758
759 /* Update the TxD head. */
760 state.txd_num += sizeof(uint32_t) + ATL2_ALIGN_32(size);
761 pos = ATL2_ALIGN_32(pos + size) % ATL2_TXD_BUFSIZE;
762 assert((int)pos ==
763 (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE);
764
765 /* Initialize and update the TxS head. */
766 state.txs_base[(state.txs_tail + state.txs_num) % ATL2_TXS_COUNT] = 0;
767 state.txs_num++;
768
769 /* Tell the device about our new position. */
770 __insn_barrier();
771
772 ATL2_WRITE_U32(ATL2_TXD_IDX_REG, pos / sizeof(uint32_t));
773
774 return OK;
775 }
776
777 /*
778 * Process an interrupt.
779 */
780 static void
atl2_intr(unsigned int __unused mask)781 atl2_intr(unsigned int __unused mask)
782 {
783 uint32_t val;
784 int r, try_send, try_recv;
785
786 /* Clear and disable interrupts. */
787 val = ATL2_READ_U32(ATL2_ISR_REG);
788
789 ATL2_WRITE_U32(ATL2_ISR_REG, val | ATL2_ISR_DISABLE);
790
791 ATL2_DEBUG(("%s: interrupt (0x%08x)\n", netdriver_name(), val));
792
793 /* If an error occurred, reset the card. */
794 if (val & (ATL2_ISR_DMAR_TIMEOUT | ATL2_ISR_DMAW_TIMEOUT |
795 ATL2_ISR_PHY_LINKDOWN))
796 atl2_setup();
797
798 try_send = try_recv = FALSE;
799
800 /* Process sent data, and possibly send pending data. */
801 if (val & ATL2_ISR_TX_EVENT) {
802 if (atl2_tx_advance())
803 try_send = TRUE;
804 }
805
806 /* Receive new data, and possible satisfy a pending receive request. */
807 if (val & ATL2_ISR_RX_EVENT) {
808 if (!state.rx_avail) {
809 atl2_rx_advance(FALSE /*next*/);
810
811 try_recv = TRUE;
812 }
813 }
814
815 /* Reenable interrupts. */
816 ATL2_WRITE_U32(ATL2_ISR_REG, 0);
817
818 if ((r = sys_irqenable(&state.hook_id)) != OK)
819 panic("unable to enable IRQ: %d", r);
820
821 /* Attempt to satisfy pending send and receive requests. */
822 if (try_send)
823 netdriver_send();
824 if (try_recv)
825 netdriver_recv();
826 }
827
828 #if 0 /* TODO: link status (using part of this code) */
829 /*
830 * Dump link status.
831 */
832 static void
833 atl2_dump_link(void)
834 {
835 uint16_t val;
836 int link_up;
837
838 /* The link status bit is latched. Read the status register twice. */
839 atl2_read_mdio(ATL2_MII_BMSR, &val);
840 if (!atl2_read_mdio(ATL2_MII_BMSR, &val)) return;
841
842 link_up = val & ATL2_MII_BMSR_LSTATUS;
843 printf("link status: %4s\t", link_up ? "up" : "down");
844
845 if (!link_up) return;
846
847 if (!atl2_read_mdio(ATL2_MII_PSSR, &val)) return;
848
849 if (!(val & ATL2_MII_PSSR_RESOLVED)) {
850 printf("(not resolved)\n");
851
852 return;
853 }
854
855 switch (val & ATL2_MII_PSSR_SPEED) {
856 case ATL2_MII_PSSR_10: printf("(10Mbps "); break;
857 case ATL2_MII_PSSR_100: printf("(100Mbps "); break;
858 case ATL2_MII_PSSR_1000: printf("(1000Mbps "); break;
859 default: printf("(unknown, ");
860 }
861
862 printf("%s duplex)", (val & ATL2_MII_PSSR_DUPLEX) ? "full" : "half");
863 }
864 #endif
865
866 /*
867 * Initialize the atl2 driver.
868 */
869 static int
atl2_init(unsigned int instance,netdriver_addr_t * addr,uint32_t * caps,unsigned int * ticks __unused)870 atl2_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps,
871 unsigned int * ticks __unused)
872 {
873 int devind;
874
875 memset(&state, 0, sizeof(state));
876
877 /* Try to find a recognized device. */
878 devind = atl2_probe(instance);
879
880 if (devind < 0)
881 return ENXIO;
882
883 /* Initialize the device. */
884 atl2_init_hw(devind, addr);
885
886 *caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST;
887 return OK;
888 }
889
890 #if 0
891 /*
892 * Deallocate resources as proof of concept. Currently unused.
893 */
894 static void
895 atl2_cleanup(void)
896 {
897 int r;
898
899 if ((r = sys_irqrmpolicy(&state.hook_id)) != OK)
900 panic("unable to deregister IRQ: %d", r);
901
902 free_contig(state.txd_base, ATL2_TXD_BUFSIZE);
903 free_contig(state.txs_base, ATL2_TXS_COUNT * sizeof(uint32_t));
904 free_contig(state.rxd_base_u,
905 state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE);
906
907 vm_unmap_phys(SELF, (void *)state.base, state.size);
908
909 /* We cannot free the PCI device at this time. */
910 }
911 #endif
912
913 /*
914 * The ATL2 ethernet driver.
915 */
916 int
main(int argc,char ** argv)917 main(int argc, char ** argv)
918 {
919
920 env_setargs(argc, argv);
921
922 netdriver_task(&atl2_table);
923
924 return EXIT_SUCCESS;
925 }
926