?? atari_bionet.c
字號:
i = get_status(station_addr); /* Read the station address PROM. */ ENABLE_IRQ(); stdma_release(); /* Check the first three octets of the S.A. for the manufactor's code. */ if( i < 0 || station_addr[0] != 'B' || station_addr[1] != 'I' || station_addr[2] != 'O' ) { no_more_found = 1; printk( "No BioNet 100 found.\n" ); return -ENODEV; } SET_MODULE_OWNER(dev); if (bionet_debug > 0 && version_printed++ == 0) printk(version); printk("%s: %s found, eth-addr: %02x-%02x-%02x:%02x-%02x-%02x.\n", dev->name, "BioNet 100", station_addr[0], station_addr[1], station_addr[2], station_addr[3], station_addr[4], station_addr[5]); /* Initialize the device structure. */ nic_packet = (struct nic_pkt_s *)acsi_buffer; phys_nic_packet = (unsigned char *)phys_acsi_buffer; if (bionet_debug > 0) { printk("nic_packet at 0x%p, phys at 0x%p\n", nic_packet, phys_nic_packet ); } if (dev->priv == NULL) dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); if (!dev->priv) return -ENOMEM; memset(dev->priv, 0, sizeof(struct net_local)); dev->open = bionet_open; dev->stop = bionet_close; dev->hard_start_xmit = bionet_send_packet; dev->get_stats = net_get_stats; /* Fill in the fields of the device structure with ethernet-generic * values. This should be in a common file instead of per-driver. */ for (i = 0; i < ETH_ALEN; i++) {#if 0 dev->broadcast[i] = 0xff;#endif dev->dev_addr[i] = station_addr[i]; } ether_setup(dev); return 0;}/* 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 intbionet_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (bionet_debug > 0) printk("bionet_open\n"); stdma_lock(bionet_intr, NULL); /* Reset the hardware here. */ set_status(4); lp->open_time = 0; /*jiffies*/ lp->poll_time = MAX_POLL_TIME; dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; stdma_release(); bionet_timer.data = (long)dev; bionet_timer.expires = jiffies + lp->poll_time; add_timer(&bionet_timer); return 0;}static intbionet_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; /* Block a timer-based transmit from overlapping. This could better be * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ save_flags(flags); cli(); if (stdma_islocked()) { restore_flags(flags); lp->stats.tx_errors++; } else { int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned long buf = virt_to_phys(skb->data); int stat; stdma_lock(bionet_intr, NULL); restore_flags(flags); if( !STRAM_ADDR(buf+length-1) ) { memcpy(nic_packet->buffer, skb->data, length); buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer; } if (bionet_debug >1) { u_char *data = nic_packet->buffer, *p; int i; printk( "%s: TX pkt type 0x%4x from ", dev->name, ((u_short *)data)[6]); for( p = &data[6], i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" ); printk(" to "); for( p = data, i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" ); printk( "%s: ", dev->name ); printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x" " %02x%02x%02x%02x len %d\n", data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], length ); } dma_cache_maintenance(buf, length, 1); stat = hardware_send_packet(buf, length); ENABLE_IRQ(); stdma_release(); dev->trans_start = jiffies; dev->tbusy = 0; lp->stats.tx_packets++; lp->stats.tx_bytes+=length; } dev_kfree_skb(skb); return 0;}/* We have a good packet(s), get it/them out of the buffers. */static voidbionet_poll_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int boguscount = 10; int pkt_len, status; unsigned long flags; save_flags(flags); cli(); /* ++roman: Take care at locking the ST-DMA... This must be done with ints * off, since otherwise an int could slip in between the question and the * locking itself, and then we'd go to sleep... And locking itself is * necessary to keep the floppy_change timer from working with ST-DMA * registers. */ if (stdma_islocked()) { restore_flags(flags); return; } stdma_lock(bionet_intr, NULL); DISABLE_IRQ(); restore_flags(flags); if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++; while(boguscount--) { status = get_frame((unsigned long)phys_nic_packet, 0); if( status == 0 ) break; /* Good packet... */ dma_cache_maintenance((unsigned long)phys_nic_packet, 1520, 0); pkt_len = (nic_packet->l_hi << 8) | nic_packet->l_lo; lp->poll_time = bionet_min_poll_time; /* fast poll */ if( pkt_len >= 60 && pkt_len <= 1520 ) { /* ^^^^ war 1514 KHL */ /* Malloc up new buffer. */ struct sk_buff *skb = dev_alloc_skb( pkt_len + 2 ); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; break; } skb->dev = dev; skb_reserve( skb, 2 ); /* 16 Byte align */ skb_put( skb, pkt_len ); /* make room */ /* 'skb->data' points to the start of sk_buff data area. */ memcpy(skb->data, nic_packet->buffer, pkt_len); skb->protocol = eth_type_trans( skb, dev ); netif_rx(skb); dev->last_rx = jiffies; lp->stats.rx_packets++; lp->stats.rx_bytes+=pkt_len; /* If any worth-while packets have been received, dev_rint() has done a mark_bh(INET_BH) for us and will work on them when we get to the bottom-half routine. */ if (bionet_debug >1) { u_char *data = nic_packet->buffer, *p; int i; printk( "%s: RX pkt type 0x%4x from ", dev->name, ((u_short *)data)[6]); for( p = &data[6], i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" ); printk(" to "); for( p = data, i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" ); printk( "%s: ", dev->name ); printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x" " %02x%02x%02x%02x len %d\n", data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], pkt_len ); } } else { printk(" Packet has wrong length: %04d bytes\n", pkt_len); lp->stats.rx_errors++; } } stdma_release(); ENABLE_IRQ(); return;}/* bionet_tick: called by bionet_timer. Reads packets from the adapter, * passes them to the higher layers and restarts the timer. */static voidbionet_tick(unsigned long data) { struct net_device *dev = (struct net_device *)data; struct net_local *lp = (struct net_local *)dev->priv; if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 ) printk("bionet_tick: %ld\n", lp->open_time); if( !stdma_islocked() ) bionet_poll_rx(dev); bionet_timer.expires = jiffies + lp->poll_time; add_timer(&bionet_timer);}/* The inverse routine to bionet_open(). */static intbionet_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (bionet_debug > 0) printk("bionet_close, open_time=%ld\n", lp->open_time); del_timer(&bionet_timer); stdma_lock(bionet_intr, NULL); set_status(0); lp->open_time = 0; dev->tbusy = 1; dev->start = 0; stdma_release(); 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; return &lp->stats;}#ifdef MODULEstatic struct net_device bio_dev;intinit_module(void) { int err; bio_dev.init = bionet_probe; if ((err = register_netdev(&bio_dev))) { if (err == -EEXIST) { printk("BIONET: devices already present. Module not loaded.\n"); } return err; } return 0;}voidcleanup_module(void) { unregister_netdev(&bio_dev);}#endif /* MODULE *//* Local variables: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -b m68k-linuxaout -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c bionet.c" * version-control: t * kept-new-versions: 5 * tab-width: 8 * End: */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -