xref: /minix3/minix/drivers/net/atl2/atl2.c (revision f7df02e7476731c31f12548e38bcadbaf0233f6a)
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