diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
commit | 008d0be72b2f160382c6e880765e96b64a050c65 (patch) | |
tree | 36f48a98a3815a408e2ce1693dd182af90f80305 /release/src/linux/linux/include/net | |
parent | 611becfb8726c60cb060368541ad98191d4532f5 (diff) | |
download | tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.gz tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.bz2 |
imported original firmware WRT54GL_v4.30.11_11_US
Diffstat (limited to 'release/src/linux/linux/include/net')
109 files changed, 18862 insertions, 0 deletions
diff --git a/release/src/linux/linux/include/net/addrconf.h b/release/src/linux/linux/include/net/addrconf.h new file mode 100644 index 00000000..3237e19f --- /dev/null +++ b/release/src/linux/linux/include/net/addrconf.h @@ -0,0 +1,195 @@ +#ifndef _ADDRCONF_H +#define _ADDRCONF_H + +#define RETRANS_TIMER HZ + +#define MAX_RTR_SOLICITATIONS 3 +#define RTR_SOLICITATION_INTERVAL (4*HZ) + +#define ADDR_CHECK_FREQUENCY (120*HZ) + +struct prefix_info { + __u8 type; + __u8 length; + __u8 prefix_len; + +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 onlink : 1, + autoconf : 1, + reserved : 6; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 reserved : 6, + autoconf : 1, + onlink : 1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + __u32 valid; + __u32 prefered; + __u32 reserved2; + + struct in6_addr prefix; +}; + + +#ifdef __KERNEL__ + +#include <linux/in6.h> +#include <linux/netdevice.h> +#include <net/if_inet6.h> + +#define IN6_ADDR_HSIZE 16 + +extern void addrconf_init(void); +extern void addrconf_cleanup(void); + +extern int addrconf_notify(struct notifier_block *this, + unsigned long event, + void * data); + +extern int addrconf_add_ifaddr(void *arg); +extern int addrconf_del_ifaddr(void *arg); +extern int addrconf_set_dstaddr(void *arg); + +extern int ipv6_chk_addr(struct in6_addr *addr, + struct net_device *dev); +extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, + struct net_device *dev); +extern int ipv6_get_saddr(struct dst_entry *dst, + struct in6_addr *daddr, + struct in6_addr *saddr); +extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); + +/* + * multicast prototypes (mcast.c) + */ +extern int ipv6_sock_mc_join(struct sock *sk, + int ifindex, + struct in6_addr *addr); +extern int ipv6_sock_mc_drop(struct sock *sk, + int ifindex, + struct in6_addr *addr); +extern void ipv6_sock_mc_close(struct sock *sk); +extern int inet6_mc_check(struct sock *sk, struct in6_addr *addr); + +extern int ipv6_dev_mc_inc(struct net_device *dev, + struct in6_addr *addr); +extern int ipv6_dev_mc_dec(struct net_device *dev, + struct in6_addr *addr); +extern void ipv6_mc_up(struct inet6_dev *idev); +extern void ipv6_mc_down(struct inet6_dev *idev); +extern void ipv6_mc_init_dev(struct inet6_dev *idev); +extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); +extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); + +extern int ipv6_chk_mcast_addr(struct net_device *dev, + struct in6_addr *addr); + +extern void addrconf_prefix_rcv(struct net_device *dev, + u8 *opt, int len); + +/* Device notifier */ +extern int register_inet6addr_notifier(struct notifier_block *nb); +extern int unregister_inet6addr_notifier(struct notifier_block *nb); + +static inline struct inet6_dev * +__in6_dev_get(struct net_device *dev) +{ + return (struct inet6_dev *)dev->ip6_ptr; +} + +extern rwlock_t addrconf_lock; + +static inline struct inet6_dev * +in6_dev_get(struct net_device *dev) +{ + struct inet6_dev *idev = NULL; + read_lock(&addrconf_lock); + idev = dev->ip6_ptr; + if (idev) + atomic_inc(&idev->refcnt); + read_unlock(&addrconf_lock); + return idev; +} + +extern void in6_dev_finish_destroy(struct inet6_dev *idev); + +static inline void +in6_dev_put(struct inet6_dev *idev) +{ + if (atomic_dec_and_test(&idev->refcnt)) + in6_dev_finish_destroy(idev); +} + +#define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt) +#define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt) + + +extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp); + +static inline void in6_ifa_put(struct inet6_ifaddr *ifp) +{ + if (atomic_dec_and_test(&ifp->refcnt)) + inet6_ifa_finish_destroy(ifp); +} + +#define __in6_ifa_put(idev) atomic_dec(&(idev)->refcnt) +#define in6_ifa_hold(idev) atomic_inc(&(idev)->refcnt) + + +extern void addrconf_forwarding_on(void); +/* + * Hash function taken from net_alias.c + */ + +static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr) +{ + __u32 word; + + /* + * We perform the hash function over the last 64 bits of the address + * This will include the IEEE address token on links that support it. + */ + + word = addr->s6_addr[2] ^ addr->s6_addr32[3]; + word ^= (word>>16); + word ^= (word >> 8); + + return ((word ^ (word >> 4)) & 0x0f); +} + +/* + * compute link-local solicited-node multicast address + */ + +static inline void addrconf_addr_solict_mult(struct in6_addr *addr, + struct in6_addr *solicited) +{ + ipv6_addr_set(solicited, + __constant_htonl(0xFF020000), 0, + __constant_htonl(0x1), + __constant_htonl(0xFF000000) | addr->s6_addr32[3]); +} + + +static inline void ipv6_addr_all_nodes(struct in6_addr *addr) +{ + ipv6_addr_set(addr, + __constant_htonl(0xFF020000), 0, 0, + __constant_htonl(0x1)); +} + +static inline void ipv6_addr_all_routers(struct in6_addr *addr) +{ + ipv6_addr_set(addr, + __constant_htonl(0xFF020000), 0, 0, + __constant_htonl(0x2)); +} + +static inline int ipv6_addr_is_multicast(struct in6_addr *addr) +{ + return (addr->s6_addr32[0] & __constant_htonl(0xFF000000)) == __constant_htonl(0xFF000000); +} + +#endif +#endif diff --git a/release/src/linux/linux/include/net/af_unix.h b/release/src/linux/linux/include/net/af_unix.h new file mode 100644 index 00000000..818df92a --- /dev/null +++ b/release/src/linux/linux/include/net/af_unix.h @@ -0,0 +1,42 @@ +#ifndef __LINUX_NET_AFUNIX_H +#define __LINUX_NET_AFUNIX_H +extern void unix_proto_init(struct net_proto *pro); +extern void unix_inflight(struct file *fp); +extern void unix_notinflight(struct file *fp); +typedef struct sock unix_socket; +extern void unix_gc(void); + +#define UNIX_HASH_SIZE 256 + +extern unix_socket *unix_socket_table[UNIX_HASH_SIZE+1]; +extern rwlock_t unix_table_lock; + +extern atomic_t unix_tot_inflight; + + +#define forall_unix_sockets(i, s) for (i=0; i<=UNIX_HASH_SIZE; i++) \ + for (s=unix_socket_table[i]; s; s=s->next) + +struct unix_address +{ + atomic_t refcnt; + int len; + unsigned hash; + struct sockaddr_un name[0]; +}; + +struct unix_skb_parms +{ + struct ucred creds; /* Skb credentials */ + struct scm_fp_list *fp; /* Passed files */ +}; + +#define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) +#define UNIXCREDS(skb) (&UNIXCB((skb)).creds) + +#define unix_state_rlock(s) read_lock(&(s)->protinfo.af_unix.lock) +#define unix_state_runlock(s) read_unlock(&(s)->protinfo.af_unix.lock) +#define unix_state_wlock(s) write_lock(&(s)->protinfo.af_unix.lock) +#define unix_state_wunlock(s) write_unlock(&(s)->protinfo.af_unix.lock) + +#endif diff --git a/release/src/linux/linux/include/net/arp.h b/release/src/linux/linux/include/net/arp.h new file mode 100644 index 00000000..f65d245f --- /dev/null +++ b/release/src/linux/linux/include/net/arp.h @@ -0,0 +1,24 @@ +/* linux/net/inet/arp.h */ +#ifndef _ARP_H +#define _ARP_H + +#include <linux/if_arp.h> +#include <net/neighbour.h> + +extern struct neigh_table arp_tbl; + +extern void arp_init(void); +extern int arp_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt); +extern int arp_find(unsigned char *haddr, struct sk_buff *skb); +extern int arp_ioctl(unsigned int cmd, void *arg); +extern void arp_send(int type, int ptype, u32 dest_ip, + struct net_device *dev, u32 src_ip, + unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th); +extern int arp_bind_neighbour(struct dst_entry *dst); +extern int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir); +extern void arp_ifdown(struct net_device *dev); + +extern struct neigh_ops arp_broken_ops; + +#endif /* _ARP_H */ diff --git a/release/src/linux/linux/include/net/atmclip.h b/release/src/linux/linux/include/net/atmclip.h new file mode 100644 index 00000000..28d0584c --- /dev/null +++ b/release/src/linux/linux/include/net/atmclip.h @@ -0,0 +1,67 @@ +/* net/atm/atmarp.h - RFC1577 ATM ARP */ + +/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + +#ifndef _ATMCLIP_H +#define _ATMCLIP_H + +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <linux/atm.h> +#include <linux/atmdev.h> +#include <linux/atmarp.h> +#include <linux/spinlock.h> +#include <net/neighbour.h> + + +#define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back)) +#define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key) + + +struct clip_vcc { + struct atm_vcc *vcc; /* VCC descriptor */ + struct atmarp_entry *entry; /* ATMARP table entry, NULL if IP addr. + isn't known yet */ + int xoff; /* 1 if send buffer is full */ + unsigned char encap; /* 0: NULL, 1: LLC/SNAP */ + unsigned long last_use; /* last send or receive operation */ + unsigned long idle_timeout; /* keep open idle for so many jiffies*/ + void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); + /* keep old push fn for chaining */ + void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); + /* keep old pop fn for chaining */ + struct clip_vcc *next; /* next VCC */ +}; + + +struct atmarp_entry { + u32 ip; /* IP address */ + struct clip_vcc *vccs; /* active VCCs; NULL if resolution is + pending */ + unsigned long expires; /* entry expiration time */ + struct neighbour *neigh; /* neighbour back-pointer */ +}; + + +#define PRIV(dev) ((struct clip_priv *) ((struct net_device *) (dev)+1)) + + +struct clip_priv { + int number; /* for convenience ... */ + spinlock_t xoff_lock; /* ensures that pop is atomic (SMP) */ + struct net_device_stats stats; + struct net_device *next; /* next CLIP interface */ +}; + + +extern struct atm_vcc *atmarpd; /* ugly */ +extern struct neigh_table clip_tbl; + +int clip_create(int number); +int clip_mkip(struct atm_vcc *vcc,int timeout); +int clip_setentry(struct atm_vcc *vcc,u32 ip); +int clip_encap(struct atm_vcc *vcc,int mode); +void atm_clip_init(void); + +#endif diff --git a/release/src/linux/linux/include/net/ax25.h b/release/src/linux/linux/include/net/ax25.h new file mode 100644 index 00000000..0957d1aa --- /dev/null +++ b/release/src/linux/linux/include/net/ax25.h @@ -0,0 +1,350 @@ +/* + * Declarations of AX.25 type objects. + * + * Alan Cox (GW4PTS) 10/11/93 + */ + +#ifndef _AX25_H +#define _AX25_H +#include <linux/config.h> +#include <linux/ax25.h> + +#define AX25_T1CLAMPLO 1 +#define AX25_T1CLAMPHI (30 * HZ) + +#define AX25_BPQ_HEADER_LEN 16 +#define AX25_KISS_HEADER_LEN 1 + +#define AX25_HEADER_LEN 17 +#define AX25_ADDR_LEN 7 +#define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN) +#define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN) + +/* AX.25 Protocol IDs */ +#define AX25_P_ROSE 0x01 +#define AX25_P_IP 0xCC +#define AX25_P_ARP 0xCD +#define AX25_P_TEXT 0xF0 +#define AX25_P_NETROM 0xCF +#define AX25_P_SEGMENT 0x08 + +/* AX.25 Segment control values */ +#define AX25_SEG_REM 0x7F +#define AX25_SEG_FIRST 0x80 + +#define AX25_CBIT 0x80 /* Command/Response bit */ +#define AX25_EBIT 0x01 /* HDLC Address Extension bit */ +#define AX25_HBIT 0x80 /* Has been repeated bit */ + +#define AX25_SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */ +#define AX25_ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */ +#define AX25_DAMA_FLAG 0x20 /* Well, it is *NOT* unused! (dl1bke 951121 */ + +#define AX25_COND_ACK_PENDING 0x01 +#define AX25_COND_REJECT 0x02 +#define AX25_COND_PEER_RX_BUSY 0x04 +#define AX25_COND_OWN_RX_BUSY 0x08 +#define AX25_COND_DAMA_MODE 0x10 + +#ifndef _LINUX_NETDEVICE_H +#include <linux/netdevice.h> +#endif + +/* Upper sub-layer (LAPB) definitions */ + +/* Control field templates */ +#define AX25_I 0x00 /* Information frames */ +#define AX25_S 0x01 /* Supervisory frames */ +#define AX25_RR 0x01 /* Receiver ready */ +#define AX25_RNR 0x05 /* Receiver not ready */ +#define AX25_REJ 0x09 /* Reject */ +#define AX25_U 0x03 /* Unnumbered frames */ +#define AX25_SABM 0x2f /* Set Asynchronous Balanced Mode */ +#define AX25_SABME 0x6f /* Set Asynchronous Balanced Mode Extended */ +#define AX25_DISC 0x43 /* Disconnect */ +#define AX25_DM 0x0f /* Disconnected mode */ +#define AX25_UA 0x63 /* Unnumbered acknowledge */ +#define AX25_FRMR 0x87 /* Frame reject */ +#define AX25_UI 0x03 /* Unnumbered information */ + +#define AX25_PF 0x10 /* Poll/final bit for standard AX.25 */ +#define AX25_EPF 0x01 /* Poll/final bit for extended AX.25 */ + +#define AX25_ILLEGAL 0x100 /* Impossible to be a real frame type */ + +#define AX25_POLLOFF 0 +#define AX25_POLLON 1 + +/* AX25 L2 C-bit */ +#define AX25_COMMAND 1 +#define AX25_RESPONSE 2 + +/* Define Link State constants. */ + +enum { + AX25_STATE_0, + AX25_STATE_1, + AX25_STATE_2, + AX25_STATE_3, + AX25_STATE_4 +}; + +#define AX25_MODULUS 8 /* Standard AX.25 modulus */ +#define AX25_EMODULUS 128 /* Extended AX.25 modulus */ + +enum { + AX25_PROTO_STD_SIMPLEX, + AX25_PROTO_STD_DUPLEX, + AX25_PROTO_DAMA_SLAVE, + AX25_PROTO_DAMA_MASTER +}; + +enum { + AX25_VALUES_IPDEFMODE, /* 0=DG 1=VC */ + AX25_VALUES_AXDEFMODE, /* 0=Normal 1=Extended Seq Nos */ + AX25_VALUES_BACKOFF, /* 0=None 1=Linear 2=Exponential */ + AX25_VALUES_CONMODE, /* Allow connected modes - 0=No 1=no "PID text" 2=all PIDs */ + AX25_VALUES_WINDOW, /* Default window size for standard AX.25 */ + AX25_VALUES_EWINDOW, /* Default window size for extended AX.25 */ + AX25_VALUES_T1, /* Default T1 timeout value */ + AX25_VALUES_T2, /* Default T2 timeout value */ + AX25_VALUES_T3, /* Default T3 timeout value */ + AX25_VALUES_IDLE, /* Connected mode idle timer */ + AX25_VALUES_N2, /* Default N2 value */ + AX25_VALUES_PACLEN, /* AX.25 MTU */ + AX25_VALUES_PROTOCOL, /* Std AX.25, DAMA Slave, DAMA Master */ + AX25_VALUES_DS_TIMEOUT, /* DAMA Slave timeout */ + AX25_MAX_VALUES /* THIS MUST REMAIN THE LAST ENTRY OF THIS LIST */ +}; + +#define AX25_DEF_IPDEFMODE 0 /* Datagram */ +#define AX25_DEF_AXDEFMODE 0 /* Normal */ +#define AX25_DEF_BACKOFF 1 /* Linear backoff */ +#define AX25_DEF_CONMODE 2 /* Connected mode allowed */ +#define AX25_DEF_WINDOW 2 /* Window=2 */ +#define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */ +#define AX25_DEF_T1 (10 * HZ) /* T1=10s */ +#define AX25_DEF_T2 (3 * HZ) /* T2=3s */ +#define AX25_DEF_T3 (300 * HZ) /* T3=300s */ +#define AX25_DEF_N2 10 /* N2=10 */ +#define AX25_DEF_IDLE (0 * 60 * HZ) /* Idle=None */ +#define AX25_DEF_PACLEN 256 /* Paclen=256 */ +#define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */ +#define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */ + +typedef struct ax25_uid_assoc { + struct ax25_uid_assoc *next; + uid_t uid; + ax25_address call; +} ax25_uid_assoc; + +typedef struct { + ax25_address calls[AX25_MAX_DIGIS]; + unsigned char repeated[AX25_MAX_DIGIS]; + unsigned char ndigi; + char lastrepeat; +} ax25_digi; + +typedef struct ax25_route { + struct ax25_route *next; + ax25_address callsign; + struct net_device *dev; + ax25_digi *digipeat; + char ip_mode; +} ax25_route; + +typedef struct { + char slave; /* slave_mode? */ + struct timer_list slave_timer; /* timeout timer */ + unsigned short slave_timeout; /* when? */ +} ax25_dama_info; + +struct ctl_table; + +typedef struct ax25_dev { + struct ax25_dev *next; + struct net_device *dev; + struct net_device *forward; + struct ctl_table *systable; + int values[AX25_MAX_VALUES]; +#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER) + ax25_dama_info dama; +#endif +} ax25_dev; + +typedef struct ax25_cb { + struct ax25_cb *next; + ax25_address source_addr, dest_addr; + ax25_digi *digipeat; + ax25_dev *ax25_dev; + unsigned char iamdigi; + unsigned char state, modulus, pidincl; + unsigned short vs, vr, va; + unsigned char condition, backoff; + unsigned char n2, n2count; + struct timer_list t1timer, t2timer, t3timer, idletimer; + unsigned long t1, t2, t3, idle, rtt; + unsigned short paclen, fragno, fraglen; + struct sk_buff_head write_queue; + struct sk_buff_head reseq_queue; + struct sk_buff_head ack_queue; + struct sk_buff_head frag_queue; + unsigned char window; + struct timer_list timer; + struct sock *sk; /* Backlink to socket */ +} ax25_cb; + +/* af_ax25.c */ +extern ax25_cb *volatile ax25_list; +extern void ax25_free_cb(ax25_cb *); +extern void ax25_insert_socket(ax25_cb *); +struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int); +struct sock *ax25_find_socket(ax25_address *, ax25_address *, int); +extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *); +extern struct sock *ax25_addr_match(ax25_address *); +extern void ax25_send_to_raw(struct sock *, struct sk_buff *, int); +extern void ax25_destroy_socket(ax25_cb *); +extern ax25_cb *ax25_create_cb(void); +extern void ax25_fillin_cb(ax25_cb *, ax25_dev *); +extern int ax25_create(struct socket *, int); +extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *); + +/* ax25_addr.c */ +extern ax25_address null_ax25_address; +extern char *ax2asc(ax25_address *); +extern ax25_address *asc2ax(char *); +extern int ax25cmp(ax25_address *, ax25_address *); +extern int ax25digicmp(ax25_digi *, ax25_digi *); +extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *); +extern int ax25_addr_build(unsigned char *, ax25_address *, ax25_address *, ax25_digi *, int, int); +extern int ax25_addr_size(ax25_digi *); +extern void ax25_digi_invert(ax25_digi *, ax25_digi *); + +/* ax25_dev.c */ +extern ax25_dev *ax25_dev_list; +extern ax25_dev *ax25_dev_ax25dev(struct net_device *); +extern ax25_dev *ax25_addr_ax25dev(ax25_address *); +extern void ax25_dev_device_up(struct net_device *); +extern void ax25_dev_device_down(struct net_device *); +extern int ax25_fwd_ioctl(unsigned int, struct ax25_fwd_struct *); +extern struct net_device *ax25_fwd_dev(struct net_device *); +extern void ax25_dev_free(void); + +/* ax25_ds_in.c */ +extern int ax25_ds_frame_in(ax25_cb *, struct sk_buff *, int); + +/* ax25_ds_subr.c */ +extern void ax25_ds_nr_error_recovery(ax25_cb *); +extern void ax25_ds_enquiry_response(ax25_cb *); +extern void ax25_ds_establish_data_link(ax25_cb *); +extern void ax25_dev_dama_on(ax25_dev *); +extern void ax25_dev_dama_off(ax25_dev *); +extern void ax25_dama_on(ax25_cb *); +extern void ax25_dama_off(ax25_cb *); + +/* ax25_ds_timer.c */ +extern void ax25_ds_set_timer(ax25_dev *); +extern void ax25_ds_del_timer(ax25_dev *); +extern void ax25_ds_timer(ax25_cb *); +extern void ax25_ds_t1_timeout(ax25_cb *); +extern void ax25_ds_heartbeat_expiry(ax25_cb *); +extern void ax25_ds_t3timer_expiry(ax25_cb *); +extern void ax25_ds_idletimer_expiry(ax25_cb *); + +/* ax25_iface.c */ +extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *)); +extern void ax25_protocol_release(unsigned int); +extern int ax25_linkfail_register(void (*)(ax25_cb *, int)); +extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); +extern int ax25_listen_register(ax25_address *, struct net_device *); +extern void ax25_listen_release(ax25_address *, struct net_device *); +extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *); +extern int ax25_listen_mine(ax25_address *, struct net_device *); +extern void ax25_link_failed(ax25_cb *, int); +extern int ax25_protocol_is_registered(unsigned int); + +/* ax25_in.c */ +extern int ax25_rx_iframe(ax25_cb *, struct sk_buff *); +extern int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *); + +/* ax25_ip.c */ +extern int ax25_encapsulate(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int); +extern int ax25_rebuild_header(struct sk_buff *); + +/* ax25_out.c */ +extern ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct net_device *); +extern void ax25_output(ax25_cb *, int, struct sk_buff *); +extern void ax25_kick(ax25_cb *); +extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int); +extern void ax25_queue_xmit(struct sk_buff *); +extern int ax25_check_iframes_acked(ax25_cb *, unsigned short); + +/* ax25_route.c */ +extern void ax25_rt_device_down(struct net_device *); +extern int ax25_rt_ioctl(unsigned int, void *); +extern int ax25_rt_get_info(char *, char **, off_t, int); +extern int ax25_rt_autobind(ax25_cb *, ax25_address *); +extern ax25_route *ax25_rt_find_route(ax25_address *, struct net_device *); +extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *); +extern void ax25_rt_free(void); + +/* ax25_std_in.c */ +extern int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int); + +/* ax25_std_subr.c */ +extern void ax25_std_nr_error_recovery(ax25_cb *); +extern void ax25_std_establish_data_link(ax25_cb *); +extern void ax25_std_transmit_enquiry(ax25_cb *); +extern void ax25_std_enquiry_response(ax25_cb *); +extern void ax25_std_timeout_response(ax25_cb *); + +/* ax25_std_timer.c */ +extern void ax25_std_heartbeat_expiry(ax25_cb *); +extern void ax25_std_t1timer_expiry(ax25_cb *); +extern void ax25_std_t2timer_expiry(ax25_cb *); +extern void ax25_std_t3timer_expiry(ax25_cb *); +extern void ax25_std_idletimer_expiry(ax25_cb *); + +/* ax25_subr.c */ +extern void ax25_clear_queues(ax25_cb *); +extern void ax25_frames_acked(ax25_cb *, unsigned short); +extern void ax25_requeue_frames(ax25_cb *); +extern int ax25_validate_nr(ax25_cb *, unsigned short); +extern int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *); +extern void ax25_send_control(ax25_cb *, int, int, int); +extern void ax25_return_dm(struct net_device *, ax25_address *, ax25_address *, ax25_digi *); +extern void ax25_calculate_t1(ax25_cb *); +extern void ax25_calculate_rtt(ax25_cb *); +extern void ax25_disconnect(ax25_cb *, int); + +/* ax25_timer.c */ +extern void ax25_start_heartbeat(ax25_cb *); +extern void ax25_start_t1timer(ax25_cb *); +extern void ax25_start_t2timer(ax25_cb *); +extern void ax25_start_t3timer(ax25_cb *); +extern void ax25_start_idletimer(ax25_cb *); +extern void ax25_stop_heartbeat(ax25_cb *); +extern void ax25_stop_t1timer(ax25_cb *); +extern void ax25_stop_t2timer(ax25_cb *); +extern void ax25_stop_t3timer(ax25_cb *); +extern void ax25_stop_idletimer(ax25_cb *); +extern int ax25_t1timer_running(ax25_cb *); +extern unsigned long ax25_display_timer(struct timer_list *); + +/* ax25_uid.c */ +extern int ax25_uid_policy; +extern ax25_address *ax25_findbyuid(uid_t); +extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); +extern int ax25_uid_get_info(char *, char **, off_t, int); +extern void ax25_uid_free(void); + +/* sysctl_net_ax25.c */ +#ifdef CONFIG_SYSCTL +extern void ax25_register_sysctl(void); +extern void ax25_unregister_sysctl(void); +#else +extern inline void ax25_register_sysctl(void) {}; +extern inline void ax25_unregister_sysctl(void) {}; +#endif /* CONFIG_SYSCTL */ + +#endif diff --git a/release/src/linux/linux/include/net/bluetooth/bluetooth.h b/release/src/linux/linux/include/net/bluetooth/bluetooth.h new file mode 100644 index 00000000..acbef9a8 --- /dev/null +++ b/release/src/linux/linux/include/net/bluetooth/bluetooth.h @@ -0,0 +1,219 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id: bluetooth.h,v 1.1.1.4 2003/10/14 08:09:29 sparq Exp $ + */ + +#ifndef __BLUETOOTH_H +#define __BLUETOOTH_H + +#include <asm/types.h> +#include <asm/byteorder.h> +#include <linux/poll.h> +#include <net/sock.h> + +#ifndef AF_BLUETOOTH +#define AF_BLUETOOTH 31 +#define PF_BLUETOOTH AF_BLUETOOTH +#endif + +/* Reserv for core and drivers use */ +#define BLUEZ_SKB_RESERVE 8 + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define BTPROTO_L2CAP 0 +#define BTPROTO_HCI 1 +#define BTPROTO_SCO 2 +#define BTPROTO_RFCOMM 3 +#define BTPROTO_BNEP 4 + +#define SOL_HCI 0 +#define SOL_L2CAP 6 +#define SOL_SCO 17 +#define SOL_RFCOMM 18 + +/* Debugging */ +#ifdef CONFIG_BLUEZ_DEBUG + +#define HCI_CORE_DEBUG 1 +#define HCI_SOCK_DEBUG 1 +#define HCI_UART_DEBUG 1 +#define HCI_USB_DEBUG 1 +//#define HCI_DATA_DUMP 1 + +#define L2CAP_DEBUG 1 +#define SCO_DEBUG 1 +#define AF_BLUETOOTH_DEBUG 1 + +#endif /* CONFIG_BLUEZ_DEBUG */ + +extern void bluez_dump(char *pref, __u8 *buf, int count); + +#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95 +#define __func__ __FUNCTION__ +#endif + +#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg) +#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg) +#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) + +#ifdef HCI_DATA_DUMP +#define BT_DMP(buf, len) bluez_dump(__func__, buf, len) +#else +#define BT_DMP(D...) +#endif + +/* Connection and socket states */ +enum { + BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ + BT_OPEN, + BT_BOUND, + BT_LISTEN, + BT_CONNECT, + BT_CONNECT2, + BT_CONFIG, + BT_DISCONN, + BT_CLOSED +}; + +/* Endianness conversions */ +#define htobs(a) __cpu_to_le16(a) +#define htobl(a) __cpu_to_le32(a) +#define btohs(a) __le16_to_cpu(a) +#define btohl(a) __le32_to_cpu(a) + +/* BD Address */ +typedef struct { + __u8 b[6]; +} __attribute__((packed)) bdaddr_t; + +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) + +/* Copy, swap, convert BD Address */ +static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2) +{ + return memcmp(ba1, ba2, sizeof(bdaddr_t)); +} +static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) +{ + memcpy(dst, src, sizeof(bdaddr_t)); +} + +void baswap(bdaddr_t *dst, bdaddr_t *src); +char *batostr(bdaddr_t *ba); +bdaddr_t *strtoba(char *str); + +/* Common socket structures and functions */ + +#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo) +#define bluez_sk(pi) ((struct sock *) \ + ((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo))) + +struct bluez_pinfo { + bdaddr_t src; + bdaddr_t dst; + + struct list_head accept_q; + struct sock *parent; +}; + +struct bluez_sock_list { + struct sock *head; + rwlock_t lock; +}; + +int bluez_sock_register(int proto, struct net_proto_family *ops); +int bluez_sock_unregister(int proto); +void bluez_sock_init(struct socket *sock, struct sock *sk); +void bluez_sock_link(struct bluez_sock_list *l, struct sock *s); +void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s); +int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm); +uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait); +int bluez_sock_w4_connect(struct sock *sk, int flags); + +void bluez_accept_enqueue(struct sock *parent, struct sock *sk); +struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock); + +/* Skb helpers */ +struct bluez_skb_cb { + int incomming; +}; +#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb)) + +static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how) +{ + struct sk_buff *skb; + + if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) { + skb_reserve(skb, BLUEZ_SKB_RESERVE); + bluez_cb(skb)->incomming = 0; + } + return skb; +} + +static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len, + int nb, int *err) +{ + struct sk_buff *skb; + + if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) { + skb_reserve(skb, BLUEZ_SKB_RESERVE); + bluez_cb(skb)->incomming = 0; + } + + return skb; +} + +static inline int skb_frags_no(struct sk_buff *skb) +{ + register struct sk_buff *frag = skb_shinfo(skb)->frag_list; + register int n = 1; + + for (; frag; frag=frag->next, n++); + return n; +} + +int hci_core_init(void); +int hci_core_cleanup(void); +int hci_sock_init(void); +int hci_sock_cleanup(void); + +int bterr(__u16 code); + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + +#ifndef list_for_each_safe +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) +#endif + +#endif /* __BLUETOOTH_H */ diff --git a/release/src/linux/linux/include/net/bluetooth/hci.h b/release/src/linux/linux/include/net/bluetooth/hci.h new file mode 100644 index 00000000..6e853f85 --- /dev/null +++ b/release/src/linux/linux/include/net/bluetooth/hci.h @@ -0,0 +1,769 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id: hci.h,v 1.1.1.4 2003/10/14 08:09:29 sparq Exp $ + */ + +#ifndef __HCI_H +#define __HCI_H + +#define HCI_MAX_ACL_SIZE 1024 +#define HCI_MAX_SCO_SIZE 255 +#define HCI_MAX_EVENT_SIZE 260 +#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) + +/* HCI dev events */ +#define HCI_DEV_REG 1 +#define HCI_DEV_UNREG 2 +#define HCI_DEV_UP 3 +#define HCI_DEV_DOWN 4 + +/* HCI device types */ +#define HCI_VHCI 0 +#define HCI_USB 1 +#define HCI_PCCARD 2 +#define HCI_UART 3 +#define HCI_RS232 4 + +/* HCI device flags */ +enum { + HCI_UP, + HCI_INIT, + HCI_RUNNING, + + HCI_PSCAN, + HCI_ISCAN, + HCI_AUTH, + HCI_ENCRYPT, + HCI_INQUIRY, + + HCI_RAW +}; + +/* HCI ioctl defines */ +#define HCIDEVUP _IOW('H', 201, int) +#define HCIDEVDOWN _IOW('H', 202, int) +#define HCIDEVRESET _IOW('H', 203, int) +#define HCIDEVRESTAT _IOW('H', 204, int) + +#define HCIGETDEVLIST _IOR('H', 210, int) +#define HCIGETDEVINFO _IOR('H', 211, int) +#define HCIGETCONNLIST _IOR('H', 212, int) +#define HCIGETCONNINFO _IOR('H', 213, int) + +#define HCISETRAW _IOW('H', 220, int) +#define HCISETSCAN _IOW('H', 221, int) +#define HCISETAUTH _IOW('H', 222, int) +#define HCISETENCRYPT _IOW('H', 223, int) +#define HCISETPTYPE _IOW('H', 224, int) +#define HCISETLINKPOL _IOW('H', 225, int) +#define HCISETLINKMODE _IOW('H', 226, int) +#define HCISETACLMTU _IOW('H', 227, int) +#define HCISETSCOMTU _IOW('H', 228, int) + +#define HCIINQUIRY _IOR('H', 240, int) + +/* HCI timeouts */ +#define HCI_CONN_TIMEOUT (HZ * 40) +#define HCI_DISCONN_TIMEOUT (HZ * 2) +#define HCI_CONN_IDLE_TIMEOUT (HZ * 60) + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_UNKNOWN_PKT 0xff + +/* HCI Packet types */ +#define HCI_DM1 0x0008 +#define HCI_DM3 0x0400 +#define HCI_DM5 0x4000 +#define HCI_DH1 0x0010 +#define HCI_DH3 0x0800 +#define HCI_DH5 0x8000 + +#define HCI_HV1 0x0020 +#define HCI_HV2 0x0040 +#define HCI_HV3 0x0080 + +#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3) +#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK) + +/* ACL flags */ +#define ACL_CONT 0x01 +#define ACL_START 0x02 +#define ACL_ACTIVE_BCAST 0x04 +#define ACL_PICO_BCAST 0x08 + +/* Baseband links */ +#define SCO_LINK 0x00 +#define ACL_LINK 0x01 + +/* LMP features */ +#define LMP_3SLOT 0x01 +#define LMP_5SLOT 0x02 +#define LMP_ENCRYPT 0x04 +#define LMP_SOFFSET 0x08 +#define LMP_TACCURACY 0x10 +#define LMP_RSWITCH 0x20 +#define LMP_HOLD 0x40 +#define LMP_SNIF 0x80 + +#define LMP_PARK 0x01 +#define LMP_RSSI 0x02 +#define LMP_QUALITY 0x04 +#define LMP_SCO 0x08 +#define LMP_HV2 0x10 +#define LMP_HV3 0x20 +#define LMP_ULAW 0x40 +#define LMP_ALAW 0x80 + +#define LMP_CVSD 0x01 +#define LMP_PSCHEME 0x02 +#define LMP_PCONTROL 0x04 + +/* Link policies */ +#define HCI_LP_RSWITCH 0x0001 +#define HCI_LP_HOLD 0x0002 +#define HCI_LP_SNIFF 0x0004 +#define HCI_LP_PARK 0x0008 + +/* Link mode */ +#define HCI_LM_ACCEPT 0x8000 +#define HCI_LM_MASTER 0x0001 +#define HCI_LM_AUTH 0x0002 +#define HCI_LM_ENCRYPT 0x0004 +#define HCI_LM_TRUSTED 0x0008 + +/* ----- HCI Commands ----- */ +/* OGF & OCF values */ + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef struct { + __u8 status; + __u8 hci_ver; + __u16 hci_rev; + __u8 lmp_ver; + __u16 manufacturer; + __u16 lmp_subver; +} __attribute__ ((packed)) read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_FEATURES 0x0003 +typedef struct { + __u8 status; + __u8 features[8]; +} __attribute__ ((packed)) read_local_features_rp; + +#define OCF_READ_BUFFER_SIZE 0x0005 +typedef struct { + __u8 status; + __u16 acl_mtu; + __u8 sco_mtu; + __u16 acl_max_pkt; + __u16 sco_max_pkt; +} __attribute__ ((packed)) read_buffer_size_rp; + +#define OCF_READ_BD_ADDR 0x0009 +typedef struct { + __u8 status; + bdaddr_t bdaddr; +} __attribute__ ((packed)) read_bd_addr_rp; + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 +#define OCF_RESET 0x0003 +#define OCF_READ_AUTH_ENABLE 0x001F +#define OCF_WRITE_AUTH_ENABLE 0x0020 + #define AUTH_DISABLED 0x00 + #define AUTH_ENABLED 0x01 + +#define OCF_READ_ENCRYPT_MODE 0x0021 +#define OCF_WRITE_ENCRYPT_MODE 0x0022 + #define ENCRYPT_DISABLED 0x00 + #define ENCRYPT_P2P 0x01 + #define ENCRYPT_BOTH 0x02 + +#define OCF_WRITE_CA_TIMEOUT 0x0016 +#define OCF_WRITE_PG_TIMEOUT 0x0018 + +#define OCF_WRITE_SCAN_ENABLE 0x001A + #define SCAN_DISABLED 0x00 + #define SCAN_INQUIRY 0x01 + #define SCAN_PAGE 0x02 + +#define OCF_SET_EVENT_FLT 0x0005 +typedef struct { + __u8 flt_type; + __u8 cond_type; + __u8 condition[0]; +} __attribute__ ((packed)) set_event_flt_cp; +#define SET_EVENT_FLT_CP_SIZE 2 + +/* Filter types */ +#define FLT_CLEAR_ALL 0x00 +#define FLT_INQ_RESULT 0x01 +#define FLT_CONN_SETUP 0x02 + +/* CONN_SETUP Condition types */ +#define CONN_SETUP_ALLOW_ALL 0x00 +#define CONN_SETUP_ALLOW_CLASS 0x01 +#define CONN_SETUP_ALLOW_BDADDR 0x02 + +/* CONN_SETUP Conditions */ +#define CONN_SETUP_AUTO_OFF 0x01 +#define CONN_SETUP_AUTO_ON 0x02 + +#define OCF_CHANGE_LOCAL_NAME 0x0013 +typedef struct { + __u8 name[248]; +} __attribute__ ((packed)) change_local_name_cp; +#define CHANGE_LOCAL_NAME_CP_SIZE 248 + +#define OCF_READ_LOCAL_NAME 0x0014 +typedef struct { + __u8 status; + __u8 name[248]; +} __attribute__ ((packed)) read_local_name_rp; +#define READ_LOCAL_NAME_RP_SIZE 249 + +#define OCF_READ_CLASS_OF_DEV 0x0023 +typedef struct { + __u8 status; + __u8 dev_class[3]; +} __attribute__ ((packed)) read_class_of_dev_rp; +#define READ_CLASS_OF_DEV_RP_SIZE 4 + +#define OCF_WRITE_CLASS_OF_DEV 0x0024 +typedef struct { + __u8 dev_class[3]; +} __attribute__ ((packed)) write_class_of_dev_cp; +#define WRITE_CLASS_OF_DEV_CP_SIZE 3 + +#define OCF_HOST_BUFFER_SIZE 0x0033 +typedef struct { + __u16 acl_mtu; + __u8 sco_mtu; + __u16 acl_max_pkt; + __u16 sco_max_pkt; +} __attribute__ ((packed)) host_buffer_size_cp; +#define HOST_BUFFER_SIZE_CP_SIZE 7 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 +#define OCF_CREATE_CONN 0x0005 +typedef struct { + bdaddr_t bdaddr; + __u16 pkt_type; + __u8 pscan_rep_mode; + __u8 pscan_mode; + __u16 clock_offset; + __u8 role_switch; +} __attribute__ ((packed)) create_conn_cp; +#define CREATE_CONN_CP_SIZE 13 + +#define OCF_ACCEPT_CONN_REQ 0x0009 +typedef struct { + bdaddr_t bdaddr; + __u8 role; +} __attribute__ ((packed)) accept_conn_req_cp; +#define ACCEPT_CONN_REQ_CP_SIZE 7 + +#define OCF_REJECT_CONN_REQ 0x000a +typedef struct { + bdaddr_t bdaddr; + __u8 reason; +} __attribute__ ((packed)) reject_conn_req_cp; +#define REJECT_CONN_REQ_CP_SIZE 7 + +#define OCF_DISCONNECT 0x0006 +typedef struct { + __u16 handle; + __u8 reason; +} __attribute__ ((packed)) disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +#define OCF_ADD_SCO 0x0007 +typedef struct { + __u16 handle; + __u16 pkt_type; +} __attribute__ ((packed)) add_sco_cp; +#define ADD_SCO_CP_SIZE 4 + +#define OCF_INQUIRY 0x0001 +typedef struct { + __u8 lap[3]; + __u8 length; + __u8 num_rsp; +} __attribute__ ((packed)) inquiry_cp; +#define INQUIRY_CP_SIZE 5 + +typedef struct { + __u8 status; + bdaddr_t bdaddr; +} __attribute__ ((packed)) status_bdaddr_rp; +#define STATUS_BDADDR_RP_SIZE 7 + +#define OCF_LINK_KEY_REPLY 0x000B +#define OCF_LINK_KEY_NEG_REPLY 0x000C +typedef struct { + bdaddr_t bdaddr; + __u8 link_key[16]; +} __attribute__ ((packed)) link_key_reply_cp; +#define LINK_KEY_REPLY_CP_SIZE 22 + +#define OCF_PIN_CODE_REPLY 0x000D +#define OCF_PIN_CODE_NEG_REPLY 0x000E +typedef struct { + bdaddr_t bdaddr; + __u8 pin_len; + __u8 pin_code[16]; +} __attribute__ ((packed)) pin_code_reply_cp; +#define PIN_CODE_REPLY_CP_SIZE 23 + +#define OCF_CHANGE_CONN_PTYPE 0x000F +typedef struct { + __u16 handle; + __u16 pkt_type; +} __attribute__ ((packed)) change_conn_ptype_cp; +#define CHANGE_CONN_PTYPE_CP_SIZE 4 + +#define OCF_AUTH_REQUESTED 0x0011 +typedef struct { + __u16 handle; +} __attribute__ ((packed)) auth_requested_cp; +#define AUTH_REQUESTED_CP_SIZE 2 + +#define OCF_SET_CONN_ENCRYPT 0x0013 +typedef struct { + __u16 handle; + __u8 encrypt; +} __attribute__ ((packed)) set_conn_encrypt_cp; +#define SET_CONN_ENCRYPT_CP_SIZE 3 + +#define OCF_REMOTE_NAME_REQ 0x0019 +typedef struct { + bdaddr_t bdaddr; + __u8 pscan_rep_mode; + __u8 pscan_mode; + __u16 clock_offset; +} __attribute__ ((packed)) remote_name_req_cp; +#define REMOTE_NAME_REQ_CP_SIZE 10 + +#define OCF_READ_REMOTE_FEATURES 0x001B +typedef struct { + __u16 handle; +} __attribute__ ((packed)) read_remote_features_cp; +#define READ_REMOTE_FEATURES_CP_SIZE 2 + +#define OCF_READ_REMOTE_VERSION 0x001D +typedef struct { + __u16 handle; +} __attribute__ ((packed)) read_remote_version_cp; +#define READ_REMOTE_VERSION_CP_SIZE 2 + +/* Link Policy */ +#define OGF_LINK_POLICY 0x02 +#define OCF_ROLE_DISCOVERY 0x0009 +typedef struct { + __u16 handle; +} __attribute__ ((packed)) role_discovery_cp; +#define ROLE_DISCOVERY_CP_SIZE 2 +typedef struct { + __u8 status; + __u16 handle; + __u8 role; +} __attribute__ ((packed)) role_discovery_rp; +#define ROLE_DISCOVERY_RP_SIZE 4 + +#define OCF_READ_LINK_POLICY 0x000C +typedef struct { + __u16 handle; +} __attribute__ ((packed)) read_link_policy_cp; +#define READ_LINK_POLICY_CP_SIZE 2 +typedef struct { + __u8 status; + __u16 handle; + __u16 policy; +} __attribute__ ((packed)) read_link_policy_rp; +#define READ_LINK_POLICY_RP_SIZE 5 + +#define OCF_SWITCH_ROLE 0x000B +typedef struct { + bdaddr_t bdaddr; + __u8 role; +} __attribute__ ((packed)) switch_role_cp; +#define SWITCH_ROLE_CP_SIZE 7 + +#define OCF_WRITE_LINK_POLICY 0x000D +typedef struct { + __u16 handle; + __u16 policy; +} __attribute__ ((packed)) write_link_policy_cp; +#define WRITE_LINK_POLICY_CP_SIZE 4 +typedef struct { + __u8 status; + __u16 handle; +} __attribute__ ((packed)) write_link_policy_rp; +#define WRITE_LINK_POLICY_RP_SIZE 3 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +/* ---- HCI Events ---- */ +#define EVT_INQUIRY_COMPLETE 0x01 + +#define EVT_INQUIRY_RESULT 0x02 +typedef struct { + bdaddr_t bdaddr; + __u8 pscan_rep_mode; + __u8 pscan_period_mode; + __u8 pscan_mode; + __u8 dev_class[3]; + __u16 clock_offset; +} __attribute__ ((packed)) inquiry_info; +#define INQUIRY_INFO_SIZE 14 + +#define EVT_CONN_COMPLETE 0x03 +typedef struct { + __u8 status; + __u16 handle; + bdaddr_t bdaddr; + __u8 link_type; + __u8 encr_mode; +} __attribute__ ((packed)) evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_CONN_REQUEST 0x04 +typedef struct { + bdaddr_t bdaddr; + __u8 dev_class[3]; + __u8 link_type; +} __attribute__ ((packed)) evt_conn_request; +#define EVT_CONN_REQUEST_SIZE 10 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef struct { + __u8 status; + __u16 handle; + __u8 reason; +} __attribute__ ((packed)) evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_AUTH_COMPLETE 0x06 +typedef struct { + __u8 status; + __u16 handle; +} __attribute__ ((packed)) evt_auth_complete; +#define EVT_AUTH_COMPLETE_SIZE 3 + +#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07 +typedef struct { + __u8 status; + bdaddr_t bdaddr; + __u8 name[248]; +} __attribute__ ((packed)) evt_remote_name_req_complete; +#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef struct { + __u8 status; + __u16 handle; + __u8 encrypt; +} __attribute__ ((packed)) evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_QOS_SETUP_COMPLETE 0x0D +typedef struct { + __u8 service_type; + __u32 token_rate; + __u32 peak_bandwidth; + __u32 latency; + __u32 delay_variation; +} __attribute__ ((packed)) hci_qos; +typedef struct { + __u8 status; + __u16 handle; + hci_qos qos; +} __attribute__ ((packed)) evt_qos_setup_complete; +#define EVT_QOS_SETUP_COMPLETE_SIZE 20 + +#define EVT_CMD_COMPLETE 0x0e +typedef struct { + __u8 ncmd; + __u16 opcode; +} __attribute__ ((packed)) evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0f +typedef struct { + __u8 status; + __u8 ncmd; + __u16 opcode; +} __attribute__ ((packed)) evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef struct { + __u8 num_hndl; + /* variable length part */ +} __attribute__ ((packed)) evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +#define EVT_ROLE_CHANGE 0x12 +typedef struct { + __u8 status; + bdaddr_t bdaddr; + __u8 role; +} __attribute__ ((packed)) evt_role_change; +#define EVT_ROLE_CHANGE_SIZE 1 + +#define EVT_PIN_CODE_REQ 0x16 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) evt_pin_code_req; +#define EVT_PIN_CODE_REQ_SIZE 6 + +#define EVT_LINK_KEY_REQ 0x17 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) evt_link_key_req; +#define EVT_LINK_KEY_REQ_SIZE 6 + +#define EVT_LINK_KEY_NOTIFY 0x18 +typedef struct { + bdaddr_t bdaddr; + __u8 link_key[16]; + __u8 key_type; +} __attribute__ ((packed)) evt_link_key_notify; +#define EVT_LINK_KEY_NOTIFY_SIZE 23 + +#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B +typedef struct { + __u8 status; + __u16 handle; + __u8 features[8]; +} __attribute__ ((packed)) evt_read_remote_features_complete; +#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C +typedef struct { + __u8 status; + __u16 handle; + __u8 lmp_ver; + __u16 manufacturer; + __u16 lmp_subver; +} __attribute__ ((packed)) evt_read_remote_version_complete; +#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8 + +/* Internal events generated by BlueZ stack */ +#define EVT_STACK_INTERNAL 0xfd +typedef struct { + __u16 type; + __u8 data[0]; +} __attribute__ ((packed)) evt_stack_internal; +#define EVT_STACK_INTERNAL_SIZE 2 + +#define EVT_SI_DEVICE 0x01 +typedef struct { + __u16 event; + __u16 dev_id; +} __attribute__ ((packed)) evt_si_device; +#define EVT_SI_DEVICE_SIZE 4 + +#define EVT_SI_SECURITY 0x02 +typedef struct { + __u16 event; + __u16 proto; + __u16 subproto; + __u8 incomming; +} __attribute__ ((packed)) evt_si_security; + +/* -------- HCI Packet structures -------- */ +#define HCI_TYPE_LEN 1 + +typedef struct { + __u16 opcode; /* OCF & OGF */ + __u8 plen; +} __attribute__ ((packed)) hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef struct { + __u8 evt; + __u8 plen; +} __attribute__ ((packed)) hci_event_hdr; +#define HCI_EVENT_HDR_SIZE 2 + +typedef struct { + __u16 handle; /* Handle & Flags(PB, BC) */ + __u16 dlen; +} __attribute__ ((packed)) hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +typedef struct { + __u16 handle; + __u8 dlen; +} __attribute__ ((packed)) hci_sco_hdr; +#define HCI_SCO_HDR_SIZE 3 + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (__u16)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + +/* ACL handle and flags pack/unpack */ +#define acl_handle_pack(h, f) (__u16)((h & 0x0fff)|(f << 12)) +#define acl_handle(h) (h & 0x0fff) +#define acl_flags(h) (h >> 12) + +/* HCI Socket options */ +#define HCI_DATA_DIR 1 +#define HCI_FILTER 2 +#define HCI_TIME_STAMP 3 + +/* HCI CMSG flags */ +#define HCI_CMSG_DIR 0x0001 +#define HCI_CMSG_TSTAMP 0x0002 + +struct sockaddr_hci { + sa_family_t hci_family; + unsigned short hci_dev; +}; +#define HCI_DEV_NONE 0xffff + +struct hci_filter { + __u32 type_mask; + __u32 event_mask[2]; + __u16 opcode; +}; + +#define HCI_FLT_TYPE_BITS 31 +#define HCI_FLT_EVENT_BITS 63 +#define HCI_FLT_OGF_BITS 63 +#define HCI_FLT_OCF_BITS 127 + +#if BITS_PER_LONG == 64 +static inline void hci_set_bit(int nr, void *addr) +{ + *((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31)); +} +static inline int hci_test_bit(int nr, void *addr) +{ + return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31)); +} +#else +#define hci_set_bit set_bit +#define hci_test_bit test_bit +#endif + +/* Ioctl requests structures */ +struct hci_dev_stats { + __u32 err_rx; + __u32 err_tx; + __u32 cmd_tx; + __u32 evt_rx; + __u32 acl_tx; + __u32 acl_rx; + __u32 sco_tx; + __u32 sco_rx; + __u32 byte_rx; + __u32 byte_tx; +}; + +struct hci_dev_info { + __u16 dev_id; + char name[8]; + + bdaddr_t bdaddr; + + __u32 flags; + __u8 type; + + __u8 features[8]; + + __u32 pkt_type; + __u32 link_policy; + __u32 link_mode; + + __u16 acl_mtu; + __u16 acl_pkts; + __u16 sco_mtu; + __u16 sco_pkts; + + struct hci_dev_stats stat; +}; + +struct hci_conn_info { + __u16 handle; + bdaddr_t bdaddr; + __u8 type; + __u8 out; + __u16 state; + __u32 link_mode; +}; + +struct hci_dev_req { + __u16 dev_id; + __u32 dev_opt; +}; + +struct hci_dev_list_req { + __u16 dev_num; + struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ +}; + +struct hci_conn_list_req { + __u16 dev_id; + __u16 conn_num; + struct hci_conn_info conn_info[0]; +}; + +struct hci_conn_info_req { + bdaddr_t bdaddr; + __u8 type; + struct hci_conn_info conn_info[0]; +}; + +struct hci_inquiry_req { + __u16 dev_id; + __u16 flags; + __u8 lap[3]; + __u8 length; + __u8 num_rsp; +}; +#define IREQ_CACHE_FLUSH 0x0001 + +struct hci_remotename_req { + __u16 dev_id; + __u16 flags; + bdaddr_t bdaddr; + __u8 name[248]; +}; + +#endif /* __HCI_H */ diff --git a/release/src/linux/linux/include/net/bluetooth/hci_core.h b/release/src/linux/linux/include/net/bluetooth/hci_core.h new file mode 100644 index 00000000..d7ee093d --- /dev/null +++ b/release/src/linux/linux/include/net/bluetooth/hci_core.h @@ -0,0 +1,470 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id: hci_core.h,v 1.1.1.4 2003/10/14 08:09:29 sparq Exp $ + */ + +#ifndef __HCI_CORE_H +#define __HCI_CORE_H + +#include <net/bluetooth/hci.h> + +/* HCI upper protocols */ +#define HCI_PROTO_L2CAP 0 +#define HCI_PROTO_SCO 1 + +#define HCI_INIT_TIMEOUT (HZ * 10) + +/* HCI Core structures */ + +struct inquiry_entry { + struct inquiry_entry *next; + __u32 timestamp; + inquiry_info info; +}; + +struct inquiry_cache { + spinlock_t lock; + __u32 timestamp; + struct inquiry_entry *list; +}; + +struct conn_hash { + struct list_head list; + spinlock_t lock; + unsigned int num; +}; + +struct hci_dev { + struct list_head list; + spinlock_t lock; + atomic_t refcnt; + + char name[8]; + unsigned long flags; + __u16 id; + __u8 type; + bdaddr_t bdaddr; + __u8 features[8]; + + __u16 pkt_type; + __u16 link_policy; + __u16 link_mode; + + atomic_t cmd_cnt; + unsigned int acl_cnt; + unsigned int sco_cnt; + + unsigned int acl_mtu; + unsigned int sco_mtu; + unsigned int acl_pkts; + unsigned int sco_pkts; + + unsigned long cmd_last_tx; + unsigned long acl_last_tx; + unsigned long sco_last_tx; + + struct tasklet_struct cmd_task; + struct tasklet_struct rx_task; + struct tasklet_struct tx_task; + + struct sk_buff_head rx_q; + struct sk_buff_head raw_q; + struct sk_buff_head cmd_q; + + struct sk_buff *sent_cmd; + + struct semaphore req_lock; + wait_queue_head_t req_wait_q; + __u32 req_status; + __u32 req_result; + + struct inquiry_cache inq_cache; + struct conn_hash conn_hash; + + struct hci_dev_stats stat; + + void *driver_data; + void *core_data; + + atomic_t promisc; + + int (*open)(struct hci_dev *hdev); + int (*close)(struct hci_dev *hdev); + int (*flush)(struct hci_dev *hdev); + int (*send)(struct sk_buff *skb); + void (*destruct)(struct hci_dev *hdev); + int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); +}; + +struct hci_conn { + struct list_head list; + + atomic_t refcnt; + spinlock_t lock; + + bdaddr_t dst; + __u16 handle; + __u16 state; + __u8 type; + __u8 out; + __u32 link_mode; + unsigned long pend; + + unsigned int sent; + + struct sk_buff_head data_q; + + struct timer_list timer; + + struct hci_dev *hdev; + void *l2cap_data; + void *sco_data; + void *priv; + + struct hci_conn *link; +}; + +extern struct hci_proto *hci_proto[]; +extern struct list_head hdev_list; +extern rwlock_t hdev_list_lock; + +/* ----- Inquiry cache ----- */ +#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds +#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds + +#define inquiry_cache_lock(c) spin_lock(&c->lock) +#define inquiry_cache_unlock(c) spin_unlock(&c->lock) +#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock) +#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock) + +static inline void inquiry_cache_init(struct hci_dev *hdev) +{ + struct inquiry_cache *c = &hdev->inq_cache; + spin_lock_init(&c->lock); + c->list = NULL; +} + +static inline long inquiry_cache_age(struct hci_dev *hdev) +{ + struct inquiry_cache *c = &hdev->inq_cache; + return jiffies - c->timestamp; +} + +static inline long inquiry_entry_age(struct inquiry_entry *e) +{ + return jiffies - e->timestamp; +} + +struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); +void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info); +void inquiry_cache_flush(struct hci_dev *hdev); +int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf); + +/* ----- HCI Connections ----- */ +enum { + HCI_CONN_AUTH_PEND, + HCI_CONN_ENCRYPT_PEND +}; + +#define hci_conn_lock(c) spin_lock(&c->lock) +#define hci_conn_unlock(c) spin_unlock(&c->lock) +#define hci_conn_lock_bh(c) spin_lock_bh(&c->lock) +#define hci_conn_unlock_bh(c) spin_unlock_bh(&c->lock) + +#define conn_hash_lock(d) spin_lock(&d->conn_hash->lock) +#define conn_hash_unlock(d) spin_unlock(&d->conn_hash->lock) +#define conn_hash_lock_bh(d) spin_lock_bh(&d->conn_hash->lock) +#define conn_hash_unlock_bh(d) spin_unlock_bh(&d->conn_hash->lock) + +static inline void conn_hash_init(struct hci_dev *hdev) +{ + struct conn_hash *h = &hdev->conn_hash; + INIT_LIST_HEAD(&h->list); + spin_lock_init(&h->lock); + h->num = 0; +} + +static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) +{ + struct conn_hash *h = &hdev->conn_hash; + list_add(&c->list, &h->list); + h->num++; +} + +static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) +{ + struct conn_hash *h = &hdev->conn_hash; + list_del(&c->list); + h->num--; +} + +static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev, + __u16 handle) +{ + register struct conn_hash *h = &hdev->conn_hash; + register struct list_head *p; + register struct hci_conn *c; + + list_for_each(p, &h->list) { + c = list_entry(p, struct hci_conn, list); + if (c->handle == handle) + return c; + } + return NULL; +} + +static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev, + __u8 type, bdaddr_t *ba) +{ + register struct conn_hash *h = &hdev->conn_hash; + register struct list_head *p; + register struct hci_conn *c; + + list_for_each(p, &h->list) { + c = list_entry(p, struct hci_conn, list); + if (c->type == type && !bacmp(&c->dst, ba)) + return c; + } + return NULL; +} + +void hci_acl_connect(struct hci_conn *conn); +void hci_acl_disconn(struct hci_conn *conn, __u8 reason); +void hci_add_sco(struct hci_conn *conn, __u16 handle); + +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); +int hci_conn_del(struct hci_conn *conn); +void hci_conn_hash_flush(struct hci_dev *hdev); + +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src); +int hci_conn_auth(struct hci_conn *conn); +int hci_conn_encrypt(struct hci_conn *conn); + +static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout) +{ + mod_timer(&conn->timer, jiffies + timeout); +} + +static inline void hci_conn_del_timer(struct hci_conn *conn) +{ + del_timer(&conn->timer); +} + +static inline void hci_conn_hold(struct hci_conn *conn) +{ + atomic_inc(&conn->refcnt); + hci_conn_del_timer(conn); +} + +static inline void hci_conn_put(struct hci_conn *conn) +{ + if (atomic_dec_and_test(&conn->refcnt) && conn->out) + hci_conn_set_timer(conn, HCI_DISCONN_TIMEOUT); +} + +/* ----- HCI Devices ----- */ +static inline void hci_dev_put(struct hci_dev *d) +{ + if (atomic_dec_and_test(&d->refcnt)) + d->destruct(d); +} +#define hci_dev_hold(d) atomic_inc(&d->refcnt) + +#define hci_dev_lock(d) spin_lock(&d->lock) +#define hci_dev_unlock(d) spin_unlock(&d->lock) +#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock) +#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock) + +struct hci_dev *hci_dev_get(int index); +struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); +int hci_register_dev(struct hci_dev *hdev); +int hci_unregister_dev(struct hci_dev *hdev); +int hci_dev_open(__u16 dev); +int hci_dev_close(__u16 dev); +int hci_dev_reset(__u16 dev); +int hci_dev_reset_stat(__u16 dev); +int hci_dev_cmd(unsigned int cmd, unsigned long arg); +int hci_get_dev_list(unsigned long arg); +int hci_get_dev_info(unsigned long arg); +int hci_get_conn_list(unsigned long arg); +int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg); +int hci_inquiry(unsigned long arg); + +int hci_recv_frame(struct sk_buff *skb); +void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); + +/* ----- LMP capabilities ----- */ +#define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH) +#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT) + +/* ----- HCI tasks ----- */ +static inline void hci_sched_cmd(struct hci_dev *hdev) +{ + tasklet_schedule(&hdev->cmd_task); +} + +static inline void hci_sched_rx(struct hci_dev *hdev) +{ + tasklet_schedule(&hdev->rx_task); +} + +static inline void hci_sched_tx(struct hci_dev *hdev) +{ + tasklet_schedule(&hdev->tx_task); +} + +/* ----- HCI protocols ----- */ +struct hci_proto { + char *name; + unsigned int id; + unsigned long flags; + + void *priv; + + int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); + int (*connect_cfm) (struct hci_conn *conn, __u8 status); + int (*disconn_ind) (struct hci_conn *conn, __u8 reason); + int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); + int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); + int (*auth_cfm) (struct hci_conn *conn, __u8 status); + int (*encrypt_cfm) (struct hci_conn *conn, __u8 status); +}; + +static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) +{ + register struct hci_proto *hp; + int mask = 0; + + hp = hci_proto[HCI_PROTO_L2CAP]; + if (hp && hp->connect_ind) + mask |= hp->connect_ind(hdev, bdaddr, type); + + hp = hci_proto[HCI_PROTO_SCO]; + if (hp && hp->connect_ind) + mask |= hp->connect_ind(hdev, bdaddr, type); + + return mask; +} + +static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) +{ + register struct hci_proto *hp; + + hp = hci_proto[HCI_PROTO_L2CAP]; + if (hp && hp->connect_cfm) + hp->connect_cfm(conn, status); + + hp = hci_proto[HCI_PROTO_SCO]; + if (hp && hp->connect_cfm) + hp->connect_cfm(conn, status); +} + +static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason) +{ + register struct hci_proto *hp; + + hp = hci_proto[HCI_PROTO_L2CAP]; + if (hp && hp->disconn_ind) + hp->disconn_ind(conn, reason); + + hp = hci_proto[HCI_PROTO_SCO]; + if (hp && hp->disconn_ind) + hp->disconn_ind(conn, reason); +} + +static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) +{ + register struct hci_proto *hp; + + hp = hci_proto[HCI_PROTO_L2CAP]; + if (hp && hp->auth_cfm) + hp->auth_cfm(conn, status); + + hp = hci_proto[HCI_PROTO_SCO]; + if (hp && hp->auth_cfm) + hp->auth_cfm(conn, status); +} + +static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status) +{ + register struct hci_proto *hp; + + hp = hci_proto[HCI_PROTO_L2CAP]; + if (hp && hp->encrypt_cfm) + hp->encrypt_cfm(conn, status); + + hp = hci_proto[HCI_PROTO_SCO]; + if (hp && hp->encrypt_cfm) + hp->encrypt_cfm(conn, status); +} + +int hci_register_proto(struct hci_proto *hproto); +int hci_unregister_proto(struct hci_proto *hproto); +int hci_register_notifier(struct notifier_block *nb); +int hci_unregister_notifier(struct notifier_block *nb); + +int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param); +int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags); +int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); +int hci_send_raw(struct sk_buff *skb); + +void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf); + +void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); + +/* ----- HCI Sockets ----- */ +void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); + +/* HCI info for socket */ +#define hci_pi(sk) ((struct hci_pinfo *) &sk->tp_pinfo) +struct hci_pinfo { + struct hci_dev *hdev; + struct hci_filter filter; + __u32 cmsg_mask; +}; + +/* HCI security filter */ +#define HCI_SFLT_MAX_OGF 4 + +struct hci_sec_filter { + __u32 type_mask; + __u32 event_mask[2]; + __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4]; +}; + + +/* ----- HCI requests ----- */ +#define HCI_REQ_DONE 0 +#define HCI_REQ_PEND 1 +#define HCI_REQ_CANCELED 2 + +#define hci_req_lock(d) down(&d->req_lock) +#define hci_req_unlock(d) up(&d->req_lock) + +void hci_req_complete(struct hci_dev *hdev, int result); +void hci_req_cancel(struct hci_dev *hdev, int err); + +#endif /* __HCI_CORE_H */ diff --git a/release/src/linux/linux/include/net/bluetooth/l2cap.h b/release/src/linux/linux/include/net/bluetooth/l2cap.h new file mode 100644 index 00000000..dd9fec6f --- /dev/null +++ b/release/src/linux/linux/include/net/bluetooth/l2cap.h @@ -0,0 +1,245 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id: l2cap.h,v 1.1.1.4 2003/10/14 08:09:29 sparq Exp $ + */ + +#ifndef __L2CAP_H +#define __L2CAP_H + +/* L2CAP defaults */ +#define L2CAP_DEFAULT_MTU 672 +#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF + +#define L2CAP_CONN_TIMEOUT (HZ * 40) + +/* L2CAP socket address */ +struct sockaddr_l2 { + sa_family_t l2_family; + unsigned short l2_psm; + bdaddr_t l2_bdaddr; +}; + +/* Socket options */ +#define L2CAP_OPTIONS 0x01 +struct l2cap_options { + __u16 omtu; + __u16 imtu; + __u16 flush_to; +}; + +#define L2CAP_CONNINFO 0x02 +struct l2cap_conninfo { + __u16 hci_handle; +}; + +#define L2CAP_LM 0x03 +#define L2CAP_LM_MASTER 0x0001 +#define L2CAP_LM_AUTH 0x0002 +#define L2CAP_LM_ENCRYPT 0x0004 +#define L2CAP_LM_TRUSTED 0x0008 + +#define L2CAP_QOS 0x04 +struct l2cap_qos { + __u16 service_type; + __u32 token_rate; + __u32 token_bucket_size; + __u32 peak_bandwidth; + __u32 latency; + __u32 delay_variation; +}; + +#define L2CAP_SERV_NO_TRAFFIC 0x00 +#define L2CAP_SERV_BEST_EFFORT 0x01 +#define L2CAP_SERV_GUARANTEED 0x02 + +/* L2CAP command codes */ +#define L2CAP_COMMAND_REJ 0x01 +#define L2CAP_CONN_REQ 0x02 +#define L2CAP_CONN_RSP 0x03 +#define L2CAP_CONF_REQ 0x04 +#define L2CAP_CONF_RSP 0x05 +#define L2CAP_DISCONN_REQ 0x06 +#define L2CAP_DISCONN_RSP 0x07 +#define L2CAP_ECHO_REQ 0x08 +#define L2CAP_ECHO_RSP 0x09 +#define L2CAP_INFO_REQ 0x0a +#define L2CAP_INFO_RSP 0x0b + +/* L2CAP structures */ +typedef struct { + __u16 len; + __u16 cid; +} __attribute__ ((packed)) l2cap_hdr; +#define L2CAP_HDR_SIZE 4 + +typedef struct { + __u8 code; + __u8 ident; + __u16 len; +} __attribute__ ((packed)) l2cap_cmd_hdr; +#define L2CAP_CMD_HDR_SIZE 4 + +typedef struct { + __u16 reason; +} __attribute__ ((packed)) l2cap_cmd_rej; +#define L2CAP_CMD_REJ_SIZE 2 + +typedef struct { + __u16 psm; + __u16 scid; +} __attribute__ ((packed)) l2cap_conn_req; +#define L2CAP_CONN_REQ_SIZE 4 + +typedef struct { + __u16 dcid; + __u16 scid; + __u16 result; + __u16 status; +} __attribute__ ((packed)) l2cap_conn_rsp; +#define L2CAP_CONN_RSP_SIZE 8 + +/* connect result */ +#define L2CAP_CR_SUCCESS 0x0000 +#define L2CAP_CR_PEND 0x0001 +#define L2CAP_CR_BAD_PSM 0x0002 +#define L2CAP_CR_SEC_BLOCK 0x0003 +#define L2CAP_CR_NO_MEM 0x0004 + +/* connect status */ +#define L2CAP_CS_NO_INFO 0x0000 +#define L2CAP_CS_AUTHEN_PEND 0x0001 +#define L2CAP_CS_AUTHOR_PEND 0x0002 + +typedef struct { + __u16 dcid; + __u16 flags; + __u8 data[0]; +} __attribute__ ((packed)) l2cap_conf_req; +#define L2CAP_CONF_REQ_SIZE 4 + +typedef struct { + __u16 scid; + __u16 flags; + __u16 result; + __u8 data[0]; +} __attribute__ ((packed)) l2cap_conf_rsp; +#define L2CAP_CONF_RSP_SIZE 6 + +#define L2CAP_CONF_SUCCESS 0x00 +#define L2CAP_CONF_UNACCEPT 0x01 + +typedef struct { + __u8 type; + __u8 len; + __u8 val[0]; +} __attribute__ ((packed)) l2cap_conf_opt; +#define L2CAP_CONF_OPT_SIZE 2 + +#define L2CAP_CONF_MTU 0x01 +#define L2CAP_CONF_FLUSH_TO 0x02 +#define L2CAP_CONF_QOS 0x03 + +#define L2CAP_CONF_MAX_SIZE 22 + +typedef struct { + __u16 dcid; + __u16 scid; +} __attribute__ ((packed)) l2cap_disconn_req; +#define L2CAP_DISCONN_REQ_SIZE 4 + +typedef struct { + __u16 dcid; + __u16 scid; +} __attribute__ ((packed)) l2cap_disconn_rsp; +#define L2CAP_DISCONN_RSP_SIZE 4 + +typedef struct { + __u16 type; + __u8 data[0]; +} __attribute__ ((packed)) l2cap_info_req; +#define L2CAP_INFO_REQ_SIZE 2 + +typedef struct { + __u16 type; + __u16 result; + __u8 data[0]; +} __attribute__ ((packed)) l2cap_info_rsp; +#define L2CAP_INFO_RSP_SIZE 4 + +/* ----- L2CAP connections ----- */ +struct l2cap_chan_list { + struct sock *head; + rwlock_t lock; + long num; +}; + +struct l2cap_conn { + struct hci_conn *hcon; + + bdaddr_t *dst; + bdaddr_t *src; + + unsigned int mtu; + + spinlock_t lock; + + struct sk_buff *rx_skb; + __u32 rx_len; + __u8 rx_ident; + __u8 tx_ident; + + struct l2cap_chan_list chan_list; +}; + +/* ----- L2CAP channel and socket info ----- */ +#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->tp_pinfo) + +struct l2cap_pinfo { + __u16 psm; + __u16 dcid; + __u16 scid; + + __u16 imtu; + __u16 omtu; + __u16 flush_to; + + __u32 link_mode; + + __u8 conf_state; + __u16 conf_mtu; + + __u8 ident; + + struct l2cap_conn *conn; + struct sock *next_c; + struct sock *prev_c; +}; + +#define CONF_REQ_SENT 0x01 +#define CONF_INPUT_DONE 0x02 +#define CONF_OUTPUT_DONE 0x04 + +#endif /* __L2CAP_H */ diff --git a/release/src/linux/linux/include/net/bluetooth/sco.h b/release/src/linux/linux/include/net/bluetooth/sco.h new file mode 100644 index 00000000..28427675 --- /dev/null +++ b/release/src/linux/linux/include/net/bluetooth/sco.h @@ -0,0 +1,81 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id: sco.h,v 1.1.1.4 2003/10/14 08:09:29 sparq Exp $ + */ + +#ifndef __SCO_H +#define __SCO_H + +/* SCO defaults */ +#define SCO_DEFAULT_MTU 500 +#define SCO_DEFAULT_FLUSH_TO 0xFFFF + +#define SCO_CONN_TIMEOUT (HZ * 40) +#define SCO_DISCONN_TIMEOUT (HZ * 2) +#define SCO_CONN_IDLE_TIMEOUT (HZ * 60) + +/* SCO socket address */ +struct sockaddr_sco { + sa_family_t sco_family; + bdaddr_t sco_bdaddr; +}; + +/* set/get sockopt defines */ +#define SCO_OPTIONS 0x01 +struct sco_options { + __u16 mtu; +}; + +#define SCO_CONNINFO 0x02 +struct sco_conninfo { + __u16 hci_handle; +}; + +/* ---- SCO connections ---- */ +struct sco_conn { + struct hci_conn *hcon; + + bdaddr_t *dst; + bdaddr_t *src; + + spinlock_t lock; + struct sock *sk; + + unsigned int mtu; +}; + +#define sco_conn_lock(c) spin_lock(&c->lock); +#define sco_conn_unlock(c) spin_unlock(&c->lock); + +/* ----- SCO socket info ----- */ +#define sco_pi(sk) ((struct sco_pinfo *) &sk->tp_pinfo) + +struct sco_pinfo { + __u32 flags; + struct sco_conn *conn; +}; + +#endif /* __SCO_H */ diff --git a/release/src/linux/linux/include/net/checksum.h b/release/src/linux/linux/include/net/checksum.h new file mode 100644 index 00000000..6a16809c --- /dev/null +++ b/release/src/linux/linux/include/net/checksum.h @@ -0,0 +1,154 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Checksumming functions for IP, TCP, UDP and so on + * + * Authors: Jorge Cwik, <jorge@laser.satlink.net> + * Arnt Gulbrandsen, <agulbra@nvg.unit.no> + * Borrows very liberally from tcp.c and ip.c, see those + * files for more names. + * + * 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. + */ + +/* + * Fixes: + * + * Ralf Baechle : generic ipv6 checksum + * <ralf@waldorf-gmbh.de> + */ + +#ifndef _CHECKSUM_H +#define _CHECKSUM_H + +#include <asm/types.h> +#include <asm/byteorder.h> +#include <net/ip.h> +#include <asm/uaccess.h> +#include <asm/checksum.h> + +#ifndef _HAVE_ARCH_IPV6_CSUM + +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int csum) +{ + + int carry; + __u32 ulen; + __u32 uproto; + + csum += saddr->s6_addr32[0]; + carry = (csum < saddr->s6_addr32[0]); + csum += carry; + + csum += saddr->s6_addr32[1]; + carry = (csum < saddr->s6_addr32[1]); + csum += carry; + + csum += saddr->s6_addr32[2]; + carry = (csum < saddr->s6_addr32[2]); + csum += carry; + + csum += saddr->s6_addr32[3]; + carry = (csum < saddr->s6_addr32[3]); + csum += carry; + + csum += daddr->s6_addr32[0]; + carry = (csum < daddr->s6_addr32[0]); + csum += carry; + + csum += daddr->s6_addr32[1]; + carry = (csum < daddr->s6_addr32[1]); + csum += carry; + + csum += daddr->s6_addr32[2]; + carry = (csum < daddr->s6_addr32[2]); + csum += carry; + + csum += daddr->s6_addr32[3]; + carry = (csum < daddr->s6_addr32[3]); + csum += carry; + + ulen = htonl((__u32) len); + csum += ulen; + carry = (csum < ulen); + csum += carry; + + uproto = htonl(proto); + csum += uproto; + carry = (csum < uproto); + csum += carry; + + return csum_fold(csum); +} + +#endif + +#ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER +static inline +unsigned int csum_and_copy_from_user (const char *src, char *dst, + int len, int sum, int *err_ptr) +{ + if (verify_area(VERIFY_READ, src, len) == 0) + return csum_partial_copy_from_user(src, dst, len, sum, err_ptr); + + if (len) + *err_ptr = -EFAULT; + + return sum; +} +#endif + +#ifndef HAVE_CSUM_COPY_USER +static __inline__ unsigned int csum_and_copy_to_user +(const char *src, char *dst, int len, unsigned int sum, int *err_ptr) +{ + sum = csum_partial(src, len, sum); + + if (access_ok(VERIFY_WRITE, dst, len)) { + if (copy_to_user(dst, src, len) == 0) + return sum; + } + if (len) + *err_ptr = -EFAULT; + + return -1; /* invalid checksum */ +} +#endif + +static inline unsigned int csum_add(unsigned int csum, unsigned int addend) +{ + csum += addend; + return csum + (csum < addend); +} + +static inline unsigned int csum_sub(unsigned int csum, unsigned int addend) +{ + return csum_add(csum, ~addend); +} + +static inline unsigned int +csum_block_add(unsigned int csum, unsigned int csum2, int offset) +{ + if (offset&1) + csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF); + return csum_add(csum, csum2); +} + +static inline unsigned int +csum_block_sub(unsigned int csum, unsigned int csum2, int offset) +{ + if (offset&1) + csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF); + return csum_sub(csum, csum2); +} + +#endif diff --git a/release/src/linux/linux/include/net/datalink.h b/release/src/linux/linux/include/net/datalink.h new file mode 100644 index 00000000..d07c21af --- /dev/null +++ b/release/src/linux/linux/include/net/datalink.h @@ -0,0 +1,16 @@ +#ifndef _NET_INET_DATALINK_H_ +#define _NET_INET_DATALINK_H_ + +struct datalink_proto { + unsigned short type_len; + unsigned char type[8]; + const char *string_name; + unsigned short header_length; + int (*rcvfunc)(struct sk_buff *, struct net_device *, + struct packet_type *); + void (*datalink_header)(struct datalink_proto *, struct sk_buff *, + unsigned char *); + struct datalink_proto *next; +}; + +#endif diff --git a/release/src/linux/linux/include/net/dn.h b/release/src/linux/linux/include/net/dn.h new file mode 100644 index 00000000..a88b6f5e --- /dev/null +++ b/release/src/linux/linux/include/net/dn.h @@ -0,0 +1,222 @@ +#ifndef _NET_DN_H +#define _NET_DN_H + +#include <linux/dn.h> +#include <asm/byteorder.h> + +typedef unsigned short dn_address; + +#define dn_ntohs(x) le16_to_cpu((unsigned short)(x)) +#define dn_htons(x) cpu_to_le16((unsigned short)(x)) + +#define DN_SK(sk) (&sk->protinfo.dn) + +struct dn_scp /* Session Control Port */ +{ + unsigned char state; +#define DN_O 1 /* Open */ +#define DN_CR 2 /* Connect Receive */ +#define DN_DR 3 /* Disconnect Reject */ +#define DN_DRC 4 /* Discon. Rej. Complete*/ +#define DN_CC 5 /* Connect Confirm */ +#define DN_CI 6 /* Connect Initiate */ +#define DN_NR 7 /* No resources */ +#define DN_NC 8 /* No communication */ +#define DN_CD 9 /* Connect Delivery */ +#define DN_RJ 10 /* Rejected */ +#define DN_RUN 11 /* Running */ +#define DN_DI 12 /* Disconnect Initiate */ +#define DN_DIC 13 /* Disconnect Complete */ +#define DN_DN 14 /* Disconnect Notificat */ +#define DN_CL 15 /* Closed */ +#define DN_CN 16 /* Closed Notification */ + + unsigned short addrloc; + unsigned short addrrem; + unsigned short numdat; + unsigned short numoth; + unsigned short numoth_rcv; + unsigned short numdat_rcv; + unsigned short ackxmt_dat; + unsigned short ackxmt_oth; + unsigned short ackrcv_dat; + unsigned short ackrcv_oth; + unsigned char flowrem_sw; + unsigned char flowloc_sw; +#define DN_SEND 2 +#define DN_DONTSEND 1 +#define DN_NOCHANGE 0 + unsigned short flowrem_dat; + unsigned short flowrem_oth; + unsigned short flowloc_dat; + unsigned short flowloc_oth; + unsigned char services_rem; + unsigned char services_loc; + unsigned char info_rem; + unsigned char info_loc; + + unsigned short segsize_rem; + unsigned short segsize_loc; + + unsigned char nonagle; + unsigned char multi_ireq; + unsigned char accept_mode; + unsigned long seg_total; /* Running total of current segment */ + + struct optdata_dn conndata_in; + struct optdata_dn conndata_out; + struct optdata_dn discdata_in; + struct optdata_dn discdata_out; + struct accessdata_dn accessdata; + + struct sockaddr_dn addr; /* Local address */ + struct sockaddr_dn peer; /* Remote address */ + + /* + * In this case the RTT estimation is not specified in the + * docs, nor is any back off algorithm. Here we follow well + * known tcp algorithms with a few small variations. + * + * snd_window: Max number of packets we send before we wait for + * an ack to come back. This will become part of a + * more complicated scheme when we support flow + * control. + * + * nsp_srtt: Round-Trip-Time (x8) in jiffies. This is a rolling + * average. + * nsp_rttvar: Round-Trip-Time-Varience (x4) in jiffies. This is the + * varience of the smoothed average (but calculated in + * a simpler way than for normal statistical varience + * calculations). + * + * nsp_rxtshift: Backoff counter. Value is zero normally, each time + * a packet is lost is increases by one until an ack + * is received. Its used to index an array of backoff + * multipliers. + */ +#define NSP_MIN_WINDOW 1 +#define NSP_MAX_WINDOW (0x07fe) + unsigned long max_window; + unsigned long snd_window; +#define NSP_INITIAL_SRTT (HZ) + unsigned long nsp_srtt; +#define NSP_INITIAL_RTTVAR (HZ*3) + unsigned long nsp_rttvar; +#define NSP_MAXRXTSHIFT 12 + unsigned long nsp_rxtshift; + + /* + * Output queues, one for data, one for otherdata/linkservice + */ + struct sk_buff_head data_xmit_queue; + struct sk_buff_head other_xmit_queue; + + /* + * Input queue for other data + */ + struct sk_buff_head other_receive_queue; + int other_report; + + /* + * Stuff to do with the slow timer + */ + unsigned long stamp; /* time of last transmit */ + unsigned long persist; + int (*persist_fxn)(struct sock *sk); + unsigned long keepalive; + void (*keepalive_fxn)(struct sock *sk); + + /* + * This stuff is for the fast timer for delayed acks + */ + struct timer_list delack_timer; + int delack_pending; + void (*delack_fxn)(struct sock *sk); + +}; + +/* + * src,dst : Source and Destination DECnet addresses + * hops : Number of hops through the network + * dst_port, src_port : NSP port numbers + * services, info : Useful data extracted from conninit messages + * rt_flags : Routing flags byte + * nsp_flags : NSP layer flags byte + * segsize : Size of segment + * segnum : Number, for data, otherdata and linkservice + * xmit_count : Number of times we've transmitted this skb + * stamp : Time stamp of most recent transmission, used in RTT calculations + * iif: Input interface number + * + * As a general policy, this structure keeps all addresses in network + * byte order, and all else in host byte order. Thus dst, src, dst_port + * and src_port are in network order. All else is in host order. + * + */ +#define DN_SKB_CB(skb) ((struct dn_skb_cb *)(skb)->cb) +struct dn_skb_cb { + unsigned short dst; + unsigned short src; + unsigned short hops; + unsigned short dst_port; + unsigned short src_port; + unsigned char services; + unsigned char info; + unsigned char rt_flags; + unsigned char nsp_flags; + unsigned short segsize; + unsigned short segnum; + unsigned short xmit_count; + unsigned long stamp; + int iif; +}; + +static __inline__ dn_address dn_eth2dn(unsigned char *ethaddr) +{ + return ethaddr[4] | (ethaddr[5] << 8); +} + +static __inline__ dn_address dn_saddr2dn(struct sockaddr_dn *saddr) +{ + return *(dn_address *)saddr->sdn_nodeaddr; +} + +static __inline__ void dn_dn2eth(unsigned char *ethaddr, dn_address addr) +{ + ethaddr[0] = 0xAA; + ethaddr[1] = 0x00; + ethaddr[2] = 0x04; + ethaddr[3] = 0x00; + ethaddr[4] = (unsigned char)(addr & 0xff); + ethaddr[5] = (unsigned char)(addr >> 8); +} + +#define DN_MENUVER_ACC 0x01 +#define DN_MENUVER_USR 0x02 +#define DN_MENUVER_PRX 0x04 +#define DN_MENUVER_UIC 0x08 + +extern struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr); +extern struct sock *dn_find_by_skb(struct sk_buff *skb); +#define DN_ASCBUF_LEN 9 +extern char *dn_addr2asc(dn_address, char *); +extern int dn_destroy_timer(struct sock *sk); + +extern int dn_sockaddr2username(struct sockaddr_dn *addr, unsigned char *buf, unsigned char type); +extern int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *addr, unsigned char *type); + +extern void dn_start_slow_timer(struct sock *sk); +extern void dn_stop_slow_timer(struct sock *sk); +extern void dn_start_fast_timer(struct sock *sk); +extern void dn_stop_fast_timer(struct sock *sk); + +extern dn_address decnet_address; +extern unsigned char decnet_ether_address[6]; +extern int decnet_debug_level; +extern int decnet_time_wait; +extern int decnet_dn_count; +extern int decnet_di_count; +extern int decnet_dr_count; +extern int decnet_no_fc_max_cwnd; + +#endif /* _NET_DN_H */ diff --git a/release/src/linux/linux/include/net/dn_dev.h b/release/src/linux/linux/include/net/dn_dev.h new file mode 100644 index 00000000..b042b824 --- /dev/null +++ b/release/src/linux/linux/include/net/dn_dev.h @@ -0,0 +1,189 @@ +#ifndef _NET_DN_DEV_H +#define _NET_DN_DEV_H + + +struct dn_dev; + +struct dn_ifaddr { + struct dn_ifaddr *ifa_next; + struct dn_dev *ifa_dev; + dn_address ifa_local; + unsigned char ifa_flags; + unsigned char ifa_scope; + char ifa_label[IFNAMSIZ]; +}; + +#define DN_DEV_S_RU 0 /* Run - working normally */ +#define DN_DEV_S_CR 1 /* Circuit Rejected */ +#define DN_DEV_S_DS 2 /* Data Link Start */ +#define DN_DEV_S_RI 3 /* Routing Layer Initialize */ +#define DN_DEV_S_RV 4 /* Routing Layer Verify */ +#define DN_DEV_S_RC 5 /* Routing Layer Complete */ +#define DN_DEV_S_OF 6 /* Off */ +#define DN_DEV_S_HA 7 /* Halt */ + + +/* + * The dn_dev_parms structure contains the set of parameters + * for each device (hence inclusion in the dn_dev structure) + * and an array is used to store the default types of supported + * device (in dn_dev.c). + * + * The type field matches the ARPHRD_ constants and is used in + * searching the list for supported devices when new devices + * come up. + * + * The mode field is used to find out if a device is broadcast, + * multipoint, or pointopoint. Please note that DECnet thinks + * different ways about devices to the rest of the kernel + * so the normal IFF_xxx flags are invalid here. For devices + * which can be any combination of the previously mentioned + * attributes, you can set this on a per device basis by + * installing an up() routine. + * + * The device state field, defines the initial state in which the + * device will come up. In the dn_dev structure, it is the actual + * state. + * + * Things have changed here. I've killed timer1 since its a user space + * issue for a user space routing deamon to sort out. The kernel does + * not need to be bothered with it. + * + * Timers: + * t2 - Rate limit timer, min time between routing and hello messages + * t3 - Hello timer, send hello messages when it expires + * + * Callbacks: + * up() - Called to initialize device, return value can veto use of + * device with DECnet. + * down() - Called to turn device off when it goes down + * timer3() - Called when timer 3 goes off + * + * sysctl - Hook for sysctl things + * + */ +struct dn_dev_parms { + int type; /* ARPHRD_xxx */ + int mode; /* Broadcast, Unicast, Mulitpoint */ +#define DN_DEV_BCAST 1 +#define DN_DEV_UCAST 2 +#define DN_DEV_MPOINT 4 + int state; /* Initial state */ + int forwarding; /* 0=EndNode, 1=L1Router, 2=L2Router */ + unsigned short blksize; /* Block Size */ + unsigned long t2; /* Default value of t2 */ + unsigned long t3; /* Default value of t3 */ + int priority; /* Priority to be a router */ + char *name; /* Name for sysctl */ + int ctl_name; /* Index for sysctl */ + int (*up)(struct net_device *); + void (*down)(struct net_device *); + void (*timer3)(struct net_device *); + void *sysctl; +}; + + +struct dn_dev { + struct dn_ifaddr *ifa_list; + struct net_device *dev; + struct dn_dev_parms parms; + char use_long; + struct timer_list timer; + unsigned long t3; + struct neigh_parms *neigh_parms; + unsigned char addr[ETH_ALEN]; + struct neighbour *router; /* Default router on circuit */ + struct neighbour *peer; /* Peer on pointopoint links */ + unsigned long uptime; /* Time device went up in jiffies */ +}; + +struct dn_short_packet +{ + unsigned char msgflg __attribute__((packed)); + unsigned short dstnode __attribute__((packed)); + unsigned short srcnode __attribute__((packed)); + unsigned char forward __attribute__((packed)); +}; + +struct dn_long_packet +{ + unsigned char msgflg __attribute__((packed)); + unsigned char d_area __attribute__((packed)); + unsigned char d_subarea __attribute__((packed)); + unsigned char d_id[6] __attribute__((packed)); + unsigned char s_area __attribute__((packed)); + unsigned char s_subarea __attribute__((packed)); + unsigned char s_id[6] __attribute__((packed)); + unsigned char nl2 __attribute__((packed)); + unsigned char visit_ct __attribute__((packed)); + unsigned char s_class __attribute__((packed)); + unsigned char pt __attribute__((packed)); +}; + +/*------------------------- DRP - Routing messages ---------------------*/ + +struct endnode_hello_message +{ + unsigned char msgflg __attribute__((packed)); + unsigned char tiver[3] __attribute__((packed)); + unsigned char id[6] __attribute__((packed)); + unsigned char iinfo __attribute__((packed)); + unsigned short blksize __attribute__((packed)); + unsigned char area __attribute__((packed)); + unsigned char seed[8] __attribute__((packed)); + unsigned char neighbor[6] __attribute__((packed)); + unsigned short timer __attribute__((packed)); + unsigned char mpd __attribute__((packed)); + unsigned char datalen __attribute__((packed)); + unsigned char data[2] __attribute__((packed)); +}; + +struct rtnode_hello_message +{ + unsigned char msgflg __attribute__((packed)); + unsigned char tiver[3] __attribute__((packed)); + unsigned char id[6] __attribute__((packed)); + unsigned char iinfo __attribute__((packed)); + unsigned short blksize __attribute__((packed)); + unsigned char priority __attribute__((packed)); + unsigned char area __attribute__((packed)); + unsigned short timer __attribute__((packed)); + unsigned char mpd __attribute__((packed)); +}; + + +extern void dn_dev_init(void); +extern void dn_dev_cleanup(void); + +extern int dn_dev_ioctl(unsigned int cmd, void *arg); + +extern void dn_dev_devices_off(void); +extern void dn_dev_devices_on(void); + +extern void dn_dev_init_pkt(struct sk_buff *skb); +extern void dn_dev_veri_pkt(struct sk_buff *skb); +extern void dn_dev_hello(struct sk_buff *skb); + +extern void dn_dev_up(struct net_device *); +extern void dn_dev_down(struct net_device *); + +extern struct net_device *decnet_default_device; + +static __inline__ int dn_dev_islocal(struct net_device *dev, dn_address addr) +{ + struct dn_dev *dn_db = dev->dn_ptr; + struct dn_ifaddr *ifa; + + if (dn_db == NULL) { + printk(KERN_DEBUG "dn_dev_islocal: Called for non DECnet device\n"); + return 0; + } + + for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) + if ((addr ^ ifa->ifa_local) == 0) + return 1; + + return 0; +} + +#endif /* _NET_DN_DEV_H */ diff --git a/release/src/linux/linux/include/net/dn_fib.h b/release/src/linux/linux/include/net/dn_fib.h new file mode 100644 index 00000000..e3e5d7b9 --- /dev/null +++ b/release/src/linux/linux/include/net/dn_fib.h @@ -0,0 +1,203 @@ +#ifndef _NET_DN_FIB_H +#define _NET_DN_FIB_H + +#include <linux/config.h> + +#ifdef CONFIG_DECNET_ROUTER + +#include <linux/rtnetlink.h> + +struct dn_kern_rta +{ + void *rta_dst; + void *rta_src; + int *rta_iif; + int *rta_oif; + void *rta_gw; + u32 *rta_priority; + void *rta_prefsrc; + struct rtattr *rta_mx; + struct rtattr *rta_mp; + unsigned char *rta_protoinfo; + unsigned char *rta_flow; + struct rta_cacheinfo *rta_ci; +}; + +struct dn_fib_key { + dn_address src; + dn_address dst; + int iif; + int oif; + u32 fwmark; + unsigned char scope; +}; + +struct dn_fib_res { + struct dn_fib_rule *r; + struct dn_fib_info *fi; + unsigned char prefixlen; + unsigned char nh_sel; + unsigned char type; + unsigned char scope; +}; + +struct dn_fib_nh { + struct net_device *nh_dev; + unsigned nh_flags; + unsigned char nh_scope; + int nh_weight; + int nh_power; + int nh_oif; + u32 nh_gw; +}; + +struct dn_fib_info { + struct dn_fib_info *fib_next; + struct dn_fib_info *fib_prev; + int fib_treeref; + atomic_t fib_clntref; + int fib_dead; + unsigned fib_flags; + int fib_protocol; + dn_address fib_prefsrc; + u32 fib_priority; + int fib_nhs; + int fib_power; + struct dn_fib_nh fib_nh[0]; +#define fib_dev fib_nh[0].nh_dev +}; + + +#define DN_FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) +#define DN_FIB_RES_RESET(res) ((res).nh_sel = 0) +#define DN_FIB_RES_GW(res) (DN_FIB_RES_NH(res).nh_gw) +#define DN_FIB_RES_DEV(res) (DN_FIB_RES_NH(res).nh_dev) +#define DN_FIB_RES_OIF(res) (DN_FIB_RES_NH(res).nh_oif) + +typedef struct { + u16 datum; +} dn_fib_key_t; + +typedef struct { + u16 datum; +} dn_fib_hash_t; + +typedef struct { + u16 datum; +} dn_fib_idx_t; + +struct dn_fib_node { + struct dn_fib_node *fn_next; + struct dn_fib_info *fn_info; +#define DN_FIB_INFO(f) ((f)->fn_info) + dn_fib_key_t fn_key; + u8 fn_type; + u8 fn_scope; + u8 fn_state; +}; + + +struct dn_fib_table { + int n; + + int (*insert)(struct dn_fib_table *t, struct rtmsg *r, + struct dn_kern_rta *rta, struct nlmsghdr *n, + struct netlink_skb_parms *req); + int (*delete)(struct dn_fib_table *t, struct rtmsg *r, + struct dn_kern_rta *rta, struct nlmsghdr *n, + struct netlink_skb_parms *req); + int (*lookup)(struct dn_fib_table *t, const struct dn_fib_key *key, + struct dn_fib_res *res); + int (*flush)(struct dn_fib_table *t); +#ifdef CONFIG_PROC_FS + int (*get_info)(struct dn_fib_table *table, char *buf, + int first, int count); +#endif /* CONFIG_PROC_FS */ + int (*dump)(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb); + + unsigned char data[0]; +}; + + +/* + * dn_fib.c + */ +extern void dn_fib_init(void); +extern void dn_fib_cleanup(void); + +extern int dn_fib_rt_message(struct sk_buff *skb); +extern int dn_fib_ioctl(struct socket *sock, unsigned int cmd, + unsigned long arg); +extern struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, + struct dn_kern_rta *rta, + const struct nlmsghdr *nlh, int *errp); +extern int dn_fib_semantic_match(int type, struct dn_fib_info *fi, + const struct dn_fib_key *key, struct dn_fib_res *res); +extern void dn_fib_release_info(struct dn_fib_info *fi); +extern u16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type); +extern void dn_fib_flush(void); +extern void dn_fib_select_multipath(const struct dn_fib_key *key, + struct dn_fib_res *res); +extern int dn_fib_sync_down(dn_address local, struct net_device *dev, + int force); +extern int dn_fib_sync_up(struct net_device *dev); + +/* + * dn_tables.c + */ +extern struct dn_fib_table *dn_fib_get_table(int n, int creat); +extern struct dn_fib_table *dn_fib_empty_table(void); +extern void dn_fib_table_init(void); +extern void dn_fib_table_cleanup(void); + +/* + * dn_rules.c + */ +extern void dn_fib_rules_init(void); +extern void dn_fib_rules_cleanup(void); +extern void dn_fib_rule_put(struct dn_fib_rule *); +extern int dn_fib_lookup(struct dn_fib_key *key, struct dn_fib_res *res); + +/* + * rtnetlink interface + */ +extern int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb); + +extern int dn_fib_rtm_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern int dn_fib_rtm_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb); + +#define DN_NUM_TABLES 255 +#define DN_MIN_TABLE 1 +#define DN_DEFAULT_TABLE 1 +#define DN_L1_TABLE 1 +#define DN_L2_TABLE 2 + +extern void dn_fib_free_info(struct dn_fib_info *fi); + +static __inline__ void dn_fib_info_put(struct dn_fib_info *fi) +{ + if (atomic_dec_and_test(&fi->fib_clntref)) + dn_fib_free_info(fi); +} + +static __inline__ void dn_fib_res_put(struct dn_fib_res *res) +{ + if (res->fi) + dn_fib_info_put(res->fi); + if (res->r) + dn_fib_rule_put(res->r); +} + +static __inline__ u16 dnet_make_mask(int n) +{ + if (n) + return htons(~((1<<(16-n))-1)); + return 0; +} + +#endif /* CONFIG_DECNET_ROUTER */ + +#endif /* _NET_DN_FIB_H */ diff --git a/release/src/linux/linux/include/net/dn_neigh.h b/release/src/linux/linux/include/net/dn_neigh.h new file mode 100644 index 00000000..4887475e --- /dev/null +++ b/release/src/linux/linux/include/net/dn_neigh.h @@ -0,0 +1,29 @@ +#ifndef _NET_DN_NEIGH_H +#define _NET_DN_NEIGH_H + +/* + * The position of the first two fields of + * this structure are critical - SJW + */ +struct dn_neigh { + struct neighbour n; + dn_address addr; + unsigned long flags; +#define DN_NDFLAG_R1 0x0001 /* Router L1 */ +#define DN_NDFLAG_R2 0x0002 /* Router L2 */ +#define DN_NDFLAG_P3 0x0004 /* Phase III Node */ + unsigned long blksize; + unsigned char priority; +}; + +extern void dn_neigh_init(void); +extern void dn_neigh_cleanup(void); +extern struct neighbour *dn_neigh_lookup(struct neigh_table *tbl, void *ptr); +extern int dn_neigh_router_hello(struct sk_buff *skb); +extern int dn_neigh_endnode_hello(struct sk_buff *skb); +extern void dn_neigh_pointopoint_hello(struct sk_buff *skb); +extern int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n); + +extern struct neigh_table dn_neigh_table; + +#endif /* _NET_DN_NEIGH_H */ diff --git a/release/src/linux/linux/include/net/dn_nsp.h b/release/src/linux/linux/include/net/dn_nsp.h new file mode 100644 index 00000000..3948c30a --- /dev/null +++ b/release/src/linux/linux/include/net/dn_nsp.h @@ -0,0 +1,207 @@ +#ifndef _NET_DN_NSP_H +#define _NET_DN_NSP_H +/****************************************************************************** + (c) 1995-1998 E.M. Serrat emserrat@geocities.com + + 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 + 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. +*******************************************************************************/ +/* dn_nsp.c functions prototyping */ + +extern void dn_nsp_send_data_ack(struct sock *sk); +extern void dn_nsp_send_oth_ack(struct sock *sk); +extern void dn_nsp_delayed_ack(struct sock *sk); +extern void dn_send_conn_ack(struct sock *sk); +extern void dn_send_conn_conf(struct sock *sk, int gfp); +extern void dn_nsp_send_disc(struct sock *sk, unsigned char type, + unsigned short reason, int gfp); +extern void dn_nsp_return_disc(struct sk_buff *skb, unsigned char type, + unsigned short reason); +extern void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval); +extern void dn_nsp_send_conninit(struct sock *sk, unsigned char flags); + +extern void dn_nsp_output(struct sock *sk); +extern int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum); +extern void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oob); +extern unsigned long dn_nsp_persist(struct sock *sk); +extern int dn_nsp_xmit_timeout(struct sock *sk); + +extern int dn_nsp_rx(struct sk_buff *); +extern int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb); + +extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri); +extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, int *size, int noblock, int *err); + +#define NSP_REASON_OK 0 /* No error */ +#define NSP_REASON_NR 1 /* No resources */ +#define NSP_REASON_UN 2 /* Unrecognised node name */ +#define NSP_REASON_SD 3 /* Node shutting down */ +#define NSP_REASON_ID 4 /* Invalid destination end user */ +#define NSP_REASON_ER 5 /* End user lacks resources */ +#define NSP_REASON_OB 6 /* Object too busy */ +#define NSP_REASON_US 7 /* Unspecified error */ +#define NSP_REASON_TP 8 /* Third-Party abort */ +#define NSP_REASON_EA 9 /* End user has aborted the link */ +#define NSP_REASON_IF 10 /* Invalid node name format */ +#define NSP_REASON_LS 11 /* Local node shutdown */ +#define NSP_REASON_LL 32 /* Node lacks logical-link resources */ +#define NSP_REASON_LE 33 /* End user lacks logical-link resources */ +#define NSP_REASON_UR 34 /* Unacceptable RQSTRID or PASSWORD field */ +#define NSP_REASON_UA 36 /* Unacceptable ACCOUNT field */ +#define NSP_REASON_TM 38 /* End user timed out logical link */ +#define NSP_REASON_NU 39 /* Node unreachable */ +#define NSP_REASON_NL 41 /* No-link message */ +#define NSP_REASON_DC 42 /* Disconnect confirm */ +#define NSP_REASON_IO 43 /* Image data field overflow */ + +#define NSP_DISCINIT 0x38 +#define NSP_DISCCONF 0x48 + +/*------------------------- NSP - messages ------------------------------*/ +/* Data Messages */ +/*---------------*/ + +/* Data Messages (data segment/interrupt/link service) */ + +struct nsp_data_seg_msg +{ + unsigned char msgflg __attribute__((packed)); + unsigned short dstaddr __attribute__((packed)); + unsigned short srcaddr __attribute__((packed)); +}; + +struct nsp_data_opt_msg +{ + unsigned short acknum __attribute__((packed)); + unsigned short segnum __attribute__((packed)); + unsigned short lsflgs __attribute__((packed)); +}; + +struct nsp_data_opt_msg1 +{ + unsigned short acknum __attribute__((packed)); + unsigned short segnum __attribute__((packed)); +}; + + +/* Acknowledgment Message (data/other data) */ +struct nsp_data_ack_msg +{ + unsigned char msgflg __attribute__((packed)); + unsigned short dstaddr __attribute__((packed)); + unsigned short srcaddr __attribute__((packed)); + unsigned short acknum __attribute__((packed)); +}; + +/* Connect Acknowledgment Message */ +struct nsp_conn_ack_msg +{ + unsigned char msgflg __attribute__((packed)); + unsigned short dstaddr __attribute__((packed)); +}; + + +/* Connect Initiate/Retransmit Initiate/Connect Confirm */ +struct nsp_conn_init_msg +{ + unsigned char msgflg __attribute__((packed)); +#define NSP_CI 0x18 /* Connect Initiate */ +#define NSP_RCI 0x68 /* Retrans. Conn Init */ + unsigned short dstaddr __attribute__((packed)); + unsigned short srcaddr __attribute__((packed)); + unsigned char services __attribute__((packed)); +#define NSP_FC_NONE 0x00 /* Flow Control None */ +#define NSP_FC_SRC 0x04 /* Seg Req. Count */ +#define NSP_FC_SCMC 0x08 /* Sess. Control Mess */ +#define NSP_FC_MASK 0x0c /* FC type mask */ + unsigned char info __attribute__((packed)); + unsigned short segsize __attribute__((packed)); +}; + +/* Disconnect Initiate/Disconnect Confirm */ +struct nsp_disconn_init_msg +{ + unsigned char msgflg __attribute__((packed)); + unsigned short dstaddr __attribute__((packed)); + unsigned short srcaddr __attribute__((packed)); + unsigned short reason __attribute__((packed)); +}; + + + +struct srcobj_fmt +{ + char format __attribute__((packed)); + unsigned char task __attribute__((packed)); + unsigned short grpcode __attribute__((packed)); + unsigned short usrcode __attribute__((packed)); + char dlen __attribute__((packed)); +}; + +/* + * A collection of functions for manipulating the sequence + * numbers used in NSP. Similar in operation to the functions + * of the same name in TCP. + */ +static __inline__ int before(unsigned short seq1, unsigned short seq2) +{ + seq1 &= 0x0fff; + seq2 &= 0x0fff; + + return (int)((seq1 - seq2) & 0x0fff) > 2048; +} + + +static __inline__ int after(unsigned short seq1, unsigned short seq2) +{ + seq1 &= 0x0fff; + seq2 &= 0x0fff; + + return (int)((seq2 - seq1) & 0x0fff) > 2048; +} + +static __inline__ int equal(unsigned short seq1, unsigned short seq2) +{ + return ((seq1 ^ seq2) & 0x0fff) == 0; +} + +static __inline__ int before_or_equal(unsigned short seq1, unsigned short seq2) +{ + return (before(seq1, seq2) || equal(seq1, seq2)); +} + +static __inline__ void seq_add(unsigned short *seq, unsigned short off) +{ + (*seq) += off; + (*seq) &= 0x0fff; +} + +static __inline__ int seq_next(unsigned short seq1, unsigned short seq2) +{ + return equal(seq1 + 1, seq2); +} + +/* + * Can we delay the ack ? + */ +static __inline__ int sendack(unsigned short seq) +{ + return (int)((seq & 0x1000) ? 0 : 1); +} + +/* + * Is socket congested ? + */ +static __inline__ int dn_congested(struct sock *sk) +{ + return atomic_read(&sk->rmem_alloc) > (sk->rcvbuf >> 1); +} + +#endif /* _NET_DN_NSP_H */ diff --git a/release/src/linux/linux/include/net/dn_route.h b/release/src/linux/linux/include/net/dn_route.h new file mode 100644 index 00000000..30ec0d24 --- /dev/null +++ b/release/src/linux/linux/include/net/dn_route.h @@ -0,0 +1,141 @@ +#ifndef _NET_DN_ROUTE_H +#define _NET_DN_ROUTE_H + +/****************************************************************************** + (c) 1995-1998 E.M. Serrat emserrat@geocities.com + + 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 + 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. +*******************************************************************************/ + +extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri); +extern int dn_route_output(struct dst_entry **pprt, dn_address dst, dn_address src, int flags); +extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb); +extern int dn_cache_getroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern void dn_rt_cache_flush(int delay); + +/* Masks for flags field */ +#define DN_RT_F_PID 0x07 /* Mask for packet type */ +#define DN_RT_F_PF 0x80 /* Padding Follows */ +#define DN_RT_F_VER 0x40 /* Version =0 discard packet if ==1 */ +#define DN_RT_F_IE 0x20 /* Intra Ethernet, Reserved in short pkt */ +#define DN_RT_F_RTS 0x10 /* Packet is being returned to sender */ +#define DN_RT_F_RQR 0x08 /* Return packet to sender upon non-delivery */ + +/* Mask for types of routing packets */ +#define DN_RT_PKT_MSK 0x06 +/* Types of routing packets */ +#define DN_RT_PKT_SHORT 0x02 /* Short routing packet */ +#define DN_RT_PKT_LONG 0x06 /* Long routing packet */ + +/* Mask for control/routing selection */ +#define DN_RT_PKT_CNTL 0x01 /* Set to 1 if a control packet */ +/* Types of control packets */ +#define DN_RT_CNTL_MSK 0x0f /* Mask for control packets */ +#define DN_RT_PKT_INIT 0x01 /* Initialisation packet */ +#define DN_RT_PKT_VERI 0x03 /* Verification Message */ +#define DN_RT_PKT_HELO 0x05 /* Hello and Test Message */ +#define DN_RT_PKT_L1RT 0x07 /* Level 1 Routing Message */ +#define DN_RT_PKT_L2RT 0x09 /* Level 2 Routing Message */ +#define DN_RT_PKT_ERTH 0x0b /* Ethernet Router Hello */ +#define DN_RT_PKT_EEDH 0x0d /* Ethernet EndNode Hello */ + +/* Values for info field in hello message */ +#define DN_RT_INFO_TYPE 0x03 /* Type mask */ +#define DN_RT_INFO_L1RT 0x02 /* L1 Router */ +#define DN_RT_INFO_L2RT 0x01 /* L2 Router */ +#define DN_RT_INFO_ENDN 0x03 /* EndNode */ +#define DN_RT_INFO_VERI 0x04 /* Verification Reqd. */ +#define DN_RT_INFO_RJCT 0x08 /* Reject Flag, Reserved */ +#define DN_RT_INFO_VFLD 0x10 /* Verification Failed, Reserved */ +#define DN_RT_INFO_NOML 0x20 /* No Multicast traffic accepted */ +#define DN_RT_INFO_BLKR 0x40 /* Blocking Requested */ + +/* + * The key structure is what we used to look up the route. + * The rt_saddr & rt_daddr entries are the same as key.saddr & key.daddr + * except for local input routes, where the rt_saddr = key.daddr and + * rt_daddr = key.saddr to allow the route to be used for returning + * packets to the originating host. + */ +struct dn_route { + union { + struct dst_entry dst; + struct dn_route *rt_next; + } u; + struct { + unsigned short saddr; + unsigned short daddr; + int iif; + int oif; + u32 fwmark; + } key; + unsigned short rt_saddr; + unsigned short rt_daddr; + unsigned char rt_type; + unsigned char rt_scope; + unsigned char rt_protocol; + unsigned char rt_table; +}; + +extern void dn_route_init(void); +extern void dn_route_cleanup(void); + +#include <net/sock.h> +#include <linux/if_arp.h> + +static inline void dn_rt_send(struct sk_buff *skb) +{ + dev_queue_xmit(skb); +} + +static inline void dn_rt_finish_output(struct sk_buff *skb, char *dst) +{ + struct net_device *dev = skb->dev; + + if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) + dst = NULL; + + if (!dev->hard_header || (dev->hard_header(skb, dev, ETH_P_DNA_RT, + dst, NULL, skb->len) >= 0)) + dn_rt_send(skb); + else + kfree_skb(skb); +} + +static inline void dn_nsp_send(struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + struct dn_scp *scp = &sk->protinfo.dn; + struct dst_entry *dst; + + skb->h.raw = skb->data; + scp->stamp = jiffies; + + if ((dst = sk->dst_cache) && !dst->obsolete) { +try_again: + skb->dst = dst_clone(dst); + dst->output(skb); + return; + } + + dst_release(xchg(&sk->dst_cache, NULL)); + + if (dn_route_output(&sk->dst_cache, dn_saddr2dn(&scp->peer), dn_saddr2dn(&scp->addr), 0) == 0) { + dst = sk->dst_cache; + goto try_again; + } + + sk->err = EHOSTUNREACH; + if (!sk->dead) + sk->state_change(sk); +} + +#endif /* _NET_DN_ROUTE_H */ diff --git a/release/src/linux/linux/include/net/dsfield.h b/release/src/linux/linux/include/net/dsfield.h new file mode 100644 index 00000000..a79c9e07 --- /dev/null +++ b/release/src/linux/linux/include/net/dsfield.h @@ -0,0 +1,54 @@ +/* include/net/dsfield.h - Manipulation of the Differentiated Services field */ + +/* Written 1998-2000 by Werner Almesberger, EPFL ICA */ + + +#ifndef __NET_DSFIELD_H +#define __NET_DSFIELD_H + +#include <linux/types.h> +#include <linux/ip.h> +#include <linux/ipv6.h> +#include <asm/byteorder.h> + + +static inline __u8 ipv4_get_dsfield(struct iphdr *iph) +{ + return iph->tos; +} + + +static inline __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h) +{ + return ntohs(*(__u16 *) ipv6h) >> 4; +} + + +static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask, + __u8 value) +{ + __u32 check = ntohs(iph->check); + __u8 dsfield; + + dsfield = (iph->tos & mask) | value; + check += iph->tos; + if ((check+1) >> 16) check = (check+1) & 0xffff; + check -= dsfield; + check += check >> 16; /* adjust carry */ + iph->check = htons(check); + iph->tos = dsfield; +} + + +static inline void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask, + __u8 value) +{ + __u16 tmp; + + tmp = ntohs(*(__u16 *) ipv6h); + tmp = (tmp & ((mask << 4) | 0xf00f)) | (value << 4); + *(__u16 *) ipv6h = htons(tmp); +} + + +#endif diff --git a/release/src/linux/linux/include/net/dst.h b/release/src/linux/linux/include/net/dst.h new file mode 100644 index 00000000..d81eb07b --- /dev/null +++ b/release/src/linux/linux/include/net/dst.h @@ -0,0 +1,162 @@ +/* + * net/dst.h Protocol independent destination cache definitions. + * + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> + * + */ + +#ifndef _NET_DST_H +#define _NET_DST_H + +#include <linux/config.h> +#include <net/neighbour.h> + +/* + * 0 - no debugging messages + * 1 - rare events and bugs (default) + * 2 - trace mode. + */ +#define RT_CACHE_DEBUG 0 + +#define DST_GC_MIN (1*HZ) +#define DST_GC_INC (5*HZ) +#define DST_GC_MAX (120*HZ) + +struct sk_buff; + +struct dst_entry +{ + struct dst_entry *next; + atomic_t __refcnt; /* client references */ + int __use; + struct net_device *dev; + int obsolete; + int flags; +#define DST_HOST 1 + unsigned long lastuse; + unsigned long expires; + + unsigned mxlock; + unsigned pmtu; + unsigned window; + unsigned rtt; + unsigned rttvar; + unsigned ssthresh; + unsigned cwnd; + unsigned advmss; + unsigned reordering; + + unsigned long rate_last; /* rate limiting for ICMP */ + unsigned long rate_tokens; + + int error; + + struct neighbour *neighbour; + struct hh_cache *hh; + + int (*input)(struct sk_buff*); + int (*output)(struct sk_buff*); + +#ifdef CONFIG_NET_CLS_ROUTE + __u32 tclassid; +#endif + + struct dst_ops *ops; + + char info[0]; +}; + + +struct dst_ops +{ + unsigned short family; + unsigned short protocol; + unsigned gc_thresh; + + int (*gc)(void); + struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); + struct dst_entry * (*reroute)(struct dst_entry *, + struct sk_buff *); + void (*destroy)(struct dst_entry *); + struct dst_entry * (*negative_advice)(struct dst_entry *); + void (*link_failure)(struct sk_buff *); + int entry_size; + + atomic_t entries; + kmem_cache_t *kmem_cachep; +}; + +#ifdef __KERNEL__ + +static inline void dst_hold(struct dst_entry * dst) +{ + atomic_inc(&dst->__refcnt); +} + +static inline +struct dst_entry * dst_clone(struct dst_entry * dst) +{ + if (dst) + atomic_inc(&dst->__refcnt); + return dst; +} + +static inline +void dst_release(struct dst_entry * dst) +{ + if (dst) + atomic_dec(&dst->__refcnt); +} + +extern void * dst_alloc(struct dst_ops * ops); +extern void __dst_free(struct dst_entry * dst); +extern void dst_destroy(struct dst_entry * dst); + +static inline +void dst_free(struct dst_entry * dst) +{ + if (dst->obsolete > 1) + return; + if (!atomic_read(&dst->__refcnt)) { + dst_destroy(dst); + return; + } + __dst_free(dst); +} + +static inline void dst_confirm(struct dst_entry *dst) +{ + if (dst) + neigh_confirm(dst->neighbour); +} + +static inline void dst_negative_advice(struct dst_entry **dst_p) +{ + struct dst_entry * dst = *dst_p; + if (dst && dst->ops->negative_advice) + *dst_p = dst->ops->negative_advice(dst); +} + +static inline void dst_link_failure(struct sk_buff *skb) +{ + struct dst_entry * dst = skb->dst; + if (dst && dst->ops && dst->ops->link_failure) + dst->ops->link_failure(skb); +} + +static inline void dst_set_expires(struct dst_entry *dst, int timeout) +{ + unsigned long expires = jiffies + timeout; + + if (expires == 0) + expires = 1; + + if (dst->expires == 0 || (long)(dst->expires - expires) > 0) + dst->expires = expires; +} + +extern void dst_init(void); + +#endif + +#endif /* _NET_DST_H */ diff --git a/release/src/linux/linux/include/net/flow.h b/release/src/linux/linux/include/net/flow.h new file mode 100644 index 00000000..e1ce1b2a --- /dev/null +++ b/release/src/linux/linux/include/net/flow.h @@ -0,0 +1,101 @@ +/* + * + * Flow based forwarding rules (usage: firewalling, etc) + * + */ + +#ifndef _NET_FLOW_H +#define _NET_FLOW_H + +struct flowi { + int proto; /* {TCP, UDP, ICMP} */ + + union { + struct { + __u32 daddr; + __u32 saddr; + } ip4_u; + + struct { + struct in6_addr * daddr; + struct in6_addr * saddr; + __u32 flowlabel; + } ip6_u; + } nl_u; +#define fl6_dst nl_u.ip6_u.daddr +#define fl6_src nl_u.ip6_u.saddr +#define fl6_flowlabel nl_u.ip6_u.flowlabel +#define fl4_dst nl_u.ip4_u.daddr +#define fl4_src nl_u.ip4_u.saddr + + int oif; + + union { + struct { + __u16 sport; + __u16 dport; + } ports; + + struct { + __u8 type; + __u8 code; + } icmpt; + + unsigned long data; + } uli_u; +}; + +#define FLOWR_NODECISION 0 /* rule not appliable to flow */ +#define FLOWR_SELECT 1 /* flow must follow this rule */ +#define FLOWR_CLEAR 2 /* priority level clears flow */ +#define FLOWR_ERROR 3 + +struct fl_acc_args { + int type; + + +#define FL_ARG_FORWARD 1 +#define FL_ARG_ORIGIN 2 + + union { + struct sk_buff *skb; + struct { + struct sock *sk; + struct flowi *flow; + } fl_o; + } fl_u; +}; + + +struct pkt_filter { + atomic_t refcnt; + unsigned int offset; + __u32 value; + __u32 mask; + struct pkt_filter *next; +}; + +#define FLR_INPUT 1 +#define FLR_OUTPUT 2 + +struct flow_filter { + int type; + union { + struct pkt_filter *filter; + struct sock *sk; + } u; +}; + +struct flow_rule { + struct flow_rule_ops *ops; + unsigned char private[0]; +}; + +struct flow_rule_ops { + int (*accept)(struct rt6_info *rt, + struct rt6_info *rule, + struct fl_acc_args *args, + struct rt6_info **nrt); +}; + +#endif diff --git a/release/src/linux/linux/include/net/icmp.h b/release/src/linux/linux/include/net/icmp.h new file mode 100644 index 00000000..460cb2c3 --- /dev/null +++ b/release/src/linux/linux/include/net/icmp.h @@ -0,0 +1,46 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the ICMP module. + * + * Version: @(#)icmp.h 1.0.4 05/13/93 + * + * Authors: Ross Biro, <bir7@leland.Stanford.Edu> + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * + * 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. + */ +#ifndef _ICMP_H +#define _ICMP_H + +#include <linux/icmp.h> +#include <linux/skbuff.h> + +#include <net/sock.h> +#include <net/protocol.h> + +struct icmp_err { + int errno; + unsigned fatal:1; +}; + +extern struct icmp_err icmp_err_convert[]; +extern struct icmp_mib icmp_statistics[NR_CPUS*2]; +#define ICMP_INC_STATS(field) SNMP_INC_STATS(icmp_statistics, field) +#define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field) +#define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field) + +extern void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info); +extern int icmp_rcv(struct sk_buff *skb); +extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern void icmp_init(struct net_proto_family *ops); + +/* Move into dst.h ? */ +extern int xrlim_allow(struct dst_entry *dst, int timeout); + +#endif /* _ICMP_H */ diff --git a/release/src/linux/linux/include/net/if_inet6.h b/release/src/linux/linux/include/net/if_inet6.h new file mode 100644 index 00000000..921268e0 --- /dev/null +++ b/release/src/linux/linux/include/net/if_inet6.h @@ -0,0 +1,179 @@ +/* + * inet6 interface/address list definitions + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * + * 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. + */ + +#ifndef _NET_IF_INET6_H +#define _NET_IF_INET6_H + +#define IF_RA_RCVD 0x20 +#define IF_RS_SENT 0x10 + +#ifdef __KERNEL__ + +struct inet6_ifaddr +{ + struct in6_addr addr; + __u32 prefix_len; + + __u32 valid_lft; + __u32 prefered_lft; + unsigned long tstamp; + atomic_t refcnt; + spinlock_t lock; + + __u8 probes; + __u8 flags; + + __u16 scope; + + struct timer_list timer; + + struct inet6_dev *idev; + + struct inet6_ifaddr *lst_next; /* next addr in addr_lst */ + struct inet6_ifaddr *if_next; /* next addr in inet6_dev */ + + int dead; +}; + +struct ipv6_mc_socklist +{ + struct in6_addr addr; + int ifindex; + struct ipv6_mc_socklist *next; +}; + +#define MAF_TIMER_RUNNING 0x01 +#define MAF_LAST_REPORTER 0x02 +#define MAF_LOADED 0x04 + +struct ifmcaddr6 +{ + struct in6_addr mca_addr; + struct inet6_dev *idev; + struct ifmcaddr6 *next; + struct timer_list mca_timer; + unsigned mca_flags; + int mca_users; + atomic_t mca_refcnt; + spinlock_t mca_lock; +}; + +#define IFA_HOST IPV6_ADDR_LOOPBACK +#define IFA_LINK IPV6_ADDR_LINKLOCAL +#define IFA_SITE IPV6_ADDR_SITELOCAL +#define IFA_GLOBAL 0x0000U + +struct ipv6_devconf +{ + int forwarding; + int hop_limit; + int mtu6; + int accept_ra; + int accept_redirects; + int autoconf; + int dad_transmits; + int rtr_solicits; + int rtr_solicit_interval; + int rtr_solicit_delay; + + void *sysctl; +}; + +struct inet6_dev +{ + struct net_device *dev; + + struct inet6_ifaddr *addr_list; + struct ifmcaddr6 *mc_list; + rwlock_t lock; + atomic_t refcnt; + __u32 if_flags; + int dead; + + struct neigh_parms *nd_parms; + struct inet6_dev *next; + struct ipv6_devconf cnf; +}; + +extern struct ipv6_devconf ipv6_devconf; + +static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf) +{ + /* + * +-------+-------+-------+-------+-------+-------+ + * | 33 | 33 | DST13 | DST14 | DST15 | DST16 | + * +-------+-------+-------+-------+-------+-------+ + */ + + buf[0]= 0x33; + buf[1]= 0x33; + + memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32)); +} + +static inline void ipv6_tr_mc_map(struct in6_addr *addr, char *buf) +{ + /* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */ + + if (((addr->s6_addr[0] == 0xFF) && + ((addr->s6_addr[1] == 0x01) || (addr->s6_addr[1] == 0x02)) && + (addr->s6_addr16[1] == 0) && + (addr->s6_addr32[1] == 0) && + (addr->s6_addr32[2] == 0) && + (addr->s6_addr16[6] == 0) && + (addr->s6_addr[15] == 1)) || + ((addr->s6_addr[0] == 0xFF) && + (addr->s6_addr[1] == 0x02) && + (addr->s6_addr16[1] == 0) && + (addr->s6_addr32[1] == 0) && + (addr->s6_addr16[4] == 0) && + (addr->s6_addr[10] == 0) && + (addr->s6_addr[11] == 1) && + (addr->s6_addr[12] == 0xff))) + { + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x01; + buf[3]=0x00; + buf[4]=0x00; + buf[5]=0x00; + /* All routers FF0x::2 */ + } else if ((addr->s6_addr[0] ==0xff) && + ((addr->s6_addr[1] & 0xF0) == 0) && + (addr->s6_addr16[1] == 0) && + (addr->s6_addr32[1] == 0) && + (addr->s6_addr32[2] == 0) && + (addr->s6_addr16[6] == 0) && + (addr->s6_addr[15] == 2)) + { + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x02; + buf[3]=0x00; + buf[4]=0x00; + buf[5]=0x00; + } else { + unsigned char i ; + + i = addr->s6_addr[15] & 7 ; + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x00; + buf[3]=0x01 << i ; + buf[4]=0x00; + buf[5]=0x00; + } +} +#endif +#endif diff --git a/release/src/linux/linux/include/net/inet_common.h b/release/src/linux/linux/include/net/inet_common.h new file mode 100644 index 00000000..87b3fd32 --- /dev/null +++ b/release/src/linux/linux/include/net/inet_common.h @@ -0,0 +1,48 @@ +#ifndef _INET_COMMON_H +#define _INET_COMMON_H + +extern struct proto_ops inet_stream_ops; +extern struct proto_ops inet_dgram_ops; + +/* + * INET4 prototypes used by INET6 + */ + +extern void inet_remove_sock(struct sock *sk1); +extern void inet_put_sock(unsigned short num, + struct sock *sk); +extern int inet_release(struct socket *sock); +extern int inet_stream_connect(struct socket *sock, + struct sockaddr * uaddr, + int addr_len, int flags); +extern int inet_dgram_connect(struct socket *sock, + struct sockaddr * uaddr, + int addr_len, int flags); +extern int inet_accept(struct socket *sock, + struct socket *newsock, int flags); +extern int inet_recvmsg(struct socket *sock, + struct msghdr *ubuf, + int size, int flags, struct scm_cookie *scm); +extern int inet_sendmsg(struct socket *sock, + struct msghdr *msg, + int size, struct scm_cookie *scm); +extern int inet_shutdown(struct socket *sock, int how); +extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); +extern int inet_setsockopt(struct socket *sock, int level, + int optname, char *optval, + int optlen); +extern int inet_getsockopt(struct socket *sock, int level, + int optname, char *optval, + int *optlen); +extern int inet_fcntl(struct socket *sock, + unsigned int cmd, + unsigned long arg); +extern int inet_listen(struct socket *sock, int backlog); + +extern void inet_sock_release(struct sock *sk); +extern void inet_sock_destruct(struct sock *sk); +extern atomic_t inet_sock_nr; + +#endif + + diff --git a/release/src/linux/linux/include/net/inet_ecn.h b/release/src/linux/linux/include/net/inet_ecn.h new file mode 100644 index 00000000..ae82d3b3 --- /dev/null +++ b/release/src/linux/linux/include/net/inet_ecn.h @@ -0,0 +1,56 @@ +#ifndef _INET_ECN_H_ +#define _INET_ECN_H_ + +static inline int INET_ECN_is_ce(__u8 dsfield) +{ + return (dsfield&3) == 3; +} + +static inline int INET_ECN_is_not_ce(__u8 dsfield) +{ + return (dsfield&3) == 2; +} + +static inline int INET_ECN_is_capable(__u8 dsfield) +{ + return (dsfield&2); +} + +static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) +{ + outer &= ~3; + if (INET_ECN_is_capable(inner)) + outer |= (inner & 3); + return outer; +} + +#define INET_ECN_xmit(sk) do { (sk)->protinfo.af_inet.tos |= 2; } while (0) +#define INET_ECN_dontxmit(sk) do { (sk)->protinfo.af_inet.tos &= ~3; } while (0) + +#define IP6_ECN_flow_init(label) do { \ + (label) &= ~htonl(3<<20); \ + } while (0) + +#define IP6_ECN_flow_xmit(sk, label) do { \ + if (INET_ECN_is_capable((sk)->protinfo.af_inet.tos)) \ + (label) |= __constant_htons(2 << 4); \ + } while (0) + +static inline void IP_ECN_set_ce(struct iphdr *iph) +{ + u32 check = iph->check; + check += __constant_htons(0xFFFE); + iph->check = check + (check>=0xFFFF); + iph->tos |= 1; +} + +struct ipv6hdr; + +static inline void IP6_ECN_set_ce(struct ipv6hdr *iph) +{ + *(u32*)iph |= htonl(1<<20); +} + +#define ip6_get_dsfield(iph) ((ntohs(*(u16*)(iph)) >> 4) & 0xFF) + +#endif diff --git a/release/src/linux/linux/include/net/inetpeer.h b/release/src/linux/linux/include/net/inetpeer.h new file mode 100644 index 00000000..2edb8700 --- /dev/null +++ b/release/src/linux/linux/include/net/inetpeer.h @@ -0,0 +1,66 @@ +/* + * INETPEER - A storage for permanent information about peers + * + * Version: $Id: inetpeer.h,v 1.1.1.4 2003/10/14 08:09:28 sparq Exp $ + * + * Authors: Andrey V. Savochkin <saw@msu.ru> + */ + +#ifndef _NET_INETPEER_H +#define _NET_INETPEER_H + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <asm/atomic.h> + +struct inet_peer +{ + struct inet_peer *avl_left, *avl_right; + struct inet_peer *unused_next, **unused_prevp; + atomic_t refcnt; + unsigned long dtime; /* the time of last use of not + * referenced entries */ + __u32 v4daddr; /* peer's address */ + __u16 avl_height; + __u16 ip_id_count; /* IP ID for the next packet */ + __u32 tcp_ts; + unsigned long tcp_ts_stamp; +}; + +void inet_initpeers(void) __init; + +/* can be called with or without local BH being disabled */ +struct inet_peer *inet_getpeer(__u32 daddr, int create); + +extern spinlock_t inet_peer_unused_lock; +extern struct inet_peer *inet_peer_unused_head; +extern struct inet_peer **inet_peer_unused_tailp; +/* can be called from BH context or outside */ +static inline void inet_putpeer(struct inet_peer *p) +{ + spin_lock_bh(&inet_peer_unused_lock); + if (atomic_dec_and_test(&p->refcnt)) { + p->unused_prevp = inet_peer_unused_tailp; + p->unused_next = NULL; + *inet_peer_unused_tailp = p; + inet_peer_unused_tailp = &p->unused_next; + p->dtime = jiffies; + } + spin_unlock_bh(&inet_peer_unused_lock); +} + +extern spinlock_t inet_peer_idlock; +/* can be called with or without local BH being disabled */ +static inline __u16 inet_getid(struct inet_peer *p) +{ + __u16 id; + + spin_lock_bh(&inet_peer_idlock); + id = p->ip_id_count++; + spin_unlock_bh(&inet_peer_idlock); + return id; +} + +#endif /* _NET_INETPEER_H */ diff --git a/release/src/linux/linux/include/net/ip.h b/release/src/linux/linux/include/net/ip.h new file mode 100644 index 00000000..2931015e --- /dev/null +++ b/release/src/linux/linux/include/net/ip.h @@ -0,0 +1,269 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the IP module. + * + * Version: @(#)ip.h 1.0.2 05/07/93 + * + * Authors: Ross Biro, <bir7@leland.Stanford.Edu> + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * Alan Cox, <gw4pts@gw4pts.ampr.org> + * + * Changes: + * Mike McLagan : Routing by source + * + * 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. + */ +#ifndef _IP_H +#define _IP_H + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/socket.h> +#include <linux/ip.h> +#include <linux/netdevice.h> +#include <linux/inetdevice.h> +#include <linux/in_route.h> +#include <net/route.h> +#include <net/arp.h> + +#ifndef _SNMP_H +#include <net/snmp.h> +#endif + +#include <net/sock.h> /* struct sock */ + +struct inet_skb_parm +{ + struct ip_options opt; /* Compiled IP options */ + unsigned char flags; + +#define IPSKB_MASQUERADED 1 +#define IPSKB_TRANSLATED 2 +#define IPSKB_FORWARDED 4 +}; + +struct ipcm_cookie +{ + u32 addr; + int oif; + struct ip_options *opt; +}; + +#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) + +struct ip_ra_chain +{ + struct ip_ra_chain *next; + struct sock *sk; + void (*destructor)(struct sock *); +}; + +extern struct ip_ra_chain *ip_ra_chain; +extern rwlock_t ip_ra_lock; + +/* IP flags. */ +#define IP_CE 0x8000 /* Flag: "Congestion" */ +#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ +#define IP_MF 0x2000 /* Flag: "More Fragments" */ +#define IP_OFFSET 0x1FFF /* "Fragment Offset" part */ + +#define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ + +extern void ip_mc_dropsocket(struct sock *); +extern void ip_mc_dropdevice(struct net_device *dev); +extern int ip_mc_procinfo(char *, char **, off_t, int); + +/* + * Functions provided by ip.c + */ + +extern int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, + u32 saddr, u32 daddr, + struct ip_options *opt); +extern int ip_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt); +extern int ip_local_deliver(struct sk_buff *skb); +extern int ip_mr_input(struct sk_buff *skb); +extern int ip_output(struct sk_buff *skb); +extern int ip_mc_output(struct sk_buff *skb); +extern int ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*)); +extern int ip_do_nat(struct sk_buff *skb); +extern void ip_send_check(struct iphdr *ip); +extern int ip_queue_xmit(struct sk_buff *skb); +extern void ip_init(void); +extern int ip_build_xmit(struct sock *sk, + int getfrag (const void *, + char *, + unsigned int, + unsigned int), + const void *frag, + unsigned length, + struct ipcm_cookie *ipc, + struct rtable *rt, + int flags); + +/* + * Map a multicast IP onto multicast MAC for type Token Ring. + * This conforms to RFC1469 Option 2 Multicasting i.e. + * using a functional address to transmit / receive + * multicast packets. + */ + +static inline void ip_tr_mc_map(u32 addr, char *buf) +{ + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x00; + buf[3]=0x04; + buf[4]=0x00; + buf[5]=0x00; +} + +struct ip_reply_arg { + struct iovec iov[2]; + int n_iov; /* redundant */ + u32 csum; + int csumoffset; /* u16 offset of csum in iov[0].iov_base */ + /* -1 if not needed */ +}; + +void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, + unsigned int len); + +extern __inline__ int ip_finish_output(struct sk_buff *skb); + +struct ipv4_config +{ + int log_martians; + int autoconfig; + int no_pmtu_disc; +}; + +extern struct ipv4_config ipv4_config; +extern struct ip_mib ip_statistics[NR_CPUS*2]; +#define IP_INC_STATS(field) SNMP_INC_STATS(ip_statistics, field) +#define IP_INC_STATS_BH(field) SNMP_INC_STATS_BH(ip_statistics, field) +#define IP_INC_STATS_USER(field) SNMP_INC_STATS_USER(ip_statistics, field) +extern struct linux_mib net_statistics[NR_CPUS*2]; +#define NET_INC_STATS(field) SNMP_INC_STATS(net_statistics, field) +#define NET_INC_STATS_BH(field) SNMP_INC_STATS_BH(net_statistics, field) +#define NET_INC_STATS_USER(field) SNMP_INC_STATS_USER(net_statistics, field) + +extern int sysctl_local_port_range[2]; +extern int sysctl_ip_default_ttl; + +#ifdef CONFIG_INET +static inline int ip_send(struct sk_buff *skb) +{ + if (skb->len > skb->dst->pmtu) + return ip_fragment(skb, ip_finish_output); + else + return ip_finish_output(skb); +} + +/* The function in 2.2 was invalid, producing wrong result for + * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */ +static inline +int ip_decrease_ttl(struct iphdr *iph) +{ + u32 check = iph->check; + check += __constant_htons(0x0100); + iph->check = check + (check>=0xFFFF); + return --iph->ttl; +} + +static inline +int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) +{ + return (sk->protinfo.af_inet.pmtudisc == IP_PMTUDISC_DO || + (sk->protinfo.af_inet.pmtudisc == IP_PMTUDISC_WANT && + !(dst->mxlock&(1<<RTAX_MTU)))); +} + +extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst); + +static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk) +{ + if (iph->frag_off&__constant_htons(IP_DF)) { + /* This is only to work around buggy Windows95/2000 + * VJ compression implementations. If the ID field + * does not change, they drop every other packet in + * a TCP stream using header compression. + */ + iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0); + } else + __ip_select_ident(iph, dst); +} + +/* + * Map a multicast IP onto multicast MAC for type ethernet. + */ + +static inline void ip_eth_mc_map(u32 addr, char *buf) +{ + addr=ntohl(addr); + buf[0]=0x01; + buf[1]=0x00; + buf[2]=0x5e; + buf[5]=addr&0xFF; + addr>>=8; + buf[4]=addr&0xFF; + addr>>=8; + buf[3]=addr&0x7F; +} + +#endif + +extern int ip_call_ra_chain(struct sk_buff *skb); + +/* + * Functions provided by ip_fragment.o + */ + +struct sk_buff *ip_defrag(struct sk_buff *skb); +extern int ip_frag_nqueues; +extern atomic_t ip_frag_mem; + +/* + * Functions provided by ip_forward.c + */ + +extern int ip_forward(struct sk_buff *skb); +extern int ip_net_unreachable(struct sk_buff *skb); + +/* + * Functions provided by ip_options.c + */ + +extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, u32 daddr, struct rtable *rt, int is_frag); +extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb); +extern void ip_options_fragment(struct sk_buff *skb); +extern int ip_options_compile(struct ip_options *opt, struct sk_buff *skb); +extern int ip_options_get(struct ip_options **optp, unsigned char *data, int optlen, int user); +extern void ip_options_undo(struct ip_options * opt); +extern void ip_forward_options(struct sk_buff *skb); +extern int ip_options_rcv_srr(struct sk_buff *skb); + +/* + * Functions provided by ip_sockglue.c + */ + +extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); +extern int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc); +extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); +extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen); +extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)); + +extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len); +extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, + u16 port, u32 info, u8 *payload); +extern void ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport, + u32 info); + +#endif /* _IP_H */ diff --git a/release/src/linux/linux/include/net/ip6_fib.h b/release/src/linux/linux/include/net/ip6_fib.h new file mode 100644 index 00000000..f8d382f4 --- /dev/null +++ b/release/src/linux/linux/include/net/ip6_fib.h @@ -0,0 +1,183 @@ +/* + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * 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. + */ + +#ifndef _IP6_FIB_H +#define _IP6_FIB_H + +#ifdef __KERNEL__ + +#include <linux/ipv6_route.h> + +#include <net/dst.h> +#include <net/flow.h> +#include <linux/rtnetlink.h> + +struct rt6_info; + +struct fib6_node +{ + struct fib6_node *parent; + struct fib6_node *left; + struct fib6_node *right; + + struct fib6_node *subtree; + + struct rt6_info *leaf; + + __u16 fn_bit; /* bit key */ + __u16 fn_flags; + __u32 fn_sernum; +}; + + +/* + * routing information + * + */ + +struct rt6key +{ + struct in6_addr addr; + int plen; +}; + +struct rt6_info +{ + union { + struct dst_entry dst; + struct rt6_info *next; + } u; + +#define rt6i_dev u.dst.dev +#define rt6i_nexthop u.dst.neighbour +#define rt6i_expires u.dst.expires + + struct fib6_node *rt6i_node; + + struct in6_addr rt6i_gateway; + + u32 rt6i_flags; + u32 rt6i_metric; + u8 rt6i_hoplimit; + atomic_t rt6i_ref; + + union { + struct flow_rule *rt6iu_flowr; + struct flow_filter *rt6iu_filter; + } flow_u; + +#define rt6i_flowr flow_u.rt6iu_flowr +#define rt6i_filter flow_u.rt6iu_filter + + struct rt6key rt6i_dst; + struct rt6key rt6i_src; +}; + +struct fib6_walker_t +{ + struct fib6_walker_t *prev, *next; + struct fib6_node *root, *node; + struct rt6_info *leaf; + unsigned char state; + unsigned char prune; + int (*func)(struct fib6_walker_t *); + void *args; +}; + +extern struct fib6_walker_t fib6_walker_list; +extern rwlock_t fib6_walker_lock; + +static inline void fib6_walker_link(struct fib6_walker_t *w) +{ + write_lock_bh(&fib6_walker_lock); + w->next = fib6_walker_list.next; + w->prev = &fib6_walker_list; + w->next->prev = w; + w->prev->next = w; + write_unlock_bh(&fib6_walker_lock); +} + +static inline void fib6_walker_unlink(struct fib6_walker_t *w) +{ + write_lock_bh(&fib6_walker_lock); + w->next->prev = w->prev; + w->prev->next = w->next; + w->prev = w->next = w; + write_unlock_bh(&fib6_walker_lock); +} + +struct rt6_statistics { + __u32 fib_nodes; + __u32 fib_route_nodes; + __u32 fib_rt_alloc; /* permanet routes */ + __u32 fib_rt_entries; /* rt entries in table */ + __u32 fib_rt_cache; /* cache routes */ +}; + +#define RTN_TL_ROOT 0x0001 +#define RTN_ROOT 0x0002 /* tree root node */ +#define RTN_RTINFO 0x0004 /* node with valid routing info */ + +/* + * priority levels (or metrics) + * + */ + +#define RTPRI_FIREWALL 8 /* Firewall control information */ +#define RTPRI_FLOW 16 /* Flow based forwarding rules */ +#define RTPRI_KERN_CTL 32 /* Kernel control routes */ + +#define RTPRI_USER_MIN 256 /* Mimimum user priority */ +#define RTPRI_USER_MAX 1024 /* Maximum user priority */ + +#define RTPRI_KERN_DFLT 4096 /* Kernel default routes */ + +#define MAX_FLOW_BACKTRACE 32 + + +typedef void (*f_pnode)(struct fib6_node *fn, void *); + +extern struct fib6_node ip6_routing_table; + +/* + * exported functions + */ + +extern struct fib6_node *fib6_lookup(struct fib6_node *root, + struct in6_addr *daddr, + struct in6_addr *saddr); + +struct fib6_node *fib6_locate(struct fib6_node *root, + struct in6_addr *daddr, int dst_len, + struct in6_addr *saddr, int src_len); + +extern void fib6_clean_tree(struct fib6_node *root, + int (*func)(struct rt6_info *, void *arg), + int prune, void *arg); + +extern int fib6_walk(struct fib6_walker_t *w); +extern int fib6_walk_continue(struct fib6_walker_t *w); + +extern int fib6_add(struct fib6_node *root, + struct rt6_info *rt); + +extern int fib6_del(struct rt6_info *rt); + +extern void inet6_rt_notify(int event, struct rt6_info *rt); + +extern void fib6_run_gc(unsigned long dummy); + +extern void fib6_gc_cleanup(void); + +extern void fib6_init(void); +#endif +#endif diff --git a/release/src/linux/linux/include/net/ip6_fw.h b/release/src/linux/linux/include/net/ip6_fw.h new file mode 100644 index 00000000..7866273d --- /dev/null +++ b/release/src/linux/linux/include/net/ip6_fw.h @@ -0,0 +1,54 @@ +#ifndef __NET_IP6_FW_H +#define __NET_IP6_FW_H + +#define IP6_FW_LISTHEAD 0x1000 +#define IP6_FW_ACCEPT 0x0001 +#define IP6_FW_REJECT 0x0002 + +#define IP6_FW_DEBUG 2 + +#define IP6_FW_MSG_ADD 1 +#define IP6_FW_MSG_DEL 2 +#define IP6_FW_MSG_REPORT 3 + + +/* + * Fast "hack" user interface + */ +struct ip6_fw_msg { + struct in6_addr dst; + struct in6_addr src; + int dst_len; + int src_len; + int action; + int policy; + int proto; + union { + struct { + __u16 sport; + __u16 dport; + } transp; + + unsigned long data; + + int icmp_type; + } u; + + int msg_len; +}; + +#ifdef __KERNEL__ + +#include <net/flow.h> + +struct ip6_fw_rule { + struct flow_rule flowr; + struct ip6_fw_rule *next; + struct ip6_fw_rule *prev; + struct flowi info; + unsigned long policy; +}; + +#endif + +#endif diff --git a/release/src/linux/linux/include/net/ip6_route.h b/release/src/linux/linux/include/net/ip6_route.h new file mode 100644 index 00000000..2ea9eefc --- /dev/null +++ b/release/src/linux/linux/include/net/ip6_route.h @@ -0,0 +1,111 @@ +#ifndef _NET_IP6_ROUTE_H +#define _NET_IP6_ROUTE_H + +#define IP6_RT_PRIO_FW 16 +#define IP6_RT_PRIO_USER 1024 +#define IP6_RT_PRIO_ADDRCONF 256 +#define IP6_RT_PRIO_KERN 512 +#define IP6_RT_FLOW_MASK 0x00ff + +#ifdef __KERNEL__ + +#include <net/flow.h> +#include <net/ip6_fib.h> + +struct pol_chain { + int type; + int priority; + struct fib6_node *rules; + struct pol_chain *next; +}; + +extern struct rt6_info ip6_null_entry; + +extern int ip6_rt_max_size; +extern int ip6_rt_gc_min; +extern int ip6_rt_gc_timeout; +extern int ip6_rt_gc_interval; + +extern void ip6_route_input(struct sk_buff *skb); + +extern struct dst_entry * ip6_route_output(struct sock *sk, + struct flowi *fl); + +extern void ip6_route_init(void); +extern void ip6_route_cleanup(void); + +extern int ipv6_route_ioctl(unsigned int cmd, void *arg); + +extern int ip6_route_add(struct in6_rtmsg *rtmsg); +extern int ip6_del_rt(struct rt6_info *); + +extern int ip6_rt_addr_add(struct in6_addr *addr, + struct net_device *dev); + +extern int ip6_rt_addr_del(struct in6_addr *addr, + struct net_device *dev); + +extern void rt6_sndmsg(int type, struct in6_addr *dst, + struct in6_addr *src, + struct in6_addr *gw, + struct net_device *dev, + int dstlen, int srclen, + int metric, __u32 flags); + +extern struct rt6_info *rt6_lookup(struct in6_addr *daddr, + struct in6_addr *saddr, + int oif, int flags); + +/* + * support functions for ND + * + */ +extern struct rt6_info * rt6_get_dflt_router(struct in6_addr *addr, + struct net_device *dev); +extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr, + struct net_device *dev); + +extern void rt6_purge_dflt_routers(int lst_resort); + +extern void rt6_redirect(struct in6_addr *dest, + struct in6_addr *saddr, + struct neighbour *neigh, + int on_link); + +extern void rt6_pmtu_discovery(struct in6_addr *daddr, + struct in6_addr *saddr, + struct net_device *dev, + u32 pmtu); + +struct nlmsghdr; +struct netlink_callback; +extern int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb); +extern int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); +extern int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); +extern int inet6_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); + +extern void rt6_ifdown(struct net_device *dev); +extern void rt6_mtu_change(struct net_device *dev, unsigned mtu); + +extern rwlock_t rt6_lock; + +/* + * Store a destination cache entry in a socket + * For UDP/RAW sockets this is done on udp_connect. + */ + +static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, + struct in6_addr *daddr) +{ + struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; + struct rt6_info *rt = (struct rt6_info *) dst; + + write_lock(&sk->dst_lock); + __sk_dst_set(sk, dst); + np->daddr_cache = daddr; + np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; + write_unlock(&sk->dst_lock); +} + +#endif +#endif diff --git a/release/src/linux/linux/include/net/ip_fib.h b/release/src/linux/linux/include/net/ip_fib.h new file mode 100644 index 00000000..3b84c5bf --- /dev/null +++ b/release/src/linux/linux/include/net/ip_fib.h @@ -0,0 +1,279 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the Forwarding Information Base. + * + * Authors: A.N.Kuznetsov, <kuznet@ms2.inr.ac.ru> + * + * 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. + */ + +#ifndef _NET_IP_FIB_H +#define _NET_IP_FIB_H + +#include <linux/config.h> + +struct kern_rta +{ + void *rta_dst; + void *rta_src; + int *rta_iif; + int *rta_oif; + void *rta_gw; + u32 *rta_priority; + void *rta_prefsrc; + struct rtattr *rta_mx; + struct rtattr *rta_mp; + unsigned char *rta_protoinfo; + unsigned char *rta_flow; + struct rta_cacheinfo *rta_ci; +}; + +struct fib_nh +{ + struct net_device *nh_dev; + unsigned nh_flags; + unsigned char nh_scope; +#ifdef CONFIG_IP_ROUTE_MULTIPATH + int nh_weight; + int nh_power; +#endif +#ifdef CONFIG_NET_CLS_ROUTE + __u32 nh_tclassid; +#endif + int nh_oif; + u32 nh_gw; +}; + +/* + * This structure contains data shared by many of routes. + */ + +struct fib_info +{ + struct fib_info *fib_next; + struct fib_info *fib_prev; + int fib_treeref; + atomic_t fib_clntref; + int fib_dead; + unsigned fib_flags; + int fib_protocol; + u32 fib_prefsrc; + u32 fib_priority; + unsigned fib_metrics[RTAX_MAX]; +#define fib_mtu fib_metrics[RTAX_MTU-1] +#define fib_window fib_metrics[RTAX_WINDOW-1] +#define fib_rtt fib_metrics[RTAX_RTT-1] +#define fib_advmss fib_metrics[RTAX_ADVMSS-1] + int fib_nhs; +#ifdef CONFIG_IP_ROUTE_MULTIPATH + int fib_power; +#endif + struct fib_nh fib_nh[0]; +#define fib_dev fib_nh[0].nh_dev +}; + + +#ifdef CONFIG_IP_MULTIPLE_TABLES +struct fib_rule; +#endif + +struct fib_result +{ + unsigned char prefixlen; + unsigned char nh_sel; + unsigned char type; + unsigned char scope; + struct fib_info *fi; +#ifdef CONFIG_IP_MULTIPLE_TABLES + struct fib_rule *r; +#endif +}; + + +#ifdef CONFIG_IP_ROUTE_MULTIPATH + +#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) +#define FIB_RES_RESET(res) ((res).nh_sel = 0) + +#else /* CONFIG_IP_ROUTE_MULTIPATH */ + +#define FIB_RES_NH(res) ((res).fi->fib_nh[0]) +#define FIB_RES_RESET(res) + +#endif /* CONFIG_IP_ROUTE_MULTIPATH */ + +#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res)) +#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) +#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) +#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) + +struct fib_table +{ + unsigned char tb_id; + unsigned tb_stamp; + int (*tb_lookup)(struct fib_table *tb, const struct rt_key *key, struct fib_result *res); + int (*tb_insert)(struct fib_table *table, struct rtmsg *r, + struct kern_rta *rta, struct nlmsghdr *n, + struct netlink_skb_parms *req); + int (*tb_delete)(struct fib_table *table, struct rtmsg *r, + struct kern_rta *rta, struct nlmsghdr *n, + struct netlink_skb_parms *req); + int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, + struct netlink_callback *cb); + int (*tb_flush)(struct fib_table *table); + int (*tb_get_info)(struct fib_table *table, char *buf, + int first, int count); + void (*tb_select_default)(struct fib_table *table, + const struct rt_key *key, struct fib_result *res); + + unsigned char tb_data[0]; +}; + +#ifndef CONFIG_IP_MULTIPLE_TABLES + +extern struct fib_table *local_table; +extern struct fib_table *main_table; + +static inline struct fib_table *fib_get_table(int id) +{ + if (id != RT_TABLE_LOCAL) + return main_table; + return local_table; +} + +static inline struct fib_table *fib_new_table(int id) +{ + return fib_get_table(id); +} + +static inline int fib_lookup(const struct rt_key *key, struct fib_result *res) +{ + if (local_table->tb_lookup(local_table, key, res) && + main_table->tb_lookup(main_table, key, res)) + return -ENETUNREACH; + return 0; +} + +static inline void fib_select_default(const struct rt_key *key, struct fib_result *res) +{ + if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) + main_table->tb_select_default(main_table, key, res); +} + +#else /* CONFIG_IP_MULTIPLE_TABLES */ +#define local_table (fib_tables[RT_TABLE_LOCAL]) +#define main_table (fib_tables[RT_TABLE_MAIN]) + +extern struct fib_table * fib_tables[RT_TABLE_MAX+1]; +extern int fib_lookup(const struct rt_key *key, struct fib_result *res); +extern struct fib_table *__fib_new_table(int id); +extern void fib_rule_put(struct fib_rule *r); + +static inline struct fib_table *fib_get_table(int id) +{ + if (id == 0) + id = RT_TABLE_MAIN; + + return fib_tables[id]; +} + +static inline struct fib_table *fib_new_table(int id) +{ + if (id == 0) + id = RT_TABLE_MAIN; + + return fib_tables[id] ? : __fib_new_table(id); +} + +extern void fib_select_default(const struct rt_key *key, struct fib_result *res); + +#endif /* CONFIG_IP_MULTIPLE_TABLES */ + +/* Exported by fib_frontend.c */ +extern void ip_fib_init(void); +extern void fib_flush(void); +extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); +extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); +extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); +extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb); +extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif, + struct net_device *dev, u32 *spec_dst, u32 *itag); +extern void fib_select_multipath(const struct rt_key *key, struct fib_result *res); + +/* Exported by fib_semantics.c */ +extern int ip_fib_check_default(u32 gw, struct net_device *dev); +extern void fib_release_info(struct fib_info *); +extern int fib_semantic_match(int type, struct fib_info *, + const struct rt_key *, struct fib_result*); +extern struct fib_info *fib_create_info(const struct rtmsg *r, struct kern_rta *rta, + const struct nlmsghdr *, int *err); +extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *, struct kern_rta *rta, struct fib_info *fi); +extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, + u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos, + struct fib_info *fi); +extern int fib_sync_down(u32 local, struct net_device *dev, int force); +extern int fib_sync_up(struct net_device *dev); +extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm, + struct kern_rta *rta, struct rtentry *r); +extern void fib_node_get_info(int type, int dead, struct fib_info *fi, u32 prefix, u32 mask, char *buffer); +extern u32 __fib_res_prefsrc(struct fib_result *res); + +/* Exported by fib_hash.c */ +extern struct fib_table *fib_hash_init(int id); + +#ifdef CONFIG_IP_MULTIPLE_TABLES +/* Exported by fib_rules.c */ + +extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); +extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); +extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb); +extern u32 fib_rules_map_destination(u32 daddr, struct fib_result *res); +#ifdef CONFIG_NET_CLS_ROUTE +extern u32 fib_rules_tclass(struct fib_result *res); +#endif +extern u32 fib_rules_policy(u32 saddr, struct fib_result *res, unsigned *flags); +extern void fib_rules_init(void); +#endif + +static inline void fib_combine_itag(u32 *itag, struct fib_result *res) +{ +#ifdef CONFIG_NET_CLS_ROUTE +#ifdef CONFIG_IP_MULTIPLE_TABLES + u32 rtag; +#endif + *itag = FIB_RES_NH(*res).nh_tclassid<<16; +#ifdef CONFIG_IP_MULTIPLE_TABLES + rtag = fib_rules_tclass(res); + if (*itag == 0) + *itag = (rtag<<16); + *itag |= (rtag>>16); +#endif +#endif +} + +extern void free_fib_info(struct fib_info *fi); + +static inline void fib_info_put(struct fib_info *fi) +{ + if (atomic_dec_and_test(&fi->fib_clntref)) + free_fib_info(fi); +} + +static inline void fib_res_put(struct fib_result *res) +{ + if (res->fi) + fib_info_put(res->fi); +#ifdef CONFIG_IP_MULTIPLE_TABLES + if (res->r) + fib_rule_put(res->r); +#endif +} + + +#endif /* _NET_FIB_H */ diff --git a/release/src/linux/linux/include/net/ipconfig.h b/release/src/linux/linux/include/net/ipconfig.h new file mode 100644 index 00000000..6bb806c6 --- /dev/null +++ b/release/src/linux/linux/include/net/ipconfig.h @@ -0,0 +1,38 @@ +/* + * $Id: ipconfig.h,v 1.1.1.4 2003/10/14 08:09:28 sparq Exp $ + * + * Copyright (C) 1997 Martin Mares + * + * Automatic IP Layer Configuration + */ + +/* The following are initdata: */ + +extern int ic_enable; /* Enable or disable the whole shebang */ + +extern int ic_proto_enabled; /* Protocols enabled (see IC_xxx) */ +extern int ic_host_name_set; /* Host name set by ipconfig? */ +extern int ic_set_manually; /* IPconfig parameters set manually */ + +extern u32 ic_myaddr; /* My IP address */ +extern u32 ic_netmask; /* Netmask for local subnet */ +extern u32 ic_gateway; /* Gateway IP address */ + +extern u32 ic_servaddr; /* Boot server IP address */ + +extern u32 root_server_addr; /* Address of NFS server */ +extern u8 root_server_path[]; /* Path to mount as root */ + + + +/* The following are persistent (not initdata): */ + +extern int ic_proto_used; /* Protocol used, if any */ +extern u32 ic_nameserver; /* DNS server IP address */ +extern u8 ic_domain[]; /* DNS (not NIS) domain name */ + +/* bits in ic_proto_{enabled,used} */ +#define IC_PROTO 0xFF /* Protocols mask: */ +#define IC_BOOTP 0x01 /* BOOTP (or DHCP, see below) */ +#define IC_RARP 0x02 /* RARP */ +#define IC_USE_DHCP 0x100 /* If on, use DHCP instead of BOOTP */ diff --git a/release/src/linux/linux/include/net/ipip.h b/release/src/linux/linux/include/net/ipip.h new file mode 100644 index 00000000..ac643876 --- /dev/null +++ b/release/src/linux/linux/include/net/ipip.h @@ -0,0 +1,53 @@ +#ifndef __NET_IPIP_H +#define __NET_IPIP_H 1 + +#include <linux/if_tunnel.h> + +/* Keep error state on tunnel for 30 sec */ +#define IPTUNNEL_ERR_TIMEO (30*HZ) + +struct ip_tunnel +{ + struct ip_tunnel *next; + struct net_device *dev; + struct net_device_stats stat; + + int recursion; /* Depth of hard_start_xmit recursion */ + int err_count; /* Number of arrived ICMP errors */ + unsigned long err_time; /* Time when the last ICMP error arrived */ + + /* These four fields used only by GRE */ + __u32 i_seqno; /* The last seen seqno */ + __u32 o_seqno; /* The last output seqno */ + int hlen; /* Precalculated GRE header length */ + int mlink; + + struct ip_tunnel_parm parms; +}; + +#define IPTUNNEL_XMIT() do { \ + int err; \ + int pkt_len = skb->len; \ + \ + skb->ip_summed = CHECKSUM_NONE; \ + iph->tot_len = htons(skb->len); \ + ip_select_ident(iph, &rt->u.dst, NULL); \ + ip_send_check(iph); \ + \ + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, do_ip_send); \ + if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { \ + stats->tx_bytes += pkt_len; \ + stats->tx_packets++; \ + } else { \ + stats->tx_errors++; \ + stats->tx_aborted_errors++; \ + } \ +} while (0) + + +extern int ipip_init(void); +extern int ipgre_init(void); +extern int sit_init(void); +extern void sit_cleanup(void); + +#endif diff --git a/release/src/linux/linux/include/net/ipv6.h b/release/src/linux/linux/include/net/ipv6.h new file mode 100644 index 00000000..c76411d7 --- /dev/null +++ b/release/src/linux/linux/include/net/ipv6.h @@ -0,0 +1,343 @@ +/* + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * $Id: ipv6.h,v 1.1.1.4 2003/10/14 08:09:28 sparq Exp $ + * + * 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. + */ + +#ifndef _NET_IPV6_H +#define _NET_IPV6_H + +#include <linux/ipv6.h> +#include <asm/hardirq.h> +#include <net/ndisc.h> +#include <net/flow.h> + +#define SIN6_LEN_RFC2133 24 + +/* + * NextHeader field of IPv6 header + */ + +#define NEXTHDR_HOP 0 /* Hop-by-hop option header. */ +#define NEXTHDR_TCP 6 /* TCP segment. */ +#define NEXTHDR_UDP 17 /* UDP message. */ +#define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */ +#define NEXTHDR_ROUTING 43 /* Routing header. */ +#define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */ +#define NEXTHDR_ESP 50 /* Encapsulating security payload. */ +#define NEXTHDR_AUTH 51 /* Authentication header. */ +#define NEXTHDR_ICMP 58 /* ICMP for IPv6. */ +#define NEXTHDR_NONE 59 /* No next header */ +#define NEXTHDR_DEST 60 /* Destination options header. */ + +#define NEXTHDR_MAX 255 + + + +#define IPV6_DEFAULT_HOPLIMIT 64 +#define IPV6_DEFAULT_MCASTHOPS 1 + +/* + * Addr type + * + * type - unicast | multicast | anycast + * scope - local | site | global + * v4 - compat + * v4mapped + * any + * loopback + */ + +#define IPV6_ADDR_ANY 0x0000U + +#define IPV6_ADDR_UNICAST 0x0001U +#define IPV6_ADDR_MULTICAST 0x0002U +#define IPV6_ADDR_ANYCAST 0x0004U + +#define IPV6_ADDR_LOOPBACK 0x0010U +#define IPV6_ADDR_LINKLOCAL 0x0020U +#define IPV6_ADDR_SITELOCAL 0x0040U + +#define IPV6_ADDR_COMPATv4 0x0080U + +#define IPV6_ADDR_SCOPE_MASK 0x00f0U + +#define IPV6_ADDR_MAPPED 0x1000U +#define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */ + +/* + * fragmentation header + */ + +struct frag_hdr { + unsigned char nexthdr; + unsigned char reserved; + unsigned short frag_off; + __u32 identification; +}; + +#ifdef __KERNEL__ + +#include <net/sock.h> + +extern struct ipv6_mib ipv6_statistics[NR_CPUS*2]; +#define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field) +#define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field) +#define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field) +extern struct icmpv6_mib icmpv6_statistics[NR_CPUS*2]; +#define ICMP6_INC_STATS(field) SNMP_INC_STATS(icmpv6_statistics, field) +#define ICMP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmpv6_statistics, field) +#define ICMP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmpv6_statistics, field) +extern struct udp_mib udp_stats_in6[NR_CPUS*2]; +#define UDP6_INC_STATS(field) SNMP_INC_STATS(udp_stats_in6, field) +#define UDP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_stats_in6, field) +#define UDP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_stats_in6, field) +extern atomic_t inet6_sock_nr; + +struct ip6_ra_chain +{ + struct ip6_ra_chain *next; + struct sock *sk; + int sel; + void (*destructor)(struct sock *); +}; + +extern struct ip6_ra_chain *ip6_ra_chain; +extern rwlock_t ip6_ra_lock; + +/* + This structure is prepared by protocol, when parsing + ancillary data and passed to IPv6. + */ + +struct ipv6_txoptions +{ + /* Length of this structure */ + int tot_len; + + /* length of extension headers */ + + __u16 opt_flen; /* after fragment hdr */ + __u16 opt_nflen; /* before fragment hdr */ + + struct ipv6_opt_hdr *hopopt; + struct ipv6_opt_hdr *dst0opt; + struct ipv6_rt_hdr *srcrt; /* Routing Header */ + struct ipv6_opt_hdr *auth; + struct ipv6_opt_hdr *dst1opt; + + /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ +}; + +struct ip6_flowlabel +{ + struct ip6_flowlabel *next; + u32 label; + struct in6_addr dst; + struct ipv6_txoptions *opt; + atomic_t users; + u32 linger; + u8 share; + u32 owner; + unsigned long lastuse; + unsigned long expires; +}; + +#define IPV6_FLOWINFO_MASK __constant_htonl(0x0FFFFFFF) +#define IPV6_FLOWLABEL_MASK __constant_htonl(0x000FFFFF) + +struct ipv6_fl_socklist +{ + struct ipv6_fl_socklist *next; + struct ip6_flowlabel *fl; +}; + +extern struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, u32 label); +extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, + struct ip6_flowlabel * fl, + struct ipv6_txoptions * fopt); +extern void fl6_free_socklist(struct sock *sk); +extern int ipv6_flowlabel_opt(struct sock *sk, char *optval, int optlen); +extern void ip6_flowlabel_init(void); +extern void ip6_flowlabel_cleanup(void); + +static inline void fl6_sock_release(struct ip6_flowlabel *fl) +{ + if (fl) + atomic_dec(&fl->users); +} + +extern int ip6_ra_control(struct sock *sk, int sel, + void (*destructor)(struct sock *)); + + +extern int ip6_call_ra_chain(struct sk_buff *skb, int sel); + +extern int ipv6_reassembly(struct sk_buff **skb, int); + +extern int ipv6_parse_hopopts(struct sk_buff *skb, int); + +extern int ipv6_parse_exthdrs(struct sk_buff **skb, int); + +extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); + +extern int ip6_frag_nqueues; +extern atomic_t ip6_frag_mem; + +#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */ + +/* + * Function prototype for build_xmit + */ + +typedef int (*inet_getfrag_t) (const void *data, + struct in6_addr *addr, + char *, + unsigned int, unsigned int); + + +extern int ipv6_addr_type(struct in6_addr *addr); + +static inline int ipv6_addr_scope(struct in6_addr *addr) +{ + return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; +} + +static inline int ipv6_addr_cmp(struct in6_addr *a1, struct in6_addr *a2) +{ + return memcmp((void *) a1, (void *) a2, sizeof(struct in6_addr)); +} + +static inline void ipv6_addr_copy(struct in6_addr *a1, struct in6_addr *a2) +{ + memcpy((void *) a1, (void *) a2, sizeof(struct in6_addr)); +} + +#ifndef __HAVE_ARCH_ADDR_SET +static inline void ipv6_addr_set(struct in6_addr *addr, + __u32 w1, __u32 w2, + __u32 w3, __u32 w4) +{ + addr->s6_addr32[0] = w1; + addr->s6_addr32[1] = w2; + addr->s6_addr32[2] = w3; + addr->s6_addr32[3] = w4; +} +#endif + +static inline int ipv6_addr_any(struct in6_addr *a) +{ + return ((a->s6_addr32[0] | a->s6_addr32[1] | + a->s6_addr32[2] | a->s6_addr32[3] ) == 0); +} + +/* + * Prototypes exported by ipv6 + */ + +/* + * rcv function (called from netdevice level) + */ + +extern int ipv6_rcv(struct sk_buff *skb, + struct net_device *dev, + struct packet_type *pt); + +/* + * upper-layer output functions + */ +extern int ip6_xmit(struct sock *sk, + struct sk_buff *skb, + struct flowi *fl, + struct ipv6_txoptions *opt); + +extern int ip6_nd_hdr(struct sock *sk, + struct sk_buff *skb, + struct net_device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr, + int proto, int len); + +extern int ip6_build_xmit(struct sock *sk, + inet_getfrag_t getfrag, + const void *data, + struct flowi *fl, + unsigned length, + struct ipv6_txoptions *opt, + int hlimit, int flags); + +/* + * skb processing functions + */ + +extern int ip6_output(struct sk_buff *skb); +extern int ip6_forward(struct sk_buff *skb); +extern int ip6_input(struct sk_buff *skb); +extern int ip6_mc_input(struct sk_buff *skb); + +/* + * Extension header (options) processing + */ + +extern u8 * ipv6_build_nfrag_opts(struct sk_buff *skb, + u8 *prev_hdr, + struct ipv6_txoptions *opt, + struct in6_addr *daddr, + u32 jumbolen); +extern u8 * ipv6_build_frag_opts(struct sk_buff *skb, + u8 *prev_hdr, + struct ipv6_txoptions *opt); +extern void ipv6_push_nfrag_opts(struct sk_buff *skb, + struct ipv6_txoptions *opt, + u8 *proto, + struct in6_addr **daddr_p); +extern void ipv6_push_frag_opts(struct sk_buff *skb, + struct ipv6_txoptions *opt, + u8 *proto); + +extern int ipv6_skip_exthdr(struct sk_buff *, int start, + u8 *nexthdrp, int len); + +extern int ipv6_ext_hdr(u8 nexthdr); + +extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk, + struct ipv6_rt_hdr *hdr); + + +/* + * socket options (ipv6_sockglue.c) + */ + +extern int ipv6_setsockopt(struct sock *sk, int level, + int optname, char *optval, + int optlen); +extern int ipv6_getsockopt(struct sock *sk, int level, + int optname, char *optval, + int *optlen); + +extern void ipv6_packet_init(void); + +extern void ipv6_netdev_notif_init(void); + +extern void ipv6_packet_cleanup(void); + +extern void ipv6_netdev_notif_cleanup(void); + +extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len); +extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, u16 port, + u32 info, u8 *payload); +extern void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info); + +#endif /* __KERNEL__ */ +#endif /* _NET_IPV6_H */ + + + diff --git a/release/src/linux/linux/include/net/ipx.h b/release/src/linux/linux/include/net/ipx.h new file mode 100644 index 00000000..78c19371 --- /dev/null +++ b/release/src/linux/linux/include/net/ipx.h @@ -0,0 +1,96 @@ +/* + * The following information is in its entirety obtained from: + * + * Novell 'IPX Router Specification' Version 1.10 + * Part No. 107-000029-001 + * + * Which is available from ftp.novell.com + */ + +#ifndef _NET_INET_IPX_H_ +#define _NET_INET_IPX_H_ + +#include <linux/netdevice.h> +#include <net/datalink.h> +#include <linux/ipx.h> + +typedef struct +{ + __u32 net; + __u8 node[IPX_NODE_LEN]; + __u16 sock; +} ipx_address; + +#define ipx_broadcast_node "\377\377\377\377\377\377" +#define ipx_this_node "\0\0\0\0\0\0" + +#define IPX_MAX_PPROP_HOPS 8 + +struct ipxhdr +{ + __u16 ipx_checksum __attribute__ ((packed)); +#define IPX_NO_CHECKSUM 0xFFFF + __u16 ipx_pktsize __attribute__ ((packed)); + __u8 ipx_tctrl; + __u8 ipx_type; +#define IPX_TYPE_UNKNOWN 0x00 +#define IPX_TYPE_RIP 0x01 /* may also be 0 */ +#define IPX_TYPE_SAP 0x04 /* may also be 0 */ +#define IPX_TYPE_SPX 0x05 /* SPX protocol */ +#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */ +#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */ + ipx_address ipx_dest __attribute__ ((packed)); + ipx_address ipx_source __attribute__ ((packed)); +}; + +typedef struct ipx_interface { + /* IPX address */ + __u32 if_netnum; + unsigned char if_node[IPX_NODE_LEN]; + atomic_t refcnt; + + /* physical device info */ + struct net_device *if_dev; + struct datalink_proto *if_dlink; + unsigned short if_dlink_type; + + /* socket support */ + unsigned short if_sknum; + struct sock *if_sklist; + spinlock_t if_sklist_lock; + + /* administrative overhead */ + int if_ipx_offset; + unsigned char if_internal; + unsigned char if_primary; + + struct ipx_interface *if_next; +} ipx_interface; + +typedef struct ipx_route { + __u32 ir_net; + ipx_interface *ir_intrfc; + unsigned char ir_routed; + unsigned char ir_router_node[IPX_NODE_LEN]; + struct ipx_route *ir_next; + atomic_t refcnt; +} ipx_route; + +#ifdef __KERNEL__ +struct ipx_cb { + u8 ipx_tctrl; + u32 ipx_dest_net; + u32 ipx_source_net; + struct { + u32 netnum; + int index; + } last_hop; +}; +#endif +#define IPX_MIN_EPHEMERAL_SOCKET 0x4000 +#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff + +extern int ipx_register_spx(struct proto_ops **, struct net_proto_family *); +extern int ipx_unregister_spx(void); + +#endif /* def _NET_INET_IPX_H_ */ diff --git a/release/src/linux/linux/include/net/irda/ali-ircc.h b/release/src/linux/linux/include/net/irda/ali-ircc.h new file mode 100644 index 00000000..dbd5a1cf --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ali-ircc.h @@ -0,0 +1,229 @@ +/********************************************************************* + * + * Filename: ali-ircc.h + * Version: 0.5 + * Description: Driver for the ALI M1535D and M1543C FIR Controller + * Status: Experimental. + * Author: Benjamin Kong <benjamin_kong@ali.com.tw> + * Created at: 2000/10/16 03:46PM + * Modified at: 2001/1/3 02:56PM + * Modified by: Benjamin Kong <benjamin_kong@ali.com.tw> + * + * Copyright (c) 2000 Benjamin Kong <benjamin_kong@ali.com.tw> + * All Rights Reserved + * + * 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. + * + ********************************************************************/ + +#ifndef ALI_IRCC_H +#define ALI_IRCC_H + +#include <linux/time.h> + +#include <linux/spinlock.h> +#include <linux/pm.h> +#include <asm/io.h> + +/* SIR Register */ +/* Usr definition of linux/serial_reg.h */ + +/* FIR Register */ +#define BANK0 0x20 +#define BANK1 0x21 +#define BANK2 0x22 +#define BANK3 0x23 + +#define FIR_MCR 0x07 /* Master Control Register */ + +/* Bank 0 */ +#define FIR_DR 0x00 /* Alias 0, FIR Data Register (R/W) */ +#define FIR_IER 0x01 /* Alias 1, FIR Interrupt Enable Register (R/W) */ +#define FIR_IIR 0x02 /* Alias 2, FIR Interrupt Identification Register (Read only) */ +#define FIR_LCR_A 0x03 /* Alias 3, FIR Line Control Register A (R/W) */ +#define FIR_LCR_B 0x04 /* Alias 4, FIR Line Control Register B (R/W) */ +#define FIR_LSR 0x05 /* Alias 5, FIR Line Status Register (R/W) */ +#define FIR_BSR 0x06 /* Alias 6, FIR Bus Status Register (Read only) */ + + + /* Alias 1 */ + #define IER_FIFO 0x10 /* FIR FIFO Interrupt Enable */ + #define IER_TIMER 0x20 /* Timer Interrupt Enable */ + #define IER_EOM 0x40 /* End of Message Interrupt Enable */ + #define IER_ACT 0x80 /* Active Frame Interrupt Enable */ + + /* Alias 2 */ + #define IIR_FIFO 0x10 /* FIR FIFO Interrupt */ + #define IIR_TIMER 0x20 /* Timer Interrupt */ + #define IIR_EOM 0x40 /* End of Message Interrupt */ + #define IIR_ACT 0x80 /* Active Frame Interrupt */ + + /* Alias 3 */ + #define LCR_A_FIFO_RESET 0x80 /* FIFO Reset */ + + /* Alias 4 */ + #define LCR_B_BW 0x10 /* Brick Wall */ + #define LCR_B_SIP 0x20 /* SIP Enable */ + #define LCR_B_TX_MODE 0x40 /* Transmit Mode */ + #define LCR_B_RX_MODE 0x80 /* Receive Mode */ + + /* Alias 5 */ + #define LSR_FIR_LSA 0x00 /* FIR Line Status Address */ + #define LSR_FRAME_ABORT 0x08 /* Frame Abort */ + #define LSR_CRC_ERROR 0x10 /* CRC Error */ + #define LSR_SIZE_ERROR 0x20 /* Size Error */ + #define LSR_FRAME_ERROR 0x40 /* Frame Error */ + #define LSR_FIFO_UR 0x80 /* FIFO Underrun */ + #define LSR_FIFO_OR 0x80 /* FIFO Overrun */ + + /* Alias 6 */ + #define BSR_FIFO_NOT_EMPTY 0x80 /* FIFO Not Empty */ + +/* Bank 1 */ +#define FIR_CR 0x00 /* Alias 0, FIR Configuration Register (R/W) */ +#define FIR_FIFO_TR 0x01 /* Alias 1, FIR FIFO Threshold Register (R/W) */ +#define FIR_DMA_TR 0x02 /* Alias 2, FIR DMA Threshold Register (R/W) */ +#define FIR_TIMER_IIR 0x03 /* Alias 3, FIR Timer interrupt interval register (W/O) */ +#define FIR_FIFO_FR 0x03 /* Alias 3, FIR FIFO Flag register (R/O) */ +#define FIR_FIFO_RAR 0x04 /* Alias 4, FIR FIFO Read Address register (R/O) */ +#define FIR_FIFO_WAR 0x05 /* Alias 5, FIR FIFO Write Address register (R/O) */ +#define FIR_TR 0x06 /* Alias 6, Test REgister (W/O) */ + + /* Alias 0 */ + #define CR_DMA_EN 0x01 /* DMA Enable */ + #define CR_DMA_BURST 0x02 /* DMA Burst Mode */ + #define CR_TIMER_EN 0x08 /* Timer Enable */ + + /* Alias 3 */ + #define TIMER_IIR_500 0x00 /* 500 us */ + #define TIMER_IIR_1ms 0x01 /* 1 ms */ + #define TIMER_IIR_2ms 0x02 /* 2 ms */ + #define TIMER_IIR_4ms 0x03 /* 4 ms */ + +/* Bank 2 */ +#define FIR_IRDA_CR 0x00 /* Alias 0, IrDA Control Register (R/W) */ +#define FIR_BOF_CR 0x01 /* Alias 1, BOF Count Register (R/W) */ +#define FIR_BW_CR 0x02 /* Alias 2, Brick Wall Count Register (R/W) */ +#define FIR_TX_DSR_HI 0x03 /* Alias 3, TX Data Size Register (high) (R/W) */ +#define FIR_TX_DSR_LO 0x04 /* Alias 4, TX Data Size Register (low) (R/W) */ +#define FIR_RX_DSR_HI 0x05 /* Alias 5, RX Data Size Register (high) (R/W) */ +#define FIR_RX_DSR_LO 0x06 /* Alias 6, RX Data Size Register (low) (R/W) */ + + /* Alias 0 */ + #define IRDA_CR_HDLC1152 0x80 /* 1.152Mbps HDLC Select */ + #define IRDA_CR_CRC 0X40 /* CRC Select. */ + #define IRDA_CR_HDLC 0x20 /* HDLC select. */ + #define IRDA_CR_HP_MODE 0x10 /* HP mode (read only) */ + #define IRDA_CR_SD_ST 0x08 /* SD/MODE State. */ + #define IRDA_CR_FIR_SIN 0x04 /* FIR SIN Select. */ + #define IRDA_CR_ITTX_0 0x02 /* SOUT State. IRTX force to 0 */ + #define IRDA_CR_ITTX_1 0x03 /* SOUT State. IRTX force to 1 */ + +/* Bank 3 */ +#define FIR_ID_VR 0x00 /* Alias 0, FIR ID Version Register (R/O) */ +#define FIR_MODULE_CR 0x01 /* Alias 1, FIR Module Control Register (R/W) */ +#define FIR_IO_BASE_HI 0x02 /* Alias 2, FIR Higher I/O Base Address Register (R/O) */ +#define FIR_IO_BASE_LO 0x03 /* Alias 3, FIR Lower I/O Base Address Register (R/O) */ +#define FIR_IRQ_CR 0x04 /* Alias 4, FIR IRQ Channel Register (R/O) */ +#define FIR_DMA_CR 0x05 /* Alias 5, FIR DMA Channel Register (R/O) */ + +struct ali_chip { + char *name; + int cfg[2]; + unsigned char entr1; + unsigned char entr2; + unsigned char cid_index; + unsigned char cid_value; + int (*probe)(struct ali_chip *chip, chipio_t *info); + int (*init)(struct ali_chip *chip, chipio_t *info); +}; +typedef struct ali_chip ali_chip_t; + + +/* DMA modes needed */ +#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ +#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ + +#define MAX_TX_WINDOW 7 +#define MAX_RX_WINDOW 7 + +#define TX_FIFO_Threshold 8 +#define RX_FIFO_Threshold 1 +#define TX_DMA_Threshold 1 +#define RX_DMA_Threshold 1 + +/* For storing entries in the status FIFO */ + +struct st_fifo_entry { + int status; + int len; +}; + +struct st_fifo { + struct st_fifo_entry entries[MAX_RX_WINDOW]; + int pending_bytes; + int head; + int tail; + int len; +}; + +struct frame_cb { + void *start; /* Start of frame in DMA mem */ + int len; /* Lenght of frame in DMA mem */ +}; + +struct tx_fifo { + struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ + int ptr; /* Currently being sent */ + int len; /* Lenght of queue */ + int free; /* Next free slot */ + void *tail; /* Next free start in DMA mem */ +}; + +/* Private data for each instance */ +struct ali_ircc_cb { + + struct st_fifo st_fifo; /* Info about received frames */ + struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + __u8 ier; /* Interrupt enable register */ + + __u8 InterruptID; /* Interrupt ID */ + __u8 BusStatus; /* Bus Status */ + __u8 LineStatus; /* Line Status */ + + unsigned char rcvFramesOverflow; + + struct timeval stamp; + struct timeval now; + + spinlock_t lock; /* For serializing operations */ + + __u32 flags; /* Interface flags */ + __u32 new_speed; + int index; /* Instance index */ + + unsigned char fifo_opti_buf; + + struct pm_dev *dev; +}; + +static inline void switch_bank(int iobase, int bank) +{ + outb(bank, iobase+FIR_MCR); +} + +#endif /* ALI_IRCC_H */ diff --git a/release/src/linux/linux/include/net/irda/au1000_ircc.h b/release/src/linux/linux/include/net/irda/au1000_ircc.h new file mode 100644 index 00000000..ac621e95 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/au1000_ircc.h @@ -0,0 +1,128 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Au1000 IrDA driver. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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. + */ + +#ifndef AU1000_IRCC_H +#define AU1000_IRCC_H + +#include <linux/time.h> + +#include <linux/spinlock.h> +#include <linux/pm.h> +#include <asm/io.h> + +#define NUM_IR_IFF 1 +#define NUM_IR_DESC 64 +#define RING_SIZE_4 0x0 +#define RING_SIZE_16 0x3 +#define RING_SIZE_64 0xF +#define MAX_NUM_IR_DESC 64 +#define MAX_BUF_SIZE 2048 + +#define BPS_115200 0 +#define BPS_57600 1 +#define BPS_38400 2 +#define BPS_19200 5 +#define BPS_9600 11 +#define BPS_2400 47 + +/* Ring descriptor flags */ +#define AU_OWN (1<<7) /* tx,rx */ + +#define IR_DIS_CRC (1<<6) /* tx */ +#define IR_BAD_CRC (1<<5) /* tx */ +#define IR_NEED_PULSE (1<<4) /* tx */ +#define IR_FORCE_UNDER (1<<3) /* tx */ +#define IR_DISABLE_TX (1<<2) /* tx */ +#define IR_HW_UNDER (1<<0) /* tx */ +#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER) + +#define IR_PHY_ERROR (1<<6) /* rx */ +#define IR_CRC_ERROR (1<<5) /* rx */ +#define IR_MAX_LEN (1<<4) /* rx */ +#define IR_FIFO_OVER (1<<3) /* rx */ +#define IR_SIR_ERROR (1<<2) /* rx */ +#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \ + IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR) + +typedef struct db_dest { + struct db_dest *pnext; + volatile u32 *vaddr; + dma_addr_t dma_addr; +} db_dest_t; + + +typedef struct ring_desc { + u8 count_0; /* 7:0 */ + u8 count_1; /* 12:8 */ + u8 reserved; + u8 flags; + u8 addr_0; /* 7:0 */ + u8 addr_1; /* 15:8 */ + u8 addr_2; /* 23:16 */ + u8 addr_3; /* 31:24 */ +} ring_dest_t; + + +/* Private data for each instance */ +struct au1k_private { + + db_dest_t *pDBfree; + db_dest_t db[2*NUM_IR_DESC]; + volatile ring_dest_t *rx_ring[NUM_IR_DESC]; + volatile ring_dest_t *tx_ring[NUM_IR_DESC]; + db_dest_t *rx_db_inuse[NUM_IR_DESC]; + db_dest_t *tx_db_inuse[NUM_IR_DESC]; + u32 rx_head; + u32 tx_head; + u32 tx_tail; + u32 tx_full; + + iobuff_t rx_buff; + + struct net_device *netdev; + struct net_device_stats stats; + + struct timeval stamp; + struct timeval now; + struct qos_info qos; + struct irlap_cb *irlap; + + u8 open; + u32 flags; /* Interface flags */ + u32 speed; + u32 newspeed; + + u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ + struct timer_list timer; + + spinlock_t lock; /* For serializing operations */ + struct pm_dev *dev; +}; +#endif /* AU1000_IRCC_H */ diff --git a/release/src/linux/linux/include/net/irda/crc.h b/release/src/linux/linux/include/net/irda/crc.h new file mode 100644 index 00000000..61a5a648 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/crc.h @@ -0,0 +1,33 @@ +/********************************************************************* + * + * Filename: crc.h + * Version: + * Description: CRC routines + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Aug 4 20:40:53 1997 + * Modified at: Sun May 2 20:25:23 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + ********************************************************************/ + +#ifndef IRDA_CRC_H +#define IRDA_CRC_H + +#include <linux/types.h> + +#define INIT_FCS 0xffff /* Initial FCS value */ +#define GOOD_FCS 0xf0b8 /* Good final FCS value */ + +extern __u16 const irda_crc16_table[]; + +/* Recompute the FCS with one more character appended. */ +static inline __u16 irda_fcs(__u16 fcs, __u8 c) +{ + return (((fcs) >> 8) ^ irda_crc16_table[((fcs) ^ (c)) & 0xff]); +} + +/* Recompute the FCS with len bytes appended. */ +unsigned short crc_calc( __u16 fcs, __u8 const *buf, size_t len); + +#endif diff --git a/release/src/linux/linux/include/net/irda/discovery.h b/release/src/linux/linux/include/net/irda/discovery.h new file mode 100644 index 00000000..b69dd381 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/discovery.h @@ -0,0 +1,78 @@ +/********************************************************************* + * + * Filename: discovery.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Apr 6 16:53:53 1999 + * Modified at: Tue Oct 5 10:05:10 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef DISCOVERY_H +#define DISCOVERY_H + +#include <asm/param.h> + +#include <net/irda/irda.h> +#include <net/irda/irqueue.h> + +#define DISCOVERY_EXPIRE_TIMEOUT (2*sysctl_discovery_timeout*HZ) +#define DISCOVERY_DEFAULT_SLOTS 0 + +/* Types of discovery */ +typedef enum { + DISCOVERY_LOG, /* What's in our discovery log */ + DISCOVERY_ACTIVE, /* Doing our own discovery on the medium */ + DISCOVERY_PASSIVE, /* Peer doing discovery on the medium */ + EXPIRY_TIMEOUT, /* Entry expired due to timeout */ +} DISCOVERY_MODE; + +#define NICKNAME_MAX_LEN 21 + +/* + * The DISCOVERY structure is used for both discovery requests and responses + */ +typedef struct discovery_t { + irda_queue_t q; /* Must be first! */ + + __u32 saddr; /* Which link the device was discovered */ + __u32 daddr; /* Remote device address */ + LAP_REASON condition; /* More info about the discovery */ + + __u16_host_order hints; /* Discovery hint bits */ + __u8 charset; /* Encoding of nickname */ + char nickname[22]; /* The name of the device (21 bytes + \0) */ + int name_len; /* Lenght of nickname */ + + int gen_addr_bit; /* Need to generate a new device address? */ + int nslots; /* Number of slots to use when discovering */ + unsigned long timestamp; /* Time discovered */ + unsigned long first_timestamp; /* First time discovered */ +} discovery_t; + +void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *discovery); +void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log); +void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force); +struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, __u16 mask); + +#endif diff --git a/release/src/linux/linux/include/net/irda/ircomm_core.h b/release/src/linux/linux/include/net/irda/ircomm_core.h new file mode 100644 index 00000000..3e891c20 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ircomm_core.h @@ -0,0 +1,107 @@ +/********************************************************************* + * + * Filename: ircomm_core.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Wed Jun 9 08:58:43 1999 + * Modified at: Mon Dec 13 11:52:29 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRCOMM_CORE_H +#define IRCOMM_CORE_H + +#include <net/irda/irda.h> +#include <net/irda/ircomm_event.h> + +#define IRCOMM_MAGIC 0x98347298 +#define IRCOMM_HEADER_SIZE 1 + +struct ircomm_cb; /* Forward decl. */ + +/* + * A small call-table, so we don't have to check the service-type whenever + * we want to do something + */ +typedef struct { + int (*data_request)(struct ircomm_cb *, struct sk_buff *, int clen); + int (*connect_request)(struct ircomm_cb *, struct sk_buff *, + struct ircomm_info *); + int (*connect_response)(struct ircomm_cb *, struct sk_buff *); + int (*disconnect_request)(struct ircomm_cb *, struct sk_buff *, + struct ircomm_info *); +} call_t; + +struct ircomm_cb { + irda_queue_t queue; + magic_t magic; + + notify_t notify; + call_t issue; + + int state; + int line; /* Which TTY line we are using */ + + struct tsap_cb *tsap; + struct lsap_cb *lsap; + + __u8 dlsap_sel; /* Destination LSAP/TSAP selector */ + __u8 slsap_sel; /* Source LSAP/TSAP selector */ + + __u32 saddr; /* Source device address (link we are using) */ + __u32 daddr; /* Destination device address */ + + int max_header_size; /* Header space we must reserve for each frame */ + int max_data_size; /* The amount of data we can fill in each frame */ + + LOCAL_FLOW flow_status; /* Used by ircomm_lmp */ + int pkt_count; /* Number of frames we have sent to IrLAP */ + + __u8 service_type; +}; + +extern hashbin_t *ircomm; + +struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line); +int ircomm_close(struct ircomm_cb *self); + +int ircomm_data_request(struct ircomm_cb *self, struct sk_buff *skb); +void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb); +void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb); +int ircomm_control_request(struct ircomm_cb *self, struct sk_buff *skb); +int ircomm_connect_request(struct ircomm_cb *self, __u8 dlsap_sel, + __u32 saddr, __u32 daddr, struct sk_buff *skb, + __u8 service_type); +void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb, + struct ircomm_info *info); +void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb, + struct ircomm_info *info); +int ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata); +int ircomm_disconnect_request(struct ircomm_cb *self, struct sk_buff *userdata); +void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb, + struct ircomm_info *info); +void ircomm_flow_request(struct ircomm_cb *self, LOCAL_FLOW flow); + +#define ircomm_is_connected(self) (self->state == IRCOMM_CONN) + +#endif diff --git a/release/src/linux/linux/include/net/irda/ircomm_event.h b/release/src/linux/linux/include/net/irda/ircomm_event.h new file mode 100644 index 00000000..8bcffa8a --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ircomm_event.h @@ -0,0 +1,84 @@ +/********************************************************************* + * + * Filename: ircomm_event.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Jun 6 23:51:13 1999 + * Modified at: Thu Jun 10 08:36:25 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRCOMM_EVENT_H +#define IRCOMM_EVENT_H + +typedef enum { + IRCOMM_IDLE, + IRCOMM_WAITI, + IRCOMM_WAITR, + IRCOMM_CONN, +} IRCOMM_STATE; + +/* IrCOMM Events */ +typedef enum { + IRCOMM_CONNECT_REQUEST, + IRCOMM_CONNECT_RESPONSE, + IRCOMM_TTP_CONNECT_INDICATION, + IRCOMM_LMP_CONNECT_INDICATION, + IRCOMM_TTP_CONNECT_CONFIRM, + IRCOMM_LMP_CONNECT_CONFIRM, + + IRCOMM_LMP_DISCONNECT_INDICATION, + IRCOMM_TTP_DISCONNECT_INDICATION, + IRCOMM_DISCONNECT_REQUEST, + + IRCOMM_TTP_DATA_INDICATION, + IRCOMM_LMP_DATA_INDICATION, + IRCOMM_DATA_REQUEST, + IRCOMM_CONTROL_REQUEST, + IRCOMM_CONTROL_INDICATION, +} IRCOMM_EVENT; + +/* + * Used for passing information through the state-machine + */ +struct ircomm_info { + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ + __u8 dlsap_sel; + LM_REASON reason; /* Reason for disconnect */ + __u32 max_data_size; + __u32 max_header_size; + + struct qos_info *qos; +}; + +extern char *ircomm_state[]; +extern char *ircomm_event[]; + +struct ircomm_cb; /* Forward decl. */ + +int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event, + struct sk_buff *skb, struct ircomm_info *info); +void ircomm_next_state(struct ircomm_cb *self, IRCOMM_STATE state); + +#endif diff --git a/release/src/linux/linux/include/net/irda/ircomm_lmp.h b/release/src/linux/linux/include/net/irda/ircomm_lmp.h new file mode 100644 index 00000000..fd738be7 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ircomm_lmp.h @@ -0,0 +1,65 @@ +/********************************************************************* + * + * Filename: ircomm_lmp.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Wed Jun 9 10:06:07 1999 + * Modified at: Fri Aug 13 07:32:32 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRCOMM_LMP_H +#define IRCOMM_LMP_H + +#include <net/irda/ircomm_core.h> +#include <net/irda/ircomm_event.h> + +int ircomm_open_lsap(struct ircomm_cb *self); +int ircomm_lmp_connect_request(struct ircomm_cb *self, + struct sk_buff *userdata, + struct ircomm_info *info); +int ircomm_lmp_connect_response(struct ircomm_cb *self, struct sk_buff *skb); +int ircomm_lmp_disconnect_request(struct ircomm_cb *self, + struct sk_buff *userdata, + struct ircomm_info *info); +int ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb, + int clen); +int ircomm_lmp_control_request(struct ircomm_cb *self, + struct sk_buff *userdata); +int ircomm_lmp_data_indication(void *instance, void *sap, + struct sk_buff *skb); +void ircomm_lmp_connect_confirm(void *instance, void *sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb); +void ircomm_lmp_connect_indication(void *instance, void *sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb); +void ircomm_lmp_disconnect_indication(void *instance, void *sap, + LM_REASON reason, + struct sk_buff *skb); + +#endif diff --git a/release/src/linux/linux/include/net/irda/ircomm_param.h b/release/src/linux/linux/include/net/irda/ircomm_param.h new file mode 100644 index 00000000..5f46fb25 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ircomm_param.h @@ -0,0 +1,150 @@ +/********************************************************************* + * + * Filename: ircomm_param.h + * Version: 1.0 + * Description: Parameter handling for the IrCOMM protocol + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Jun 7 08:47:28 1999 + * Modified at: Wed Aug 25 13:46:33 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRCOMM_PARAMS_H +#define IRCOMM_PARAMS_H + +#include <net/irda/parameters.h> + +/* Parameters common to all service types */ +#define IRCOMM_SERVICE_TYPE 0x00 +#define IRCOMM_PORT_TYPE 0x01 /* Only used in LM-IAS */ +#define IRCOMM_PORT_NAME 0x02 /* Only used in LM-IAS */ + +/* Parameters for both 3 wire and 9 wire */ +#define IRCOMM_DATA_RATE 0x10 +#define IRCOMM_DATA_FORMAT 0x11 +#define IRCOMM_FLOW_CONTROL 0x12 +#define IRCOMM_XON_XOFF 0x13 +#define IRCOMM_ENQ_ACK 0x14 +#define IRCOMM_LINE_STATUS 0x15 +#define IRCOMM_BREAK 0x16 + +/* Parameters for 9 wire */ +#define IRCOMM_DTE 0x20 +#define IRCOMM_DCE 0x21 +#define IRCOMM_POLL 0x22 + +/* Service type (details) */ +#define IRCOMM_3_WIRE_RAW 0x01 +#define IRCOMM_3_WIRE 0x02 +#define IRCOMM_9_WIRE 0x04 +#define IRCOMM_CENTRONICS 0x08 + +/* Port type (details) */ +#define IRCOMM_SERIAL 0x00 +#define IRCOMM_PARALLEL 0x01 + +/* Data format (details) */ +#define IRCOMM_WSIZE_5 0x00 +#define IRCOMM_WSIZE_6 0x01 +#define IRCOMM_WSIZE_7 0x02 +#define IRCOMM_WSIZE_8 0x03 + +#define IRCOMM_1_STOP_BIT 0x00 +#define IRCOMM_2_STOP_BIT 0x04 /* 1.5 if char len 5 */ + +#define IRCOMM_PARITY_DISABLE 0x00 +#define IRCOMM_PARITY_ENABLE 0x08 + +#define IRCOMM_PARITY_ODD 0x00 +#define IRCOMM_PARITY_EVEN 0x10 +#define IRCOMM_PARITY_MARK 0x20 +#define IRCOMM_PARITY_SPACE 0x30 + +/* Flow control */ +#define IRCOMM_XON_XOFF_IN 0x01 +#define IRCOMM_XON_XOFF_OUT 0x02 +#define IRCOMM_RTS_CTS_IN 0x04 +#define IRCOMM_RTS_CTS_OUT 0x08 +#define IRCOMM_DSR_DTR_IN 0x10 +#define IRCOMM_DSR_DTR_OUT 0x20 +#define IRCOMM_ENQ_ACK_IN 0x40 +#define IRCOMM_ENQ_ACK_OUT 0x80 + +/* Line status */ +#define IRCOMM_OVERRUN_ERROR 0x02 +#define IRCOMM_PARITY_ERROR 0x04 +#define IRCOMM_FRAMING_ERROR 0x08 + +/* DTE (Data terminal equipment) line settings */ +#define IRCOMM_DELTA_DTR 0x01 +#define IRCOMM_DELTA_RTS 0x02 +#define IRCOMM_DTR 0x04 +#define IRCOMM_RTS 0x08 + +/* DCE (Data communications equipment) line settings */ +#define IRCOMM_DELTA_CTS 0x01 /* Clear to send has changed */ +#define IRCOMM_DELTA_DSR 0x02 /* Data set ready has changed */ +#define IRCOMM_DELTA_RI 0x04 /* Ring indicator has changed */ +#define IRCOMM_DELTA_CD 0x08 /* Carrier detect has changed */ +#define IRCOMM_CTS 0x10 /* Clear to send is high */ +#define IRCOMM_DSR 0x20 /* Data set ready is high */ +#define IRCOMM_RI 0x40 /* Ring indicator is high */ +#define IRCOMM_CD 0x80 /* Carrier detect is high */ +#define IRCOMM_DCE_DELTA_ANY 0x0f + +/* + * Parameter state + */ +struct ircomm_params { + /* General control params */ + __u8 service_type; + __u8 port_type; + char port_name[32]; + + /* Control params for 3- and 9-wire service type */ + __u32 data_rate; /* Data rate in bps */ + __u8 data_format; + __u8 flow_control; + char xonxoff[2]; + char enqack[2]; + __u8 line_status; + __u8 _break; + + __u8 null_modem; + + /* Control params for 9-wire service type */ + __u8 dte; + __u8 dce; + __u8 poll; + + /* Control params for Centronics service type */ +}; + +struct ircomm_tty_cb; /* Forward decl. */ + +int ircomm_param_flush(struct ircomm_tty_cb *self); +int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush); + +extern pi_param_info_t ircomm_param_info; + +#endif /* IRCOMM_PARAMS_H */ + diff --git a/release/src/linux/linux/include/net/irda/ircomm_ttp.h b/release/src/linux/linux/include/net/irda/ircomm_ttp.h new file mode 100644 index 00000000..014d7f56 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ircomm_ttp.h @@ -0,0 +1,70 @@ +/********************************************************************* + * + * Filename: ircomm_ttp.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Wed Jun 9 10:06:07 1999 + * Modified at: Fri Aug 13 07:32:22 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRCOMM_TTP_H +#define IRCOMM_TTP_H + +#include <net/irda/ircomm_core.h> +#include <net/irda/ircomm_event.h> + +int ircomm_open_tsap(struct ircomm_cb *self); +int ircomm_ttp_connect_request(struct ircomm_cb *self, + struct sk_buff *userdata, + struct ircomm_info *info); +int ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb); +int ircomm_ttp_disconnect_request(struct ircomm_cb *self, + struct sk_buff *userdata, + struct ircomm_info *info); +int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb, + int clen); +int ircomm_ttp_control_request(struct ircomm_cb *self, + struct sk_buff *userdata); +int ircomm_ttp_data_indication(void *instance, void *sap, + struct sk_buff *skb); +void ircomm_ttp_connect_confirm(void *instance, void *sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb); +void ircomm_ttp_connect_indication(void *instance, void *sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb); +void ircomm_ttp_disconnect_indication(void *instance, void *sap, + LM_REASON reason, + struct sk_buff *skb); +void ircomm_ttp_flow_indication(void *instance, void *sap, LOCAL_FLOW cmd); + +#endif + + + + diff --git a/release/src/linux/linux/include/net/irda/ircomm_tty.h b/release/src/linux/linux/include/net/irda/ircomm_tty.h new file mode 100644 index 00000000..77f7dd0d --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ircomm_tty.h @@ -0,0 +1,126 @@ +/********************************************************************* + * + * Filename: ircomm_tty.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Jun 6 23:24:22 1999 + * Modified at: Fri Jan 28 13:16:57 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRCOMM_TTY_H +#define IRCOMM_TTY_H + +#include <linux/serial.h> +#include <linux/termios.h> +#include <linux/timer.h> + +#include <net/irda/irias_object.h> +#include <net/irda/ircomm_core.h> +#include <net/irda/ircomm_param.h> + +#define IRCOMM_TTY_PORTS 32 +#define IRCOMM_TTY_MAGIC 0x3432 +#define IRCOMM_TTY_MAJOR 161 +#define IRCOMM_TTY_MINOR 0 + +/* This is used as an initial value to max_header_size before the proper + * value is filled in (5 for ttp, 4 for lmp). This allow us to detect + * the state of the underlying connection. - Jean II */ +#define IRCOMM_TTY_HDR_UNITIALISED 32 + +/* + * IrCOMM TTY driver state + */ +struct ircomm_tty_cb { + irda_queue_t queue; /* Must be first */ + magic_t magic; + + int state; /* Connect state */ + + struct tty_struct *tty; + struct ircomm_cb *ircomm; /* IrCOMM layer instance */ + + struct sk_buff *tx_skb; /* Transmit buffer */ + struct sk_buff *ctrl_skb; /* Control data buffer */ + + /* Parameters */ + struct ircomm_params settings; + + __u8 service_type; /* The service that we support */ + int client; /* True if we are a client */ + LOCAL_FLOW flow; /* IrTTP flow status */ + + int line; + __u32 flags; + + __u8 dlsap_sel; + __u8 slsap_sel; + + __u32 saddr; + __u32 daddr; + + __u32 max_data_size; /* Max data we can transmit in one packet */ + __u32 max_header_size; /* The amount of header space we must reserve */ + + struct iriap_cb *iriap; /* Instance used for querying remote IAS */ + struct ias_object* obj; + int skey; + int ckey; + + struct termios normal_termios; + struct termios callout_termios; + + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + struct timer_list watchdog_timer; + struct tq_struct tqueue; + + unsigned short close_delay; + unsigned short closing_wait; /* time to wait before closing */ + + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + int open_count; + int blocked_open; /* # of blocked opens */ +}; + +void ircomm_tty_start(struct tty_struct *tty); +void ircomm_tty_stop(struct tty_struct *tty); +void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self); + +extern void ircomm_tty_change_speed(struct ircomm_tty_cb *self); +extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg); +extern void ircomm_tty_set_termios(struct tty_struct *tty, + struct termios *old_termios); +extern hashbin_t *ircomm_tty; + +#endif + + + + + + + diff --git a/release/src/linux/linux/include/net/irda/ircomm_tty_attach.h b/release/src/linux/linux/include/net/irda/ircomm_tty_attach.h new file mode 100644 index 00000000..357bf080 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/ircomm_tty_attach.h @@ -0,0 +1,96 @@ +/********************************************************************* + * + * Filename: ircomm_tty_attach.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Wed Jun 9 15:55:18 1999 + * Modified at: Fri Dec 10 21:04:55 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRCOMM_TTY_ATTACH_H +#define IRCOMM_TTY_ATTACH_H + +#include <net/irda/ircomm_tty.h> + +typedef enum { + IRCOMM_TTY_IDLE, + IRCOMM_TTY_SEARCH, + IRCOMM_TTY_QUERY_PARAMETERS, + IRCOMM_TTY_QUERY_LSAP_SEL, + IRCOMM_TTY_SETUP, + IRCOMM_TTY_READY, +} IRCOMM_TTY_STATE; + +/* IrCOMM TTY Events */ +typedef enum { + IRCOMM_TTY_ATTACH_CABLE, + IRCOMM_TTY_DETACH_CABLE, + IRCOMM_TTY_DATA_REQUEST, + IRCOMM_TTY_DATA_INDICATION, + IRCOMM_TTY_DISCOVERY_REQUEST, + IRCOMM_TTY_DISCOVERY_INDICATION, + IRCOMM_TTY_CONNECT_CONFIRM, + IRCOMM_TTY_CONNECT_INDICATION, + IRCOMM_TTY_DISCONNECT_REQUEST, + IRCOMM_TTY_DISCONNECT_INDICATION, + IRCOMM_TTY_WD_TIMER_EXPIRED, + IRCOMM_TTY_GOT_PARAMETERS, + IRCOMM_TTY_GOT_LSAPSEL, +} IRCOMM_TTY_EVENT; + +/* Used for passing information through the state-machine */ +struct ircomm_tty_info { + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ + __u8 dlsap_sel; +}; + +extern char *ircomm_state[]; +extern char *ircomm_event[]; +extern char *ircomm_tty_state[]; + +int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, + struct sk_buff *skb, struct ircomm_tty_info *info); +void ircomm_tty_next_state(struct ircomm_tty_cb *self, IRCOMM_TTY_STATE state); + + +int ircomm_tty_attach_cable(struct ircomm_tty_cb *self); +void ircomm_tty_detach_cable(struct ircomm_tty_cb *self); +void ircomm_tty_connect_confirm(void *instance, void *sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb); +void ircomm_tty_disconnect_indication(void *instance, void *sap, + LM_REASON reason, + struct sk_buff *skb); +void ircomm_tty_connect_indication(void *instance, void *sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb); +int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self); +void ircomm_tty_link_established(struct ircomm_tty_cb *self); + +#endif /* IRCOMM_TTY_ATTACH_H */ diff --git a/release/src/linux/linux/include/net/irda/irda-usb.h b/release/src/linux/linux/include/net/irda/irda-usb.h new file mode 100644 index 00000000..80d722c2 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irda-usb.h @@ -0,0 +1,164 @@ +/***************************************************************************** + * + * Filename: irda-usb.h + * Version: 0.9b + * Description: IrDA-USB Driver + * Status: Experimental + * Author: Dag Brattli <dag@brattli.net> + * + * Copyright (C) 2001, Roman Weissgaerber <weissg@vienna.at> + * Copyright (C) 2000, Dag Brattli <dag@brattli.net> + * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> + * + * 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. + * + *****************************************************************************/ + +#include <linux/time.h> + +#include <net/irda/irda.h> +#include <net/irda/irlap.h> +#include <net/irda/irda_device.h> + +#define RX_COPY_THRESHOLD 200 +#define IRDA_USB_MAX_MTU 2051 +#define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ + +/* Maximum number of active URB on the Rx path + * This is the amount of buffers the we keep between the USB harware and the + * IrDA stack. + * + * Note : the network layer does also queue the packets between us and the + * IrDA stack, and is actually pretty fast and efficient in doing that. + * Therefore, we don't need to have a large number of URBs, and we can + * perfectly live happy with only one. We certainly don't need to keep the + * full IrTTP window around here... + * I repeat for those who have trouble to understand : 1 URB is plenty + * good enough to handle back-to-back (brickwalled) frames. I tried it, + * it works (it's the hardware that has trouble doing it). + * + * Having 2 URBs would allow the USB stack to process one URB while we take + * care of the other and then swap the URBs... + * On the other hand, increasing the number of URB will have penalities + * in term of latency and will interact with the link management in IrLAP... + * Jean II */ +#define IU_MAX_ACTIVE_RX_URBS 1 /* Don't touch !!! */ + +/* When a Rx URB is passed back to us, we can't reuse it immediately, + * because it may still be referenced by the USB layer. Therefore we + * need to keep one extra URB in the Rx path. + * Jean II */ +#define IU_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + 1) + +/* Send speed command in case of timeout, just for trying to get things sane */ +#define IU_BUG_KICK_TIMEOUT +/* Show the USB class descriptor */ +#undef IU_DUMP_CLASS_DESC +/* Assume a minimum round trip latency for USB transfer (in us)... + * USB transfer are done in the next USB slot if there is no traffic + * (1/19 msec) and is done at 12 Mb/s : + * Waiting for slot + tx = (53us + 16us) * 2 = 137us minimum. + * Rx notification will only be done at the end of the USB frame period : + * OHCI : frame period = 1ms + * UHCI : frame period = 1ms, but notification can take 2 or 3 ms :-( + * EHCI : frame period = 125us */ +#define IU_USB_MIN_RTT 500 /* This should be safe in most cases */ + +/* Inbound header */ +#define MEDIA_BUSY 0x80 + +#define SPEED_2400 0x01 +#define SPEED_9600 0x02 +#define SPEED_19200 0x03 +#define SPEED_38400 0x04 +#define SPEED_57600 0x05 +#define SPEED_115200 0x06 +#define SPEED_576000 0x07 +#define SPEED_1152000 0x08 +#define SPEED_4000000 0x09 + +/* Basic capabilities */ +#define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ +/* Main bugs */ +#define IUC_SPEED_BUG 0x01 /* Device doesn't set speed after the frame */ +#define IUC_NO_WINDOW 0x02 /* Device doesn't behave with big Rx window */ +#define IUC_NO_TURN 0x04 /* Device doesn't do turnaround by itself */ +/* Not currently used */ +#define IUC_SIR_ONLY 0x08 /* Device doesn't behave at FIR speeds */ +#define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ +#define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ +#define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ + +/* USB class definitions */ +#define USB_IRDA_HEADER 0x01 +#define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ +#define USB_DT_IRDA 0x21 + +struct irda_class_desc { + __u8 bLength; + __u8 bDescriptorType; + __u16 bcdSpecRevision; + __u8 bmDataSize; + __u8 bmWindowSize; + __u8 bmMinTurnaroundTime; + __u16 wBaudRate; + __u8 bmAdditionalBOFs; + __u8 bIrdaRateSniff; + __u8 bMaxUnicastList; +} __attribute__ ((packed)); + +/* class specific interface request to get the IrDA-USB class descriptor + * (6.2.5, USB-IrDA class spec 1.0) */ + +#define IU_REQ_GET_CLASS_DESC 0x06 + +struct irda_usb_cb { + struct irda_class_desc *irda_desc; + struct usb_device *usbdev; /* init: probe_irda */ + unsigned int ifnum; /* Interface number of the USB dev. */ + int netopen; /* Device is active for network */ + int present; /* Device is present on the bus */ + __u32 capability; /* Capability of the hardware */ + __u8 bulk_in_ep; /* Rx Endpoint assignments */ + __u8 bulk_out_ep; /* Tx Endpoint assignments */ + __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ + __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ + + wait_queue_head_t wait_q; /* for timeouts */ + + struct urb rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ + struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ + struct urb tx_urb; /* URB used to send data frames */ + struct urb speed_urb; /* URB used to send speed commands */ + + struct net_device *netdev; /* Yes! we are some kind of netdev. */ + struct net_device_stats stats; + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; + hashbin_t *tx_list; /* Queued transmit skb's */ + char *speed_buff; /* Buffer for speed changes */ + + struct timeval stamp; + struct timeval now; + + spinlock_t lock; /* For serializing operations */ + + __u16 xbofs; /* Current xbofs setting */ + __s16 new_xbofs; /* xbofs we need to set */ + __u32 speed; /* Current speed */ + __s32 new_speed; /* speed we need to set */ + __u32 flags; /* Interface flags */ +}; + diff --git a/release/src/linux/linux/include/net/irda/irda.h b/release/src/linux/linux/include/net/irda/irda.h new file mode 100644 index 00000000..d90cff80 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irda.h @@ -0,0 +1,264 @@ +/********************************************************************* + * + * Filename: irda.h + * Version: 1.0 + * Description: IrDA common include file for kernel internal use + * Status: Stable + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Dec 9 21:13:12 1997 + * Modified at: Fri Jan 28 13:16:32 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. + * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef NET_IRDA_H +#define NET_IRDA_H + +#include <linux/config.h> +#include <linux/skbuff.h> +#include <linux/kernel.h> +#include <linux/if.h> +#include <linux/irda.h> + +typedef __u32 magic_t; + +#include <net/irda/qos.h> +#include <net/irda/irqueue.h> + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +/* Hack to do small backoff when setting media busy in IrLAP */ +#ifndef SMALL +#define SMALL 5 +#endif + +#ifndef IRDA_MIN /* Lets not mix this MIN with other header files */ +#define IRDA_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef ALIGN +# define ALIGN __attribute__((aligned)) +#endif +#ifndef PACK +# define PACK __attribute__((packed)) +#endif + + +#ifdef CONFIG_IRDA_DEBUG + +extern __u32 irda_debug; + +/* use 0 for production, 1 for verification, >2 for debug */ +#define IRDA_DEBUG_LEVEL 0 + +#define IRDA_DEBUG(n, args...) (irda_debug >= (n)) ? (printk(KERN_DEBUG args)) : 0 +#define ASSERT(expr, func) \ +if(!(expr)) { \ + printk( "Assertion failed! %s:%s:%d %s\n", \ + __FILE__,__FUNCTION__,__LINE__,(#expr)); \ + func } +#else +#define IRDA_DEBUG(n, args...) +#define ASSERT(expr, func) \ +if(!(expr)) do { \ + func } while (0) +#endif /* CONFIG_IRDA_DEBUG */ + +#define WARNING(args...) printk(KERN_WARNING args) +#define MESSAGE(args...) printk(KERN_INFO args) +#define ERROR(args...) printk(KERN_ERR args) + +#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000) + +/* + * Magic numbers used by Linux-IrDA. Random numbers which must be unique to + * give the best protection + */ + +#define IRTTY_MAGIC 0x2357 +#define LAP_MAGIC 0x1357 +#define LMP_MAGIC 0x4321 +#define LMP_LSAP_MAGIC 0x69333 +#define LMP_LAP_MAGIC 0x3432 +#define IRDA_DEVICE_MAGIC 0x63454 +#define IAS_MAGIC 0x007 +#define TTP_MAGIC 0x241169 +#define TTP_TSAP_MAGIC 0x4345 +#define IROBEX_MAGIC 0x341324 +#define HB_MAGIC 0x64534 +#define IRLAN_MAGIC 0x754 +#define IAS_OBJECT_MAGIC 0x34234 +#define IAS_ATTRIB_MAGIC 0x45232 +#define IRDA_TASK_MAGIC 0x38423 + +#define IAS_DEVICE_ID 0x0000 /* Defined by IrDA, IrLMP section 4.1 (page 68) */ +#define IAS_PNP_ID 0xd342 +#define IAS_OBEX_ID 0x34323 +#define IAS_IRLAN_ID 0x34234 +#define IAS_IRCOMM_ID 0x2343 +#define IAS_IRLPT_ID 0x9876 + +typedef enum { FLOW_STOP, FLOW_START } LOCAL_FLOW; + +/* A few forward declarations (to make compiler happy) */ +struct tsap_cb; /* in <net/irda/irttp.h> */ +struct lsap_cb; /* in <net/irda/irlmp.h> */ +struct iriap_cb; /* in <net/irda/iriap.h> */ +struct ias_value; /* in <net/irda/irias_object.h> */ +struct discovery_t; /* in <net/irda/discovery.h> */ + +/* IrDA Socket */ +struct irda_sock { + __u32 saddr; /* my local address */ + __u32 daddr; /* peer address */ + + struct lsap_cb *lsap; /* LSAP used by Ultra */ + __u8 pid; /* Protocol IP (PID) used by Ultra */ + + struct tsap_cb *tsap; /* TSAP used by this connection */ + __u8 dtsap_sel; /* remote TSAP address */ + __u8 stsap_sel; /* local TSAP address */ + + __u32 max_sdu_size_rx; + __u32 max_sdu_size_tx; + __u32 max_data_size; + __u8 max_header_size; + struct qos_info qos_tx; + + __u16 mask; /* Hint bits mask */ + __u16 hints; /* Hint bits */ + + __u32 ckey; /* IrLMP client handle */ + __u32 skey; /* IrLMP service handle */ + + struct ias_object *ias_obj; /* Our service name + lsap in IAS */ + struct iriap_cb *iriap; /* Used to query remote IAS */ + struct ias_value *ias_result; /* Result of remote IAS query */ + + hashbin_t *cachelog; /* Result of discovery query */ + struct discovery_t *cachediscovery; /* Result of selective discovery query */ + + int nslots; /* Number of slots to use for discovery */ + + int errno; /* status of the IAS query */ + + struct sock *sk; + wait_queue_head_t query_wait; /* Wait for the answer to a query */ + struct timer_list watchdog; /* Timeout for discovery */ + + LOCAL_FLOW tx_flow; + LOCAL_FLOW rx_flow; +}; + +/* + * This type is used by the protocols that transmit 16 bits words in + * little endian format. A little endian machine stores MSB of word in + * byte[1] and LSB in byte[0]. A big endian machine stores MSB in byte[0] + * and LSB in byte[1]. + */ +typedef union { + __u16 word; + __u8 byte[2]; +} __u16_host_order; + +/* + * Per-packet information we need to hide inside sk_buff + * (must not exceed 48 bytes, check with struct sk_buff) + */ +struct irda_skb_cb { + magic_t magic; /* Be sure that we can trust the information */ + __u32 next_speed; /* The Speed to be set *after* this frame */ + __u16 mtt; /* Minimum turn around time */ + __u16 xbofs; /* Number of xbofs required, used by SIR mode */ + __u16 next_xbofs; /* Number of xbofs required *after* this frame */ + void *context; /* May be used by drivers */ + void (*destructor)(struct sk_buff *skb); /* Used for flow control */ + __u16 xbofs_delay; /* Number of xbofs used for generating the mtt */ + __u8 line; /* Used by IrCOMM in IrLPT mode */ +}; + +/* Misc status information */ +typedef enum { + STATUS_OK, + STATUS_ABORTED, + STATUS_NO_ACTIVITY, + STATUS_NOISY, + STATUS_REMOTE, +} LINK_STATUS; + +typedef enum { + LOCK_NO_CHANGE, + LOCK_LOCKED, + LOCK_UNLOCKED, +} LOCK_STATUS; + +typedef enum { + LAP_DISC_INDICATION=1, /* Received a disconnect request from peer */ + LAP_NO_RESPONSE, /* To many retransmits without response */ + LAP_RESET_INDICATION, /* To many retransmits, or invalid nr/ns */ + LAP_FOUND_NONE, /* No devices were discovered */ + LAP_MEDIA_BUSY, + LAP_PRIMARY_CONFLICT, +} LAP_REASON; + +/* + * IrLMP disconnect reasons. The order is very important, since they + * correspond to disconnect reasons sent in IrLMP disconnect frames, so + * please do not touch :-) + */ +typedef enum { + LM_USER_REQUEST = 1, /* User request */ + LM_LAP_DISCONNECT, /* Unexpected IrLAP disconnect */ + LM_CONNECT_FAILURE, /* Failed to establish IrLAP connection */ + LM_LAP_RESET, /* IrLAP reset */ + LM_INIT_DISCONNECT, /* Link Management initiated disconnect */ + LM_LSAP_NOTCONN, /* Data delivered on unconnected LSAP */ + LM_NON_RESP_CLIENT, /* Non responsive LM-MUX client */ + LM_NO_AVAIL_CLIENT, /* No available LM-MUX client */ + LM_CONN_HALF_OPEN, /* Connection is half open */ + LM_BAD_SOURCE_ADDR, /* Illegal source address (i.e 0x00) */ +} LM_REASON; +#define LM_UNKNOWN 0xff /* Unspecified disconnect reason */ + +/* + * Notify structure used between transport and link management layers + */ +typedef struct { + int (*data_indication)(void *priv, void *sap, struct sk_buff *skb); + int (*udata_indication)(void *priv, void *sap, struct sk_buff *skb); + void (*connect_confirm)(void *instance, void *sap, + struct qos_info *qos, __u32 max_sdu_size, + __u8 max_header_size, struct sk_buff *skb); + void (*connect_indication)(void *instance, void *sap, + struct qos_info *qos, __u32 max_sdu_size, + __u8 max_header_size, struct sk_buff *skb); + void (*disconnect_indication)(void *instance, void *sap, + LM_REASON reason, struct sk_buff *); + void (*flow_indication)(void *instance, void *sap, LOCAL_FLOW flow); + void (*status_indication)(void *instance, + LINK_STATUS link, LOCK_STATUS lock); + void *instance; /* Layer instance pointer */ + char name[16]; /* Name of layer */ +} notify_t; + +#define NOTIFY_MAX_NAME 16 + +#endif /* NET_IRDA_H */ diff --git a/release/src/linux/linux/include/net/irda/irda_device.h b/release/src/linux/linux/include/net/irda/irda_device.h new file mode 100644 index 00000000..3af60688 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irda_device.h @@ -0,0 +1,244 @@ +/********************************************************************* + * + * Filename: irda_device.h + * Version: 0.9 + * Description: Contains various declarations used by the drivers + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Apr 14 12:41:42 1998 + * Modified at: Mon Mar 20 09:08:57 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. + * Copyright (c) 1998 Thomas Davis, <ratbert@radiks.net>, + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRDA_DEVICE_H +#define IRDA_DEVICE_H + +#include <linux/tty.h> +#include <linux/netdevice.h> +#include <linux/spinlock.h> +#include <linux/irda.h> + +#include <net/irda/irda.h> +#include <net/irda/qos.h> +#include <net/irda/irqueue.h> +#include <net/irda/irlap_frame.h> + +/* Some non-standard interface flags (should not conflict with any in if.h) */ +#define IFF_SIR 0x0001 /* Supports SIR speeds */ +#define IFF_MIR 0x0002 /* Supports MIR speeds */ +#define IFF_FIR 0x0004 /* Supports FIR speeds */ +#define IFF_VFIR 0x0008 /* Supports VFIR speeds */ +#define IFF_PIO 0x0010 /* Supports PIO transfer of data */ +#define IFF_DMA 0x0020 /* Supports DMA transfer of data */ +#define IFF_SHM 0x0040 /* Supports shared memory data transfers */ +#define IFF_DONGLE 0x0080 /* Interface has a dongle attached */ +#define IFF_AIR 0x0100 /* Supports Advanced IR (AIR) standards */ + +#define IO_XMIT 0x01 +#define IO_RECV 0x02 + +typedef enum { + IRDA_IRLAP, /* IrDA mode, and deliver to IrLAP */ + IRDA_RAW, /* IrDA mode */ + SHARP_ASK, + TV_REMOTE, /* Also known as Consumer Electronics IR */ +} INFRARED_MODE; + +typedef enum { + IRDA_TASK_INIT, /* All tasks are initialized with this state */ + IRDA_TASK_DONE, /* Signals that the task is finished */ + IRDA_TASK_WAIT, + IRDA_TASK_WAIT1, + IRDA_TASK_WAIT2, + IRDA_TASK_WAIT3, + IRDA_TASK_CHILD_INIT, /* Initializing child task */ + IRDA_TASK_CHILD_WAIT, /* Waiting for child task to finish */ + IRDA_TASK_CHILD_DONE /* Child task is finished */ +} IRDA_TASK_STATE; + +struct irda_task; +typedef int (*IRDA_TASK_CALLBACK) (struct irda_task *task); + +struct irda_task { + irda_queue_t q; + magic_t magic; + + IRDA_TASK_STATE state; + IRDA_TASK_CALLBACK function; + IRDA_TASK_CALLBACK finished; + + struct irda_task *parent; + struct timer_list timer; + + void *instance; /* Instance being called */ + void *param; /* Parameter to be used by instance */ +}; + +/* Dongle info */ +struct dongle_reg; +typedef struct { + struct dongle_reg *issue; /* Registration info */ + struct net_device *dev; /* Device we are attached to */ + struct irda_task *speed_task; /* Task handling speed change */ + struct irda_task *reset_task; /* Task handling reset */ + __u32 speed; /* Current speed */ + + /* Callbacks to the IrDA device driver */ + int (*set_mode)(struct net_device *, int mode); + int (*read)(struct net_device *dev, __u8 *buf, int len); + int (*write)(struct net_device *dev, __u8 *buf, int len); + int (*set_dtr_rts)(struct net_device *dev, int dtr, int rts); +} dongle_t; + +/* Dongle registration info */ +struct dongle_reg { + irda_queue_t q; /* Must be first */ + IRDA_DONGLE type; + + void (*open)(dongle_t *dongle, struct qos_info *qos); + void (*close)(dongle_t *dongle); + int (*reset)(struct irda_task *task); + int (*change_speed)(struct irda_task *task); +}; + +/* Chip specific info */ +typedef struct { + int cfg_base; /* Config register IO base */ + int sir_base; /* SIR IO base */ + int fir_base; /* FIR IO base */ + int mem_base; /* Shared memory base */ + int sir_ext; /* Length of SIR iobase */ + int fir_ext; /* Length of FIR iobase */ + int irq, irq2; /* Interrupts used */ + int dma, dma2; /* DMA channel(s) used */ + int fifo_size; /* FIFO size */ + int irqflags; /* interrupt flags (ie, SA_SHIRQ|SA_INTERRUPT) */ + int direction; /* Link direction, used by some FIR drivers */ + int enabled; /* Powered on? */ + int suspended; /* Suspended by APM */ + __u32 speed; /* Currently used speed */ + __u32 new_speed; /* Speed we must change to when Tx is finished */ + int dongle_id; /* Dongle or transceiver currently used */ +} chipio_t; + +/* IO buffer specific info (inspired by struct sk_buff) */ +typedef struct { + int state; /* Receiving state (transmit state not used) */ + int in_frame; /* True if receiving frame */ + + __u8 *head; /* start of buffer */ + __u8 *data; /* start of data in buffer */ + __u8 *tail; /* end of data in buffer */ + + int len; /* length of data */ + int truesize; /* total size of buffer */ + __u16 fcs; +} iobuff_t; + +/* Function prototypes */ +int irda_device_init(void); +void irda_device_cleanup(void); + +/* Interface to be uses by IrLAP */ +void irda_device_set_media_busy(struct net_device *dev, int status); +int irda_device_is_media_busy(struct net_device *dev); +int irda_device_is_receiving(struct net_device *dev); + +/* Interface for internal use */ +int irda_device_txqueue_empty(struct net_device *dev); +int irda_device_set_raw_mode(struct net_device* self, int status); +int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts); +int irda_device_change_speed(struct net_device *dev, __u32 speed); +int irda_device_setup(struct net_device *dev); + +/* Dongle interface */ +void irda_device_unregister_dongle(struct dongle_reg *dongle); +int irda_device_register_dongle(struct dongle_reg *dongle); +dongle_t *irda_device_dongle_init(struct net_device *dev, int type); +int irda_device_dongle_cleanup(dongle_t *dongle); + +void setup_dma(int channel, char *buffer, int count, int mode); + +void irda_task_delete(struct irda_task *task); +int irda_task_kick(struct irda_task *task); +struct irda_task *irda_task_execute(void *instance, + IRDA_TASK_CALLBACK function, + IRDA_TASK_CALLBACK finished, + struct irda_task *parent, void *param); +void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state); + +extern const char *infrared_mode[]; + +/* + * Function irda_get_mtt (skb) + * + * Utility function for getting the minimum turnaround time out of + * the skb, where it has been hidden in the cb field. + */ +#define irda_get_mtt(skb) ( \ + IRDA_MIN(10000, \ + (((struct irda_skb_cb *) skb->cb)->magic == LAP_MAGIC) ? \ + ((struct irda_skb_cb *)(skb->cb))->mtt : 10000 \ + ) \ +) + + +/* + * Function irda_get_next_speed (skb) + * + * Extract the speed that should be set *after* this frame from the skb + * + * Note : return -1 for user space frames + */ +#define irda_get_next_speed(skb) ( \ + (((struct irda_skb_cb*) skb->cb)->magic == LAP_MAGIC) ? \ + ((struct irda_skb_cb *)(skb->cb))->next_speed : -1 \ +) + + +/* + * Function irda_get_next_xbofs (skb) + * + * Extract the xbofs that should be set for this frame from the skb + * + * Note : default to 10 for user space frames + */ +#define irda_get_xbofs(skb) ( \ + (((struct irda_skb_cb*) skb->cb)->magic == LAP_MAGIC) ? \ + ((struct irda_skb_cb *)(skb->cb))->xbofs : 10 \ +) + +/* + * Function irda_get_next_xbofs (skb) + * + * Extract the xbofs that should be set *after* this frame from the skb + * + * Note : return -1 for user space frames + */ +#define irda_get_next_xbofs(skb) ( \ + (((struct irda_skb_cb*) skb->cb)->magic == LAP_MAGIC) ? \ + ((struct irda_skb_cb *)(skb->cb))->next_xbofs : -1 \ +) + +#endif /* IRDA_DEVICE_H */ + + diff --git a/release/src/linux/linux/include/net/irda/iriap.h b/release/src/linux/linux/include/net/irda/iriap.h new file mode 100644 index 00000000..8aed55b1 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/iriap.h @@ -0,0 +1,119 @@ +/********************************************************************* + * + * Filename: iriap.h + * Version: 0.5 + * Description: Information Access Protocol (IAP) + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Thu Aug 21 00:02:07 1997 + * Modified at: Sat Dec 25 16:42:09 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRIAP_H +#define IRIAP_H + +#include <linux/types.h> +#include <linux/skbuff.h> + +#include <net/irda/qos.h> +#include <net/irda/iriap_event.h> +#include <net/irda/irias_object.h> +#include <net/irda/irqueue.h> +#include <net/irda/timer.h> + +#define IAP_LST 0x80 +#define IAP_ACK 0x40 + +#define IAS_SERVER 0 +#define IAS_CLIENT 1 + +/* IrIAP Op-codes */ +#define GET_INFO_BASE 0x01 +#define GET_OBJECTS 0x02 +#define GET_VALUE 0x03 +#define GET_VALUE_BY_CLASS 0x04 +#define GET_OBJECT_INFO 0x05 +#define GET_ATTRIB_NAMES 0x06 + +#define IAS_SUCCESS 0 +#define IAS_CLASS_UNKNOWN 1 +#define IAS_ATTRIB_UNKNOWN 2 +#define IAS_DISCONNECT 10 + +typedef void (*CONFIRM_CALLBACK)(int result, __u16 obj_id, + struct ias_value *value, void *priv); + +struct iriap_cb { + irda_queue_t q; /* Must be first */ + magic_t magic; /* Magic cookie */ + + int mode; /* Client or server */ + + __u32 saddr; + __u32 daddr; + __u8 operation; + + struct sk_buff *skb; + struct lsap_cb *lsap; + __u8 slsap_sel; + + /* Client states */ + IRIAP_STATE client_state; + IRIAP_STATE call_state; + + /* Server states */ + IRIAP_STATE server_state; + IRIAP_STATE r_connect_state; + + CONFIRM_CALLBACK confirm; + void *priv; /* Used to identify client */ + + __u8 max_header_size; + __u32 max_data_size; + + struct timer_list watchdog_timer; +}; + +int iriap_init(void); +void iriap_cleanup(void); + +struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, + CONFIRM_CALLBACK callback); +void iriap_close(struct iriap_cb *self); + +int iriap_getvaluebyclass_request(struct iriap_cb *self, + __u32 saddr, __u32 daddr, + char *name, char *attr); +void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb); +void iriap_connect_request(struct iriap_cb *self); +void iriap_send_ack( struct iriap_cb *self); +void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb); + +void iriap_register_server(void); + +void iriap_watchdog_timer_expired(void *data); + +static inline void iriap_start_watchdog_timer(struct iriap_cb *self, + int timeout) +{ + irda_start_timer(&self->watchdog_timer, timeout, self, + iriap_watchdog_timer_expired); +} + +#endif + + diff --git a/release/src/linux/linux/include/net/irda/iriap_event.h b/release/src/linux/linux/include/net/irda/iriap_event.h new file mode 100644 index 00000000..4ca3d207 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/iriap_event.h @@ -0,0 +1,85 @@ +/********************************************************************* + * + * Filename: iriap_event.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Aug 4 20:40:53 1997 + * Modified at: Sun Oct 31 22:02:54 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRIAP_FSM_H +#define IRIAP_FSM_H + +/* Forward because of circular include dependecies */ +struct iriap_cb; + +/* IrIAP states */ +typedef enum { + /* Client */ + S_DISCONNECT, + S_CONNECTING, + S_CALL, + + /* S-Call */ + S_MAKE_CALL, + S_CALLING, + S_OUTSTANDING, + S_REPLYING, + S_WAIT_FOR_CALL, + S_WAIT_ACTIVE, + + /* Server */ + R_DISCONNECT, + R_CALL, + + /* R-Connect */ + R_WAITING, + R_WAIT_ACTIVE, + R_RECEIVING, + R_EXECUTE, + R_RETURNING, +} IRIAP_STATE; + +typedef enum { + IAP_CALL_REQUEST, + IAP_CALL_REQUEST_GVBC, + IAP_CALL_RESPONSE, + IAP_RECV_F_LST, + IAP_LM_DISCONNECT_INDICATION, + IAP_LM_CONNECT_INDICATION, + IAP_LM_CONNECT_CONFIRM, +} IRIAP_EVENT; + +void iriap_next_client_state (struct iriap_cb *self, IRIAP_STATE state); +void iriap_next_call_state (struct iriap_cb *self, IRIAP_STATE state); +void iriap_next_server_state (struct iriap_cb *self, IRIAP_STATE state); +void iriap_next_r_connect_state(struct iriap_cb *self, IRIAP_STATE state); + + +void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event, + struct sk_buff *skb); +void iriap_do_call_event (struct iriap_cb *self, IRIAP_EVENT event, + struct sk_buff *skb); + +void iriap_do_server_event (struct iriap_cb *self, IRIAP_EVENT event, + struct sk_buff *skb); +void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event, + struct sk_buff *skb); + +#endif /* IRIAP_FSM_H */ + diff --git a/release/src/linux/linux/include/net/irda/irias_object.h b/release/src/linux/linux/include/net/irda/irias_object.h new file mode 100644 index 00000000..36ad1d89 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irias_object.h @@ -0,0 +1,109 @@ +/********************************************************************* + * + * Filename: irias_object.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Thu Oct 1 22:49:50 1998 + * Modified at: Wed Dec 15 11:20:57 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef LM_IAS_OBJECT_H +#define LM_IAS_OBJECT_H + +#include <net/irda/irda.h> +#include <net/irda/irqueue.h> + +/* LM-IAS Attribute types */ +#define IAS_MISSING 0 +#define IAS_INTEGER 1 +#define IAS_OCT_SEQ 2 +#define IAS_STRING 3 + +/* Object ownership of attributes (user or kernel) */ +#define IAS_KERNEL_ATTR 0 +#define IAS_USER_ATTR 1 + +/* + * LM-IAS Object + */ +struct ias_object { + irda_queue_t q; /* Must be first! */ + magic_t magic; + + char *name; + int id; + hashbin_t *attribs; +}; + +/* + * Values used by LM-IAS attributes + */ +struct ias_value { + __u8 type; /* Value description */ + __u8 owner; /* Managed from user/kernel space */ + int charset; /* Only used by string type */ + int len; + + /* Value */ + union { + int integer; + char *string; + __u8 *oct_seq; + } t; +}; + +/* + * Attributes used by LM-IAS objects + */ +struct ias_attrib { + irda_queue_t q; /* Must be first! */ + int magic; + + char *name; /* Attribute name */ + struct ias_value *value; /* Attribute value */ +}; + +char *strndup(char *str, int max); + +struct ias_object *irias_new_object(char *name, int id); +void irias_insert_object(struct ias_object *obj); +int irias_delete_object(struct ias_object *obj); +int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib); +void __irias_delete_object(struct ias_object *obj); + +void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, + int user); +void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, + int user); +void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, + int len, int user); +int irias_object_change_attribute(char *obj_name, char *attrib_name, + struct ias_value *new_value); +struct ias_object *irias_find_object(char *name); +struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name); + +struct ias_value *irias_new_string_value(char *string); +struct ias_value *irias_new_integer_value(int integer); +struct ias_value *irias_new_octseq_value(__u8 *octseq , int len); +struct ias_value *irias_new_missing_value(void); +void irias_delete_value(struct ias_value *value); + +extern struct ias_value missing; +extern hashbin_t *objects; + +#endif diff --git a/release/src/linux/linux/include/net/irda/irlan_client.h b/release/src/linux/linux/include/net/irda/irlan_client.h new file mode 100644 index 00000000..e42871a0 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlan_client.h @@ -0,0 +1,45 @@ +/********************************************************************* + * + * Filename: irlan_client.h + * Version: 0.3 + * Description: IrDA LAN access layer + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Aug 31 20:14:37 1997 + * Modified at: Thu Apr 22 14:13:34 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLAN_CLIENT_H +#define IRLAN_CLIENT_H + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/skbuff.h> +#include <linux/netdevice.h> + +#include <net/irda/irias_object.h> +#include <net/irda/irlan_event.h> + +void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout); +void irlan_client_discovery_indication(discovery_t *, DISCOVERY_MODE, void *); +void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr); + +void irlan_client_open_ctrl_tsap( struct irlan_cb *self); + +void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb); +void irlan_client_get_value_confirm(int result, __u16 obj_id, + struct ias_value *value, void *priv); +#endif diff --git a/release/src/linux/linux/include/net/irda/irlan_common.h b/release/src/linux/linux/include/net/irda/irlan_common.h new file mode 100644 index 00000000..02ecaf8e --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlan_common.h @@ -0,0 +1,231 @@ +/********************************************************************* + * + * Filename: irlan_common.h + * Version: 0.8 + * Description: IrDA LAN access layer + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Aug 31 20:14:37 1997 + * Modified at: Sun Oct 31 19:41:24 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLAN_H +#define IRLAN_H + +#include <asm/param.h> /* for HZ */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/skbuff.h> +#include <linux/netdevice.h> + +#include <net/irda/irqueue.h> +#include <net/irda/irttp.h> + +#define IRLAN_MTU 1518 +#define IRLAN_TIMEOUT 10*HZ /* 10 seconds */ + +/* Command packet types */ +#define CMD_GET_PROVIDER_INFO 0 +#define CMD_GET_MEDIA_CHAR 1 +#define CMD_OPEN_DATA_CHANNEL 2 +#define CMD_CLOSE_DATA_CHAN 3 +#define CMD_RECONNECT_DATA_CHAN 4 +#define CMD_FILTER_OPERATION 5 + +/* Some responses */ +#define RSP_SUCCESS 0 +#define RSP_INSUFFICIENT_RESOURCES 1 +#define RSP_INVALID_COMMAND_FORMAT 2 +#define RSP_COMMAND_NOT_SUPPORTED 3 +#define RSP_PARAM_NOT_SUPPORTED 4 +#define RSP_VALUE_NOT_SUPPORTED 5 +#define RSP_NOT_OPEN 6 +#define RSP_AUTHENTICATION_REQUIRED 7 +#define RSP_INVALID_PASSWORD 8 +#define RSP_PROTOCOL_ERROR 9 +#define RSP_ASYNCHRONOUS_ERROR 255 + +/* Media types */ +#define MEDIA_802_3 1 +#define MEDIA_802_5 2 + +/* Filter parameters */ +#define DATA_CHAN 1 +#define FILTER_TYPE 2 +#define FILTER_MODE 3 + +/* Filter types */ +#define IRLAN_DIRECTED 0x01 +#define IRLAN_FUNCTIONAL 0x02 +#define IRLAN_GROUP 0x04 +#define IRLAN_MAC_FRAME 0x08 +#define IRLAN_MULTICAST 0x10 +#define IRLAN_BROADCAST 0x20 +#define IRLAN_IPX_SOCKET 0x40 + +/* Filter modes */ +#define ALL 1 +#define FILTER 2 +#define NONE 3 + +/* Filter operations */ +#define GET 1 +#define CLEAR 2 +#define ADD 3 +#define REMOVE 4 +#define DYNAMIC 5 + +/* Access types */ +#define ACCESS_DIRECT 1 +#define ACCESS_PEER 2 +#define ACCESS_HOSTED 3 + +#define IRLAN_BYTE 0 +#define IRLAN_SHORT 1 +#define IRLAN_ARRAY 2 + +#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_MAX_HEADER) + +/* + * IrLAN client + */ +struct irlan_client_cb { + int state; + + int open_retries; + + struct tsap_cb *tsap_ctrl; + __u32 max_sdu_size; + __u8 max_header_size; + + int access_type; /* Access type of provider */ + __u8 reconnect_key[255]; + __u8 key_len; + + __u16 recv_arb_val; + __u16 max_frame; + int filter_type; + + int unicast_open; + int broadcast_open; + + int tx_busy; + struct sk_buff_head txq; /* Transmit control queue */ + + struct iriap_cb *iriap; + + struct timer_list kick_timer; +}; + +/* + * IrLAN provider + */ +struct irlan_provider_cb { + int state; + + struct tsap_cb *tsap_ctrl; + __u32 max_sdu_size; + __u8 max_header_size; + + /* + * Store some values here which are used by the provider to parse + * the filter operations + */ + int data_chan; + int filter_type; + int filter_mode; + int filter_operation; + int filter_entry; + int access_type; /* Access type */ + __u16 send_arb_val; + + __u8 mac_address[6]; /* Generated MAC address for peer device */ +}; + +/* + * IrLAN control block + */ +struct irlan_cb { + irda_queue_t q; /* Must be first */ + + int magic; + struct net_device dev; /* Ethernet device structure*/ + struct net_device_stats stats; + + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ + int disconnect_reason; /* Why we got disconnected */ + + int media; /* Media type */ + __u8 version[2]; /* IrLAN version */ + + struct tsap_cb *tsap_data; /* Data TSAP */ + + int use_udata; /* Use Unit Data transfers */ + + __u8 stsap_sel_data; /* Source data TSAP selector */ + __u8 dtsap_sel_data; /* Destination data TSAP selector */ + __u8 dtsap_sel_ctrl; /* Destination ctrl TSAP selector */ + + struct irlan_client_cb client; /* Client specific fields */ + struct irlan_provider_cb provider; /* Provider specific fields */ + + __u32 max_sdu_size; + __u8 max_header_size; + + wait_queue_head_t open_wait; + struct timer_list watchdog_timer; +}; + +struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr); +void irlan_close(struct irlan_cb *self); +void irlan_close_tsaps(struct irlan_cb *self); +void irlan_mod_inc_use_count(void); +void irlan_mod_dec_use_count(void); + +int irlan_register_netdev(struct irlan_cb *self); +void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel); +void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout); + +void irlan_open_data_tsap(struct irlan_cb *self); + +int irlan_run_ctrl_tx_queue(struct irlan_cb *self); + +void irlan_get_provider_info(struct irlan_cb *self); +void irlan_get_unicast_addr(struct irlan_cb *self); +void irlan_get_media_char(struct irlan_cb *self); +void irlan_open_data_channel(struct irlan_cb *self); +void irlan_close_data_channel(struct irlan_cb *self); +void irlan_set_multicast_filter(struct irlan_cb *self, int status); +void irlan_set_broadcast_filter(struct irlan_cb *self, int status); +void irlan_open_unicast_addr(struct irlan_cb *self); + +int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value); +int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value); +int irlan_insert_string_param(struct sk_buff *skb, char *param, char *value); +int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *value, + __u16 value_len); + +int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len); +void print_ret_code(__u8 code); + +extern hashbin_t *irlan; + +#endif + + diff --git a/release/src/linux/linux/include/net/irda/irlan_eth.h b/release/src/linux/linux/include/net/irda/irlan_eth.h new file mode 100644 index 00000000..53c6ae82 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlan_eth.h @@ -0,0 +1,40 @@ +/********************************************************************* + * + * Filename: irlan_eth.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Thu Oct 15 08:36:58 1998 + * Modified at: Fri May 14 23:29:00 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLAN_ETH_H +#define IRLAN_ETH_H + +int irlan_eth_init(struct net_device *dev); +int irlan_eth_open(struct net_device *dev); +int irlan_eth_close(struct net_device *dev); +int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb); +int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev); + +void irlan_eth_flow_indication( void *instance, void *sap, LOCAL_FLOW flow); +void irlan_eth_send_gratuitous_arp(struct net_device *dev); + +void irlan_eth_set_multicast_list( struct net_device *dev); +struct net_device_stats *irlan_eth_get_stats(struct net_device *dev); + +#endif diff --git a/release/src/linux/linux/include/net/irda/irlan_event.h b/release/src/linux/linux/include/net/irda/irlan_event.h new file mode 100644 index 00000000..b9baac9e --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlan_event.h @@ -0,0 +1,81 @@ +/********************************************************************* + * + * Filename: irlan_event.h + * Version: + * Description: LAN access + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Aug 31 20:14:37 1997 + * Modified at: Tue Feb 2 09:45:17 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLAN_EVENT_H +#define IRLAN_EVENT_H + +#include <linux/kernel.h> +#include <linux/skbuff.h> + +#include <net/irda/irlan_common.h> + +typedef enum { + IRLAN_IDLE, + IRLAN_QUERY, + IRLAN_CONN, + IRLAN_INFO, + IRLAN_MEDIA, + IRLAN_OPEN, + IRLAN_WAIT, + IRLAN_ARB, + IRLAN_DATA, + IRLAN_CLOSE, + IRLAN_SYNC +} IRLAN_STATE; + +typedef enum { + IRLAN_DISCOVERY_INDICATION, + IRLAN_IAS_PROVIDER_AVAIL, + IRLAN_IAS_PROVIDER_NOT_AVAIL, + IRLAN_LAP_DISCONNECT, + IRLAN_LMP_DISCONNECT, + IRLAN_CONNECT_COMPLETE, + IRLAN_DATA_INDICATION, + IRLAN_DATA_CONNECT_INDICATION, + IRLAN_RETRY_CONNECT, + + IRLAN_CONNECT_INDICATION, + IRLAN_GET_INFO_CMD, + IRLAN_GET_MEDIA_CMD, + IRLAN_OPEN_DATA_CMD, + IRLAN_FILTER_CONFIG_CMD, + + IRLAN_CHECK_CON_ARB, + IRLAN_PROVIDER_SIGNAL, + + IRLAN_WATCHDOG_TIMEOUT, +} IRLAN_EVENT; + +extern char *irlan_state[]; + +void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event, + struct sk_buff *skb); + +void irlan_do_provider_event(struct irlan_cb *self, IRLAN_EVENT event, + struct sk_buff *skb); + +void irlan_next_client_state(struct irlan_cb *self, IRLAN_STATE state); +void irlan_next_provider_state(struct irlan_cb *self, IRLAN_STATE state); + +#endif diff --git a/release/src/linux/linux/include/net/irda/irlan_filter.h b/release/src/linux/linux/include/net/irda/irlan_filter.h new file mode 100644 index 00000000..b68eec16 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlan_filter.h @@ -0,0 +1,33 @@ +/********************************************************************* + * + * Filename: irlan_filter.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Fri Jan 29 15:24:08 1999 + * Modified at: Sun Feb 7 23:35:31 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998 Dag Brattli, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLAN_FILTER_H +#define IRLAN_FILTER_H + +void irlan_check_command_param(struct irlan_cb *self, char *param, + char *value); +void handle_filter_request(struct irlan_cb *self, struct sk_buff *skb); +int irlan_print_filter(int filter_type, char *buf); + +#endif /* IRLAN_FILTER_H */ diff --git a/release/src/linux/linux/include/net/irda/irlan_provider.h b/release/src/linux/linux/include/net/irda/irlan_provider.h new file mode 100644 index 00000000..ca51d5b7 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlan_provider.h @@ -0,0 +1,52 @@ +/********************************************************************* + * + * Filename: irlan_provider.h + * Version: 0.1 + * Description: IrDA LAN access layer + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Aug 31 20:14:37 1997 + * Modified at: Sun May 9 12:26:11 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLAN_SERVER_H +#define IRLAN_SERVER_H + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/skbuff.h> +#include <linux/netdevice.h> + +#include <net/irda/irlan_common.h> + +void irlan_provider_ctrl_disconnect_indication(void *instance, void *sap, + LM_REASON reason, + struct sk_buff *skb); + + +void irlan_provider_connect_response(struct irlan_cb *, struct tsap_cb *); + +int irlan_parse_open_data_cmd(struct irlan_cb *self, struct sk_buff *skb); +int irlan_provider_parse_command(struct irlan_cb *self, int cmd, + struct sk_buff *skb); + +void irlan_provider_send_reply(struct irlan_cb *self, int command, + int ret_code); +int irlan_provider_open_ctrl_tsap(struct irlan_cb *self); + +#endif + + diff --git a/release/src/linux/linux/include/net/irda/irlap.h b/release/src/linux/linux/include/net/irda/irlap.h new file mode 100644 index 00000000..774d4cd3 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlap.h @@ -0,0 +1,219 @@ +/********************************************************************* + * + * Filename: irlap.h + * Version: 0.8 + * Description: An IrDA LAP driver for Linux + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Aug 4 20:40:53 1997 + * Modified at: Fri Dec 10 13:21:17 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLAP_H +#define IRLAP_H + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/skbuff.h> +#include <linux/netdevice.h> +#include <linux/ppp_defs.h> +#include <linux/ppp-comp.h> +#include <linux/timer.h> + +#include <net/irda/irlap_event.h> + +#define CONFIG_IRDA_DYNAMIC_WINDOW 1 + +#define LAP_RELIABLE 1 +#define LAP_UNRELIABLE 0 + +#define LAP_ADDR_HEADER 1 /* IrLAP Address Header */ +#define LAP_CTRL_HEADER 1 /* IrLAP Control Header */ + +/* May be different when we get VFIR */ +#define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER) + +#define BROADCAST 0xffffffff /* Broadcast device address */ +#define CBROADCAST 0xfe /* Connection broadcast address */ +#define XID_FORMAT 0x01 /* Discovery XID format */ + +#define LAP_WINDOW_SIZE 8 +#define LAP_MAX_QUEUE 10 + +#define NR_EXPECTED 1 +#define NR_UNEXPECTED 0 +#define NR_INVALID -1 + +#define NS_EXPECTED 1 +#define NS_UNEXPECTED 0 +#define NS_INVALID -1 + +/* Main structure of IrLAP */ +struct irlap_cb { + irda_queue_t q; /* Must be first */ + magic_t magic; + + /* Device we are attached to */ + struct net_device *netdev; + char hw_name[2*IFNAMSIZ + 1]; + + /* Connection state */ + volatile IRLAP_STATE state; /* Current state */ + + /* Timers used by IrLAP */ + struct timer_list query_timer; + struct timer_list slot_timer; + struct timer_list discovery_timer; + struct timer_list final_timer; + struct timer_list poll_timer; + struct timer_list wd_timer; + struct timer_list backoff_timer; + + /* Media busy stuff */ + struct timer_list media_busy_timer; + int media_busy; + + /* Timeouts which will be different with different turn time */ + int slot_timeout; + int poll_timeout; + int final_timeout; + int wd_timeout; + + struct sk_buff_head txq; /* Frames to be transmitted */ + struct sk_buff_head txq_ultra; + + __u8 caddr; /* Connection address */ + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ + + int retry_count; /* Times tried to establish connection */ + int add_wait; /* True if we are waiting for frame */ + + __u8 connect_pending; + __u8 disconnect_pending; + + /* To send a faster RR if tx queue empty */ +#ifdef CONFIG_IRDA_FAST_RR + int fast_RR_timeout; + int fast_RR; +#endif /* CONFIG_IRDA_FAST_RR */ + + int N1; /* N1 * F-timer = Negitiated link disconnect warning threshold */ + int N2; /* N2 * F-timer = Negitiated link disconnect time */ + int N3; /* Connection retry count */ + + int local_busy; + int remote_busy; + int xmitflag; + + __u8 vs; /* Next frame to be sent */ + __u8 vr; /* Next frame to be received */ + __u8 va; /* Last frame acked */ + int window; /* Nr of I-frames allowed to send */ + int window_size; /* Current negotiated window size */ + +#ifdef CONFIG_IRDA_DYNAMIC_WINDOW + __u32 line_capacity; /* Number of bytes allowed to send */ + __u32 bytes_left; /* Number of bytes still allowed to transmit */ +#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */ + + struct sk_buff_head wx_list; + + __u8 ack_required; + + /* XID parameters */ + __u8 S; /* Number of slots */ + __u8 slot; /* Random chosen slot */ + __u8 s; /* Current slot */ + int frame_sent; /* Have we sent reply? */ + + hashbin_t *discovery_log; + discovery_t *discovery_cmd; + + __u32 speed; /* Link speed */ + + struct qos_info qos_tx; /* QoS requested by peer */ + struct qos_info qos_rx; /* QoS requested by self */ + struct qos_info *qos_dev; /* QoS supported by device */ + + notify_t notify; /* Callbacks to IrLMP */ + + int mtt_required; /* Minumum turnaround time required */ + int xbofs_delay; /* Nr of XBOF's used to MTT */ + int bofs_count; /* Negotiated extra BOFs */ + int next_bofs; /* Negotiated extra BOFs after next frame */ +}; + +extern hashbin_t *irlap; + +/* + * Function prototypes + */ +int irlap_init(void); +void irlap_cleanup(void); + +struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, + char * hw_name); +void irlap_close(struct irlap_cb *self); + +void irlap_connect_request(struct irlap_cb *self, __u32 daddr, + struct qos_info *qos, int sniff); +void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb); +void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb); +void irlap_connect_confirm(struct irlap_cb *, struct sk_buff *skb); + +void irlap_data_indication(struct irlap_cb *, struct sk_buff *, int unreliable); +void irlap_data_request(struct irlap_cb *, struct sk_buff *, int unreliable); + +#ifdef CONFIG_IRDA_ULTRA +void irlap_unitdata_request(struct irlap_cb *, struct sk_buff *); +void irlap_unitdata_indication(struct irlap_cb *, struct sk_buff *); +#endif /* CONFIG_IRDA_ULTRA */ + +void irlap_disconnect_request(struct irlap_cb *); +void irlap_disconnect_indication(struct irlap_cb *, LAP_REASON reason); + +void irlap_status_indication(struct irlap_cb *, int quality_of_link); + +void irlap_test_request(__u8 *info, int len); + +void irlap_discovery_request(struct irlap_cb *, discovery_t *discovery); +void irlap_discovery_confirm(struct irlap_cb *, hashbin_t *discovery_log); +void irlap_discovery_indication(struct irlap_cb *, discovery_t *discovery); + +void irlap_reset_indication(struct irlap_cb *self); +void irlap_reset_confirm(void); + +void irlap_update_nr_received(struct irlap_cb *, int nr); +int irlap_validate_nr_received(struct irlap_cb *, int nr); +int irlap_validate_ns_received(struct irlap_cb *, int ns); + +int irlap_generate_rand_time_slot(int S, int s); +void irlap_initiate_connection_state(struct irlap_cb *); +void irlap_flush_all_queues(struct irlap_cb *); +void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now); +void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *); + +void irlap_init_qos_capabilities(struct irlap_cb *, struct qos_info *); +void irlap_apply_default_connection_parameters(struct irlap_cb *self); +void irlap_apply_connection_parameters(struct irlap_cb *self, int now); + +#define IRLAP_GET_HEADER_SIZE(self) (LAP_MAX_HEADER) +#define IRLAP_GET_TX_QUEUE_LEN(self) skb_queue_len(&self->txq) + +#endif diff --git a/release/src/linux/linux/include/net/irda/irlap_event.h b/release/src/linux/linux/include/net/irda/irlap_event.h new file mode 100644 index 00000000..9c7b995c --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlap_event.h @@ -0,0 +1,141 @@ +/********************************************************************* + * + * + * Filename: irlap_event.h + * Version: 0.1 + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sat Aug 16 00:59:29 1997 + * Modified at: Tue Dec 21 11:20:30 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRLAP_EVENT_H +#define IRLAP_EVENT_H + +#include <net/irda/irda.h> +#include <net/irda/discovery.h> + +struct irlap_cb; + +/* IrLAP States */ +typedef enum { + LAP_NDM, /* Normal disconnected mode */ + LAP_QUERY, + LAP_REPLY, + LAP_CONN, /* Connect indication */ + LAP_SETUP, /* Setting up connection */ + LAP_OFFLINE, /* A really boring state */ + LAP_XMIT_P, + LAP_PCLOSE, + LAP_NRM_P, /* Normal response mode as primary */ + LAP_RESET_WAIT, + LAP_RESET, + LAP_NRM_S, /* Normal response mode as secondary */ + LAP_XMIT_S, + LAP_SCLOSE, + LAP_RESET_CHECK, +} IRLAP_STATE; + +/* IrLAP Events */ +typedef enum { + /* Services events */ + DISCOVERY_REQUEST, + CONNECT_REQUEST, + CONNECT_RESPONSE, + DISCONNECT_REQUEST, + DATA_REQUEST, + RESET_REQUEST, + RESET_RESPONSE, + + /* Send events */ + SEND_I_CMD, + SEND_UI_FRAME, + + /* Receive events */ + RECV_DISCOVERY_XID_CMD, + RECV_DISCOVERY_XID_RSP, + RECV_SNRM_CMD, + RECV_TEST_CMD, + RECV_TEST_RSP, + RECV_UA_RSP, + RECV_DM_RSP, + RECV_RD_RSP, + RECV_I_CMD, + RECV_I_RSP, + RECV_UI_FRAME, + RECV_FRMR_RSP, + RECV_RR_CMD, + RECV_RR_RSP, + RECV_RNR_CMD, + RECV_RNR_RSP, + RECV_REJ_CMD, + RECV_REJ_RSP, + RECV_SREJ_CMD, + RECV_SREJ_RSP, + RECV_DISC_CMD, + + /* Timer events */ + SLOT_TIMER_EXPIRED, + QUERY_TIMER_EXPIRED, + FINAL_TIMER_EXPIRED, + POLL_TIMER_EXPIRED, + DISCOVERY_TIMER_EXPIRED, + WD_TIMER_EXPIRED, + BACKOFF_TIMER_EXPIRED, + MEDIA_BUSY_TIMER_EXPIRED, +} IRLAP_EVENT; + +/* + * Various things used by the IrLAP state machine + */ +struct irlap_info { + __u8 caddr; /* Connection address */ + __u8 control; /* Frame type */ + __u8 cmd; + + __u32 saddr; + __u32 daddr; + + int pf; /* Poll/final bit set */ + + __u8 nr; /* Sequence number of next frame expected */ + __u8 ns; /* Sequence number of frame sent */ + + int S; /* Number of slots */ + int slot; /* Random chosen slot */ + int s; /* Current slot */ + + discovery_t *discovery; /* Discovery information */ +}; + +extern const char *irlap_state[]; + +void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, + struct sk_buff *skb, struct irlap_info *info); +void irlap_print_event(IRLAP_EVENT event); + +extern int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb); + +#endif diff --git a/release/src/linux/linux/include/net/irda/irlap_frame.h b/release/src/linux/linux/include/net/irda/irlap_frame.h new file mode 100644 index 00000000..99a2a95e --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlap_frame.h @@ -0,0 +1,139 @@ +/********************************************************************* + * + * Filename: irlap_frame.h + * Version: 0.9 + * Description: IrLAP frame declarations + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Aug 19 10:27:26 1997 + * Modified at: Sat Dec 25 21:07:26 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRLAP_FRAME_H +#define IRLAP_FRAME_H + +#include <linux/skbuff.h> + +#include <net/irda/irda.h> +#include <net/irda/irlap.h> +#include <net/irda/qos.h> + +/* Frame types and templates */ +#define INVALID 0xff + +/* Unnumbered (U) commands */ +#define SNRM_CMD 0x83 /* Set Normal Response Mode */ +#define DISC_CMD 0x43 /* Disconnect */ +#define XID_CMD 0x2f /* Exchange Station Identification */ +#define TEST_CMD 0xe3 /* Test */ + +/* Unnumbered responses */ +#define RNRM_RSP 0x83 /* Request Normal Response Mode */ +#define UA_RSP 0x63 /* Unnumbered Acknowledgement */ +#define FRMR_RSP 0x87 /* Frame Reject */ +#define DM_RSP 0x0f /* Disconnect Mode */ +#define RD_RSP 0x43 /* Request Disconnection */ +#define XID_RSP 0xaf /* Exchange Station Identification */ +#define TEST_RSP 0xe3 /* Test frame */ + +/* Supervisory (S) */ +#define RR 0x01 /* Receive Ready */ +#define REJ 0x09 /* Reject */ +#define RNR 0x05 /* Receive Not Ready */ +#define SREJ 0x0d /* Selective Reject */ + +/* Information (I) */ +#define I_FRAME 0x00 /* Information Format */ +#define UI_FRAME 0x03 /* Unnumbered Information */ + +#define CMD_FRAME 0x01 +#define RSP_FRAME 0x00 + +#define PF_BIT 0x10 /* Poll/final bit */ + +struct xid_frame { + __u8 caddr; /* Connection address */ + __u8 control; + __u8 ident; /* Should always be XID_FORMAT */ + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ + __u8 flags; /* Discovery flags */ + __u8 slotnr; + __u8 version; +} PACK; + +struct test_frame { + __u8 caddr; /* Connection address */ + __u8 control; + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ +} PACK; + +struct ua_frame { + __u8 caddr; + __u8 control; + + __u32 saddr; /* Source device address */ + __u32 daddr; /* Dest device address */ +} PACK; + +struct i_frame { + __u8 caddr; + __u8 control; +} PACK; + +struct snrm_frame { + __u8 caddr; + __u8 control; + __u32 saddr; + __u32 daddr; + __u8 ncaddr; +} PACK; + +void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb); +void irlap_send_discovery_xid_frame(struct irlap_cb *, int S, __u8 s, + __u8 command, discovery_t *discovery); +void irlap_send_snrm_frame(struct irlap_cb *, struct qos_info *); +void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, + struct sk_buff *cmd); +void irlap_send_ua_response_frame(struct irlap_cb *, struct qos_info *); +void irlap_send_dm_frame(struct irlap_cb *self); +void irlap_send_rd_frame(struct irlap_cb *self); +void irlap_send_disc_frame(struct irlap_cb *self); +void irlap_send_rr_frame(struct irlap_cb *self, int command); + +void irlap_send_data_primary(struct irlap_cb *, struct sk_buff *); +void irlap_send_data_primary_poll(struct irlap_cb *, struct sk_buff *); +void irlap_send_data_secondary(struct irlap_cb *, struct sk_buff *); +void irlap_send_data_secondary_final(struct irlap_cb *, struct sk_buff *); +void irlap_resend_rejected_frames(struct irlap_cb *, int command); +void irlap_resend_rejected_frame(struct irlap_cb *self, int command); + +void irlap_send_i_frame(struct irlap_cb *, struct sk_buff *, int command); +void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb, + __u8 caddr, int command); + +extern int irlap_insert_qos_negotiation_params(struct irlap_cb *self, + struct sk_buff *skb); + +#endif diff --git a/release/src/linux/linux/include/net/irda/irlmp.h b/release/src/linux/linux/include/net/irda/irlmp.h new file mode 100644 index 00000000..fa87b52d --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlmp.h @@ -0,0 +1,279 @@ +/********************************************************************* + * + * Filename: irlmp.h + * Version: 0.9 + * Description: IrDA Link Management Protocol (LMP) layer + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Aug 17 20:54:32 1997 + * Modified at: Fri Dec 10 13:23:01 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLMP_H +#define IRLMP_H + +#include <asm/param.h> /* for HZ */ + +#include <linux/config.h> +#include <linux/types.h> + +#include <net/irda/irda.h> +#include <net/irda/qos.h> +#include <net/irda/irlap.h> +#include <net/irda/irlmp_event.h> +#include <net/irda/irqueue.h> +#include <net/irda/discovery.h> + +/* LSAP-SEL's */ +#define LSAP_MASK 0x7f +#define LSAP_IAS 0x00 +#define LSAP_ANY 0xff +#define LSAP_MAX 0x6f /* 0x70-0x7f are reserved */ +#define LSAP_CONNLESS 0x70 /* Connectionless LSAP, mostly used for Ultra */ + +#define DEV_ADDR_ANY 0xffffffff + +#define LMP_HEADER 2 /* Dest LSAP + Source LSAP */ +#define LMP_CONTROL_HEADER 4 +#define LMP_PID_HEADER 1 /* Used by Ultra */ +#define LMP_MAX_HEADER (LMP_CONTROL_HEADER+LAP_MAX_HEADER) + +#define LM_MAX_CONNECTIONS 10 + +#define LM_IDLE_TIMEOUT 2*HZ /* 2 seconds for now */ + +typedef enum { + S_PNP, + S_PDA, + S_COMPUTER, + S_PRINTER, + S_MODEM, + S_FAX, + S_LAN, + S_TELEPHONY, + S_COMM, + S_OBEX, + S_ANY, + S_END, +} SERVICE; + +typedef void (*DISCOVERY_CALLBACK1) (discovery_t *, DISCOVERY_MODE, void *); +typedef void (*DISCOVERY_CALLBACK2) (hashbin_t *, void *); + +typedef struct { + irda_queue_t queue; /* Must be first */ + + __u16 hints; /* Hint bits */ +} irlmp_service_t; + +typedef struct { + irda_queue_t queue; /* Must be first */ + + __u16 hint_mask; + + DISCOVERY_CALLBACK1 disco_callback; /* Selective discovery */ + DISCOVERY_CALLBACK1 expir_callback; /* Selective expiration */ + void *priv; /* Used to identify client */ +} irlmp_client_t; + +struct lap_cb; /* Forward decl. */ + +/* + * Information about each logical LSAP connection + */ +struct lsap_cb { + irda_queue_t queue; /* Must be first */ + magic_t magic; + + int connected; + int persistent; + + __u8 slsap_sel; /* Source (this) LSAP address */ + __u8 dlsap_sel; /* Destination LSAP address (if connected) */ +#ifdef CONFIG_IRDA_ULTRA + __u8 pid; /* Used by connectionless LSAP */ +#endif /* CONFIG_IRDA_ULTRA */ + struct sk_buff *conn_skb; /* Store skb here while connecting */ + + struct timer_list watchdog_timer; + + IRLMP_STATE lsap_state; /* Connection state */ + notify_t notify; /* Indication/Confirm entry points */ + struct qos_info qos; /* QoS for this connection */ + + struct lap_cb *lap; /* Pointer to LAP connection structure */ +}; + +/* + * Information about each registred IrLAP layer + */ +struct lap_cb { + irda_queue_t queue; /* Must be first */ + magic_t magic; + + int reason; /* LAP disconnect reason */ + + IRLMP_STATE lap_state; + + struct irlap_cb *irlap; /* Instance of IrLAP layer */ + hashbin_t *lsaps; /* LSAP associated with this link */ + + __u8 caddr; /* Connection address */ + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ + + struct qos_info *qos; /* LAP QoS for this session */ + struct timer_list idle_timer; +}; + +/* + * Used for caching the last slsap->dlsap->handle mapping + */ +typedef struct { + int valid; + + __u8 slsap_sel; + __u8 dlsap_sel; + struct lsap_cb *lsap; +} CACHE_ENTRY; + +/* + * Main structure for IrLMP + */ +struct irlmp_cb { + magic_t magic; + + __u8 conflict_flag; + + discovery_t discovery_cmd; /* Discovery command to use by IrLAP */ + discovery_t discovery_rsp; /* Discovery response to use by IrLAP */ + + int free_lsap_sel; + +#ifdef CONFIG_IRDA_CACHE_LAST_LSAP + CACHE_ENTRY cache; /* Caching last slsap->dlsap->handle mapping */ +#endif + struct timer_list discovery_timer; + + hashbin_t *links; /* IrLAP connection table */ + hashbin_t *unconnected_lsaps; + hashbin_t *clients; + hashbin_t *services; + + hashbin_t *cachelog; /* Current discovery log */ + spinlock_t log_lock; /* discovery log spinlock */ + + int running; + + __u16_host_order hints; /* Hint bits */ +}; + +/* Prototype declarations */ +int irlmp_init(void); +void irlmp_cleanup(void); +struct lsap_cb *irlmp_open_lsap(__u8 slsap, notify_t *notify, __u8 pid); +void irlmp_close_lsap( struct lsap_cb *self); + +__u16 irlmp_service_to_hint(int service); +__u32 irlmp_register_service(__u16 hints); +int irlmp_unregister_service(__u32 handle); +__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, + DISCOVERY_CALLBACK1 expir_clb, void *priv); +int irlmp_unregister_client(__u32 handle); +int irlmp_update_client(__u32 handle, __u16 hint_mask, + DISCOVERY_CALLBACK1 disco_clb, + DISCOVERY_CALLBACK1 expir_clb, void *priv); + +void irlmp_register_link(struct irlap_cb *, __u32 saddr, notify_t *); +void irlmp_unregister_link(__u32 saddr); + +int irlmp_connect_request(struct lsap_cb *, __u8 dlsap_sel, + __u32 saddr, __u32 daddr, + struct qos_info *, struct sk_buff *); +void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb); +int irlmp_connect_response(struct lsap_cb *, struct sk_buff *); +void irlmp_connect_confirm(struct lsap_cb *, struct sk_buff *); +struct lsap_cb *irlmp_dup(struct lsap_cb *self, void *instance); + +void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, + struct sk_buff *userdata); +int irlmp_disconnect_request(struct lsap_cb *, struct sk_buff *userdata); + +void irlmp_discovery_confirm(hashbin_t *discovery_log, DISCOVERY_MODE); +void irlmp_discovery_request(int nslots); +struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots); +void irlmp_do_expiry(void); +void irlmp_do_discovery(int nslots); +discovery_t *irlmp_get_discovery_response(void); +void irlmp_discovery_expiry(discovery_t *expiry); + +int irlmp_data_request(struct lsap_cb *, struct sk_buff *); +void irlmp_data_indication(struct lsap_cb *, struct sk_buff *); + +int irlmp_udata_request(struct lsap_cb *, struct sk_buff *); +void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *); + +#ifdef CONFIG_IRDA_ULTRA +int irlmp_connless_data_request(struct lsap_cb *, struct sk_buff *); +void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *); +#endif /* CONFIG_IRDA_ULTRA */ + +void irlmp_status_request(void); +void irlmp_status_indication(struct lap_cb *, LINK_STATUS link, LOCK_STATUS lock); + +int irlmp_slsap_inuse(__u8 slsap); +__u8 irlmp_find_free_slsap(void); +LM_REASON irlmp_convert_lap_reason(LAP_REASON); + +__u32 irlmp_get_saddr(struct lsap_cb *self); +__u32 irlmp_get_daddr(struct lsap_cb *self); + +extern char *lmp_reasons[]; +extern int sysctl_discovery_timeout; +extern int sysctl_discovery_slots; +extern int sysctl_discovery; +extern int sysctl_lap_keepalive_time; /* in ms, default is LM_IDLE_TIMEOUT */ +extern struct irlmp_cb *irlmp; + +static inline hashbin_t *irlmp_get_cachelog(void) { return irlmp->cachelog; } + +static inline int irlmp_get_lap_tx_queue_len(struct lsap_cb *self) +{ + if (self == NULL) + return 0; + if (self->lap == NULL) + return 0; + if (self->lap->irlap == NULL) + return 0; + + return IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap); +} + +/* After doing a irlmp_dup(), this get one of the two socket back into + * a state where it's waiting incomming connections. + * Note : this can be used *only* if the socket is not yet connected + * (i.e. NO irlmp_connect_response() done on this socket). + * - Jean II */ +static inline void irlmp_listen(struct lsap_cb *self) +{ + self->dlsap_sel = LSAP_ANY; + self->lap = NULL; + self->lsap_state = LSAP_DISCONNECTED; +} + +#endif diff --git a/release/src/linux/linux/include/net/irda/irlmp_event.h b/release/src/linux/linux/include/net/irda/irlmp_event.h new file mode 100644 index 00000000..e8af8d3d --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlmp_event.h @@ -0,0 +1,116 @@ +/********************************************************************* + * + * Filename: irlmp_event.h + * Version: 0.1 + * Description: IrDA-LMP event handling + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Aug 4 20:40:53 1997 + * Modified at: Thu Jul 8 12:18:54 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRLMP_EVENT_H +#define IRLMP_EVENT_H + +struct irlmp_cb; +struct lsap_cb; +struct lap_cb; + +/* LAP states */ +typedef enum { + /* IrLAP connection control states */ + LAP_STANDBY, /* No LAP connection */ + LAP_U_CONNECT, /* Starting LAP connection */ + LAP_ACTIVE, /* LAP connection is active */ +} IRLMP_STATE; + +/* LSAP connection control states */ +typedef enum { + LSAP_DISCONNECTED, /* No LSAP connection */ + LSAP_CONNECT, /* Connect indication from peer */ + LSAP_CONNECT_PEND, /* Connect request from service user */ + LSAP_DATA_TRANSFER_READY, /* LSAP connection established */ + LSAP_SETUP, /* Trying to set up LSAP connection */ + LSAP_SETUP_PEND, /* Request to start LAP connection */ +} LSAP_STATE; + +typedef enum { + /* LSAP events */ + LM_CONNECT_REQUEST, + LM_CONNECT_CONFIRM, + LM_CONNECT_RESPONSE, + LM_CONNECT_INDICATION, + + LM_DISCONNECT_INDICATION, + LM_DISCONNECT_REQUEST, + + LM_DATA_REQUEST, + LM_UDATA_REQUEST, + LM_DATA_INDICATION, + LM_UDATA_INDICATION, + + LM_WATCHDOG_TIMEOUT, + + /* IrLAP events */ + LM_LAP_CONNECT_REQUEST, + LM_LAP_CONNECT_INDICATION, + LM_LAP_CONNECT_CONFIRM, + LM_LAP_DISCONNECT_INDICATION, + LM_LAP_DISCONNECT_REQUEST, + LM_LAP_DISCOVERY_REQUEST, + LM_LAP_DISCOVERY_CONFIRM, + LM_LAP_IDLE_TIMEOUT, +} IRLMP_EVENT; + +/* + * Information which is used by the current thread, when executing in the + * state machine. + */ +struct irlmp_event { + IRLMP_EVENT *event; + struct sk_buff *skb; + + __u8 hint; + __u32 daddr; + __u32 saddr; + + __u8 slsap; + __u8 dlsap; + + int reason; + + discovery_t *discovery; +}; + +extern const char *irlmp_state[]; +extern const char *irlsap_state[]; + +void irlmp_watchdog_timer_expired(void *data); +void irlmp_discovery_timer_expired(void *data); +void irlmp_idle_timer_expired(void *data); + +void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event, + struct sk_buff *skb); +int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, + struct sk_buff *skb); + +#endif /* IRLMP_EVENT_H */ + + + + diff --git a/release/src/linux/linux/include/net/irda/irlmp_frame.h b/release/src/linux/linux/include/net/irda/irlmp_frame.h new file mode 100644 index 00000000..779d34ac --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irlmp_frame.h @@ -0,0 +1,63 @@ +/********************************************************************* + * + * Filename: irlmp_frame.h + * Version: 0.9 + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Aug 19 02:09:59 1997 + * Modified at: Fri Dec 10 13:21:53 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRMLP_FRAME_H +#define IRMLP_FRAME_H + +#include <linux/config.h> +#include <linux/skbuff.h> + +#include <net/irda/discovery.h> + +/* IrLMP frame opcodes */ +#define CONNECT_CMD 0x01 +#define CONNECT_CNF 0x81 +#define DISCONNECT 0x02 +#define ACCESSMODE_CMD 0x03 +#define ACCESSMODE_CNF 0x83 + +#define CONTROL_BIT 0x80 + +inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, + int expedited, struct sk_buff *skb); +void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, + __u8 opcode, struct sk_buff *skb); +void irlmp_link_data_indication(struct lap_cb *, struct sk_buff *, + int unreliable); +#ifdef CONFIG_IRDA_ULTRA +void irlmp_link_unitdata_indication(struct lap_cb *, struct sk_buff *); +#endif /* CONFIG_IRDA_ULTRA */ + +void irlmp_link_connect_indication(struct lap_cb *, __u32 saddr, __u32 daddr, + struct qos_info *qos, struct sk_buff *skb); +void irlmp_link_connect_request(__u32 daddr); +void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos, + struct sk_buff *skb); +void irlmp_link_disconnect_indication(struct lap_cb *, struct irlap_cb *, + LAP_REASON reason, struct sk_buff *); +void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log); +void irlmp_link_discovery_indication(struct lap_cb *, discovery_t *discovery); + +#endif diff --git a/release/src/linux/linux/include/net/irda/irmod.h b/release/src/linux/linux/include/net/irda/irmod.h new file mode 100644 index 00000000..d5472092 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irmod.h @@ -0,0 +1,52 @@ +/********************************************************************* + * + * Filename: irmod.h + * Version: 0.3 + * Description: IrDA module and utilities functions + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Dec 15 13:58:52 1997 + * Modified at: Fri Jan 28 13:15:24 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. + * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charg. + * + ********************************************************************/ + +#ifndef IRMOD_H +#define IRMOD_H + +#include <net/irda/irda.h> /* Notify stuff */ + +/* Nothing much here anymore - Maybe this header should be merged in + * another header like net/irda/irda.h... - Jean II */ + +/* Locking wrapper - Note the inverted logic on irda_lock(). + * Those function basically return false if the lock is already in the + * position you want to set it. - Jean II */ +#define irda_lock(lock) (! test_and_set_bit(0, (void *) (lock))) +#define irda_unlock(lock) (test_and_clear_bit(0, (void *) (lock))) + +/* Zero the notify structure */ +void irda_notify_init(notify_t *notify); + +#endif /* IRMOD_H */ + + + + + + + + + diff --git a/release/src/linux/linux/include/net/irda/irport.h b/release/src/linux/linux/include/net/irda/irport.h new file mode 100644 index 00000000..23b1a244 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irport.h @@ -0,0 +1,89 @@ +/********************************************************************* + * + * Filename: irport.h + * Version: 0.1 + * Description: Serial driver for IrDA + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Aug 3 13:49:59 1997 + * Modified at: Fri Jan 14 10:21:10 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997, 1998-2000 Dag Brattli <dagb@cs.uit.no> + * All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRPORT_H +#define IRPORT_H + +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <linux/types.h> +#include <linux/spinlock.h> + +#include <net/irda/irda_device.h> + +#define SPEED_DEFAULT 9600 +#define SPEED_MAX 115200 + +/* + * These are the supported serial types. + */ +#define PORT_UNKNOWN 0 +#define PORT_8250 1 +#define PORT_16450 2 +#define PORT_16550 3 +#define PORT_16550A 4 +#define PORT_CIRRUS 5 +#define PORT_16650 6 +#define PORT_MAX 6 + +#define FRAME_MAX_SIZE 2048 + +struct irport_cb { + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are attached to */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + struct qos_info qos; /* QoS capabilities for this device */ + dongle_t *dongle; /* Dongle driver */ + + __u32 flags; /* Interface flags */ + __u32 new_speed; + int mode; + int index; /* Instance index */ + + spinlock_t lock; /* For serializing operations */ + + /* For piggyback drivers */ + void *priv; + void (*change_speed)(void *priv, __u32 speed); + void (*interrupt)(int irq, void *dev_id, struct pt_regs *regs); +}; + +struct irport_cb *irport_open(int i, unsigned int iobase, unsigned int irq); +int irport_close(struct irport_cb *self); +void irport_start(struct irport_cb *self); +void irport_stop(struct irport_cb *self); +void irport_change_speed(void *priv, __u32 speed); +void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs); +int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev); +int irport_net_open(struct net_device *dev); +int irport_net_close(struct net_device *dev); + +#endif /* IRPORT_H */ diff --git a/release/src/linux/linux/include/net/irda/irqueue.h b/release/src/linux/linux/include/net/irda/irqueue.h new file mode 100644 index 00000000..f7c1ba65 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irqueue.h @@ -0,0 +1,102 @@ +/********************************************************************* + * + * Filename: irqueue.h + * Version: 0.3 + * Description: General queue implementation + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Jun 9 13:26:50 1998 + * Modified at: Thu Oct 7 13:25:16 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (C) 1998-1999, Aage Kvalnes <aage@cs.uit.no> + * Copyright (c) 1998, Dag Brattli + * All Rights Reserved. + * + * This code is taken from the Vortex Operating System written by Aage + * Kvalnes and has been ported to Linux and Linux/IR by Dag Brattli + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#include <linux/types.h> +#include <linux/spinlock.h> + +#ifndef IRDA_QUEUE_H +#define IRDA_QUEUE_H + +#define NAME_SIZE 32 + +/* + * Hash types + */ +#define HB_NOLOCK 0 +#define HB_GLOBAL 1 +#define HB_LOCAL 2 +#define HB_SORTED 4 + +/* + * Hash defines + */ +#define HASHBIN_SIZE 8 +#define HASHBIN_MASK 0x7 + +#ifndef ALIGN +#define ALIGN __attribute__((aligned)) +#endif + +#define Q_NULL { NULL, NULL, "", 0 } + +typedef void (*FREE_FUNC)(void *arg); + +/* + * Hashbin + */ +#define GET_HASHBIN(x) ( x & HASHBIN_MASK ) + +struct irda_queue { + struct irda_queue *q_next; + struct irda_queue *q_prev; + + char q_name[NAME_SIZE]; + __u32 q_hash; +}; +typedef struct irda_queue irda_queue_t; + +typedef struct hashbin_t { + __u32 magic; + int hb_type; + int hb_size; + spinlock_t hb_mutex[HASHBIN_SIZE] ALIGN; + irda_queue_t *hb_queue[HASHBIN_SIZE] ALIGN; + + irda_queue_t* hb_current; +} hashbin_t; + +hashbin_t *hashbin_new(int type); +int hashbin_delete(hashbin_t* hashbin, FREE_FUNC func); +int hashbin_clear(hashbin_t* hashbin, FREE_FUNC free_func); +void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, + char* name); +void* hashbin_find(hashbin_t* hashbin, __u32 hashv, char* name); +void* hashbin_remove(hashbin_t* hashbin, __u32 hashv, char* name); +void* hashbin_remove_first(hashbin_t *hashbin); +void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry); +irda_queue_t *hashbin_get_first(hashbin_t *hashbin); +irda_queue_t *hashbin_get_next(hashbin_t *hashbin); + +void enqueue_last(irda_queue_t **queue, irda_queue_t* element); +void enqueue_first(irda_queue_t **queue, irda_queue_t* element); +irda_queue_t *dequeue_first(irda_queue_t **queue); + +#define HASHBIN_GET_SIZE(hashbin) hashbin->hb_size + +#endif diff --git a/release/src/linux/linux/include/net/irda/irttp.h b/release/src/linux/linux/include/net/irda/irttp.h new file mode 100644 index 00000000..d1087418 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irttp.h @@ -0,0 +1,164 @@ +/********************************************************************* + * + * Filename: irttp.h + * Version: 1.0 + * Description: Tiny Transport Protocol (TTP) definitions + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sun Aug 31 20:14:31 1997 + * Modified at: Sun Dec 12 13:09:07 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRTTP_H +#define IRTTP_H + +#include <linux/types.h> +#include <linux/skbuff.h> +#include <linux/spinlock.h> + +#include <net/irda/irda.h> +#include <net/irda/irlmp.h> +#include <net/irda/qos.h> +#include <net/irda/irqueue.h> + +#define TTP_MAX_CONNECTIONS LM_MAX_CONNECTIONS +#define TTP_HEADER 1 +#define TTP_MAX_HEADER (TTP_HEADER + LMP_MAX_HEADER) +#define TTP_SAR_HEADER 5 +#define TTP_PARAMETERS 0x80 +#define TTP_MORE 0x80 + +#define DEFAULT_INITIAL_CREDIT 14 + +#define TTP_LOW_THRESHOLD 4 +#define TTP_HIGH_THRESHOLD 10 +#define TTP_MAX_QUEUE 14 + +/* Some priorities for disconnect requests */ +#define P_NORMAL 0 +#define P_HIGH 1 + +#define TTP_SAR_DISABLE 0 +#define TTP_SAR_UNBOUND 0xffffffff + +/* Parameters */ +#define TTP_MAX_SDU_SIZE 0x01 + +/* + * This structure contains all data assosiated with one instance of a TTP + * connection. + */ +struct tsap_cb { + irda_queue_t q; /* Must be first */ + magic_t magic; /* Just in case */ + + __u8 stsap_sel; /* Source TSAP */ + __u8 dtsap_sel; /* Destination TSAP */ + + struct lsap_cb *lsap; /* Corresponding LSAP to this TSAP */ + + __u8 connected; /* TSAP connected */ + + __u8 initial_credit; /* Initial credit to give peer */ + + int avail_credit; /* Available credit to return to peer */ + int remote_credit; /* Credit held by peer TTP entity */ + int send_credit; /* Credit held by local TTP entity */ + + struct sk_buff_head tx_queue; /* Frames to be transmitted */ + struct sk_buff_head rx_queue; /* Received frames */ + struct sk_buff_head rx_fragments; + int tx_queue_lock; + int rx_queue_lock; + spinlock_t lock; + + notify_t notify; /* Callbacks to client layer */ + + struct net_device_stats stats; + struct timer_list todo_timer; + + __u32 max_seg_size; /* Max data that fit into an IrLAP frame */ + __u8 max_header_size; + + int rx_sdu_busy; /* RxSdu.busy */ + __u32 rx_sdu_size; /* Current size of a partially received frame */ + __u32 rx_max_sdu_size; /* Max receive user data size */ + + int tx_sdu_busy; /* TxSdu.busy */ + __u32 tx_max_sdu_size; /* Max transmit user data size */ + + int close_pend; /* Close, but disconnect_pend */ + int disconnect_pend; /* Disconnect, but still data to send */ + struct sk_buff *disconnect_skb; +}; + +struct irttp_cb { + magic_t magic; + hashbin_t *tsaps; +}; + +int irttp_init(void); +void irttp_cleanup(void); + +struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify); +int irttp_close_tsap(struct tsap_cb *self); + +int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb); +int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb); + +int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, + __u32 saddr, __u32 daddr, + struct qos_info *qos, __u32 max_sdu_size, + struct sk_buff *userdata); +int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, + struct sk_buff *userdata); +int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb, + int priority); +void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow); +void irttp_status_indication(void *instance, + LINK_STATUS link, LOCK_STATUS lock); +struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance); + +static __inline __u32 irttp_get_saddr(struct tsap_cb *self) +{ + return irlmp_get_saddr(self->lsap); +} + +static __inline __u32 irttp_get_daddr(struct tsap_cb *self) +{ + return irlmp_get_daddr(self->lsap); +} + +static __inline __u32 irttp_get_max_seg_size(struct tsap_cb *self) +{ + return self->max_seg_size; +} + +/* After doing a irttp_dup(), this get one of the two socket back into + * a state where it's waiting incomming connections. + * Note : this can be used *only* if the socket is not yet connected + * (i.e. NO irttp_connect_response() done on this socket). + * - Jean II */ +static inline void irttp_listen(struct tsap_cb *self) +{ + irlmp_listen(self->lsap); + self->dtsap_sel = LSAP_ANY; +} + +extern struct irttp_cb *irttp; + +#endif /* IRTTP_H */ diff --git a/release/src/linux/linux/include/net/irda/irtty.h b/release/src/linux/linux/include/net/irda/irtty.h new file mode 100644 index 00000000..c6c54e1a --- /dev/null +++ b/release/src/linux/linux/include/net/irda/irtty.h @@ -0,0 +1,79 @@ +/********************************************************************* + * + * Filename: irtty.h + * Version: 1.0 + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Dec 9 21:13:12 1997 + * Modified at: Tue Jan 25 09:10:18 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997, 1999-2000 Dag Brattli, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRTTY_H +#define IRTTY_H + +#include <linux/if.h> +#include <linux/skbuff.h> +#include <linux/termios.h> +#include <linux/netdevice.h> + +#include <net/irda/irda.h> +#include <net/irda/irqueue.h> +#include <net/irda/irda_device.h> + +/* Used by ioctl */ +struct irtty_info { + char name[6]; +}; + +#define IRTTY_IOC_MAGIC 'e' +#define IRTTY_IOCTDONGLE _IO(IRTTY_IOC_MAGIC, 1) +#define IRTTY_IOCGET _IOR(IRTTY_IOC_MAGIC, 2, struct irtty_info) +#define IRTTY_IOC_MAXNR 2 + +struct irtty_cb { + irda_queue_t q; /* Must be first */ + magic_t magic; + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct irda_task *task; + struct net_device_stats stats; + + struct tty_struct *tty; + struct irlap_cb *irlap; /* The link layer we are binded to */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + struct qos_info qos; /* QoS capabilities for this device */ + dongle_t *dongle; /* Dongle driver */ + + __u32 new_speed; + __u32 flags; /* Interface flags */ + + INFRARED_MODE mode; +}; + +int irtty_register_dongle(struct dongle_reg *dongle); +void irtty_unregister_dongle(struct dongle_reg *dongle); + +#endif + + + + + diff --git a/release/src/linux/linux/include/net/irda/nsc-ircc.h b/release/src/linux/linux/include/net/irda/nsc-ircc.h new file mode 100644 index 00000000..637458dd --- /dev/null +++ b/release/src/linux/linux/include/net/irda/nsc-ircc.h @@ -0,0 +1,266 @@ +/********************************************************************* + * + * Filename: nsc-ircc.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Fri Nov 13 14:37:40 1998 + * Modified at: Sun Jan 23 17:47:00 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no> + * Copyright (c) 1998 Lichen Wang, <lwang@actisys.com> + * Copyright (c) 1998 Actisys Corp., www.actisys.com + * All Rights Reserved + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef NSC_IRCC_H +#define NSC_IRCC_H + +#include <linux/time.h> + +#include <linux/spinlock.h> +#include <linux/pm.h> +#include <asm/io.h> + +/* DMA modes needed */ +#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ +#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ + +/* Config registers for the '108 */ +#define CFG_BAIC 0x00 +#define CFG_CSRT 0x01 +#define CFG_MCTL 0x02 + +/* Config registers for the '338 */ +#define CFG_FER 0x00 +#define CFG_FAR 0x01 +#define CFG_PTR 0x02 +#define CFG_PNP0 0x1b +#define CFG_PNP1 0x1c +#define CFG_PNP3 0x4f + +/* Flags for configuration register CRF0 */ +#define APEDCRC 0x02 +#define ENBNKSEL 0x01 + +/* Set 0 */ +#define TXD 0x00 /* Transmit data port */ +#define RXD 0x00 /* Receive data port */ + +/* Register 1 */ +#define IER 0x01 /* Interrupt Enable Register*/ +#define IER_RXHDL_IE 0x01 /* Receiver high data level interrupt */ +#define IER_TXLDL_IE 0x02 /* Transeiver low data level interrupt */ +#define IER_LS_IE 0x04//* Link Status Interrupt */ +#define IER_ETXURI 0x04 /* Tx underrun */ +#define IER_DMA_IE 0x10 /* DMA finished interrupt */ +#define IER_TXEMP_IE 0x20 +#define IER_SFIF_IE 0x40 /* Frame status FIFO intr */ +#define IER_TMR_IE 0x80 /* Timer event */ + +#define FCR 0x02 /* (write only) */ +#define FCR_FIFO_EN 0x01 /* Enable FIFO's */ +#define FCR_RXSR 0x02 /* Rx FIFO soft reset */ +#define FCR_TXSR 0x04 /* Tx FIFO soft reset */ +#define FCR_RXTH 0x40 /* Rx FIFO threshold (set to 16) */ +#define FCR_TXTH 0x20 /* Tx FIFO threshold (set to 17) */ + +#define EIR 0x02 /* (read only) */ +#define EIR_RXHDL_EV 0x01 +#define EIR_TXLDL_EV 0x02 +#define EIR_LS_EV 0x04 +#define EIR_DMA_EV 0x10 +#define EIR_TXEMP_EV 0x20 +#define EIR_SFIF_EV 0x40 +#define EIR_TMR_EV 0x80 + +#define LCR 0x03 /* Link control register */ +#define LCR_WLS_8 0x03 /* 8 bits */ + +#define BSR 0x03 /* Bank select register */ +#define BSR_BKSE 0x80 +#define BANK0 LCR_WLS_8 /* Must make sure that we set 8N1 */ +#define BANK1 0x80 +#define BANK2 0xe0 +#define BANK3 0xe4 +#define BANK4 0xe8 +#define BANK5 0xec +#define BANK6 0xf0 +#define BANK7 0xf4 + +#define MCR 0x04 /* Mode Control Register */ +#define MCR_MODE_MASK ~(0xd0) +#define MCR_UART 0x00 +#define MCR_RESERVED 0x20 +#define MCR_SHARP_IR 0x40 +#define MCR_SIR 0x60 +#define MCR_MIR 0x80 +#define MCR_FIR 0xa0 +#define MCR_CEIR 0xb0 +#define MCR_IR_PLS 0x10 +#define MCR_DMA_EN 0x04 +#define MCR_EN_IRQ 0x08 +#define MCR_TX_DFR 0x08 + +#define LSR 0x05 /* Link status register */ +#define LSR_RXDA 0x01 /* Receiver data available */ +#define LSR_TXRDY 0x20 /* Transmitter ready */ +#define LSR_TXEMP 0x40 /* Transmitter empty */ + +#define ASCR 0x07 /* Auxillary Status and Control Register */ +#define ASCR_RXF_TOUT 0x01 /* Rx FIFO timeout */ +#define ASCR_FEND_INF 0x02 /* Frame end bytes in rx FIFO */ +#define ASCR_S_EOT 0x04 /* Set end of transmission */ +#define ASCT_RXBSY 0x20 /* Rx busy */ +#define ASCR_TXUR 0x40 /* Transeiver underrun */ +#define ASCR_CTE 0x80 /* Clear timer event */ + +/* Bank 2 */ +#define BGDL 0x00 /* Baud Generator Divisor Port (Low Byte) */ +#define BGDH 0x01 /* Baud Generator Divisor Port (High Byte) */ + +#define ECR1 0x02 /* Extended Control Register 1 */ +#define ECR1_EXT_SL 0x01 /* Extended Mode Select */ +#define ECR1_DMANF 0x02 /* DMA Fairness */ +#define ECR1_DMATH 0x04 /* DMA Threshold */ +#define ECR1_DMASWP 0x08 /* DMA Swap */ + +#define EXCR2 0x04 +#define EXCR2_TFSIZ 0x01 /* Rx FIFO size = 32 */ +#define EXCR2_RFSIZ 0x04 /* Tx FIFO size = 32 */ + +#define TXFLV 0x06 /* Tx FIFO level */ +#define RXFLV 0x07 /* Rx FIFO level */ + +/* Bank 3 */ +#define MID 0x00 + +/* Bank 4 */ +#define TMRL 0x00 /* Timer low byte */ +#define TMRH 0x01 /* Timer high byte */ +#define IRCR1 0x02 /* Infrared control register 1 */ +#define IRCR1_TMR_EN 0x01 /* Timer enable */ + +#define TFRLL 0x04 +#define TFRLH 0x05 +#define RFRLL 0x06 +#define RFRLH 0x07 + +/* Bank 5 */ +#define IRCR2 0x04 /* Infrared control register 2 */ +#define IRCR2_MDRS 0x04 /* MIR data rate select */ +#define IRCR2_FEND_MD 0x20 /* */ + +#define FRM_ST 0x05 /* Frame status FIFO */ +#define FRM_ST_VLD 0x80 /* Frame status FIFO data valid */ +#define FRM_ST_ERR_MSK 0x5f +#define FRM_ST_LOST_FR 0x40 /* Frame lost */ +#define FRM_ST_MAX_LEN 0x10 /* Max frame len exceeded */ +#define FRM_ST_PHY_ERR 0x08 /* Physical layer error */ +#define FRM_ST_BAD_CRC 0x04 +#define FRM_ST_OVR1 0x02 /* Rx FIFO overrun */ +#define FRM_ST_OVR2 0x01 /* Frame status FIFO overrun */ + +#define RFLFL 0x06 +#define RFLFH 0x07 + +/* Bank 6 */ +#define IR_CFG2 0x00 +#define IR_CFG2_DIS_CRC 0x02 + +/* Bank 7 */ +#define IRM_CR 0x07 /* Infrared module control register */ +#define IRM_CR_IRX_MSL 0x40 +#define IRM_CR_AF_MNT 0x80 /* Automatic format */ + +/* NSC chip information */ +struct nsc_chip { + char *name; /* Name of chipset */ + int cfg[3]; /* Config registers */ + u_int8_t cid_index; /* Chip identification index reg */ + u_int8_t cid_value; /* Chip identification expected value */ + u_int8_t cid_mask; /* Chip identification revision mask */ + + /* Functions for probing and initializing the specific chip */ + int (*probe)(struct nsc_chip *chip, chipio_t *info); + int (*init)(struct nsc_chip *chip, chipio_t *info); +}; +typedef struct nsc_chip nsc_chip_t; + +/* For storing entries in the status FIFO */ +struct st_fifo_entry { + int status; + int len; +}; + +#define MAX_TX_WINDOW 7 +#define MAX_RX_WINDOW 7 + +struct st_fifo { + struct st_fifo_entry entries[MAX_RX_WINDOW]; + int pending_bytes; + int head; + int tail; + int len; +}; + +struct frame_cb { + void *start; /* Start of frame in DMA mem */ + int len; /* Lenght of frame in DMA mem */ +}; + +struct tx_fifo { + struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ + int ptr; /* Currently being sent */ + int len; /* Lenght of queue */ + int free; /* Next free slot */ + void *tail; /* Next free start in DMA mem */ +}; + +/* Private data for each instance */ +struct nsc_ircc_cb { + struct st_fifo st_fifo; /* Info about received frames */ + struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + __u8 ier; /* Interrupt enable register */ + + struct timeval stamp; + struct timeval now; + + spinlock_t lock; /* For serializing operations */ + + __u32 flags; /* Interface flags */ + __u32 new_speed; + int index; /* Instance index */ + + struct pm_dev *dev; +}; + +static inline void switch_bank(int iobase, int bank) +{ + outb(bank, iobase+BSR); +} + +#endif /* NSC_IRCC_H */ diff --git a/release/src/linux/linux/include/net/irda/parameters.h b/release/src/linux/linux/include/net/irda/parameters.h new file mode 100644 index 00000000..3938975c --- /dev/null +++ b/release/src/linux/linux/include/net/irda/parameters.h @@ -0,0 +1,104 @@ +/********************************************************************* + * + * Filename: parameters.h + * Version: 1.0 + * Description: A more general way to handle (pi,pl,pv) parameters + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Jun 7 08:47:28 1999 + * Modified at: Sun Jan 30 14:05:14 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Michel Dänzer <daenzer@debian.org>, 10/2001 + * - simplify irda_pv_t to avoid endianness issues + * + ********************************************************************/ + +#ifndef IRDA_PARAMS_H +#define IRDA_PARAMS_H + +/* + * The currently supported types. Beware not to change the sequence since + * it a good reason why the sized integers has a value equal to their size + */ +typedef enum { + PV_INTEGER, /* Integer of any (pl) length */ + PV_INT_8_BITS, /* Integer of 8 bits in length */ + PV_INT_16_BITS, /* Integer of 16 bits in length */ + PV_STRING, /* \0 terminated string */ + PV_INT_32_BITS, /* Integer of 32 bits in length */ + PV_OCT_SEQ, /* Octet sequence */ + PV_NO_VALUE /* Does not contain any value (pl=0) */ +} PV_TYPE; + +/* Bit 7 of type field */ +#define PV_BIG_ENDIAN 0x80 +#define PV_LITTLE_ENDIAN 0x00 +#define PV_MASK 0x7f /* To mask away endian bit */ + +#define PV_PUT 0 +#define PV_GET 1 + +typedef union { + char *c; + __u32 i; + __u32 *ip; +} irda_pv_t; + +typedef struct { + __u8 pi; + __u8 pl; + irda_pv_t pv; +} irda_param_t; + +typedef int (*PI_HANDLER)(void *self, irda_param_t *param, int get); +typedef int (*PV_HANDLER)(void *self, __u8 *buf, int len, __u8 pi, + PV_TYPE type, PI_HANDLER func); + +typedef struct { + PI_HANDLER func; /* Handler for this parameter identifier */ + PV_TYPE type; /* Data type for this parameter */ +} pi_minor_info_t; + +typedef struct { + pi_minor_info_t *pi_minor_call_table; + int len; +} pi_major_info_t; + +typedef struct { + pi_major_info_t *tables; + int len; + __u8 pi_mask; + int pi_major_offset; +} pi_param_info_t; + +int irda_param_pack(__u8 *buf, char *fmt, ...); +int irda_param_unpack(__u8 *buf, char *fmt, ...); + +int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, + pi_param_info_t *info); +int irda_param_extract(void *self, __u8 *buf, int len, pi_param_info_t *info); +int irda_param_extract_all(void *self, __u8 *buf, int len, + pi_param_info_t *info); + +#define irda_param_insert_byte(buf,pi,pv) irda_param_pack(buf,"bbb",pi,1,pv) + +#endif /* IRDA_PARAMS_H */ + diff --git a/release/src/linux/linux/include/net/irda/qos.h b/release/src/linux/linux/include/net/irda/qos.h new file mode 100644 index 00000000..fd6e2de0 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/qos.h @@ -0,0 +1,112 @@ +/********************************************************************* + * + * Filename: qos.h + * Version: 1.0 + * Description: Quality of Service definitions + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Fri Sep 19 23:21:09 1997 + * Modified at: Thu Dec 2 13:51:54 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRDA_QOS_H +#define IRDA_QOS_H + +#include <linux/config.h> +#include <linux/skbuff.h> + +#include <net/irda/parameters.h> + +#define PI_BAUD_RATE 0x01 +#define PI_MAX_TURN_TIME 0x82 +#define PI_DATA_SIZE 0x83 +#define PI_WINDOW_SIZE 0x84 +#define PI_ADD_BOFS 0x85 +#define PI_MIN_TURN_TIME 0x86 +#define PI_LINK_DISC 0x08 + +#define IR_115200_MAX 0x3f + +/* Baud rates (first byte) */ +#define IR_2400 0x01 +#define IR_9600 0x02 +#define IR_19200 0x04 +#define IR_38400 0x08 +#define IR_57600 0x10 +#define IR_115200 0x20 +#define IR_576000 0x40 +#define IR_1152000 0x80 + +/* Baud rates (second byte) */ +#define IR_4000000 0x01 +#define IR_16000000 0x02 + +/* Quality of Service information */ +typedef struct { + __u32 value; + __u16 bits; /* LSB is first byte, MSB is second byte */ +} qos_value_t; + +struct qos_info { + magic_t magic; + + qos_value_t baud_rate; /* IR_11520O | ... */ + qos_value_t max_turn_time; + qos_value_t data_size; + qos_value_t window_size; + qos_value_t additional_bofs; + qos_value_t min_turn_time; + qos_value_t link_disc_time; + + qos_value_t power; +}; + +extern int sysctl_max_baud_rate; +extern int sysctl_max_inactive_time; + +extern __u32 baud_rates[]; +extern __u32 data_sizes[]; +extern __u32 min_turn_times[]; +extern __u32 add_bofs[]; +extern __u32 compressions[]; + +void irda_init_max_qos_capabilies(struct qos_info *qos); +void irda_qos_compute_intersection(struct qos_info *, struct qos_info *); + +__u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time); +__u32 irlap_requested_line_capacity(struct qos_info *qos); + +int msb_index(__u16 byte); +void irda_qos_bits_to_value(struct qos_info *qos); + +/* So simple, how could we not inline those two ? + * Note : one byte is 10 bits if you include start and stop bits + * Jean II */ +#define irlap_min_turn_time_in_bytes(speed, min_turn_time) ( \ + speed * min_turn_time / 10000000 \ +) +#define irlap_xbofs_in_usec(speed, xbofs) ( \ + xbofs * 10000000 / speed \ +) + +#endif + diff --git a/release/src/linux/linux/include/net/irda/smc-ircc.h b/release/src/linux/linux/include/net/irda/smc-ircc.h new file mode 100644 index 00000000..f4af3908 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/smc-ircc.h @@ -0,0 +1,179 @@ +/********************************************************************* + * + * Filename: smc-ircc.h + * Version: 0.3 + * Description: Definitions for the SMC IrCC chipset + * Status: Experimental. + * Author: Thomas Davis (tadavis@jps.net) + * + * Copyright (c) 1999-2000, Dag Brattli <dagb@cs.uit.no> + * Copyright (c) 1998-1999, Thomas Davis (tadavis@jps.net> + * All Rights Reserved + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef SMC_IRCC_H +#define SMC_IRCC_H + +#include <linux/spinlock.h> +#include <linux/pm.h> + +#include <net/irda/irport.h> + +/* DMA modes needed */ +#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ +#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ + +/* Master Control Register */ +#define IRCC_MASTER 0x07 +#define IRCC_MASTER_POWERDOWN 0x80 +#define IRCC_MASTER_RESET 0x40 +#define IRCC_MASTER_INT_EN 0x20 +#define IRCC_MASTER_ERROR_RESET 0x10 + +/* Register block 0 */ + +/* Interrupt Identification */ +#define IRCC_IIR 0x01 +#define IRCC_IIR_ACTIVE_FRAME 0x80 +#define IRCC_IIR_EOM 0x40 +#define IRCC_IIR_RAW_MODE 0x20 +#define IRCC_IIR_FIFO 0x10 + +/* Interrupt Enable */ +#define IRCC_IER 0x02 +#define IRCC_IER_ACTIVE_FRAME 0x80 +#define IRCC_IER_EOM 0x40 +#define IRCC_IER_RAW_MODE 0x20 +#define IRCC_IER_FIFO 0x10 + +/* Line Status Register */ +#define IRCC_LSR 0x03 +#define IRCC_LSR_UNDERRUN 0x80 +#define IRCC_LSR_OVERRUN 0x40 +#define IRCC_LSR_FRAME_ERROR 0x20 +#define IRCC_LSR_SIZE_ERROR 0x10 +#define IRCC_LSR_CRC_ERROR 0x80 +#define IRCC_LSR_FRAME_ABORT 0x40 + +/* Line Control Register A */ +#define IRCC_LCR_A 0x04 +#define IRCC_LCR_A_FIFO_RESET 0x80 +#define IRCC_LCR_A_FAST 0x40 +#define IRCC_LCR_A_GP_DATA 0x20 +#define IRCC_LCR_A_RAW_TX 0x10 +#define IRCC_LCR_A_RAW_RX 0x08 +#define IRCC_LCR_A_ABORT 0x04 +#define IRCC_LCR_A_DATA_DONE 0x02 + +/* Line Control Register B */ +#define IRCC_LCR_B 0x05 +#define IRCC_LCR_B_SCE_DISABLED 0x00 +#define IRCC_LCR_B_SCE_TRANSMIT 0x40 +#define IRCC_LCR_B_SCE_RECEIVE 0x80 +#define IRCC_LCR_B_SCE_UNDEFINED 0xc0 +#define IRCC_LCR_B_SIP_ENABLE 0x20 +#define IRCC_LCR_B_BRICK_WALL 0x10 + +/* Bus Status Register */ +#define IRCC_BSR 0x06 +#define IRCC_BSR_NOT_EMPTY 0x80 +#define IRCC_BSR_FIFO_FULL 0x40 +#define IRCC_BSR_TIMEOUT 0x20 + +/* Register block 1 */ + +#define IRCC_FIFO_THRESHOLD 0x02 + +#define IRCC_SCE_CFGA 0x00 +#define IRCC_CFGA_AUX_IR 0x80 +#define IRCC_CFGA_HALF_DUPLEX 0x04 +#define IRCC_CFGA_TX_POLARITY 0x02 +#define IRCC_CFGA_RX_POLARITY 0x01 + +#define IRCC_CFGA_COM 0x00 +#define IRCC_CFGA_IRDA_SIR_A 0x08 +#define IRCC_CFGA_ASK_SIR 0x10 +#define IRCC_CFGA_IRDA_SIR_B 0x18 +#define IRCC_CFGA_IRDA_HDLC 0x20 +#define IRCC_CFGA_IRDA_4PPM 0x28 +#define IRCC_CFGA_CONSUMER 0x30 +#define IRCC_CFGA_RAW_IR 0x38 +#define IRCC_CFGA_OTHER 0x40 + +#define IRCC_IR_HDLC 0x04 +#define IRCC_IR_4PPM 0x01 +#define IRCC_IR_CONSUMER 0x02 + +#define IRCC_SCE_CFGB 0x01 +#define IRCC_CFGB_LOOPBACK 0x20 +#define IRCC_CFGB_LPBCK_TX_CRC 0x10 +#define IRCC_CFGB_NOWAIT 0x08 +#define IRCC_CFGB_STRING_MOVE 0x04 +#define IRCC_CFGB_DMA_BURST 0x02 +#define IRCC_CFGB_DMA_ENABLE 0x01 + +#define IRCC_CFGB_MUX_COM 0x00 +#define IRCC_CFGB_MUX_IR 0x40 +#define IRCC_CFGB_MUX_AUX 0x80 +#define IRCC_CFGB_MUX_INACTIVE 0xc0 + +/* Register block 3 - Identification Registers! */ +#define IRCC_ID_HIGH 0x00 /* 0x10 */ +#define IRCC_ID_LOW 0x01 /* 0xB8 */ +#define IRCC_CHIP_ID 0x02 /* 0xF1 */ +#define IRCC_VERSION 0x03 /* 0x01 */ +#define IRCC_INTERFACE 0x04 /* low 4 = DMA, high 4 = IRQ */ + +/* Register block 4 - IrDA */ +#define IRCC_CONTROL 0x00 +#define IRCC_BOF_COUNT_LO 0x01 /* Low byte */ +#define IRCC_BOF_COUNT_HI 0x00 /* High nibble (bit 0-3) */ +#define IRCC_BRICKWALL_CNT_LO 0x02 /* Low byte */ +#define IRCC_BRICKWALL_CNT_HI 0x03 /* High nibble (bit 4-7) */ +#define IRCC_TX_SIZE_LO 0x04 /* Low byte */ +#define IRCC_TX_SIZE_HI 0x03 /* High nibble (bit 0-3) */ +#define IRCC_RX_SIZE_HI 0x05 /* High nibble (bit 0-3) */ +#define IRCC_RX_SIZE_LO 0x06 /* Low byte */ + +#define IRCC_1152 0x80 +#define IRCC_CRC 0x40 + +/* Private data for each instance */ +struct ircc_cb { + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct irlap_cb *irlap; /* The link layer we are binded to */ + + chipio_t *io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + struct irport_cb *irport; + + spinlock_t lock; /* For serializing operations */ + + __u32 new_speed; + __u32 flags; /* Interface flags */ + + int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */ + int tx_len; /* Number of frames in tx_buff */ + + struct pm_dev *pmdev; +}; + +#endif /* SMC_IRCC_H */ diff --git a/release/src/linux/linux/include/net/irda/timer.h b/release/src/linux/linux/include/net/irda/timer.h new file mode 100644 index 00000000..ba648b9b --- /dev/null +++ b/release/src/linux/linux/include/net/irda/timer.h @@ -0,0 +1,92 @@ +/********************************************************************* + * + * Filename: timer.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Sat Aug 16 00:59:29 1997 + * Modified at: Thu Oct 7 12:25:24 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com> + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef TIMER_H +#define TIMER_H + +#include <linux/netdevice.h> + +#include <asm/param.h> /* for HZ */ + +#include <net/irda/irda.h> +#include <net/irda/irmod.h> +#include <net/irda/irlap.h> +#include <net/irda/irlmp.h> +#include <net/irda/irda_device.h> + +/* + * Timeout definitions, some defined in IrLAP p. 92 + */ +#define POLL_TIMEOUT (450*HZ/1000) /* Must never exceed 500 ms */ +#define FINAL_TIMEOUT (500*HZ/1000) /* Must never exceed 500 ms */ + +/* + * Normally twice of p-timer. Note 3, IrLAP p. 60 suggests at least twice + * duration of the P-timer. + */ +#define WD_TIMEOUT (POLL_TIMEOUT*2) + +#define MEDIABUSY_TIMEOUT (500*HZ/1000) /* 500 msec */ +#define SMALLBUSY_TIMEOUT (100*HZ/1000) /* 100 msec - IrLAP 6.13.4 */ + +/* + * Slot timer must never exceed 85 ms, and must always be at least 25 ms, + * suggested to 75-85 msec by IrDA lite. This doesn't work with a lot of + * devices, and other stackes uses a lot more, so it's best we do it as well + */ +#define SLOT_TIMEOUT (90*HZ/1000) + +/* + * We set the query timeout to 100 ms and then expect the value to be + * multiplied with the number of slots to product the actual timeout value + */ +#define QUERY_TIMEOUT (HZ/10) + +#define WATCHDOG_TIMEOUT (20*HZ) /* 20 sec */ + +typedef void (*TIMER_CALLBACK)(void *); + +void irda_start_timer(struct timer_list *ptimer, int timeout, void* data, + TIMER_CALLBACK callback); + +inline void irlap_start_slot_timer(struct irlap_cb *self, int timeout); +inline void irlap_start_query_timer(struct irlap_cb *self, int timeout); +inline void irlap_start_final_timer(struct irlap_cb *self, int timeout); +inline void irlap_start_wd_timer(struct irlap_cb *self, int timeout); +inline void irlap_start_backoff_timer(struct irlap_cb *self, int timeout); + +void irlap_start_mbusy_timer(struct irlap_cb *self, int timeout); +void irlap_stop_mbusy_timer(struct irlap_cb *); + +struct lsap_cb; +struct lap_cb; +inline void irlmp_start_watchdog_timer(struct lsap_cb *, int timeout); +inline void irlmp_start_discovery_timer(struct irlmp_cb *, int timeout); +inline void irlmp_start_idle_timer(struct lap_cb *, int timeout); +inline void irlmp_stop_idle_timer(struct lap_cb *self); + +#endif + diff --git a/release/src/linux/linux/include/net/irda/toshoboe.h b/release/src/linux/linux/include/net/irda/toshoboe.h new file mode 100644 index 00000000..9bf4fb9c --- /dev/null +++ b/release/src/linux/linux/include/net/irda/toshoboe.h @@ -0,0 +1,167 @@ +/********************************************************************* + * + * Filename: toshoboe.h + * Version: 0.1 + * Description: Driver for the Toshiba OBOE (or type-O) + * FIR Chipset. + * Status: Experimental. + * Author: James McKenzie <james@fishsoup.dhs.org> + * Created at: Sat May 8 12:35:27 1999 + * + * Copyright (c) 1999-2000 James McKenzie, All Rights Reserved. + * + * 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. + * + * Neither James McKenzie nor Cambridge University admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + * Applicable Models : Libretto 100CT. and many more + * + ********************************************************************/ + +#ifndef TOSHOBOE_H +#define TOSHOBOE_H + +/* Registers */ +/*Receive and transmit task registers (read only) */ +#define OBOE_RCVT (0x00+(self->base)) +#define OBOE_XMTT (0x01+(self->base)) +#define OBOE_XMTT_OFFSET 0x40 + +/*Page pointers to the TaskFile structure */ +#define OBOE_TFP2 (0x02+(self->base)) +#define OBOE_TFP0 (0x04+(self->base)) +#define OBOE_TFP1 (0x05+(self->base)) + +/*Dunno */ +#define OBOE_REG_3 (0x03+(self->base)) + +/*Number of tasks to use in Xmit and Recv queues */ +#define OBOE_NTR (0x07+(self->base)) +#define OBOE_NTR_XMIT4 0x00 +#define OBOE_NTR_XMIT8 0x10 +#define OBOE_NTR_XMIT16 0x30 +#define OBOE_NTR_XMIT32 0x70 +#define OBOE_NTR_XMIT64 0xf0 +#define OBOE_NTR_RECV4 0x00 +#define OBOE_NTR_RECV8 0x01 +#define OBOE_NTR_RECV6 0x03 +#define OBOE_NTR_RECV32 0x07 +#define OBOE_NTR_RECV64 0x0f + +/* Dunno */ +#define OBOE_REG_9 (0x09+(self->base)) + +/* Interrupt Status Register */ +#define OBOE_ISR (0x0c+(self->base)) +#define OBOE_ISR_TXDONE 0x80 +#define OBOE_ISR_RXDONE 0x40 +#define OBOE_ISR_20 0x20 +#define OBOE_ISR_10 0x10 +#define OBOE_ISR_8 0x08 /*This is collision or parity or something */ +#define OBOE_ISR_4 0x08 +#define OBOE_ISR_2 0x08 +#define OBOE_ISR_1 0x08 + +/*Dunno */ +#define OBOE_REG_D (0x0d+(self->base)) + +/*Register Lock Register */ +#define OBOE_LOCK ((self->base)+0x0e) + + + +/*Speed control registers */ +#define OBOE_PMDL (0x10+(self->base)) +#define OBOE_PMDL_SIR 0x18 +#define OBOE_PMDL_MIR 0xa0 +#define OBOE_PMDL_FIR 0x40 + +#define OBOE_SMDL (0x18+(self->base)) +#define OBOE_SMDL_SIR 0x20 +#define OBOE_SMDL_MIR 0x01 +#define OBOE_SMDL_FIR 0x0f + +#define OBOE_UDIV (0x19+(self->base)) + +/*Dunno */ +#define OBOE_REG_11 (0x11+(self->base)) + +/*Chip Reset Register */ +#define OBOE_RST (0x15+(self->base)) +#define OBOE_RST_WRAP 0x8 + +/*Dunno */ +#define OBOE_REG_1A (0x1a+(self->base)) +#define OBOE_REG_1B (0x1b+(self->base)) + +/* The PCI ID of the OBOE chip */ +#ifndef PCI_DEVICE_ID_FIR701 +#define PCI_DEVICE_ID_FIR701 0x0701 +#endif + +typedef unsigned int dword; +typedef unsigned short int word; +typedef unsigned char byte; +typedef dword Paddr; + +struct OboeTask + { + __u16 len; + __u8 unused; + __u8 control; + __u32 buffer; + }; + +#define OBOE_NTASKS 64 + +struct OboeTaskFile + { + struct OboeTask recv[OBOE_NTASKS]; + struct OboeTask xmit[OBOE_NTASKS]; + }; + +#define OBOE_TASK_BUF_LEN (sizeof(struct OboeTaskFile) << 1) + +/*These set the number of slots in use */ +#define TX_SLOTS 4 +#define RX_SLOTS 4 + +/* You need also to change this, toshiba uses 4,8 and 4,4 */ +/* It makes no difference if you are only going to use ONETASK mode */ +/* remember each buffer use XX_BUF_SZ more _PHYSICAL_ memory */ +#define OBOE_NTR_VAL (OBOE_NTR_XMIT4 | OBOE_NTR_RECV4) + +struct toshoboe_cb + { + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + + __u32 flags; /* Interface flags */ + __u32 new_speed; + + struct pci_dev *pdev; /*PCI device */ + int base; /*IO base */ + int txpending; /*how many tx's are pending */ + int txs, rxs; /*Which slots are we at */ + void *taskfilebuf; /*The unaligned taskfile buffer */ + struct OboeTaskFile *taskfile; /*The taskfile */ + void *xmit_bufs[TX_SLOTS]; /*The buffers */ + void *recv_bufs[RX_SLOTS]; + int open; + int stopped; /*Stopped by some or other APM stuff*/ + }; + + +#endif + + diff --git a/release/src/linux/linux/include/net/irda/vlsi_ir.h b/release/src/linux/linux/include/net/irda/vlsi_ir.h new file mode 100644 index 00000000..0c9ce512 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/vlsi_ir.h @@ -0,0 +1,575 @@ + +/********************************************************************* + * + * vlsi_ir.h: VLSI82C147 PCI IrDA controller driver for Linux + * + * Version: 0.3, Sep 30, 2001 + * + * Copyright (c) 2001 Martin Diehl + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRDA_VLSI_FIR_H +#define IRDA_VLSI_FIR_H + +/* ================================================================ */ + +/* non-standard PCI registers */ + +enum vlsi_pci_regs { + VLSI_PCI_CLKCTL = 0x40, /* chip clock input control */ + VLSI_PCI_MSTRPAGE = 0x41, /* addr [31:24] for all busmaster cycles */ + VLSI_PCI_IRMISC = 0x42 /* mainly legacy UART related */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PCI_CLKCTL: Clock Control Register (u8, rw) */ + +/* Three possible clock sources: either on-chip 48MHz PLL or + * external clock applied to EXTCLK pin. External clock may + * be either 48MHz or 40MHz, which is indicated by XCKSEL. + * CLKSTP controls whether the selected clock source gets + * connected to the IrDA block. + * + * On my HP OB-800 the BIOS sets external 40MHz clock as source + * when IrDA enabled and I've never detected any PLL lock success. + * Apparently the 14.3...MHz OSC input required for the PLL to work + * is not connected and the 40MHz EXTCLK is provided externally. + * At least this is what makes the driver working for me. + */ + +enum vlsi_pci_clkctl { + + /* PLL control */ + + CLKCTL_NO_PD = 0x04, /* PD# (inverted power down) signal, + * i.e. PLL is powered, if NO_PD set */ + CLKCTL_LOCK = 0x40, /* (ro) set, if PLL is locked */ + + /* clock source selection */ + + CLKCTL_EXTCLK = 0x20, /* set to select external clock input */ + CLKCTL_XCKSEL = 0x10, /* set to indicate 40MHz EXTCLK, not 48MHz */ + + /* IrDA block control */ + + CLKCTL_CLKSTP = 0x80, /* set to disconnect from selected clock source */ + CLKCTL_WAKE = 0x08 /* set to enable wakeup feature: whenever IR activity + * is detected, NO_PD gets set and CLKSTP cleared */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PCI_MSTRPAGE: Master Page Register (u8, rw) and busmastering stuff */ + +#define DMA_MASK_USED_BY_HW 0xffffffff +#define DMA_MASK_MSTRPAGE 0x00ffffff +#define MSTRPAGE_VALUE (DMA_MASK_MSTRPAGE >> 24) + + + /* PCI busmastering is somewhat special for this guy - in short: + * + * We select to operate using MSTRPAGE=0 fixed, use ISA DMA + * address restrictions to make the PCI BM api aware of this, + * but ensure the hardware is dealing with real 32bit access. + * + * In detail: + * The chip executes normal 32bit busmaster cycles, i.e. + * drives all 32 address lines. These addresses however are + * composed of [0:23] taken from various busaddr-pointers + * and [24:31] taken from the MSTRPAGE register in the VLSI82C147 + * config space. Therefore _all_ busmastering must be + * targeted to/from one single 16MB (busaddr-) superpage! + * The point is to make sure all the allocations for memory + * locations with busmaster access (ring descriptors, buffers) + * are indeed bus-mappable to the same 16MB range (for x86 this + * means they must reside in the same 16MB physical memory address + * range). The only constraint we have which supports "several objects + * mappable to common 16MB range" paradigma, is the old ISA DMA + * restriction to the first 16MB of physical address range. + * Hence the approach here is to enable PCI busmaster support using + * the correct 32bit dma-mask used by the chip. Afterwards the device's + * dma-mask gets restricted to 24bit, which must be honoured somehow by + * all allocations for memory areas to be exposed to the chip ... + * + * Note: + * Don't be surprised to get "Setting latency timer..." messages every + * time when PCI busmastering is enabled for the chip. + * The chip has its PCI latency timer RO fixed at 0 - which is not a + * problem here, because it is never requesting _burst_ transactions. + */ + +/* ------------------------------------------ */ + +/* VLSI_PCIIRMISC: IR Miscellaneous Register (u8, rw) */ + +/* legacy UART emulation - not used by this driver - would require: + * (see below for some register-value definitions) + * + * - IRMISC_UARTEN must be set to enable UART address decoding + * - IRMISC_UARTSEL configured + * - IRCFG_MASTER must be cleared + * - IRCFG_SIR must be set + * - IRENABLE_IREN must be asserted 0->1 (and hence IRENABLE_SIR_ON) + */ + +enum vlsi_pci_irmisc { + + /* IR transceiver control */ + + IRMISC_IRRAIL = 0x40, /* (ro?) IR rail power indication (and control?) + * 0=3.3V / 1=5V. Probably set during power-on? + * unclear - not touched by driver */ + IRMISC_IRPD = 0x08, /* transceiver power down, if set */ + + /* legacy UART control */ + + IRMISC_UARTTST = 0x80, /* UART test mode - "always write 0" */ + IRMISC_UARTEN = 0x04, /* enable UART address decoding */ + + /* bits [1:0] IRMISC_UARTSEL to select legacy UART address */ + + IRMISC_UARTSEL_3f8 = 0x00, + IRMISC_UARTSEL_2f8 = 0x01, + IRMISC_UARTSEL_3e8 = 0x02, + IRMISC_UARTSEL_2e8 = 0x03 +}; + + +/* ================================================================ */ + +/* registers mapped to 32 byte PCI IO space */ + +/* note: better access all registers at the indicated u8/u16 size + * although some of them contain only 1 byte of information. + * some of them (particaluarly PROMPT and IRCFG) ignore + * access when using the wrong addressing mode! + */ + +enum vlsi_pio_regs { + VLSI_PIO_IRINTR = 0x00, /* interrupt enable/request (u8, rw) */ + VLSI_PIO_RINGPTR = 0x02, /* rx/tx ring pointer (u16, ro) */ + VLSI_PIO_RINGBASE = 0x04, /* [23:10] of ring address (u16, rw) */ + VLSI_PIO_RINGSIZE = 0x06, /* rx/tx ring size (u16, rw) */ + VLSI_PIO_PROMPT = 0x08, /* triggers ring processing (u16, wo) */ + /* 0x0a-0x0f: reserved / duplicated UART regs */ + VLSI_PIO_IRCFG = 0x10, /* configuration select (u16, rw) */ + VLSI_PIO_SIRFLAG = 0x12, /* BOF/EOF for filtered SIR (u16, ro) */ + VLSI_PIO_IRENABLE = 0x14, /* enable and status register (u16, rw/ro) */ + VLSI_PIO_PHYCTL = 0x16, /* physical layer current status (u16, ro) */ + VLSI_PIO_NPHYCTL = 0x18, /* next physical layer select (u16, rw) */ + VLSI_PIO_MAXPKT = 0x1a, /* [11:0] max len for packet receive (u16, rw) */ + VLSI_PIO_RCVBCNT = 0x1c /* current receive-FIFO byte count (u16, ro) */ + /* 0x1e-0x1f: reserved / duplicated UART regs */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PIO_IRINTR: Interrupt Register (u8, rw) */ + +/* enable-bits: + * 1 = enable / 0 = disable + * interrupt condition bits: + * set according to corresponding interrupt source + * (regardless of the state of the enable bits) + * enable bit status indicates whether interrupt gets raised + * write-to-clear + * note: RPKTINT and TPKTINT behave different in legacy UART mode (which we don't use :-) + */ + +enum vlsi_pio_irintr { + IRINTR_ACTEN = 0x80, /* activity interrupt enable */ + IRINTR_ACTIVITY = 0x40, /* activity monitor (traffic detected) */ + IRINTR_RPKTEN = 0x20, /* receive packet interrupt enable*/ + IRINTR_RPKTINT = 0x10, /* rx-packet transfered from fifo to memory finished */ + IRINTR_TPKTEN = 0x08, /* transmit packet interrupt enable */ + IRINTR_TPKTINT = 0x04, /* last bit of tx-packet+crc shifted to ir-pulser */ + IRINTR_OE_EN = 0x02, /* UART rx fifo overrun error interrupt enable */ + IRINTR_OE_INT = 0x01 /* UART rx fifo overrun error (read LSR to clear) */ +}; + +/* we use this mask to check whether the (shared PCI) interrupt is ours */ + +#define IRINTR_INT_MASK (IRINTR_ACTIVITY|IRINTR_RPKTINT|IRINTR_TPKTINT) + +/* ------------------------------------------ */ + +/* VLSI_PIO_RINGPTR: Ring Pointer Read-Back Register (u16, ro) */ + +/* _both_ ring pointers are indices relative to the _entire_ rx,tx-ring! + * i.e. the referenced descriptor is located + * at RINGBASE + PTR * sizeof(descr) for rx and tx + * therefore, the tx-pointer has offset MAX_RING_DESCR + */ + +#define MAX_RING_DESCR 64 /* tx, rx rings may contain up to 64 descr each */ + +#define RINGPTR_RX_MASK (MAX_RING_DESCR-1) +#define RINGPTR_TX_MASK ((MAX_RING_DESCR-1)<<8) + +#define RINGPTR_GET_RX(p) ((p)&RINGPTR_RX_MASK) +#define RINGPTR_GET_TX(p) (((p)&RINGPTR_TX_MASK)>>8) + +/* ------------------------------------------ */ + +/* VLSI_PIO_RINGBASE: Ring Pointer Base Address Register (u16, ro) */ + +/* Contains [23:10] part of the ring base (bus-) address + * which must be 1k-alinged. [31:24] is taken from + * VLSI_PCI_MSTRPAGE above. + * The controller initiates non-burst PCI BM cycles to + * fetch and update the descriptors in the ring. + * Once fetched, the descriptor remains cached onchip + * until it gets closed and updated due to the ring + * processing state machine. + * The entire ring area is split in rx and tx areas with each + * area consisting of 64 descriptors of 8 bytes each. + * The rx(tx) ring is located at ringbase+0 (ringbase+64*8). + */ + +#define BUS_TO_RINGBASE(p) (((p)>>10)&0x3fff) + +/* ------------------------------------------ */ + +/* VLSI_PIO_RINGSIZE: Ring Size Register (u16, rw) */ + +/* bit mask to indicate the ring size to be used for rx and tx. + * possible values encoded bits + * 4 0000 + * 8 0001 + * 16 0011 + * 32 0111 + * 64 1111 + * located at [15:12] for tx and [11:8] for rx ([7:0] unused) + * + * note: probably a good idea to have IRCFG_MSTR cleared when writing + * this so the state machines are stopped and the RINGPTR is reset! + */ + +#define SIZE_TO_BITS(num) ((((num)-1)>>2)&0x0f) +#define TX_RX_TO_RINGSIZE(tx,rx) ((SIZE_TO_BITS(tx)<<12)|(SIZE_TO_BITS(rx)<<8)) +#define RINGSIZE_TO_RXSIZE(rs) ((((rs)&0x0f00)>>6)+4) +#define RINGSIZE_TO_TXSIZE(rs) ((((rs)&0xf000)>>10)+4) + + +/* ------------------------------------------ */ + +/* VLSI_PIO_PROMPT: Ring Prompting Register (u16, write-to-start) */ + +/* writing any value kicks the ring processing state machines + * for both tx, rx rings as follows: + * - active rings (currently owning an active descriptor) + * ignore the prompt and continue + * - idle rings fetch the next descr from the ring and start + * their processing + */ + +/* ------------------------------------------ */ + +/* VLSI_PIO_IRCFG: IR Config Register (u16, rw) */ + +/* notes: + * - not more than one SIR/MIR/FIR bit must be set at any time + * - SIR, MIR, FIR and CRC16 select the configuration which will + * be applied on next 0->1 transition of IRENABLE_IREN (see below). + * - besides allowing the PCI interface to execute busmaster cycles + * and therefore the ring SM to operate, the MSTR bit has side-effects: + * when MSTR is cleared, the RINGPTR's get reset and the legacy UART mode + * (in contrast to busmaster access mode) gets enabled. + * - clearing ENRX or setting ENTX while data is received may stall the + * receive fifo until ENRX reenabled _and_ another packet arrives + * - SIRFILT means the chip performs the required unwrapping of hardware + * headers (XBOF's, BOF/EOF) and un-escaping in the _receive_ direction. + * Only the resulting IrLAP payload is copied to the receive buffers - + * but with the 16bit FCS still encluded. Question remains, whether it + * was already checked or we should do it before passing the packet to IrLAP? + */ + +enum vlsi_pio_ircfg { + IRCFG_LOOP = 0x4000, /* enable loopback test mode */ + IRCFG_ENTX = 0x1000, /* transmit enable */ + IRCFG_ENRX = 0x0800, /* receive enable */ + IRCFG_MSTR = 0x0400, /* master enable */ + IRCFG_RXANY = 0x0200, /* receive any packet */ + IRCFG_CRC16 = 0x0080, /* 16bit (not 32bit) CRC select for MIR/FIR */ + IRCFG_FIR = 0x0040, /* FIR 4PPM encoding mode enable */ + IRCFG_MIR = 0x0020, /* MIR HDLC encoding mode enable */ + IRCFG_SIR = 0x0010, /* SIR encoding mode enable */ + IRCFG_SIRFILT = 0x0008, /* enable SIR decode filter (receiver unwrapping) */ + IRCFG_SIRTEST = 0x0004, /* allow SIR decode filter when not in SIR mode */ + IRCFG_TXPOL = 0x0002, /* invert tx polarity when set */ + IRCFG_RXPOL = 0x0001 /* invert rx polarity when set */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PIO_SIRFLAG: SIR Flag Register (u16, ro) */ + +/* register contains hardcoded BOF=0xc0 at [7:0] and EOF=0xc1 at [15:8] + * which is used for unwrapping received frames in SIR decode-filter mode + */ + +/* ------------------------------------------ */ + +/* VLSI_PIO_IRENABLE: IR Enable Register (u16, rw/ro) */ + +/* notes: + * - IREN acts as gate for latching the configured IR mode information + * from IRCFG and IRPHYCTL when IREN=reset and applying them when + * IREN gets set afterwards. + * - ENTXST reflects IRCFG_ENTX + * - ENRXST = IRCFG_ENRX && (!IRCFG_ENTX || IRCFG_LOOP) + */ + +enum vlsi_pio_irenable { + IRENABLE_IREN = 0x8000, /* enable IR phy and gate the mode config (rw) */ + IRENABLE_CFGER = 0x4000, /* mode configuration error (ro) */ + IRENABLE_FIR_ON = 0x2000, /* FIR on status (ro) */ + IRENABLE_MIR_ON = 0x1000, /* MIR on status (ro) */ + IRENABLE_SIR_ON = 0x0800, /* SIR on status (ro) */ + IRENABLE_ENTXST = 0x0400, /* transmit enable status (ro) */ + IRENABLE_ENRXST = 0x0200, /* Receive enable status (ro) */ + IRENABLE_CRC16_ON = 0x0100 /* 16bit (not 32bit) CRC enabled status (ro) */ +}; + +#define IRENABLE_MASK 0xff00 /* Read mask */ + + +/* ------------------------------------------ */ + +/* VLSI_PIO_PHYCTL: IR Physical Layer Current Control Register (u16, ro) */ + + +/* read-back of the currently applied physical layer status. + * applied from VLSI_PIO_NPHYCTL at rising edge of IRENABLE_IREN + * contents identical to VLSI_PIO_NPHYCTL (see below) + */ + + + +/* ------------------------------------------ */ + + +/* VLSI_PIO_NPHYCTL: IR Physical Layer Next Control Register (u16, rw) */ + +/* latched during IRENABLE_IREN=0 and applied at 0-1 transition + * + * consists of BAUD[15:10], PLSWID[9:5] and PREAMB[4:0] bits defined as follows: + * + * SIR-mode: BAUD = (115.2kHz / baudrate) - 1 + * PLSWID = (pulsetime * freq / (BAUD+1)) - 1 + * where pulsetime is the requested IrPHY pulse width + * and freq is 8(16)MHz for 40(48)MHz primary input clock + * PREAMB: dont care for SIR + * + * The nominal SIR pulse width is 3/16 bit time so we have PLSWID=12 + * fixed for all SIR speeds at 40MHz input clock (PLSWID=24 at 48MHz). + * IrPHY also allows shorter pulses down to the nominal pulse duration + * at 115.2kbaud (minus some tolerance) which is 1.41 usec. + * Using the expression PLSWID = 12/(BAUD+1)-1 (multiplied by to for 48MHz) + * we get the minimum acceptable PLSWID values according to the VLSI + * specification, which provides 1.5 usec pulse width for all speeds (except + * for 2.4kbaud getting 6usec). This is well inside IrPHY v1.3 specs and + * reduces the transceiver power which drains the battery. At 9.6kbaud for + * example this amounts to more than 90% battery power saving! + * + * MIR-mode: BAUD = 0 + * PLSWID = 9(10) for 40(48) MHz input clock + * to get nominal MIR pulse width + * PREAMB = 1 + * + * FIR-mode: BAUD = 0 + * PLSWID: dont care + * PREAMB = 15 + */ + +#define BWP_TO_PHYCTL(B,W,P) ((((B)&0x3f)<<10) | (((W)&0x1f)<<5) | (((P)&0x1f)<<0)) +#define BAUD_BITS(br) ((115200/(br))-1) + +static inline unsigned +calc_width_bits(unsigned baudrate, unsigned widthselect, unsigned clockselect) +{ + unsigned tmp; + + if (widthselect) /* nominal 3/16 puls width */ + return (clockselect) ? 12 : 24; + + tmp = ((clockselect) ? 12 : 24) / (BAUD_BITS(baudrate)+1); + + /* intermediate result of integer division needed here */ + + return (tmp>0) ? (tmp-1) : 0; +} + + +#define PHYCTL_SIR(br,ws,cs) BWP_TO_PHYCTL(BAUD_BITS(br),calc_width_bits((br),(ws),(cs)),0) +#define PHYCTL_MIR(cs) BWP_TO_PHYCTL(0,((cs)?9:10),1) +#define PHYCTL_FIR BWP_TO_PHYCTL(0,0,15) + +/* quite ugly, I know. But implementing these calculations here avoids + * having magic numbers in the code and allows some playing with pulsewidths + * without risk to violate the standards. + * FWIW, here is the table for reference: + * + * baudrate BAUD min-PLSWID nom-PLSWID PREAMB + * 2400 47 0(0) 12(24) 0 + * 9600 11 0(0) 12(24) 0 + * 19200 5 1(2) 12(24) 0 + * 38400 2 3(6) 12(24) 0 + * 57600 1 5(10) 12(24) 0 + * 115200 0 11(22) 12(24) 0 + * MIR 0 - 9(10) 1 + * FIR 0 - 0 15 + * + * note: x(y) means x-value for 40MHz / y-value for 48MHz primary input clock + */ + +/* ------------------------------------------ */ + + +/* VLSI_PIO_MAXPKT: Maximum Packet Length register (u16, rw) */ + +/* specifies the maximum legth (up to 4k - or (4k-1)? - bytes), which a + * received frame may have - i.e. the size of the corresponding + * receive buffers. For simplicity we use the same length for + * receive and submit buffers and increase transfer buffer size + * byond IrDA-MTU = 2048 so we have sufficient space left when + * packet size increases during wrapping due to XBOFs and CE's. + * Even for receiving unwrapped frames we need >MAX_PACKET_LEN + * space since the controller appends FCS/CRC (2 or 4 bytes) + * so we use 2*IrDA-MTU for both directions and cover even the + * worst case, where all data bytes have to be escaped when wrapping. + * well, this wastes some memory - anyway, later we will + * either map skb's directly or use pci_pool allocator... + */ + +#define IRDA_MTU 2048 /* seems to be undefined elsewhere */ + +#define XFER_BUF_SIZE (2*IRDA_MTU) + +#define MAX_PACKET_LENGTH (XFER_BUF_SIZE-1) /* register uses only [11:0] */ + + +/* ------------------------------------------ */ + + +/* VLSI_PIO_RCVBCNT: Receive Byte Count Register (u16, ro) */ + +/* recive packet counter gets incremented on every non-filtered + * byte which was put in the receive fifo and reset for each + * new packet. Used to decide whether we are just in the middle + * of receiving + */ + +#define RCVBCNT_MASK 0x0fff + +/* ================================================================ */ + + + +struct ring_descr { + volatile u16 rd_count; /* tx/rx count [11:0] */ + u16 reserved; + union { + u32 addr; /* [23:0] of the buffer's busaddress */ + struct { + u8 addr_res[3]; + volatile u8 status; /* descriptor status */ + } rd_s; + } rd_u; +}; + +#define rd_addr rd_u.addr +#define rd_status rd_u.rd_s.status + + +/* ring descriptor status bits */ + +#define RD_STAT_ACTIVE 0x80 /* descriptor owned by hw (both TX,RX) */ + +/* TX ring descriptor status */ + +#define TX_STAT_DISCRC 0x40 /* do not send CRC (for SIR) */ +#define TX_STAT_BADCRC 0x20 /* force a bad CRC */ +#define TX_STAT_PULSE 0x10 /* send indication pulse after this frame (MIR/FIR) */ +#define TX_STAT_FRCEUND 0x08 /* force underrun */ +#define TX_STAT_CLRENTX 0x04 /* clear ENTX after this frame */ +#define TX_STAT_UNDRN 0x01 /* TX fifo underrun (probably PCI problem) */ + +/* RX ring descriptor status */ + +#define RX_STAT_PHYERR 0x40 /* physical encoding error */ +#define RX_STAT_CRCERR 0x20 /* CRC error (MIR/FIR) */ +#define RX_STAT_LENGTH 0x10 /* frame exceeds buffer length */ +#define RX_STAT_OVER 0x08 /* RX fifo overrun (probably PCI problem) */ +#define RX_STAT_SIRBAD 0x04 /* EOF missing: BOF follows BOF (SIR, filtered) */ + + +#define RX_STAT_ERROR 0x7c /* any error in frame */ + + +/* ------------------------------------------ */ + +/* contains the objects we've put into the ring descriptors + * static buffers for now - probably skb's later + */ + +struct ring_entry { + struct sk_buff *skb; + void *data; +}; + + +struct vlsi_ring { + unsigned size; + unsigned mask; + unsigned head, tail; + struct ring_descr *hw; + struct ring_entry buf[MAX_RING_DESCR]; +}; + +/* ------------------------------------------ */ + +/* our private compound VLSI-PCI-IRDA device information */ + +typedef struct vlsi_irda_dev { + struct pci_dev *pdev; + struct net_device_stats stats; + + struct irlap_cb *irlap; + + struct qos_info qos; + + unsigned mode; + int baud, new_baud; + + dma_addr_t busaddr; + void *virtaddr; + struct vlsi_ring tx_ring, rx_ring; + + struct timeval last_rx; + + spinlock_t lock; + +} vlsi_irda_dev_t; + +/********************************************************/ + +#endif /* IRDA_VLSI_FIR_H */ + diff --git a/release/src/linux/linux/include/net/irda/w83977af.h b/release/src/linux/linux/include/net/irda/w83977af.h new file mode 100644 index 00000000..04476c2e --- /dev/null +++ b/release/src/linux/linux/include/net/irda/w83977af.h @@ -0,0 +1,53 @@ +#ifndef W83977AF_H +#define W83977AF_H + +#define W977_EFIO_BASE 0x370 +#define W977_EFIO2_BASE 0x3f0 +#define W977_DEVICE_IR 0x06 + + +/* + * Enter extended function mode + */ +static inline void w977_efm_enter(unsigned int efio) +{ + outb(0x87, efio); + outb(0x87, efio); +} + +/* + * Select a device to configure + */ + +static inline void w977_select_device(__u8 devnum, unsigned int efio) +{ + outb(0x07, efio); + outb(devnum, efio+1); +} + +/* + * Write a byte to a register + */ +static inline void w977_write_reg(__u8 reg, __u8 value, unsigned int efio) +{ + outb(reg, efio); + outb(value, efio+1); +} + +/* + * read a byte from a register + */ +static inline __u8 w977_read_reg(__u8 reg, unsigned int efio) +{ + outb(reg, efio); + return inb(efio+1); +} + +/* + * Exit extended function mode + */ +static inline void w977_efm_exit(unsigned int efio) +{ + outb(0xAA, efio); +} +#endif diff --git a/release/src/linux/linux/include/net/irda/w83977af_ir.h b/release/src/linux/linux/include/net/irda/w83977af_ir.h new file mode 100644 index 00000000..795f24fb --- /dev/null +++ b/release/src/linux/linux/include/net/irda/w83977af_ir.h @@ -0,0 +1,192 @@ +/********************************************************************* + * + * Filename: w83977af_ir.h + * Version: + * Description: + * Status: Experimental. + * Author: Paul VanderSpek + * Created at: Thu Nov 19 13:55:34 1998 + * Modified at: Tue Jan 11 13:08:19 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef W83977AF_IR_H +#define W83977AF_IR_H + +#include <asm/io.h> + +/* Flags for configuration register CRF0 */ +#define ENBNKSEL 0x01 +#define APEDCRC 0x02 +#define TXW4C 0x04 +#define RXW4C 0x08 + +/* Bank 0 */ +#define RBR 0x00 /* Receiver buffer register */ +#define TBR 0x00 /* Transmitter buffer register */ + +#define ICR 0x01 /* Interrupt configuration register */ +#define ICR_ERBRI 0x01 /* Receiver buffer register interrupt */ +#define ICR_ETBREI 0x02 /* Transeiver empty interrupt */ +#define ICR_EUSRI 0x04//* IR status interrupt */ +#define ICR_EHSRI 0x04 +#define ICR_ETXURI 0x04 /* Tx underrun */ +#define ICR_EDMAI 0x10 /* DMA interrupt */ +#define ICR_ETXTHI 0x20 /* Transmitter threshold interrupt */ +#define ICR_EFSFI 0x40 /* Frame status FIFO interrupt */ +#define ICR_ETMRI 0x80 /* Timer interrupt */ + +#define UFR 0x02 /* FIFO control register */ +#define UFR_EN_FIFO 0x01 /* Enable FIFO's */ +#define UFR_RXF_RST 0x02 /* Reset Rx FIFO */ +#define UFR_TXF_RST 0x04 /* Reset Tx FIFO */ +#define UFR_RXTL 0x80 /* Rx FIFO threshold (set to 16) */ +#define UFR_TXTL 0x20 /* Tx FIFO threshold (set to 17) */ + +#define ISR 0x02 /* Interrupt status register */ +#define ISR_RXTH_I 0x01 /* Receive threshold interrupt */ +#define ISR_TXEMP_I 0x02 /* Transmitter empty interrupt */ +#define ISR_FEND_I 0x04 +#define ISR_DMA_I 0x10 +#define ISR_TXTH_I 0x20 /* Transmitter threshold interrupt */ +#define ISR_FSF_I 0x40 +#define ISR_TMR_I 0x80 /* Timer interrupt */ + +#define UCR 0x03 /* Uart control register */ +#define UCR_DLS8 0x03 /* 8N1 */ + +#define SSR 0x03 /* Sets select register */ +#define SET0 UCR_DLS8 /* Make sure we keep 8N1 */ +#define SET1 (0x80|UCR_DLS8) /* Make sure we keep 8N1 */ +#define SET2 0xE0 +#define SET3 0xE4 +#define SET4 0xE8 +#define SET5 0xEC +#define SET6 0xF0 +#define SET7 0xF4 + +#define HCR 0x04 +#define HCR_MODE_MASK ~(0xD0) +#define HCR_SIR 0x60 +#define HCR_MIR_576 0x20 +#define HCR_MIR_1152 0x80 +#define HCR_FIR 0xA0 +#define HCR_EN_DMA 0x04 +#define HCR_EN_IRQ 0x08 +#define HCR_TX_WT 0x08 + +#define USR 0x05 /* IR status register */ +#define USR_RDR 0x01 /* Receive data ready */ +#define USR_TSRE 0x40 /* Transmitter empty? */ + +#define AUDR 0x07 +#define AUDR_SFEND 0x08 /* Set a frame end */ +#define AUDR_RXBSY 0x20 /* Rx busy */ +#define AUDR_UNDR 0x40 /* Transeiver underrun */ + +/* Set 2 */ +#define ABLL 0x00 /* Advanced baud rate divisor latch (low byte) */ +#define ABHL 0x01 /* Advanced baud rate divisor latch (high byte) */ + +#define ADCR1 0x02 +#define ADCR1_ADV_SL 0x01 +#define ADCR1_D_CHSW 0x08 /* the specs are wrong. its bit 3, not 4 */ +#define ADCR1_DMA_F 0x02 + +#define ADCR2 0x04 +#define ADCR2_TXFS32 0x01 +#define ADCR2_RXFS32 0x04 + +#define RXFDTH 0x07 + +/* Set 3 */ +#define AUID 0x00 + +/* Set 4 */ +#define TMRL 0x00 /* Timer value register (low byte) */ +#define TMRH 0x01 /* Timer value register (high byte) */ + +#define IR_MSL 0x02 /* Infrared mode select */ +#define IR_MSL_EN_TMR 0x01 /* Enable timer */ + +#define TFRLL 0x04 /* Transmitter frame length (low byte) */ +#define TFRLH 0x05 /* Transmitter frame length (high byte) */ +#define RFRLL 0x06 /* Receiver frame length (low byte) */ +#define RFRLH 0x07 /* Receiver frame length (high byte) */ + +/* Set 5 */ + +#define FS_FO 0x05 /* Frame status FIFO */ +#define FS_FO_FSFDR 0x80 /* Frame status FIFO data ready */ +#define FS_FO_LST_FR 0x40 /* Frame lost */ +#define FS_FO_MX_LEX 0x10 /* Max frame len exceeded */ +#define FS_FO_PHY_ERR 0x08 /* Physical layer error */ +#define FS_FO_CRC_ERR 0x04 +#define FS_FO_RX_OV 0x02 /* Receive overrun */ +#define FS_FO_FSF_OV 0x01 /* Frame status FIFO overrun */ +#define FS_FO_ERR_MSK 0x5f /* Error mask */ + +#define RFLFL 0x06 +#define RFLFH 0x07 + +/* Set 6 */ +#define IR_CFG2 0x00 +#define IR_CFG2_DIS_CRC 0x02 + +/* Set 7 */ +#define IRM_CR 0x07 /* Infrared module control register */ +#define IRM_CR_IRX_MSL 0x40 +#define IRM_CR_AF_MNT 0x80 /* Automatic format */ + +/* For storing entries in the status FIFO */ +struct st_fifo_entry { + int status; + int len; +}; + +struct st_fifo { + struct st_fifo_entry entries[10]; + int head; + int tail; + int len; +}; + +/* Private data for each instance */ +struct w83977af_ir { + struct st_fifo st_fifo; + + int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */ + int tx_len; /* Number of frames in tx_buff */ + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + __u32 flags; /* Interface flags */ + __u32 new_speed; +}; + +static inline void switch_bank( int iobase, int set) +{ + outb(set, iobase+SSR); +} + +#endif diff --git a/release/src/linux/linux/include/net/irda/wrapper.h b/release/src/linux/linux/include/net/irda/wrapper.h new file mode 100644 index 00000000..5dc0b0d1 --- /dev/null +++ b/release/src/linux/linux/include/net/irda/wrapper.h @@ -0,0 +1,60 @@ +/********************************************************************* + * + * Filename: wrapper.h + * Version: 1.2 + * Description: IrDA SIR async wrapper layer + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Mon Aug 4 20:40:53 1997 + * Modified at: Tue Jan 11 12:37:29 2000 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, + * All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef WRAPPER_H +#define WRAPPER_H + +#include <linux/types.h> +#include <linux/skbuff.h> +#include <linux/netdevice.h> + +#include <net/irda/irda_device.h> + +#define BOF 0xc0 /* Beginning of frame */ +#define XBOF 0xff +#define EOF 0xc1 /* End of frame */ +#define CE 0x7d /* Control escape */ + +#define STA BOF /* Start flag */ +#define STO EOF /* End flag */ + +#define IRDA_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* States for receving a frame in async mode */ +enum { + OUTSIDE_FRAME, + BEGIN_FRAME, + LINK_ESCAPE, + INSIDE_FRAME +}; + +/* Proto definitions */ +int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize); +void async_bump(struct net_device *dev, struct net_device_stats *stats, + __u8 *buf, int len); +void async_unwrap_char(struct net_device *dev, struct net_device_stats *stats, + iobuff_t *buf, __u8 byte); + +#endif diff --git a/release/src/linux/linux/include/net/iw_handler.h b/release/src/linux/linux/include/net/iw_handler.h new file mode 100644 index 00000000..192dea1f --- /dev/null +++ b/release/src/linux/linux/include/net/iw_handler.h @@ -0,0 +1,450 @@ +/* + * This file define the new driver API for Wireless Extensions + * + * Version : 3 17.1.02 + * + * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> + * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved. + */ + +#ifndef _IW_HANDLER_H +#define _IW_HANDLER_H + +/************************** DOCUMENTATION **************************/ +/* + * Initial driver API (1996 -> onward) : + * ----------------------------------- + * The initial API just sends the IOCTL request received from user space + * to the driver (via the driver ioctl handler). The driver has to + * handle all the rest... + * + * The initial API also defines a specific handler in struct net_device + * to handle wireless statistics. + * + * The initial APIs served us well and has proven a reasonably good design. + * However, there is a few shortcommings : + * o No events, everything is a request to the driver. + * o Large ioctl function in driver with gigantic switch statement + * (i.e. spaghetti code). + * o Driver has to mess up with copy_to/from_user, and in many cases + * does it unproperly. Common mistakes are : + * * buffer overflows (no checks or off by one checks) + * * call copy_to/from_user with irq disabled + * o The user space interface is tied to ioctl because of the use + * copy_to/from_user. + * + * New driver API (2002 -> onward) : + * ------------------------------- + * The new driver API is just a bunch of standard functions (handlers), + * each handling a specific Wireless Extension. The driver just export + * the list of handler it supports, and those will be called apropriately. + * + * I tried to keep the main advantage of the previous API (simplicity, + * efficiency and light weight), and also I provide a good dose of backward + * compatibility (most structures are the same, driver can use both API + * simultaneously, ...). + * Hopefully, I've also addressed the shortcomming of the initial API. + * + * The advantage of the new API are : + * o Handling of Extensions in driver broken in small contained functions + * o Tighter checks of ioctl before calling the driver + * o Flexible commit strategy (at least, the start of it) + * o Backward compatibility (can be mixed with old API) + * o Driver doesn't have to worry about memory and user-space issues + * The last point is important for the following reasons : + * o You are now able to call the new driver API from any API you + * want (including from within other parts of the kernel). + * o Common mistakes are avoided (buffer overflow, user space copy + * with irq disabled and so on). + * + * The Drawback of the new API are : + * o bloat (especially kernel) + * o need to migrate existing drivers to new API + * My initial testing shows that the new API adds around 3kB to the kernel + * and save between 0 and 5kB from a typical driver. + * Also, as all structures and data types are unchanged, the migration is + * quite straightforward (but tedious). + * + * --- + * + * The new driver API is defined below in this file. User space should + * not be aware of what's happening down there... + * + * A new kernel wrapper is in charge of validating the IOCTLs and calling + * the appropriate driver handler. This is implemented in : + * # net/core/wireless.c + * + * The driver export the list of handlers in : + * # include/linux/netdevice.h (one place) + * + * The new driver API is available for WIRELESS_EXT >= 13. + * Good luck with migration to the new API ;-) + */ + +/* ---------------------- THE IMPLEMENTATION ---------------------- */ +/* + * Some of the choice I've made are pretty controversials. Defining an + * API is very much weighting compromises. This goes into some of the + * details and the thinking behind the implementation. + * + * Implementation goals : + * -------------------- + * The implementation goals were as follow : + * o Obvious : you should not need a PhD to understand what's happening, + * the benefit is easier maintainance. + * o Flexible : it should accomodate a wide variety of driver + * implementations and be as flexible as the old API. + * o Lean : it should be efficient memory wise to minimise the impact + * on kernel footprint. + * o Transparent to user space : the large number of user space + * applications that use Wireless Extensions should not need + * any modifications. + * + * Array of functions versus Struct of functions + * --------------------------------------------- + * 1) Having an array of functions allow the kernel code to access the + * handler in a single lookup, which is much more efficient (think hash + * table here). + * 2) The only drawback is that driver writer may put their handler in + * the wrong slot. This is trivial to test (I set the frequency, the + * bitrate changes). Once the handler is in the proper slot, it will be + * there forever, because the array is only extended at the end. + * 3) Backward/forward compatibility : adding new handler just require + * extending the array, so you can put newer driver in older kernel + * without having to patch the kernel code (and vice versa). + * + * All handler are of the same generic type + * ---------------------------------------- + * That's a feature !!! + * 1) Having a generic handler allow to have generic code, which is more + * efficient. If each of the handler was individually typed I would need + * to add a big switch in the kernel (== more bloat). This solution is + * more scalable, adding new Wireless Extensions doesn't add new code. + * 2) You can use the same handler in different slots of the array. For + * hardware, it may be more efficient or logical to handle multiple + * Wireless Extensions with a single function, and the API allow you to + * do that. (An example would be a single record on the card to control + * both bitrate and frequency, the handler would read the old record, + * modify it according to info->cmd and rewrite it). + * + * Functions prototype uses union iwreq_data + * ----------------------------------------- + * Some would have prefered functions defined this way : + * static int mydriver_ioctl_setrate(struct net_device *dev, + * long rate, int auto) + * 1) The kernel code doesn't "validate" the content of iwreq_data, and + * can't do it (different hardware may have different notion of what a + * valid frequency is), so we don't pretend that we do it. + * 2) The above form is not extendable. If I want to add a flag (for + * example to distinguish setting max rate and basic rate), I would + * break the prototype. Using iwreq_data is more flexible. + * 3) Also, the above form is not generic (see above). + * 4) I don't expect driver developper using the wrong field of the + * union (Doh !), so static typechecking doesn't add much value. + * 5) Lastly, you can skip the union by doing : + * static int mydriver_ioctl_setrate(struct net_device *dev, + * struct iw_request_info *info, + * struct iw_param *rrq, + * char *extra) + * And then adding the handler in the array like this : + * (iw_handler) mydriver_ioctl_setrate, // SIOCSIWRATE + * + * Using functions and not a registry + * ---------------------------------- + * Another implementation option would have been for every instance to + * define a registry (a struct containing all the Wireless Extensions) + * and only have a function to commit the registry to the hardware. + * 1) This approach can be emulated by the current code, but not + * vice versa. + * 2) Some drivers don't keep any configuration in the driver, for them + * adding such a registry would be a significant bloat. + * 3) The code to translate from Wireless Extension to native format is + * needed anyway, so it would not reduce significantely the amount of code. + * 4) The current approach only selectively translate Wireless Extensions + * to native format and only selectively set, whereas the registry approach + * would require to translate all WE and set all parameters for any single + * change. + * 5) For many Wireless Extensions, the GET operation return the current + * dynamic value, not the value that was set. + * + * This header is <net/iw_handler.h> + * --------------------------------- + * 1) This header is kernel space only and should not be exported to + * user space. Headers in "include/linux/" are exported, headers in + * "include/net/" are not. + * + * Mixed 32/64 bit issues + * ---------------------- + * The Wireless Extensions are designed to be 64 bit clean, by using only + * datatypes with explicit storage size. + * There are some issues related to kernel and user space using different + * memory model, and in particular 64bit kernel with 32bit user space. + * The problem is related to struct iw_point, that contains a pointer + * that *may* need to be translated. + * This is quite messy. The new API doesn't solve this problem (it can't), + * but is a step in the right direction : + * 1) Meta data about each ioctl is easily available, so we know what type + * of translation is needed. + * 2) The move of data between kernel and user space is only done in a single + * place in the kernel, so adding specific hooks in there is possible. + * 3) In the long term, it allows to move away from using ioctl as the + * user space API. + * + * So many comments and so few code + * -------------------------------- + * That's a feature. Comments won't bloat the resulting kernel binary. + */ + +/***************************** INCLUDES *****************************/ + +#include <linux/wireless.h> /* IOCTL user space API */ + +/***************************** VERSION *****************************/ +/* + * This constant is used to know which version of the driver API is + * available. Hopefully, this will be pretty stable and no changes + * will be needed... + * I just plan to increment with each new version. + */ +#define IW_HANDLER_VERSION 3 + +/* + * Changes : + * + * V2 to V3 + * -------- + * - Move event definition in <linux/wireless.h> + * - Add Wireless Event support : + * o wireless_send_event() prototype + * o iwe_stream_add_event/point() inline functions + */ + +/**************************** CONSTANTS ****************************/ + +/* Special error message for the driver to indicate that we + * should do a commit after return from the iw_handler */ +#define EIWCOMMIT EINPROGRESS + +/* Flags available in struct iw_request_info */ +#define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */ + +/* Type of headers we know about (basically union iwreq_data) */ +#define IW_HEADER_TYPE_NULL 0 /* Not available */ +#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */ +#define IW_HEADER_TYPE_UINT 4 /* __u32 */ +#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */ +#define IW_HEADER_TYPE_POINT 6 /* struct iw_point */ +#define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */ +#define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */ +#define IW_HEADER_TYPE_QUAL 9 /* struct iw_quality */ + +/* Handling flags */ +/* Most are not implemented. I just use them as a reminder of some + * cool features we might need one day ;-) */ +#define IW_DESCR_FLAG_NONE 0x0000 /* Obvious */ +/* Wrapper level flags */ +#define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */ +#define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */ +#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */ + /* SET : Omit payload from generated iwevent */ +/* Driver level flags */ +#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */ + +/****************************** TYPES ******************************/ + +/* ----------------------- WIRELESS HANDLER ----------------------- */ +/* + * A wireless handler is just a standard function, that looks like the + * ioctl handler. + * We also define there how a handler list look like... As the Wireless + * Extension space is quite dense, we use a simple array, which is faster + * (that's the perfect hash table ;-). + */ + +/* + * Meta data about the request passed to the iw_handler. + * Most handlers can safely ignore what's in there. + * The 'cmd' field might come handy if you want to use the same handler + * for multiple command... + * This struct is also my long term insurance. I can add new fields here + * without breaking the prototype of iw_handler... + */ +struct iw_request_info +{ + __u16 cmd; /* Wireless Extension command */ + __u16 flags; /* More to come ;-) */ +}; + +/* + * This is how a function handling a Wireless Extension should look + * like (both get and set, standard and private). + */ +typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +/* + * This define all the handler that the driver export. + * As you need only one per driver type, please use a static const + * shared by all driver instances... Same for the members... + * This will be linked from net_device in <linux/netdevice.h> + */ +struct iw_handler_def +{ + /* Number of handlers defined (more precisely, index of the + * last defined handler + 1) */ + __u16 num_standard; + __u16 num_private; + /* Number of private arg description */ + __u16 num_private_args; + + /* Array of handlers for standard ioctls + * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME] + */ + iw_handler * standard; + + /* Array of handlers for private ioctls + * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV] + */ + iw_handler * private; + + /* Arguments of private handler. This one is just a list, so you + * can put it in any order you want and should not leave holes... + * We will automatically export that to user space... */ + struct iw_priv_args * private_args; + + /* In the long term, get_wireless_stats will move from + * 'struct net_device' to here, to minimise bloat. */ +}; + +/* ---------------------- IOCTL DESCRIPTION ---------------------- */ +/* + * One of the main goal of the new interface is to deal entirely with + * user space/kernel space memory move. + * For that, we need to know : + * o if iwreq is a pointer or contain the full data + * o what is the size of the data to copy + * + * For private IOCTLs, we use the same rules as used by iwpriv and + * defined in struct iw_priv_args. + * + * For standard IOCTLs, things are quite different and we need to + * use the stuctures below. Actually, this struct is also more + * efficient, but that's another story... + */ + +/* + * Describe how a standard IOCTL looks like. + */ +struct iw_ioctl_description +{ + __u8 header_type; /* NULL, iw_point or other */ + __u8 token_type; /* Future */ + __u16 token_size; /* Granularity of payload */ + __u16 min_tokens; /* Min acceptable token number */ + __u16 max_tokens; /* Max acceptable token number */ + __u32 flags; /* Special handling of the request */ +}; + +/* Need to think of short header translation table. Later. */ + +/**************************** PROTOTYPES ****************************/ +/* + * Functions part of the Wireless Extensions (defined in net/core/wireless.c). + * Those may be called only within the kernel. + */ + +/* First : function strictly used inside the kernel */ + +/* Handle /proc/net/wireless, called in net/code/dev.c */ +extern int dev_get_wireless_info(char * buffer, char **start, off_t offset, + int length); + +/* Handle IOCTLs, called in net/code/dev.c */ +extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd); + +/* Second : functions that may be called by driver modules */ + +/* Send a single event to user space */ +extern void wireless_send_event(struct net_device * dev, + unsigned int cmd, + union iwreq_data * wrqu, + char * extra); + +/* We may need a function to send a stream of events to user space. + * More on that later... */ + +/************************* INLINE FUNTIONS *************************/ +/* + * Function that are so simple that it's more efficient inlining them + */ + +/*------------------------------------------------------------------*/ +/* + * Wrapper to add an Wireless Event to a stream of events. + */ +static inline char * +iwe_stream_add_event(char * stream, /* Stream of events */ + char * ends, /* End of stream */ + struct iw_event *iwe, /* Payload */ + int event_len) /* Real size of payload */ +{ + /* Check if it's possible */ + if((stream + event_len) < ends) { + iwe->len = event_len; + memcpy(stream, (char *) iwe, event_len); + stream += event_len; + } + return stream; +} + +/*------------------------------------------------------------------*/ +/* + * Wrapper to add an short Wireless Event containing a pointer to a + * stream of events. + */ +static inline char * +iwe_stream_add_point(char * stream, /* Stream of events */ + char * ends, /* End of stream */ + struct iw_event *iwe, /* Payload */ + char * extra) +{ + int event_len = IW_EV_POINT_LEN + iwe->u.data.length; + /* Check if it's possible */ + if((stream + event_len) < ends) { + iwe->len = event_len; + memcpy(stream, (char *) iwe, IW_EV_POINT_LEN); + memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); + stream += event_len; + } + return stream; +} + +/*------------------------------------------------------------------*/ +/* + * Wrapper to add a value to a Wireless Event in a stream of events. + * Be careful, this one is tricky to use properly : + * At the first run, you need to have (value = event + IW_EV_LCP_LEN). + */ +static inline char * +iwe_stream_add_value(char * event, /* Event in the stream */ + char * value, /* Value in event */ + char * ends, /* End of stream */ + struct iw_event *iwe, /* Payload */ + int event_len) /* Real size of payload */ +{ + /* Don't duplicate LCP */ + event_len -= IW_EV_LCP_LEN; + + /* Check if it's possible */ + if((value + event_len) < ends) { + /* Add new value */ + memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len); + value += event_len; + /* Patch LCP */ + iwe->len = value - event; + memcpy(event, (char *) iwe, IW_EV_LCP_LEN); + } + return value; +} + +#endif /* _IW_HANDLER_H */ diff --git a/release/src/linux/linux/include/net/lapb.h b/release/src/linux/linux/include/net/lapb.h new file mode 100644 index 00000000..7cc9b345 --- /dev/null +++ b/release/src/linux/linux/include/net/lapb.h @@ -0,0 +1,150 @@ +#ifndef _LAPB_H +#define _LAPB_H +#include <linux/lapb.h> + +#define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */ + +#define LAPB_ACK_PENDING_CONDITION 0x01 +#define LAPB_REJECT_CONDITION 0x02 +#define LAPB_PEER_RX_BUSY_CONDITION 0x04 + +/* Control field templates */ +#define LAPB_I 0x00 /* Information frames */ +#define LAPB_S 0x01 /* Supervisory frames */ +#define LAPB_U 0x03 /* Unnumbered frames */ + +#define LAPB_RR 0x01 /* Receiver ready */ +#define LAPB_RNR 0x05 /* Receiver not ready */ +#define LAPB_REJ 0x09 /* Reject */ + +#define LAPB_SABM 0x2F /* Set Asynchronous Balanced Mode */ +#define LAPB_SABME 0x6F /* Set Asynchronous Balanced Mode Extended */ +#define LAPB_DISC 0x43 /* Disconnect */ +#define LAPB_DM 0x0F /* Disconnected mode */ +#define LAPB_UA 0x63 /* Unnumbered acknowledge */ +#define LAPB_FRMR 0x87 /* Frame reject */ + +#define LAPB_ILLEGAL 0x100 /* Impossible to be a real frame type */ + +#define LAPB_SPF 0x10 /* Poll/final bit for standard LAPB */ +#define LAPB_EPF 0x01 /* Poll/final bit for extended LAPB */ + +#define LAPB_FRMR_W 0x01 /* Control field invalid */ +#define LAPB_FRMR_X 0x02 /* I field invalid */ +#define LAPB_FRMR_Y 0x04 /* I field too long */ +#define LAPB_FRMR_Z 0x08 /* Invalid N(R) */ + +#define LAPB_POLLOFF 0 +#define LAPB_POLLON 1 + +/* LAPB C-bit */ +#define LAPB_COMMAND 1 +#define LAPB_RESPONSE 2 + +#define LAPB_ADDR_A 0x03 +#define LAPB_ADDR_B 0x01 +#define LAPB_ADDR_C 0x0F +#define LAPB_ADDR_D 0x07 + +/* Define Link State constants. */ +enum { + LAPB_STATE_0, /* Disconnected State */ + LAPB_STATE_1, /* Awaiting Connection State */ + LAPB_STATE_2, /* Awaiting Disconnection State */ + LAPB_STATE_3, /* Data Transfer State */ + LAPB_STATE_4 /* Frame Reject State */ +}; + +#define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE) +#define LAPB_DEFAULT_WINDOW 7 /* Window=7 */ +#define LAPB_DEFAULT_T1 (5 * HZ) /* T1=5s */ +#define LAPB_DEFAULT_T2 (1 * HZ) /* T2=1s */ +#define LAPB_DEFAULT_N2 20 /* N2=20 */ + +#define LAPB_SMODULUS 8 +#define LAPB_EMODULUS 128 + +/* + * Information about the current frame. + */ +struct lapb_frame { + unsigned short type; /* Parsed type */ + unsigned short nr, ns; /* N(R), N(S) */ + unsigned char cr; /* Command/Response */ + unsigned char pf; /* Poll/Final */ + unsigned char control[2]; /* Original control data*/ +}; + +/* + * The per LAPB connection control structure. + */ +typedef struct lapb_cb { + struct lapb_cb *next; + void *token; + + /* Link status fields */ + unsigned int mode; + unsigned char state; + unsigned short vs, vr, va; + unsigned char condition; + unsigned short n2, n2count; + unsigned short t1, t2; + struct timer_list t1timer, t2timer; + + /* Internal control information */ + struct sk_buff_head write_queue; + struct sk_buff_head ack_queue; + unsigned char window; + struct lapb_register_struct callbacks; + + /* FRMR control information */ + struct lapb_frame frmr_data; + unsigned char frmr_type; +} lapb_cb; + +/* lapb_iface.c */ +extern void lapb_connect_confirmation(lapb_cb *, int); +extern void lapb_connect_indication(lapb_cb *, int); +extern void lapb_disconnect_confirmation(lapb_cb *, int); +extern void lapb_disconnect_indication(lapb_cb *, int); +extern int lapb_data_indication(lapb_cb *, struct sk_buff *); +extern int lapb_data_transmit(lapb_cb *, struct sk_buff *); + +/* lapb_in.c */ +extern void lapb_data_input(lapb_cb *, struct sk_buff *); + +/* lapb_out.c */ +extern void lapb_kick(lapb_cb *); +extern void lapb_transmit_buffer(lapb_cb *, struct sk_buff *, int); +extern void lapb_establish_data_link(lapb_cb *); +extern void lapb_enquiry_response(lapb_cb *); +extern void lapb_timeout_response(lapb_cb *); +extern void lapb_check_iframes_acked(lapb_cb *, unsigned short); +extern void lapb_check_need_response(lapb_cb *, int, int); + +/* lapb_subr.c */ +extern void lapb_clear_queues(lapb_cb *); +extern void lapb_frames_acked(lapb_cb *, unsigned short); +extern void lapb_requeue_frames(lapb_cb *); +extern int lapb_validate_nr(lapb_cb *, unsigned short); +extern void lapb_decode(lapb_cb *, struct sk_buff *, struct lapb_frame *); +extern void lapb_send_control(lapb_cb *, int, int, int); +extern void lapb_transmit_frmr(lapb_cb *); + +/* lapb_timer.c */ +extern void lapb_start_t1timer(lapb_cb *); +extern void lapb_start_t2timer(lapb_cb *); +extern void lapb_stop_t1timer(lapb_cb *); +extern void lapb_stop_t2timer(lapb_cb *); +extern int lapb_t1timer_running(lapb_cb *); + +/* + * Debug levels. + * 0 = Off + * 1 = State Changes + * 2 = Packets I/O and State Changes + * 3 = Hex dumps, Packets I/O and State Changes. + */ +#define LAPB_DEBUG 0 + +#endif diff --git a/release/src/linux/linux/include/net/llc.h b/release/src/linux/linux/include/net/llc.h new file mode 100644 index 00000000..609b2123 --- /dev/null +++ b/release/src/linux/linux/include/net/llc.h @@ -0,0 +1,135 @@ +#include <linux/skbuff.h> + +#define LLC_MODULE + +typedef struct llc_struct llc; +typedef struct llc_struct *llcptr; + +/* + * LLC private data area structure. + */ + +struct llc_struct +{ + char eye[4]; /* To recognize llc area in dump */ + int retry_count; /* LLC link state variables */ + unsigned char name[9]; /* name of this llc instance */ + unsigned char s_flag; + unsigned char p_flag; + unsigned char f_flag; + unsigned char data_flag; + unsigned char cause_flag; + unsigned char vs; /* Send state variable */ + unsigned char vr; /* Receive state variable */ + unsigned char remote_busy; + unsigned char state; /* Current state of type2 llc procedure */ + int n1; /* Maximum number of bytes in I pdu 7.8.2 */ + int n2; /* Naximum number of retransmissions 7.8.2 */ + unsigned char k; /* Transmit window size 7.8.4, tw in IBM doc*/ + unsigned char rw; /* Receive window size */ + struct + { + /* + * FRMR_RSP info field structure: 5.4.2.3.5 p55 + */ + + unsigned char cntl1; + unsigned char cntl2; + unsigned char vs; + unsigned char vr_cr; + unsigned char xxyz; + } frmr_info_fld; + + /* + * Timers in 7.8.1 page 78 + */ + +#define P_TIMER 0 +#define REJ_TIMER 1 +#define ACK_TIMER 2 +#define BUSY_TIMER 3 + unsigned long timer_expire_time[4]; + unsigned char timer_state[4]; /* The state of each timer */ +#define TIMER_IDLE 0 +#define TIMER_RUNNING 1 +#define TIMER_EXPIRED 2 + unsigned long timer_interval[4]; + struct timer_list tl[4]; + + /* + * Client entry point, called by the LLC. + */ + + void (*llc_event)(struct llc_struct *); + + /* + * Mux and Demux variables + */ + + char * client_data; /* Pointer to clients context */ + unsigned char local_sap; + unsigned char remote_sap ; + char remote_mac[MAX_ADDR_LEN]; /* MAC address of remote session partner */ + struct net_device *dev; /* Device we are attached to */ + + unsigned char llc_mode; /* See doc 7.1 on p70 */ +#define MODE_ADM 1 +#define MODE_ABM 2 + + int llc_callbacks; /* Pending callbacks */ +#define LLC_CONN_INDICATION 1 /* We have to ensure the names don't */ +#define LLC_CONN_CONFIRM 2 /* mix up with the 802 state table */ +#define LLC_DATA_INDIC 4 +#define LLC_DISC_INDICATION 8 +#define LLC_RESET_INDIC_LOC 16 +#define LLC_RESET_INDIC_REM 32 +#define LLC_RST_CONFIRM 64 +#define LLC_FRMR_RECV 128 +#define LLC_FRMR_SENT 256 +#define LLC_REMOTE_BUSY 512 +#define LLC_REMOTE_NOTBUSY 1024 +#define LLC_TEST_INDICATION 2048 +#define LLC_XID_INDICATION 4096 +#define LLC_UI_DATA 8192 + + struct sk_buff *inc_skb; /* Saved data buffer for indications */ + + struct sk_buff_head rtq; /* Retransmit queue */ + struct sk_buff_head atq; /* Await transit queue */ + + unsigned char xid_count; + + struct llc_struct *nextllc; /* ptr to next llc struct in proto chain */ +}; + +#define ADD_TO_RTQ(skb) skb_queue_tail(&lp->rtq,skb) +#define ADD_TO_ATQ(skb) skb_queue_tail(&lp->atq,skb) + +void llc_cancel_timers(llcptr lp); +int llc_decode_frametype(frameptr fr); +llcptr llc_find(void); +int llc_free_acknowledged_skbs(llcptr lp, unsigned char ack); +void llc_handle_xid_indication( char *chsp, short int ll, char *xid_data); +void llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, char type); +void llc_add_to_queue(struct sk_buff *skb, struct sk_buff **f, struct sk_buff **b); +void llc_process_otype2_frame(llcptr lp, struct sk_buff *skb, char type); +struct sk_buff *llc_pull_from_atq(llcptr lp); +int llc_resend_ipdu(llcptr lp, unsigned char ack_nr, unsigned char type, char p); +void llc_sendpdu(llcptr lp, char type, char pf, int data_len, char *pdu_data); +void llc_sendipdu(llcptr lp, char type, char pf, struct sk_buff *skb); +void llc_start_timer(llcptr lp, int t); +void llc_stop_timer(llcptr lp, int t); +void llc_timer_expired(llcptr lp, int t); +int llc_validate_seq_nos(llcptr lp, frameptr fr); + +int llc_data_request(llcptr lp, struct sk_buff *skb); +void llc_unit_data_request(llcptr lp, int ll, char * data); +void llc_disconnect_request(llcptr lp); +void llc_connect_request(llcptr lp); +void llc_xid_request(llcptr lp, char opt, int data_len, char *pdu_data); +void llc_test_request(llcptr lp, int data_len, char *pdu_data); + +int register_cl2llc_client(llcptr llc, const char *device, void (*ops)(llcptr), u8 *rmac, u8 ssap, u8 dsap); +void unregister_cl2llc_client(llcptr lp); +int llc_mac_data_indicate(llcptr lp, struct sk_buff *skb ); + diff --git a/release/src/linux/linux/include/net/llc_frame.h b/release/src/linux/linux/include/net/llc_frame.h new file mode 100644 index 00000000..e8fb198d --- /dev/null +++ b/release/src/linux/linux/include/net/llc_frame.h @@ -0,0 +1,98 @@ +/* if_ether.h needed for definition of ETH_DATA_LEN and ETH_ALEN + */ +#include "linux/if_ether.h" + +/* frame layout based on par3.2 "LLC PDU format" + */ +typedef union { /* pdu layout from pages 40 & 44 */ + struct { /* general header, all pdu types */ + unsigned dsap : 8; /* dest service access point */ + unsigned ssap : 8; /* source service access point */ + unsigned f1 : 1; /* I- U- or S- format id bits */ + unsigned f2 : 1; + unsigned : 6; + unsigned : 8; + } pdu_hdr; + struct { + char dummy1[2]; /* dsap + ssap */ + char byte1; + char byte2; + } pdu_cntl; /* unformatted control bytes */ + struct { /* header of an Information pdu */ + unsigned char dummy2[2]; + unsigned : 1; + unsigned ns : 7; + unsigned i_pflag : 1; /* poll/final bit */ + unsigned nr : 7; /* N(R) */ + unsigned char is_info[ ETH_DATA_LEN ]; + } i_hdr; + struct { /* header of a Supervisory pdu */ + unsigned char dummy3[2]; + unsigned : 2; + unsigned ss : 2; /* supervisory function bits */ + unsigned : 4; + unsigned s_pflag : 1; /* poll/final bit */ + unsigned nr : 7; /* N(R) */ + } s_hdr; + +/* when accessing the P/F bit or the N(R) field there's no need to distinguish + I pdus from S pdus i_pflag and s_pflag / i_nr and s_nr map to the same + physical location. + */ + struct { /* header of an Unnumbered pdu */ + unsigned char dummy4[2]; + unsigned : 2; + unsigned mm1 : 2; /* modifier function part1 */ + unsigned u_pflag : 1; /* P/F for U- pdus */ + unsigned mm2 : 3; /* modifier function part2 */ + unsigned char u_info[ ETH_DATA_LEN-1]; + } u_hdr; + struct { /* mm field in an Unnumbered pdu */ + unsigned char dummy5[2]; + unsigned : 2; + unsigned mm : 6; /* must be masked to get ridd of P/F ! */ + } u_mm; + +} frame_type, *frameptr; + +/* frame format test macros: */ + +#define IS_UFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & ( (fr)->pdu_hdr.f2) ) + +#define IS_IFRAME( fr ) ( !( (fr)->pdu_hdr.f1) ) + +#define IS_SFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & !( (fr)->pdu_hdr.f2) ) + +#define IS_RSP( fr ) ( fr->pdu_hdr.ssap & 0x01 ) + + +/* The transition table, the _encode tables and some tests in the + source code depend on the numeric order of these values. + Think twice before changing. + */ + +/* frame names for TYPE 2 operation: */ +#define I_CMD 0 +#define RR_CMD 1 +#define RNR_CMD 2 +#define REJ_CMD 3 +#define DISC_CMD 4 +#define SABME_CMD 5 +#define I_RSP 6 +#define RR_RSP 7 +#define RNR_RSP 8 +#define REJ_RSP 9 +#define UA_RSP 10 +#define DM_RSP 11 +#define FRMR_RSP 12 + +/* junk frame name: */ +#define BAD_FRAME 13 +#define NO_FRAME 13 + +/* frame names for TYPE 1 operation: */ +#define UI_CMD 14 +#define XID_CMD 15 +#define TEST_CMD 16 +#define XID_RSP 17 +#define TEST_RSP 18 diff --git a/release/src/linux/linux/include/net/llc_name.h b/release/src/linux/linux/include/net/llc_name.h new file mode 100644 index 00000000..72128719 --- /dev/null +++ b/release/src/linux/linux/include/net/llc_name.h @@ -0,0 +1,7 @@ +char *frame_names[] = + {"I_CMD","RR_CMD","RNR_CMD","REJ_CMD","DISC_CMD", + "SABME_CMD","I_RSP","RR_RSP","RNR_RSP","REJ_RSP", + "UA_RSP","DM_RSP","FRMR_RSP","BAD_FRAME","UI_CMD", + "XID_CMD","TEST_CMD","XID_RSP","TEST_RSP" +}; + diff --git a/release/src/linux/linux/include/net/llc_state.h b/release/src/linux/linux/include/net/llc_state.h new file mode 100644 index 00000000..bb18e9bd --- /dev/null +++ b/release/src/linux/linux/include/net/llc_state.h @@ -0,0 +1,4 @@ +char *state_names[] = { + "ADM","CONN","RESET_WAIT","RESET_CHECK","SETUP", + "RESET","D_CONN","ERROR","NORMAL" +}; diff --git a/release/src/linux/linux/include/net/ndisc.h b/release/src/linux/linux/include/net/ndisc.h new file mode 100644 index 00000000..8748b657 --- /dev/null +++ b/release/src/linux/linux/include/net/ndisc.h @@ -0,0 +1,128 @@ +#ifndef _NDISC_H +#define _NDISC_H + +/* + * ICMP codes for neighbour discovery messages + */ + +#define NDISC_ROUTER_SOLICITATION 133 +#define NDISC_ROUTER_ADVERTISEMENT 134 +#define NDISC_NEIGHBOUR_SOLICITATION 135 +#define NDISC_NEIGHBOUR_ADVERTISEMENT 136 +#define NDISC_REDIRECT 137 + +/* + * ndisc options + */ + +#define ND_OPT_SOURCE_LL_ADDR 1 +#define ND_OPT_TARGET_LL_ADDR 2 +#define ND_OPT_PREFIX_INFO 3 +#define ND_OPT_REDIRECT_HDR 4 +#define ND_OPT_MTU 5 + +#define MAX_RTR_SOLICITATION_DELAY HZ + +#define ND_REACHABLE_TIME (30*HZ) +#define ND_RETRANS_TIMER HZ + +#define ND_MIN_RANDOM_FACTOR (1/2) +#define ND_MAX_RANDOM_FACTOR (3/2) + +#ifdef __KERNEL__ + +#include <linux/skbuff.h> +#include <linux/netdevice.h> +#include <linux/icmpv6.h> +#include <net/neighbour.h> +#include <asm/atomic.h> + +extern struct neigh_table nd_tbl; + +struct nd_msg { + struct icmp6hdr icmph; + struct in6_addr target; + __u8 opt[0]; +}; + +struct ra_msg { + struct icmp6hdr icmph; + __u32 reachable_time; + __u32 retrans_timer; +}; + +struct nd_opt_hdr { + __u8 nd_opt_type; + __u8 nd_opt_len; +} __attribute__((__packed__)); + +struct ndisc_options { + struct nd_opt_hdr *nd_opt_array[7]; + struct nd_opt_hdr *nd_opt_piend; +}; + +#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR] +#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR] +#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO] +#define nd_opts_pi_end nd_opt_piend +#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR] +#define nd_opts_mtu nd_opt_array[ND_OPT_MTU] + +extern struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, struct nd_opt_hdr *end); +extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, struct ndisc_options *ndopts); + +extern int ndisc_init(struct net_proto_family *ops); + +extern void ndisc_cleanup(void); + +extern int ndisc_rcv(struct sk_buff *skb); + +extern void ndisc_send_ns(struct net_device *dev, + struct neighbour *neigh, + struct in6_addr *solicit, + struct in6_addr *daddr, + struct in6_addr *saddr); + +extern void ndisc_send_rs(struct net_device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr); + +extern void ndisc_forwarding_on(void); +extern void ndisc_forwarding_off(void); + +extern void ndisc_send_redirect(struct sk_buff *skb, + struct neighbour *neigh, + struct in6_addr *target); + +extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir); + + +struct rt6_info * dflt_rt_lookup(void); + +/* + * IGMP + */ +extern int igmp6_init(struct net_proto_family *ops); + +extern void igmp6_cleanup(void); + +extern int igmp6_event_query(struct sk_buff *skb); + +extern int igmp6_event_report(struct sk_buff *skb); + +extern void igmp6_cleanup(void); + +static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr) +{ + + if (dev) + return __neigh_lookup(&nd_tbl, addr, dev, 1); + + return NULL; +} + + +#endif /* __KERNEL__ */ + + +#endif diff --git a/release/src/linux/linux/include/net/neighbour.h b/release/src/linux/linux/include/net/neighbour.h new file mode 100644 index 00000000..1a60139a --- /dev/null +++ b/release/src/linux/linux/include/net/neighbour.h @@ -0,0 +1,281 @@ +#ifndef _NET_NEIGHBOUR_H +#define _NET_NEIGHBOUR_H + +/* + * Generic neighbour manipulation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> + */ + +/* The following flags & states are exported to user space, + so that they should be moved to include/linux/ directory. + */ + +/* + * Neighbor Cache Entry Flags + */ + +#define NTF_PROXY 0x08 /* == ATF_PUBL */ +#define NTF_ROUTER 0x80 + +/* + * Neighbor Cache Entry States. + */ + +#define NUD_INCOMPLETE 0x01 +#define NUD_REACHABLE 0x02 +#define NUD_STALE 0x04 +#define NUD_DELAY 0x08 +#define NUD_PROBE 0x10 +#define NUD_FAILED 0x20 + +/* Dummy states */ +#define NUD_NOARP 0x40 +#define NUD_PERMANENT 0x80 +#define NUD_NONE 0x00 + +/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change + and make no address resolution or NUD. + NUD_PERMANENT is also cannot be deleted by garbage collectors. + */ + +#ifdef __KERNEL__ + +#include <asm/atomic.h> +#include <linux/skbuff.h> + +#define NUD_IN_TIMER (NUD_INCOMPLETE|NUD_DELAY|NUD_PROBE) +#define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY) +#define NUD_CONNECTED (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE) + +struct neigh_parms +{ + struct neigh_parms *next; + int (*neigh_setup)(struct neighbour *); + struct neigh_table *tbl; + int entries; + void *priv; + + void *sysctl_table; + + int base_reachable_time; + int retrans_time; + int gc_staletime; + int reachable_time; + int delay_probe_time; + + int queue_len; + int ucast_probes; + int app_probes; + int mcast_probes; + int anycast_delay; + int proxy_delay; + int proxy_qlen; + int locktime; +}; + +struct neigh_statistics +{ + unsigned long allocs; + unsigned long res_failed; + unsigned long rcv_probes_mcast; + unsigned long rcv_probes_ucast; +}; + +struct neighbour +{ + struct neighbour *next; + struct neigh_table *tbl; + struct neigh_parms *parms; + struct net_device *dev; + unsigned long used; + unsigned long confirmed; + unsigned long updated; + __u8 flags; + __u8 nud_state; + __u8 type; + __u8 dead; + atomic_t probes; + rwlock_t lock; + unsigned char ha[(MAX_ADDR_LEN+sizeof(unsigned long)-1)&~(sizeof(unsigned long)-1)]; + struct hh_cache *hh; + atomic_t refcnt; + int (*output)(struct sk_buff *skb); + struct sk_buff_head arp_queue; + struct timer_list timer; + struct neigh_ops *ops; + u8 primary_key[0]; +}; + +struct neigh_ops +{ + int family; + void (*destructor)(struct neighbour *); + void (*solicit)(struct neighbour *, struct sk_buff*); + void (*error_report)(struct neighbour *, struct sk_buff*); + int (*output)(struct sk_buff*); + int (*connected_output)(struct sk_buff*); + int (*hh_output)(struct sk_buff*); + int (*queue_xmit)(struct sk_buff*); +}; + +struct pneigh_entry +{ + struct pneigh_entry *next; + struct net_device *dev; + u8 key[0]; +}; + +#define NEIGH_HASHMASK 0x1F +#define PNEIGH_HASHMASK 0xF + +/* + * neighbour table manipulation + */ + + +struct neigh_table +{ + struct neigh_table *next; + int family; + int entry_size; + int key_len; + __u32 (*hash)(const void *pkey, const struct net_device *); + int (*constructor)(struct neighbour *); + int (*pconstructor)(struct pneigh_entry *); + void (*pdestructor)(struct pneigh_entry *); + void (*proxy_redo)(struct sk_buff *skb); + char *id; + struct neigh_parms parms; + /* HACK. gc_* shoul follow parms without a gap! */ + int gc_interval; + int gc_thresh1; + int gc_thresh2; + int gc_thresh3; + unsigned long last_flush; + struct timer_list gc_timer; + struct timer_list proxy_timer; + struct sk_buff_head proxy_queue; + int entries; + rwlock_t lock; + unsigned long last_rand; + struct neigh_parms *parms_list; + kmem_cache_t *kmem_cachep; + struct tasklet_struct gc_task; + struct neigh_statistics stats; + struct neighbour *hash_buckets[NEIGH_HASHMASK+1]; + struct pneigh_entry *phash_buckets[PNEIGH_HASHMASK+1]; +}; + +extern void neigh_table_init(struct neigh_table *tbl); +extern int neigh_table_clear(struct neigh_table *tbl); +extern struct neighbour * neigh_lookup(struct neigh_table *tbl, + const void *pkey, + struct net_device *dev); +extern struct neighbour * neigh_create(struct neigh_table *tbl, + const void *pkey, + struct net_device *dev); +extern void neigh_destroy(struct neighbour *neigh); +extern int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb); +extern int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, int override, int arp); +extern int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev); +extern int neigh_resolve_output(struct sk_buff *skb); +extern int neigh_connected_output(struct sk_buff *skb); +extern int neigh_compat_output(struct sk_buff *skb); +extern struct neighbour *neigh_event_ns(struct neigh_table *tbl, + u8 *lladdr, void *saddr, + struct net_device *dev); + +extern struct neigh_parms *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl); +extern void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms); +extern unsigned long neigh_rand_reach_time(unsigned long base); + +extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, + struct sk_buff *skb); +extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat); +extern int pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev); + +struct netlink_callback; +struct nlmsghdr; +extern int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb); +extern int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern void neigh_app_ns(struct neighbour *n); + +extern int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, + int p_id, int pdev_id, char *p_name); +extern void neigh_sysctl_unregister(struct neigh_parms *p); + +/* + * Neighbour references + */ + +static inline void neigh_release(struct neighbour *neigh) +{ + if (atomic_dec_and_test(&neigh->refcnt)) + neigh_destroy(neigh); +} + +static inline struct neighbour * neigh_clone(struct neighbour *neigh) +{ + if (neigh) + atomic_inc(&neigh->refcnt); + return neigh; +} + +#define neigh_hold(n) atomic_inc(&(n)->refcnt) + +static inline void neigh_confirm(struct neighbour *neigh) +{ + if (neigh) + neigh->confirmed = jiffies; +} + +static inline int neigh_is_connected(struct neighbour *neigh) +{ + return neigh->nud_state&NUD_CONNECTED; +} + +static inline int neigh_is_valid(struct neighbour *neigh) +{ + return neigh->nud_state&NUD_VALID; +} + +static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) +{ + neigh->used = jiffies; + if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) + return __neigh_event_send(neigh, skb); + return 0; +} + +static inline struct neighbour * +__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat) +{ + struct neighbour *n = neigh_lookup(tbl, pkey, dev); + + if (n || !creat) + return n; + + n = neigh_create(tbl, pkey, dev); + return IS_ERR(n) ? NULL : n; +} + +static inline struct neighbour * +__neigh_lookup_errno(struct neigh_table *tbl, const void *pkey, + struct net_device *dev) +{ + struct neighbour *n = neigh_lookup(tbl, pkey, dev); + + if (n) + return n; + + return neigh_create(tbl, pkey, dev); +} + +#endif +#endif + + diff --git a/release/src/linux/linux/include/net/netrom.h b/release/src/linux/linux/include/net/netrom.h new file mode 100644 index 00000000..21c9f8b8 --- /dev/null +++ b/release/src/linux/linux/include/net/netrom.h @@ -0,0 +1,179 @@ +/* + * Declarations of NET/ROM type objects. + * + * Jonathan Naylor G4KLX 9/4/95 + */ + +#ifndef _NETROM_H +#define _NETROM_H +#include <linux/netrom.h> + +#define NR_NETWORK_LEN 15 +#define NR_TRANSPORT_LEN 5 + +#define NR_PROTO_IP 0x0C + +#define NR_PROTOEXT 0x00 +#define NR_CONNREQ 0x01 +#define NR_CONNACK 0x02 +#define NR_DISCREQ 0x03 +#define NR_DISCACK 0x04 +#define NR_INFO 0x05 +#define NR_INFOACK 0x06 + +#define NR_CHOKE_FLAG 0x80 +#define NR_NAK_FLAG 0x40 +#define NR_MORE_FLAG 0x20 + +/* Define Link State constants. */ +enum { + NR_STATE_0, + NR_STATE_1, + NR_STATE_2, + NR_STATE_3 +}; + +#define NR_COND_ACK_PENDING 0x01 +#define NR_COND_REJECT 0x02 +#define NR_COND_PEER_RX_BUSY 0x04 +#define NR_COND_OWN_RX_BUSY 0x08 + +#define NR_DEFAULT_T1 (120 * HZ) /* Outstanding frames - 120 seconds */ +#define NR_DEFAULT_T2 (5 * HZ) /* Response delay - 5 seconds */ +#define NR_DEFAULT_N2 3 /* Number of Retries - 3 */ +#define NR_DEFAULT_T4 (180 * HZ) /* Busy Delay - 180 seconds */ +#define NR_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */ +#define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */ +#define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */ +#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */ +#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */ +#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */ +#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */ + +#define NR_MODULUS 256 +#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */ +#define NR_MAX_PACKET_SIZE 236 /* Maximum Packet Length - 236 */ + +typedef struct { + ax25_address user_addr, source_addr, dest_addr; + struct net_device *device; + unsigned char my_index, my_id; + unsigned char your_index, your_id; + unsigned char state, condition, bpqext, window; + unsigned short vs, vr, va, vl; + unsigned char n2, n2count; + unsigned long t1, t2, t4, idle; + unsigned short fraglen; + struct timer_list t1timer; + struct timer_list t2timer; + struct timer_list t4timer; + struct timer_list idletimer; + struct sk_buff_head ack_queue; + struct sk_buff_head reseq_queue; + struct sk_buff_head frag_queue; + struct sock *sk; /* Backlink to socket */ +} nr_cb; + +struct nr_neigh { + struct nr_neigh *next; + ax25_address callsign; + ax25_digi *digipeat; + ax25_cb *ax25; + struct net_device *dev; + unsigned char quality; + unsigned char locked; + unsigned short count; + unsigned int number; + unsigned char failed; +}; + +struct nr_route { + unsigned char quality; + unsigned char obs_count; + struct nr_neigh *neighbour; +}; + +struct nr_node { + struct nr_node *next; + ax25_address callsign; + char mnemonic[7]; + unsigned char which; + unsigned char count; + struct nr_route routes[3]; +}; + +/* af_netrom.c */ +extern int sysctl_netrom_default_path_quality; +extern int sysctl_netrom_obsolescence_count_initialiser; +extern int sysctl_netrom_network_ttl_initialiser; +extern int sysctl_netrom_transport_timeout; +extern int sysctl_netrom_transport_maximum_tries; +extern int sysctl_netrom_transport_acknowledge_delay; +extern int sysctl_netrom_transport_busy_delay; +extern int sysctl_netrom_transport_requested_window_size; +extern int sysctl_netrom_transport_no_activity_timeout; +extern int sysctl_netrom_routing_control; +extern int sysctl_netrom_link_fails_count; +extern int nr_rx_frame(struct sk_buff *, struct net_device *); +extern void nr_destroy_socket(struct sock *); + +/* nr_dev.c */ +extern int nr_rx_ip(struct sk_buff *, struct net_device *); +extern int nr_init(struct net_device *); + +/* nr_in.c */ +extern int nr_process_rx_frame(struct sock *, struct sk_buff *); + +/* nr_loopback.c */ +extern void nr_loopback_init(void); +extern void nr_loopback_clear(void); +extern int nr_loopback_queue(struct sk_buff *); + +/* nr_out.c */ +extern void nr_output(struct sock *, struct sk_buff *); +extern void nr_send_nak_frame(struct sock *); +extern void nr_kick(struct sock *); +extern void nr_transmit_buffer(struct sock *, struct sk_buff *); +extern void nr_establish_data_link(struct sock *); +extern void nr_enquiry_response(struct sock *); +extern void nr_check_iframes_acked(struct sock *, unsigned short); + +/* nr_route.c */ +extern void nr_rt_device_down(struct net_device *); +extern struct net_device *nr_dev_first(void); +extern struct net_device *nr_dev_get(ax25_address *); +extern int nr_rt_ioctl(unsigned int, void *); +extern void nr_link_failed(ax25_cb *, int); +extern int nr_route_frame(struct sk_buff *, ax25_cb *); +extern int nr_nodes_get_info(char *, char **, off_t, int); +extern int nr_neigh_get_info(char *, char **, off_t, int); +extern void nr_rt_free(void); + +/* nr_subr.c */ +extern void nr_clear_queues(struct sock *); +extern void nr_frames_acked(struct sock *, unsigned short); +extern void nr_requeue_frames(struct sock *); +extern int nr_validate_nr(struct sock *, unsigned short); +extern int nr_in_rx_window(struct sock *, unsigned short); +extern void nr_write_internal(struct sock *, int); +extern void nr_transmit_refusal(struct sk_buff *, int); +extern void nr_disconnect(struct sock *, int); + +/* nr_timer.c */ +extern void nr_start_heartbeat(struct sock *); +extern void nr_start_t1timer(struct sock *); +extern void nr_start_t2timer(struct sock *); +extern void nr_start_t4timer(struct sock *); +extern void nr_start_idletimer(struct sock *); +extern void nr_stop_heartbeat(struct sock *); +extern void nr_stop_t1timer(struct sock *); +extern void nr_stop_t2timer(struct sock *); +extern void nr_stop_t4timer(struct sock *); +extern void nr_stop_idletimer(struct sock *); +extern int nr_t1timer_running(struct sock *); + +/* sysctl_net_netrom.c */ +extern void nr_register_sysctl(void); +extern void nr_unregister_sysctl(void); + +#endif diff --git a/release/src/linux/linux/include/net/p8022.h b/release/src/linux/linux/include/net/p8022.h new file mode 100644 index 00000000..8b8871c9 --- /dev/null +++ b/release/src/linux/linux/include/net/p8022.h @@ -0,0 +1,7 @@ +#ifndef _NET_P8022_H +#define _NET_P8022_H + +extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *)); +extern void unregister_8022_client(unsigned char type); + +#endif diff --git a/release/src/linux/linux/include/net/pkt_cls.h b/release/src/linux/linux/include/net/pkt_cls.h new file mode 100644 index 00000000..cb2bde23 --- /dev/null +++ b/release/src/linux/linux/include/net/pkt_cls.h @@ -0,0 +1,87 @@ +#ifndef __NET_PKT_CLS_H +#define __NET_PKT_CLS_H + + +#include <linux/pkt_cls.h> + +struct rtattr; +struct tcmsg; + +/* Basic packet classifier frontend definitions. */ + +struct tcf_result +{ + unsigned long class; + u32 classid; +}; + +struct tcf_proto +{ + /* Fast access part */ + struct tcf_proto *next; + void *root; + int (*classify)(struct sk_buff*, struct tcf_proto*, struct tcf_result *); + u32 protocol; + + /* All the rest */ + u32 prio; + u32 classid; + struct Qdisc *q; + void *data; + struct tcf_proto_ops *ops; +}; + +struct tcf_walker +{ + int stop; + int skip; + int count; + int (*fn)(struct tcf_proto *, unsigned long node, struct tcf_walker *); +}; + +struct tcf_proto_ops +{ + struct tcf_proto_ops *next; + char kind[IFNAMSIZ]; + + int (*classify)(struct sk_buff*, struct tcf_proto*, struct tcf_result *); + int (*init)(struct tcf_proto*); + void (*destroy)(struct tcf_proto*); + + unsigned long (*get)(struct tcf_proto*, u32 handle); + void (*put)(struct tcf_proto*, unsigned long); + int (*change)(struct tcf_proto*, unsigned long, u32 handle, struct rtattr **, unsigned long *); + int (*delete)(struct tcf_proto*, unsigned long); + void (*walk)(struct tcf_proto*, struct tcf_walker *arg); + + /* rtnetlink specific */ + int (*dump)(struct tcf_proto*, unsigned long, struct sk_buff *skb, struct tcmsg*); +}; + +/* Main classifier routine: scans classifier chain attached + to this qdisc, (optionally) tests for protocol and asks + specific classifiers. + */ + +static inline int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res) +{ + int err = 0; + u32 protocol = skb->protocol; + + for ( ; tp; tp = tp->next) { + if ((tp->protocol == protocol || + tp->protocol == __constant_htons(ETH_P_ALL)) && + (err = tp->classify(skb, tp, res)) >= 0) + return err; + } + return -1; +} + + + +extern int register_tcf_proto_ops(struct tcf_proto_ops *ops); +extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); + + + +#endif diff --git a/release/src/linux/linux/include/net/pkt_sched.h b/release/src/linux/linux/include/net/pkt_sched.h new file mode 100644 index 00000000..a9027b90 --- /dev/null +++ b/release/src/linux/linux/include/net/pkt_sched.h @@ -0,0 +1,453 @@ +#ifndef __NET_PKT_SCHED_H +#define __NET_PKT_SCHED_H + +#define PSCHED_GETTIMEOFDAY 1 +#define PSCHED_JIFFIES 2 +#define PSCHED_CPU 3 + +#define PSCHED_CLOCK_SOURCE PSCHED_JIFFIES + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/pkt_sched.h> +#include <net/pkt_cls.h> + +#ifdef CONFIG_X86_TSC +#include <asm/msr.h> +#endif + +struct rtattr; +struct Qdisc; + +struct qdisc_walker +{ + int stop; + int skip; + int count; + int (*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *); +}; + +struct Qdisc_class_ops +{ + /* Child qdisc manipulation */ + int (*graft)(struct Qdisc *, unsigned long cl, struct Qdisc *, struct Qdisc **); + struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl); + + /* Class manipulation routines */ + unsigned long (*get)(struct Qdisc *, u32 classid); + void (*put)(struct Qdisc *, unsigned long); + int (*change)(struct Qdisc *, u32, u32, struct rtattr **, unsigned long *); + int (*delete)(struct Qdisc *, unsigned long); + void (*walk)(struct Qdisc *, struct qdisc_walker * arg); + + /* Filter manipulation */ + struct tcf_proto ** (*tcf_chain)(struct Qdisc *, unsigned long); + unsigned long (*bind_tcf)(struct Qdisc *, unsigned long, u32 classid); + void (*unbind_tcf)(struct Qdisc *, unsigned long); + + /* rtnetlink specific */ + int (*dump)(struct Qdisc *, unsigned long, struct sk_buff *skb, struct tcmsg*); +}; + +struct Qdisc_ops +{ + struct Qdisc_ops *next; + struct Qdisc_class_ops *cl_ops; + char id[IFNAMSIZ]; + int priv_size; + + int (*enqueue)(struct sk_buff *, struct Qdisc *); + struct sk_buff * (*dequeue)(struct Qdisc *); + int (*requeue)(struct sk_buff *, struct Qdisc *); + int (*drop)(struct Qdisc *); + + int (*init)(struct Qdisc *, struct rtattr *arg); + void (*reset)(struct Qdisc *); + void (*destroy)(struct Qdisc *); + int (*change)(struct Qdisc *, struct rtattr *arg); + + int (*dump)(struct Qdisc *, struct sk_buff *); +}; + +extern rwlock_t qdisc_tree_lock; + +struct Qdisc +{ + int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev); + struct sk_buff * (*dequeue)(struct Qdisc *dev); + unsigned flags; +#define TCQ_F_BUILTIN 1 +#define TCQ_F_THROTTLED 2 +#define TCQ_F_INGRES 4 + struct Qdisc_ops *ops; + struct Qdisc *next; + u32 handle; + atomic_t refcnt; + struct sk_buff_head q; + struct net_device *dev; + + struct tc_stats stats; + int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q); + + /* This field is deprecated, but it is still used by CBQ + * and it will live until better solution will be invented. + */ + struct Qdisc *__parent; + + char data[0]; +}; + +struct qdisc_rate_table +{ + struct tc_ratespec rate; + u32 data[256]; + struct qdisc_rate_table *next; + int refcnt; +}; + +static inline void sch_tree_lock(struct Qdisc *q) +{ + write_lock(&qdisc_tree_lock); + spin_lock_bh(&q->dev->queue_lock); +} + +static inline void sch_tree_unlock(struct Qdisc *q) +{ + spin_unlock_bh(&q->dev->queue_lock); + write_unlock(&qdisc_tree_lock); +} + +static inline void tcf_tree_lock(struct tcf_proto *tp) +{ + write_lock(&qdisc_tree_lock); + spin_lock_bh(&tp->q->dev->queue_lock); +} + +static inline void tcf_tree_unlock(struct tcf_proto *tp) +{ + spin_unlock_bh(&tp->q->dev->queue_lock); + write_unlock(&qdisc_tree_lock); +} + + +static inline unsigned long +cls_set_class(struct tcf_proto *tp, unsigned long *clp, unsigned long cl) +{ + unsigned long old_cl; + + tcf_tree_lock(tp); + old_cl = *clp; + *clp = cl; + tcf_tree_unlock(tp); + return old_cl; +} + +static inline unsigned long +__cls_set_class(unsigned long *clp, unsigned long cl) +{ + unsigned long old_cl; + + old_cl = *clp; + *clp = cl; + return old_cl; +} + + +/* + Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth + + Normal IP packet size ~ 512byte, hence: + + 0.5Kbyte/1Mbyte/sec = 0.5msec, so that we need 50usec timer for + 10Mbit ethernet. + + 10msec resolution -> <50Kbit/sec. + + The result: [34]86 is not good choice for QoS router :-( + + The things are not so bad, because we may use artifical + clock evaluated by integration of network data flow + in the most critical places. + + Note: we do not use fastgettimeofday. + The reason is that, when it is not the same thing as + gettimeofday, it returns invalid timestamp, which is + not updated, when net_bh is active. + + So, use PSCHED_CLOCK_SOURCE = PSCHED_CPU on alpha and pentiums + with rtdsc. And PSCHED_JIFFIES on all other architectures, including [34]86 + and pentiums without rtdsc. + You can use PSCHED_GETTIMEOFDAY on another architectures, + which have fast and precise clock source, but it is too expensive. + */ + +/* General note about internal clock. + + Any clock source returns time intervals, measured in units + close to 1usec. With source PSCHED_GETTIMEOFDAY it is precisely + microseconds, otherwise something close but different chosen to minimize + arithmetic cost. Ratio usec/internal untis in form nominator/denominator + may be read from /proc/net/psched. + */ + + +#if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY + +typedef struct timeval psched_time_t; +typedef long psched_tdiff_t; + +#define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp)) +#define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ)) + +#define PSCHED_EXPORTLIST EXPORT_SYMBOL(psched_tod_diff); + +#else /* PSCHED_CLOCK_SOURCE != PSCHED_GETTIMEOFDAY */ + +#define PSCHED_EXPORTLIST PSCHED_EXPORTLIST_1 PSCHED_EXPORTLIST_2 + +typedef u64 psched_time_t; +typedef long psched_tdiff_t; + +extern psched_time_t psched_time_base; + +#if PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES + +#if HZ == 100 +#define PSCHED_JSCALE 13 +#elif HZ == 1024 +#define PSCHED_JSCALE 10 +#else +#define PSCHED_JSCALE 0 +#endif + +#define PSCHED_EXPORTLIST_2 + +#if BITS_PER_LONG <= 32 + +#define PSCHED_WATCHER unsigned long + +extern PSCHED_WATCHER psched_time_mark; + +#define PSCHED_GET_TIME(stamp) ((stamp) = psched_time_base + (((unsigned long)(jiffies-psched_time_mark))<<PSCHED_JSCALE)) + +#define PSCHED_EXPORTLIST_1 EXPORT_SYMBOL(psched_time_base); \ + EXPORT_SYMBOL(psched_time_mark); + +#else + +#define PSCHED_GET_TIME(stamp) ((stamp) = (jiffies<<PSCHED_JSCALE)) + +#define PSCHED_EXPORTLIST_1 + +#endif + +#define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE) + +#elif PSCHED_CLOCK_SOURCE == PSCHED_CPU + +extern psched_tdiff_t psched_clock_per_hz; +extern int psched_clock_scale; + +#define PSCHED_EXPORTLIST_2 EXPORT_SYMBOL(psched_clock_per_hz); \ + EXPORT_SYMBOL(psched_clock_scale); + +#define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz) + +#ifdef CONFIG_X86_TSC + +#define PSCHED_GET_TIME(stamp) \ +({ u64 __cur; \ + rdtscll(__cur); \ + (stamp) = __cur>>psched_clock_scale; \ +}) + +#define PSCHED_EXPORTLIST_1 + +#elif defined(__alpha__) + +#define PSCHED_WATCHER u32 + +extern PSCHED_WATCHER psched_time_mark; + +#define PSCHED_GET_TIME(stamp) \ +({ u32 __res; \ + __asm__ __volatile__ ("rpcc %0" : "r="(__res)); \ + if (__res <= psched_time_mark) psched_time_base += 0x100000000UL; \ + psched_time_mark = __res; \ + (stamp) = (psched_time_base + __res)>>psched_clock_scale; \ +}) + +#define PSCHED_EXPORTLIST_1 EXPORT_SYMBOL(psched_time_base); \ + EXPORT_SYMBOL(psched_time_mark); + +#else + +#error PSCHED_CLOCK_SOURCE=PSCHED_CPU is not supported on this arch. + +#endif /* ARCH */ + +#endif /* PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES */ + +#endif /* PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY */ + +#if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY +#define PSCHED_TDIFF(tv1, tv2) \ +({ \ + int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \ + int __delta = (tv1).tv_usec - (tv2).tv_usec; \ + if (__delta_sec) { \ + switch (__delta_sec) { \ + default: \ + __delta = 0; \ + case 2: \ + __delta += 1000000; \ + case 1: \ + __delta += 1000000; \ + } \ + } \ + __delta; \ +}) + +extern int psched_tod_diff(int delta_sec, int bound); + +#define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \ +({ \ + int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \ + int __delta = (tv1).tv_usec - (tv2).tv_usec; \ + switch (__delta_sec) { \ + default: \ + __delta = psched_tod_diff(__delta_sec, bound); guard; break; \ + case 2: \ + __delta += 1000000; \ + case 1: \ + __delta += 1000000; \ + case 0: ; \ + } \ + __delta; \ +}) + +#define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \ + (tv1).tv_sec <= (tv2).tv_sec) || \ + (tv1).tv_sec < (tv2).tv_sec) + +#define PSCHED_TADD2(tv, delta, tv_res) \ +({ \ + int __delta = (tv).tv_usec + (delta); \ + (tv_res).tv_sec = (tv).tv_sec; \ + if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \ + (tv_res).tv_usec = __delta; \ +}) + +#define PSCHED_TADD(tv, delta) \ +({ \ + (tv).tv_usec += (delta); \ + if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \ + (tv).tv_usec -= 1000000; } \ +}) + +/* Set/check that time is in the "past perfect"; + it depends on concrete representation of system time + */ + +#define PSCHED_SET_PASTPERFECT(t) ((t).tv_sec = 0) +#define PSCHED_IS_PASTPERFECT(t) ((t).tv_sec == 0) + +#define PSCHED_AUDIT_TDIFF(t) ({ if ((t) > 2000000) (t) = 2000000; }) + +#else + +#define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2)) +#define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \ +({ \ + long long __delta = (tv1) - (tv2); \ + if ( __delta > (long long)(bound)) { __delta = (bound); guard; } \ + __delta; \ +}) + + +#define PSCHED_TLESS(tv1, tv2) ((tv1) < (tv2)) +#define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = (tv) + (delta)) +#define PSCHED_TADD(tv, delta) ((tv) += (delta)) +#define PSCHED_SET_PASTPERFECT(t) ((t) = 0) +#define PSCHED_IS_PASTPERFECT(t) ((t) == 0) +#define PSCHED_AUDIT_TDIFF(t) + +#endif + +struct tcf_police +{ + struct tcf_police *next; + int refcnt; + u32 index; + + int action; + int result; + u32 ewma_rate; + u32 burst; + u32 mtu; + + u32 toks; + u32 ptoks; + psched_time_t t_c; + spinlock_t lock; + struct qdisc_rate_table *R_tab; + struct qdisc_rate_table *P_tab; + + struct tc_stats stats; +}; + +extern int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st); +extern void tcf_police_destroy(struct tcf_police *p); +extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est); +extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p); +extern int tcf_police(struct sk_buff *skb, struct tcf_police *p); + +static inline void tcf_police_release(struct tcf_police *p) +{ + if (p && --p->refcnt == 0) + tcf_police_destroy(p); +} + +extern struct Qdisc noop_qdisc; +extern struct Qdisc_ops noop_qdisc_ops; +extern struct Qdisc_ops pfifo_qdisc_ops; +extern struct Qdisc_ops bfifo_qdisc_ops; + +int register_qdisc(struct Qdisc_ops *qops); +int unregister_qdisc(struct Qdisc_ops *qops); +struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle); +struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle); +void dev_init_scheduler(struct net_device *dev); +void dev_shutdown(struct net_device *dev); +void dev_activate(struct net_device *dev); +void dev_deactivate(struct net_device *dev); +void qdisc_reset(struct Qdisc *qdisc); +void qdisc_destroy(struct Qdisc *qdisc); +struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops); +int qdisc_new_estimator(struct tc_stats *stats, struct rtattr *opt); +void qdisc_kill_estimator(struct tc_stats *stats); +struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab); +void qdisc_put_rtab(struct qdisc_rate_table *tab); +int teql_init(void); +int tc_filter_init(void); +int pktsched_init(void); + +extern int qdisc_restart(struct net_device *dev); + +static inline void qdisc_run(struct net_device *dev) +{ + while (!netif_queue_stopped(dev) && + qdisc_restart(dev)<0) + /* NOTHING */; +} + +/* Calculate maximal size of packet seen by hard_start_xmit + routine of this device. + */ +static inline unsigned psched_mtu(struct net_device *dev) +{ + unsigned mtu = dev->mtu; + return dev->hard_header ? mtu + dev->hard_header_len : mtu; +} + +#endif diff --git a/release/src/linux/linux/include/net/profile.h b/release/src/linux/linux/include/net/profile.h new file mode 100644 index 00000000..7c8c0f85 --- /dev/null +++ b/release/src/linux/linux/include/net/profile.h @@ -0,0 +1,312 @@ +#include <linux/config.h> /* for CONFIG_NET_PROFILE */ +#ifndef _NET_PROFILE_H_ +#define _NET_PROFILE_H_ 1 + +#ifdef CONFIG_NET_PROFILE + +#include <linux/types.h> +#include <linux/time.h> +#include <linux/kernel.h> +#include <asm/system.h> + +#ifdef CONFIG_X86_TSC +#include <asm/msr.h> +#endif + +struct net_profile_slot +{ + char id[16]; + struct net_profile_slot *next; + struct timeval entered; + struct timeval accumulator; + struct timeval irq; + int hits; + int active; + int underflow; +}; + +extern atomic_t net_profile_active; +extern struct timeval net_profile_adjust; +extern void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved); + +#ifdef CONFIG_X86_TSC + +static inline void net_profile_stamp(struct timeval *pstamp) +{ + rdtsc(pstamp->tv_usec, pstamp->tv_sec); +} + +static inline void net_profile_accumulate(struct timeval *entered, + struct timeval *leaved, + struct timeval *acc) +{ + __asm__ __volatile__ ("subl %2,%0\n\t" + "sbbl %3,%1\n\t" + "addl %4,%0\n\t" + "adcl %5,%1\n\t" + "subl " SYMBOL_NAME_STR(net_profile_adjust) "+4,%0\n\t" + "sbbl $0,%1\n\t" + : "=r" (acc->tv_usec), "=r" (acc->tv_sec) + : "g" (entered->tv_usec), "g" (entered->tv_sec), + "g" (leaved->tv_usec), "g" (leaved->tv_sec), + "0" (acc->tv_usec), "1" (acc->tv_sec)); +} + +static inline void net_profile_sub(struct timeval *sub, + struct timeval *acc) +{ + __asm__ __volatile__ ("subl %2,%0\n\t" + "sbbl %3,%1\n\t" + : "=r" (acc->tv_usec), "=r" (acc->tv_sec) + : "g" (sub->tv_usec), "g" (sub->tv_sec), + "0" (acc->tv_usec), "1" (acc->tv_sec)); +} + +static inline void net_profile_add(struct timeval *add, + struct timeval *acc) +{ + __asm__ __volatile__ ("addl %2,%0\n\t" + "adcl %3,%1\n\t" + : "=r" (acc->tv_usec), "=r" (acc->tv_sec) + : "g" (add->tv_usec), "g" (add->tv_sec), + "0" (acc->tv_usec), "1" (acc->tv_sec)); +} + + +#elif defined(__alpha__) + +extern __u32 alpha_lo; +extern long alpha_hi; + +/* On alpha cycle counter has only 32 bits :-( :-( */ + +static inline void net_profile_stamp(struct timeval *pstamp) +{ + __u32 result; + __asm__ __volatile__ ("rpcc %0" : "r="(result)); + if (result <= alpha_lo) + alpha_hi++; + alpha_lo = result; + pstamp->tv_sec = alpha_hi; + pstamp->tv_usec = alpha_lo; +} + +static inline void net_profile_accumulate(struct timeval *entered, + struct timeval *leaved, + struct timeval *acc) +{ + time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec + - net_profile_adjust.tv_usec; + time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec; + + if (usecs >= 0x100000000L) { + usecs -= 0x100000000L; + secs++; + } else if (usecs < -0x100000000L) { + usecs += 0x200000000L; + secs -= 2; + } else if (usecs < 0) { + usecs += 0x100000000L; + secs--; + } + acc->tv_sec = secs; + acc->tv_usec = usecs; +} + +static inline void net_profile_sub(struct timeval *entered, + struct timeval *leaved) +{ + time_t usecs = leaved->tv_usec - entered->tv_usec; + time_t secs = leaved->tv_sec - entered->tv_sec; + + if (usecs < 0) { + usecs += 0x100000000L; + secs--; + } + leaved->tv_sec = secs; + leaved->tv_usec = usecs; +} + +static inline void net_profile_add(struct timeval *entered, struct timeval *leaved) +{ + time_t usecs = leaved->tv_usec + entered->tv_usec; + time_t secs = leaved->tv_sec + entered->tv_sec; + + if (usecs >= 0x100000000L) { + usecs -= 0x100000000L; + secs++; + } + leaved->tv_sec = secs; + leaved->tv_usec = usecs; +} + + +#else + +static inline void net_profile_stamp(struct timeval *pstamp) +{ + /* Not "fast" counterpart! On architectures without + cpu clock "fast" routine is absolutely useless in this + situation. do_gettimeofday still says something on slow-slow-slow + boxes, though it eats more cpu time than the subject of + investigation :-) :-) + */ + do_gettimeofday(pstamp); +} + +static inline void net_profile_accumulate(struct timeval *entered, + struct timeval *leaved, + struct timeval *acc) +{ + time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec + - net_profile_adjust.tv_usec; + time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec; + + if (usecs >= 1000000) { + usecs -= 1000000; + secs++; + } else if (usecs < -1000000) { + usecs += 2000000; + secs -= 2; + } else if (usecs < 0) { + usecs += 1000000; + secs--; + } + acc->tv_sec = secs; + acc->tv_usec = usecs; +} + +static inline void net_profile_sub(struct timeval *entered, + struct timeval *leaved) +{ + time_t usecs = leaved->tv_usec - entered->tv_usec; + time_t secs = leaved->tv_sec - entered->tv_sec; + + if (usecs < 0) { + usecs += 1000000; + secs--; + } + leaved->tv_sec = secs; + leaved->tv_usec = usecs; +} + +static inline void net_profile_add(struct timeval *entered, struct timeval *leaved) +{ + time_t usecs = leaved->tv_usec + entered->tv_usec; + time_t secs = leaved->tv_sec + entered->tv_sec; + + if (usecs >= 1000000) { + usecs -= 1000000; + secs++; + } + leaved->tv_sec = secs; + leaved->tv_usec = usecs; +} + + + +#endif + +static inline void net_profile_enter(struct net_profile_slot *s) +{ + unsigned long flags; + + save_flags(flags); + cli(); + if (s->active++ == 0) { + net_profile_stamp(&s->entered); + atomic_inc(&net_profile_active); + } + restore_flags(flags); +} + +static inline void net_profile_leave_irq(struct net_profile_slot *s) +{ + unsigned long flags; + + save_flags(flags); + cli(); + if (--s->active <= 0) { + if (s->active == 0) { + struct timeval curr_pstamp; + net_profile_stamp(&curr_pstamp); + net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator); + if (!atomic_dec_and_test(&net_profile_active)) + net_profile_irq_adjust(&s->entered, &curr_pstamp); + } else { + s->underflow++; + } + } + s->hits++; + restore_flags(flags); +} + +static inline void net_profile_leave(struct net_profile_slot *s) +{ + unsigned long flags; + save_flags(flags); + cli(); + if (--s->active <= 0) { + if (s->active == 0) { + struct timeval curr_pstamp; + net_profile_stamp(&curr_pstamp); + net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator); + atomic_dec(&net_profile_active); + } else { + s->underflow++; + } + } + s->hits++; + restore_flags(flags); +} + + +#define NET_PROFILE_ENTER(slot) net_profile_enter(&net_prof_##slot) +#define NET_PROFILE_LEAVE(slot) net_profile_leave(&net_prof_##slot) +#define NET_PROFILE_LEAVE_IRQ(slot) net_profile_leave_irq(&net_prof_##slot) + +#define NET_PROFILE_SKB_CLEAR(skb) ({ \ + skb->pstamp.tv_usec = 0; \ +}) + +#define NET_PROFILE_SKB_INIT(skb) ({ \ + net_profile_stamp(&skb->pstamp); \ +}) + +#define NET_PROFILE_SKB_PASSED(skb, slot) ({ \ + if (skb->pstamp.tv_usec) { \ + struct timeval cur_pstamp = skb->pstamp; \ + net_profile_stamp(&skb->pstamp); \ + net_profile_accumulate(&cur_pstamp, &skb->pstamp, &net_prof_##slot.accumulator); \ + net_prof_##slot.hits++; \ + }}) + +#define NET_PROFILE_DECL(slot) \ + extern struct net_profile_slot net_prof_##slot; + +#define NET_PROFILE_DEFINE(slot) \ + struct net_profile_slot net_prof_##slot = { #slot, }; + +#define NET_PROFILE_REGISTER(slot) net_profile_register(&net_prof_##slot) +#define NET_PROFILE_UNREGISTER(slot) net_profile_unregister(&net_prof_##slot) + +extern int net_profile_init(void); +extern int net_profile_register(struct net_profile_slot *); +extern int net_profile_unregister(struct net_profile_slot *); + +#else + +#define NET_PROFILE_ENTER(slot) do { /* nothing */ } while(0) +#define NET_PROFILE_LEAVE(slot) do { /* nothing */ } while(0) +#define NET_PROFILE_LEAVE_IRQ(slot) do { /* nothing */ } while(0) +#define NET_PROFILE_SKB_CLEAR(skb) do { /* nothing */ } while(0) +#define NET_PROFILE_SKB_INIT(skb) do { /* nothing */ } while(0) +#define NET_PROFILE_SKB_PASSED(skb, slot) do { /* nothing */ } while(0) +#define NET_PROFILE_DECL(slot) +#define NET_PROFILE_DEFINE(slot) +#define NET_PROFILE_REGISTER(slot) do { /* nothing */ } while(0) +#define NET_PROFILE_UNREGISTER(slot) do { /* nothing */ } while(0) + +#endif + +#endif diff --git a/release/src/linux/linux/include/net/protocol.h b/release/src/linux/linux/include/net/protocol.h new file mode 100644 index 00000000..6cd8cb78 --- /dev/null +++ b/release/src/linux/linux/include/net/protocol.h @@ -0,0 +1,108 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the protocol dispatcher. + * + * Version: @(#)protocol.h 1.0.2 05/07/93 + * + * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * + * 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. + * + * Changes: + * Alan Cox : Added a name field and a frag handler + * field for later. + * Alan Cox : Cleaned up, and sorted types. + * Pedro Roque : inet6 protocols + */ + +#ifndef _PROTOCOL_H +#define _PROTOCOL_H + +#include <linux/config.h> +#include <linux/in6.h> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#include <linux/ipv6.h> +#endif + +#define MAX_INET_PROTOS 32 /* Must be a power of 2 */ + + +/* This is used to register protocols. */ +struct inet_protocol +{ + int (*handler)(struct sk_buff *skb); + void (*err_handler)(struct sk_buff *skb, u32 info); + struct inet_protocol *next; + unsigned char protocol; + unsigned char copy:1; + void *data; + const char *name; +}; + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +struct inet6_protocol +{ + int (*handler)(struct sk_buff *skb); + + void (*err_handler)(struct sk_buff *skb, + struct inet6_skb_parm *opt, + int type, int code, int offset, + __u32 info); + struct inet6_protocol *next; + unsigned char protocol; + unsigned char copy:1; + void *data; + const char *name; +}; + +#endif + +/* This is used to register socket interfaces for IP protocols. */ +struct inet_protosw { + struct list_head list; + + /* These two fields form the lookup key. */ + unsigned short type; /* This is the 2nd argument to socket(2). */ + int protocol; /* This is the L4 protocol number. */ + + struct proto *prot; + struct proto_ops *ops; + + int capability; /* Which (if any) capability do + * we need to use this socket + * interface? + */ + char no_check; /* checksum on rcv/xmit/none? */ + unsigned char flags; /* See INET_PROTOSW_* below. */ +}; +#define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ +#define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ + +extern struct inet_protocol *inet_protocol_base; +extern struct inet_protocol *inet_protos[MAX_INET_PROTOS]; +extern struct list_head inetsw[SOCK_MAX]; + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; +extern struct list_head inetsw6[SOCK_MAX]; +#endif + +extern void inet_add_protocol(struct inet_protocol *prot); +extern int inet_del_protocol(struct inet_protocol *prot); +extern void inet_register_protosw(struct inet_protosw *p); +extern void inet_unregister_protosw(struct inet_protosw *p); + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +extern void inet6_add_protocol(struct inet6_protocol *prot); +extern int inet6_del_protocol(struct inet6_protocol *prot); +extern void inet6_register_protosw(struct inet_protosw *p); +extern void inet6_unregister_protosw(struct inet_protosw *p); +#endif + +#endif /* _PROTOCOL_H */ diff --git a/release/src/linux/linux/include/net/psnap.h b/release/src/linux/linux/include/net/psnap.h new file mode 100644 index 00000000..30dbee16 --- /dev/null +++ b/release/src/linux/linux/include/net/psnap.h @@ -0,0 +1,7 @@ +#ifndef _NET_PSNAP_H +#define _NET_PSNAP_H + +extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *)); +extern void unregister_snap_client(unsigned char *desc); + +#endif diff --git a/release/src/linux/linux/include/net/raw.h b/release/src/linux/linux/include/net/raw.h new file mode 100644 index 00000000..00c25f23 --- /dev/null +++ b/release/src/linux/linux/include/net/raw.h @@ -0,0 +1,42 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the RAW-IP module. + * + * Version: @(#)raw.h 1.0.2 05/07/93 + * + * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * + * 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. + */ +#ifndef _RAW_H +#define _RAW_H + + +extern struct proto raw_prot; + + +extern void raw_err(struct sock *, struct sk_buff *, u32 info); +extern int raw_rcv(struct sock *, struct sk_buff *); + +/* Note: v4 ICMP wants to get at this stuff, if you change the + * hashing mechanism, make sure you update icmp.c as well. + */ +#define RAWV4_HTABLE_SIZE MAX_INET_PROTOS +extern struct sock *raw_v4_htable[RAWV4_HTABLE_SIZE]; + +extern rwlock_t raw_v4_lock; + + +extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, + unsigned long raddr, unsigned long laddr, + int dif); + +extern struct sock *raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash); + +#endif /* _RAW_H */ diff --git a/release/src/linux/linux/include/net/rawv6.h b/release/src/linux/linux/include/net/rawv6.h new file mode 100644 index 00000000..c8ddaaa1 --- /dev/null +++ b/release/src/linux/linux/include/net/rawv6.h @@ -0,0 +1,29 @@ +#ifndef _NET_RAWV6_H +#define _NET_RAWV6_H + +#ifdef __KERNEL__ + +#define RAWV6_HTABLE_SIZE MAX_INET_PROTOS +extern struct sock *raw_v6_htable[RAWV6_HTABLE_SIZE]; +extern rwlock_t raw_v6_lock; + +extern struct sock * ipv6_raw_deliver(struct sk_buff *skb, + int nexthdr); + + +extern struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num, + struct in6_addr *loc_addr, struct in6_addr *rmt_addr); + +extern int rawv6_rcv(struct sock *sk, + struct sk_buff *skb); + + +extern void rawv6_err(struct sock *sk, + struct sk_buff *skb, + struct inet6_skb_parm *opt, + int type, int code, + int offset, u32 info); + +#endif + +#endif diff --git a/release/src/linux/linux/include/net/rose.h b/release/src/linux/linux/include/net/rose.h new file mode 100644 index 00000000..f1f893e2 --- /dev/null +++ b/release/src/linux/linux/include/net/rose.h @@ -0,0 +1,239 @@ +/* + * Declarations of Rose type objects. + * + * Jonathan Naylor G4KLX 25/8/96 + */ + +#ifndef _ROSE_H +#define _ROSE_H +#include <linux/rose.h> + +#define ROSE_ADDR_LEN 5 + +#define ROSE_MIN_LEN 3 + +#define ROSE_GFI 0x10 +#define ROSE_Q_BIT 0x80 +#define ROSE_D_BIT 0x40 +#define ROSE_M_BIT 0x10 + +#define ROSE_CALL_REQUEST 0x0B +#define ROSE_CALL_ACCEPTED 0x0F +#define ROSE_CLEAR_REQUEST 0x13 +#define ROSE_CLEAR_CONFIRMATION 0x17 +#define ROSE_DATA 0x00 +#define ROSE_INTERRUPT 0x23 +#define ROSE_INTERRUPT_CONFIRMATION 0x27 +#define ROSE_RR 0x01 +#define ROSE_RNR 0x05 +#define ROSE_REJ 0x09 +#define ROSE_RESET_REQUEST 0x1B +#define ROSE_RESET_CONFIRMATION 0x1F +#define ROSE_REGISTRATION_REQUEST 0xF3 +#define ROSE_REGISTRATION_CONFIRMATION 0xF7 +#define ROSE_RESTART_REQUEST 0xFB +#define ROSE_RESTART_CONFIRMATION 0xFF +#define ROSE_DIAGNOSTIC 0xF1 +#define ROSE_ILLEGAL 0xFD + +/* Define Link State constants. */ + +enum { + ROSE_STATE_0, /* Ready */ + ROSE_STATE_1, /* Awaiting Call Accepted */ + ROSE_STATE_2, /* Awaiting Clear Confirmation */ + ROSE_STATE_3, /* Data Transfer */ + ROSE_STATE_4, /* Awaiting Reset Confirmation */ + ROSE_STATE_5 /* Deferred Call Acceptance */ +}; + +#define ROSE_DEFAULT_T0 (180 * HZ) /* Default T10 T20 value */ +#define ROSE_DEFAULT_T1 (200 * HZ) /* Default T11 T21 value */ +#define ROSE_DEFAULT_T2 (180 * HZ) /* Default T12 T22 value */ +#define ROSE_DEFAULT_T3 (180 * HZ) /* Default T13 T23 value */ +#define ROSE_DEFAULT_HB (5 * HZ) /* Default Holdback value */ +#define ROSE_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */ +#define ROSE_DEFAULT_ROUTING 1 /* Default routing flag */ +#define ROSE_DEFAULT_FAIL_TIMEOUT (120 * HZ) /* Time until link considered usable */ +#define ROSE_DEFAULT_MAXVC 50 /* Maximum number of VCs per neighbour */ +#define ROSE_DEFAULT_WINDOW_SIZE 7 /* Default window size */ + +#define ROSE_MODULUS 8 +#define ROSE_MAX_PACKET_SIZE 251 /* Maximum packet size */ + +#define ROSE_COND_ACK_PENDING 0x01 +#define ROSE_COND_PEER_RX_BUSY 0x02 +#define ROSE_COND_OWN_RX_BUSY 0x04 + +#define FAC_NATIONAL 0x00 +#define FAC_CCITT 0x0F + +#define FAC_NATIONAL_RAND 0x7F +#define FAC_NATIONAL_FLAGS 0x3F +#define FAC_NATIONAL_DEST_DIGI 0xE9 +#define FAC_NATIONAL_SRC_DIGI 0xEB +#define FAC_NATIONAL_FAIL_CALL 0xED +#define FAC_NATIONAL_FAIL_ADD 0xEE +#define FAC_NATIONAL_DIGIS 0xEF + +#define FAC_CCITT_DEST_NSAP 0xC9 +#define FAC_CCITT_SRC_NSAP 0xCB + +struct rose_neigh { + struct rose_neigh *next; + ax25_address callsign; + ax25_digi *digipeat; + ax25_cb *ax25; + struct net_device *dev; + unsigned short count; + unsigned short use; + unsigned int number; + char restarted; + char dce_mode; + char loopback; + struct sk_buff_head queue; + struct timer_list t0timer; + struct timer_list ftimer; +}; + +struct rose_node { + struct rose_node *next; + rose_address address; + unsigned short mask; + unsigned char count; + char loopback; + struct rose_neigh *neighbour[3]; +}; + +struct rose_route { + struct rose_route *next; + unsigned int lci1, lci2; + rose_address src_addr, dest_addr; + ax25_address src_call, dest_call; + struct rose_neigh *neigh1, *neigh2; + unsigned int rand; +}; + +typedef struct { + rose_address source_addr, dest_addr; + ax25_address source_call, dest_call; + unsigned char source_ndigis, dest_ndigis; + ax25_address source_digis[ROSE_MAX_DIGIS]; + ax25_address dest_digis[ROSE_MAX_DIGIS]; + struct rose_neigh *neighbour; + struct net_device *device; + unsigned int lci, rand; + unsigned char state, condition, qbitincl, defer; + unsigned char cause, diagnostic; + unsigned short vs, vr, va, vl; + unsigned long t1, t2, t3, hb, idle; +#ifdef M_BIT + unsigned short fraglen; + struct sk_buff_head frag_queue; +#endif + struct sk_buff_head ack_queue; + struct rose_facilities_struct facilities; + struct timer_list timer; + struct timer_list idletimer; + struct sock *sk; /* Backlink to socket */ +} rose_cb; + +/* af_rose.c */ +extern ax25_address rose_callsign; +extern int sysctl_rose_restart_request_timeout; +extern int sysctl_rose_call_request_timeout; +extern int sysctl_rose_reset_request_timeout; +extern int sysctl_rose_clear_request_timeout; +extern int sysctl_rose_no_activity_timeout; +extern int sysctl_rose_ack_hold_back_timeout; +extern int sysctl_rose_routing_control; +extern int sysctl_rose_link_fail_timeout; +extern int sysctl_rose_maximum_vcs; +extern int sysctl_rose_window_size; +extern int rosecmp(rose_address *, rose_address *); +extern int rosecmpm(rose_address *, rose_address *, unsigned short); +extern char *rose2asc(rose_address *); +extern struct sock *rose_find_socket(unsigned int, struct rose_neigh *); +extern void rose_kill_by_neigh(struct rose_neigh *); +extern unsigned int rose_new_lci(struct rose_neigh *); +extern int rose_rx_call_request(struct sk_buff *, struct net_device *, struct rose_neigh *, unsigned int); +extern void rose_destroy_socket(struct sock *); + +/* rose_dev.c */ +extern int rose_rx_ip(struct sk_buff *, struct net_device *); +extern int rose_init(struct net_device *); + +/* rose_in.c */ +extern int rose_process_rx_frame(struct sock *, struct sk_buff *); + +/* rose_link.c */ +extern void rose_start_ftimer(struct rose_neigh *); +extern void rose_start_t0timer(struct rose_neigh *); +extern void rose_stop_ftimer(struct rose_neigh *); +extern void rose_stop_t0timer(struct rose_neigh *); +extern int rose_ftimer_running(struct rose_neigh *); +extern int rose_t0timer_running(struct rose_neigh *); +extern void rose_link_rx_restart(struct sk_buff *, struct rose_neigh *, unsigned short); +extern void rose_transmit_restart_request(struct rose_neigh *); +extern void rose_transmit_restart_confirmation(struct rose_neigh *); +extern void rose_transmit_diagnostic(struct rose_neigh *, unsigned char); +extern void rose_transmit_clear_request(struct rose_neigh *, unsigned int, unsigned char, unsigned char); +extern void rose_transmit_link(struct sk_buff *, struct rose_neigh *); + +/* rose_loopback.c */ +extern void rose_loopback_init(void); +extern void rose_loopback_clear(void); +extern int rose_loopback_queue(struct sk_buff *, struct rose_neigh *); + +/* rose_out.c */ +extern void rose_kick(struct sock *); +extern void rose_enquiry_response(struct sock *); + +/* rose_route.c */ +extern struct rose_neigh *rose_loopback_neigh; + +extern int rose_add_loopback_neigh(void); +extern int rose_add_loopback_node(rose_address *); +extern void rose_del_loopback_node(rose_address *); +extern void rose_rt_device_down(struct net_device *); +extern void rose_link_device_down(struct net_device *); +extern struct net_device *rose_dev_first(void); +extern struct net_device *rose_dev_get(rose_address *); +extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *); +extern struct net_device *rose_ax25_dev_get(char *); +extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *); +extern int rose_rt_ioctl(unsigned int, void *); +extern void rose_link_failed(ax25_cb *, int); +extern int rose_route_frame(struct sk_buff *, ax25_cb *); +extern int rose_nodes_get_info(char *, char **, off_t, int); +extern int rose_neigh_get_info(char *, char **, off_t, int); +extern int rose_routes_get_info(char *, char **, off_t, int); +extern void rose_rt_free(void); + +/* rose_subr.c */ +extern void rose_clear_queues(struct sock *); +extern void rose_frames_acked(struct sock *, unsigned short); +extern void rose_requeue_frames(struct sock *); +extern int rose_validate_nr(struct sock *, unsigned short); +extern void rose_write_internal(struct sock *, int); +extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); +extern int rose_parse_facilities(unsigned char *, struct rose_facilities_struct *); +extern int rose_create_facilities(unsigned char *, rose_cb *); +extern void rose_disconnect(struct sock *, int, int, int); + +/* rose_timer.c */ +extern void rose_start_heartbeat(struct sock *); +extern void rose_start_t1timer(struct sock *); +extern void rose_start_t2timer(struct sock *); +extern void rose_start_t3timer(struct sock *); +extern void rose_start_hbtimer(struct sock *); +extern void rose_start_idletimer(struct sock *); +extern void rose_stop_heartbeat(struct sock *); +extern void rose_stop_timer(struct sock *); +extern void rose_stop_idletimer(struct sock *); + +/* sysctl_net_rose.c */ +extern void rose_register_sysctl(void); +extern void rose_unregister_sysctl(void); + +#endif diff --git a/release/src/linux/linux/include/net/route.h b/release/src/linux/linux/include/net/route.h new file mode 100644 index 00000000..4f85eb5d --- /dev/null +++ b/release/src/linux/linux/include/net/route.h @@ -0,0 +1,188 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the IP router. + * + * Version: @(#)route.h 1.0.4 05/27/93 + * + * Authors: Ross Biro, <bir7@leland.Stanford.Edu> + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * Fixes: + * Alan Cox : Reformatted. Added ip_rt_local() + * Alan Cox : Support for TCP parameters. + * Alexey Kuznetsov: Major changes for new routing code. + * Mike McLagan : Routing by source + * Robert Olsson : Added rt_cache statistics + * + * 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. + */ +#ifndef _ROUTE_H +#define _ROUTE_H + +#include <linux/config.h> +#include <net/dst.h> +#include <net/inetpeer.h> +#include <linux/in_route.h> +#include <linux/rtnetlink.h> +#include <linux/route.h> +#include <linux/ip.h> +#include <linux/cache.h> + +#ifndef __KERNEL__ +#warning This file is not supposed to be used outside of kernel. +#endif + +#define RTO_ONLINK 0x01 + +#define RTO_CONN 0 +/* RTO_CONN is not used (being alias for 0), but preserved not to break + * some modules referring to it. */ + +#define RT_CONN_FLAGS(sk) (RT_TOS(sk->protinfo.af_inet.tos) | sk->localroute) + +struct rt_key +{ + __u32 dst; + __u32 src; + int iif; + int oif; +#ifdef CONFIG_IP_ROUTE_FWMARK + __u32 fwmark; +#endif + __u8 tos; + __u8 scope; +}; + +struct inet_peer; +struct rtable +{ + union + { + struct dst_entry dst; + struct rtable *rt_next; + } u; + + unsigned rt_flags; + unsigned rt_type; + + __u32 rt_dst; /* Path destination */ + __u32 rt_src; /* Path source */ + int rt_iif; + + /* Info on neighbour */ + __u32 rt_gateway; + + /* Cache lookup keys */ + struct rt_key key; + + /* Miscellaneous cached information */ + __u32 rt_spec_dst; /* RFC1122 specific destination */ + struct inet_peer *peer; /* long-living peer info */ + +#ifdef CONFIG_IP_ROUTE_NAT + __u32 rt_src_map; + __u32 rt_dst_map; +#endif +}; + +struct ip_rt_acct +{ + __u32 o_bytes; + __u32 o_packets; + __u32 i_bytes; + __u32 i_packets; +}; + +struct rt_cache_stat +{ + unsigned int in_hit; + unsigned int in_slow_tot; + unsigned int in_slow_mc; + unsigned int in_no_route; + unsigned int in_brd; + unsigned int in_martian_dst; + unsigned int in_martian_src; + unsigned int out_hit; + unsigned int out_slow_tot; + unsigned int out_slow_mc; + unsigned int gc_total; + unsigned int gc_ignored; + unsigned int gc_goal_miss; + unsigned int gc_dst_overflow; +} ____cacheline_aligned_in_smp; + +extern struct ip_rt_acct *ip_rt_acct; + +struct in_device; +extern void ip_rt_init(void); +extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw, + u32 src, u8 tos, struct net_device *dev); +extern void ip_rt_advice(struct rtable **rp, int advice); +extern void rt_cache_flush(int how); +extern int ip_route_output_key(struct rtable **, const struct rt_key *key); +extern int ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin); +extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu); +extern void ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu); +extern void ip_rt_send_redirect(struct sk_buff *skb); + +extern unsigned inet_addr_type(u32 addr); +extern void ip_rt_multicast_event(struct in_device *); +extern int ip_rt_ioctl(unsigned int cmd, void *arg); +extern void ip_rt_get_source(u8 *src, struct rtable *rt); +extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); + +/* Deprecated: use ip_route_output_key directly */ +static inline int ip_route_output(struct rtable **rp, + u32 daddr, u32 saddr, u32 tos, int oif) +{ + struct rt_key key = { dst:daddr, src:saddr, oif:oif, tos:tos }; + + return ip_route_output_key(rp, &key); +} + + +static inline void ip_rt_put(struct rtable * rt) +{ + if (rt) + dst_release(&rt->u.dst); +} + +#define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3) + +extern __u8 ip_tos2prio[16]; + +static inline char rt_tos2priority(u8 tos) +{ + return ip_tos2prio[IPTOS_TOS(tos)>>1]; +} + +static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif) +{ + int err; + err = ip_route_output(rp, dst, src, tos, oif); + if (err || (dst && src)) + return err; + dst = (*rp)->rt_dst; + src = (*rp)->rt_src; + ip_rt_put(*rp); + *rp = NULL; + return ip_route_output(rp, dst, src, tos, oif); +} + +extern void rt_bind_peer(struct rtable *rt, int create); + +static inline struct inet_peer *rt_get_peer(struct rtable *rt) +{ + if (rt->peer) + return rt->peer; + + rt_bind_peer(rt, 0); + return rt->peer; +} + +#endif /* _ROUTE_H */ diff --git a/release/src/linux/linux/include/net/scm.h b/release/src/linux/linux/include/net/scm.h new file mode 100644 index 00000000..e26b43f5 --- /dev/null +++ b/release/src/linux/linux/include/net/scm.h @@ -0,0 +1,67 @@ +#ifndef __LINUX_NET_SCM_H +#define __LINUX_NET_SCM_H + +/* Well, we should have at least one descriptor open + * to accept passed FDs 8) + */ +#define SCM_MAX_FD (OPEN_MAX-1) + +struct scm_fp_list +{ + int count; + struct file *fp[SCM_MAX_FD]; +}; + +struct scm_cookie +{ + struct ucred creds; /* Skb credentials */ + struct scm_fp_list *fp; /* Passed files */ + unsigned long seq; /* Connection seqno */ +}; + +extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm); +extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm); +extern void __scm_destroy(struct scm_cookie *scm); +extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); + +static __inline__ void scm_destroy(struct scm_cookie *scm) +{ + if (scm && scm->fp) + __scm_destroy(scm); +} + +static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm) +{ + memset(scm, 0, sizeof(*scm)); + scm->creds.uid = current->uid; + scm->creds.gid = current->gid; + scm->creds.pid = current->pid; + if (msg->msg_controllen <= 0) + return 0; + return __scm_send(sock, msg, scm); +} + +static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm, int flags) +{ + if (!msg->msg_control) + { + if (sock->passcred || scm->fp) + msg->msg_flags |= MSG_CTRUNC; + scm_destroy(scm); + return; + } + + if (sock->passcred) + put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds); + + if (!scm->fp) + return; + + scm_detach_fds(msg, scm); +} + + +#endif /* __LINUX_NET_SCM_H */ + diff --git a/release/src/linux/linux/include/net/slhc_vj.h b/release/src/linux/linux/include/net/slhc_vj.h new file mode 100644 index 00000000..3ae8aca5 --- /dev/null +++ b/release/src/linux/linux/include/net/slhc_vj.h @@ -0,0 +1,191 @@ +#ifndef _SLHC_H +#define _SLHC_H +/* + * Definitions for tcp compression routines. + * + * $Header: /home/cvsroot/wrt54g/src/linux/linux/include/net/slhc_vj.h,v 1.1.1.2 2003/10/14 08:09:29 sparq Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + * + * + * modified for KA9Q Internet Software Package by + * Katie Stevens (dkstevens@ucdavis.edu) + * University of California, Davis + * Computing Services + * - 01-31-90 initial adaptation + * + * - Feb 1991 Bill_Simpson@um.cc.umich.edu + * variable number of conversation slots + * allow zero or one slots + * separate routines + * status display + */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowledgment, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + + +#include <linux/ip.h> +#include <linux/tcp.h> + +/* SLIP compression masks for len/vers byte */ +#define SL_TYPE_IP 0x40 +#define SL_TYPE_UNCOMPRESSED_TCP 0x70 +#define SL_TYPE_COMPRESSED_TCP 0x80 +#define SL_TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + +/* + * data type and sizes conversion assumptions: + * + * VJ code KA9Q style generic + * u_char byte_t unsigned char 8 bits + * u_short int16 unsigned short 16 bits + * u_int int16 unsigned short 16 bits + * u_long unsigned long unsigned long 32 bits + * int int32 long 32 bits + */ + +typedef __u8 byte_t; +typedef __u32 int32; + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + byte_t cs_this; /* connection id number (xmit) */ + struct cstate *next; /* next in ring (xmit) */ + struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ + struct tcphdr cs_tcp; + unsigned char cs_ipopt[64]; + unsigned char cs_tcpopt[64]; + int cs_hsize; +}; +#define NULLSLSTATE (struct cstate *)0 + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct slcompress { + struct cstate *tstate; /* transmit connection states (array)*/ + struct cstate *rstate; /* receive connection states (array)*/ + + byte_t tslot_limit; /* highest transmit slot id (0-l)*/ + byte_t rslot_limit; /* highest receive slot id (0-l)*/ + + byte_t xmit_oldest; /* oldest xmit in ring */ + byte_t xmit_current; /* most recent xmit id */ + byte_t recv_current; /* most recent rcvd id */ + + byte_t flags; +#define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ + + int32 sls_o_nontcp; /* outbound non-TCP packets */ + int32 sls_o_tcp; /* outbound TCP packets */ + int32 sls_o_uncompressed; /* outbound uncompressed packets */ + int32 sls_o_compressed; /* outbound compressed packets */ + int32 sls_o_searches; /* searches for connection state */ + int32 sls_o_misses; /* times couldn't find conn. state */ + + int32 sls_i_uncompressed; /* inbound uncompressed packets */ + int32 sls_i_compressed; /* inbound compressed packets */ + int32 sls_i_error; /* inbound error packets */ + int32 sls_i_tossed; /* inbound packets tossed because of error */ + + int32 sls_i_runt; + int32 sls_i_badcheck; +}; +#define NULLSLCOMPR (struct slcompress *)0 + +#define __ARGS(x) x + +/* In slhc.c: */ +struct slcompress *slhc_init __ARGS((int rslots, int tslots)); +void slhc_free __ARGS((struct slcompress *comp)); + +int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp, + int isize, unsigned char *ocp, unsigned char **cpp, + int compress_cid)); +int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp, + int isize)); +int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp, + int isize)); +int slhc_toss __ARGS((struct slcompress *comp)); + +void slhc_i_status __ARGS((struct slcompress *comp)); +void slhc_o_status __ARGS((struct slcompress *comp)); + +#endif /* _SLHC_H */ diff --git a/release/src/linux/linux/include/net/snmp.h b/release/src/linux/linux/include/net/snmp.h new file mode 100644 index 00000000..f1b90926 --- /dev/null +++ b/release/src/linux/linux/include/net/snmp.h @@ -0,0 +1,267 @@ +/* + * + * SNMP MIB entries for the IP subsystem. + * + * Alan Cox <gw4pts@gw4pts.ampr.org> + * + * We don't chose to implement SNMP in the kernel (this would + * be silly as SNMP is a pain in the backside in places). We do + * however need to collect the MIB statistics and export them + * out of /proc (eventually) + * + * 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. + * + * $Id: snmp.h,v 1.1.1.4 2003/10/14 08:09:29 sparq Exp $ + * + */ + +#ifndef _SNMP_H +#define _SNMP_H + +#include <linux/cache.h> + +/* + * We use all unsigned longs. Linux will soon be so reliable that even these + * will rapidly get too small 8-). Seriously consider the IpInReceives count + * on the 20Gb/s + networks people expect in a few years time! + */ + +/* + * The rule for padding: + * Best is power of two because then the right structure can be found by a simple + * shift. The structure should be always cache line aligned. + * gcc needs n=alignto(cachelinesize, popcnt(sizeof(bla_mib))) shift/add instructions + * to emulate multiply in case it is not power-of-two. Currently n is always <=3 for + * all sizes so simple cache line alignment is enough. + * + * The best solution would be a global CPU local area , especially on 64 and 128byte + * cacheline machine it makes a *lot* of sense -AK + */ + + +struct ip_mib +{ + unsigned long IpInReceives; + unsigned long IpInHdrErrors; + unsigned long IpInAddrErrors; + unsigned long IpForwDatagrams; + unsigned long IpInUnknownProtos; + unsigned long IpInDiscards; + unsigned long IpInDelivers; + unsigned long IpOutRequests; + unsigned long IpOutDiscards; + unsigned long IpOutNoRoutes; + unsigned long IpReasmTimeout; + unsigned long IpReasmReqds; + unsigned long IpReasmOKs; + unsigned long IpReasmFails; + unsigned long IpFragOKs; + unsigned long IpFragFails; + unsigned long IpFragCreates; + unsigned long __pad[0]; +} ____cacheline_aligned; + +struct ipv6_mib +{ + unsigned long Ip6InReceives; + unsigned long Ip6InHdrErrors; + unsigned long Ip6InTooBigErrors; + unsigned long Ip6InNoRoutes; + unsigned long Ip6InAddrErrors; + unsigned long Ip6InUnknownProtos; + unsigned long Ip6InTruncatedPkts; + unsigned long Ip6InDiscards; + unsigned long Ip6InDelivers; + unsigned long Ip6OutForwDatagrams; + unsigned long Ip6OutRequests; + unsigned long Ip6OutDiscards; + unsigned long Ip6OutNoRoutes; + unsigned long Ip6ReasmTimeout; + unsigned long Ip6ReasmReqds; + unsigned long Ip6ReasmOKs; + unsigned long Ip6ReasmFails; + unsigned long Ip6FragOKs; + unsigned long Ip6FragFails; + unsigned long Ip6FragCreates; + unsigned long Ip6InMcastPkts; + unsigned long Ip6OutMcastPkts; + unsigned long __pad[0]; +} ____cacheline_aligned; + +struct icmp_mib +{ + unsigned long IcmpInMsgs; + unsigned long IcmpInErrors; + unsigned long IcmpInDestUnreachs; + unsigned long IcmpInTimeExcds; + unsigned long IcmpInParmProbs; + unsigned long IcmpInSrcQuenchs; + unsigned long IcmpInRedirects; + unsigned long IcmpInEchos; + unsigned long IcmpInEchoReps; + unsigned long IcmpInTimestamps; + unsigned long IcmpInTimestampReps; + unsigned long IcmpInAddrMasks; + unsigned long IcmpInAddrMaskReps; + unsigned long IcmpOutMsgs; + unsigned long IcmpOutErrors; + unsigned long IcmpOutDestUnreachs; + unsigned long IcmpOutTimeExcds; + unsigned long IcmpOutParmProbs; + unsigned long IcmpOutSrcQuenchs; + unsigned long IcmpOutRedirects; + unsigned long IcmpOutEchos; + unsigned long IcmpOutEchoReps; + unsigned long IcmpOutTimestamps; + unsigned long IcmpOutTimestampReps; + unsigned long IcmpOutAddrMasks; + unsigned long IcmpOutAddrMaskReps; + unsigned long dummy; + unsigned long __pad[0]; +} ____cacheline_aligned; + +struct icmpv6_mib +{ + unsigned long Icmp6InMsgs; + unsigned long Icmp6InErrors; + + unsigned long Icmp6InDestUnreachs; + unsigned long Icmp6InPktTooBigs; + unsigned long Icmp6InTimeExcds; + unsigned long Icmp6InParmProblems; + + unsigned long Icmp6InEchos; + unsigned long Icmp6InEchoReplies; + unsigned long Icmp6InGroupMembQueries; + unsigned long Icmp6InGroupMembResponses; + unsigned long Icmp6InGroupMembReductions; + unsigned long Icmp6InRouterSolicits; + unsigned long Icmp6InRouterAdvertisements; + unsigned long Icmp6InNeighborSolicits; + unsigned long Icmp6InNeighborAdvertisements; + unsigned long Icmp6InRedirects; + + unsigned long Icmp6OutMsgs; + + unsigned long Icmp6OutDestUnreachs; + unsigned long Icmp6OutPktTooBigs; + unsigned long Icmp6OutTimeExcds; + unsigned long Icmp6OutParmProblems; + + unsigned long Icmp6OutEchoReplies; + unsigned long Icmp6OutRouterSolicits; + unsigned long Icmp6OutNeighborSolicits; + unsigned long Icmp6OutNeighborAdvertisements; + unsigned long Icmp6OutRedirects; + unsigned long Icmp6OutGroupMembResponses; + unsigned long Icmp6OutGroupMembReductions; + unsigned long __pad[0]; +} ____cacheline_aligned; + +struct tcp_mib +{ + unsigned long TcpRtoAlgorithm; + unsigned long TcpRtoMin; + unsigned long TcpRtoMax; + unsigned long TcpMaxConn; + unsigned long TcpActiveOpens; + unsigned long TcpPassiveOpens; + unsigned long TcpAttemptFails; + unsigned long TcpEstabResets; + unsigned long TcpCurrEstab; + unsigned long TcpInSegs; + unsigned long TcpOutSegs; + unsigned long TcpRetransSegs; + unsigned long TcpInErrs; + unsigned long TcpOutRsts; + unsigned long __pad[0]; +} ____cacheline_aligned; + +struct udp_mib +{ + unsigned long UdpInDatagrams; + unsigned long UdpNoPorts; + unsigned long UdpInErrors; + unsigned long UdpOutDatagrams; + unsigned long __pad[0]; +} ____cacheline_aligned; + +struct linux_mib +{ + unsigned long SyncookiesSent; + unsigned long SyncookiesRecv; + unsigned long SyncookiesFailed; + unsigned long EmbryonicRsts; + unsigned long PruneCalled; + unsigned long RcvPruned; + unsigned long OfoPruned; + unsigned long OutOfWindowIcmps; + unsigned long LockDroppedIcmps; + unsigned long ArpFilter; + unsigned long TimeWaited; + unsigned long TimeWaitRecycled; + unsigned long TimeWaitKilled; + unsigned long PAWSPassiveRejected; + unsigned long PAWSActiveRejected; + unsigned long PAWSEstabRejected; + unsigned long DelayedACKs; + unsigned long DelayedACKLocked; + unsigned long DelayedACKLost; + unsigned long ListenOverflows; + unsigned long ListenDrops; + unsigned long TCPPrequeued; + unsigned long TCPDirectCopyFromBacklog; + unsigned long TCPDirectCopyFromPrequeue; + unsigned long TCPPrequeueDropped; + unsigned long TCPHPHits; + unsigned long TCPHPHitsToUser; + unsigned long TCPPureAcks; + unsigned long TCPHPAcks; + unsigned long TCPRenoRecovery; + unsigned long TCPSackRecovery; + unsigned long TCPSACKReneging; + unsigned long TCPFACKReorder; + unsigned long TCPSACKReorder; + unsigned long TCPRenoReorder; + unsigned long TCPTSReorder; + unsigned long TCPFullUndo; + unsigned long TCPPartialUndo; + unsigned long TCPDSACKUndo; + unsigned long TCPLossUndo; + unsigned long TCPLoss; + unsigned long TCPLostRetransmit; + unsigned long TCPRenoFailures; + unsigned long TCPSackFailures; + unsigned long TCPLossFailures; + unsigned long TCPFastRetrans; + unsigned long TCPForwardRetrans; + unsigned long TCPSlowStartRetrans; + unsigned long TCPTimeouts; + unsigned long TCPRenoRecoveryFail; + unsigned long TCPSackRecoveryFail; + unsigned long TCPSchedulerFailed; + unsigned long TCPRcvCollapsed; + unsigned long TCPDSACKOldSent; + unsigned long TCPDSACKOfoSent; + unsigned long TCPDSACKRecv; + unsigned long TCPDSACKOfoRecv; + unsigned long TCPAbortOnSyn; + unsigned long TCPAbortOnData; + unsigned long TCPAbortOnClose; + unsigned long TCPAbortOnMemory; + unsigned long TCPAbortOnTimeout; + unsigned long TCPAbortOnLinger; + unsigned long TCPAbortFailed; + unsigned long TCPMemoryPressures; + unsigned long __pad[0]; +} ____cacheline_aligned; + + +#define SNMP_INC_STATS(mib, field) ((mib)[2*smp_processor_id()+!in_softirq()].field++) +#define SNMP_INC_STATS_BH(mib, field) ((mib)[2*smp_processor_id()].field++) +#define SNMP_INC_STATS_USER(mib, field) ((mib)[2*smp_processor_id()+1].field++) + +#endif diff --git a/release/src/linux/linux/include/net/sock.h b/release/src/linux/linux/include/net/sock.h new file mode 100644 index 00000000..0482a102 --- /dev/null +++ b/release/src/linux/linux/include/net/sock.h @@ -0,0 +1,1297 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the AF_INET socket handler. + * + * Version: @(#)sock.h 1.0.4 05/13/93 + * + * Authors: Ross Biro, <bir7@leland.Stanford.Edu> + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * Corey Minyard <wf-rch!minyard@relay.EU.net> + * Florian La Roche <flla@stud.uni-sb.de> + * + * Fixes: + * Alan Cox : Volatiles in skbuff pointers. See + * skbuff comments. May be overdone, + * better to prove they can be removed + * than the reverse. + * Alan Cox : Added a zapped field for tcp to note + * a socket is reset and must stay shut up + * Alan Cox : New fields for options + * Pauline Middelink : identd support + * Alan Cox : Eliminate low level recv/recvfrom + * David S. Miller : New socket lookup architecture. + * Steve Whitehouse: Default routines for sock_ops + * + * 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. + */ +#ifndef _SOCK_H +#define _SOCK_H + +#include <linux/config.h> +#include <linux/timer.h> +#include <linux/cache.h> +#include <linux/in.h> /* struct sockaddr_in */ + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#include <linux/in6.h> /* struct sockaddr_in6 */ +#include <linux/ipv6.h> /* dest_cache, inet6_options */ +#include <linux/icmpv6.h> +#include <net/if_inet6.h> /* struct ipv6_mc_socklist */ +#endif + +#if defined(CONFIG_INET) || defined(CONFIG_INET_MODULE) +#include <linux/icmp.h> +#endif +#include <linux/tcp.h> /* struct tcphdr */ + +#include <linux/netdevice.h> +#include <linux/skbuff.h> /* struct sk_buff */ +#include <net/protocol.h> /* struct inet_protocol */ +#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) +#include <net/x25.h> +#endif +#if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE) +#include <linux/if_wanpipe.h> +#endif + +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) +#include <net/ax25.h> +#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE) +#include <net/netrom.h> +#endif +#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE) +#include <net/rose.h> +#endif +#endif + +#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE) +#include <linux/if_pppox.h> +#include <linux/ppp_channel.h> /* struct ppp_channel */ +#endif + +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) +#if defined(CONFIG_SPX) || defined(CONFIG_SPX_MODULE) +#include <net/spx.h> +#else +#include <net/ipx.h> +#endif /* CONFIG_SPX */ +#endif /* CONFIG_IPX */ + +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) +#include <linux/atalk.h> +#endif + +#if defined(CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE) +#include <net/dn.h> +#endif + +#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) +#include <net/irda/irda.h> +#endif + +#if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE) +struct atm_vcc; +#endif + +#ifdef CONFIG_FILTER +#include <linux/filter.h> +#endif + +#include <asm/atomic.h> +#include <net/dst.h> + + +/* The AF_UNIX specific socket options */ +struct unix_opt { + struct unix_address *addr; + struct dentry * dentry; + struct vfsmount * mnt; + struct semaphore readsem; + struct sock * other; + struct sock ** list; + struct sock * gc_tree; + atomic_t inflight; + rwlock_t lock; + wait_queue_head_t peer_wait; +}; + + +/* Once the IPX ncpd patches are in these are going into protinfo. */ +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) +struct ipx_opt { + ipx_address dest_addr; + ipx_interface *intrfc; + unsigned short port; +#ifdef CONFIG_IPX_INTERN + unsigned char node[IPX_NODE_LEN]; +#endif + unsigned short type; +/* + * To handle special ncp connection-handling sockets for mars_nwe, + * the connection number must be stored in the socket. + */ + unsigned short ipx_ncp_conn; +}; +#endif + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +struct ipv6_pinfo { + struct in6_addr saddr; + struct in6_addr rcv_saddr; + struct in6_addr daddr; + struct in6_addr *daddr_cache; + + __u32 flow_label; + __u32 frag_size; + int hop_limit; + int mcast_hops; + int mcast_oif; + + /* pktoption flags */ + union { + struct { + __u8 srcrt:2, + rxinfo:1, + rxhlim:1, + hopopts:1, + dstopts:1, + authhdr:1, + rxflow:1; + } bits; + __u8 all; + } rxopt; + + /* sockopt flags */ + __u8 mc_loop:1, + recverr:1, + sndflow:1, + pmtudisc:2; + + struct ipv6_mc_socklist *ipv6_mc_list; + struct ipv6_fl_socklist *ipv6_fl_list; + __u32 dst_cookie; + + struct ipv6_txoptions *opt; + struct sk_buff *pktoptions; +}; + +struct raw6_opt { + __u32 checksum; /* perform checksum */ + __u32 offset; /* checksum offset */ + + struct icmp6_filter filter; +}; + +#endif /* IPV6 */ + +#if defined(CONFIG_INET) || defined(CONFIG_INET_MODULE) +struct raw_opt { + struct icmp_filter filter; +}; +#endif + +#if defined(CONFIG_INET) || defined(CONFIG_INET_MODULE) +struct inet_opt +{ + int ttl; /* TTL setting */ + int tos; /* TOS */ + unsigned cmsg_flags; + struct ip_options *opt; + unsigned char hdrincl; /* Include headers ? */ + __u8 mc_ttl; /* Multicasting TTL */ + __u8 mc_loop; /* Loopback */ + unsigned recverr : 1, + freebind : 1; + __u16 id; /* ID counter for DF pkts */ + __u8 pmtudisc; + int mc_index; /* Multicast device index */ + __u32 mc_addr; + struct ip_mc_socklist *mc_list; /* Group array */ +}; +#endif + +#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE) +struct pppoe_opt +{ + struct net_device *dev; /* device associated with socket*/ + struct pppoe_addr pa; /* what this socket is bound to*/ + struct sockaddr_pppox relay; /* what socket data will be + relayed to (PPPoE relaying) */ +}; + +struct pppox_opt +{ + struct ppp_channel chan; + struct sock *sk; + struct pppox_opt *next; /* for hash table */ + union { + struct pppoe_opt pppoe; + } proto; +}; +#define pppoe_dev proto.pppoe.dev +#define pppoe_pa proto.pppoe.pa +#define pppoe_relay proto.pppoe.relay +#endif + +/* This defines a selective acknowledgement block. */ +struct tcp_sack_block { + __u32 start_seq; + __u32 end_seq; +}; + +struct tcp_opt { + int tcp_header_len; /* Bytes of tcp header to send */ + +/* + * Header prediction flags + * 0x5?10 << 16 + snd_wnd in net byte order + */ + __u32 pred_flags; + +/* + * RFC793 variables by their proper names. This means you can + * read the code and the spec side by side (and laugh ...) + * See RFC793 and RFC1122. The RFC writes these in capitals. + */ + __u32 rcv_nxt; /* What we want to receive next */ + __u32 snd_nxt; /* Next sequence we send */ + + __u32 snd_una; /* First byte we want an ack for */ + __u32 snd_sml; /* Last byte of the most recently transmitted small packet */ + __u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ + __u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ + + /* Delayed ACK control data */ + struct { + __u8 pending; /* ACK is pending */ + __u8 quick; /* Scheduled number of quick acks */ + __u8 pingpong; /* The session is interactive */ + __u8 blocked; /* Delayed ACK was blocked by socket lock*/ + __u32 ato; /* Predicted tick of soft clock */ + unsigned long timeout; /* Currently scheduled timeout */ + __u32 lrcvtime; /* timestamp of last received data packet*/ + __u16 last_seg_size; /* Size of last incoming segment */ + __u16 rcv_mss; /* MSS used for delayed ACK decisions */ + } ack; + + /* Data for direct copy to user */ + struct { + struct sk_buff_head prequeue; + struct task_struct *task; + struct iovec *iov; + int memory; + int len; + } ucopy; + + __u32 snd_wl1; /* Sequence for window update */ + __u32 snd_wnd; /* The window we expect to receive */ + __u32 max_window; /* Maximal window ever seen from peer */ + __u32 pmtu_cookie; /* Last pmtu seen by socket */ + __u16 mss_cache; /* Cached effective mss, not including SACKS */ + __u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ + __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ + __u8 ca_state; /* State of fast-retransmit machine */ + __u8 retransmits; /* Number of unrecovered RTO timeouts. */ + + __u8 reordering; /* Packet reordering metric. */ + __u8 queue_shrunk; /* Write queue has been shrunk recently.*/ + __u8 defer_accept; /* User waits for some data after accept() */ + +/* RTT measurement */ + __u8 backoff; /* backoff */ + __u32 srtt; /* smothed round trip time << 3 */ + __u32 mdev; /* medium deviation */ + __u32 mdev_max; /* maximal mdev for the last rtt period */ + __u32 rttvar; /* smoothed mdev_max */ + __u32 rtt_seq; /* sequence number to update rttvar */ + __u32 rto; /* retransmit timeout */ + + __u32 packets_out; /* Packets which are "in flight" */ + __u32 left_out; /* Packets which leaved network */ + __u32 retrans_out; /* Retransmitted packets out */ + + +/* + * Slow start and congestion control (see also Nagle, and Karn & Partridge) + */ + __u32 snd_ssthresh; /* Slow start size threshold */ + __u32 snd_cwnd; /* Sending congestion window */ + __u16 snd_cwnd_cnt; /* Linear increase counter */ + __u16 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */ + __u32 snd_cwnd_used; + __u32 snd_cwnd_stamp; + + /* Two commonly used timers in both sender and receiver paths. */ + unsigned long timeout; + struct timer_list retransmit_timer; /* Resend (no ack) */ + struct timer_list delack_timer; /* Ack delay */ + + struct sk_buff_head out_of_order_queue; /* Out of order segments go here */ + + struct tcp_func *af_specific; /* Operations which are AF_INET{4,6} specific */ + struct sk_buff *send_head; /* Front of stuff to transmit */ + struct page *sndmsg_page; /* Cached page for sendmsg */ + u32 sndmsg_off; /* Cached offset for sendmsg */ + + __u32 rcv_wnd; /* Current receiver window */ + __u32 rcv_wup; /* rcv_nxt on last window update sent */ + __u32 write_seq; /* Tail(+1) of data held in tcp send buffer */ + __u32 pushed_seq; /* Last pushed seq, required to talk to windows */ + __u32 copied_seq; /* Head of yet unread data */ +/* + * Options received (usually on last packet, some only on SYN packets). + */ + char tstamp_ok, /* TIMESTAMP seen on SYN packet */ + wscale_ok, /* Wscale seen on SYN packet */ + sack_ok; /* SACK seen on SYN packet */ + char saw_tstamp; /* Saw TIMESTAMP on last packet */ + __u8 snd_wscale; /* Window scaling received from sender */ + __u8 rcv_wscale; /* Window scaling to send to receiver */ + __u8 nonagle; /* Disable Nagle algorithm? */ + __u8 keepalive_probes; /* num of allowed keep alive probes */ + +/* PAWS/RTTM data */ + __u32 rcv_tsval; /* Time stamp value */ + __u32 rcv_tsecr; /* Time stamp echo reply */ + __u32 ts_recent; /* Time stamp to echo next */ + long ts_recent_stamp;/* Time we stored ts_recent (for aging) */ + +/* SACKs data */ + __u16 user_mss; /* mss requested by user in ioctl */ + __u8 dsack; /* D-SACK is scheduled */ + __u8 eff_sacks; /* Size of SACK array to send with next packet */ + struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */ + struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/ + + __u32 window_clamp; /* Maximal window to advertise */ + __u32 rcv_ssthresh; /* Current window clamp */ + __u8 probes_out; /* unanswered 0 window probes */ + __u8 num_sacks; /* Number of SACK blocks */ + __u16 advmss; /* Advertised MSS */ + + __u8 syn_retries; /* num of allowed syn retries */ + __u8 ecn_flags; /* ECN status bits. */ + __u16 prior_ssthresh; /* ssthresh saved at recovery start */ + __u32 lost_out; /* Lost packets */ + __u32 sacked_out; /* SACK'd packets */ + __u32 fackets_out; /* FACK'd packets */ + __u32 high_seq; /* snd_nxt at onset of congestion */ + + __u32 retrans_stamp; /* Timestamp of the last retransmit, + * also used in SYN-SENT to remember stamp of + * the first SYN. */ + __u32 undo_marker; /* tracking retrans started here. */ + int undo_retrans; /* number of undoable retransmissions. */ + __u32 urg_seq; /* Seq of received urgent pointer */ + __u16 urg_data; /* Saved octet of OOB data and control flags */ + __u8 pending; /* Scheduled timer event */ + __u8 urg_mode; /* In urgent mode */ + __u32 snd_up; /* Urgent pointer */ + + /* The syn_wait_lock is necessary only to avoid tcp_get_info having + * to grab the main lock sock while browsing the listening hash + * (otherwise it's deadlock prone). + * This lock is acquired in read mode only from tcp_get_info() and + * it's acquired in write mode _only_ from code that is actively + * changing the syn_wait_queue. All readers that are holding + * the master sock lock don't need to grab this lock in read mode + * too as the syn_wait_queue writes are always protected from + * the main sock lock. + */ + rwlock_t syn_wait_lock; + struct tcp_listen_opt *listen_opt; + + /* FIFO of established children */ + struct open_request *accept_queue; + struct open_request *accept_queue_tail; + + int write_pending; /* A write to socket waits to start. */ + + unsigned int keepalive_time; /* time before keep alive takes place */ + unsigned int keepalive_intvl; /* time interval between keep alive probes */ + int linger2; + + unsigned long last_synq_overflow; +}; + + +/* + * This structure really needs to be cleaned up. + * Most of it is for TCP, and not used by any of + * the other protocols. + */ + +/* + * The idea is to start moving to a newer struct gradualy + * + * IMHO the newer struct should have the following format: + * + * struct sock { + * sockmem [mem, proto, callbacks] + * + * union or struct { + * ax25; + * } ll_pinfo; + * + * union { + * ipv4; + * ipv6; + * ipx; + * netrom; + * rose; + * x25; + * } net_pinfo; + * + * union { + * tcp; + * udp; + * spx; + * netrom; + * } tp_pinfo; + * + * } + * + * The idea failed because IPv6 transition asssumes dual IP/IPv6 sockets. + * So, net_pinfo is IPv6 are really, and protinfo unifies all another + * private areas. + */ + +/* Define this to get the sk->debug debugging facility. */ +#define SOCK_DEBUGGING +#ifdef SOCK_DEBUGGING +#define SOCK_DEBUG(sk, msg...) do { if((sk) && ((sk)->debug)) printk(KERN_DEBUG msg); } while (0) +#else +#define SOCK_DEBUG(sk, msg...) do { } while (0) +#endif + +/* This is the per-socket lock. The spinlock provides a synchronization + * between user contexts and software interrupt processing, whereas the + * mini-semaphore synchronizes multiple users amongst themselves. + */ +typedef struct { + spinlock_t slock; + unsigned int users; + wait_queue_head_t wq; +} socket_lock_t; + +#define sock_lock_init(__sk) \ +do { spin_lock_init(&((__sk)->lock.slock)); \ + (__sk)->lock.users = 0; \ + init_waitqueue_head(&((__sk)->lock.wq)); \ +} while(0) + +struct sock { + /* Socket demultiplex comparisons on incoming packets. */ + __u32 daddr; /* Foreign IPv4 addr */ + __u32 rcv_saddr; /* Bound local IPv4 addr */ + __u16 dport; /* Destination port */ + unsigned short num; /* Local port */ + int bound_dev_if; /* Bound device index if != 0 */ + + /* Main hash linkage for various protocol lookup tables. */ + struct sock *next; + struct sock **pprev; + struct sock *bind_next; + struct sock **bind_pprev; + + volatile unsigned char state, /* Connection state */ + zapped; /* In ax25 & ipx means not linked */ + __u16 sport; /* Source port */ + + unsigned short family; /* Address family */ + unsigned char reuse; /* SO_REUSEADDR setting */ + unsigned char shutdown; + atomic_t refcnt; /* Reference count */ + + socket_lock_t lock; /* Synchronizer... */ + int rcvbuf; /* Size of receive buffer in bytes */ + + wait_queue_head_t *sleep; /* Sock wait queue */ + struct dst_entry *dst_cache; /* Destination cache */ + rwlock_t dst_lock; + atomic_t rmem_alloc; /* Receive queue bytes committed */ + struct sk_buff_head receive_queue; /* Incoming packets */ + atomic_t wmem_alloc; /* Transmit queue bytes committed */ + struct sk_buff_head write_queue; /* Packet sending queue */ + atomic_t omem_alloc; /* "o" is "option" or "other" */ + int wmem_queued; /* Persistent queue size */ + int forward_alloc; /* Space allocated forward. */ + __u32 saddr; /* Sending source */ + unsigned int allocation; /* Allocation mode */ + int sndbuf; /* Size of send buffer in bytes */ + struct sock *prev; + + volatile char dead, + done, + urginline, + keepopen, + linger, + destroy, + no_check, + broadcast, + bsdism; + unsigned char debug; + unsigned char rcvtstamp; + unsigned char use_write_queue; + unsigned char userlocks; + /* Hole of 3 bytes. Try to pack. */ + int route_caps; + int proc; + unsigned long lingertime; + + int hashent; + struct sock *pair; + + /* The backlog queue is special, it is always used with + * the per-socket spinlock held and requires low latency + * access. Therefore we special case it's implementation. + */ + struct { + struct sk_buff *head; + struct sk_buff *tail; + } backlog; + + rwlock_t callback_lock; + + /* Error queue, rarely used. */ + struct sk_buff_head error_queue; + + struct proto *prot; + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + union { + struct ipv6_pinfo af_inet6; + } net_pinfo; +#endif + + union { + struct tcp_opt af_tcp; +#if defined(CONFIG_INET) || defined(CONFIG_INET_MODULE) + struct raw_opt tp_raw4; +#endif +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct raw6_opt tp_raw; +#endif /* CONFIG_IPV6 */ +#if defined(CONFIG_SPX) || defined(CONFIG_SPX_MODULE) + struct spx_opt af_spx; +#endif /* CONFIG_SPX */ + + } tp_pinfo; + + int err, err_soft; /* Soft holds errors that don't + cause failure but are the cause + of a persistent failure not just + 'timed out' */ + unsigned short ack_backlog; + unsigned short max_ack_backlog; + __u32 priority; + unsigned short type; + unsigned char localroute; /* Route locally only */ + unsigned char protocol; + struct ucred peercred; + int rcvlowat; + long rcvtimeo; + long sndtimeo; + +#ifdef CONFIG_FILTER + /* Socket Filtering Instructions */ + struct sk_filter *filter; +#endif /* CONFIG_FILTER */ + + /* This is where all the private (optional) areas that don't + * overlap will eventually live. + */ + union { + void *destruct_hook; + struct unix_opt af_unix; +#if defined(CONFIG_INET) || defined(CONFIG_INET_MODULE) + struct inet_opt af_inet; +#endif +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) + struct atalk_sock af_at; +#endif +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) + struct ipx_opt af_ipx; +#endif +#if defined(CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE) + struct dn_scp dn; +#endif +#if defined(CONFIG_PACKET) || defined(CONFIG_PACKET_MODULE) + struct packet_opt *af_packet; +#endif +#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) + x25_cb *x25; +#endif +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) + ax25_cb *ax25; +#endif +#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE) + nr_cb *nr; +#endif +#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE) + rose_cb *rose; +#endif +#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE) + struct pppox_opt *pppox; +#endif + struct netlink_opt *af_netlink; +#if defined(CONFIG_ECONET) || defined(CONFIG_ECONET_MODULE) + struct econet_opt *af_econet; +#endif +#if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE) + struct atm_vcc *af_atm; +#endif +#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) + struct irda_sock *irda; +#endif +#if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE) + struct wanpipe_opt *af_wanpipe; +#endif + } protinfo; + + + /* This part is used for the timeout functions. */ + struct timer_list timer; /* This is the sock cleanup timer. */ + struct timeval stamp; + + /* Identd and reporting IO signals */ + struct socket *socket; + + /* RPC layer private data */ + void *user_data; + + /* Callbacks */ + void (*state_change)(struct sock *sk); + void (*data_ready)(struct sock *sk,int bytes); + void (*write_space)(struct sock *sk); + void (*error_report)(struct sock *sk); + + int (*backlog_rcv) (struct sock *sk, + struct sk_buff *skb); + void (*destruct)(struct sock *sk); +}; + +/* The per-socket spinlock must be held here. */ +#define sk_add_backlog(__sk, __skb) \ +do { if((__sk)->backlog.tail == NULL) { \ + (__sk)->backlog.head = \ + (__sk)->backlog.tail = (__skb); \ + } else { \ + ((__sk)->backlog.tail)->next = (__skb); \ + (__sk)->backlog.tail = (__skb); \ + } \ + (__skb)->next = NULL; \ +} while(0) + +/* IP protocol blocks we attach to sockets. + * socket layer -> transport layer interface + * transport -> network interface is defined by struct inet_proto + */ +struct proto { + void (*close)(struct sock *sk, + long timeout); + int (*connect)(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + int (*disconnect)(struct sock *sk, int flags); + + struct sock * (*accept) (struct sock *sk, int flags, int *err); + + int (*ioctl)(struct sock *sk, int cmd, + unsigned long arg); + int (*init)(struct sock *sk); + int (*destroy)(struct sock *sk); + void (*shutdown)(struct sock *sk, int how); + int (*setsockopt)(struct sock *sk, int level, + int optname, char *optval, int optlen); + int (*getsockopt)(struct sock *sk, int level, + int optname, char *optval, + int *option); + int (*sendmsg)(struct sock *sk, struct msghdr *msg, + int len); + int (*recvmsg)(struct sock *sk, struct msghdr *msg, + int len, int noblock, int flags, + int *addr_len); + int (*bind)(struct sock *sk, + struct sockaddr *uaddr, int addr_len); + + int (*backlog_rcv) (struct sock *sk, + struct sk_buff *skb); + + /* Keeping track of sk's, looking them up, and port selection methods. */ + void (*hash)(struct sock *sk); + void (*unhash)(struct sock *sk); + int (*get_port)(struct sock *sk, unsigned short snum); + + char name[32]; + + struct { + int inuse; + u8 __pad[SMP_CACHE_BYTES - sizeof(int)]; + } stats[NR_CPUS]; +}; + +/* Called with local bh disabled */ +static __inline__ void sock_prot_inc_use(struct proto *prot) +{ + prot->stats[smp_processor_id()].inuse++; +} + +static __inline__ void sock_prot_dec_use(struct proto *prot) +{ + prot->stats[smp_processor_id()].inuse--; +} + +/* About 10 seconds */ +#define SOCK_DESTROY_TIME (10*HZ) + +/* Sockets 0-1023 can't be bound to unless you are superuser */ +#define PROT_SOCK 1024 + +#define SHUTDOWN_MASK 3 +#define RCV_SHUTDOWN 1 +#define SEND_SHUTDOWN 2 + +#define SOCK_SNDBUF_LOCK 1 +#define SOCK_RCVBUF_LOCK 2 +#define SOCK_BINDADDR_LOCK 4 +#define SOCK_BINDPORT_LOCK 8 + + +/* Used by processes to "lock" a socket state, so that + * interrupts and bottom half handlers won't change it + * from under us. It essentially blocks any incoming + * packets, so that we won't get any new data or any + * packets that change the state of the socket. + * + * While locked, BH processing will add new packets to + * the backlog queue. This queue is processed by the + * owner of the socket lock right before it is released. + * + * Since ~2.3.5 it is also exclusive sleep lock serializing + * accesses from user process context. + */ +extern void __lock_sock(struct sock *sk); +extern void __release_sock(struct sock *sk); +#define lock_sock(__sk) \ +do { spin_lock_bh(&((__sk)->lock.slock)); \ + if ((__sk)->lock.users != 0) \ + __lock_sock(__sk); \ + (__sk)->lock.users = 1; \ + spin_unlock_bh(&((__sk)->lock.slock)); \ +} while(0) + +#define release_sock(__sk) \ +do { spin_lock_bh(&((__sk)->lock.slock)); \ + if ((__sk)->backlog.tail != NULL) \ + __release_sock(__sk); \ + (__sk)->lock.users = 0; \ + if (waitqueue_active(&((__sk)->lock.wq))) wake_up(&((__sk)->lock.wq)); \ + spin_unlock_bh(&((__sk)->lock.slock)); \ +} while(0) + +/* BH context may only use the following locking interface. */ +#define bh_lock_sock(__sk) spin_lock(&((__sk)->lock.slock)) +#define bh_unlock_sock(__sk) spin_unlock(&((__sk)->lock.slock)) + +extern struct sock * sk_alloc(int family, int priority, int zero_it); +extern void sk_free(struct sock *sk); + +extern struct sk_buff *sock_wmalloc(struct sock *sk, + unsigned long size, int force, + int priority); +extern struct sk_buff *sock_rmalloc(struct sock *sk, + unsigned long size, int force, + int priority); +extern void sock_wfree(struct sk_buff *skb); +extern void sock_rfree(struct sk_buff *skb); + +extern int sock_setsockopt(struct socket *sock, int level, + int op, char *optval, + int optlen); + +extern int sock_getsockopt(struct socket *sock, int level, + int op, char *optval, + int *optlen); +extern struct sk_buff *sock_alloc_send_skb(struct sock *sk, + unsigned long size, + int noblock, + int *errcode); +extern struct sk_buff *sock_alloc_send_pskb(struct sock *sk, + unsigned long header_len, + unsigned long data_len, + int noblock, + int *errcode); +extern void *sock_kmalloc(struct sock *sk, int size, int priority); +extern void sock_kfree_s(struct sock *sk, void *mem, int size); + +/* + * Functions to fill in entries in struct proto_ops when a protocol + * does not implement a particular function. + */ +extern int sock_no_release(struct socket *); +extern int sock_no_bind(struct socket *, + struct sockaddr *, int); +extern int sock_no_connect(struct socket *, + struct sockaddr *, int, int); +extern int sock_no_socketpair(struct socket *, + struct socket *); +extern int sock_no_accept(struct socket *, + struct socket *, int); +extern int sock_no_getname(struct socket *, + struct sockaddr *, int *, int); +extern unsigned int sock_no_poll(struct file *, struct socket *, + struct poll_table_struct *); +extern int sock_no_ioctl(struct socket *, unsigned int, + unsigned long); +extern int sock_no_listen(struct socket *, int); +extern int sock_no_shutdown(struct socket *, int); +extern int sock_no_getsockopt(struct socket *, int , int, + char *, int *); +extern int sock_no_setsockopt(struct socket *, int, int, + char *, int); +extern int sock_no_fcntl(struct socket *, + unsigned int, unsigned long); +extern int sock_no_sendmsg(struct socket *, + struct msghdr *, int, + struct scm_cookie *); +extern int sock_no_recvmsg(struct socket *, + struct msghdr *, int, int, + struct scm_cookie *); +extern int sock_no_mmap(struct file *file, + struct socket *sock, + struct vm_area_struct *vma); +extern ssize_t sock_no_sendpage(struct socket *sock, + struct page *page, + int offset, size_t size, + int flags); + +/* + * Default socket callbacks and setup code + */ + +extern void sock_def_destruct(struct sock *); + +/* Initialise core socket variables */ +extern void sock_init_data(struct socket *sock, struct sock *sk); + +extern void sklist_remove_socket(struct sock **list, struct sock *sk); +extern void sklist_insert_socket(struct sock **list, struct sock *sk); +extern void sklist_destroy_socket(struct sock **list, struct sock *sk); + +#ifdef CONFIG_FILTER + +/** + * sk_filter - run a packet through a socket filter + * @skb: buffer to filter + * @filter: filter to apply + * + * Run the filter code and then cut skb->data to correct size returned by + * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller + * than pkt_len we keep whole skb->data. This is the socket level + * wrapper to sk_run_filter. It returns 0 if the packet should + * be accepted or 1 if the packet should be tossed. + */ + +static inline int sk_filter(struct sk_buff *skb, struct sk_filter *filter) +{ + int pkt_len; + + pkt_len = sk_run_filter(skb, filter->insns, filter->len); + if(!pkt_len) + return 1; /* Toss Packet */ + else + skb_trim(skb, pkt_len); + + return 0; +} + +/** + * sk_filter_release: Release a socket filter + * @sk: socket + * @fp: filter to remove + * + * Remove a filter from a socket and release its resources. + */ + +static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) +{ + unsigned int size = sk_filter_len(fp); + + atomic_sub(size, &sk->omem_alloc); + + if (atomic_dec_and_test(&fp->refcnt)) + kfree(fp); +} + +static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) +{ + atomic_inc(&fp->refcnt); + atomic_add(sk_filter_len(fp), &sk->omem_alloc); +} + +#endif /* CONFIG_FILTER */ + +/* + * Socket reference counting postulates. + * + * * Each user of socket SHOULD hold a reference count. + * * Each access point to socket (an hash table bucket, reference from a list, + * running timer, skb in flight MUST hold a reference count. + * * When reference count hits 0, it means it will never increase back. + * * When reference count hits 0, it means that no references from + * outside exist to this socket and current process on current CPU + * is last user and may/should destroy this socket. + * * sk_free is called from any context: process, BH, IRQ. When + * it is called, socket has no references from outside -> sk_free + * may release descendant resources allocated by the socket, but + * to the time when it is called, socket is NOT referenced by any + * hash tables, lists etc. + * * Packets, delivered from outside (from network or from another process) + * and enqueued on receive/error queues SHOULD NOT grab reference count, + * when they sit in queue. Otherwise, packets will leak to hole, when + * socket is looked up by one cpu and unhasing is made by another CPU. + * It is true for udp/raw, netlink (leak to receive and error queues), tcp + * (leak to backlog). Packet socket does all the processing inside + * BR_NETPROTO_LOCK, so that it has not this race condition. UNIX sockets + * use separate SMP lock, so that they are prone too. + */ + +/* Grab socket reference count. This operation is valid only + when sk is ALREADY grabbed f.e. it is found in hash table + or a list and the lookup is made under lock preventing hash table + modifications. + */ + +static inline void sock_hold(struct sock *sk) +{ + atomic_inc(&sk->refcnt); +} + +/* Ungrab socket in the context, which assumes that socket refcnt + cannot hit zero, f.e. it is true in context of any socketcall. + */ +static inline void __sock_put(struct sock *sk) +{ + atomic_dec(&sk->refcnt); +} + +/* Ungrab socket and destroy it, if it was the last reference. */ +static inline void sock_put(struct sock *sk) +{ + if (atomic_dec_and_test(&sk->refcnt)) + sk_free(sk); +} + +/* Detach socket from process context. + * Announce socket dead, detach it from wait queue and inode. + * Note that parent inode held reference count on this struct sock, + * we do not release it in this function, because protocol + * probably wants some additional cleanups or even continuing + * to work with this socket (TCP). + */ +static inline void sock_orphan(struct sock *sk) +{ + write_lock_bh(&sk->callback_lock); + sk->dead = 1; + sk->socket = NULL; + sk->sleep = NULL; + write_unlock_bh(&sk->callback_lock); +} + +static inline void sock_graft(struct sock *sk, struct socket *parent) +{ + write_lock_bh(&sk->callback_lock); + sk->sleep = &parent->wait; + parent->sk = sk; + sk->socket = parent; + write_unlock_bh(&sk->callback_lock); +} + +static inline int sock_i_uid(struct sock *sk) +{ + int uid; + + read_lock(&sk->callback_lock); + uid = sk->socket ? sk->socket->inode->i_uid : 0; + read_unlock(&sk->callback_lock); + return uid; +} + +static inline unsigned long sock_i_ino(struct sock *sk) +{ + unsigned long ino; + + read_lock(&sk->callback_lock); + ino = sk->socket ? sk->socket->inode->i_ino : 0; + read_unlock(&sk->callback_lock); + return ino; +} + +static inline struct dst_entry * +__sk_dst_get(struct sock *sk) +{ + return sk->dst_cache; +} + +static inline struct dst_entry * +sk_dst_get(struct sock *sk) +{ + struct dst_entry *dst; + + read_lock(&sk->dst_lock); + dst = sk->dst_cache; + if (dst) + dst_hold(dst); + read_unlock(&sk->dst_lock); + return dst; +} + +static inline void +__sk_dst_set(struct sock *sk, struct dst_entry *dst) +{ + struct dst_entry *old_dst; + + old_dst = sk->dst_cache; + sk->dst_cache = dst; + dst_release(old_dst); +} + +static inline void +sk_dst_set(struct sock *sk, struct dst_entry *dst) +{ + write_lock(&sk->dst_lock); + __sk_dst_set(sk, dst); + write_unlock(&sk->dst_lock); +} + +static inline void +__sk_dst_reset(struct sock *sk) +{ + struct dst_entry *old_dst; + + old_dst = sk->dst_cache; + sk->dst_cache = NULL; + dst_release(old_dst); +} + +static inline void +sk_dst_reset(struct sock *sk) +{ + write_lock(&sk->dst_lock); + __sk_dst_reset(sk); + write_unlock(&sk->dst_lock); +} + +static inline struct dst_entry * +__sk_dst_check(struct sock *sk, u32 cookie) +{ + struct dst_entry *dst = sk->dst_cache; + + if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { + sk->dst_cache = NULL; + return NULL; + } + + return dst; +} + +static inline struct dst_entry * +sk_dst_check(struct sock *sk, u32 cookie) +{ + struct dst_entry *dst = sk_dst_get(sk); + + if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { + sk_dst_reset(sk); + return NULL; + } + + return dst; +} + + +/* + * Queue a received datagram if it will fit. Stream and sequenced + * protocols can't normally use this as they need to fit buffers in + * and play with them. + * + * Inlined as it's very short and called for pretty much every + * packet ever received. + */ + +static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) +{ + sock_hold(sk); + skb->sk = sk; + skb->destructor = sock_wfree; + atomic_add(skb->truesize, &sk->wmem_alloc); +} + +static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) +{ + skb->sk = sk; + skb->destructor = sock_rfree; + atomic_add(skb->truesize, &sk->rmem_alloc); +} + +static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) +{ + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces + number of warnings when compiling with -W --ANK + */ + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) + return -ENOMEM; + +#ifdef CONFIG_FILTER + if (sk->filter) { + int err = 0; + struct sk_filter *filter; + + /* It would be deadlock, if sock_queue_rcv_skb is used + with socket lock! We assume that users of this + function are lock free. + */ + bh_lock_sock(sk); + if ((filter = sk->filter) != NULL && sk_filter(skb, filter)) + err = -EPERM; + bh_unlock_sock(sk); + if (err) + return err; /* Toss packet */ + } +#endif /* CONFIG_FILTER */ + + skb->dev = NULL; + skb_set_owner_r(skb, sk); + skb_queue_tail(&sk->receive_queue, skb); + if (!sk->dead) + sk->data_ready(sk,skb->len); + return 0; +} + +static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) +{ + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces + number of warnings when compiling with -W --ANK + */ + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) + return -ENOMEM; + skb_set_owner_r(skb, sk); + skb_queue_tail(&sk->error_queue,skb); + if (!sk->dead) + sk->data_ready(sk,skb->len); + return 0; +} + +/* + * Recover an error report and clear atomically + */ + +static inline int sock_error(struct sock *sk) +{ + int err=xchg(&sk->err,0); + return -err; +} + +static inline unsigned long sock_wspace(struct sock *sk) +{ + int amt = 0; + + if (!(sk->shutdown & SEND_SHUTDOWN)) { + amt = sk->sndbuf - atomic_read(&sk->wmem_alloc); + if (amt < 0) + amt = 0; + } + return amt; +} + +static inline void sk_wake_async(struct sock *sk, int how, int band) +{ + if (sk->socket && sk->socket->fasync_list) + sock_wake_async(sk->socket, how, band); +} + +#define SOCK_MIN_SNDBUF 2048 +#define SOCK_MIN_RCVBUF 256 + +/* + * Default write policy as shown to user space via poll/select/SIGIO + */ +static inline int sock_writeable(struct sock *sk) +{ + return atomic_read(&sk->wmem_alloc) < (sk->sndbuf / 2); +} + +static inline int gfp_any(void) +{ + return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; +} + +static inline long sock_rcvtimeo(struct sock *sk, int noblock) +{ + return noblock ? 0 : sk->rcvtimeo; +} + +static inline long sock_sndtimeo(struct sock *sk, int noblock) +{ + return noblock ? 0 : sk->sndtimeo; +} + +static inline int sock_rcvlowat(struct sock *sk, int waitall, int len) +{ + return (waitall ? len : min_t(int, sk->rcvlowat, len)) ? : 1; +} + +/* Alas, with timeout socket operations are not restartable. + * Compare this to poll(). + */ +static inline int sock_intr_errno(long timeo) +{ + return timeo == MAX_SCHEDULE_TIMEOUT ? -ERESTARTSYS : -EINTR; +} + +static __inline__ void +sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) +{ + if (sk->rcvtstamp) + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(skb->stamp), &skb->stamp); + else + sk->stamp = skb->stamp; +} + +/* + * Enable debug/info messages + */ + +#define NETDEBUG(x) do { x; } while (0) + +/* + * Macros for sleeping on a socket. Use them like this: + * + * SOCK_SLEEP_PRE(sk) + * if (condition) + * schedule(); + * SOCK_SLEEP_POST(sk) + * + */ + +#define SOCK_SLEEP_PRE(sk) { struct task_struct *tsk = current; \ + DECLARE_WAITQUEUE(wait, tsk); \ + tsk->state = TASK_INTERRUPTIBLE; \ + add_wait_queue((sk)->sleep, &wait); \ + release_sock(sk); + +#define SOCK_SLEEP_POST(sk) tsk->state = TASK_RUNNING; \ + remove_wait_queue((sk)->sleep, &wait); \ + lock_sock(sk); \ + } + +extern __u32 sysctl_wmem_max; +extern __u32 sysctl_rmem_max; + +#endif /* _SOCK_H */ diff --git a/release/src/linux/linux/include/net/spx.h b/release/src/linux/linux/include/net/spx.h new file mode 100644 index 00000000..a449b891 --- /dev/null +++ b/release/src/linux/linux/include/net/spx.h @@ -0,0 +1,93 @@ +#ifndef __NET_SPX_H +#define __NET_SPX_H + +#include <net/ipx.h> + +struct spxhdr +{ __u8 cctl; + __u8 dtype; +#define SPX_DTYPE_ECONN 0xFE /* Finished */ +#define SPX_DTYPE_ECACK 0xFF /* Ok */ + __u16 sconn; /* Connection ID */ + __u16 dconn; /* Connection ID */ + __u16 sequence; + __u16 ackseq; + __u16 allocseq; +}; + +struct ipxspxhdr +{ struct ipxhdr ipx; + struct spxhdr spx; +}; + +#define SPX_SYS_PKT_LEN (sizeof(struct ipxspxhdr)) + +#ifdef __KERNEL__ +struct spx_opt +{ int state; + int sndbuf; + int retries; /* Number of WD retries */ + int retransmits; /* Number of retransmits */ + int max_retries; + int wd_interval; + void *owner; + __u16 dest_connid; /* Net order */ + __u16 source_connid; /* Net order */ + __u16 sequence; /* Host order - our current pkt # */ + __u16 alloc; /* Host order - max seq we can rcv now */ + __u16 rmt_ack; /* Host order - last pkt ACKd by remote */ + __u16 rmt_seq; + __u16 acknowledge; + __u16 rmt_alloc; /* Host order - max seq remote can handle now */ + ipx_address dest_addr; + ipx_address source_addr; + struct timer_list watchdog; /* Idle watch */ + struct timer_list retransmit; /* Retransmit timer */ + struct sk_buff_head rcv_queue; + struct sk_buff_head transmit_queue; + struct sk_buff_head retransmit_queue; +}; + +/* Packet connectino control defines */ +#define CCTL_SPXII_XHD 0x01 /* SPX2 extended header */ +#define CCTL_SPX_UNKNOWN 0x02 /* Unknown (unused ??) */ +#define CCTL_SPXII_NEG 0x04 /* Negotiate size */ +#define CCTL_SPXII 0x08 /* Set for SPX2 */ +#define CCTL_EOM 0x10 /* End of message marker */ +#define CCTL_URG 0x20 /* Urgent marker in SPP (not used in SPX?) */ +#define CCTL_ACK 0x40 /* Send me an ACK */ +#define CCTL_CTL 0x80 /* Control message */ +#define CCTL_SYS CCTL_CTL /* Spec uses CCTL_SYS */ + +/* Connection state defines */ +#define SPX_CLOSED 7 +#define SPX_CONNECTING 8 +#define SPX_CONNECTED 9 + +/* Packet transmit types - Internal */ +#define DATA 0 /* Data */ +#define ACK 1 /* Data ACK */ +#define WDACK 2 /* WD ACK */ +#define CONACK 3 /* Connection Request ACK */ +#define CONREQ 4 /* Connection Request */ +#define WDREQ 5 /* WD Request */ +#define DISCON 6 /* Informed Disconnect */ +#define DISACK 7 /* Informed Disconnect ACK */ +#define RETRAN 8 /* Int. Retransmit of packet */ +#define TQUEUE 9 /* Int. Transmit of a queued packet */ + +/* + * These are good canidates for IOcontrol calls + */ + +/* Watchdog defines */ +#define VERIFY_TIMEOUT 3 * HZ +#define ABORT_TIMEOUT 30 * HZ + +/* Packet retransmit defines */ +#define RETRY_COUNT 10 +#define RETRY_TIME 1 * HZ +#define MAX_RETRY_DELAY 5 * HZ + +#endif /* __KERNEL__ */ +#endif /* def __NET_SPX_H */ diff --git a/release/src/linux/linux/include/net/syncppp.h b/release/src/linux/linux/include/net/syncppp.h new file mode 100644 index 00000000..df5b0aa3 --- /dev/null +++ b/release/src/linux/linux/include/net/syncppp.h @@ -0,0 +1,100 @@ +/* + * Defines for synchronous PPP/Cisco link level subroutines. + * + * Copyright (C) 1994 Cronyx Ltd. + * Author: Serge Vakulenko, <vak@zebub.msk.su> + * + * This software is distributed with NO WARRANTIES, not even the implied + * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Authors grant any other persons or organizations permission to use + * or modify this software as long as this message is kept with the software, + * all derivative works or modified versions. + * + * Version 1.7, Wed Jun 7 22:12:02 MSD 1995 + * + * + * + */ + +#ifndef _SYNCPPP_H_ +#define _SYNCPPP_H_ 1 + +#ifdef __KERNEL__ +struct slcp { + u16 state; /* state machine */ + u32 magic; /* local magic number */ + u_char echoid; /* id of last keepalive echo request */ + u_char confid; /* id of last configuration request */ +}; + +struct sipcp { + u16 state; /* state machine */ + u_char confid; /* id of last configuration request */ +}; + +struct sppp +{ + struct sppp * pp_next; /* next interface in keepalive list */ + u32 pp_flags; /* use Cisco protocol instead of PPP */ + u16 pp_alivecnt; /* keepalive packets counter */ + u16 pp_loopcnt; /* loopback detection counter */ + u32 pp_seq; /* local sequence number */ + u32 pp_rseq; /* remote sequence number */ + struct slcp lcp; /* LCP params */ + struct sipcp ipcp; /* IPCP params */ + u32 ibytes,obytes; /* Bytes in/out */ + u32 ipkts,opkts; /* Packets in/out */ + struct timer_list pp_timer; + struct net_device *pp_if; + char pp_link_state; /* Link status */ +}; + +struct ppp_device +{ + struct net_device *dev; /* Network device pointer */ + struct sppp sppp; /* Synchronous PPP */ +}; + +#define sppp_of(dev) \ + (&((struct ppp_device *)(*(unsigned long *)((dev)->priv)))->sppp) + +#define PP_KEEPALIVE 0x01 /* use keepalive protocol */ +#define PP_CISCO 0x02 /* use Cisco protocol instead of PPP */ +#define PP_TIMO 0x04 /* cp_timeout routine active */ +#define PP_DEBUG 0x08 + +#define PPP_MTU 1500 /* max. transmit unit */ + +#define LCP_STATE_CLOSED 0 /* LCP state: closed (conf-req sent) */ +#define LCP_STATE_ACK_RCVD 1 /* LCP state: conf-ack received */ +#define LCP_STATE_ACK_SENT 2 /* LCP state: conf-ack sent */ +#define LCP_STATE_OPENED 3 /* LCP state: opened */ + +#define IPCP_STATE_CLOSED 0 /* IPCP state: closed (conf-req sent) */ +#define IPCP_STATE_ACK_RCVD 1 /* IPCP state: conf-ack received */ +#define IPCP_STATE_ACK_SENT 2 /* IPCP state: conf-ack sent */ +#define IPCP_STATE_OPENED 3 /* IPCP state: opened */ + +#define SPPP_LINK_DOWN 0 /* link down - no keepalive */ +#define SPPP_LINK_UP 1 /* link is up - keepalive ok */ + +void sppp_attach (struct ppp_device *pd); +void sppp_detach (struct net_device *dev); +void sppp_input (struct net_device *dev, struct sk_buff *m); +int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); +struct sk_buff *sppp_dequeue (struct net_device *dev); +int sppp_isempty (struct net_device *dev); +void sppp_flush (struct net_device *dev); +int sppp_open (struct net_device *dev); +int sppp_reopen (struct net_device *dev); +int sppp_close (struct net_device *dev); +#endif + +#define SPPPIOCCISCO (SIOCDEVPRIVATE) +#define SPPPIOCPPP (SIOCDEVPRIVATE+1) +#define SPPPIOCDEBUG (SIOCDEVPRIVATE+2) +#define SPPPIOCSFLAGS (SIOCDEVPRIVATE+3) +#define SPPPIOCGFLAGS (SIOCDEVPRIVATE+4) + +#endif /* _SYNCPPP_H_ */ diff --git a/release/src/linux/linux/include/net/tcp.h b/release/src/linux/linux/include/net/tcp.h new file mode 100644 index 00000000..6571f4b2 --- /dev/null +++ b/release/src/linux/linux/include/net/tcp.h @@ -0,0 +1,1822 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the TCP module. + * + * Version: @(#)tcp.h 1.0.5 05/23/93 + * + * Authors: Ross Biro, <bir7@leland.Stanford.Edu> + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * + * 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. + */ +#ifndef _TCP_H +#define _TCP_H + +#define TCP_DEBUG 1 +#define FASTRETRANS_DEBUG 1 + +/* Cancel timers, when they are not required. */ +#undef TCP_CLEAR_TIMERS + +#include <linux/config.h> +#include <linux/tcp.h> +#include <linux/slab.h> +#include <linux/cache.h> +#include <net/checksum.h> +#include <net/sock.h> + +/* This is for all connections with a full identity, no wildcards. + * New scheme, half the table is for TIME_WAIT, the other half is + * for the rest. I'll experiment with dynamic table growth later. + */ +struct tcp_ehash_bucket { + rwlock_t lock; + struct sock *chain; +} __attribute__((__aligned__(8))); + +/* This is for listening sockets, thus all sockets which possess wildcards. */ +#define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ + +/* There are a few simple rules, which allow for local port reuse by + * an application. In essence: + * + * 1) Sockets bound to different interfaces may share a local port. + * Failing that, goto test 2. + * 2) If all sockets have sk->reuse set, and none of them are in + * TCP_LISTEN state, the port may be shared. + * Failing that, goto test 3. + * 3) If all sockets are bound to a specific sk->rcv_saddr local + * address, and none of them are the same, the port may be + * shared. + * Failing this, the port cannot be shared. + * + * The interesting point, is test #2. This is what an FTP server does + * all day. To optimize this case we use a specific flag bit defined + * below. As we add sockets to a bind bucket list, we perform a + * check of: (newsk->reuse && (newsk->state != TCP_LISTEN)) + * As long as all sockets added to a bind bucket pass this test, + * the flag bit will be set. + * The resulting situation is that tcp_v[46]_verify_bind() can just check + * for this flag bit, if it is set and the socket trying to bind has + * sk->reuse set, we don't even have to walk the owners list at all, + * we return that it is ok to bind this socket to the requested local port. + * + * Sounds like a lot of work, but it is worth it. In a more naive + * implementation (ie. current FreeBSD etc.) the entire list of ports + * must be walked for each data port opened by an ftp server. Needless + * to say, this does not scale at all. With a couple thousand FTP + * users logged onto your box, isn't it nice to know that new data + * ports are created in O(1) time? I thought so. ;-) -DaveM + */ +struct tcp_bind_bucket { + unsigned short port; + signed short fastreuse; + struct tcp_bind_bucket *next; + struct sock *owners; + struct tcp_bind_bucket **pprev; +}; + +struct tcp_bind_hashbucket { + spinlock_t lock; + struct tcp_bind_bucket *chain; +}; + +extern struct tcp_hashinfo { + /* This is for sockets with full identity only. Sockets here will + * always be without wildcards and will have the following invariant: + * + * TCP_ESTABLISHED <= sk->state < TCP_CLOSE + * + * First half of the table is for sockets not in TIME_WAIT, second half + * is for TIME_WAIT sockets only. + */ + struct tcp_ehash_bucket *__tcp_ehash; + + /* Ok, let's try this, I give up, we do need a local binding + * TCP hash as well as the others for fast bind/connect. + */ + struct tcp_bind_hashbucket *__tcp_bhash; + + int __tcp_bhash_size; + int __tcp_ehash_size; + + /* All sockets in TCP_LISTEN state will be in here. This is the only + * table where wildcard'd TCP sockets can exist. Hash function here + * is just local port number. + */ + struct sock *__tcp_listening_hash[TCP_LHTABLE_SIZE]; + + /* All the above members are written once at bootup and + * never written again _or_ are predominantly read-access. + * + * Now align to a new cache line as all the following members + * are often dirty. + */ + rwlock_t __tcp_lhash_lock ____cacheline_aligned; + atomic_t __tcp_lhash_users; + wait_queue_head_t __tcp_lhash_wait; + spinlock_t __tcp_portalloc_lock; +} tcp_hashinfo; + +#define tcp_ehash (tcp_hashinfo.__tcp_ehash) +#define tcp_bhash (tcp_hashinfo.__tcp_bhash) +#define tcp_ehash_size (tcp_hashinfo.__tcp_ehash_size) +#define tcp_bhash_size (tcp_hashinfo.__tcp_bhash_size) +#define tcp_listening_hash (tcp_hashinfo.__tcp_listening_hash) +#define tcp_lhash_lock (tcp_hashinfo.__tcp_lhash_lock) +#define tcp_lhash_users (tcp_hashinfo.__tcp_lhash_users) +#define tcp_lhash_wait (tcp_hashinfo.__tcp_lhash_wait) +#define tcp_portalloc_lock (tcp_hashinfo.__tcp_portalloc_lock) + +extern kmem_cache_t *tcp_bucket_cachep; +extern struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head, + unsigned short snum); +extern void tcp_bucket_unlock(struct sock *sk); +extern int tcp_port_rover; +extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif); + +/* These are AF independent. */ +static __inline__ int tcp_bhashfn(__u16 lport) +{ + return (lport & (tcp_bhash_size - 1)); +} + +/* This is a TIME_WAIT bucket. It works around the memory consumption + * problems of sockets in such a state on heavily loaded servers, but + * without violating the protocol specification. + */ +struct tcp_tw_bucket { + __u32 daddr; + __u32 rcv_saddr; + __u16 dport; + unsigned short num; + int bound_dev_if; + struct sock *next; + struct sock **pprev; + struct sock *bind_next; + struct sock **bind_pprev; + unsigned char state, + substate; /* "zapped" is replaced with "substate" */ + __u16 sport; + unsigned short family; + unsigned char reuse, + rcv_wscale; /* It is also TW bucket specific */ + atomic_t refcnt; + + /* And these are ours. */ + int hashent; + int timeout; + __u32 rcv_nxt; + __u32 snd_nxt; + __u32 rcv_wnd; + __u32 ts_recent; + long ts_recent_stamp; + unsigned long ttd; + struct tcp_bind_bucket *tb; + struct tcp_tw_bucket *next_death; + struct tcp_tw_bucket **pprev_death; + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct in6_addr v6_daddr; + struct in6_addr v6_rcv_saddr; +#endif +}; + +extern kmem_cache_t *tcp_timewait_cachep; + +static inline void tcp_tw_put(struct tcp_tw_bucket *tw) +{ + if (atomic_dec_and_test(&tw->refcnt)) { +#ifdef INET_REFCNT_DEBUG + printk(KERN_DEBUG "tw_bucket %p released\n", tw); +#endif + kmem_cache_free(tcp_timewait_cachep, tw); + } +} + +extern atomic_t tcp_orphan_count; +extern int tcp_tw_count; +extern void tcp_time_wait(struct sock *sk, int state, int timeo); +extern void tcp_timewait_kill(struct tcp_tw_bucket *tw); +extern void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo); +extern void tcp_tw_deschedule(struct tcp_tw_bucket *tw); + + +/* Socket demux engine toys. */ +#ifdef __BIG_ENDIAN +#define TCP_COMBINED_PORTS(__sport, __dport) \ + (((__u32)(__sport)<<16) | (__u32)(__dport)) +#else /* __LITTLE_ENDIAN */ +#define TCP_COMBINED_PORTS(__sport, __dport) \ + (((__u32)(__dport)<<16) | (__u32)(__sport)) +#endif + +#if BITS_PER_LONG == 64 +#ifdef __BIG_ENDIAN +#define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \ + __u64 __name = (((__u64)(__saddr))<<32)|((__u64)(__daddr)); +#else /* __LITTLE_ENDIAN */ +#define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \ + __u64 __name = (((__u64)(__daddr))<<32)|((__u64)(__saddr)); +#endif /* __BIG_ENDIAN */ +#define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ + (((*((__u64 *)&((__sk)->daddr)))== (__cookie)) && \ + ((*((__u32 *)&((__sk)->dport)))== (__ports)) && \ + (!((__sk)->bound_dev_if) || ((__sk)->bound_dev_if == (__dif)))) +#else /* 32-bit arch */ +#define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) +#define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ + (((__sk)->daddr == (__saddr)) && \ + ((__sk)->rcv_saddr == (__daddr)) && \ + ((*((__u32 *)&((__sk)->dport)))== (__ports)) && \ + (!((__sk)->bound_dev_if) || ((__sk)->bound_dev_if == (__dif)))) +#endif /* 64-bit arch */ + +#define TCP_IPV6_MATCH(__sk, __saddr, __daddr, __ports, __dif) \ + (((*((__u32 *)&((__sk)->dport)))== (__ports)) && \ + ((__sk)->family == AF_INET6) && \ + !ipv6_addr_cmp(&(__sk)->net_pinfo.af_inet6.daddr, (__saddr)) && \ + !ipv6_addr_cmp(&(__sk)->net_pinfo.af_inet6.rcv_saddr, (__daddr)) && \ + (!((__sk)->bound_dev_if) || ((__sk)->bound_dev_if == (__dif)))) + +/* These can have wildcards, don't try too hard. */ +static __inline__ int tcp_lhashfn(unsigned short num) +{ + return num & (TCP_LHTABLE_SIZE - 1); +} + +static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) +{ + return tcp_lhashfn(sk->num); +} + +#define MAX_TCP_HEADER (128 + MAX_HEADER) + +/* + * Never offer a window over 32767 without using window scaling. Some + * poor stacks do signed 16bit maths! + */ +#define MAX_TCP_WINDOW 32767U + +/* Minimal accepted MSS. It is (60+60+8) - (20+20). */ +#define TCP_MIN_MSS 88U + +/* Minimal RCV_MSS. */ +#define TCP_MIN_RCVMSS 536U + +/* After receiving this amount of duplicate ACKs fast retransmit starts. */ +#define TCP_FASTRETRANS_THRESH 3 + +/* Maximal reordering. */ +#define TCP_MAX_REORDERING 127 + +/* Maximal number of ACKs sent quickly to accelerate slow-start. */ +#define TCP_MAX_QUICKACKS 16U + +/* urg_data states */ +#define TCP_URG_VALID 0x0100 +#define TCP_URG_NOTYET 0x0200 +#define TCP_URG_READ 0x0400 + +#define TCP_RETR1 3 /* + * This is how many retries it does before it + * tries to figure out if the gateway is + * down. Minimal RFC value is 3; it corresponds + * to ~3sec-8min depending on RTO. + */ + +#define TCP_RETR2 15 /* + * This should take at least + * 90 minutes to time out. + * RFC1122 says that the limit is 100 sec. + * 15 is ~13-30min depending on RTO. + */ + +#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a + * connection: ~180sec is RFC minumum */ + +#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a + * connection: ~180sec is RFC minumum */ + + +#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned + * socket. 7 is ~50sec-16min. + */ + + +#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT + * state, about 60 seconds */ +#define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN + /* BSD style FIN_WAIT2 deadlock breaker. + * It used to be 3min, new value is 60sec, + * to combine FIN-WAIT-2 timeout with + * TIME-WAIT timer. + */ + +#define TCP_DELACK_MAX ((unsigned)(HZ/5)) /* maximal time to delay before sending an ACK */ +#if HZ >= 100 +#define TCP_DELACK_MIN ((unsigned)(HZ/25)) /* minimal time to delay before sending an ACK */ +#define TCP_ATO_MIN ((unsigned)(HZ/25)) +#else +#define TCP_DELACK_MIN 4U +#define TCP_ATO_MIN 4U +#endif +#define TCP_RTO_MAX ((unsigned)(120*HZ)) +#define TCP_RTO_MIN ((unsigned)(HZ/5)) +#define TCP_TIMEOUT_INIT ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value */ + +#define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes + * for local resources. + */ + +#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ +#define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ +#define TCP_KEEPALIVE_INTVL (75*HZ) + +#define MAX_TCP_KEEPIDLE 32767 +#define MAX_TCP_KEEPINTVL 32767 +#define MAX_TCP_KEEPCNT 127 +#define MAX_TCP_SYNCNT 127 + +/* TIME_WAIT reaping mechanism. */ +#define TCP_TWKILL_SLOTS 8 /* Please keep this a power of 2. */ +#define TCP_TWKILL_PERIOD (TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS) + +#define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ +#define TCP_SYNQ_HSIZE 512 /* Size of SYNACK hash table */ + +#define TCP_PAWS_24DAYS (60 * 60 * 24 * 24) +#define TCP_PAWS_MSL 60 /* Per-host timestamps are invalidated + * after this time. It should be equal + * (or greater than) TCP_TIMEWAIT_LEN + * to provide reliability equal to one + * provided by timewait state. + */ +#define TCP_PAWS_WINDOW 1 /* Replay window for per-host + * timestamps. It must be less than + * minimal timewait lifetime. + */ + +#define TCP_TW_RECYCLE_SLOTS_LOG 5 +#define TCP_TW_RECYCLE_SLOTS (1<<TCP_TW_RECYCLE_SLOTS_LOG) + +/* If time > 4sec, it is "slow" path, no recycling is required, + so that we select tick to get range about 4 seconds. + */ + +#if HZ <= 16 || HZ > 4096 +# error Unsupported: HZ <= 16 or HZ > 4096 +#elif HZ <= 32 +# define TCP_TW_RECYCLE_TICK (5+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 64 +# define TCP_TW_RECYCLE_TICK (6+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 128 +# define TCP_TW_RECYCLE_TICK (7+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 256 +# define TCP_TW_RECYCLE_TICK (8+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 512 +# define TCP_TW_RECYCLE_TICK (9+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 1024 +# define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ <= 2048 +# define TCP_TW_RECYCLE_TICK (11+2-TCP_TW_RECYCLE_SLOTS_LOG) +#else +# define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG) +#endif + +/* + * TCP option + */ + +#define TCPOPT_NOP 1 /* Padding */ +#define TCPOPT_EOL 0 /* End of options */ +#define TCPOPT_MSS 2 /* Segment size negotiating */ +#define TCPOPT_WINDOW 3 /* Window scaling */ +#define TCPOPT_SACK_PERM 4 /* SACK Permitted */ +#define TCPOPT_SACK 5 /* SACK Block */ +#define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ + +/* + * TCP option lengths + */ + +#define TCPOLEN_MSS 4 +#define TCPOLEN_WINDOW 3 +#define TCPOLEN_SACK_PERM 2 +#define TCPOLEN_TIMESTAMP 10 + +/* But this is what stacks really send out. */ +#define TCPOLEN_TSTAMP_ALIGNED 12 +#define TCPOLEN_WSCALE_ALIGNED 4 +#define TCPOLEN_SACKPERM_ALIGNED 4 +#define TCPOLEN_SACK_BASE 2 +#define TCPOLEN_SACK_BASE_ALIGNED 4 +#define TCPOLEN_SACK_PERBLOCK 8 + +#define TCP_TIME_RETRANS 1 /* Retransmit timer */ +#define TCP_TIME_DACK 2 /* Delayed ack timer */ +#define TCP_TIME_PROBE0 3 /* Zero window probe timer */ +#define TCP_TIME_KEEPOPEN 4 /* Keepalive timer */ + +/* sysctl variables for tcp */ +extern int sysctl_max_syn_backlog; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; +extern int sysctl_tcp_sack; +extern int sysctl_tcp_fin_timeout; +extern int sysctl_tcp_tw_recycle; +extern int sysctl_tcp_keepalive_time; +extern int sysctl_tcp_keepalive_probes; +extern int sysctl_tcp_keepalive_intvl; +extern int sysctl_tcp_syn_retries; +extern int sysctl_tcp_synack_retries; +extern int sysctl_tcp_retries1; +extern int sysctl_tcp_retries2; +extern int sysctl_tcp_orphan_retries; +extern int sysctl_tcp_syncookies; +extern int sysctl_tcp_retrans_collapse; +extern int sysctl_tcp_stdurg; +extern int sysctl_tcp_rfc1337; +extern int sysctl_tcp_abort_on_overflow; +extern int sysctl_tcp_max_orphans; +extern int sysctl_tcp_max_tw_buckets; +extern int sysctl_tcp_fack; +extern int sysctl_tcp_reordering; +extern int sysctl_tcp_ecn; +extern int sysctl_tcp_dsack; +extern int sysctl_tcp_mem[3]; +extern int sysctl_tcp_wmem[3]; +extern int sysctl_tcp_rmem[3]; +extern int sysctl_tcp_app_win; +extern int sysctl_tcp_adv_win_scale; +extern int sysctl_tcp_tw_reuse; + +extern atomic_t tcp_memory_allocated; +extern atomic_t tcp_sockets_allocated; +extern int tcp_memory_pressure; + +struct open_request; + +struct or_calltable { + int family; + int (*rtx_syn_ack) (struct sock *sk, struct open_request *req, struct dst_entry*); + void (*send_ack) (struct sk_buff *skb, struct open_request *req); + void (*destructor) (struct open_request *req); + void (*send_reset) (struct sk_buff *skb); +}; + +struct tcp_v4_open_req { + __u32 loc_addr; + __u32 rmt_addr; + struct ip_options *opt; +}; + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +struct tcp_v6_open_req { + struct in6_addr loc_addr; + struct in6_addr rmt_addr; + struct sk_buff *pktopts; + int iif; +}; +#endif + +/* this structure is too big */ +struct open_request { + struct open_request *dl_next; /* Must be first member! */ + __u32 rcv_isn; + __u32 snt_isn; + __u16 rmt_port; + __u16 mss; + __u8 retrans; + __u8 __pad; + __u16 snd_wscale : 4, + rcv_wscale : 4, + tstamp_ok : 1, + sack_ok : 1, + wscale_ok : 1, + ecn_ok : 1, + acked : 1; + /* The following two fields can be easily recomputed I think -AK */ + __u32 window_clamp; /* window clamp at creation time */ + __u32 rcv_wnd; /* rcv_wnd offered first time */ + __u32 ts_recent; + unsigned long expires; + struct or_calltable *class; + struct sock *sk; + union { + struct tcp_v4_open_req v4_req; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct tcp_v6_open_req v6_req; +#endif + } af; +}; + +/* SLAB cache for open requests. */ +extern kmem_cache_t *tcp_openreq_cachep; + +#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC) +#define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req) + +static inline void tcp_openreq_free(struct open_request *req) +{ + req->class->destructor(req); + tcp_openreq_fastfree(req); +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#define TCP_INET_FAMILY(fam) ((fam) == AF_INET) +#else +#define TCP_INET_FAMILY(fam) 1 +#endif + +/* + * Pointers to address related TCP functions + * (i.e. things that depend on the address family) + * + * BUGGG_FUTURE: all the idea behind this struct is wrong. + * It mixes socket frontend with transport function. + * With port sharing between IPv6/v4 it gives the only advantage, + * only poor IPv6 needs to permanently recheck, that it + * is still IPv6 8)8) It must be cleaned up as soon as possible. + * --ANK (980802) + */ + +struct tcp_func { + int (*queue_xmit) (struct sk_buff *skb); + + void (*send_check) (struct sock *sk, + struct tcphdr *th, + int len, + struct sk_buff *skb); + + int (*rebuild_header) (struct sock *sk); + + int (*conn_request) (struct sock *sk, + struct sk_buff *skb); + + struct sock * (*syn_recv_sock) (struct sock *sk, + struct sk_buff *skb, + struct open_request *req, + struct dst_entry *dst); + + int (*remember_stamp) (struct sock *sk); + + __u16 net_header_len; + + int (*setsockopt) (struct sock *sk, + int level, + int optname, + char *optval, + int optlen); + + int (*getsockopt) (struct sock *sk, + int level, + int optname, + char *optval, + int *optlen); + + + void (*addr2sockaddr) (struct sock *sk, + struct sockaddr *); + + int sockaddr_len; +}; + +/* + * The next routines deal with comparing 32 bit unsigned ints + * and worry about wraparound (automatic with unsigned arithmetic). + */ + +extern __inline int before(__u32 seq1, __u32 seq2) +{ + return (__s32)(seq1-seq2) < 0; +} + +extern __inline int after(__u32 seq1, __u32 seq2) +{ + return (__s32)(seq2-seq1) < 0; +} + + +/* is s2<=s1<=s3 ? */ +extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3) +{ + return seq3 - seq2 >= seq1 - seq2; +} + + +extern struct proto tcp_prot; + +extern struct tcp_mib tcp_statistics[NR_CPUS*2]; +#define TCP_INC_STATS(field) SNMP_INC_STATS(tcp_statistics, field) +#define TCP_INC_STATS_BH(field) SNMP_INC_STATS_BH(tcp_statistics, field) +#define TCP_INC_STATS_USER(field) SNMP_INC_STATS_USER(tcp_statistics, field) + +extern void tcp_put_port(struct sock *sk); +extern void __tcp_put_port(struct sock *sk); +extern void tcp_inherit_port(struct sock *sk, struct sock *child); + +extern void tcp_v4_err(struct sk_buff *skb, u32); + +extern void tcp_shutdown (struct sock *sk, int how); + +extern int tcp_v4_rcv(struct sk_buff *skb); + +extern int tcp_v4_remember_stamp(struct sock *sk); + +extern int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw); + +extern int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size); +extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags); + +extern int tcp_ioctl(struct sock *sk, + int cmd, + unsigned long arg); + +extern int tcp_rcv_state_process(struct sock *sk, + struct sk_buff *skb, + struct tcphdr *th, + unsigned len); + +extern int tcp_rcv_established(struct sock *sk, + struct sk_buff *skb, + struct tcphdr *th, + unsigned len); + +enum tcp_ack_state_t +{ + TCP_ACK_SCHED = 1, + TCP_ACK_TIMER = 2, + TCP_ACK_PUSHED= 4 +}; + +static inline void tcp_schedule_ack(struct tcp_opt *tp) +{ + tp->ack.pending |= TCP_ACK_SCHED; +} + +static inline int tcp_ack_scheduled(struct tcp_opt *tp) +{ + return tp->ack.pending&TCP_ACK_SCHED; +} + +static __inline__ void tcp_dec_quickack_mode(struct tcp_opt *tp) +{ + if (tp->ack.quick && --tp->ack.quick == 0) { + /* Leaving quickack mode we deflate ATO. */ + tp->ack.ato = TCP_ATO_MIN; + } +} + +extern void tcp_enter_quickack_mode(struct tcp_opt *tp); + +static __inline__ void tcp_delack_init(struct tcp_opt *tp) +{ + memset(&tp->ack, 0, sizeof(tp->ack)); +} + +static inline void tcp_clear_options(struct tcp_opt *tp) +{ + tp->tstamp_ok = tp->sack_ok = tp->wscale_ok = tp->snd_wscale = 0; +} + +enum tcp_tw_status +{ + TCP_TW_SUCCESS = 0, + TCP_TW_RST = 1, + TCP_TW_ACK = 2, + TCP_TW_SYN = 3 +}; + + +extern enum tcp_tw_status tcp_timewait_state_process(struct tcp_tw_bucket *tw, + struct sk_buff *skb, + struct tcphdr *th, + unsigned len); + +extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, + struct open_request *req, + struct open_request **prev); +extern int tcp_child_process(struct sock *parent, + struct sock *child, + struct sk_buff *skb); +extern void tcp_enter_loss(struct sock *sk, int how); +extern void tcp_clear_retrans(struct tcp_opt *tp); +extern void tcp_update_metrics(struct sock *sk); + +extern void tcp_close(struct sock *sk, + long timeout); +extern struct sock * tcp_accept(struct sock *sk, int flags, int *err); +extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); +extern void tcp_write_space(struct sock *sk); + +extern int tcp_getsockopt(struct sock *sk, int level, + int optname, char *optval, + int *optlen); +extern int tcp_setsockopt(struct sock *sk, int level, + int optname, char *optval, + int optlen); +extern void tcp_set_keepalive(struct sock *sk, int val); +extern int tcp_recvmsg(struct sock *sk, + struct msghdr *msg, + int len, int nonblock, + int flags, int *addr_len); + +extern int tcp_listen_start(struct sock *sk); + +extern void tcp_parse_options(struct sk_buff *skb, + struct tcp_opt *tp, + int estab); + +/* + * TCP v4 functions exported for the inet6 API + */ + +extern int tcp_v4_rebuild_header(struct sock *sk); + +extern int tcp_v4_build_header(struct sock *sk, + struct sk_buff *skb); + +extern void tcp_v4_send_check(struct sock *sk, + struct tcphdr *th, int len, + struct sk_buff *skb); + +extern int tcp_v4_conn_request(struct sock *sk, + struct sk_buff *skb); + +extern struct sock * tcp_create_openreq_child(struct sock *sk, + struct open_request *req, + struct sk_buff *skb); + +extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk, + struct sk_buff *skb, + struct open_request *req, + struct dst_entry *dst); + +extern int tcp_v4_do_rcv(struct sock *sk, + struct sk_buff *skb); + +extern int tcp_v4_connect(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + +extern int tcp_connect(struct sock *sk); + +extern struct sk_buff * tcp_make_synack(struct sock *sk, + struct dst_entry *dst, + struct open_request *req); + +extern int tcp_disconnect(struct sock *sk, int flags); + +extern void tcp_unhash(struct sock *sk); + +extern int tcp_v4_hash_connecting(struct sock *sk); + + +/* From syncookies.c */ +extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, + struct ip_options *opt); +extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, + __u16 *mss); + +/* tcp_output.c */ + +extern int tcp_write_xmit(struct sock *, int nonagle); +extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); +extern void tcp_xmit_retransmit_queue(struct sock *); +extern void tcp_simple_retransmit(struct sock *); + +extern void tcp_send_probe0(struct sock *); +extern void tcp_send_partial(struct sock *); +extern int tcp_write_wakeup(struct sock *); +extern void tcp_send_fin(struct sock *sk); +extern void tcp_send_active_reset(struct sock *sk, int priority); +extern int tcp_send_synack(struct sock *); +extern int tcp_transmit_skb(struct sock *, struct sk_buff *); +extern void tcp_send_skb(struct sock *, struct sk_buff *, int force_queue, unsigned mss_now); +extern void tcp_push_one(struct sock *, unsigned mss_now); +extern void tcp_send_ack(struct sock *sk); +extern void tcp_send_delayed_ack(struct sock *sk); + +/* tcp_timer.c */ +extern void tcp_init_xmit_timers(struct sock *); +extern void tcp_clear_xmit_timers(struct sock *); + +extern void tcp_delete_keepalive_timer (struct sock *); +extern void tcp_reset_keepalive_timer (struct sock *, unsigned long); +extern int tcp_sync_mss(struct sock *sk, u32 pmtu); + +extern const char timer_bug_msg[]; + +/* Read 'sendfile()'-style from a TCP socket */ +typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *, + unsigned int, size_t); +extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + sk_read_actor_t recv_actor); + +static inline void tcp_clear_xmit_timer(struct sock *sk, int what) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + switch (what) { + case TCP_TIME_RETRANS: + case TCP_TIME_PROBE0: + tp->pending = 0; + +#ifdef TCP_CLEAR_TIMERS + if (timer_pending(&tp->retransmit_timer) && + del_timer(&tp->retransmit_timer)) + __sock_put(sk); +#endif + break; + case TCP_TIME_DACK: + tp->ack.blocked = 0; + tp->ack.pending = 0; + +#ifdef TCP_CLEAR_TIMERS + if (timer_pending(&tp->delack_timer) && + del_timer(&tp->delack_timer)) + __sock_put(sk); +#endif + break; + default: + printk(timer_bug_msg); + return; + }; + +} + +/* + * Reset the retransmission timer + */ +static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + if (when > TCP_RTO_MAX) { +#ifdef TCP_DEBUG + printk(KERN_DEBUG "reset_xmit_timer sk=%p %d when=0x%lx, caller=%p\n", sk, what, when, current_text_addr()); +#endif + when = TCP_RTO_MAX; + } + + switch (what) { + case TCP_TIME_RETRANS: + case TCP_TIME_PROBE0: + tp->pending = what; + tp->timeout = jiffies+when; + if (!mod_timer(&tp->retransmit_timer, tp->timeout)) + sock_hold(sk); + break; + + case TCP_TIME_DACK: + tp->ack.pending |= TCP_ACK_TIMER; + tp->ack.timeout = jiffies+when; + if (!mod_timer(&tp->delack_timer, tp->ack.timeout)) + sock_hold(sk); + break; + + default: + printk(KERN_DEBUG "bug: unknown timer value\n"); + }; +} + +/* Compute the current effective MSS, taking SACKs and IP options, + * and even PMTU discovery events into account. + */ + +static __inline__ unsigned int tcp_current_mss(struct sock *sk) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct dst_entry *dst = __sk_dst_get(sk); + int mss_now = tp->mss_cache; + + if (dst && dst->pmtu != tp->pmtu_cookie) + mss_now = tcp_sync_mss(sk, dst->pmtu); + + if (tp->eff_sacks) + mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + + (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK)); + return mss_now; +} + +/* Initialize RCV_MSS value. + * RCV_MSS is an our guess about MSS used by the peer. + * We haven't any direct information about the MSS. + * It's better to underestimate the RCV_MSS rather than overestimate. + * Overestimations make us ACKing less frequently than needed. + * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss(). + */ + +static inline void tcp_initialize_rcv_mss(struct sock *sk) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + unsigned int hint = min(tp->advmss, tp->mss_cache); + + hint = min(hint, tp->rcv_wnd/2); + hint = min(hint, TCP_MIN_RCVMSS); + hint = max(hint, TCP_MIN_MSS); + + tp->ack.rcv_mss = hint; +} + +static __inline__ void __tcp_fast_path_on(struct tcp_opt *tp, u32 snd_wnd) +{ + tp->pred_flags = htonl((tp->tcp_header_len << 26) | + ntohl(TCP_FLAG_ACK) | + snd_wnd); +} + +static __inline__ void tcp_fast_path_on(struct tcp_opt *tp) +{ + __tcp_fast_path_on(tp, tp->snd_wnd>>tp->snd_wscale); +} + +static inline void tcp_fast_path_check(struct sock *sk, struct tcp_opt *tp) +{ + if (skb_queue_len(&tp->out_of_order_queue) == 0 && + tp->rcv_wnd && + atomic_read(&sk->rmem_alloc) < sk->rcvbuf && + !tp->urg_data) + tcp_fast_path_on(tp); +} + +/* Compute the actual receive window we are currently advertising. + * Rcv_nxt can be after the window if our peer push more data + * than the offered window. + */ +static __inline__ u32 tcp_receive_window(struct tcp_opt *tp) +{ + s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt; + + if (win < 0) + win = 0; + return (u32) win; +} + +/* Choose a new window, without checks for shrinking, and without + * scaling applied to the result. The caller does these things + * if necessary. This is a "raw" window selection. + */ +extern u32 __tcp_select_window(struct sock *sk); + +/* TCP timestamps are only 32-bits, this causes a slight + * complication on 64-bit systems since we store a snapshot + * of jiffies in the buffer control blocks below. We decidely + * only use of the low 32-bits of jiffies and hide the ugly + * casts with the following macro. + */ +#define tcp_time_stamp ((__u32)(jiffies)) + +struct tcp_skb_cb { + union { + struct inet_skb_parm h4; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct inet6_skb_parm h6; +#endif + } header; /* For incoming frames */ + __u32 seq; /* Starting sequence number */ + __u32 end_seq; /* SEQ + FIN + SYN + datalen */ + __u32 when; /* used to compute rtt's */ + __u8 flags; /* TCP header flags. */ + + /* NOTE: These must match up to the flags byte in a + * real TCP header. + */ +#define TCPCB_FLAG_FIN 0x01 +#define TCPCB_FLAG_SYN 0x02 +#define TCPCB_FLAG_RST 0x04 +#define TCPCB_FLAG_PSH 0x08 +#define TCPCB_FLAG_ACK 0x10 +#define TCPCB_FLAG_URG 0x20 +#define TCPCB_FLAG_ECE 0x40 +#define TCPCB_FLAG_CWR 0x80 + + __u8 sacked; /* State flags for SACK/FACK. */ +#define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ +#define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */ +#define TCPCB_LOST 0x04 /* SKB is lost */ +#define TCPCB_TAGBITS 0x07 /* All tag bits */ + +#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */ +#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS) + +#define TCPCB_URG 0x20 /* Urgent pointer advenced here */ + +#define TCPCB_AT_TAIL (TCPCB_URG) + + __u16 urg_ptr; /* Valid w/URG flags is set. */ + __u32 ack_seq; /* Sequence number ACK'd */ +}; + +#define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0])) + +#define for_retrans_queue(skb, sk, tp) \ + for (skb = (sk)->write_queue.next; \ + (skb != (tp)->send_head) && \ + (skb != (struct sk_buff *)&(sk)->write_queue); \ + skb=skb->next) + + +#include <net/tcp_ecn.h> + + +/* + * Compute minimal free write space needed to queue new packets. + */ +static inline int tcp_min_write_space(struct sock *sk) +{ + return sk->wmem_queued/2; +} + +static inline int tcp_wspace(struct sock *sk) +{ + return sk->sndbuf - sk->wmem_queued; +} + + +/* This determines how many packets are "in the network" to the best + * of our knowledge. In many cases it is conservative, but where + * detailed information is available from the receiver (via SACK + * blocks etc.) we can make more aggressive calculations. + * + * Use this for decisions involving congestion control, use just + * tp->packets_out to determine if the send queue is empty or not. + * + * Read this equation as: + * + * "Packets sent once on transmission queue" MINUS + * "Packets left network, but not honestly ACKed yet" PLUS + * "Packets fast retransmitted" + */ +static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp) +{ + return tp->packets_out - tp->left_out + tp->retrans_out; +} + +/* Recalculate snd_ssthresh, we want to set it to: + * + * one half the current congestion window, but no + * less than two segments + */ +static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp) +{ + return max(tp->snd_cwnd >> 1U, 2U); +} + +/* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. + * The exception is rate halving phase, when cwnd is decreasing towards + * ssthresh. + */ +static inline __u32 tcp_current_ssthresh(struct tcp_opt *tp) +{ + if ((1<<tp->ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery)) + return tp->snd_ssthresh; + else + return max(tp->snd_ssthresh, + ((tp->snd_cwnd >> 1) + + (tp->snd_cwnd >> 2))); +} + +static inline void tcp_sync_left_out(struct tcp_opt *tp) +{ + if (tp->sack_ok && tp->sacked_out >= tp->packets_out - tp->lost_out) + tp->sacked_out = tp->packets_out - tp->lost_out; + tp->left_out = tp->sacked_out + tp->lost_out; +} + +extern void tcp_cwnd_application_limited(struct sock *sk); + +/* Congestion window validation. (RFC2861) */ + +static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_opt *tp) +{ + if (tp->packets_out >= tp->snd_cwnd) { + /* Network is feed fully. */ + tp->snd_cwnd_used = 0; + tp->snd_cwnd_stamp = tcp_time_stamp; + } else { + /* Network starves. */ + if (tp->packets_out > tp->snd_cwnd_used) + tp->snd_cwnd_used = tp->packets_out; + + if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto) + tcp_cwnd_application_limited(sk); + } +} + +/* Set slow start threshould and cwnd not falling to slow start */ +static inline void __tcp_enter_cwr(struct tcp_opt *tp) +{ + tp->undo_marker = 0; + tp->snd_ssthresh = tcp_recalc_ssthresh(tp); + tp->snd_cwnd = min(tp->snd_cwnd, + tcp_packets_in_flight(tp) + 1U); + tp->snd_cwnd_cnt = 0; + tp->high_seq = tp->snd_nxt; + tp->snd_cwnd_stamp = tcp_time_stamp; + TCP_ECN_queue_cwr(tp); +} + +static inline void tcp_enter_cwr(struct tcp_opt *tp) +{ + tp->prior_ssthresh = 0; + if (tp->ca_state < TCP_CA_CWR) { + __tcp_enter_cwr(tp); + tp->ca_state = TCP_CA_CWR; + } +} + +extern __u32 tcp_init_cwnd(struct tcp_opt *tp); + +/* Slow start with delack produces 3 packets of burst, so that + * it is safe "de facto". + */ +static __inline__ __u32 tcp_max_burst(struct tcp_opt *tp) +{ + return 3; +} + +static __inline__ int tcp_minshall_check(struct tcp_opt *tp) +{ + return after(tp->snd_sml,tp->snd_una) && + !after(tp->snd_sml, tp->snd_nxt); +} + +static __inline__ void tcp_minshall_update(struct tcp_opt *tp, int mss, struct sk_buff *skb) +{ + if (skb->len < mss) + tp->snd_sml = TCP_SKB_CB(skb)->end_seq; +} + +/* Return 0, if packet can be sent now without violation Nagle's rules: + 1. It is full sized. + 2. Or it contains FIN. + 3. Or TCP_NODELAY was set. + 4. Or TCP_CORK is not set, and all sent packets are ACKed. + With Minshall's modification: all sent small packets are ACKed. + */ + +static __inline__ int +tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now, int nonagle) +{ + return (skb->len < mss_now && + !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && + (nonagle == 2 || + (!nonagle && + tp->packets_out && + tcp_minshall_check(tp)))); +} + +/* This checks if the data bearing packet SKB (usually tp->send_head) + * should be put on the wire right now. + */ +static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb, + unsigned cur_mss, int nonagle) +{ + /* RFC 1122 - section 4.2.3.4 + * + * We must queue if + * + * a) The right edge of this frame exceeds the window + * b) There are packets in flight and we have a small segment + * [SWS avoidance and Nagle algorithm] + * (part of SWS is done on packetization) + * Minshall version sounds: there are no _small_ + * segments in flight. (tcp_nagle_check) + * c) We have too many packets 'in flight' + * + * Don't use the nagle rule for urgent data (or + * for the final FIN -DaveM). + * + * Also, Nagle rule does not apply to frames, which + * sit in the middle of queue (they have no chances + * to get new data) and if room at tail of skb is + * not enough to save something seriously (<32 for now). + */ + + /* Don't be strict about the congestion window for the + * final FIN frame. -DaveM + */ + return ((nonagle==1 || tp->urg_mode + || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) && + ((tcp_packets_in_flight(tp) < tp->snd_cwnd) || + (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && + !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd)); +} + +static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_opt *tp) +{ + if (!tp->packets_out && !tp->pending) + tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto); +} + +static __inline__ int tcp_skb_is_last(struct sock *sk, struct sk_buff *skb) +{ + return (skb->next == (struct sk_buff*)&sk->write_queue); +} + +/* Push out any pending frames which were held back due to + * TCP_CORK or attempt at coalescing tiny packets. + * The socket must be locked by the caller. + */ +static __inline__ void __tcp_push_pending_frames(struct sock *sk, + struct tcp_opt *tp, + unsigned cur_mss, + int nonagle) +{ + struct sk_buff *skb = tp->send_head; + + if (skb) { + if (!tcp_skb_is_last(sk, skb)) + nonagle = 1; + if (!tcp_snd_test(tp, skb, cur_mss, nonagle) || + tcp_write_xmit(sk, nonagle)) + tcp_check_probe_timer(sk, tp); + } + tcp_cwnd_validate(sk, tp); +} + +static __inline__ void tcp_push_pending_frames(struct sock *sk, + struct tcp_opt *tp) +{ + __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk), tp->nonagle); +} + +static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp) +{ + struct sk_buff *skb = tp->send_head; + + return (skb && + tcp_snd_test(tp, skb, tcp_current_mss(sk), + tcp_skb_is_last(sk, skb) ? 1 : tp->nonagle)); +} + +static __inline__ void tcp_init_wl(struct tcp_opt *tp, u32 ack, u32 seq) +{ + tp->snd_wl1 = seq; +} + +static __inline__ void tcp_update_wl(struct tcp_opt *tp, u32 ack, u32 seq) +{ + tp->snd_wl1 = seq; +} + +extern void tcp_destroy_sock(struct sock *sk); + + +/* + * Calculate(/check) TCP checksum + */ +static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len, + unsigned long saddr, unsigned long daddr, + unsigned long base) +{ + return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); +} + +static __inline__ int __tcp_checksum_complete(struct sk_buff *skb) +{ + return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); +} + +static __inline__ int tcp_checksum_complete(struct sk_buff *skb) +{ + return skb->ip_summed != CHECKSUM_UNNECESSARY && + __tcp_checksum_complete(skb); +} + +/* Prequeue for VJ style copy to user, combined with checksumming. */ + +static __inline__ void tcp_prequeue_init(struct tcp_opt *tp) +{ + tp->ucopy.task = NULL; + tp->ucopy.len = 0; + tp->ucopy.memory = 0; + skb_queue_head_init(&tp->ucopy.prequeue); +} + +/* Packet is added to VJ-style prequeue for processing in process + * context, if a reader task is waiting. Apparently, this exciting + * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) + * failed somewhere. Latency? Burstiness? Well, at least now we will + * see, why it failed. 8)8) --ANK + * + * NOTE: is this not too big to inline? + */ +static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + if (tp->ucopy.task) { + __skb_queue_tail(&tp->ucopy.prequeue, skb); + tp->ucopy.memory += skb->truesize; + if (tp->ucopy.memory > sk->rcvbuf) { + struct sk_buff *skb1; + + if (sk->lock.users) + out_of_line_bug(); + + while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) { + sk->backlog_rcv(sk, skb1); + NET_INC_STATS_BH(TCPPrequeueDropped); + } + + tp->ucopy.memory = 0; + } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { + wake_up_interruptible(sk->sleep); + if (!tcp_ack_scheduled(tp)) + tcp_reset_xmit_timer(sk, TCP_TIME_DACK, (3*TCP_RTO_MIN)/4); + } + return 1; + } + return 0; +} + + +#undef STATE_TRACE + +#ifdef STATE_TRACE +static char *statename[]={ + "Unused","Established","Syn Sent","Syn Recv", + "Fin Wait 1","Fin Wait 2","Time Wait", "Close", + "Close Wait","Last ACK","Listen","Closing" +}; +#endif + +static __inline__ void tcp_set_state(struct sock *sk, int state) +{ + int oldstate = sk->state; + + switch (state) { + case TCP_ESTABLISHED: + if (oldstate != TCP_ESTABLISHED) + TCP_INC_STATS(TcpCurrEstab); + break; + + case TCP_CLOSE: + sk->prot->unhash(sk); + if (sk->prev && !(sk->userlocks&SOCK_BINDPORT_LOCK)) + tcp_put_port(sk); + /* fall through */ + default: + if (oldstate==TCP_ESTABLISHED) + tcp_statistics[smp_processor_id()*2+!in_softirq()].TcpCurrEstab--; + } + + /* Change state AFTER socket is unhashed to avoid closed + * socket sitting in hash tables. + */ + sk->state = state; + +#ifdef STATE_TRACE + SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]); +#endif +} + +static __inline__ void tcp_done(struct sock *sk) +{ + tcp_set_state(sk, TCP_CLOSE); + tcp_clear_xmit_timers(sk); + + sk->shutdown = SHUTDOWN_MASK; + + if (!sk->dead) + sk->state_change(sk); + else + tcp_destroy_sock(sk); +} + +static __inline__ void tcp_sack_reset(struct tcp_opt *tp) +{ + tp->dsack = 0; + tp->eff_sacks = 0; + tp->num_sacks = 0; +} + +static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_opt *tp, __u32 tstamp) +{ + if (tp->tstamp_ok) { + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | + TCPOLEN_TIMESTAMP); + *ptr++ = htonl(tstamp); + *ptr++ = htonl(tp->ts_recent); + } + if (tp->eff_sacks) { + struct tcp_sack_block *sp = tp->dsack ? tp->duplicate_sack : tp->selective_acks; + int this_sack; + + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_SACK << 8) | + (TCPOLEN_SACK_BASE + + (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK))); + for(this_sack = 0; this_sack < tp->eff_sacks; this_sack++) { + *ptr++ = htonl(sp[this_sack].start_seq); + *ptr++ = htonl(sp[this_sack].end_seq); + } + if (tp->dsack) { + tp->dsack = 0; + tp->eff_sacks--; + } + } +} + +/* Construct a tcp options header for a SYN or SYN_ACK packet. + * If this is every changed make sure to change the definition of + * MAX_SYN_SIZE to match the new maximum number of options that you + * can generate. + */ +static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack, + int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent) +{ + /* We always get an MSS option. + * The option bytes which will be seen in normal data + * packets should timestamps be used, must be in the MSS + * advertised. But we subtract them from tp->mss_cache so + * that calculations in tcp_sendmsg are simpler etc. + * So account for this fact here if necessary. If we + * don't do this correctly, as a receiver we won't + * recognize data packets as being full sized when we + * should, and thus we won't abide by the delayed ACK + * rules correctly. + * SACKs don't matter, we never delay an ACK when we + * have any of those going out. + */ + *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); + if (ts) { + if(sack) + *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + else + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(tstamp); /* TSVAL */ + *ptr++ = htonl(ts_recent); /* TSECR */ + } else if(sack) + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | + (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); + if (offer_wscale) + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); +} + +/* Determine a window scaling and initial window to offer. + * Based on the assumption that the given amount of space + * will be offered. Store the results in the tp structure. + * NOTE: for smooth operation initial space offering should + * be a multiple of mss if possible. We assume here that mss >= 1. + * This MUST be enforced by all callers. + */ +static inline void tcp_select_initial_window(int __space, __u32 mss, + __u32 *rcv_wnd, + __u32 *window_clamp, + int wscale_ok, + __u8 *rcv_wscale) +{ + unsigned int space = (__space < 0 ? 0 : __space); + + /* If no clamp set the clamp to the max possible scaled window */ + if (*window_clamp == 0) + (*window_clamp) = (65535 << 14); + space = min(*window_clamp, space); + + /* Quantize space offering to a multiple of mss if possible. */ + if (space > mss) + space = (space / mss) * mss; + + /* NOTE: offering an initial window larger than 32767 + * will break some buggy TCP stacks. We try to be nice. + * If we are not window scaling, then this truncates + * our initial window offering to 32k. There should also + * be a sysctl option to stop being nice. + */ + (*rcv_wnd) = min(space, MAX_TCP_WINDOW); + (*rcv_wscale) = 0; + if (wscale_ok) { + /* See RFC1323 for an explanation of the limit to 14 */ + while (space > 65535 && (*rcv_wscale) < 14) { + space >>= 1; + (*rcv_wscale)++; + } + if (*rcv_wscale && sysctl_tcp_app_win && space>=mss && + space - max((space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2) + (*rcv_wscale)--; + } + + /* Set initial window to value enough for senders, + * following RFC1414. Senders, not following this RFC, + * will be satisfied with 2. + */ + if (mss > (1<<*rcv_wscale)) { + int init_cwnd = 4; + if (mss > 1460*3) + init_cwnd = 2; + else if (mss > 1460) + init_cwnd = 3; + if (*rcv_wnd > init_cwnd*mss) + *rcv_wnd = init_cwnd*mss; + } + /* Set the clamp no higher than max representable value */ + (*window_clamp) = min(65535U << (*rcv_wscale), *window_clamp); +} + +static inline int tcp_win_from_space(int space) +{ + return sysctl_tcp_adv_win_scale<=0 ? + (space>>(-sysctl_tcp_adv_win_scale)) : + space - (space>>sysctl_tcp_adv_win_scale); +} + +/* Note: caller must be prepared to deal with negative returns */ +static inline int tcp_space(struct sock *sk) +{ + return tcp_win_from_space(sk->rcvbuf - atomic_read(&sk->rmem_alloc)); +} + +static inline int tcp_full_space( struct sock *sk) +{ + return tcp_win_from_space(sk->rcvbuf); +} + +static inline void tcp_acceptq_removed(struct sock *sk) +{ + sk->ack_backlog--; +} + +static inline void tcp_acceptq_added(struct sock *sk) +{ + sk->ack_backlog++; +} + +static inline int tcp_acceptq_is_full(struct sock *sk) +{ + return sk->ack_backlog > sk->max_ack_backlog; +} + +static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req, + struct sock *child) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + req->sk = child; + tcp_acceptq_added(sk); + + if (!tp->accept_queue_tail) { + tp->accept_queue = req; + } else { + tp->accept_queue_tail->dl_next = req; + } + tp->accept_queue_tail = req; + req->dl_next = NULL; +} + +struct tcp_listen_opt +{ + u8 max_qlen_log; /* log_2 of maximal queued SYNs */ + int qlen; + int qlen_young; + int clock_hand; + struct open_request *syn_table[TCP_SYNQ_HSIZE]; +}; + +static inline void +tcp_synq_removed(struct sock *sk, struct open_request *req) +{ + struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt; + + if (--lopt->qlen == 0) + tcp_delete_keepalive_timer(sk); + if (req->retrans == 0) + lopt->qlen_young--; +} + +static inline void tcp_synq_added(struct sock *sk) +{ + struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt; + + if (lopt->qlen++ == 0) + tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT); + lopt->qlen_young++; +} + +static inline int tcp_synq_len(struct sock *sk) +{ + return sk->tp_pinfo.af_tcp.listen_opt->qlen; +} + +static inline int tcp_synq_young(struct sock *sk) +{ + return sk->tp_pinfo.af_tcp.listen_opt->qlen_young; +} + +static inline int tcp_synq_is_full(struct sock *sk) +{ + return tcp_synq_len(sk)>>sk->tp_pinfo.af_tcp.listen_opt->max_qlen_log; +} + +static inline void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req, + struct open_request **prev) +{ + write_lock(&tp->syn_wait_lock); + *prev = req->dl_next; + write_unlock(&tp->syn_wait_lock); +} + +static inline void tcp_synq_drop(struct sock *sk, struct open_request *req, + struct open_request **prev) +{ + tcp_synq_unlink(&sk->tp_pinfo.af_tcp, req, prev); + tcp_synq_removed(sk, req); + tcp_openreq_free(req); +} + +static __inline__ void tcp_openreq_init(struct open_request *req, + struct tcp_opt *tp, + struct sk_buff *skb) +{ + req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ + req->rcv_isn = TCP_SKB_CB(skb)->seq; + req->mss = tp->mss_clamp; + req->ts_recent = tp->saw_tstamp ? tp->rcv_tsval : 0; + req->tstamp_ok = tp->tstamp_ok; + req->sack_ok = tp->sack_ok; + req->snd_wscale = tp->snd_wscale; + req->wscale_ok = tp->wscale_ok; + req->acked = 0; + req->ecn_ok = 0; + req->rmt_port = skb->h.th->source; +} + +#define TCP_MEM_QUANTUM ((int)PAGE_SIZE) + +static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb) +{ + sk->tp_pinfo.af_tcp.queue_shrunk = 1; + sk->wmem_queued -= skb->truesize; + sk->forward_alloc += skb->truesize; + __kfree_skb(skb); +} + +static inline void tcp_charge_skb(struct sock *sk, struct sk_buff *skb) +{ + sk->wmem_queued += skb->truesize; + sk->forward_alloc -= skb->truesize; +} + +extern void __tcp_mem_reclaim(struct sock *sk); +extern int tcp_mem_schedule(struct sock *sk, int size, int kind); + +static inline void tcp_mem_reclaim(struct sock *sk) +{ + if (sk->forward_alloc >= TCP_MEM_QUANTUM) + __tcp_mem_reclaim(sk); +} + +static inline void tcp_enter_memory_pressure(void) +{ + if (!tcp_memory_pressure) { + NET_INC_STATS(TCPMemoryPressures); + tcp_memory_pressure = 1; + } +} + +static inline void tcp_moderate_sndbuf(struct sock *sk) +{ + if (!(sk->userlocks&SOCK_SNDBUF_LOCK)) { + sk->sndbuf = min(sk->sndbuf, sk->wmem_queued/2); + sk->sndbuf = max(sk->sndbuf, SOCK_MIN_SNDBUF); + } +} + +static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp) +{ + struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp); + + if (skb) { + skb->truesize += mem; + if (sk->forward_alloc >= (int)skb->truesize || + tcp_mem_schedule(sk, skb->truesize, 0)) { + skb_reserve(skb, MAX_TCP_HEADER); + return skb; + } + __kfree_skb(skb); + } else { + tcp_enter_memory_pressure(); + tcp_moderate_sndbuf(sk); + } + return NULL; +} + +static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp) +{ + return tcp_alloc_pskb(sk, size, 0, gfp); +} + +static inline struct page * tcp_alloc_page(struct sock *sk) +{ + if (sk->forward_alloc >= (int)PAGE_SIZE || + tcp_mem_schedule(sk, PAGE_SIZE, 0)) { + struct page *page = alloc_pages(sk->allocation, 0); + if (page) + return page; + } + tcp_enter_memory_pressure(); + tcp_moderate_sndbuf(sk); + return NULL; +} + +static inline void tcp_writequeue_purge(struct sock *sk) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&sk->write_queue)) != NULL) + tcp_free_skb(sk, skb); + tcp_mem_reclaim(sk); +} + +extern void tcp_rfree(struct sk_buff *skb); + +static inline void tcp_set_owner_r(struct sk_buff *skb, struct sock *sk) +{ + skb->sk = sk; + skb->destructor = tcp_rfree; + atomic_add(skb->truesize, &sk->rmem_alloc); + sk->forward_alloc -= skb->truesize; +} + +extern void tcp_listen_wlock(void); + +/* - We may sleep inside this lock. + * - If sleeping is not required (or called from BH), + * use plain read_(un)lock(&tcp_lhash_lock). + */ + +static inline void tcp_listen_lock(void) +{ + /* read_lock synchronizes to candidates to writers */ + read_lock(&tcp_lhash_lock); + atomic_inc(&tcp_lhash_users); + read_unlock(&tcp_lhash_lock); +} + +static inline void tcp_listen_unlock(void) +{ + if (atomic_dec_and_test(&tcp_lhash_users)) + wake_up(&tcp_lhash_wait); +} + +static inline int keepalive_intvl_when(struct tcp_opt *tp) +{ + return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl; +} + +static inline int keepalive_time_when(struct tcp_opt *tp) +{ + return tp->keepalive_time ? : sysctl_tcp_keepalive_time; +} + +static inline int tcp_fin_time(struct tcp_opt *tp) +{ + int fin_timeout = tp->linger2 ? : sysctl_tcp_fin_timeout; + + if (fin_timeout < (tp->rto<<2) - (tp->rto>>1)) + fin_timeout = (tp->rto<<2) - (tp->rto>>1); + + return fin_timeout; +} + +static inline int tcp_paws_check(struct tcp_opt *tp, int rst) +{ + if ((s32)(tp->rcv_tsval - tp->ts_recent) >= 0) + return 0; + if (xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS) + return 0; + + /* RST segments are not recommended to carry timestamp, + and, if they do, it is recommended to ignore PAWS because + "their cleanup function should take precedence over timestamps." + Certainly, it is mistake. It is necessary to understand the reasons + of this constraint to relax it: if peer reboots, clock may go + out-of-sync and half-open connections will not be reset. + Actually, the problem would be not existing if all + the implementations followed draft about maintaining clock + via reboots. Linux-2.2 DOES NOT! + + However, we can relax time bounds for RST segments to MSL. + */ + if (rst && xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_MSL) + return 0; + return 1; +} + +#define TCP_CHECK_TIMER(sk) do { } while (0) + +#endif /* _TCP_H */ diff --git a/release/src/linux/linux/include/net/tcp_ecn.h b/release/src/linux/linux/include/net/tcp_ecn.h new file mode 100644 index 00000000..d21c115a --- /dev/null +++ b/release/src/linux/linux/include/net/tcp_ecn.h @@ -0,0 +1,132 @@ +#ifndef _NET_TCP_ECN_H_ +#define _NET_TCP_ECN_H_ 1 + +#include <net/inet_ecn.h> + +#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) + +#define TCP_ECN_OK 1 +#define TCP_ECN_QUEUE_CWR 2 +#define TCP_ECN_DEMAND_CWR 4 + +static __inline__ void +TCP_ECN_queue_cwr(struct tcp_opt *tp) +{ + if (tp->ecn_flags&TCP_ECN_OK) + tp->ecn_flags |= TCP_ECN_QUEUE_CWR; +} + + +/* Output functions */ + +static __inline__ void +TCP_ECN_send_synack(struct tcp_opt *tp, struct sk_buff *skb) +{ + TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR; + if (!(tp->ecn_flags&TCP_ECN_OK)) + TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE; +} + +static __inline__ void +TCP_ECN_send_syn(struct tcp_opt *tp, struct sk_buff *skb) +{ + tp->ecn_flags = 0; + if (sysctl_tcp_ecn) { + TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE|TCPCB_FLAG_CWR; + tp->ecn_flags = TCP_ECN_OK; + } +} + +static __inline__ void +TCP_ECN_make_synack(struct open_request *req, struct tcphdr *th) +{ + if (req->ecn_ok) + th->ece = 1; +} + +static __inline__ void +TCP_ECN_send(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb, int tcp_header_len) +{ + if (tp->ecn_flags & TCP_ECN_OK) { + /* Not-retransmitted data segment: set ECT and inject CWR. */ + if (skb->len != tcp_header_len && + !before(TCP_SKB_CB(skb)->seq, tp->snd_nxt)) { + INET_ECN_xmit(sk); + if (tp->ecn_flags&TCP_ECN_QUEUE_CWR) { + tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR; + skb->h.th->cwr = 1; + } + } else { + /* ACK or retransmitted segment: clear ECT|CE */ + INET_ECN_dontxmit(sk); + } + if (tp->ecn_flags & TCP_ECN_DEMAND_CWR) + skb->h.th->ece = 1; + } +} + +/* Input functions */ + +static __inline__ void +TCP_ECN_accept_cwr(struct tcp_opt *tp, struct sk_buff *skb) +{ + if (skb->h.th->cwr) + tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; +} + +static __inline__ void +TCP_ECN_withdraw_cwr(struct tcp_opt *tp) +{ + tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; +} + +static __inline__ void +TCP_ECN_check_ce(struct tcp_opt *tp, struct sk_buff *skb) +{ + if (tp->ecn_flags&TCP_ECN_OK) { + if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags)) + tp->ecn_flags |= TCP_ECN_DEMAND_CWR; + /* Funny extension: if ECT is not set on a segment, + * it is surely retransmit. It is not in ECN RFC, + * but Linux follows this rule. */ + else if (!INET_ECN_is_capable((TCP_SKB_CB(skb)->flags))) + tcp_enter_quickack_mode(tp); + } +} + +static __inline__ void +TCP_ECN_rcv_synack(struct tcp_opt *tp, struct tcphdr *th) +{ + if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || th->cwr)) + tp->ecn_flags &= ~TCP_ECN_OK; +} + +static __inline__ void +TCP_ECN_rcv_syn(struct tcp_opt *tp, struct tcphdr *th) +{ + if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || !th->cwr)) + tp->ecn_flags &= ~TCP_ECN_OK; +} + +static __inline__ int +TCP_ECN_rcv_ecn_echo(struct tcp_opt *tp, struct tcphdr *th) +{ + if (th->ece && !th->syn && (tp->ecn_flags&TCP_ECN_OK)) + return 1; + return 0; +} + +static __inline__ void +TCP_ECN_openreq_child(struct tcp_opt *tp, struct open_request *req) +{ + tp->ecn_flags = req->ecn_ok ? TCP_ECN_OK : 0; +} + +static __inline__ void +TCP_ECN_create_request(struct open_request *req, struct tcphdr *th) +{ + if (sysctl_tcp_ecn && th->ece && th->cwr) + req->ecn_ok = 1; +} + +#endif diff --git a/release/src/linux/linux/include/net/transp_v6.h b/release/src/linux/linux/include/net/transp_v6.h new file mode 100644 index 00000000..d49bc86e --- /dev/null +++ b/release/src/linux/linux/include/net/transp_v6.h @@ -0,0 +1,46 @@ +#ifndef _TRANSP_V6_H +#define _TRANSP_V6_H + +#include <net/checksum.h> + +/* + * IPv6 transport protocols + */ + +#ifdef __KERNEL__ + +extern struct proto rawv6_prot; +extern struct proto udpv6_prot; +extern struct proto tcpv6_prot; + +struct flowi; + +extern void rawv6_init(void); +extern void udpv6_init(void); +extern void tcpv6_init(void); + +extern int udpv6_connect(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + +extern int datagram_recv_ctl(struct sock *sk, + struct msghdr *msg, + struct sk_buff *skb); + +extern int datagram_send_ctl(struct msghdr *msg, + struct flowi *fl, + struct ipv6_txoptions *opt, + int *hlimit); + +#define LOOPBACK4_IPV6 __constant_htonl(0x7f000006) + +/* + * address family specific functions + */ +extern struct tcp_func ipv4_specific; + +extern int inet6_destroy_sock(struct sock *sk); + +#endif + +#endif diff --git a/release/src/linux/linux/include/net/udp.h b/release/src/linux/linux/include/net/udp.h new file mode 100644 index 00000000..d27b8e7e --- /dev/null +++ b/release/src/linux/linux/include/net/udp.h @@ -0,0 +1,77 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the UDP module. + * + * Version: @(#)udp.h 1.0.2 05/07/93 + * + * Authors: Ross Biro, <bir7@leland.Stanford.Edu> + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * + * Fixes: + * Alan Cox : Turned on udp checksums. I don't want to + * chase 'memory corruption' bugs that aren't! + * + * 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. + */ +#ifndef _UDP_H +#define _UDP_H + +#include <linux/udp.h> +#include <net/sock.h> + +#define UDP_HTABLE_SIZE 128 + +/* udp.c: This needs to be shared by v4 and v6 because the lookup + * and hashing code needs to work with different AF's yet + * the port space is shared. + */ +extern struct sock *udp_hash[UDP_HTABLE_SIZE]; +extern rwlock_t udp_hash_lock; + +extern int udp_port_rover; + +static inline int udp_lport_inuse(u16 num) +{ + struct sock *sk = udp_hash[num & (UDP_HTABLE_SIZE - 1)]; + + for(; sk != NULL; sk = sk->next) { + if(sk->num == num) + return 1; + } + return 0; +} + +/* Note: this must match 'valbool' in sock_setsockopt */ +#define UDP_CSUM_NOXMIT 1 + +/* Used by SunRPC/xprt layer. */ +#define UDP_CSUM_NORCV 2 + +/* Default, as per the RFC, is to always do csums. */ +#define UDP_CSUM_DEFAULT 0 + +extern struct proto udp_prot; + + +extern void udp_err(struct sk_buff *, u32); +extern int udp_connect(struct sock *sk, + struct sockaddr *usin, int addr_len); + +extern int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len); + +extern int udp_rcv(struct sk_buff *skb); +extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern int udp_disconnect(struct sock *sk, int flags); + +extern struct udp_mib udp_statistics[NR_CPUS*2]; +#define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field) +#define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field) +#define UDP_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_statistics, field) + +#endif /* _UDP_H */ diff --git a/release/src/linux/linux/include/net/x25.h b/release/src/linux/linux/include/net/x25.h new file mode 100644 index 00000000..2e1e8842 --- /dev/null +++ b/release/src/linux/linux/include/net/x25.h @@ -0,0 +1,229 @@ +/* + * Declarations of X.25 Packet Layer type objects. + * + * History + * nov/17/96 Jonathan Naylor Initial version. + * mar/20/00 Daniela Squassoni Disabling/enabling of facilities + * negotiation. + */ + +#ifndef _X25_H +#define _X25_H +#include <linux/x25.h> + +#define X25_ADDR_LEN 16 + +#define X25_MAX_L2_LEN 18 /* 802.2 LLC */ + +#define X25_STD_MIN_LEN 3 +#define X25_EXT_MIN_LEN 4 + +#define X25_GFI_SEQ_MASK 0x30 +#define X25_GFI_STDSEQ 0x10 +#define X25_GFI_EXTSEQ 0x20 + +#define X25_Q_BIT 0x80 +#define X25_D_BIT 0x40 +#define X25_STD_M_BIT 0x10 +#define X25_EXT_M_BIT 0x01 + +#define X25_CALL_REQUEST 0x0B +#define X25_CALL_ACCEPTED 0x0F +#define X25_CLEAR_REQUEST 0x13 +#define X25_CLEAR_CONFIRMATION 0x17 +#define X25_DATA 0x00 +#define X25_INTERRUPT 0x23 +#define X25_INTERRUPT_CONFIRMATION 0x27 +#define X25_RR 0x01 +#define X25_RNR 0x05 +#define X25_REJ 0x09 +#define X25_RESET_REQUEST 0x1B +#define X25_RESET_CONFIRMATION 0x1F +#define X25_REGISTRATION_REQUEST 0xF3 +#define X25_REGISTRATION_CONFIRMATION 0xF7 +#define X25_RESTART_REQUEST 0xFB +#define X25_RESTART_CONFIRMATION 0xFF +#define X25_DIAGNOSTIC 0xF1 +#define X25_ILLEGAL 0xFD + +/* Define the various conditions that may exist */ + +#define X25_COND_ACK_PENDING 0x01 +#define X25_COND_OWN_RX_BUSY 0x02 +#define X25_COND_PEER_RX_BUSY 0x04 + +/* Define Link State constants. */ +enum { + X25_STATE_0, /* Ready */ + X25_STATE_1, /* Awaiting Call Accepted */ + X25_STATE_2, /* Awaiting Clear Confirmation */ + X25_STATE_3, /* Data Transfer */ + X25_STATE_4 /* Awaiting Reset Confirmation */ +}; + +enum { + X25_LINK_STATE_0, + X25_LINK_STATE_1, + X25_LINK_STATE_2, + X25_LINK_STATE_3 +}; + +#define X25_DEFAULT_T20 (180 * HZ) /* Default T20 value */ +#define X25_DEFAULT_T21 (200 * HZ) /* Default T21 value */ +#define X25_DEFAULT_T22 (180 * HZ) /* Default T22 value */ +#define X25_DEFAULT_T23 (180 * HZ) /* Default T23 value */ +#define X25_DEFAULT_T2 (3 * HZ) /* Default ack holdback value */ + +#define X25_DEFAULT_WINDOW_SIZE 2 /* Default Window Size */ +#define X25_DEFAULT_PACKET_SIZE X25_PS128 /* Default Packet Size */ +#define X25_DEFAULT_THROUGHPUT 0x0A /* Deafult Throughput */ +#define X25_DEFAULT_REVERSE 0x00 /* Default Reverse Charging */ + +#define X25_SMODULUS 8 +#define X25_EMODULUS 128 + +/* + * X.25 Facilities constants. + */ + +#define X25_FAC_CLASS_MASK 0xC0 + +#define X25_FAC_CLASS_A 0x00 +#define X25_FAC_CLASS_B 0x40 +#define X25_FAC_CLASS_C 0x80 +#define X25_FAC_CLASS_D 0xC0 + +#define X25_FAC_REVERSE 0x01 +#define X25_FAC_THROUGHPUT 0x02 +#define X25_FAC_PACKET_SIZE 0x42 +#define X25_FAC_WINDOW_SIZE 0x43 + +#define X25_MAX_FAC_LEN 20 /* Plenty to spare */ +#define X25_MAX_CUD_LEN 128 + +struct x25_route { + struct x25_route *next; + x25_address address; /* Start of address range */ + unsigned int sigdigits; /* Number of sig digits */ + struct net_device *dev; /* More than one for MLP */ +}; + +struct x25_neigh { + struct x25_neigh *next; + struct net_device *dev; + unsigned int state; + unsigned int extended; + struct sk_buff_head queue; + unsigned long t20; + struct timer_list t20timer; + unsigned long global_facil_mask; +}; + +typedef struct { + x25_address source_addr, dest_addr; + struct x25_neigh *neighbour; + unsigned int lci; + unsigned char state, condition, qbitincl, intflag; + unsigned short vs, vr, va, vl; + unsigned long t2, t21, t22, t23; + unsigned short fraglen; + struct sk_buff_head ack_queue; + struct sk_buff_head fragment_queue; + struct sk_buff_head interrupt_in_queue; + struct sk_buff_head interrupt_out_queue; + struct sock *sk; /* Backlink to socket */ + struct timer_list timer; + struct x25_causediag causediag; + struct x25_facilities facilities; + struct x25_calluserdata calluserdata; + unsigned long vc_facil_mask; /* inc_call facilities mask */ +} x25_cb; + +/* af_x25.c */ +extern int sysctl_x25_restart_request_timeout; +extern int sysctl_x25_call_request_timeout; +extern int sysctl_x25_reset_request_timeout; +extern int sysctl_x25_clear_request_timeout; +extern int sysctl_x25_ack_holdback_timeout; + +extern int x25_addr_ntoa(unsigned char *, x25_address *, x25_address *); +extern int x25_addr_aton(unsigned char *, x25_address *, x25_address *); +extern unsigned int x25_new_lci(struct x25_neigh *); +extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *); +extern void x25_destroy_socket(struct sock *); +extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int); +extern void x25_kill_by_neigh(struct x25_neigh *); + +/* x25_dev.c */ +extern void x25_send_frame(struct sk_buff *, struct x25_neigh *); +extern int x25_lapb_receive_frame(struct sk_buff *, struct net_device *, struct packet_type *); +extern int x25_llc_receive_frame(struct sk_buff *, struct net_device *, struct packet_type *); +extern void x25_establish_link(struct x25_neigh *); +extern void x25_terminate_link(struct x25_neigh *); + +/* x25_facilities.c */ +extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, unsigned long *); +extern int x25_create_facilities(unsigned char *, struct x25_facilities *, unsigned long); +extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *); +extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *); + +/* x25_in.c */ +extern int x25_process_rx_frame(struct sock *, struct sk_buff *); +extern int x25_backlog_rcv(struct sock *, struct sk_buff *); + +/* x25_link.c */ +extern void x25_link_control(struct sk_buff *, struct x25_neigh *, unsigned short); +extern void x25_link_device_up(struct net_device *); +extern void x25_link_device_down(struct net_device *); +extern void x25_link_established(struct x25_neigh *); +extern void x25_link_terminated(struct x25_neigh *); +extern void x25_transmit_restart_request(struct x25_neigh *); +extern void x25_transmit_restart_confirmation(struct x25_neigh *); +extern void x25_transmit_diagnostic(struct x25_neigh *, unsigned char); +extern void x25_transmit_clear_request(struct x25_neigh *, unsigned int, unsigned char); +extern void x25_transmit_link(struct sk_buff *, struct x25_neigh *); +extern int x25_subscr_ioctl(unsigned int, void *); +extern struct x25_neigh *x25_get_neigh(struct net_device *); +extern void x25_link_free(void); + +/* x25_out.c */ +extern int x25_output(struct sock *, struct sk_buff *); +extern void x25_kick(struct sock *); +extern void x25_enquiry_response(struct sock *); + +/* x25_route.c */ +extern struct net_device *x25_get_route(x25_address *); +extern struct net_device *x25_dev_get(char *); +extern void x25_route_device_down(struct net_device *); +extern int x25_route_ioctl(unsigned int, void *); +extern int x25_routes_get_info(char *, char **, off_t, int); +extern void x25_route_free(void); + +/* x25_subr.c */ +extern void x25_clear_queues(struct sock *); +extern void x25_frames_acked(struct sock *, unsigned short); +extern void x25_requeue_frames(struct sock *); +extern int x25_validate_nr(struct sock *, unsigned short); +extern void x25_write_internal(struct sock *, int); +extern int x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int *, int *); +extern void x25_disconnect(struct sock *, int, unsigned char, unsigned char); + +/* x25_timer.c */ +extern void x25_start_heartbeat(struct sock *); +extern void x25_start_t2timer(struct sock *); +extern void x25_start_t21timer(struct sock *); +extern void x25_start_t22timer(struct sock *); +extern void x25_start_t23timer(struct sock *); +extern void x25_stop_heartbeat(struct sock *); +extern void x25_stop_timer(struct sock *); +extern unsigned long x25_display_timer(struct sock *); +extern void x25_check_rbuf(struct sock *); + +/* sysctl_net_x25.c */ +extern void x25_register_sysctl(void); +extern void x25_unregister_sysctl(void); +struct x25_skb_cb { + unsigned flags; +}; +#define X25_SKB_CB(s) ((struct x25_skb_cb *) ((s)->cb)) +#endif |