www.pudn.com > Linux2410_device.rar > netproto.h
/* * linux/drivers/usbd/net_fd/netproto.h * * Copyright (c) 2000, 2001, 2002 Lineo * Copyright (c) 2001 Hewlett Packard * * By: * Stuart Lynne, * Tom Rushworth , * Bruce Balden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ //#define NP_ENABLED 0x01 //#define NP_REGISTERED 0x01 /* netproto_dev support routines ***************************************************************** */ #define MAX_NP_CMDS 16 // length of queue of commands for bh #define NPC_CREATE 0x01 // not presently used #define NPC_REGISTER 0x02 #define NPC_ENABLE 0x03 #define NPC_DISABLE 0x04 #define NPC_UNREGISTER 0x05 #define NPC_CLOSE 0x07 /* These should really be in the bus interface, but in order to avoid putting a whole task structure into there like the netproto_registration_task, it's included here. */ #define NPC_SUSPEND 0x08 // bus inactive - host has suspended #define NPC_RESUME 0x09 // bus active - host has resumed /* Values for device state */ #define NP_REGISTERED 0x01 // device has been registered #define NP_ENABLED 0x02 #define NP_DESTROYED 0x04 #define NP_CLOSING 0x08 #define NP_LOCKED 0x10 //#define NP_ENABLE 0x10 //#define NP_DISABLE 0x20 //#define NP_ENABLED 0x40 /* per network interface device structure */ struct netproto_dev { struct net_device *net_dev; // network device information struct net_device_stats stats; // network device statistics int interface; // interface number int mac_was_set; int state; int ops_in_progress; int cmd_queue_count; unsigned char queued_cmds[MAX_NP_CMDS]; int (*xmit_skb) (int, struct sk_buff *); // use to send a network buffer int (*set_addr) (int, void *, int); // set address int (*tx_timeout) (int); // timeout int addr_set; // addr set by ioctl flag int addr_mac; // addr provided flag // XXX is this sufficent should we just use // module netproto_rwlock for everything // lock for reading/writing rwlock_t rwlock; int mtu; unsigned int stopped; unsigned int restarts; unsigned int max_queue_entries; unsigned int max_queue_bytes; unsigned int queued_entries; unsigned int queued_bytes; time_t avg_queue_entries; time_t jiffies; unsigned long samples; }; extern char *netproto_procname; // name to use for proc filesystem extern int netproto_devices; // maximum number of interfaces that can be created extern struct netproto_dev **netproto_device_array; // pointer to array of pointers to netproto dev structures extern rwlock_t netproto_rwlock; // lock for netproto device array access #include "../usbd-debug.h" // Some debug macros for the inlines... extern int dbgflg_usbdfd_prx; extern int dbgflg_usbdfd_ptx; #ifndef dbg_prx #define dbg_prx(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_prx,lvl,fmt,##args) #endif #ifndef dbg_ptx #define dbg_ptx(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_ptx,lvl,fmt,##args) #endif extern debug_option *netproto_get_dbg_table (void); /* proc file system */ #define NET_DEVICE_CONDITION_UNKNOWN 0 #define NET_DEVICE_CONDITION_RESET 1 #define NET_DEVICE_CONDITION_OK 2 #define NET_DEVICE_CONDITION_FAIL 3 /** * netproto * * This is a simple linux network driver library that is suitable for * implementing layered network drivers. I.e. networking over adsl or usb. * */ /** * netproto_modinit - initialize netproto library * @int: number of interfaces to allow * * Initialize the netproto library setting the maximum number of network * interfaces that may be created. */ int netproto_modinit (char *, int); /* * * netproto_create - create network interface * @name: name * @int (*)(struct sk_buff *) * @int (*)(void *,int) * @void * - pointer to mac address buffer * @int - length of mac address buffer * @mtu: maximum mtu * @max_queue_entries: * @max_queue_bytes: * @flags * * Create a network interface, providing an xmit skb function, an option * function to set network addreses and an optional mac address. * * A returned value greater than zero indicates success and can be used with * subsequent function calls to indicate the created network interface. */ int netproto_create (char *, int (*)(int, struct sk_buff *), int (*)(int, void *, int), int (*)(int), void *, int, int, int, int, int); /* * * netproto_command - * @device */ //void netproto_command(int, int); /* * * netproto_enable - * @int * @flags */ void netproto_enable (int, int); /* * * netproto_recv - receive a network buffer * @int - network interface * @struct sk_buff * - network buffer * * Call to pass up a network buffer. */ static __inline__ int netproto_recv (int, struct sk_buff *); /* * * netproto_done - transmit done * @int - network interface * @struct sk_buff * - network buffer * @int - non-zero indicates failure * * Call to indicate that a network buffer has been transferred. */ static __inline__ int netproto_done (int, struct sk_buff *, int); /* * * netproto_control - control network interface * @int - network interface * @int - operation * * Control a network interface, */ int netproto_control (int, int); /* * * netproto_destroy - destroy a network interface * @int - network interface * * Call to tear down a previously created network interface */ int netproto_destroy (int); /* * * netproto_rx_dropped * @int - network interface * */ void netproto_rx_dropped (int); /* * * netproto_rx_length_error * @int - network interface * */ void netproto_rx_length_error (int); /* * * netproto_rx_over_error * @int - network interface * */ void netproto_rx_over_error (int); /* * * netproto_rx_crc_error * @int - network interface * */ void netproto_rx_crc_error (int); /* * * netproto_rx_frame_error * @int - network interface * */ void netproto_rx_frame_error (int); /* * * netproto_rx_fifo_error * @int - network interface * */ void netproto_rx_fifo_error (int); /* * * netproto_rx_missed_error * @int - network interface * */ void netproto_rx_missed_error (int); /* * * netproto_rx_packets * @int - network interface * @len: * */ void netproto_rx_packets (int, int); /* * * netproto_tx_dropped * @int - network interface * */ void netproto_tx_dropped (int); /* * * netproto_tx_carrier_errors * @int - network interface * */ void netproto_tx_carrier_errors (int); /* * * netproto_tx_fifo_errors * @int - network interface * */ void netproto_tx_fifo_errors (int); /* * * netproto_tx_packets * @int - network interface * @len: * */ void netproto_tx_packets (int, int); /* * * netproto_name * @int - network interface * */ char *netproto_name (int interface); /* * * netproto_mtu * @int - network interface * */ int netproto_mtu (int interface); /* * * netproto_modexit * * Call to unload the library. */ /* * * netproto_on * @int - network interface * */ void netproto_on (int interface); /* * * netproto_off * @int - network interface * */ void netproto_off (int interface); int netproto_modexit (void); /** * netproto_recv - receive a network buffer * @interface: network interface * @skb: pointer to network buffer * * Call to pass up a network buffer. * * Called by netproto_recv() to process a received skb and push it to the * network layer. Return non-zero if the skb was not freed. */ static __inline__ int netproto_recv (int interface, struct sk_buff *skb) { struct netproto_dev *device; struct net_device *net_dev; int rc; //printk(KERN_DEBUG"netproto_recv\n"); //dbg_prx(0, "receiving %x %d", skb, skb->len); if ((interface >= netproto_devices) || (device = netproto_device_array[interface]) == NULL) { dbg_prx (0, "bad interface: %d", interface); return -EINVAL; } if (device->state != (NP_REGISTERED | NP_ENABLED)) { dbg_prx (0, "not registered: state: %x", device->state); return -EINVAL; } if (!(net_dev = device->net_dev)) { dbg_prx (0, "bad net_dev: %p", net_dev); return -EINVAL; } // return -EINVAL; if (!netif_device_present (net_dev)) { dbg_prx (0, "device not present"); return -EINVAL; } if (!netif_carrier_ok (net_dev)) { dbg_prx (0, "no carrier"); return -EINVAL; } // if the net device is down, refuse the skb if (!(net_dev->flags & IFF_UP)) { dbg_prx (0, "not up net_dev->flags: %x", net_dev->flags); netproto_rx_dropped (interface); return -EINVAL; } skb->dev = net_dev; skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans (skb, net_dev); skb->ip_summed = CHECKSUM_UNNECESSARY; dbg_prx (5, "skb: %p head: %p data: %p tail: %p end: %p len: %d", skb, skb->head, skb->data, skb->tail, skb->end, skb->len); // pass it up to kernel networking layer if ((rc = netif_rx (skb))) { dbg_prx (0, "netif_rx rc: %d", rc); } netproto_rx_packets (interface, skb->len); { extern int net_device_condition; if (net_device_condition == NET_DEVICE_CONDITION_RESET) net_device_condition = NET_DEVICE_CONDITION_OK; } return 0; } /** * netproto_done - transmit done * @interface: network interface * @skb: network buffer * @rc: non-zero indicates failure * * Call to indicate that a network buffer has been transferred. * * The network layer will be restarted. */ static __inline__ int netproto_done (int interface, struct sk_buff *skb, int rc) { struct netproto_dev *device; struct net_device *net_dev; time_t elapsed = 0; dbg_ptx (5, "skb: %p", skb); if (!skb) { return -EINVAL; } if ((interface >= netproto_devices) || (device = netproto_device_array[interface]) == NULL) { dbg_prx (0, "bad interface: %d", interface); return -EINVAL; } if (!(net_dev = device->net_dev)) { dbg_prx (0, "bad net_dev: %p", net_dev); return -EINVAL; } if (rc) { netproto_tx_dropped (interface); } { // lock and update stats unsigned long flags; write_lock_irqsave (&device->rwlock, flags); device->avg_queue_entries += device->queued_entries; device->queued_entries--; if (skb) { device->samples++; device->jiffies += jiffies - *(time_t *) (&skb->cb); device->queued_bytes -= skb->len; elapsed = jiffies - *(time_t *) (&skb->cb); } write_unlock_irqrestore (&device->rwlock, flags); } if (skb) { dev_kfree_skb_any (skb); } if (netif_queue_stopped (net_dev)) { unsigned long flags; netif_wake_queue (net_dev); write_lock_irqsave (&device->rwlock, flags); device->restarts++; write_unlock_irqrestore (&device->rwlock, flags); } return 0; } /* netproto_dev_alloc_skb - allocate an skb suitable for IP with alignment * @len: * * IP headers need to be aligned on 16 byte boundary. */ static __inline__ struct sk_buff *netproto_dev_alloc_skb (unsigned int length) { struct sk_buff *skb; if ((skb = dev_alloc_skb (length + 2))) { skb_reserve (skb, 2); } dbg_prx (5, "skb: %p len:%d adding 2 for IP alignment", skb, length); return skb; }