Lines Matching +full:ethernet +full:- +full:pse

2  *  Amiga Linux/m68k Ariadne Ethernet Driver
4 * © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
7 * ---------------------------------------------------------------------------
11 * lance.c: An AMD LANCE ethernet driver for linux.
12 * Written 1993-94 by Donald Becker.
14 * Am79C960: PCnet(tm)-ISA Single-Chip Ethernet Controller
21 * ---------------------------------------------------------------------------
27 * ---------------------------------------------------------------------------
29 * The Ariadne is a Zorro-II board made by Village Tronic. It contains:
31 * - an Am79C960 PCnet-ISA Single-Chip Ethernet Controller with both
32 * 10BASE-2 (thin coax) and 10BASE-T (UTP) connectors
34 * - an MC68230 Parallel Interface/Timer configured as 2 parallel ports
110 len -= 2; in memcpyw()
119 volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start; in ariadne_init_ring()
124 priv->tx_full = 0; in ariadne_init_ring()
125 priv->cur_rx = priv->cur_tx = 0; in ariadne_init_ring()
126 priv->dirty_tx = 0; in ariadne_init_ring()
130 volatile struct TDRE *t = &lancedata->tx_ring[i]; in ariadne_init_ring()
131 t->TMD0 = swloww(ARIADNE_RAM + in ariadne_init_ring()
133 t->TMD1 = swhighw(ARIADNE_RAM + in ariadne_init_ring()
136 t->TMD2 = swapw((u_short)-PKT_BUF_SIZE); in ariadne_init_ring()
137 t->TMD3 = 0; in ariadne_init_ring()
138 priv->tx_ring[i] = &lancedata->tx_ring[i]; in ariadne_init_ring()
139 priv->tx_buff[i] = lancedata->tx_buff[i]; in ariadne_init_ring()
141 i, &lancedata->tx_ring[i], lancedata->tx_buff[i]); in ariadne_init_ring()
146 volatile struct RDRE *r = &lancedata->rx_ring[i]; in ariadne_init_ring()
147 r->RMD0 = swloww(ARIADNE_RAM + in ariadne_init_ring()
149 r->RMD1 = swhighw(ARIADNE_RAM + in ariadne_init_ring()
152 r->RMD2 = swapw((u_short)-PKT_BUF_SIZE); in ariadne_init_ring()
153 r->RMD3 = 0x0000; in ariadne_init_ring()
154 priv->rx_ring[i] = &lancedata->rx_ring[i]; in ariadne_init_ring()
155 priv->rx_buff[i] = lancedata->rx_buff[i]; in ariadne_init_ring()
157 i, &lancedata->rx_ring[i], lancedata->rx_buff[i]); in ariadne_init_ring()
164 int entry = priv->cur_rx % RX_RING_SIZE; in ariadne_rx()
168 while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) { in ariadne_rx()
169 int status = lowb(priv->rx_ring[entry]->RMD1); in ariadne_rx()
174 * Even with full-sized buffers it's possible for a in ariadne_rx()
180 dev->stats.rx_errors++; in ariadne_rx()
182 dev->stats.rx_frame_errors++; in ariadne_rx()
184 dev->stats.rx_over_errors++; in ariadne_rx()
186 dev->stats.rx_crc_errors++; in ariadne_rx()
188 dev->stats.rx_fifo_errors++; in ariadne_rx()
189 priv->rx_ring[entry]->RMD1 &= 0xff00 | RF_STP | RF_ENP; in ariadne_rx()
191 /* Malloc up new buffer, compatible with net-3 */ in ariadne_rx()
192 short pkt_len = swapw(priv->rx_ring[entry]->RMD3); in ariadne_rx()
198 if (lowb(priv->rx_ring[(entry + i) % RX_RING_SIZE]->RMD1) & RF_OWN) in ariadne_rx()
201 if (i > RX_RING_SIZE - 2) { in ariadne_rx()
202 dev->stats.rx_dropped++; in ariadne_rx()
203 priv->rx_ring[entry]->RMD1 |= RF_OWN; in ariadne_rx()
204 priv->cur_rx++; in ariadne_rx()
213 (const void *)priv->rx_buff[entry], in ariadne_rx()
215 skb->protocol = eth_type_trans(skb, dev); in ariadne_rx()
217 ((u_short *)skb->data)[6], in ariadne_rx()
218 skb->data + 6, skb->data, in ariadne_rx()
219 skb->data, skb->len); in ariadne_rx()
222 dev->stats.rx_packets++; in ariadne_rx()
223 dev->stats.rx_bytes += pkt_len; in ariadne_rx()
226 priv->rx_ring[entry]->RMD1 |= RF_OWN; in ariadne_rx()
227 entry = (++priv->cur_rx) % RX_RING_SIZE; in ariadne_rx()
230 priv->cur_rx = priv->cur_rx % RX_RING_SIZE; in ariadne_rx()
233 * If not, we should free one and mark stats->rx_dropped++ in ariadne_rx()
242 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in ariadne_interrupt()
247 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_interrupt()
249 if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ in ariadne_interrupt()
255 while ((csr0 = lance->RDP) & (ERR | RINT | TINT) && --boguscnt >= 0) { in ariadne_interrupt()
257 lance->RDP = csr0 & ~(INEA | TDMD | STOP | STRT | INIT); in ariadne_interrupt()
262 csr0, lance->RDP); in ariadne_interrupt()
304 if (csr0 & TINT) { /* Tx-done interrupt */ in ariadne_interrupt()
305 int dirty_tx = priv->dirty_tx; in ariadne_interrupt()
308 while (dirty_tx < priv->cur_tx) { in ariadne_interrupt()
310 int status = lowb(priv->tx_ring[entry]->TMD1); in ariadne_interrupt()
315 priv->tx_ring[entry]->TMD1 &= 0xff00; in ariadne_interrupt()
319 int err_status = priv->tx_ring[entry]->TMD3; in ariadne_interrupt()
320 dev->stats.tx_errors++; in ariadne_interrupt()
322 dev->stats.tx_aborted_errors++; in ariadne_interrupt()
324 dev->stats.tx_carrier_errors++; in ariadne_interrupt()
326 dev->stats.tx_window_errors++; in ariadne_interrupt()
329 dev->stats.tx_fifo_errors++; in ariadne_interrupt()
334 lance->RDP = STRT; in ariadne_interrupt()
338 dev->stats.collisions++; in ariadne_interrupt()
339 dev->stats.tx_packets++; in ariadne_interrupt()
345 if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) { in ariadne_interrupt()
346 netdev_err(dev, "out-of-sync dirty pointer, %d vs. %d, full=%d\n", in ariadne_interrupt()
347 dirty_tx, priv->cur_tx, in ariadne_interrupt()
348 priv->tx_full); in ariadne_interrupt()
353 if (priv->tx_full && netif_queue_stopped(dev) && in ariadne_interrupt()
354 dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) { in ariadne_interrupt()
356 priv->tx_full = 0; in ariadne_interrupt()
360 priv->dirty_tx = dirty_tx; in ariadne_interrupt()
366 dev->stats.tx_errors++; /* Tx babble */ in ariadne_interrupt()
370 dev->stats.rx_errors++; /* Missed a Rx frame */ in ariadne_interrupt()
377 lance->RDP = STRT; in ariadne_interrupt()
382 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_interrupt()
383 lance->RDP = INEA | BABL | CERR | MISS | MERR | IDON; in ariadne_interrupt()
387 lance->RAP, lance->RDP); in ariadne_interrupt()
394 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in ariadne_open()
400 in = lance->Reset; in ariadne_open()
403 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_open()
404 lance->RDP = STOP; in ariadne_open()
407 lance->RAP = CSR88; /* Chip ID */ in ariadne_open()
408 version = swapw(lance->RDP); in ariadne_open()
409 lance->RAP = CSR89; /* Chip ID */ in ariadne_open()
410 version |= swapw(lance->RDP) << 16; in ariadne_open()
412 pr_warn("Couldn't find AMD Ethernet Chip\n"); in ariadne_open()
413 return -EAGAIN; in ariadne_open()
418 return -EAGAIN; in ariadne_open()
421 netdev_dbg(dev, "Am79C960 (PCnet-ISA) Revision %ld\n", in ariadne_open()
427 lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */ in ariadne_open()
428 lance->RDP = 0x0000; in ariadne_open()
429 lance->RAP = CSR4; /* Test and Features Control */ in ariadne_open()
430 lance->RDP = DPOLL | APAD_XMT | MFCOM | RCVCCOM | TXSTRTM | JABM; in ariadne_open()
433 lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */ in ariadne_open()
434 lance->RDP = 0x0000; in ariadne_open()
435 lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */ in ariadne_open()
436 lance->RDP = 0x0000; in ariadne_open()
437 lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */ in ariadne_open()
438 lance->RDP = 0x0000; in ariadne_open()
439 lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */ in ariadne_open()
440 lance->RDP = 0x0000; in ariadne_open()
442 /* Set the Ethernet Hardware Address */ in ariadne_open()
443 lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */ in ariadne_open()
444 lance->RDP = ((const u_short *)&dev->dev_addr[0])[0]; in ariadne_open()
445 lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */ in ariadne_open()
446 lance->RDP = ((const u_short *)&dev->dev_addr[0])[1]; in ariadne_open()
447 lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */ in ariadne_open()
448 lance->RDP = ((const u_short *)&dev->dev_addr[0])[2]; in ariadne_open()
451 lance->RAP = CSR15; /* Mode Register */ in ariadne_open()
452 lance->RDP = 0x0000; in ariadne_open()
455 lance->RAP = CSR30; /* Base Address of Transmit Ring */ in ariadne_open()
456 lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, tx_ring)); in ariadne_open()
457 lance->RAP = CSR31; /* Base Address of transmit Ring */ in ariadne_open()
458 lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, tx_ring)); in ariadne_open()
461 lance->RAP = CSR24; /* Base Address of Receive Ring */ in ariadne_open()
462 lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, rx_ring)); in ariadne_open()
463 lance->RAP = CSR25; /* Base Address of Receive Ring */ in ariadne_open()
464 lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, rx_ring)); in ariadne_open()
467 lance->RAP = CSR76; /* Receive Ring Length */ in ariadne_open()
468 lance->RDP = swapw(((u_short)-RX_RING_SIZE)); in ariadne_open()
469 lance->RAP = CSR78; /* Transmit Ring Length */ in ariadne_open()
470 lance->RDP = swapw(((u_short)-TX_RING_SIZE)); in ariadne_open()
472 /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */ in ariadne_open()
473 lance->RAP = ISACSR2; /* Miscellaneous Configuration */ in ariadne_open()
474 lance->IDP = ASEL; in ariadne_open()
477 lance->RAP = ISACSR5; /* LED1 Status */ in ariadne_open()
478 lance->IDP = PSE|XMTE; in ariadne_open()
479 lance->RAP = ISACSR6; /* LED2 Status */ in ariadne_open()
480 lance->IDP = PSE|COLE; in ariadne_open()
481 lance->RAP = ISACSR7; /* LED3 Status */ in ariadne_open()
482 lance->IDP = PSE|RCVE; in ariadne_open()
487 dev->name, dev); in ariadne_open()
491 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_open()
492 lance->RDP = INEA | STRT; in ariadne_open()
499 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in ariadne_close()
503 lance->RAP = CSR112; /* Missed Frame Count */ in ariadne_close()
504 dev->stats.rx_missed_errors = swapw(lance->RDP); in ariadne_close()
505 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_close()
509 lance->RDP); in ariadne_close()
511 dev->stats.rx_missed_errors); in ariadne_close()
514 /* We stop the LANCE here -- it occasionally polls memory if we don't */ in ariadne_close()
515 lance->RDP = STOP; in ariadne_close()
524 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in ariadne_reset()
526 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_reset()
527 lance->RDP = STOP; in ariadne_reset()
529 lance->RDP = INEA | STRT; in ariadne_reset()
535 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in ariadne_tx_timeout()
538 lance->RDP); in ariadne_tx_timeout()
547 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in ariadne_start_xmit()
550 int len = skb->len; in ariadne_start_xmit()
554 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_start_xmit()
555 netdev_dbg(dev, "%s: csr0 %04x\n", __func__, lance->RDP); in ariadne_start_xmit()
556 lance->RDP = 0x0000; in ariadne_start_xmit()
561 if (skb->len < ETH_ZLEN) { in ariadne_start_xmit()
570 ((u_short *)skb->data)[6], in ariadne_start_xmit()
571 skb->data + 6, skb->data, in ariadne_start_xmit()
572 skb->data, skb->len); in ariadne_start_xmit()
576 entry = priv->cur_tx % TX_RING_SIZE; in ariadne_start_xmit()
581 priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len); in ariadne_start_xmit()
582 priv->tx_ring[entry]->TMD3 = 0x0000; in ariadne_start_xmit()
583 memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len); in ariadne_start_xmit()
587 (void *)priv->tx_buff[entry], in ariadne_start_xmit()
588 skb->len > 64 ? 64 : skb->len, true); in ariadne_start_xmit()
591 priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1 & 0xff00) in ariadne_start_xmit()
596 priv->cur_tx++; in ariadne_start_xmit()
597 if ((priv->cur_tx >= TX_RING_SIZE) && in ariadne_start_xmit()
598 (priv->dirty_tx >= TX_RING_SIZE)) { in ariadne_start_xmit()
601 priv->cur_tx, priv->dirty_tx); in ariadne_start_xmit()
603 priv->cur_tx -= TX_RING_SIZE; in ariadne_start_xmit()
604 priv->dirty_tx -= TX_RING_SIZE; in ariadne_start_xmit()
606 dev->stats.tx_bytes += len; in ariadne_start_xmit()
609 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in ariadne_start_xmit()
610 lance->RDP = INEA | TDMD; in ariadne_start_xmit()
612 if (lowb(priv->tx_ring[(entry + 1) % TX_RING_SIZE]->TMD1) != 0) { in ariadne_start_xmit()
614 priv->tx_full = 1; in ariadne_start_xmit()
623 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in ariadne_get_stats()
628 saved_addr = lance->RAP; in ariadne_get_stats()
629 lance->RAP = CSR112; /* Missed Frame Count */ in ariadne_get_stats()
630 dev->stats.rx_missed_errors = swapw(lance->RDP); in ariadne_get_stats()
631 lance->RAP = saved_addr; in ariadne_get_stats()
634 return &dev->stats; in ariadne_get_stats()
638 * num_addrs == -1 Promiscuous mode, receive all packets
641 * and do best-effort filtering.
645 volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; in set_multicast_list()
653 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in set_multicast_list()
654 lance->RDP = STOP; /* Temporarily stop the lance */ in set_multicast_list()
657 if (dev->flags & IFF_PROMISC) { in set_multicast_list()
658 lance->RAP = CSR15; /* Mode Register */ in set_multicast_list()
659 lance->RDP = PROM; /* Set promiscuous mode */ in set_multicast_list()
665 * but rely on upper-layer filtering in set_multicast_list()
667 memset(multicast_table, (num_addrs == 0) ? 0 : -1, in set_multicast_list()
670 lance->RAP = CSR8 + (i << 8); in set_multicast_list()
672 lance->RDP = swapw(multicast_table[i]); in set_multicast_list()
674 lance->RAP = CSR15; /* Mode Register */ in set_multicast_list()
675 lance->RDP = 0x0000; /* Unset promiscuous mode */ in set_multicast_list()
678 lance->RAP = CSR0; /* PCnet-ISA Controller Status */ in set_multicast_list()
679 lance->RDP = INEA | STRT | IDON;/* Resume normal operation */ in set_multicast_list()
690 release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960)); in ariadne_remove_one()
691 release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE); in ariadne_remove_one()
715 unsigned long board = z->resource.start; in ariadne_init_one()
726 return -EBUSY; in ariadne_init_one()
730 return -EBUSY; in ariadne_init_one()
737 return -ENOMEM; in ariadne_init_one()
740 r1->name = dev->name; in ariadne_init_one()
741 r2->name = dev->name; in ariadne_init_one()
743 serial = be32_to_cpu(z->rom.er_SerialNumber); in ariadne_init_one()
751 dev->base_addr = (unsigned long)ZTWO_VADDR(base_addr); in ariadne_init_one()
752 dev->mem_start = (unsigned long)ZTWO_VADDR(mem_start); in ariadne_init_one()
753 dev->mem_end = dev->mem_start + ARIADNE_RAM_SIZE; in ariadne_init_one()
755 dev->netdev_ops = &ariadne_netdev_ops; in ariadne_init_one()
756 dev->watchdog_timeo = 5 * HZ; in ariadne_init_one()
767 netdev_info(dev, "Ariadne at 0x%08lx, Ethernet Address %pM\n", in ariadne_init_one()
768 board, dev->dev_addr); in ariadne_init_one()
793 MODULE_DESCRIPTION("Ariadne Ethernet Driver");