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

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