Lines Matching +full:mem +full:- +full:io
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
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";
64 #include <asm/io.h>
81 MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)");
113 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
117 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
146 unsigned short mode; /* Pre-set mode */
175 #define RIEBL_MAGIC_ADDR ((unsigned long *)(((char *)MEM) + 0xee8a))
176 #define RIEBL_HWADDR_ADDR ((unsigned char *)(((char *)MEM) + 0xee8e))
177 #define RIEBL_IVEC_ADDR ((unsigned short *)(((char *)MEM) + 0xfffe))
199 /* base+0xf */ volatile unsigned char mem; member
211 "Riebl-Card (without battery)",
212 "Riebl-Card (with battery)",
221 struct lance_memory *mem; member
233 #define MEM lp->mem macro
234 #define DREG IO->data
235 #define AREG IO->addr
241 #define PKTBUF_ADDR(head) (((unsigned char *)(MEM)) + (head)->base)
243 /* Possible memory/IO addresses for probing */
325 #define CSR0_CERR 0x2000 /* carrier error (no heartbeat :-) (RC) */
326 #define CSR0_BABL 0x4000 /* babble: tx-ed too many bits (RC) */
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()
392 free_irq(dev->irq, dev); in atarilance_probe()
466 (volatile unsigned short *)init_rec->memaddr; in lance_probe1()
468 (volatile unsigned short *)init_rec->ioaddr; in lance_probe1()
470 struct lance_ioreg *IO; in lance_probe1() local
476 PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n", in lance_probe1()
530 MEM = (struct lance_memory *)memaddr; in lance_probe1()
531 IO = lp->iobase = (struct lance_ioreg *)ioaddr; in lance_probe1()
532 dev->base_addr = (unsigned long)ioaddr; /* informational only */ in lance_probe1()
533 lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy; in lance_probe1()
539 if (addr_accessible( &(IO->eeprom), 0, 0 )) { in lance_probe1()
541 i = IO->mem; in lance_probe1()
542 lp->cardtype = PAM_CARD; in lance_probe1()
545 lp->cardtype = NEW_RIEBL; in lance_probe1()
548 lp->cardtype = OLD_RIEBL; in lance_probe1()
550 if (lp->cardtype == PAM_CARD || in lance_probe1()
554 "PAM,Riebl-ST Ethernet", dev)) { in lance_probe1()
558 dev->irq = IRQ_AUTO_5; in lance_probe1()
561 /* For VME-RieblCards, request a free VME int */ in lance_probe1()
567 if (request_irq(irq, lance_interrupt, 0, "Riebl-VME Ethernet", in lance_probe1()
572 dev->irq = irq; in lance_probe1()
575 printk("%s: %s at io %#lx, mem %#lx, irq %d%s, hwaddr ", in lance_probe1()
576 dev->name, lance_names[lp->cardtype], in lance_probe1()
579 dev->irq, in lance_probe1()
580 init_rec->slow_flag ? " (slow memcpy)" : "" ); in lance_probe1()
583 switch( lp->cardtype ) { in lance_probe1()
589 lp->memcpy_f(addr, RIEBL_HWADDR_ADDR, ETH_ALEN); in lance_probe1()
593 i = IO->eeprom; in lance_probe1()
596 ((((unsigned short *)MEM)[i*2] & 0x0f) << 4) | in lance_probe1()
597 ((((unsigned short *)MEM)[i*2+1] & 0x0f)); in lance_probe1()
599 i = IO->mem; in lance_probe1()
602 printk("%pM\n", dev->dev_addr); in lance_probe1()
603 if (lp->cardtype == OLD_RIEBL) { in lance_probe1()
605 dev->name ); in lance_probe1()
609 spin_lock_init(&lp->devlock); in lance_probe1()
611 MEM->init.mode = 0x0000; /* Disable Rx and Tx. */ in lance_probe1()
613 MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */ in lance_probe1()
614 MEM->init.filter[0] = 0x00000000; in lance_probe1()
615 MEM->init.filter[1] = 0x00000000; in lance_probe1()
616 MEM->init.rx_ring.adr_lo = offsetof( struct lance_memory, rx_head ); in lance_probe1()
617 MEM->init.rx_ring.adr_hi = 0; in lance_probe1()
618 MEM->init.rx_ring.len = RX_RING_LEN_BITS; in lance_probe1()
619 MEM->init.tx_ring.adr_lo = offsetof( struct lance_memory, tx_head ); in lance_probe1()
620 MEM->init.tx_ring.adr_hi = 0; in lance_probe1()
621 MEM->init.tx_ring.len = TX_RING_LEN_BITS; in lance_probe1()
623 if (lp->cardtype == PAM_CARD) in lance_probe1()
624 IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq); in lance_probe1()
626 *RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq); in lance_probe1()
631 dev->netdev_ops = &lance_netdev_ops; in lance_probe1()
634 dev->watchdog_timeo = TX_TIMEOUT; in lance_probe1()
643 struct lance_ioreg *IO = lp->iobase; in lance_open() local
646 DPRINTK( 2, ( "%s: lance_open()\n", dev->name )); in lance_open()
649 /* Re-initialize the LANCE, and start it when done. */ in lance_open()
651 REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); in lance_open()
658 while (--i > 0) in lance_open()
663 dev->name, i, DREG )); in lance_open()
665 return -EIO; in lance_open()
673 DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); in lance_open()
687 lp->tx_full = 0; in lance_init_ring()
688 lp->cur_rx = lp->cur_tx = 0; in lance_init_ring()
689 lp->dirty_tx = 0; in lance_init_ring()
697 if (lp->cardtype == OLD_RIEBL || lp->cardtype == NEW_RIEBL) { \ in lance_init_ring()
706 MEM->tx_head[i].base = offset; in lance_init_ring()
707 MEM->tx_head[i].flag = TMD1_OWN_HOST; in lance_init_ring()
708 MEM->tx_head[i].base_hi = 0; in lance_init_ring()
709 MEM->tx_head[i].length = 0; in lance_init_ring()
710 MEM->tx_head[i].misc = 0; in lance_init_ring()
716 MEM->rx_head[i].base = offset; in lance_init_ring()
717 MEM->rx_head[i].flag = TMD1_OWN_CHIP; in lance_init_ring()
718 MEM->rx_head[i].base_hi = 0; in lance_init_ring()
719 MEM->rx_head[i].buf_length = -PKT_BUF_SZ; in lance_init_ring()
720 MEM->rx_head[i].msg_length = 0; in lance_init_ring()
732 struct lance_ioreg *IO = lp->iobase; in lance_tx_timeout() local
736 dev->name, DREG )); in lance_tx_timeout()
742 REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); in lance_tx_timeout()
743 dev->stats.tx_errors++; in lance_tx_timeout()
747 lp->dirty_tx, lp->cur_tx, in lance_tx_timeout()
748 lp->tx_full ? " (full)" : "", in lance_tx_timeout()
749 lp->cur_rx )); in lance_tx_timeout()
752 i, MEM->rx_head[i].base, in lance_tx_timeout()
753 -MEM->rx_head[i].buf_length, in lance_tx_timeout()
754 MEM->rx_head[i].msg_length )); in lance_tx_timeout()
757 i, MEM->tx_head[i].base, in lance_tx_timeout()
758 -MEM->tx_head[i].length, in lance_tx_timeout()
759 MEM->tx_head[i].misc )); in lance_tx_timeout()
776 struct lance_ioreg *IO = lp->iobase; in lance_start_xmit() local
782 dev->name, DREG )); in lance_start_xmit()
786 len = skb->len; in lance_start_xmit()
789 /* PAM-Card has a bug: Can only send packets with even number of bytes! */ in lance_start_xmit()
790 else if (lp->cardtype == PAM_CARD && (len & 1)) in lance_start_xmit()
793 if (len > skb->len) { in lance_start_xmit()
804 dev->name, ((u_short *)skb->data)[6], in lance_start_xmit()
805 &skb->data[6], skb->data, in lance_start_xmit()
806 (int)skb->data, (int)skb->len ); in lance_start_xmit()
811 spin_lock_irqsave (&lp->devlock, flags); in lance_start_xmit()
814 entry = lp->cur_tx & TX_RING_MOD_MASK; in lance_start_xmit()
815 head = &(MEM->tx_head[entry]); in lance_start_xmit()
822 head->length = -len; in lance_start_xmit()
823 head->misc = 0; in lance_start_xmit()
824 lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); in lance_start_xmit()
825 head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP; in lance_start_xmit()
826 dev->stats.tx_bytes += skb->len; in lance_start_xmit()
828 lp->cur_tx++; in lance_start_xmit()
829 while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) { in lance_start_xmit()
830 lp->cur_tx -= TX_RING_SIZE; in lance_start_xmit()
831 lp->dirty_tx -= TX_RING_SIZE; in lance_start_xmit()
837 if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) == in lance_start_xmit()
841 lp->tx_full = 1; in lance_start_xmit()
842 spin_unlock_irqrestore (&lp->devlock, flags); in lance_start_xmit()
853 struct lance_ioreg *IO; in lance_interrupt() local
863 IO = lp->iobase; in lance_interrupt()
864 spin_lock (&lp->devlock); in lance_interrupt()
869 --boguscnt >= 0) { in lance_interrupt()
876 dev->name, csr0, DREG )); in lance_interrupt()
881 if (csr0 & CSR0_TINT) { /* Tx-done interrupt */ in lance_interrupt()
882 int dirty_tx = lp->dirty_tx; in lance_interrupt()
884 while( dirty_tx < lp->cur_tx) { in lance_interrupt()
886 int status = MEM->tx_head[entry].flag; in lance_interrupt()
891 MEM->tx_head[entry].flag = 0; in lance_interrupt()
895 int err_status = MEM->tx_head[entry].misc; in lance_interrupt()
896 dev->stats.tx_errors++; in lance_interrupt()
897 if (err_status & TMD3_RTRY) dev->stats.tx_aborted_errors++; in lance_interrupt()
898 if (err_status & TMD3_LCAR) dev->stats.tx_carrier_errors++; in lance_interrupt()
899 if (err_status & TMD3_LCOL) dev->stats.tx_window_errors++; in lance_interrupt()
902 dev->stats.tx_fifo_errors++; in lance_interrupt()
905 dev->name, csr0 )); in lance_interrupt()
911 dev->stats.collisions++; in lance_interrupt()
912 dev->stats.tx_packets++; in lance_interrupt()
920 if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) { in lance_interrupt()
921 DPRINTK( 0, ( "out-of-sync dirty pointer," in lance_interrupt()
923 dirty_tx, lp->cur_tx, lp->tx_full )); in lance_interrupt()
928 if (lp->tx_full && (netif_queue_stopped(dev)) && in lance_interrupt()
929 dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) { in lance_interrupt()
931 lp->tx_full = 0; in lance_interrupt()
935 lp->dirty_tx = dirty_tx; in lance_interrupt()
939 if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */ in lance_interrupt()
940 if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */ in lance_interrupt()
943 "status %04x.\n", dev->name, csr0 )); in lance_interrupt()
954 dev->name, DREG )); in lance_interrupt()
956 spin_unlock (&lp->devlock); in lance_interrupt()
964 int entry = lp->cur_rx & RX_RING_MOD_MASK; in lance_rx()
967 DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name, in lance_rx()
968 MEM->rx_head[entry].flag )); in lance_rx()
971 while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) { in lance_rx()
972 struct lance_rx_head *head = &(MEM->rx_head[entry]); in lance_rx()
973 int status = head->flag; in lance_rx()
977 <murf@perftech.com> to Russ Nelson: Even with full-sized in lance_rx()
981 dev->stats.rx_errors++; /* end of a packet.*/ in lance_rx()
982 if (status & RMD1_FRAM) dev->stats.rx_frame_errors++; in lance_rx()
983 if (status & RMD1_OFLO) dev->stats.rx_over_errors++; in lance_rx()
984 if (status & RMD1_CRC) dev->stats.rx_crc_errors++; in lance_rx()
985 if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++; in lance_rx()
986 head->flag &= (RMD1_ENP|RMD1_STP); in lance_rx()
988 /* Malloc up new buffer, compatible with net-3. */ in lance_rx()
989 short pkt_len = head->msg_length & 0xfff; in lance_rx()
993 printk( "%s: Runt packet!\n", dev->name ); in lance_rx()
994 dev->stats.rx_errors++; in lance_rx()
1000 if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag & in lance_rx()
1004 if (i > RX_RING_SIZE - 2) { in lance_rx()
1005 dev->stats.rx_dropped++; in lance_rx()
1006 head->flag |= RMD1_OWN_CHIP; in lance_rx()
1007 lp->cur_rx++; in lance_rx()
1017 dev->name, ((u_short *)data)[6], in lance_rx()
1023 lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len ); in lance_rx()
1024 skb->protocol = eth_type_trans( skb, dev ); in lance_rx()
1026 dev->stats.rx_packets++; in lance_rx()
1027 dev->stats.rx_bytes += pkt_len; in lance_rx()
1031 head->flag |= RMD1_OWN_CHIP; in lance_rx()
1032 entry = (++lp->cur_rx) & RX_RING_MOD_MASK; in lance_rx()
1034 lp->cur_rx &= RX_RING_MOD_MASK; in lance_rx()
1038 we should free one and mark stats->rx_dropped++. */ in lance_rx()
1047 struct lance_ioreg *IO = lp->iobase; in lance_close() local
1054 dev->name, DREG )); in lance_close()
1056 /* We stop the LANCE here -- it occasionally polls in lance_close()
1065 num_addrs == -1 Promiscuous mode, receive all packets
1068 best-effort filtering.
1074 struct lance_ioreg *IO = lp->iobase; in set_multicast_list() local
1083 if (dev->flags & IFF_PROMISC) { in set_multicast_list()
1085 DPRINTK( 2, ( "%s: Promiscuous mode enabled.\n", dev->name )); in set_multicast_list()
1091 /* We don't use the multicast table, but rely on upper-layer in set_multicast_list()
1093 memset( multicast_table, (num_addrs == 0) ? 0 : -1, in set_multicast_list()
1104 REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); in set_multicast_list()
1119 if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL) in lance_set_mac_address()
1120 return -EOPNOTSUPP; in lance_set_mac_address()
1125 dev->name )); in lance_set_mac_address()
1126 return -EIO; in lance_set_mac_address()
1129 eth_hw_addr_set(dev, saddr->sa_data); in lance_set_mac_address()
1131 MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */ in lance_set_mac_address()
1132 lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 ); in lance_set_mac_address()
1150 free_irq(atarilance_dev->irq, atarilance_dev); in atarilance_module_exit()