static int com90xx_reset(struct net_device *dev, int really_reset) { struct arcnet_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS()); if (really_reset) { inb(_RESET); mdelay(RESETtime); } ACOMMAND(CFLAGScmd | RESETclear); ACOMMAND(CFLAGScmd | CONFIGclear); if (readb(lp->mem_start) != TESTvalue) { if (really_reset) BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n"); return 1; } ACOMMAND(CONFIGcmd | EXTconf); BUGLVL(D_DURING) memset_io(lp->mem_start, 0x42, 2048); return 0; }
/* * Do a hardware reset on the card, and set up necessary registers. * * This should be called as little as possible, because it disrupts the * token on the network (causes a RECON) and requires a significant delay. * * However, it does make sure the card is in a defined state. */ static int com90io_reset(struct net_device *dev, int really_reset) { struct arcnet_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS()); if (really_reset) { /* reset the card */ inb(_RESET); mdelay(RESETtime); } /* Set the thing to IO-mapped, 8-bit mode */ lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag; SETCONF(); ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */ ACOMMAND(CFLAGScmd | CONFIGclear); /* verify that the ARCnet signature byte is present */ if (get_buffer_byte(dev, 0) != TESTvalue) { BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n"); return 1; } /* enable extended (512-byte) packets */ ACOMMAND(CONFIGcmd | EXTconf); /* done! return success. */ return 0; }
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum) { struct arcnet_local *lp = dev->priv; struct arc_hardware *hard = &pkt->hard; int ofs; BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n", lp->next_tx, lp->cur_tx, bufnum); length -= ARC_HDR_SIZE; /* hard header is not included in packet length */ if (length > XMTU) { /* should never happen! other people already check for this. */ BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n", length, XMTU); length = XMTU; } if (length > MinTU) { hard->offset[0] = 0; hard->offset[1] = ofs = 512 - length; } else if (length > MTU) { hard->offset[0] = 0; hard->offset[1] = ofs = 512 - length - 3; } else hard->offset[0] = ofs = 256 - length; lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE); lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length); lp->lastload_dest = hard->dest; return 1; /* done */ }
/* * Do a hardware reset on the card, and set up necessary registers. * * This should be called as little as possible, because it disrupts the * token on the network (causes a RECON) and requires a significant delay. * * However, it does make sure the card is in a defined state. */ static int com90xx_reset(struct net_device *dev, int really_reset) { struct arcnet_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS()); if (really_reset) { /* reset the card */ inb(_RESET); mdelay(RESETtime); } ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */ ACOMMAND(CFLAGScmd | CONFIGclear); /* don't do this until we verify that it doesn't hurt older cards! */ /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */ /* verify that the ARCnet signature byte is present */ if (readb(lp->mem_start) != TESTvalue) { if (really_reset) BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n"); return 1; } /* enable extended (512-byte) packets */ ACOMMAND(CONFIGcmd | EXTconf); /* clean out all the memory to make debugging make more sense :) */ BUGLVL(D_DURING) memset_io(lp->mem_start, 0x42, 2048); /* done! return success. */ return 0; }
/* * We cannot probe for a RIM I card; one reason is I don't know how to reset * them. In fact, we can't even get their node ID automatically. So, we * need to be passed a specific shmem address, IRQ, and node ID. */ static int __init arcrimi_probe(struct net_device *dev) { BUGLVL(D_NORMAL) printk(VERSION); BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", dev->dev_addr[0], dev->mem_start, dev->irq); if (dev->mem_start <= 0 || dev->irq <= 0) { BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " "must specify the shmem and irq!\n"); return -ENODEV; } if (dev->dev_addr[0] == 0) { BUGMSG(D_NORMAL, "You need to specify your card's station " "ID!\n"); return -ENODEV; } /* * Grab the memory region at mem_start for MIRROR_SIZE bytes. * Later in arcrimi_found() the real size will be determined * and this reserve will be released and the correct size * will be taken. */ if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { BUGMSG(D_NORMAL, "Card memory already allocated\n"); return -ENODEV; } return arcrimi_found(dev); }
static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *dev; struct arcnet_local *lp; int ioaddr, err; if (pci_enable_device(pdev)) return -EIO; dev = dev_alloc(device ? : "arc%d", &err); if (!dev) return err; lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL); if (!lp) { err = -ENOMEM; goto out_dev; } memset(lp, 0, sizeof(struct arcnet_local)); pci_set_drvdata(pdev, dev); ioaddr = pci_resource_start(pdev, 2); dev->base_addr = ioaddr; dev->irq = pdev->irq; dev->dev_addr[0] = node; lp->card_name = pdev->name; lp->card_flags = id->driver_data; lp->backplane = backplane; lp->clockp = clockp & 7; lp->clockm = clockm & 3; lp->timeout = timeout; lp->hw.open_close_ll = com20020pci_open_close; if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) { BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n", ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); err = -EBUSY; goto out_priv; } if (ASTATUS() == 0xFF) { BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, " "but seems empty!\n", ioaddr); err = -EIO; goto out_priv; } if (com20020_check(dev)) { err = -EIO; goto out_priv; } if ((err = com20020_found(dev, SA_SHIRQ)) != 0) goto out_priv; return 0; out_priv: kfree(dev->priv); out_dev: kfree(dev); return err; }
/* * Open/initialize the board. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. * * This routine should set everything up anew at each open, even * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ static int net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; struct sk_buff *skb; int irqval; int i; MOD_INC_USE_COUNT; /* For now we always do Eth1 */ lp->uEth = uETH1; BUGMSG("%s:Opening Ethernet interface ", dev->name); if(lp->uEth == uETH1) { BUGMSG("1\n"); dev->irq = IRQ_ETH1; } else { BUGMSG("2\n"); dev->irq = IRQ_ETH2; } irqval = request_irq(dev->irq, &net_interrupt, SA_INTERRUPT, cardname, NULL); if (irqval) { printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, irqval); return -EAGAIN; } /* Allocate Ethernet RX buffers */ for( i = 0; i < ETH_RXQ_SIZE; i++ ) { skb = dev_alloc_skb( PKT_BUF_SZ ); if (skb == NULL) { printk("%s: Could not allocate RX Ring buffer\n", dev->name); while(i != 0) dev_kfree_skb(lp->rx_frames[--i]); return -ENOMEM; } skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ /* word align IP header */ skb_reserve( skb, 2 ); lp->rx_frames[i] = skb; } lp->rxq_ptr = 0; lp->txq_p = 0; lp->txq_c = 0; BUGMSG("%s: Resetting hardware\n", dev->name); /* Reset the hardware here. */ chipset_init( dev, 1 ); lp->open_time = jiffies; BUGMSG("%s: netif_start_queue\n", dev->name); netif_start_queue(dev); return 0; }
/* packet receiver */ static void rx(struct net_device *dev, int bufnum, struct archdr *pkthdr, int length) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; struct sk_buff *skb; struct archdr *pkt = pkthdr; char *pktbuf, *pkthdrbuf; int ofs; BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length); if (length >= MinTU) ofs = 512 - length; else ofs = 256 - length; skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC); if (skb == NULL) { BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); lp->stats.rx_dropped++; return; } skb_put(skb, length + ARC_HDR_SIZE + sizeof(int)); skb->dev = dev; pkt = (struct archdr *) skb->data; skb->mac.raw = skb->data; skb_pull(skb, ARC_HDR_SIZE); /* up to sizeof(pkt->soft) has already been copied from the card */ /* squeeze in an int for the cap encapsulation */ /* use these variables to be sure we count in bytes, not in sizeof(struct archdr) */ pktbuf=(char*)pkt; pkthdrbuf=(char*)pkthdr; memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)); memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int), pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto), sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto)); if (length > sizeof(pkt->soft)) lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft), pkt->soft.raw + sizeof(pkt->soft) + sizeof(int), length - sizeof(pkt->soft)); BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); skb->protocol = __constant_htons(ETH_P_ARCNET); ; netif_rx(skb); dev->last_rx = jiffies; }
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum) { struct arcnet_local *lp = netdev_priv(dev); struct arc_hardware *hard = &pkt->hard; int ofs; /* hard header is not included in packet length */ length -= ARC_HDR_SIZE; /* And neither is the cookie field */ length -= sizeof(int); BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n", lp->next_tx, lp->cur_tx, bufnum); BUGMSG(D_PROTO, "Sending for cap packet %x.\n", *((int*)&pkt->soft.cap.cookie[0])); if (length > XMTU) { /* should never happen! other people already check for this. */ BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n", length, XMTU); length = XMTU; } if (length > MinTU) { hard->offset[0] = 0; hard->offset[1] = ofs = 512 - length; } else if (length > MTU) { hard->offset[0] = 0; hard->offset[1] = ofs = 512 - length - 3; } else hard->offset[0] = ofs = 256 - length; BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n", length,ofs); // Copy the arcnet-header + the protocol byte down: lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE); lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto, sizeof(pkt->soft.cap.proto)); // Skip the extra integer we have written into it as a cookie // but write the rest of the message: lp->hw.copy_to_card(dev, bufnum, ofs+1, ((unsigned char*)&pkt->soft.cap.mes),length-1); lp->lastload_dest = hard->dest; return 1; /* done */ }
static void rx(struct net_device *dev, int bufnum, struct archdr *pkthdr, int length) { struct arcnet_local *lp = netdev_priv(dev); struct sk_buff *skb; struct archdr *pkt = pkthdr; char *pktbuf, *pkthdrbuf; int ofs; BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length); if (length >= MinTU) ofs = 512 - length; else ofs = 256 - length; skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC); if (skb == NULL) { BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); dev->stats.rx_dropped++; return; } skb_put(skb, length + ARC_HDR_SIZE + sizeof(int)); skb->dev = dev; skb_reset_mac_header(skb); pkt = (struct archdr *)skb_mac_header(skb); skb_pull(skb, ARC_HDR_SIZE); /* */ /* */ /* */ pktbuf=(char*)pkt; pkthdrbuf=(char*)pkthdr; memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)); memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int), pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto), sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto)); if (length > sizeof(pkt->soft)) lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft), pkt->soft.raw + sizeof(pkt->soft) + sizeof(int), length - sizeof(pkt->soft)); BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); skb->protocol = cpu_to_be16(ETH_P_ARCNET); netif_rx(skb); }
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum) { struct arcnet_local *lp = netdev_priv(dev); struct arc_hardware *hard = &pkt->hard; int ofs; /* */ length -= ARC_HDR_SIZE; /* */ length -= sizeof(int); BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n", lp->next_tx, lp->cur_tx, bufnum); BUGMSG(D_PROTO, "Sending for cap packet %x.\n", *((int*)&pkt->soft.cap.cookie[0])); if (length > XMTU) { /* */ BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n", length, XMTU); length = XMTU; } if (length > MinTU) { hard->offset[0] = 0; hard->offset[1] = ofs = 512 - length; } else if (length > MTU) { hard->offset[0] = 0; hard->offset[1] = ofs = 512 - length - 3; } else hard->offset[0] = ofs = 256 - length; BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n", length,ofs); /* */ lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE); lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto, sizeof(pkt->soft.cap.proto)); /* */ lp->hw.copy_to_card(dev, bufnum, ofs+1, ((unsigned char*)&pkt->soft.cap.mes),length-1); lp->lastload_dest = hard->dest; return 1; /* */ }
static int build_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, uint8_t daddr) { int hdr_size = ARC_HDR_SIZE; struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size); BUGMSG(D_PROTO, "Preparing header for cap packet %x.\n", *((int*)&pkt->soft.cap.cookie[0])); /* */ pkt->hard.source = *dev->dev_addr; /* */ if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { /* */ pkt->hard.dest = 0; return hdr_size; } /* */ pkt->hard.dest = daddr; return hdr_size; /* */ }
/* * Create the ARCnet hard/soft headers for cap mode. * There aren't any soft headers in cap mode - not even the protocol id. */ static int build_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, uint8_t daddr) { int hdr_size = ARC_HDR_SIZE; struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size); BUGMSG(D_PROTO, "Preparing header for cap packet %x.\n", *((int*)&pkt->soft.cap.cookie[0])); /* * Set the source hardware address. * * This is pretty pointless for most purposes, but it can help in * debugging. ARCnet does not allow us to change the source address in * the actual packet sent) */ pkt->hard.source = *dev->dev_addr; /* see linux/net/ethernet/eth.c to see where I got the following */ if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { /* * FIXME: fill in the last byte of the dest ipaddr here to better * comply with RFC1051 in "noarp" mode. */ pkt->hard.dest = 0; return hdr_size; } /* otherwise, just fill it in and go! */ pkt->hard.dest = daddr; return hdr_size; /* success */ }
/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ static int __init com90io_found(struct net_device *dev) { struct arcnet_local *lp; int ioaddr = dev->base_addr; int err; /* Reserve the irq */ if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) { BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); return -ENODEV; } /* Reserve the I/O region */ if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE, "arcnet (COM90xx-IO)")) { free_irq(dev->irq, dev); return -EBUSY; } lp = netdev_priv(dev); lp->card_name = "COM90xx I/O"; lp->hw.command = com90io_command; lp->hw.status = com90io_status; lp->hw.intmask = com90io_setmask; lp->hw.reset = com90io_reset; lp->hw.owner = THIS_MODULE; lp->hw.copy_to_card = com90io_copy_to_card; lp->hw.copy_from_card = com90io_copy_from_card; lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag; SETCONF(); /* get and check the station ID from offset 1 in shmem */ dev->dev_addr[0] = get_buffer_byte(dev, 1); err = register_netdev(dev); if (err) { outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG); free_irq(dev->irq, dev); release_region(dev->base_addr, ARCNET_TOTAL_SIZE); return err; } BUGMSG(D_NORMAL, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n", dev->dev_addr[0], dev->base_addr, dev->irq); return 0; }
static int ack_tx(struct net_device *dev, int acked) { struct arcnet_local *lp = netdev_priv(dev); struct sk_buff *ackskb; struct archdr *ackpkt; int length=sizeof(struct arc_cap); BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n", lp->outgoing.skb->protocol, acked); BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx"); /* Now alloc a skb to send back up through the layers: */ ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC); if (ackskb == NULL) { BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n"); goto free_outskb; } skb_put(ackskb, length + ARC_HDR_SIZE ); ackskb->dev = dev; skb_reset_mac_header(ackskb); ackpkt = (struct archdr *)skb_mac_header(ackskb); /* skb_pull(ackskb, ARC_HDR_SIZE); */ skb_copy_from_linear_data(lp->outgoing.skb, ackpkt, ARC_HDR_SIZE + sizeof(struct arc_cap)); ackpkt->soft.cap.proto=0; /* using protocol 0 for acknowledge */ ackpkt->soft.cap.mes.ack=acked; BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n", *((int*)&ackpkt->soft.cap.cookie[0])); ackskb->protocol = __constant_htons(ETH_P_ARCNET); BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv"); netif_rx(ackskb); free_outskb: dev_kfree_skb_irq(lp->outgoing.skb); lp->outgoing.proto = NULL; /* We are always finished when in this protocol */ return 0; }
/* * Get the current statistics. * This may be called with the card open or closed. */ static struct net_device_stats * net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; BUGMSG("%s: net_get_stats\n", dev->name); return &lp->stats; }
/* * We cannot (yet) probe for an IO mapped card, although we can check that * it's where we were told it was, and even do autoirq. */ static int __init com20020isa_probe(struct net_device *dev) { int ioaddr; unsigned long airqmask; struct arcnet_local *lp = netdev_priv(dev); int err; BUGLVL(D_NORMAL) printk(VERSION); ioaddr = dev->base_addr; if (!ioaddr) { BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you " "must specify the base address!\n"); return -ENODEV; } if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) { BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n", ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); return -ENXIO; } if (ASTATUS() == 0xFF) { BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr); err = -ENODEV; goto out; } if (com20020_check(dev)) { err = -ENODEV; goto out; } if (!dev->irq) { /* if we do this, we're sure to get an IRQ since the * card has just reset and the NORXflag is on until * we tell it to start receiving. */ BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK)); outb(0, _INTMASK); airqmask = probe_irq_on(); outb(NORXflag, _INTMASK); udelay(1); outb(0, _INTMASK); dev->irq = probe_irq_off(airqmask); <<<<<<< HEAD
/* The inverse routine to net_open(). */ static int net_close(struct net_device *dev) { BUGMSG("%s: net_close\n", dev->name); netif_stop_queue(dev); /* can't transmit any more */ MOD_DEC_USE_COUNT; return 0; }
/* packet receiver */ static void rx(struct net_device *dev, int bufnum, struct archdr *pkthdr, int length) { struct arcnet_local *lp = dev->priv; struct sk_buff *skb; struct archdr *pkt = pkthdr; int ofs; BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length); if (length > MTU) ofs = 512 - length; else ofs = 256 - length; skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC); if (skb == NULL) { BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); lp->stats.rx_dropped++; return; } skb_put(skb, length + ARC_HDR_SIZE); skb->dev = dev; pkt = (struct archdr *) skb->data; skb_reset_mac_header(skb); skb_pull(skb, ARC_HDR_SIZE); /* up to sizeof(pkt->soft) has already been copied from the card */ memcpy(pkt, pkthdr, sizeof(struct archdr)); if (length > sizeof(pkt->soft)) lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft), pkt->soft.raw + sizeof(pkt->soft), length - sizeof(pkt->soft)); BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); skb->protocol = __constant_htons(ETH_P_ARCNET); ; netif_rx(skb); dev->last_rx = jiffies; }
static void arcrimi_rx(struct device *dev,int recbuf) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int ioaddr=dev->mem_start+0x800; union ArcPacket *arcpacket= (union ArcPacket *)phys_to_virt(dev->mem_start+recbuf*512); u_char *arcsoft; short length,offset; u_char daddr,saddr; lp->stats.rx_packets++; saddr=arcpacket->hardheader.source; /* if source is 0, it's a "used" packet! */ if (saddr==0) { BUGMSG(D_NORMAL,"discarding old packet. (status=%Xh)\n", ARCSTATUS); lp->stats.rx_errors++; return; } /* Set source address to zero to mark it as old */ arcpacket->hardheader.source=0; daddr=arcpacket->hardheader.destination; if (arcpacket->hardheader.offset1) /* Normal Packet */ { offset=arcpacket->hardheader.offset1; arcsoft=&arcpacket->raw[offset]; length=256-offset; } else /* ExtendedPacket or ExceptionPacket */ { offset=arcpacket->hardheader.offset2; arcsoft=&arcpacket->raw[offset]; length=512-offset; } arcnet_rx(lp, arcsoft, length, saddr, daddr); BUGLVL(D_RX) arcnet_dump_packet(lp->adev,arcpacket->raw,length>240,"rx"); #ifndef SLOW_XMIT_COPY /* clean out the page to make debugging make more sense :) */ BUGLVL(D_DURING) memset((void *)arcpacket->raw,0x42,512); #endif }
/* * We cannot (yet) probe for an IO mapped card, although we can check that * it's where we were told it was, and even do autoirq. */ static int __init com20020isa_probe(struct net_device *dev) { int ioaddr; unsigned long airqmask; struct arcnet_local *lp = dev->priv; #ifndef MODULE arcnet_init(); #endif BUGLVL(D_NORMAL) printk(VERSION); ioaddr = dev->base_addr; if (!ioaddr) { BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you " "must specify the base address!\n"); return -ENODEV; } if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) { BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n", ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); return -ENXIO; } if (ASTATUS() == 0xFF) { BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr); return -ENODEV; } if (com20020_check(dev)) return -ENODEV; if (!dev->irq) { /* if we do this, we're sure to get an IRQ since the * card has just reset and the NORXflag is on until * we tell it to start receiving. */ BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK)); outb(0, _INTMASK); airqmask = probe_irq_on(); outb(NORXflag, _INTMASK); udelay(1); outb(0, _INTMASK); dev->irq = probe_irq_off(airqmask); if (dev->irq <= 0) { BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n"); airqmask = probe_irq_on(); outb(NORXflag, _INTMASK); udelay(5); outb(0, _INTMASK); dev->irq = probe_irq_off(airqmask); if (dev->irq <= 0) { BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n"); return -ENODEV; } } } lp->card_name = "ISA COM20020"; return com20020_found(dev, 0); }
/* We cannot probe for a RIM I card; one reason is I don't know how to reset * them. In fact, we can't even get their node ID automatically. So, we * need to be passed a specific shmem address, IRQ, and node ID. */ __initfunc(int arcrimi_probe(struct device *dev)) { BUGLVL(D_NORMAL) printk(version); BUGMSG(D_NORMAL,"Given: node %02Xh, shmem %lXh, irq %d\n", dev->dev_addr[0],dev->mem_start,dev->irq); if (dev->mem_start<=0 || dev->irq<=0) { BUGMSG(D_NORMAL,"No autoprobe for RIM I; you " "must specify the shmem and irq!\n"); return -ENODEV; } if (dev->dev_addr[0]==0) { BUGMSG(D_NORMAL,"You need to specify your card's station " "ID!\n"); return -ENODEV; } return arcrimi_found(dev,dev->dev_addr[0],dev->irq,dev->mem_start); }
/* * Create the ARCnet hard/soft headers for RFC1051. */ static int build_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, uint8_t daddr) { struct arcnet_local *lp = dev->priv; int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE; struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size); struct arc_rfc1051 *soft = &pkt->soft.rfc1051; /* set the protocol ID according to RFC1051 */ switch (type) { case ETH_P_IP: soft->proto = ARC_P_IP_RFC1051; break; case ETH_P_ARP: soft->proto = ARC_P_ARP_RFC1051; break; default: BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n", type, type); lp->stats.tx_errors++; lp->stats.tx_aborted_errors++; return 0; } /* * Set the source hardware address. * * This is pretty pointless for most purposes, but it can help in * debugging. ARCnet does not allow us to change the source address in * the actual packet sent) */ pkt->hard.source = *dev->dev_addr; /* see linux/net/ethernet/eth.c to see where I got the following */ if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { /* * FIXME: fill in the last byte of the dest ipaddr here to better * comply with RFC1051 in "noarp" mode. */ pkt->hard.dest = 0; return hdr_size; } /* otherwise, just fill it in and go! */ pkt->hard.dest = daddr; return hdr_size; /* success */ }
static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; BUGMSG("%s: net_send_packet p %d, c %d\n", dev->name, lp->txq_p, lp->txq_c); if((lp->txq_p - lp->txq_c) > (ETH_TXQ_SIZE - 1)) { printk("TX Queue full, dropping packet! (p %d, c %d)\n", lp->txq_p, lp->txq_c); dev_kfree_skb(skb); return 0; } /* Put packet in the Ethernet queue */ lp->uEth->TXBCR = length; lp->uEth->TXADDR = (int)skb->data; lp->tx_frames[lp->txq_p++ & (ETH_TXQ_SIZE - 1)] = skb; dev->trans_start = jiffies; BUGMSG("%s: net_send_packet finished\n", dev->name); return 0; }
/* * We cannot probe for a RIM I card; one reason is I don't know how to reset * them. In fact, we can't even get their node ID automatically. So, we * need to be passed a specific shmem address, IRQ, and node ID. */ static int __init arcrimi_probe(struct net_device *dev) { BUGLVL(D_NORMAL) printk(VERSION); BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", dev->dev_addr[0], dev->mem_start, dev->irq); if (dev->mem_start <= 0 || dev->irq <= 0) { BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " "must specify the shmem and irq!\n"); return -ENODEV; } if (check_mem_region(dev->mem_start, BUFFER_SIZE)) { BUGMSG(D_NORMAL, "Card memory already allocated\n"); return -ENODEV; } if (dev->dev_addr[0] == 0) { BUGMSG(D_NORMAL, "You need to specify your card's station " "ID!\n"); return -ENODEV; } return arcrimi_found(dev); }
/* Do a hardware reset on the card, and set up necessary registers. * * This should be called as little as possible, because it disrupts the * token on the network (causes a RECON) and requires a significant delay. * * However, it does make sure the card is in a defined state. */ int arcrimi_reset(struct device *dev,int reset_delay) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; short ioaddr=dev->mem_start + 0x800; int recbuf=lp->recbuf; if (reset_delay==3) { ARCRESET; return 0; } /* no IRQ's, please! */ lp->intmask=0; SETMASK; BUGMSG(D_INIT,"Resetting %s (status=%Xh)\n", dev->name,ARCSTATUS); ACOMMAND(CFLAGScmd|RESETclear); /* clear flags & end reset */ ACOMMAND(CFLAGScmd|CONFIGclear); /* clear out status variables */ recbuf=lp->recbuf=0; lp->txbuf=2; /* enable extended (512-byte) packets */ ACOMMAND(CONFIGcmd|EXTconf); #ifndef SLOW_XMIT_COPY /* clean out all the memory to make debugging make more sense :) */ BUGLVL(D_DURING) memset_io(dev->mem_start,0x42,2048); #endif /* and enable receive of our first packet to the first buffer */ EnableReceiver(); /* re-enable interrupts */ lp->intmask|=NORXflag; #ifdef DETECT_RECONFIGS lp->intmask|=RECONflag; #endif SETMASK; /* done! return success. */ return 0; }
/* * Do a hardware reset on the card, and set up necessary registers. * * This should be called as little as possible, because it disrupts the * token on the network (causes a RECON) and requires a significant delay. * * However, it does make sure the card is in a defined state. */ static int arcrimi_reset(struct net_device *dev, int really_reset) { struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS()); if (really_reset) { writeb(TESTvalue, ioaddr - 0x800); /* fake reset */ return 0; } ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */ ACOMMAND(CFLAGScmd | CONFIGclear); /* enable extended (512-byte) packets */ ACOMMAND(CONFIGcmd | EXTconf); /* done! return success. */ return 0; }
/* * Set up the struct net_device associated with this card. Called after * probing succeeds. */ static int __init arcrimi_found(struct net_device *dev) { struct arcnet_local *lp; unsigned long first_mirror, last_mirror, shmem; void __iomem *p; int mirror_size; int err; p = ioremap(dev->mem_start, MIRROR_SIZE); if (!p) { release_mem_region(dev->mem_start, MIRROR_SIZE); BUGMSG(D_NORMAL, "Can't ioremap\n"); return -ENODEV; } /* reserve the irq */ if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (RIM I)", dev)) { iounmap(p); release_mem_region(dev->mem_start, MIRROR_SIZE); BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); return -ENODEV; } shmem = dev->mem_start; writeb(TESTvalue, p); writeb(dev->dev_addr[0], p + 1); /* actually the node ID */ /* find the real shared memory start/end points, including mirrors */ /* guess the actual size of one "memory mirror" - the number of * bytes between copies of the shared memory. On most cards, it's * 2k (or there are no mirrors at all) but on some, it's 4k. */ mirror_size = MIRROR_SIZE; if (readb(p) == TESTvalue && check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 && check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1) mirror_size = 2 * MIRROR_SIZE; first_mirror = shmem - mirror_size; while (check_mirror(first_mirror, mirror_size) == 1) first_mirror -= mirror_size; first_mirror += mirror_size; last_mirror = shmem + mirror_size; while (check_mirror(last_mirror, mirror_size) == 1) last_mirror += mirror_size; last_mirror -= mirror_size; dev->mem_start = first_mirror; dev->mem_end = last_mirror + MIRROR_SIZE - 1; /* initialize the rest of the device structure. */ lp = netdev_priv(dev); lp->card_name = "RIM I"; lp->hw.command = arcrimi_command; lp->hw.status = arcrimi_status; lp->hw.intmask = arcrimi_setmask; lp->hw.reset = arcrimi_reset; lp->hw.owner = THIS_MODULE; lp->hw.copy_to_card = arcrimi_copy_to_card; lp->hw.copy_from_card = arcrimi_copy_from_card; /* * re-reserve the memory region - arcrimi_probe() alloced this reqion * but didn't know the real size. Free that region and then re-get * with the correct size. There is a VERY slim chance this could * fail. */ iounmap(p); release_mem_region(shmem, MIRROR_SIZE); if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)")) { BUGMSG(D_NORMAL, "Card memory already allocated\n"); goto err_free_irq; } lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1); if (!lp->mem_start) { BUGMSG(D_NORMAL, "Can't remap device memory!\n"); goto err_release_mem; } /* get and check the station ID from offset 1 in shmem */ dev->dev_addr[0] = readb(lp->mem_start + 1); BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, " "ShMem %lXh (%ld*%d bytes).\n", dev->dev_addr[0], dev->irq, dev->mem_start, (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size); err = register_netdev(dev); if (err) goto err_unmap; return 0; err_unmap: iounmap(lp->mem_start); err_release_mem: release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); err_free_irq: free_irq(dev->irq, dev); return -EIO; }
/* Set up the struct device associated with this card. Called after * probing succeeds. */ __initfunc(int arc20020_found(struct device *dev,int ioaddr,int airq)) { struct arcnet_local *lp; /* reserve the irq */ if (request_irq(airq,&arcnet_interrupt,0,"arcnet (COM20020)",dev)) { BUGMSG(D_NORMAL,"Can't get IRQ %d!\n",airq); return -ENODEV; } dev->irq=airq; /* reserve the I/O region - guaranteed to work by check_region */ request_region(ioaddr,ARCNET_TOTAL_SIZE,"arcnet (COM20020)"); dev->base_addr=ioaddr; dev->mem_start=dev->mem_end=dev->rmem_start=dev->rmem_end=(long)NULL; /* Initialize the rest of the device structure. */ dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL); if (dev->priv == NULL) { free_irq(airq,dev); release_region(ioaddr,ARCNET_TOTAL_SIZE); return -ENOMEM; } memset(dev->priv,0,sizeof(struct arcnet_local)); lp=(struct arcnet_local *)(dev->priv); lp->card_type = ARC_20020; lp->card_type_str = "COM 20020"; lp->arcnet_reset=arc20020_reset; lp->asetmask=arc20020_setmask; lp->astatus=arc20020_status; lp->acommand=arc20020_command; lp->en_dis_able_TX=arc20020_en_dis_able_TX; lp->openclose_device=arc20020_openclose; lp->prepare_tx=arc20020_prepare_tx; lp->inthandler=arc20020_inthandler; dev->set_multicast_list = arc20020_set_mc_list; /* Fill in the fields of the device structure with generic * values. */ arcnet_setup(dev); /* And now fill particular fields with arcnet values */ dev->mtu=1500; /* completely arbitrary - agrees with ether, though */ dev->hard_header_len=sizeof(struct ClientData); lp->sequence=1; lp->recbuf=0; BUGMSG(D_DURING,"ClientData header size is %d.\n", sizeof(struct ClientData)); BUGMSG(D_DURING,"HardHeader size is %d.\n", sizeof(struct archdr)); /* get and check the station ID from offset 1 in shmem */ lp->timeout = dev->dev_addr[3] & 3; dev->dev_addr[3]=0; lp->backplane =dev->dev_addr[1] & 1; dev->dev_addr[1]=0; lp->setup = (dev->dev_addr[2] & 7) << 1; dev->dev_addr[2]=0; if (dev->dev_addr[0]) lp->stationid=dev->dev_addr[0]; else lp->stationid=inb(ioaddr+8); /* FIX ME - We should check that this is valid before using it */ lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2); /* Default 0x38 + register: Node ID */ SETCONF; outb(lp->stationid, ioaddr+7); REGSETUP; SETCONF; outb(lp->setup, ioaddr+7); if (!lp->stationid) BUGMSG(D_NORMAL,"WARNING! Station address 00 is reserved " "for broadcasts!\n"); else if (lp->stationid==255) BUGMSG(D_NORMAL,"WARNING! Station address FF may confuse " "DOS networking programs!\n"); dev->dev_addr[0]=lp->stationid; BUGMSG(D_NORMAL,"ARCnet COM20020: station %02Xh found at %03lXh, IRQ %d.\n", lp->stationid, dev->base_addr,dev->irq); if (lp->backplane) BUGMSG (D_NORMAL, "Using backplane mode.\n"); if (lp->timeout != 3) BUGMSG (D_NORMAL, "Using Extended Timeout value of %d.\n",lp->timeout); if (lp->setup) { BUGMSG (D_NORMAL, "Using CKP %d - Data rate %s.\n", lp->setup >>1,clockrates[lp->setup >> 1] ); }
/* * Set up the struct net_device associated with this card. Called after * probing succeeds. */ static int __init arcrimi_found(struct net_device *dev) { struct arcnet_local *lp; u_long first_mirror, last_mirror, shmem; int mirror_size; /* reserve the irq */ { if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); return -ENODEV; } shmem = dev->mem_start; isa_writeb(TESTvalue, shmem); isa_writeb(dev->dev_addr[0], shmem + 1); /* actually the node ID */ /* find the real shared memory start/end points, including mirrors */ /* guess the actual size of one "memory mirror" - the number of * bytes between copies of the shared memory. On most cards, it's * 2k (or there are no mirrors at all) but on some, it's 4k. */ mirror_size = MIRROR_SIZE; if (isa_readb(shmem) == TESTvalue && isa_readb(shmem - mirror_size) != TESTvalue && isa_readb(shmem - 2 * mirror_size) == TESTvalue) mirror_size *= 2; first_mirror = last_mirror = shmem; while (isa_readb(first_mirror) == TESTvalue) first_mirror -= mirror_size; first_mirror += mirror_size; while (isa_readb(last_mirror) == TESTvalue) last_mirror += mirror_size; last_mirror -= mirror_size; dev->mem_start = first_mirror; dev->mem_end = last_mirror + MIRROR_SIZE - 1; dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0; dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1; /* initialize the rest of the device structure. */ lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL); if (!lp) { BUGMSG(D_NORMAL, "Can't allocate device data!\n"); goto err_free_irq; } lp->card_name = "RIM I"; lp->hw.command = arcrimi_command; lp->hw.status = arcrimi_status; lp->hw.intmask = arcrimi_setmask; lp->hw.reset = arcrimi_reset; lp->hw.open_close = arcrimi_openclose; lp->hw.copy_to_card = arcrimi_copy_to_card; lp->hw.copy_from_card = arcrimi_copy_from_card; lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1); if (!lp->mem_start) { BUGMSG(D_NORMAL, "Can't remap device memory!\n"); goto err_free_dev_priv; } /* Fill in the fields of the device structure with generic * values. */ arcdev_setup(dev); /* get and check the station ID from offset 1 in shmem */ dev->dev_addr[0] = readb(lp->mem_start + 1); /* reserve the memory region - guaranteed to work by check_region */ request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"); BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, " "ShMem %lXh (%ld*%d bytes).\n", dev->dev_addr[0], dev->irq, dev->mem_start, (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size); return 0; err_free_dev_priv: kfree(dev->priv); err_free_irq: free_irq(dev->irq, dev); return -EIO; }