Lines Matching +full:rx +full:- +full:tx +full:- +full:swap
3 Written 1995/96 by Roman Hodek (Roman.Hodek@informatik.uni-erlangen.de)
9 - The driver for the Riebl Lance card by the TU Vienna.
10 - The modified TUW driver for PAM's VME cards
11 - The PC-Linux driver for Lance cards (but this is for bus master
13 - The Amiga Ariadne driver
23 better probe procedure for 24-bit systems
24 non-VME-RieblCards need extra delays in memcpy
26 use 8/32 tx/rx buffers, which should give better NFS performance;
36 When the lance is stopped it jumps back into little-endian
39 This might be the reason why multicast-mode didn't work
46 "Roman.Hodek@informatik.uni-erlangen.de\n";
81 MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)");
99 /* These define the number of Rx and Tx buffers as log2. (Only powers
101 * Much more rx buffers (32) are reserved than tx buffers (8), since receiving
113 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
117 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
121 /* The LANCE Rx and Tx ring descriptors. */
146 unsigned short mode; /* Pre-set mode */
211 "Riebl-Card (without battery)",
212 "Riebl-Card (with battery)",
233 #define MEM lp->mem
234 #define DREG IO->data
235 #define AREG IO->addr
241 #define PKTBUF_ADDR(head) (((unsigned char *)(MEM)) + (head)->base)
325 #define CSR0_CERR 0x2000 /* carrier error (no heartbeat :-) (RC) */
326 #define CSR0_BABL 0x4000 /* babble: tx-ed too many bits (RC) */
332 #define CSR3_BSWP 0x0004 /* byte swap (1=big endian) */
362 while( len-- ) { in slow_memcpy()
375 int err = -ENODEV; in atarilance_probe()
380 return ERR_PTR(-ENODEV); in atarilance_probe()
384 return ERR_PTR(-ENOMEM); in atarilance_probe()
386 sprintf(dev->name, "eth%d", unit); in atarilance_probe()
396 free_irq(dev->irq, dev); in atarilance_probe()
470 (volatile unsigned short *)init_rec->memaddr; in lance_probe1()
472 (volatile unsigned short *)init_rec->ioaddr; in lance_probe1()
534 IO = lp->iobase = (struct lance_ioreg *)ioaddr; in lance_probe1()
535 dev->base_addr = (unsigned long)ioaddr; /* informational only */ in lance_probe1()
536 lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy; in lance_probe1()
542 if (addr_accessible( &(IO->eeprom), 0, 0 )) { in lance_probe1()
544 i = IO->mem; in lance_probe1()
545 lp->cardtype = PAM_CARD; in lance_probe1()
548 lp->cardtype = NEW_RIEBL; in lance_probe1()
551 lp->cardtype = OLD_RIEBL; in lance_probe1()
553 if (lp->cardtype == PAM_CARD || in lance_probe1()
557 "PAM,Riebl-ST Ethernet", dev)) { in lance_probe1()
561 dev->irq = IRQ_AUTO_5; in lance_probe1()
564 /* For VME-RieblCards, request a free VME int */ in lance_probe1()
570 if (request_irq(irq, lance_interrupt, 0, "Riebl-VME Ethernet", in lance_probe1()
575 dev->irq = irq; in lance_probe1()
579 dev->name, lance_names[lp->cardtype], in lance_probe1()
582 dev->irq, in lance_probe1()
583 init_rec->slow_flag ? " (slow memcpy)" : "" ); in lance_probe1()
586 switch( lp->cardtype ) { in lance_probe1()
589 memcpy(dev->dev_addr, OldRieblDefHwaddr, ETH_ALEN); in lance_probe1()
592 lp->memcpy_f(dev->dev_addr, RIEBL_HWADDR_ADDR, ETH_ALEN); in lance_probe1()
595 i = IO->eeprom; in lance_probe1()
597 dev->dev_addr[i] = in lance_probe1()
600 i = IO->mem; in lance_probe1()
603 printk("%pM\n", dev->dev_addr); in lance_probe1()
604 if (lp->cardtype == OLD_RIEBL) { in lance_probe1()
606 dev->name ); in lance_probe1()
610 spin_lock_init(&lp->devlock); in lance_probe1()
612 MEM->init.mode = 0x0000; /* Disable Rx and Tx. */ in lance_probe1()
614 MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */ in lance_probe1()
615 MEM->init.filter[0] = 0x00000000; in lance_probe1()
616 MEM->init.filter[1] = 0x00000000; in lance_probe1()
617 MEM->init.rx_ring.adr_lo = offsetof( struct lance_memory, rx_head ); in lance_probe1()
618 MEM->init.rx_ring.adr_hi = 0; in lance_probe1()
619 MEM->init.rx_ring.len = RX_RING_LEN_BITS; in lance_probe1()
620 MEM->init.tx_ring.adr_lo = offsetof( struct lance_memory, tx_head ); in lance_probe1()
621 MEM->init.tx_ring.adr_hi = 0; in lance_probe1()
622 MEM->init.tx_ring.len = TX_RING_LEN_BITS; in lance_probe1()
624 if (lp->cardtype == PAM_CARD) in lance_probe1()
625 IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq); in lance_probe1()
627 *RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq); in lance_probe1()
632 dev->netdev_ops = &lance_netdev_ops; in lance_probe1()
635 dev->watchdog_timeo = TX_TIMEOUT; in lance_probe1()
644 struct lance_ioreg *IO = lp->iobase; in lance_open()
647 DPRINTK( 2, ( "%s: lance_open()\n", dev->name )); in lance_open()
650 /* Re-initialize the LANCE, and start it when done. */ in lance_open()
652 REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); in lance_open()
659 while (--i > 0) in lance_open()
664 dev->name, i, DREG )); in lance_open()
666 return -EIO; in lance_open()
674 DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); in lance_open()
680 /* Initialize the LANCE Rx and Tx rings. */
688 lp->tx_full = 0; in lance_init_ring()
689 lp->cur_rx = lp->cur_tx = 0; in lance_init_ring()
690 lp->dirty_tx = 0; in lance_init_ring()
698 if (lp->cardtype == OLD_RIEBL || lp->cardtype == NEW_RIEBL) { \ in lance_init_ring()
707 MEM->tx_head[i].base = offset; in lance_init_ring()
708 MEM->tx_head[i].flag = TMD1_OWN_HOST; in lance_init_ring()
709 MEM->tx_head[i].base_hi = 0; in lance_init_ring()
710 MEM->tx_head[i].length = 0; in lance_init_ring()
711 MEM->tx_head[i].misc = 0; in lance_init_ring()
717 MEM->rx_head[i].base = offset; in lance_init_ring()
718 MEM->rx_head[i].flag = TMD1_OWN_CHIP; in lance_init_ring()
719 MEM->rx_head[i].base_hi = 0; in lance_init_ring()
720 MEM->rx_head[i].buf_length = -PKT_BUF_SZ; in lance_init_ring()
721 MEM->rx_head[i].msg_length = 0; in lance_init_ring()
733 struct lance_ioreg *IO = lp->iobase; in lance_tx_timeout()
737 dev->name, DREG )); in lance_tx_timeout()
743 REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); in lance_tx_timeout()
744 dev->stats.tx_errors++; in lance_tx_timeout()
748 lp->dirty_tx, lp->cur_tx, in lance_tx_timeout()
749 lp->tx_full ? " (full)" : "", in lance_tx_timeout()
750 lp->cur_rx )); in lance_tx_timeout()
752 DPRINTK( 2, ( "rx #%d: base=%04x blen=%04x mlen=%04x\n", in lance_tx_timeout()
753 i, MEM->rx_head[i].base, in lance_tx_timeout()
754 -MEM->rx_head[i].buf_length, in lance_tx_timeout()
755 MEM->rx_head[i].msg_length )); in lance_tx_timeout()
757 DPRINTK( 2, ( "tx #%d: base=%04x len=%04x misc=%04x\n", in lance_tx_timeout()
758 i, MEM->tx_head[i].base, in lance_tx_timeout()
759 -MEM->tx_head[i].length, in lance_tx_timeout()
760 MEM->tx_head[i].misc )); in lance_tx_timeout()
767 netif_trans_update(dev); /* prevent tx timeout */ in lance_tx_timeout()
777 struct lance_ioreg *IO = lp->iobase; in lance_start_xmit()
783 dev->name, DREG )); in lance_start_xmit()
787 len = skb->len; in lance_start_xmit()
790 /* PAM-Card has a bug: Can only send packets with even number of bytes! */ in lance_start_xmit()
791 else if (lp->cardtype == PAM_CARD && (len & 1)) in lance_start_xmit()
794 if (len > skb->len) { in lance_start_xmit()
801 /* Fill in a Tx ring entry */ in lance_start_xmit()
803 printk( "%s: TX pkt type 0x%04x from %pM to %pM" in lance_start_xmit()
805 dev->name, ((u_short *)skb->data)[6], in lance_start_xmit()
806 &skb->data[6], skb->data, in lance_start_xmit()
807 (int)skb->data, (int)skb->len ); in lance_start_xmit()
812 spin_lock_irqsave (&lp->devlock, flags); in lance_start_xmit()
815 entry = lp->cur_tx & TX_RING_MOD_MASK; in lance_start_xmit()
816 head = &(MEM->tx_head[entry]); in lance_start_xmit()
823 head->length = -len; in lance_start_xmit()
824 head->misc = 0; in lance_start_xmit()
825 lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); in lance_start_xmit()
826 head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP; in lance_start_xmit()
827 dev->stats.tx_bytes += skb->len; in lance_start_xmit()
829 lp->cur_tx++; in lance_start_xmit()
830 while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) { in lance_start_xmit()
831 lp->cur_tx -= TX_RING_SIZE; in lance_start_xmit()
832 lp->dirty_tx -= TX_RING_SIZE; in lance_start_xmit()
838 if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) == in lance_start_xmit()
842 lp->tx_full = 1; in lance_start_xmit()
843 spin_unlock_irqrestore (&lp->devlock, flags); in lance_start_xmit()
864 IO = lp->iobase; in lance_interrupt()
865 spin_lock (&lp->devlock); in lance_interrupt()
870 --boguscnt >= 0) { in lance_interrupt()
877 dev->name, csr0, DREG )); in lance_interrupt()
879 if (csr0 & CSR0_RINT) /* Rx interrupt */ in lance_interrupt()
882 if (csr0 & CSR0_TINT) { /* Tx-done interrupt */ in lance_interrupt()
883 int dirty_tx = lp->dirty_tx; in lance_interrupt()
885 while( dirty_tx < lp->cur_tx) { in lance_interrupt()
887 int status = MEM->tx_head[entry].flag; in lance_interrupt()
892 MEM->tx_head[entry].flag = 0; in lance_interrupt()
896 int err_status = MEM->tx_head[entry].misc; in lance_interrupt()
897 dev->stats.tx_errors++; in lance_interrupt()
898 if (err_status & TMD3_RTRY) dev->stats.tx_aborted_errors++; in lance_interrupt()
899 if (err_status & TMD3_LCAR) dev->stats.tx_carrier_errors++; in lance_interrupt()
900 if (err_status & TMD3_LCOL) dev->stats.tx_window_errors++; in lance_interrupt()
902 /* Ackk! On FIFO errors the Tx unit is turned off! */ in lance_interrupt()
903 dev->stats.tx_fifo_errors++; in lance_interrupt()
905 DPRINTK( 1, ( "%s: Tx FIFO error! Status %04x\n", in lance_interrupt()
906 dev->name, csr0 )); in lance_interrupt()
912 dev->stats.collisions++; in lance_interrupt()
913 dev->stats.tx_packets++; in lance_interrupt()
921 if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) { in lance_interrupt()
922 DPRINTK( 0, ( "out-of-sync dirty pointer," in lance_interrupt()
924 dirty_tx, lp->cur_tx, lp->tx_full )); in lance_interrupt()
929 if (lp->tx_full && (netif_queue_stopped(dev)) && in lance_interrupt()
930 dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) { in lance_interrupt()
932 lp->tx_full = 0; in lance_interrupt()
936 lp->dirty_tx = dirty_tx; in lance_interrupt()
940 if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */ in lance_interrupt()
941 if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */ in lance_interrupt()
944 "status %04x.\n", dev->name, csr0 )); in lance_interrupt()
955 dev->name, DREG )); in lance_interrupt()
957 spin_unlock (&lp->devlock); in lance_interrupt()
965 int entry = lp->cur_rx & RX_RING_MOD_MASK; in lance_rx()
968 DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name, in lance_rx()
969 MEM->rx_head[entry].flag )); in lance_rx()
972 while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) { in lance_rx()
973 struct lance_rx_head *head = &(MEM->rx_head[entry]); in lance_rx()
974 int status = head->flag; in lance_rx()
978 <murf@perftech.com> to Russ Nelson: Even with full-sized in lance_rx()
982 dev->stats.rx_errors++; /* end of a packet.*/ in lance_rx()
983 if (status & RMD1_FRAM) dev->stats.rx_frame_errors++; in lance_rx()
984 if (status & RMD1_OFLO) dev->stats.rx_over_errors++; in lance_rx()
985 if (status & RMD1_CRC) dev->stats.rx_crc_errors++; in lance_rx()
986 if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++; in lance_rx()
987 head->flag &= (RMD1_ENP|RMD1_STP); in lance_rx()
989 /* Malloc up new buffer, compatible with net-3. */ in lance_rx()
990 short pkt_len = head->msg_length & 0xfff; in lance_rx()
994 printk( "%s: Runt packet!\n", dev->name ); in lance_rx()
995 dev->stats.rx_errors++; in lance_rx()
1001 if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag & in lance_rx()
1005 if (i > RX_RING_SIZE - 2) { in lance_rx()
1006 dev->stats.rx_dropped++; in lance_rx()
1007 head->flag |= RMD1_OWN_CHIP; in lance_rx()
1008 lp->cur_rx++; in lance_rx()
1016 printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %pM to %pM " in lance_rx()
1018 dev->name, ((u_short *)data)[6], in lance_rx()
1024 lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len ); in lance_rx()
1025 skb->protocol = eth_type_trans( skb, dev ); in lance_rx()
1027 dev->stats.rx_packets++; in lance_rx()
1028 dev->stats.rx_bytes += pkt_len; in lance_rx()
1032 head->flag |= RMD1_OWN_CHIP; in lance_rx()
1033 entry = (++lp->cur_rx) & RX_RING_MOD_MASK; in lance_rx()
1035 lp->cur_rx &= RX_RING_MOD_MASK; in lance_rx()
1039 we should free one and mark stats->rx_dropped++. */ in lance_rx()
1048 struct lance_ioreg *IO = lp->iobase; in lance_close()
1055 dev->name, DREG )); in lance_close()
1057 /* We stop the LANCE here -- it occasionally polls in lance_close()
1066 num_addrs == -1 Promiscuous mode, receive all packets
1069 best-effort filtering.
1075 struct lance_ioreg *IO = lp->iobase; in set_multicast_list()
1084 if (dev->flags & IFF_PROMISC) { in set_multicast_list()
1086 DPRINTK( 2, ( "%s: Promiscuous mode enabled.\n", dev->name )); in set_multicast_list()
1092 /* We don't use the multicast table, but rely on upper-layer in set_multicast_list()
1094 memset( multicast_table, (num_addrs == 0) ? 0 : -1, in set_multicast_list()
1105 REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); in set_multicast_list()
1120 if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL) in lance_set_mac_address()
1121 return -EOPNOTSUPP; in lance_set_mac_address()
1126 dev->name )); in lance_set_mac_address()
1127 return -EIO; in lance_set_mac_address()
1130 memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len ); in lance_set_mac_address()
1132 MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */ in lance_set_mac_address()
1133 lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 ); in lance_set_mac_address()
1146 atarilance_dev = atarilance_probe(-1); in atarilance_module_init()
1153 free_irq(atarilance_dev->irq, atarilance_dev); in atarilance_module_exit()
1163 * c-indent-level: 4
1164 * tab-width: 4