patch-2.1.23 linux/drivers/ap1000/bif.c
Next file: linux/drivers/ap1000/ddv.c
Previous file: linux/drivers/ap1000/apfddi.h
Back to the patch index
Back to the overall index
- Lines: 290
- Date:
Sun Jan 26 12:07:10 1997
- Orig file:
v2.1.22/linux/drivers/ap1000/bif.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v2.1.22/linux/drivers/ap1000/bif.c linux/drivers/ap1000/bif.c
@@ -0,0 +1,289 @@
+ /*
+ * Copyright 1996 The Australian National University.
+ * Copyright 1996 Fujitsu Laboratories Limited
+ *
+ * This software may be distributed under the terms of the Gnu
+ * Public License version 2 or later
+ */
+/*
+ * $Id: bif.c,v 1.13 1996/12/18 01:45:52 tridge Exp $
+ *
+ * Network interface definitions for bif device.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/in.h>
+#include <linux/if_ether.h> /* For the statistics structure. */
+#include <linux/netdevice.h>
+#include <linux/if_arp.h> /* For ARPHRD_BIF */
+
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/io.h>
+
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+
+#include <asm/ap1000/apservice.h>
+#include <asm/ap1000/apreg.h>
+
+#define BIF_DEBUG 0
+#if BIF_DEBUG
+static int seq = 0;
+#endif
+
+#define BIF_MTU 10240
+
+static struct device *bif_device = 0;
+static struct enet_statistics *bif_stats = 0;
+
+int bif_init(struct device *dev);
+int bif_open(struct device *dev);
+static int bif_xmit(struct sk_buff *skb, struct device *dev);
+int bif_rx(struct sk_buff *skb);
+int bif_stop(struct device *dev);
+static struct enet_statistics *bif_get_stats(struct device *dev);
+
+static int bif_hard_header(struct sk_buff *skb, struct device *dev,
+ unsigned short type, void *daddr,
+ void *saddr, unsigned len)
+{
+#if BIF_DEBUG
+ printk("bif_hard_header()\n");
+#endif
+
+ skb_push(skb,dev->hard_header_len);
+
+ if (daddr) skb->arp = 1;
+
+ /* tell IP how much space we took */
+ return (dev->hard_header_len);
+}
+
+static int bif_rebuild_header(void *buff, struct device *dev,
+ unsigned long raddr, struct sk_buff *skb)
+{
+ /* this would normally be used to fill in hardware addresses after
+ an ARP */
+#if BIF_DEBUG
+ printk("bif_rebuild_header()\n");
+#endif
+ if (skb) skb->arp = 1;
+ return(0);
+}
+
+static int bif_set_mac_address(struct device *dev, void *addr)
+{
+ printk("BIF: set_mac_address called\n");
+ return (0);
+}
+
+static void bif_set_multicast_list(struct device *dev)
+{
+ return;
+}
+
+static int bif_do_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+ printk("BIF: Called do_ioctl\n");
+ return (0);
+}
+
+static int bif_set_config(struct device *dev, struct ifmap *map)
+{
+ printk("BIF: Called bif_set_config\n");
+ return (0);
+}
+
+/*
+ * Initialise bif network interface.
+ */
+int bif_init(struct device *dev)
+{
+ int i;
+
+ printk("bif_init(): Initialising bif interface\n");
+ bif_device = dev;
+
+ dev->mtu = BIF_MTU;
+ dev->tbusy = 0;
+ dev->hard_start_xmit = bif_xmit;
+ dev->hard_header = bif_hard_header;
+ dev->hard_header_len = sizeof(struct cap_request);
+ dev->addr_len = 0;
+ dev->tx_queue_len = 50000; /* no limit (almost!) */
+ dev->type = ARPHRD_BIF;
+ dev->rebuild_header = bif_rebuild_header;
+ dev->open = bif_open;
+ dev->flags = IFF_NOARP; /* Don't use ARP on this device */
+ dev->family = AF_INET;
+ dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct enet_statistics));
+ bif_stats = (struct enet_statistics *)bif_device->priv;
+
+
+ dev->stop = bif_stop;
+ dev->get_stats = bif_get_stats;
+
+ /* Initialise the bif device structure */
+ for (i = 0; i < DEV_NUMBUFFS; i++)
+ skb_queue_head_init(&dev->buffs[i]);
+
+ dev->set_mac_address = bif_set_mac_address;
+ dev->header_cache_update = NULL;
+ dev->do_ioctl = bif_do_ioctl;
+ dev->set_config = bif_set_config;
+ dev->set_multicast_list = bif_set_multicast_list;
+
+ memset(dev->broadcast, 0xFF, ETH_ALEN);
+
+ dev->pa_addr = 0;
+ dev->pa_brdaddr = 0;
+ dev->pa_mask = 0;
+ dev->pa_alen = 4;
+
+ return(0);
+}
+
+int bif_open(struct device *dev)
+{
+ printk("In bif_open\n");
+ dev->tbusy = 0;
+ dev->start = 1;
+ return 0;
+}
+
+#if BIF_DEBUG
+static void dump_packet(char *action, char *buf, int len, int seq)
+{
+ int flags;
+ char *sep;
+
+ printk("%s packet %d of %d bytes at %d:\n", action, seq,
+ len, (int)jiffies);
+ printk(" from %x to %x pktid=%d ttl=%d pcol=%d len=%d\n",
+ *(long *)(buf+12), *(long *)(buf+16), *(u_short *)(buf+4),
+ *(unsigned char *)(buf+8), buf[9], *(u_short *)(buf+2));
+ if( buf[9] == 6 || buf[9] == 17 ){
+ /* TCP or UDP */
+ printk(" sport=%d dport=%d",
+ *(u_short *)(buf+20), *(u_short *)(buf+22));
+ if( buf[9] == 6 ){
+ printk(" seq=%d ack=%d win=%d flags=<",
+ *(long *)(buf+24), *(long *)(buf+28),
+ *(unsigned short *)(buf+34));
+ flags = buf[33];
+ sep = "";
+ printk(">");
+ }
+ printk("\n");
+ }
+ else {
+ printk(" protocol = %d\n", buf[9]);
+ }
+}
+#endif
+
+
+static int bif_xmit(struct sk_buff *skb, struct device *dev)
+{
+ extern int bif_send_ip(int cid,struct sk_buff *skb);
+ extern int tnet_send_ip(int cid,struct sk_buff *skb);
+ extern int msc_blocked, tnet_ip_enabled;
+ u_long destip;
+ int cid;
+
+ if (skb == NULL || dev == NULL)
+ return(0);
+
+ destip = *(u_long *)(skb->data+sizeof(struct cap_request)+16);
+ cid = ap_ip_to_cid(destip);
+
+ skb->dev = dev;
+ skb->mac.raw = skb->data;
+
+ if (cid != -1 && tnet_ip_enabled && !msc_blocked) {
+ tnet_send_ip(cid,skb);
+ } else {
+ bif_send_ip(cid, skb);
+ }
+
+ dev->tbusy = 0;
+
+ bif_stats->tx_packets++;
+
+ mark_bh(NET_BH);
+
+ return 0;
+}
+
+
+/*
+ * Receive a packet from the BIF - called from interrupt handler.
+ */
+int bif_rx(struct sk_buff *skb)
+{
+#if BIF_DEBUG
+ dump_packet("bif_rx:", skb->data, skb->len, seq++);
+#endif
+
+ if (bif_device == NULL) {
+ printk("bif: bif_device is NULL in bif_rx\n");
+ dev_kfree_skb(skb, FREE_WRITE);
+ return 0;
+ }
+ skb->dev = bif_device;
+ skb->protocol = ETH_P_IP;
+
+#if 1
+ /* try disabling checksums on receive */
+ if (ap_ip_to_cid(*(u_long *)(((char *)skb->data)+12)) != -1)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+#endif
+
+ /*
+ * Inform the network layer of the new packet.
+ */
+ skb->mac.raw = skb->data;
+ netif_rx(skb);
+
+ if (bif_stats == NULL) {
+ printk("bif: bif_stats is NULL is bif_rx\n");
+ return 0;
+ }
+ bif_stats->rx_packets++;
+
+ return 0;
+}
+
+int bif_stop(struct device *dev)
+{
+ printk("in bif_close\n");
+
+ dev->tbusy = 1;
+ dev->start = 0;
+
+ return 0;
+}
+
+/*
+ * Return statistics of bif driver.
+ */
+static struct enet_statistics *bif_get_stats(struct device *dev)
+{
+ return((struct enet_statistics *)dev->priv);
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov