dec21140A ethernet driver for virtualpc, contributed by nicolas tittley.
[minix.git] / drivers / atl2 / atl2.c
blob33963d56bed96a99a9cdf96570aea55efb5548a4
1 /* Attansic/Atheros L2 FastEthernet driver, by D.C. van Moolenbroek */
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 */
7 #include "../drivers.h"
9 #include <signal.h>
10 #include <sys/mman.h>
11 #include <minix/ds.h>
12 #include <minix/vm.h>
13 #include <ibm/pci.h>
14 #include <net/gen/ether.h>
15 #include <net/gen/eth_io.h>
16 #include <assert.h>
18 #include "atl2.h"
20 #define VERBOSE 0 /* Verbose debugging output */
21 #define ATL2_FKEY 1 /* Register Shift+F11 for dumping statistics */
23 #if VERBOSE
24 #define ATL2_DEBUG(x) printf x
25 #else
26 #define ATL2_DEBUG(x)
27 #endif
29 typedef struct {
30 u32_t hdr;
31 u32_t vtag;
32 u8_t data[ATL2_RXD_SIZE - sizeof(u32_t) * 2];
33 } rxd_t;
35 PRIVATE struct {
36 int devind; /* PCI device index */
37 int irq; /* IRQ number */
38 int hook_id; /* IRQ hook ID */
39 int mode; /* datalink mode */
40 char *base; /* base address of memory-mapped registers */
41 u32_t hwaddr[2]; /* MAC address, in register representation */
43 u8_t *txd_base; /* local address of TxD ring buffer base */
44 u32_t *txs_base; /* local address of TxS ring buffer base */
45 u8_t *rxd_base_u; /* unaligned base address of RxD ring buffer */
46 rxd_t *rxd_base; /* local address of RxD ring buffer base */
48 int rxd_align; /* alignment offset of RxD ring buffer */
50 vir_bytes txd_phys; /* physical address of TxD ring buffer */
51 vir_bytes txs_phys; /* physical address of TxS ring buffer */
52 vir_bytes rxd_phys; /* physical address of RxD ring buffer */
54 int txd_tail; /* tail index into TxD, in bytes */
55 int txd_num; /* head-tail offset into TxD, in bytes */
56 int txs_tail; /* tail index into TxS, in elements */
57 int txs_num; /* head-tail offset into TxS, in elements */
58 int rxd_tail; /* tail index into RxD, in elements */
60 int flags; /* state flags (ATL2_FLAG_) */
61 message read_msg; /* suspended read request (READ_PEND) */
62 message write_msg; /* suspended write request (WRITE_PEND) */
63 endpoint_t task_endpt; /* requester endpoint (PACK_RCVD|PACK_SENT) */
64 size_t recv_count; /* packet size (PACK_RCVD) */
66 eth_stat_t stat; /* statistics */
67 } state;
69 #define ATL2_FLAG_RX_AVAIL 0x01 /* packet available for receipt */
70 #define ATL2_FLAG_READ_PEND 0x02 /* read request pending */
71 #define ATL2_FLAG_WRITE_PEND 0x04 /* write request pending */
72 #define ATL2_FLAG_PACK_RCVD 0x08 /* packet received */
73 #define ATL2_FLAG_PACK_SENT 0x10 /* packet transmitted */
75 #define ATL2_READ_U8(off) (* (u8_t *) (state.base + (off)))
76 #define ATL2_READ_U16(off) (* (u16_t *) (state.base + (off)))
77 #define ATL2_READ_U32(off) (* (u32_t *) (state.base + (off)))
78 #define ATL2_WRITE_U8(off, val) * (u8_t *) (state.base + (off)) = (val);
79 #define ATL2_WRITE_U16(off, val) * (u16_t *) (state.base + (off)) = (val);
80 #define ATL2_WRITE_U32(off, val) * (u32_t *) (state.base + (off)) = (val);
82 #define ATL2_ALIGN_32(n) (((n) + 3) & ~3)
84 PRIVATE iovec_s_t iovec[NR_IOREQS];
86 PRIVATE struct {
87 u16_t vid;
88 u16_t did;
89 } pcitab[] = {
90 { 0x1969, 0x2048 }, /* Attansic Technology Corp, L2 FastEthernet */
91 { 0x0000, 0x0000 }
94 PRIVATE long instance;
96 /*===========================================================================*
97 * atl2_read_vpd *
98 *===========================================================================*/
99 PRIVATE int atl2_read_vpd(int index, u32_t *res)
101 /* Read a value from the VPD register area.
103 u32_t off, val;
104 int i;
106 ATL2_WRITE_U32(ATL2_VPD_DATA_REG, 0);
108 off = ATL2_VPD_REGBASE + index * sizeof(u32_t);
110 ATL2_WRITE_U32(ATL2_VPD_CAP_REG,
111 (off << ATL2_VPD_CAP_ADDR_SHIFT) & ATL2_VPD_CAP_ADDR_MASK);
113 for (i = 0; i < ATL2_VPD_NTRIES; i++) {
114 micro_delay(ATL2_VPD_DELAY);
116 val = ATL2_READ_U32(ATL2_VPD_CAP_REG);
117 if (val & ATL2_VPD_CAP_DONE)
118 break;
121 if (i == ATL2_VPD_NTRIES) {
122 printf("ATL2: timeout reading EEPROM register %d\n", index);
123 return FALSE;
126 *res = ATL2_READ_U32(ATL2_VPD_DATA_REG);
127 return TRUE;
130 /*===========================================================================*
131 * atl2_get_vpd_hwaddr *
132 *===========================================================================*/
133 PRIVATE int atl2_get_vpd_hwaddr(void)
135 /* Read the MAC address from the EEPROM, using the Vital Product Data
136 * register interface.
138 u32_t key, val;
139 int i, n, found[2];
141 /* No idea, copied from FreeBSD which copied it from Linux. */
142 val = ATL2_READ_U32(ATL2_SPICTL_REG);
143 if (val & ATL2_SPICTL_VPD_EN) {
144 val &= ~ATL2_SPICTL_VPD_EN;
145 ATL2_WRITE_U32(ATL2_SPICTL_REG, val);
148 /* Is VPD supported? */
149 #ifdef PCI_CAP_VPD /* FIXME: just a guess at the future name */
150 if (!pci_find_cap(state.devind, PCI_CAP_VPD, &n))
151 return FALSE;
152 #endif
154 /* Read out the set of key/value pairs. Look for the two parts that
155 * make up the MAC address.
157 found[0] = found[1] = FALSE;
158 for (i = 0; i < ATL2_VPD_NREGS; i += 2) {
159 if (!atl2_read_vpd(i, &key))
160 break;
162 if ((key & ATL2_VPD_SIG_MASK) != ATL2_VPD_SIG)
163 break;
165 key >>= ATL2_VPD_REG_SHIFT;
167 if (key != ATL2_HWADDR0_REG && key != ATL2_HWADDR1_REG)
168 continue;
170 if (!atl2_read_vpd(i + 1, &val))
171 break;
173 n = (key == ATL2_HWADDR1_REG);
174 state.hwaddr[n] = val;
175 found[n] = TRUE;
177 if (found[1 - n]) break;
180 return found[0] && found[1];
183 /*===========================================================================*
184 * atl2_get_hwaddr *
185 *===========================================================================*/
186 PRIVATE void atl2_get_hwaddr(void)
188 /* Get the MAC address of the card. First try the EEPROM; if that
189 * fails, just use whatever the card was already set to.
192 if (!atl2_get_vpd_hwaddr()) {
193 printf("ATL2: unable to read from VPD\n");
195 state.hwaddr[0] = ATL2_READ_U32(ATL2_HWADDR0_REG);
196 state.hwaddr[1] = ATL2_READ_U32(ATL2_HWADDR1_REG) & 0xffff;
199 ATL2_DEBUG(("ATL2: MAC address %04lx%08lx\n",
200 state.hwaddr[1], state.hwaddr[0]));
203 /*===========================================================================*
204 * atl2_read_mdio *
205 *===========================================================================*/
206 PRIVATE int atl2_read_mdio(int addr, u16_t *res)
208 /* Read a MII PHY register using MDIO.
210 u32_t rval;
211 int i;
213 rval = ((addr << ATL2_MDIO_ADDR_SHIFT) & ATL2_MDIO_ADDR_MASK) |
214 ATL2_MDIO_START | ATL2_MDIO_READ | ATL2_MDIO_SUP_PREAMBLE |
215 ATL2_MDIO_CLK_25_4;
217 ATL2_WRITE_U32(ATL2_MDIO_REG, rval);
219 for (i = 0; i < ATL2_MDIO_NTRIES; i++) {
220 micro_delay(ATL2_MDIO_DELAY);
222 rval = ATL2_READ_U32(ATL2_MDIO_REG);
224 if (!(rval & (ATL2_MDIO_START | ATL2_MDIO_BUSY)))
225 break;
228 if (i == ATL2_MDIO_NTRIES) return FALSE;
230 *res = (u16_t) (rval & ATL2_MDIO_DATA_MASK);
231 return TRUE;
234 /*===========================================================================*
235 * atl2_alloc_dma *
236 *===========================================================================*/
237 PRIVATE int atl2_alloc_dma(void)
239 /* Allocate DMA ring buffers.
242 state.txd_base = alloc_contig(ATL2_TXD_BUFSIZE,
243 AC_ALIGN4K, &state.txd_phys);
244 state.txs_base = alloc_contig(ATL2_TXS_COUNT * sizeof(u32_t),
245 AC_ALIGN4K, &state.txs_phys);
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.
250 state.rxd_align = 128 - offsetof(rxd_t, data);
251 state.rxd_base_u =
252 alloc_contig(state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE,
253 AC_ALIGN4K, &state.rxd_phys);
255 /* Unlike mmap, alloc_contig returns NULL on failure. */
256 if (!state.txd_base || !state.txs_base || !state.rxd_base_u)
257 return ENOMEM;
259 state.rxd_base = (rxd_t *) (state.rxd_base_u + state.rxd_align);
260 state.rxd_phys += state.rxd_align;
262 /* Zero out just in case. */
263 memset(state.txd_base, 0, ATL2_TXD_BUFSIZE);
264 memset(state.txs_base, 0, ATL2_TXS_COUNT * sizeof(u32_t));
265 memset(state.rxd_base, 0, ATL2_RXD_COUNT * ATL2_RXD_SIZE);
267 return OK;
270 /*===========================================================================*
271 * atl2_stop *
272 *===========================================================================*/
273 PRIVATE int atl2_stop(void)
275 /* Stop the device.
277 u32_t val;
278 int i;
280 /* Clear and disable interrupts. */
281 ATL2_WRITE_U32(ATL2_IMR_REG, 0);
282 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff);
284 /* Stop Rx/Tx MACs. */
285 val = ATL2_READ_U32(ATL2_MAC_REG);
286 if (val & (ATL2_MAC_RX_EN | ATL2_MAC_TX_EN)) {
287 val &= ~(ATL2_MAC_RX_EN | ATL2_MAC_TX_EN);
288 ATL2_WRITE_U32(ATL2_MAC_REG, val);
291 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, 0);
292 ATL2_WRITE_U8(ATL2_DMAREAD_REG, 0);
294 /* Wait until everything is idle. */
295 for (i = 0; i < ATL2_IDLE_NTRIES; i++) {
296 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0)
297 break;
299 micro_delay(ATL2_IDLE_DELAY);
302 /* The caller will generally ignore this return value. */
303 return (i < ATL2_IDLE_NTRIES);
306 /*===========================================================================*
307 * atl2_reset *
308 *===========================================================================*/
309 PRIVATE int atl2_reset(void)
311 /* Reset the device to a known good state.
313 u32_t val;
314 int i;
316 /* Issue a soft reset, and wait for the device to respond. */
317 ATL2_WRITE_U32(ATL2_MASTER_REG, ATL2_MASTER_SOFT_RESET);
319 for (i = 0; i < ATL2_RESET_NTRIES; i++) {
320 val = ATL2_READ_U32(ATL2_MASTER_REG);
321 if (!(val & ATL2_MASTER_SOFT_RESET))
322 break;
324 micro_delay(ATL2_RESET_DELAY);
327 if (i == ATL2_RESET_NTRIES)
328 return FALSE;
330 /* Wait until everything is idle. */
331 for (i = 0; i < ATL2_IDLE_NTRIES; i++) {
332 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0)
333 break;
335 micro_delay(ATL2_IDLE_DELAY);
338 return (i < ATL2_IDLE_NTRIES);
341 /*===========================================================================*
342 * atl2_set_mode *
343 *===========================================================================*/
344 PRIVATE void atl2_set_mode(void)
346 /* Reconfigure the device's promiscuity, multicast, and broadcast mode
347 * settings.
349 u32_t val;
351 val = ATL2_READ_U32(ATL2_MAC_REG);
352 val &= ~(ATL2_MAC_PROMISC_EN | ATL2_MAC_MCAST_EN | ATL2_MAC_BCAST_EN);
354 if (state.mode & DL_PROMISC_REQ)
355 val |= ATL2_MAC_PROMISC_EN;
356 if (state.mode & DL_MULTI_REQ)
357 val |= ATL2_MAC_MCAST_EN;
358 if (state.mode & DL_BROAD_REQ)
359 val |= ATL2_MAC_BCAST_EN;
361 ATL2_WRITE_U32(ATL2_MAC_REG, val);
364 /*===========================================================================*
365 * atl2_setup *
366 *===========================================================================*/
367 PRIVATE int atl2_setup(void)
369 /* Set up the device for normal operation.
371 u32_t val;
373 atl2_stop();
375 if (!atl2_reset())
376 return FALSE;
378 /* Initialize PCIE module. Magic. */
379 ATL2_WRITE_U32(ATL2_LTSSM_TESTMODE_REG, ATL2_LTSSM_TESTMODE_DEFAULT);
380 ATL2_WRITE_U32(ATL2_DLL_TX_CTRL_REG, ATL2_DLL_TX_CTRL_DEFAULT);
382 /* Enable PHY. */
383 ATL2_WRITE_U32(ATL2_PHY_ENABLE_REG, ATL2_PHY_ENABLE);
384 micro_delay(1000);
386 /* Clear and disable interrupts. */
387 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff);
389 /* Set the MAC address. */
390 ATL2_WRITE_U32(ATL2_HWADDR0_REG, state.hwaddr[0]);
391 ATL2_WRITE_U32(ATL2_HWADDR1_REG, state.hwaddr[1]);
393 /* Initialize ring buffer addresses and sizes. */
394 ATL2_WRITE_U32(ATL2_DESC_ADDR_HI_REG, 0); /* no 64 bit */
395 ATL2_WRITE_U32(ATL2_TXD_ADDR_LO_REG, state.txd_phys);
396 ATL2_WRITE_U32(ATL2_TXS_ADDR_LO_REG, state.txs_phys);
397 ATL2_WRITE_U32(ATL2_RXD_ADDR_LO_REG, state.rxd_phys);
399 ATL2_WRITE_U16(ATL2_RXD_COUNT_REG, ATL2_RXD_COUNT);
400 ATL2_WRITE_U16(ATL2_TXD_BUFSIZE_REG, ATL2_TXD_BUFSIZE / sizeof(u32_t));
401 ATL2_WRITE_U16(ATL2_TXS_COUNT_REG, ATL2_TXS_COUNT);
403 /* A whole lot of other initialization copied from Linux/FreeBSD. */
404 ATL2_WRITE_U32(ATL2_IFG_REG, ATL2_IFG_DEFAULT);
406 ATL2_WRITE_U32(ATL2_HDPX_REG, ATL2_HDPX_DEFAULT);
408 ATL2_WRITE_U16(ATL2_IMT_REG, ATL2_IMT_DEFAULT);
409 val = ATL2_READ_U32(ATL2_MASTER_REG);
410 ATL2_WRITE_U32(ATL2_MASTER_REG, val | ATL2_MASTER_IMT_EN);
412 ATL2_WRITE_U16(ATL2_ICT_REG, ATL2_ICT_DEFAULT);
414 ATL2_WRITE_U32(ATL2_CUT_THRESH_REG, ATL2_CUT_THRESH_DEFAULT);
416 ATL2_WRITE_U16(ATL2_FLOW_THRESH_HI_REG, (ATL2_RXD_COUNT / 8) * 7);
417 ATL2_WRITE_U16(ATL2_FLOW_THRESH_LO_REG, ATL2_RXD_COUNT / 12);
419 /* Set MTU. */
420 ATL2_WRITE_U16(ATL2_MTU_REG, ATL2_MTU_DEFAULT);
422 /* Reset descriptors, and enable DMA. */
423 state.txd_tail = state.txs_tail = state.rxd_tail = 0;
424 state.txd_num = state.txs_num = 0;
425 state.flags &= ~ATL2_FLAG_RX_AVAIL;
426 ATL2_WRITE_U16(ATL2_TXD_IDX_REG, 0);
427 ATL2_WRITE_U16(ATL2_RXD_IDX_REG, 0);
429 ATL2_WRITE_U8(ATL2_DMAREAD_REG, ATL2_DMAREAD_EN);
430 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, ATL2_DMAWRITE_EN);
432 /* Did everything go alright? */
433 val = ATL2_READ_U32(ATL2_ISR_REG);
434 if (val & ATL2_ISR_PHY_LINKDOWN) {
435 printf("ATL2: initialization failed\n");
436 return FALSE;
439 /* Clear interrupt status. */
440 ATL2_WRITE_U32(ATL2_ISR_REG, 0x3fffffff);
441 ATL2_WRITE_U32(ATL2_ISR_REG, 0);
443 /* Enable interrupts. */
444 ATL2_WRITE_U32(ATL2_IMR_REG, ATL2_IMR_DEFAULT);
446 /* Configure MAC. */
447 ATL2_WRITE_U32(ATL2_MAC_REG, ATL2_MAC_DEFAULT);
449 /* Inet does not tell us about the multicast addresses that it is
450 * interested in, so we have to simply accept all multicast packets.
452 ATL2_WRITE_U32(ATL2_MHT0_REG, 0xffffffff);
453 ATL2_WRITE_U32(ATL2_MHT1_REG, 0xffffffff);
455 atl2_set_mode();
457 /* Enable Tx/Rx. */
458 val = ATL2_READ_U32(ATL2_MAC_REG);
459 ATL2_WRITE_U32(ATL2_MAC_REG, val | ATL2_MAC_TX_EN | ATL2_MAC_RX_EN);
461 return TRUE;
464 /*===========================================================================*
465 * atl2_probe *
466 *===========================================================================*/
467 PRIVATE int atl2_probe(int instance)
469 /* Find a matching PCI device.
471 u16_t vid, did;
472 char *dname;
473 int i, r, devind, skip;
475 pci_init();
477 r = pci_first_dev(&devind, &vid, &did);
478 if (r <= 0)
479 return -1;
481 skip = 0;
483 for (;;) {
484 for (i = 0; pcitab[i].vid != 0; i++)
485 if (pcitab[i].vid == vid && pcitab[i].did == did)
486 break;
488 if (pcitab[i].vid != 0) {
489 if (skip == instance) break;
491 skip++;
494 r = pci_next_dev(&devind, &vid, &did);
495 if (r <= 0)
496 return -1;
499 dname = pci_dev_name(vid, did);
500 ATL2_DEBUG(("ATL2: found %s (%x/%x) at %s\n",
501 dname ? dname : "<unknown>", vid, did,
502 pci_slot_name(devind)));
504 pci_reserve(devind);
506 return devind;
509 /*===========================================================================*
510 * atl2_init *
511 *===========================================================================*/
512 PRIVATE void atl2_init(int devind)
514 /* Initialize the device.
516 u32_t bar;
517 int r;
519 /* Initialize global state. */
520 state.devind = devind;
521 state.mode = DL_NOMODE;
522 state.flags = 0;
523 state.recv_count = 0;
525 memset(&state.stat, 0, sizeof(state.stat));
527 bar = pci_attr_r32(devind, PCI_BAR) & 0xfffffff0;
529 /* FIXME: hardcoded length, as PCI doesn't expose the size, and it is
530 * not our job to compute the size from the BAR ourselves.
532 state.base = vm_map_phys(SELF, (void *) bar, ATL2_MMAP_SIZE);
533 if (state.base == MAP_FAILED)
534 panic("atl2", "unable to map in registers", NO_NUM);
536 if ((r = atl2_alloc_dma()) != OK)
537 panic("atl2", "unable to allocate DMA buffers", r);
539 state.irq = pci_attr_r8(devind, PCI_ILR);
541 if ((r = sys_irqsetpolicy(state.irq, 0, &state.hook_id)) != OK)
542 panic("atl2", "unable to register IRQ", r);
544 if (!atl2_reset())
545 panic("atl2", "unable to reset hardware", NO_NUM);
547 if ((r = sys_irqenable(&state.hook_id)) != OK)
548 panic("atl2", "unable to enable IRQ", r);
550 atl2_get_hwaddr();
552 atl2_setup();
555 /*===========================================================================*
556 * atl2_tx_stat *
557 *===========================================================================*/
558 PRIVATE void atl2_tx_stat(u32_t stat)
560 /* Update statistics for packet transmission.
563 if (stat & ATL2_TXS_SUCCESS)
564 state.stat.ets_packetT++;
565 else
566 state.stat.ets_recvErr++;
568 if (stat & ATL2_TXS_DEFER)
569 state.stat.ets_transDef++;
570 if (stat & (ATL2_TXS_EXCDEFER | ATL2_TXS_ABORTCOL))
571 state.stat.ets_transAb++;
572 if (stat & ATL2_TXS_SINGLECOL)
573 state.stat.ets_collision++;
574 if (stat & ATL2_TXS_MULTICOL)
575 state.stat.ets_collision++;
576 if (stat & ATL2_TXS_LATECOL)
577 state.stat.ets_OWC++;
578 if (stat & ATL2_TXS_UNDERRUN)
579 state.stat.ets_fifoUnder++;
582 /*===========================================================================*
583 * atl2_rx_stat *
584 *===========================================================================*/
585 PRIVATE void atl2_rx_stat(u32_t stat)
587 /* Update statistics for packet receipt.
590 if (stat & ATL2_RXD_SUCCESS)
591 state.stat.ets_packetR++;
592 else
593 state.stat.ets_recvErr++;
595 if (stat & ATL2_RXD_CRCERR)
596 state.stat.ets_CRCerr++;
597 if (stat & ATL2_RXD_FRAG)
598 state.stat.ets_collision++;
599 if (stat & ATL2_RXD_TRUNC)
600 state.stat.ets_fifoOver++;
601 if (stat & ATL2_RXD_ALIGN)
602 state.stat.ets_frameAll++;
605 /*===========================================================================*
606 * atl2_tx_advance *
607 *===========================================================================*/
608 PRIVATE int atl2_tx_advance(void)
610 /* Advance the TxD/TxS tails by as many sent packets as found.
612 u32_t stat, size, dsize;
613 int advanced;
615 advanced = FALSE;
617 while (state.txs_num > 0) {
618 /* Has the tail packet been processed by the driver? */
619 stat = state.txs_base[state.txs_tail];
621 if (!(stat & ATL2_TXS_UPDATE))
622 break;
624 /* The packet size from the status must match the packet size
625 * we put in. If they don't, there's not much we can do..
627 size = stat & ATL2_TXS_SIZE_MASK;
629 assert(state.txd_tail <= ATL2_TXD_BUFSIZE - sizeof(u32_t));
630 dsize = * (u32_t *) (state.txd_base + state.txd_tail);
631 if (size != dsize)
632 printf("ATL2: TxD/TxS size mismatch (%lx vs %lx)\n",
633 size, dsize);
635 /* Advance tails accordingly. */
636 size = sizeof(u32_t) + ATL2_ALIGN_32(dsize);
637 assert(state.txd_num >= size);
638 state.txd_tail = (state.txd_tail + size) % ATL2_TXD_BUFSIZE;
639 state.txd_num -= size;
641 state.txs_tail = (state.txs_tail + 1) % ATL2_TXS_COUNT;
642 state.txs_num--;
644 if (stat & ATL2_TXS_SUCCESS)
645 ATL2_DEBUG(("ATL2: successfully sent packet\n"));
646 else
647 ATL2_DEBUG(("ATL2: failed to send packet\n"));
649 /* Update statistics. */
650 atl2_tx_stat(stat);
652 advanced = TRUE;
655 return advanced;
658 /*===========================================================================*
659 * atl2_rx_advance *
660 *===========================================================================*/
661 PRIVATE void atl2_rx_advance(int next)
663 /* Advance the RxD tail by as many failed receipts as possible, and
664 * see if there is an actual packet left to receive. If 'next' is set,
665 * the packet at the current tail has been processed.
667 int update_tail;
668 rxd_t *rxd;
669 u32_t hdr, size;
671 update_tail = FALSE;
673 if (next) {
674 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT;
675 update_tail = TRUE;
677 ATL2_DEBUG(("ATL2: successfully received packet\n"));
679 state.flags &= ~ATL2_FLAG_RX_AVAIL;
682 assert(!(state.flags & ATL2_FLAG_RX_AVAIL));
684 for (;;) {
685 /* Check the RxD tail for updates. */
686 rxd = &state.rxd_base[state.rxd_tail];
688 hdr = rxd->hdr;
690 if (!(hdr & ATL2_RXD_UPDATE))
691 break;
693 rxd->hdr = hdr & ~(ATL2_RXD_UPDATE);
695 /* Update statistics. */
696 atl2_rx_stat(hdr);
698 /* Stop at the first successful receipt. The packet will be
699 * picked up by Inet later.
701 size = hdr & ATL2_RXD_SIZE_MASK;
703 if ((hdr & ATL2_RXD_SUCCESS) && size >= ETH_MIN_PACK_SIZE) {
704 ATL2_DEBUG(("ATL2: packet available, size %ld\n",
705 size));
707 state.flags |= ATL2_FLAG_RX_AVAIL;
708 break;
711 ATL2_DEBUG(("ATL2: packet receipt failed\n"));
713 /* Advance tail. */
714 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT;
715 update_tail = TRUE;
718 /* If new RxD descriptors are now up for reuse, tell the device. */
719 if (update_tail)
720 ATL2_WRITE_U32(ATL2_RXD_IDX_REG, state.rxd_tail);
723 /*===========================================================================*
724 * atl2_reply *
725 *===========================================================================*/
726 PRIVATE void atl2_reply(void)
728 /* Send a task reply to Inet.
730 message m;
731 int r, stat;
733 stat = 0;
734 if (state.flags & ATL2_FLAG_PACK_SENT)
735 stat |= DL_PACK_SEND;
736 if (state.flags & ATL2_FLAG_PACK_RCVD)
737 stat |= DL_PACK_RECV;
739 m.m_type = DL_TASK_REPLY;
740 m.DL_PORT = 0;
741 m.DL_PROC = state.task_endpt;
742 m.DL_STAT = stat;
743 m.DL_COUNT = state.recv_count;
745 ATL2_DEBUG(("ATL2: sending reply stat %x count %d\n", stat,
746 m.DL_COUNT));
748 if ((r = send(state.task_endpt, &m)) != OK)
749 panic("atl2", "unable to reply", r);
751 state.flags &= ~(ATL2_FLAG_PACK_SENT | ATL2_FLAG_PACK_RCVD);
752 state.recv_count = 0;
755 /*===========================================================================*
756 * atl2_readv *
757 *===========================================================================*/
758 PRIVATE void atl2_readv(message *m, int from_int)
760 /* Read packet data.
762 rxd_t *rxd;
763 iovec_s_t *iovp;
764 size_t count, off, left, size;
765 u8_t *pos;
766 int i, j, r, batch;
768 if (m->DL_PORT != 0) {
769 printf("ATL2: read from invalid port\n");
771 return;
774 /* We can deal with only one read request from Inet at a time. */
775 assert(from_int || !(state.flags & ATL2_FLAG_READ_PEND));
777 /* The exact semantics of DL_PROC are not clear. This driver takes it
778 * to be only the grant owner; other drivers treat it as the reply
779 * destination as well.
781 assert(m->m_source == m->DL_PROC);
782 state.task_endpt = m->m_source;
784 /* Are there any packets available at all? */
785 if (!(state.flags & ATL2_FLAG_RX_AVAIL))
786 goto suspend;
788 /* Get the first available packet's size. Cut off the CRC. */
789 rxd = &state.rxd_base[state.rxd_tail];
791 count = rxd->hdr & ATL2_RXD_SIZE_MASK;
792 count -= ETH_CRC_SIZE;
794 ATL2_DEBUG(("ATL2: readv: found packet with length %d\n", count));
796 /* Copy out the packet. */
797 off = 0;
798 left = count;
799 pos = rxd->data;
801 for (i = 0; i < m->DL_COUNT && left > 0; i += batch) {
802 /* Copy in the next batch. */
803 batch = MIN(m->DL_COUNT - i, NR_IOREQS);
805 r = sys_safecopyfrom(m->DL_PROC, m->DL_GRANT, off,
806 (vir_bytes) iovec, batch * sizeof(iovec[0]), D);
807 if (r != OK)
808 panic("atl2", "vector copy failed", r);
810 /* Copy out each element in the batch, until we run out. */
811 for (j = 0, iovp = iovec; j < batch && left > 0; j++, iovp++) {
812 size = MIN(iovp->iov_size, left);
814 r = sys_safecopyto(m->DL_PROC, iovp->iov_grant, 0,
815 (vir_bytes) pos, size, D);
816 if (r != OK)
817 panic("atl2", "safe copy failed", r);
819 pos += size;
820 left -= size;
823 off += batch * sizeof(iovec[0]);
826 /* Not sure what to do here. Inet shouldn't mess this up anyway. */
827 if (left > 0) {
828 printf("ATL2: truncated packet of %d bytes by %d bytes\n",
829 count, left);
830 count -= left;
833 /* We are done with this packet. Move on to the next. */
834 atl2_rx_advance(TRUE /*next*/);
836 /* We have now successfully received a packet. */
837 state.flags &= ~ATL2_FLAG_READ_PEND;
838 state.flags |= ATL2_FLAG_PACK_RCVD;
839 state.recv_count = count;
841 /* If called from the interrupt handler, the caller will reply. */
842 if (!from_int)
843 atl2_reply();
845 return;
847 suspend:
848 /* No packets are available at this time. If we were not already
849 * trying to resume receipt, save the read request for later, and tell
850 * Inet that the request has been suspended.
852 if (from_int)
853 return;
855 state.flags |= ATL2_FLAG_READ_PEND;
856 state.read_msg = *m;
858 atl2_reply();
861 /*===========================================================================*
862 * atl2_writev *
863 *===========================================================================*/
864 PRIVATE void atl2_writev(message *m, int from_int)
866 /* Write packet data.
868 iovec_s_t *iovp;
869 size_t off, count, left, pos, size, skip;
870 u8_t *sizep;
871 int i, j, r, batch, maxnum;
873 if (m->DL_PORT != 0) {
874 printf("ATL2: write to invalid port\n");
876 return;
879 /* We can deal with only one write request from Inet at a time. */
880 assert(from_int || !(state.flags & ATL2_FLAG_WRITE_PEND));
882 assert(m->m_source == m->DL_PROC);
883 state.task_endpt = m->m_source;
885 /* If we are already certain that the packet won't fit, bail out.
886 * Keep at least some space between TxD head and tail, as it is not
887 * clear whether the device deals well with the case that they collide.
889 if (state.txs_num >= ATL2_TXS_COUNT)
890 goto suspend;
891 maxnum = ATL2_TXD_BUFSIZE - ETH_MIN_PACK_SIZE - sizeof(u32_t);
892 if (state.txd_num >= maxnum)
893 goto suspend;
895 /* Optimistically try to copy in the data; suspend if it turns out
896 * that it does not fit.
898 off = 0;
899 count = 0;
900 left = state.txd_num - sizeof(u32_t);
901 pos = (state.txd_tail + state.txd_num +
902 sizeof(u32_t)) % ATL2_TXD_BUFSIZE;
904 for (i = 0; i < m->DL_COUNT; i += batch) {
905 /* Copy in the next batch. */
906 batch = MIN(m->DL_COUNT - i, NR_IOREQS);
908 r = sys_safecopyfrom(m->DL_PROC, m->DL_GRANT, off,
909 (vir_bytes) iovec, batch * sizeof(iovec[0]), D);
910 if (r != OK)
911 panic("atl2", "vector copy failed", r);
913 /* Copy in each element in the batch. */
914 for (j = 0, iovp = iovec; j < batch; j++, iovp++) {
915 size = iovp->iov_size;
916 if (size > left)
917 goto suspend;
919 skip = 0;
920 if (size > ATL2_TXD_BUFSIZE - pos) {
921 skip = ATL2_TXD_BUFSIZE - pos;
922 r = sys_safecopyfrom(m->DL_PROC,
923 iovp->iov_grant, 0,
924 (vir_bytes) (state.txd_base + pos),
925 skip, D);
926 if (r != OK)
927 panic("atl2", "safe copy failed", r);
928 pos = 0;
931 r = sys_safecopyfrom(m->DL_PROC, iovp->iov_grant, skip,
932 (vir_bytes) (state.txd_base + pos),
933 size - skip, D);
934 if (r != OK)
935 panic("atl2", "safe copy failed", r);
937 pos = (pos + size - skip) % ATL2_TXD_BUFSIZE;
938 left -= size;
939 count += size;
942 off += batch * sizeof(iovec[0]);
945 assert(count <= ETH_MAX_PACK_SIZE_TAGGED);
947 /* Write the length to the DWORD right before the packet. */
948 sizep = state.txd_base +
949 (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE;
950 * (u32_t *) sizep = count;
952 /* Update the TxD head. */
953 state.txd_num += sizeof(u32_t) + ATL2_ALIGN_32(count);
954 pos = ATL2_ALIGN_32(pos) % ATL2_TXD_BUFSIZE;
955 assert(pos == (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE);
957 /* Initialize and update the TxS head. */
958 state.txs_base[(state.txs_tail + state.txs_num) % ATL2_TXS_COUNT] = 0;
959 state.txs_num++;
961 /* Tell the device about our new position. */
962 ATL2_WRITE_U32(ATL2_TXD_IDX_REG, pos / sizeof(u32_t));
964 /* We have now successfully set up the transmission of a packet. */
965 state.flags &= ~ATL2_FLAG_WRITE_PEND;
966 state.flags |= ATL2_FLAG_PACK_SENT;
968 /* If called from the interrupt handler, the caller will reply. */
969 if (!from_int)
970 atl2_reply();
972 return;
974 suspend:
975 /* We cannot transmit the packet at this time. If we were not already
976 * trying to resume transmission, save the write request for later,
977 * and tell Inet that the request has been suspended.
979 if (from_int)
980 return;
982 state.flags |= ATL2_FLAG_WRITE_PEND;
983 state.write_msg = *m;
985 atl2_reply();
988 /*===========================================================================*
989 * atl2_intr *
990 *===========================================================================*/
991 PRIVATE void atl2_intr(message *m)
993 /* Interrupt received.
995 u32_t val;
996 int r, try_write, try_read;
998 /* Clear and disable interrupts. */
999 val = ATL2_READ_U32(ATL2_ISR_REG);
1001 ATL2_WRITE_U32(ATL2_ISR_REG, val | ATL2_ISR_DISABLE);
1003 ATL2_DEBUG(("ATL2: interrupt (0x%08lx)\n", val));
1005 /* If an error occurred, reset the card. */
1006 if (val & (ATL2_ISR_DMAR_TIMEOUT | ATL2_ISR_DMAW_TIMEOUT |
1007 ATL2_ISR_PHY_LINKDOWN)) {
1008 atl2_setup();
1011 try_write = try_read = FALSE;
1013 /* Process sent data, and possibly send pending data. */
1014 if (val & ATL2_ISR_TX_EVENT) {
1015 if (atl2_tx_advance())
1016 try_write = (state.flags & ATL2_FLAG_WRITE_PEND);
1019 /* Receive new data, and possible satisfy a pending receive request. */
1020 if (val & ATL2_ISR_RX_EVENT) {
1021 if (!(state.flags & ATL2_FLAG_RX_AVAIL)) {
1022 atl2_rx_advance(FALSE /*next*/);
1024 try_read = (state.flags & ATL2_FLAG_READ_PEND);
1028 /* Reenable interrupts. */
1029 ATL2_WRITE_U32(ATL2_ISR_REG, 0);
1031 if ((r = sys_irqenable(&state.hook_id)) != OK)
1032 panic("atl2", "unable to enable IRQ", r);
1034 /* Attempt to satisfy pending write and read requests. */
1035 if (try_write)
1036 atl2_writev(&state.write_msg, TRUE /*from_int*/);
1037 if (try_read)
1038 atl2_readv(&state.read_msg, TRUE /*from_int*/);
1039 if (state.flags & (ATL2_FLAG_PACK_SENT | ATL2_FLAG_PACK_RCVD))
1040 atl2_reply();
1043 /*===========================================================================*
1044 * atl2_conf *
1045 *===========================================================================*/
1046 PRIVATE void atl2_conf(message *m)
1048 /* Configure the mode of the card.
1050 ether_addr_t *addr;
1051 int r;
1053 if (m->DL_PORT != 0) {
1054 m->m3_i1 = ENXIO;
1056 else {
1057 state.mode = m->DL_MODE;
1059 atl2_set_mode();
1061 addr = (ether_addr_t *) m->m3_ca1;
1063 addr->ea_addr[0] = state.hwaddr[1] >> 8;
1064 addr->ea_addr[1] = state.hwaddr[1] & 0xff;
1065 addr->ea_addr[2] = state.hwaddr[0] >> 24;
1066 addr->ea_addr[3] = (state.hwaddr[0] >> 16) & 0xff;
1067 addr->ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff;
1068 addr->ea_addr[5] = state.hwaddr[0] & 0xff;
1070 m->m3_i1 = OK;
1073 m->m_type = DL_CONF_REPLY;
1075 if ((r = send(m->m_source, m)) != OK)
1076 printf("ATL2: unable to send reply (%d)\n", r);
1079 /*===========================================================================*
1080 * atl2_getstat *
1081 *===========================================================================*/
1082 PRIVATE void atl2_getstat(message *m)
1084 /* Copy out statistics.
1086 int r;
1088 if (m->DL_PORT != 0) {
1089 r = ENXIO;
1091 else {
1092 r = sys_safecopyto(m->DL_PROC, m->DL_GRANT, 0,
1093 (vir_bytes) &state.stat, sizeof(state.stat), D);
1096 m->m_type = DL_STAT_REPLY;
1097 /* keep m->DL_PORT */
1098 m->DL_STAT = r;
1100 if ((r = send(m->m_source, m)) != OK)
1101 printf("ATL2: unable to send reply (%d)\n", r);
1104 /*===========================================================================*
1105 * atl2_getname *
1106 *===========================================================================*/
1107 PRIVATE void atl2_getname(message *m, int instance)
1109 /* Tell Inet the name of this driver.
1111 int r;
1113 /* Each instance must have a unique name. */
1114 m->m_type = DL_NAME_REPLY;
1115 if (instance > 0)
1116 snprintf(m->DL_NAME, sizeof(m->DL_NAME), "atl2:%u",
1117 instance - 1);
1118 else
1119 strcpy(m->DL_NAME, "atl2");
1121 if ((r = send(m->m_source, m)) != OK)
1122 printf("ATL2: unable to send reply (%d)\n", r);
1125 /*===========================================================================*
1126 * atl2_shutdown *
1127 *===========================================================================*/
1128 PRIVATE void atl2_shutdown(void)
1130 /* Shut down this driver. Stop the device, and deallocate resources
1131 * as proof of concept.
1133 int r;
1135 atl2_stop();
1137 if ((r = sys_irqrmpolicy(&state.hook_id)) != OK)
1138 panic("atl2", "unable to deregister IRQ", r);
1140 munmap(state.txd_base, ATL2_TXD_BUFSIZE);
1141 munmap(state.txs_base, ATL2_TXS_COUNT * sizeof(u32_t));
1142 munmap(state.rxd_base_u,
1143 state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE);
1145 vm_unmap_phys(SELF, state.base, ATL2_MMAP_SIZE);
1147 /* We cannot free the PCI device at this time. */
1149 exit(0);
1152 /*===========================================================================*
1153 * atl2_dump_link *
1154 *===========================================================================*/
1155 PRIVATE void atl2_dump_link(void)
1157 /* Dump link status.
1159 u16_t val;
1160 int link_up;
1162 /* The link status bit is latched. Read the status register twice. */
1163 atl2_read_mdio(ATL2_MII_BMSR, &val);
1164 if (!atl2_read_mdio(ATL2_MII_BMSR, &val)) return;
1166 link_up = val & ATL2_MII_BMSR_LSTATUS;
1167 printf("link status: %4s\t", link_up ? "up" : "down");
1169 if (!link_up) return;
1171 if (!atl2_read_mdio(ATL2_MII_PSSR, &val)) return;
1173 if (!(val & ATL2_MII_PSSR_RESOLVED)) {
1174 printf("(not resolved)\n");
1176 return;
1179 switch (val & ATL2_MII_PSSR_SPEED) {
1180 case ATL2_MII_PSSR_10: printf("(10Mbps "); break;
1181 case ATL2_MII_PSSR_100: printf("(100Mbps "); break;
1182 case ATL2_MII_PSSR_1000: printf("(1000Mbps "); break;
1183 default: printf("(unknown, ");
1186 printf("%s duplex)", (val & ATL2_MII_PSSR_DUPLEX) ? "full" : "half");
1189 /*===========================================================================*
1190 * atl2_dump *
1191 *===========================================================================*/
1192 PRIVATE void atl2_dump(void)
1194 /* Dump statistics.
1197 printf("\n");
1198 printf("Attansic L2 statistics:\n");
1200 printf("recvErr: %8ld\t", state.stat.ets_recvErr);
1201 printf("sendErr: %8ld\t", state.stat.ets_sendErr);
1202 printf("OVW: %8ld\n", state.stat.ets_OVW);
1204 printf("CRCerr: %8ld\t", state.stat.ets_CRCerr);
1205 printf("frameAll: %8ld\t", state.stat.ets_frameAll);
1206 printf("missedP: %8ld\n", state.stat.ets_missedP);
1208 printf("packetR: %8ld\t", state.stat.ets_packetR);
1209 printf("packetT: %8ld\t", state.stat.ets_packetT);
1210 printf("transDef: %8ld\n", state.stat.ets_transDef);
1212 printf("collision: %8ld\t", state.stat.ets_collision);
1213 printf("transAb: %8ld\t", state.stat.ets_transAb);
1214 printf("carrSense: %8ld\n", state.stat.ets_carrSense);
1216 printf("fifoUnder: %8ld\t", state.stat.ets_fifoUnder);
1217 printf("fifoOver: %8ld\t", state.stat.ets_fifoOver);
1218 printf("CDheartbeat: %8ld\n", state.stat.ets_CDheartbeat);
1220 printf("OWC: %8ld\t", state.stat.ets_OWC);
1221 printf("TxD tail: %8d\t", state.txd_tail);
1222 printf("TxD count: %8d\n", state.txd_num);
1224 printf("RxD tail: %8d\t", state.rxd_tail);
1225 printf("TxS tail: %8d\t", state.txs_tail);
1226 printf("TxS count: %8d\n", state.txs_num);
1228 printf("flags: 0x%04x\t", state.flags);
1229 atl2_dump_link();
1230 printf("\n");
1233 /*===========================================================================*
1234 * sef_cb_init_fresh *
1235 *===========================================================================*/
1236 PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
1238 /* Initialize the atl2 driver.
1240 u32_t inet_endpt;
1241 int r, devind;
1242 #if ATL2_FKEY
1243 int fkeys, sfkeys;
1244 #endif
1246 /* How many matching devices should we skip? */
1247 instance = 0;
1248 env_parse("atl2_instance", "d", 0, &instance, 0, 32);
1250 /* Try to find a recognized device. */
1251 devind = atl2_probe(instance);
1253 if (devind < 0)
1254 panic("atl2", "no matching device found", NO_NUM);
1256 /* Initialize the device. */
1257 atl2_init(devind);
1259 /* Notify Inet of our presence, if it has already been started. */
1260 r = ds_retrieve_label_num("inet", &inet_endpt);
1261 if (r == OK)
1262 notify(inet_endpt);
1263 else if (r != ESRCH)
1264 printf("ATL2: ds_retrieve_label_num failed for 'inet': %d\n",
1267 #if ATL2_FKEY
1268 /* Register debug dump function key. */
1269 fkeys = sfkeys = 0;
1270 bit_set(sfkeys, 11);
1271 if ((r = fkey_map(&fkeys, &sfkeys)) != OK)
1272 printf("ATL2: warning, could not map Shift+F11 key (%d)\n", r);
1273 #endif
1275 return(OK);
1278 /*===========================================================================*
1279 * sef_local_startup *
1280 *===========================================================================*/
1281 PRIVATE void sef_local_startup(void)
1283 /* Initialize SEF.
1286 /* Register init callbacks. */
1287 sef_setcb_init_fresh(sef_cb_init_fresh);
1288 sef_setcb_init_restart(sef_cb_init_fresh);
1290 /* No support for live update yet. */
1292 /* Let SEF perform startup. */
1293 sef_startup();
1296 /*===========================================================================*
1297 * main *
1298 *===========================================================================*/
1299 int main(int argc, char **argv)
1301 /* Driver task.
1303 message m;
1304 sigset_t set;
1305 int r;
1307 /* Initialize SEF. */
1308 env_setargs(argc, argv);
1309 sef_local_startup();
1311 while (TRUE) {
1312 if ((r = sef_receive(ANY, &m)) != OK)
1313 panic("atl2", "sef_receive failed", r);
1315 if (is_notify(m.m_type)) {
1316 switch (m.m_source) {
1317 case HARDWARE: /* interrupt */
1318 atl2_intr(&m);
1320 break;
1322 case PM_PROC_NR: /* signal */
1323 if (getsigset(&set) != 0) break;
1325 if (sigismember(&set, SIGTERM))
1326 atl2_shutdown();
1328 break;
1330 case TTY_PROC_NR: /* function key */
1331 atl2_dump();
1333 break;
1335 default:
1336 printf("ATL2: illegal notify from %d\n",
1337 m.m_source);
1340 continue;
1343 /* Process requests from Inet. */
1344 switch (m.m_type) {
1345 case DL_GETNAME: atl2_getname(&m, instance); break;
1346 case DL_CONF: atl2_conf(&m); break;
1347 case DL_GETSTAT_S: atl2_getstat(&m); break;
1348 case DL_WRITEV_S: atl2_writev(&m, FALSE); break;
1349 case DL_READV_S: atl2_readv(&m, FALSE); break;
1350 default:
1351 printf("ATL2: illegal message %d from %d\n",
1352 m.m_type, m.m_source);