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.
7 #include <minix/drivers.h>
8 #include <minix/netdriver.h>
13 #include <machine/pci.h>
14 #include <net/gen/ether.h>
15 #include <net/gen/eth_io.h>
20 #define VERBOSE 0 /* Verbose debugging output */
21 #define ATL2_FKEY 1 /* Register Shift+F11 for dumping statistics */
24 #define ATL2_DEBUG(x) printf x
32 u8_t data
[ATL2_RXD_SIZE
- sizeof(u32_t
) * 2];
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 */
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
];
90 { 0x1969, 0x2048 }, /* Attansic Technology Corp, L2 FastEthernet */
94 PRIVATE
long instance
;
96 /*===========================================================================*
98 *===========================================================================*/
99 PRIVATE
int atl2_read_vpd(int index
, u32_t
*res
)
101 /* Read a value from the VPD register area.
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
)
121 if (i
== ATL2_VPD_NTRIES
) {
122 printf("ATL2: timeout reading EEPROM register %d\n", index
);
126 *res
= ATL2_READ_U32(ATL2_VPD_DATA_REG
);
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.
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
))
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
))
162 if ((key
& ATL2_VPD_SIG_MASK
) != ATL2_VPD_SIG
)
165 key
>>= ATL2_VPD_REG_SHIFT
;
167 if (key
!= ATL2_HWADDR0_REG
&& key
!= ATL2_HWADDR1_REG
)
170 if (!atl2_read_vpd(i
+ 1, &val
))
173 n
= (key
== ATL2_HWADDR1_REG
);
174 state
.hwaddr
[n
] = val
;
177 if (found
[1 - n
]) break;
180 return found
[0] && found
[1];
183 /*===========================================================================*
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 /*===========================================================================*
205 *===========================================================================*/
206 PRIVATE
int atl2_read_mdio(int addr
, u16_t
*res
)
208 /* Read a MII PHY register using MDIO.
213 rval
= ((addr
<< ATL2_MDIO_ADDR_SHIFT
) & ATL2_MDIO_ADDR_MASK
) |
214 ATL2_MDIO_START
| ATL2_MDIO_READ
| ATL2_MDIO_SUP_PREAMBLE
|
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
)))
228 if (i
== ATL2_MDIO_NTRIES
) return FALSE
;
230 *res
= (u16_t
) (rval
& ATL2_MDIO_DATA_MASK
);
234 /*===========================================================================*
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
);
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
)
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
);
270 /*===========================================================================*
272 *===========================================================================*/
273 PRIVATE
int atl2_stop(void)
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)
299 micro_delay(ATL2_IDLE_DELAY
);
302 /* The caller will generally ignore this return value. */
303 return (i
< ATL2_IDLE_NTRIES
);
306 /*===========================================================================*
308 *===========================================================================*/
309 PRIVATE
int atl2_reset(void)
311 /* Reset the device to a known good state.
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
))
324 micro_delay(ATL2_RESET_DELAY
);
327 if (i
== ATL2_RESET_NTRIES
)
330 /* Wait until everything is idle. */
331 for (i
= 0; i
< ATL2_IDLE_NTRIES
; i
++) {
332 if (ATL2_READ_U32(ATL2_IDLE_REG
) == 0)
335 micro_delay(ATL2_IDLE_DELAY
);
338 return (i
< ATL2_IDLE_NTRIES
);
341 /*===========================================================================*
343 *===========================================================================*/
344 PRIVATE
void atl2_set_mode(void)
346 /* Reconfigure the device's promiscuity, multicast, and broadcast mode
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 /*===========================================================================*
366 *===========================================================================*/
367 PRIVATE
int atl2_setup(void)
369 /* Set up the device for normal operation.
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
);
383 ATL2_WRITE_U32(ATL2_PHY_ENABLE_REG
, ATL2_PHY_ENABLE
);
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);
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");
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
);
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);
458 val
= ATL2_READ_U32(ATL2_MAC_REG
);
459 ATL2_WRITE_U32(ATL2_MAC_REG
, val
| ATL2_MAC_TX_EN
| ATL2_MAC_RX_EN
);
464 /*===========================================================================*
466 *===========================================================================*/
467 PRIVATE
int atl2_probe(int instance
)
469 /* Find a matching PCI device.
473 int i
, r
, devind
, skip
;
477 r
= pci_first_dev(&devind
, &vid
, &did
);
484 for (i
= 0; pcitab
[i
].vid
!= 0; i
++)
485 if (pcitab
[i
].vid
== vid
&& pcitab
[i
].did
== did
)
488 if (pcitab
[i
].vid
!= 0) {
489 if (skip
== instance
) break;
494 r
= pci_next_dev(&devind
, &vid
, &did
);
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
)));
509 /*===========================================================================*
511 *===========================================================================*/
512 PRIVATE
void atl2_init(int devind
)
514 /* Initialize the device.
519 /* Initialize global state. */
520 state
.devind
= devind
;
521 state
.mode
= DL_NOMODE
;
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("unable to map in registers");
536 if ((r
= atl2_alloc_dma()) != OK
)
537 panic("unable to allocate DMA buffers: %d", r
);
539 state
.irq
= pci_attr_r8(devind
, PCI_ILR
);
541 if ((r
= sys_irqsetpolicy(state
.irq
, 0, &state
.hook_id
)) != OK
)
542 panic("unable to register IRQ: %d", r
);
545 panic("unable to reset hardware");
547 if ((r
= sys_irqenable(&state
.hook_id
)) != OK
)
548 panic("unable to enable IRQ: %d", r
);
555 /*===========================================================================*
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
++;
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 /*===========================================================================*
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
++;
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 /*===========================================================================*
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
;
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
))
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
);
632 printf("ATL2: TxD/TxS size mismatch (%lx vs %lx)\n",
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
;
644 if (stat
& ATL2_TXS_SUCCESS
)
645 ATL2_DEBUG(("ATL2: successfully sent packet\n"));
647 ATL2_DEBUG(("ATL2: failed to send packet\n"));
649 /* Update statistics. */
658 /*===========================================================================*
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.
674 state
.rxd_tail
= (state
.rxd_tail
+ 1) % ATL2_RXD_COUNT
;
677 ATL2_DEBUG(("ATL2: successfully received packet\n"));
679 state
.flags
&= ~ATL2_FLAG_RX_AVAIL
;
682 assert(!(state
.flags
& ATL2_FLAG_RX_AVAIL
));
685 /* Check the RxD tail for updates. */
686 rxd
= &state
.rxd_base
[state
.rxd_tail
];
690 if (!(hdr
& ATL2_RXD_UPDATE
))
693 rxd
->hdr
= hdr
& ~(ATL2_RXD_UPDATE
);
695 /* Update statistics. */
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",
707 state
.flags
|= ATL2_FLAG_RX_AVAIL
;
711 ATL2_DEBUG(("ATL2: packet receipt failed\n"));
714 state
.rxd_tail
= (state
.rxd_tail
+ 1) % ATL2_RXD_COUNT
;
718 /* If new RxD descriptors are now up for reuse, tell the device. */
720 ATL2_WRITE_U32(ATL2_RXD_IDX_REG
, state
.rxd_tail
);
723 /*===========================================================================*
725 *===========================================================================*/
726 PRIVATE
void atl2_reply(void)
728 /* Send a task reply to Inet.
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
;
741 m
.DL_PROC
= state
.task_endpt
;
743 m
.DL_COUNT
= state
.recv_count
;
745 ATL2_DEBUG(("ATL2: sending reply stat %x count %d\n", stat
,
748 if ((r
= send(state
.task_endpt
, &m
)) != OK
)
749 panic("unable to reply: %d", r
);
751 state
.flags
&= ~(ATL2_FLAG_PACK_SENT
| ATL2_FLAG_PACK_RCVD
);
752 state
.recv_count
= 0;
755 /*===========================================================================*
757 *===========================================================================*/
758 PRIVATE
void atl2_readv(const message
*m
, int from_int
)
764 size_t count
, off
, left
, size
;
768 if (m
->DL_PORT
!= 0) {
769 printf("ATL2: read from invalid port\n");
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
))
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. */
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
);
808 panic("vector copy failed: %d", 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
);
817 panic("safe copy failed: %d", r
);
823 off
+= batch
* sizeof(iovec
[0]);
826 /* Not sure what to do here. Inet shouldn't mess this up anyway. */
828 printf("ATL2: truncated packet of %d bytes by %d bytes\n",
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. */
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.
855 state
.flags
|= ATL2_FLAG_READ_PEND
;
861 /*===========================================================================*
863 *===========================================================================*/
864 PRIVATE
void atl2_writev(const message
*m
, int from_int
)
866 /* Write packet data.
869 size_t off
, count
, left
, pos
, skip
;
872 int i
, j
, r
, batch
, maxnum
;
874 if (m
->DL_PORT
!= 0) {
875 printf("ATL2: write to invalid port\n");
880 /* We can deal with only one write request from Inet at a time. */
881 assert(from_int
|| !(state
.flags
& ATL2_FLAG_WRITE_PEND
));
883 assert(m
->m_source
== m
->DL_PROC
);
884 state
.task_endpt
= m
->m_source
;
886 /* If we are already certain that the packet won't fit, bail out.
887 * Keep at least some space between TxD head and tail, as it is not
888 * clear whether the device deals well with the case that they collide.
890 if (state
.txs_num
>= ATL2_TXS_COUNT
)
892 maxnum
= ATL2_TXD_BUFSIZE
- ETH_MIN_PACK_SIZE
- sizeof(u32_t
);
893 if (state
.txd_num
>= maxnum
)
896 /* Optimistically try to copy in the data; suspend if it turns out
897 * that it does not fit.
901 left
= state
.txd_num
- sizeof(u32_t
);
902 pos
= (state
.txd_tail
+ state
.txd_num
+
903 sizeof(u32_t
)) % ATL2_TXD_BUFSIZE
;
905 for (i
= 0; i
< m
->DL_COUNT
; i
+= batch
) {
906 /* Copy in the next batch. */
907 batch
= MIN(m
->DL_COUNT
- i
, NR_IOREQS
);
909 r
= sys_safecopyfrom(m
->DL_PROC
, m
->DL_GRANT
, off
,
910 (vir_bytes
) iovec
, batch
* sizeof(iovec
[0]), D
);
912 panic("vector copy failed: %d", r
);
914 /* Copy in each element in the batch. */
915 for (j
= 0, iovp
= iovec
; j
< batch
; j
++, iovp
++) {
916 size
= iovp
->iov_size
;
921 if (size
> ATL2_TXD_BUFSIZE
- pos
) {
922 skip
= ATL2_TXD_BUFSIZE
- pos
;
923 r
= sys_safecopyfrom(m
->DL_PROC
,
925 (vir_bytes
) (state
.txd_base
+ pos
),
928 panic("safe copy failed: %d", r
);
932 r
= sys_safecopyfrom(m
->DL_PROC
, iovp
->iov_grant
, skip
,
933 (vir_bytes
) (state
.txd_base
+ pos
),
936 panic("safe copy failed: %d", r
);
938 pos
= (pos
+ size
- skip
) % ATL2_TXD_BUFSIZE
;
943 off
+= batch
* sizeof(iovec
[0]);
946 assert(count
<= ETH_MAX_PACK_SIZE_TAGGED
);
948 /* Write the length to the DWORD right before the packet. */
949 sizep
= state
.txd_base
+
950 (state
.txd_tail
+ state
.txd_num
) % ATL2_TXD_BUFSIZE
;
951 * (u32_t
*) sizep
= count
;
953 /* Update the TxD head. */
954 state
.txd_num
+= sizeof(u32_t
) + ATL2_ALIGN_32(count
);
955 pos
= ATL2_ALIGN_32(pos
) % ATL2_TXD_BUFSIZE
;
956 assert(pos
== (state
.txd_tail
+ state
.txd_num
) % ATL2_TXD_BUFSIZE
);
958 /* Initialize and update the TxS head. */
959 state
.txs_base
[(state
.txs_tail
+ state
.txs_num
) % ATL2_TXS_COUNT
] = 0;
962 /* Tell the device about our new position. */
963 ATL2_WRITE_U32(ATL2_TXD_IDX_REG
, pos
/ sizeof(u32_t
));
965 /* We have now successfully set up the transmission of a packet. */
966 state
.flags
&= ~ATL2_FLAG_WRITE_PEND
;
967 state
.flags
|= ATL2_FLAG_PACK_SENT
;
969 /* If called from the interrupt handler, the caller will reply. */
976 /* We cannot transmit the packet at this time. If we were not already
977 * trying to resume transmission, save the write request for later,
978 * and tell Inet that the request has been suspended.
983 state
.flags
|= ATL2_FLAG_WRITE_PEND
;
984 state
.write_msg
= *m
;
989 /*===========================================================================*
991 *===========================================================================*/
992 PRIVATE
void atl2_intr(const message
*m
)
994 /* Interrupt received.
997 int r
, try_write
, try_read
;
999 /* Clear and disable interrupts. */
1000 val
= ATL2_READ_U32(ATL2_ISR_REG
);
1002 ATL2_WRITE_U32(ATL2_ISR_REG
, val
| ATL2_ISR_DISABLE
);
1004 ATL2_DEBUG(("ATL2: interrupt (0x%08lx)\n", val
));
1006 /* If an error occurred, reset the card. */
1007 if (val
& (ATL2_ISR_DMAR_TIMEOUT
| ATL2_ISR_DMAW_TIMEOUT
|
1008 ATL2_ISR_PHY_LINKDOWN
)) {
1012 try_write
= try_read
= FALSE
;
1014 /* Process sent data, and possibly send pending data. */
1015 if (val
& ATL2_ISR_TX_EVENT
) {
1016 if (atl2_tx_advance())
1017 try_write
= (state
.flags
& ATL2_FLAG_WRITE_PEND
);
1020 /* Receive new data, and possible satisfy a pending receive request. */
1021 if (val
& ATL2_ISR_RX_EVENT
) {
1022 if (!(state
.flags
& ATL2_FLAG_RX_AVAIL
)) {
1023 atl2_rx_advance(FALSE
/*next*/);
1025 try_read
= (state
.flags
& ATL2_FLAG_READ_PEND
);
1029 /* Reenable interrupts. */
1030 ATL2_WRITE_U32(ATL2_ISR_REG
, 0);
1032 if ((r
= sys_irqenable(&state
.hook_id
)) != OK
)
1033 panic("unable to enable IRQ: %d", r
);
1035 /* Attempt to satisfy pending write and read requests. */
1037 atl2_writev(&state
.write_msg
, TRUE
/*from_int*/);
1039 atl2_readv(&state
.read_msg
, TRUE
/*from_int*/);
1040 if (state
.flags
& (ATL2_FLAG_PACK_SENT
| ATL2_FLAG_PACK_RCVD
))
1044 /*===========================================================================*
1046 *===========================================================================*/
1047 PRIVATE
void atl2_conf(message
*m
)
1049 /* Configure the mode of the card.
1054 if (m
->DL_PORT
!= 0) {
1058 state
.mode
= m
->DL_MODE
;
1062 addr
= (ether_addr_t
*) m
->m3_ca1
;
1064 addr
->ea_addr
[0] = state
.hwaddr
[1] >> 8;
1065 addr
->ea_addr
[1] = state
.hwaddr
[1] & 0xff;
1066 addr
->ea_addr
[2] = state
.hwaddr
[0] >> 24;
1067 addr
->ea_addr
[3] = (state
.hwaddr
[0] >> 16) & 0xff;
1068 addr
->ea_addr
[4] = (state
.hwaddr
[0] >> 8) & 0xff;
1069 addr
->ea_addr
[5] = state
.hwaddr
[0] & 0xff;
1074 m
->m_type
= DL_CONF_REPLY
;
1076 if ((r
= send(m
->m_source
, m
)) != OK
)
1077 printf("ATL2: unable to send reply (%d)\n", r
);
1080 /*===========================================================================*
1082 *===========================================================================*/
1083 PRIVATE
void atl2_getstat(message
*m
)
1085 /* Copy out statistics.
1089 if (m
->DL_PORT
!= 0) {
1093 r
= sys_safecopyto(m
->DL_PROC
, m
->DL_GRANT
, 0,
1094 (vir_bytes
) &state
.stat
, sizeof(state
.stat
), D
);
1097 m
->m_type
= DL_STAT_REPLY
;
1098 /* keep m->DL_PORT */
1101 if ((r
= send(m
->m_source
, m
)) != OK
)
1102 printf("ATL2: unable to send reply (%d)\n", r
);
1105 /*===========================================================================*
1107 *===========================================================================*/
1108 PRIVATE
void atl2_getname(message
*m
, int instance
)
1110 /* Tell Inet the name of this driver.
1114 /* Each instance must have a unique name. */
1115 m
->m_type
= DL_NAME_REPLY
;
1117 snprintf(m
->DL_NAME
, sizeof(m
->DL_NAME
), "atl2:%u",
1120 strcpy(m
->DL_NAME
, "atl2");
1122 if ((r
= send(m
->m_source
, m
)) != OK
)
1123 printf("ATL2: unable to send reply (%d)\n", r
);
1126 /*===========================================================================*
1128 *===========================================================================*/
1129 PRIVATE
void atl2_dump_link(void)
1131 /* Dump link status.
1136 /* The link status bit is latched. Read the status register twice. */
1137 atl2_read_mdio(ATL2_MII_BMSR
, &val
);
1138 if (!atl2_read_mdio(ATL2_MII_BMSR
, &val
)) return;
1140 link_up
= val
& ATL2_MII_BMSR_LSTATUS
;
1141 printf("link status: %4s\t", link_up
? "up" : "down");
1143 if (!link_up
) return;
1145 if (!atl2_read_mdio(ATL2_MII_PSSR
, &val
)) return;
1147 if (!(val
& ATL2_MII_PSSR_RESOLVED
)) {
1148 printf("(not resolved)\n");
1153 switch (val
& ATL2_MII_PSSR_SPEED
) {
1154 case ATL2_MII_PSSR_10
: printf("(10Mbps "); break;
1155 case ATL2_MII_PSSR_100
: printf("(100Mbps "); break;
1156 case ATL2_MII_PSSR_1000
: printf("(1000Mbps "); break;
1157 default: printf("(unknown, ");
1160 printf("%s duplex)", (val
& ATL2_MII_PSSR_DUPLEX
) ? "full" : "half");
1163 /*===========================================================================*
1165 *===========================================================================*/
1166 PRIVATE
void atl2_dump(void)
1172 printf("Attansic L2 statistics:\n");
1174 printf("recvErr: %8ld\t", state
.stat
.ets_recvErr
);
1175 printf("sendErr: %8ld\t", state
.stat
.ets_sendErr
);
1176 printf("OVW: %8ld\n", state
.stat
.ets_OVW
);
1178 printf("CRCerr: %8ld\t", state
.stat
.ets_CRCerr
);
1179 printf("frameAll: %8ld\t", state
.stat
.ets_frameAll
);
1180 printf("missedP: %8ld\n", state
.stat
.ets_missedP
);
1182 printf("packetR: %8ld\t", state
.stat
.ets_packetR
);
1183 printf("packetT: %8ld\t", state
.stat
.ets_packetT
);
1184 printf("transDef: %8ld\n", state
.stat
.ets_transDef
);
1186 printf("collision: %8ld\t", state
.stat
.ets_collision
);
1187 printf("transAb: %8ld\t", state
.stat
.ets_transAb
);
1188 printf("carrSense: %8ld\n", state
.stat
.ets_carrSense
);
1190 printf("fifoUnder: %8ld\t", state
.stat
.ets_fifoUnder
);
1191 printf("fifoOver: %8ld\t", state
.stat
.ets_fifoOver
);
1192 printf("CDheartbeat: %8ld\n", state
.stat
.ets_CDheartbeat
);
1194 printf("OWC: %8ld\t", state
.stat
.ets_OWC
);
1195 printf("TxD tail: %8d\t", state
.txd_tail
);
1196 printf("TxD count: %8d\n", state
.txd_num
);
1198 printf("RxD tail: %8d\t", state
.rxd_tail
);
1199 printf("TxS tail: %8d\t", state
.txs_tail
);
1200 printf("TxS count: %8d\n", state
.txs_num
);
1202 printf("flags: 0x%04x\t", state
.flags
);
1207 /*===========================================================================*
1208 * sef_cb_init_fresh *
1209 *===========================================================================*/
1210 PRIVATE
int sef_cb_init_fresh(int type
, sef_init_info_t
*UNUSED(info
))
1212 /* Initialize the atl2 driver.
1219 /* How many matching devices should we skip? */
1221 env_parse("atl2_instance", "d", 0, &instance
, 0, 32);
1223 /* Try to find a recognized device. */
1224 devind
= atl2_probe(instance
);
1227 panic("no matching device found");
1229 /* Initialize the device. */
1232 /* Announce we are up! */
1233 netdriver_announce();
1236 /* Register debug dump function key. */
1238 bit_set(sfkeys
, 11);
1239 if ((r
= fkey_map(&fkeys
, &sfkeys
)) != OK
)
1240 printf("ATL2: warning, could not map Shift+F11 key (%d)\n", r
);
1246 /*===========================================================================*
1247 * sef_cb_signal_handler *
1248 *===========================================================================*/
1249 PRIVATE
void sef_cb_signal_handler(int signo
)
1251 /* In case of a termination signal, shut down this driver.
1252 * Stop the device, and deallocate resources as proof of concept.
1256 /* Only check for termination signal, ignore anything else. */
1257 if (signo
!= SIGTERM
) return;
1261 if ((r
= sys_irqrmpolicy(&state
.hook_id
)) != OK
)
1262 panic("unable to deregister IRQ: %d", r
);
1264 free_contig(state
.txd_base
, ATL2_TXD_BUFSIZE
);
1265 free_contig(state
.txs_base
, ATL2_TXS_COUNT
* sizeof(u32_t
));
1266 free_contig(state
.rxd_base_u
,
1267 state
.rxd_align
+ ATL2_RXD_COUNT
* ATL2_RXD_SIZE
);
1269 vm_unmap_phys(SELF
, state
.base
, ATL2_MMAP_SIZE
);
1271 /* We cannot free the PCI device at this time. */
1276 /*===========================================================================*
1277 * sef_local_startup *
1278 *===========================================================================*/
1279 PRIVATE
void sef_local_startup(void)
1281 /* Register init callbacks. */
1282 sef_setcb_init_fresh(sef_cb_init_fresh
);
1283 sef_setcb_init_lu(sef_cb_init_fresh
);
1284 sef_setcb_init_restart(sef_cb_init_fresh
);
1286 /* Register live update callbacks. */
1287 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
1288 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree
);
1290 /* Register signal callbacks. */
1291 sef_setcb_signal_handler(sef_cb_signal_handler
);
1293 /* Let SEF perform startup. */
1297 /*===========================================================================*
1299 *===========================================================================*/
1300 int main(int argc
, char **argv
)
1308 /* Initialize SEF. */
1309 env_setargs(argc
, argv
);
1310 sef_local_startup();
1313 if ((r
= netdriver_receive(ANY
, &m
, &ipc_status
)) != OK
)
1314 panic("netdriver_receive failed: %d", r
);
1316 if (is_ipc_notify(ipc_status
)) {
1317 switch (m
.m_source
) {
1318 case HARDWARE
: /* interrupt */
1323 case TTY_PROC_NR
: /* function key */
1329 printf("ATL2: illegal notify from %d\n",
1336 /* Process requests from Inet. */
1338 case DL_GETNAME
: atl2_getname(&m
, instance
); break;
1339 case DL_CONF
: atl2_conf(&m
); break;
1340 case DL_GETSTAT_S
: atl2_getstat(&m
); break;
1341 case DL_WRITEV_S
: atl2_writev(&m
, FALSE
); break;
1342 case DL_READV_S
: atl2_readv(&m
, FALSE
); break;
1344 printf("ATL2: illegal message %d from %d\n",
1345 m
.m_type
, m
.m_source
);