diff options
Diffstat (limited to 'include/net')
32 files changed, 434 insertions, 259 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index d711d0d51..730fe97b4 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -56,7 +56,7 @@ extern struct inet6_ifaddr * ipv6_chk_addr(struct in6_addr *addr, extern int ipv6_get_saddr(struct dst_entry *dst, struct in6_addr *daddr, struct in6_addr *saddr); -extern struct inet6_ifaddr * ipv6_get_lladdr(struct device *dev); +extern int ipv6_get_lladdr(struct device *dev, struct in6_addr *); /* * multicast prototypes (mcast.c) @@ -68,6 +68,7 @@ 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 device *dev, struct in6_addr *addr); diff --git a/include/net/dst.h b/include/net/dst.h index baf4f414d..d34eb5079 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -77,9 +77,6 @@ struct dst_ops #ifdef __KERNEL__ -extern struct dst_entry * dst_garbage_list; -extern atomic_t dst_total; - extern __inline__ struct dst_entry * dst_clone(struct dst_entry * dst) { @@ -173,6 +170,9 @@ extern __inline__ void dst_set_expires(struct dst_entry *dst, int timeout) 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/include/net/if_inet6.h b/include/net/if_inet6.h index 4e9ed9780..3702028b6 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -44,6 +44,7 @@ struct inet6_ifaddr __u32 valid_lft; __u32 prefered_lft; unsigned long tstamp; + atomic_t refcnt; __u8 probes; __u8 flags; @@ -108,6 +109,7 @@ struct inet6_dev struct inet6_ifaddr *addr_list; struct ifmcaddr6 *mc_list; + rwlock_t lock; __u32 if_flags; struct neigh_parms *nd_parms; diff --git a/include/net/ip.h b/include/net/ip.h index 5e80fb438..c078484c3 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -83,7 +83,6 @@ extern int ip_mc_procinfo(char *, char **, off_t, int, int); * Functions provided by ip.c */ -extern int ip_ioctl(struct sock *sk, int cmd, unsigned long arg); extern void ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, u32 saddr, u32 daddr, struct ip_options *opt); @@ -147,10 +146,10 @@ extern __inline__ int ip_finish_output(struct sk_buff *skb) skb->protocol = __constant_htons(ETH_P_IP); if (hh) { - read_lock_irq(&hh->hh_lock); + read_lock_bh(&hh->hh_lock); memcpy(skb->data - 16, hh->hh_data, 16); - read_unlock_irq(&hh->hh_lock); - skb_push(skb, dev->hard_header_len); + read_unlock_bh(&hh->hh_lock); + skb_push(skb, hh->hh_len); return hh->hh_output(skb); } else if (dst->neighbour) return dst->neighbour->output(skb); diff --git a/include/net/ip_masq.h b/include/net/ip_masq.h index 9c8e9bf94..518e5c4d8 100644 --- a/include/net/ip_masq.h +++ b/include/net/ip_masq.h @@ -231,24 +231,6 @@ extern void ip_masq_put(struct ip_masq *ms); extern rwlock_t __ip_masq_lock; -#ifdef __SMP__ -#define read_lock_bh(lock) do { start_bh_atomic(); read_lock(lock); \ - } while (0) -#define read_unlock_bh(lock) do { read_unlock(lock); end_bh_atomic(); \ - } while (0) -#define write_lock_bh(lock) do { start_bh_atomic(); write_lock(lock); \ - } while (0) -#define write_unlock_bh(lock) do { write_unlock(lock); end_bh_atomic(); \ - } while (0) -#else -#define read_lock_bh(lock) start_bh_atomic() -#define read_unlock_bh(lock) end_bh_atomic() -#define write_lock_bh(lock) start_bh_atomic() -#define write_unlock_bh(lock) end_bh_atomic() -#endif -/* - * - */ /* * Debugging stuff diff --git a/include/net/irda/crc.h b/include/net/irda/crc.h index d4ee011e4..61a5a6488 100644 --- a/include/net/irda/crc.h +++ b/include/net/irda/crc.h @@ -6,25 +6,28 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Aug 4 20:40:53 1997 - * Modified at: Tue Dec 15 22:18:53 1998 + * Modified at: Sun May 2 20:25:23 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * ********************************************************************/ -#ifndef IR_CRC_H -#define IR_CRC_H +#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. */ -#define IR_FCS(fcs, c) (((fcs) >> 8) ^ irda_crc16_table[((fcs) ^ (c)) & 0xff]) +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); -extern __u16 const irda_crc16_table[]; - #endif diff --git a/include/net/irda/dongle.h b/include/net/irda/dongle.h index d8983c009..82f129fca 100644 --- a/include/net/irda/dongle.h +++ b/include/net/irda/dongle.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Oct 21 22:47:12 1998 - * Modified at: Sat Feb 6 07:37:49 1999 + * Modified at: Sun May 16 13:40:03 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli, All Rights Reserved. + * 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 @@ -26,7 +26,6 @@ #define DONGLE_H #include <net/irda/qos.h> -#include <net/irda/irda_device.h> /* These are the currently known dongles */ typedef enum { @@ -35,13 +34,16 @@ typedef enum { ACTISYS_DONGLE, ACTISYS_PLUS_DONGLE, GIRBIL_DONGLE, -} DONGLE_T; + LITELINK_DONGLE, +} IRDA_DONGLE; + +struct irda_device; struct dongle { - DONGLE_T type; + IRDA_DONGLE type; void (*open)(struct irda_device *, int type); void (*close)(struct irda_device *); - void (*reset)( struct irda_device *, int unused); + void (*reset)( struct irda_device *); void (*change_speed)( struct irda_device *, int baudrate); void (*qos_init)( struct irda_device *, struct qos_info *); }; diff --git a/include/net/irda/ircomm_common.h b/include/net/irda/ircomm_common.h index cd1c41f86..44d1b1774 100644 --- a/include/net/irda/ircomm_common.h +++ b/include/net/irda/ircomm_common.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Takahide Higuchi <thiguchi@pluto.dti.ne.jp> * - * Copyright (c) 1998, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>, + * Copyright (c) 1998-1999, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>, * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -77,9 +77,9 @@ typedef enum { #define IRCOMM_MAGIC 0x434f4d4d #define COMM_INIT_CTRL_PARAM 3 /* length of initial control parameters */ -#define COMM_HEADER 1 /* length of clen field */ -#define COMM_HEADER_SIZE (LAP_HEADER+LMP_HEADER+TTP_HEADER+COMM_HEADER) -#define COMM_DEFAULT_DATA_SIZE 64 +#define COMM_HEADER_SIZE 1 /* length of clen field */ +#define COMM_MAX_HEADER_SIZE (TTP_MAX_HEADER+COMM_HEADER_SIZE) +#define COMM_DEFAULT_SDU_SIZE (64 - COMM_HEADER_SIZE) #define IRCOMM_MAX_CONNECTION 1 /* Don't change for now */ @@ -167,7 +167,7 @@ typedef enum { #define LSR_BI 0x01 /* Break interrupt indicator */ -struct ircomm_cb{ +struct ircomm_cb { int magic; int state; /* Current state of IrCOMM layer: * DISCOVERY,COMM_IDLE, COMM_WAITR, @@ -177,8 +177,9 @@ struct ircomm_cb{ int null_modem_mode; /* switch for null modem emulation */ int ttp_stop; - int max_txbuff_size; - __u32 maxsdusize; + __u32 tx_max_sdu_size; + __u32 rx_max_sdu_size; + __u8 max_header_size; __u32 daddr; /* Device address of the peer device */ __u32 saddr; @@ -201,8 +202,8 @@ struct ircomm_cb{ see Irlmp.c or somewhere :p)*/ int peer_cap; /* capability of peer device */ - struct wait_queue *discovery_wait; - struct wait_queue *ias_wait; + wait_queue_head_t discovery_wait; + wait_queue_head_t ias_wait; /* statistics */ int tx_packets; @@ -211,8 +212,6 @@ struct ircomm_cb{ int pending_control_tuples; int ignored_control_tuples; - - __u8 pi ; /* instruction of control channel*/ __u8 port_type; @@ -253,8 +252,6 @@ struct ircomm_cb{ int port_name_critical; }; - - void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype); void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata, __u32 maxsdusize); diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index 35c15fadc..b0e67385b 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Dec 9 21:13:12 1997 - * Modified at: Wed Apr 21 17:49:00 1999 + * Modified at: Mon May 10 09:51:13 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli, All Rights Reserved. + * 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 @@ -109,6 +109,8 @@ struct irda_sock { __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 */ @@ -122,7 +124,7 @@ struct irda_sock { int errno; struct sock *sk; - struct wait_queue *ias_wait; /* Wait for LM-IAS answer */ + wait_queue_head_t ias_wait; /* Wait for LM-IAS answer */ LOCAL_FLOW tx_flow; LOCAL_FLOW rx_flow; @@ -225,10 +227,10 @@ struct notify_t { 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, - struct sk_buff *skb); + __u8 max_header_size, struct sk_buff *skb); void (*connect_indication)(void *instance, void *sap, struct qos_info *qos, __u32 max_sdu_size, - struct sk_buff *skb); + __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); diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h index a3dcf2d6e..5272633f7 100644 --- a/include/net/irda/irda_device.h +++ b/include/net/irda/irda_device.h @@ -4,24 +4,29 @@ * Version: * Description: * Status: Experimental. - * Author: Haris Zukanovic <haris@stud.cs.uit.no> + * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Apr 14 12:41:42 1998 - * Modified at: Tue Apr 20 11:06:28 1999 + * Modified at: Wed May 19 08:44:48 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Haris Zukanovic, <haris@stud.cs.uit.no> - * Copyright (c) 1998 Dag Brattli, <dagb@cs.uit.no> + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. * Copyright (c) 1998 Thomas Davis, <ratbert@radiks.net>, - * All Rights Reserved. - * + * Copyright (c) 1998 Haris Zukanovic, <haris@stud.cs.uit.no> + * * 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 Haris Zukanovic nor University of Tromsų admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. + * + * 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 * ********************************************************************/ @@ -35,6 +40,7 @@ #include <net/irda/irda.h> #include <net/irda/qos.h> +#include <net/irda/dongle.h> #include <net/irda/irqueue.h> #include <net/irda/irlap_frame.h> @@ -52,6 +58,11 @@ #define IO_XMIT 0x01 #define IO_RECV 0x02 +struct dongle_q { + QUEUE q; + struct dongle *dongle; +}; + /* Chip specific info */ struct chipio_t { int iobase, iobase2; /* IO base */ @@ -111,16 +122,19 @@ struct irda_device { struct iobuff_t tx_buff; struct iobuff_t rx_buff; - /* spinlock_t lock; */ /* For serializing operations */ + struct dongle *dongle; /* Dongle driver */ + + spinlock_t lock; /* For serializing operations */ /* Media busy stuff */ int media_busy; struct timer_list media_busy_timer; /* Callbacks for driver specific implementation */ - void (*change_speed)(struct irda_device *driver, int baud); + void (*change_speed)(struct irda_device *idev, int baud); int (*is_receiving)(struct irda_device *); /* receiving? */ - /* int (*is_tbusy)(struct irda_device *); */ /* transmitting? */ + void (*set_dtr_rts)(struct irda_device *idev, int dtr, int rts); + int (*raw_write)(struct irda_device *idev, __u8 *buf, int len); void (*wait_until_sent)(struct irda_device *); void (*set_caddr)(struct irda_device *); /* Set connection addr */ }; @@ -142,6 +156,9 @@ inline void irda_device_change_speed(struct irda_device *, int); inline struct qos_info *irda_device_get_qos(struct irda_device *self); int irda_device_txqueue_empty(struct irda_device *self); +void irda_device_init_dongle(struct irda_device *self, int type); +void irda_device_unregister_dongle(struct dongle *dongle); +int irda_device_register_dongle(struct dongle *dongle); int irda_device_setup(struct device *dev); @@ -153,7 +170,7 @@ void setup_dma(int channel, char *buffer, int count, int mode); * Utility function for getting the minimum turnaround time out of * the skb, where it has been hidden in the cb field. */ -inline static __u16 irda_get_mtt(struct sk_buff *skb) +extern inline __u16 irda_get_mtt(struct sk_buff *skb) { __u16 mtt; @@ -167,6 +184,23 @@ inline static __u16 irda_get_mtt(struct sk_buff *skb) return mtt; } +extern inline void irda_device_set_dtr_rts(struct irda_device *self, int dtr, + int rts) +{ + if (self->set_dtr_rts) + self->set_dtr_rts(self, dtr, rts); +} + +extern inline int irda_device_raw_write(struct irda_device *self, __u8 *buf, + int len) +{ + int ret = -1; + + if (self->raw_write) + ret = self->raw_write(self, buf, len); + return ret; +} + #endif diff --git a/include/net/irda/iriap.h b/include/net/irda/iriap.h index 071ed8561..355751afa 100644 --- a/include/net/irda/iriap.h +++ b/include/net/irda/iriap.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Thu Aug 21 00:02:07 1997 - * Modified at: Wed Apr 21 16:37:21 1999 + * Modified at: Sun May 9 10:56:57 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * 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 @@ -81,6 +81,8 @@ struct iriap_cb { CONFIRM_CALLBACK confirm; void *priv; + __u8 max_header_size; + struct timer_list watchdog_timer; }; @@ -92,8 +94,6 @@ void iriap_getvaluebyclass_request( char *name, char *attr, void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb); void iriap_send_ack( struct iriap_cb *self); -void iriap_connect_confirm(void *instance, void *sap, struct qos_info *qos, - __u32 max_sdu_size, struct sk_buff *skb); void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb); void iriap_register_server(void); diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h index 35d83096f..fc343e5c0 100644 --- a/include/net/irda/irlan_common.h +++ b/include/net/irda/irlan_common.h @@ -6,10 +6,11 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:37 1997 - * Modified at: Thu Apr 22 14:30:37 1999 + * Modified at: Mon May 31 13:54:20 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * 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 @@ -98,7 +99,7 @@ #define IRLAN_SHORT 1 #define IRLAN_ARRAY 2 -#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_HEADER) +#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_MAX_HEADER) /* * IrLAN client @@ -109,7 +110,10 @@ struct irlan_client_cb { 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; @@ -120,6 +124,9 @@ struct irlan_client_cb { int unicast_open; int broadcast_open; + int tx_busy; + struct sk_buff_head txq; /* Transmit control queue */ + struct timer_list kick_timer; }; @@ -130,6 +137,8 @@ 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 @@ -140,42 +149,45 @@ struct irlan_provider_cb { 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 + * IrLAN control block */ struct irlan_cb { QUEUE queue; /* Must be first */ int magic; char ifname[9]; - struct device dev; /* Ethernet device structure*/ + struct device dev; /* Ethernet device structure*/ struct enet_statistics stats; - __u32 saddr; /* Source devcie address */ - __u32 daddr; /* Destination device address */ + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ int netdev_registered; int notify_irmanager; - int media; /* Media type */ - int access_type; /* Currently used access type */ - __u8 version[2]; /* IrLAN version */ + int media; /* Media type */ + __u8 version[2]; /* IrLAN version */ struct tsap_cb *tsap_data; - int use_udata; /* Use Unit Data transfers */ + int master; /* Master instance? */ + 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 */ + __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_client_cb client; /* Client specific fields */ struct irlan_provider_cb provider; /* Provider specific fields */ + + __u32 max_sdu_size; + __u8 max_header_size; struct timer_list watchdog_timer; }; @@ -192,6 +204,8 @@ 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); diff --git a/include/net/irda/irlan_eth.h b/include/net/irda/irlan_eth.h index 6ad33ee48..376df91ff 100644 --- a/include/net/irda/irlan_eth.h +++ b/include/net/irda/irlan_eth.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Thu Oct 15 08:36:58 1998 - * Modified at: Thu Apr 22 14:09:37 1999 + * Modified at: Fri May 14 23:29:00 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli, All Rights Reserved. + * 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 @@ -32,6 +32,7 @@ int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb); int irlan_eth_xmit(struct sk_buff *skb, struct device *dev); void irlan_eth_flow_indication( void *instance, void *sap, LOCAL_FLOW flow); +void irlan_eth_send_gratuitous_arp(struct device *dev); void irlan_eth_set_multicast_list( struct device *dev); struct enet_statistics *irlan_eth_get_stats(struct device *dev); diff --git a/include/net/irda/irlan_provider.h b/include/net/irda/irlan_provider.h index aafbf9141..ca51d5b7c 100644 --- a/include/net/irda/irlan_provider.h +++ b/include/net/irda/irlan_provider.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:37 1997 - * Modified at: Thu Apr 22 14:29:16 1999 + * Modified at: Sun May 9 12:26:11 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * 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 @@ -36,13 +36,7 @@ void irlan_provider_ctrl_disconnect_indication(void *instance, void *sap, LM_REASON reason, struct sk_buff *skb); -void irlan_provider_ctrl_data_indication(void *instance, void *sap, - struct sk_buff *skb); -void irlan_provider_connect_indication(void *instance, void *sap, - struct qos_info *qos, - __u32 max_sdu_size, - 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); diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h index f3b26110f..c5767397e 100644 --- a/include/net/irda/irlap.h +++ b/include/net/irda/irlap.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Aug 4 20:40:53 1997 - * Modified at: Fri Apr 23 09:51:15 1999 + * Modified at: Sun May 9 11:38:18 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * 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 @@ -42,11 +42,11 @@ #define LAP_COMP_HEADER 1 /* IrLAP Compression Header */ #ifdef CONFIG_IRDA_COMPRESSION -# define LAP_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER + LAP_COMP_HEADER) +# define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER + LAP_COMP_HEADER) # define IRDA_COMPRESSED 1 # define IRDA_NORMAL 0 #else -#define LAP_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER) +#define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER) #endif #define BROADCAST 0xffffffff /* Broadcast device address */ @@ -138,7 +138,7 @@ struct irlap_cb { __u8 vs; /* Next frame to be sent */ __u8 vr; /* Next frame to be received */ - int tmp; +/* int tmp; */ __u8 va; /* Last frame acked */ int window; /* Nr of I-frames allowed to send */ int window_size; /* Current negotiated window size */ @@ -155,8 +155,7 @@ struct irlap_cb { __u8 s; /* Current slot */ int frame_sent; /* Have we sent reply? */ - int discovery_count; - hashbin_t *discovery_log; + hashbin_t *discovery_log; discovery_t *discovery_cmd; struct qos_info qos_tx; /* QoS requested by peer */ @@ -227,4 +226,9 @@ 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 *, struct qos_info *); +extern inline __u8 irlap_get_header_size(struct irlap_cb *self) +{ + return 2; +} + #endif diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h index 31785883a..e879c6b94 100644 --- a/include/net/irda/irlmp.h +++ b/include/net/irda/irlmp.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 17 20:54:32 1997 - * Modified at: Fri Apr 23 09:15:07 1999 + * Modified at: Sun May 9 11:01:34 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * 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 @@ -52,7 +52,7 @@ #define LMP_HEADER 2 /* Dest LSAP + Source LSAP */ #define LMP_CONTROL_HEADER 4 -#define LMP_MAX_HEADER (LAP_HEADER+LMP_HEADER) +#define LMP_MAX_HEADER (LMP_CONTROL_HEADER+LAP_MAX_HEADER) #define LM_MAX_CONNECTIONS 10 diff --git a/include/net/irda/irlpt_common.h b/include/net/irda/irlpt_common.h index 83a9c307c..25ad8ef01 100644 --- a/include/net/irda/irlpt_common.h +++ b/include/net/irda/irlpt_common.h @@ -46,7 +46,7 @@ extern char *irlpt_client_fsm_state[]; extern char *irlpt_server_fsm_state[]; extern char *irlpt_fsm_event[]; -extern struct wait_queue *lpt_wait; +extern wait_queue_head_t lpt_wait; extern struct irlpt_cb *irlpt_find_handle(unsigned int minor); extern void irlpt_flow_control(struct sk_buff *skb); @@ -158,12 +158,13 @@ struct irlpt_cb { struct miscdevice ir_dev; /* used to register the misc device. */ int count; /* open count */ - int irlap_data_size; /* max frame size we can send */ + int max_data_size; /* max frame size we can send */ + int max_header_size; /* how much header space is needed */ int pkt_count; /* how many packets are queued up */ - struct wait_queue *read_wait; /* wait queues */ - struct wait_queue *write_wait; - struct wait_queue *ex_wait; + wait_queue_head_t read_wait; /* wait queues */ + wait_queue_head_t write_wait; + wait_queue_head_t ex_wait; /* this is used to remove the printer when it's gone */ struct timer_list lpt_timer; diff --git a/include/net/irda/irmod.h b/include/net/irda/irmod.h index 651e87dbc..9612a5572 100644 --- a/include/net/irda/irmod.h +++ b/include/net/irda/irmod.h @@ -90,7 +90,7 @@ struct irda_todo { */ struct irda_cb { struct miscdevice dev; - struct wait_queue *wait_queue; + wait_queue_head_t *wait_queue; int in_use; diff --git a/include/net/irda/irport.h b/include/net/irda/irport.h index c4a036a4d..0912e0496 100644 --- a/include/net/irda/irport.h +++ b/include/net/irda/irport.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Thu Jan 7 14:17:31 1999 + * Modified at: Wed May 19 15:31:16 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1997, 1998 Dag Brattli <dagb@cs.uit.no> + * Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no> * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -49,13 +49,14 @@ #define FRAME_MAX_SIZE 2048 -void irport_close( int iobase); -int irport_open( int iobase); -int irport_detect(struct irda_device *idev); +void irport_start(struct irda_device *idev, int iobase); +void irport_stop(struct irda_device *idev, int iobase); +int irport_probe(int iobase); -void irport_change_speed( int iobase, int speed); +void irport_change_speed(struct irda_device *idev, int speed); void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs); -int irport_hard_xmit( struct sk_buff *skb, struct device *dev); +int irport_hard_xmit(struct sk_buff *skb, struct device *dev); +void irport_wait_until_sent(struct irda_device *idev); #endif diff --git a/include/net/irda/irqueue.h b/include/net/irda/irqueue.h index 1e208ccf4..523de0db6 100644 --- a/include/net/irda/irqueue.h +++ b/include/net/irda/irqueue.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Jun 9 13:26:50 1998 - * Modified at: Thu Feb 25 20:34:21 1999 + * Modified at: Tue May 25 07:54:41 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (C) 1998, Aage Kvalnes <aage@cs.uit.no> @@ -30,8 +30,6 @@ #include <linux/types.h> #include <asm/spinlock.h> -/* #include <net/irda/irda.h> */ - #ifndef QUEUE_H #define QUEUE_H diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index aec1d57dc..3e6511cea 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:31 1997 - * Modified at: Sat Apr 10 10:19:56 1999 + * Modified at: Mon May 10 19:14:51 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * 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 @@ -36,7 +36,8 @@ #define TTP_MAX_CONNECTIONS LM_MAX_CONNECTIONS #define TTP_HEADER 1 -#define TTP_HEADER_WITH_SAR 6 +#define TTP_MAX_HEADER (TTP_HEADER + LMP_MAX_HEADER) +#define TTP_SAR_HEADER 5 #define TTP_PARAMETERS 0x80 #define TTP_MORE 0x80 @@ -61,8 +62,6 @@ struct tsap_cb { QUEUE queue; /* For linking it into the hashbin */ int magic; /* Just in case */ - int max_seg_size; /* Max data that fit into an IrLAP frame */ - __u8 stsap_sel; /* Source TSAP */ __u8 dtsap_sel; /* Destination TSAP */ @@ -88,6 +87,9 @@ struct tsap_cb { struct irda_statistics 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 */ @@ -120,8 +122,6 @@ 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); -void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos, - __u32 max_sdu_size, struct sk_buff *skb); void irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, struct sk_buff *userdata); struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance); diff --git a/include/net/irda/irtty.h b/include/net/irda/irtty.h index 920909600..38b5c4d81 100644 --- a/include/net/irda/irtty.h +++ b/include/net/irda/irtty.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Dec 9 21:13:12 1997 - * Modified at: Sun Feb 7 01:57:33 1999 + * Modified at: Mon May 10 13:22:23 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1997 Dag Brattli, All Rights Reserved. + * Copyright (c) 1997, 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 @@ -33,8 +33,6 @@ #include <net/irda/irqueue.h> #include <net/irda/irda_device.h> -#include <net/irda/dongle.h> - #define IRTTY_IOC_MAGIC 'e' #define IRTTY_IOCTDONGLE _IO(IRTTY_IOC_MAGIC, 1) #define IRTTY_IOC_MAXNR 1 @@ -43,28 +41,21 @@ #define N_IRDA 11 /* This one should go in </asm/termio.h> */ #endif -struct dongle_q { - QUEUE q; - - struct dongle *dongle; -}; - struct irtty_cb { QUEUE q; /* Must be first */ -/* char name[16]; */ - int magic; struct tty_struct *tty; /* Ptr to TTY structure */ struct irda_device idev; - - struct dongle_q *dongle_q; /* Has this tty got a dongle attached? */ }; -int irtty_register_dongle( struct dongle *dongle); -void irtty_unregister_dongle( struct dongle *dongle); - -void irtty_set_dtr_rts(struct tty_struct *tty, int dtr, int rts); +int irtty_register_dongle(struct dongle *dongle); +void irtty_unregister_dongle(struct dongle *dongle); #endif + + + + + diff --git a/include/net/irda/irvtd.h b/include/net/irda/irvtd.h index 1fc7d6b0f..68340087a 100644 --- a/include/net/irda/irvtd.h +++ b/include/net/irda/irvtd.h @@ -53,6 +53,8 @@ struct irvtd_cb { struct sk_buff_head rxbuff; struct ircomm_cb *comm; /* ircomm instance */ + __u32 tx_max_sdu_size; + __u32 max_header_size; /* * These members are used for compatibility with usual serial device. * See linux/serial.h @@ -64,12 +66,13 @@ struct irvtd_cb { int line; int count; /* open count */ int blocked_open; - struct wait_queue *open_wait; - struct wait_queue *close_wait; - struct wait_queue *delta_msr_wait; - struct wait_queue *tx_wait; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + wait_queue_head_t delta_msr_wait; + wait_queue_head_t tx_wait; - struct timer_list timer; + struct timer_list tx_timer; + struct timer_list rx_timer; long pgrp; long session; diff --git a/include/net/irda/w83977af_ir.h b/include/net/irda/w83977af_ir.h index 3e3200b2d..d86456ada 100644 --- a/include/net/irda/w83977af_ir.h +++ b/include/net/irda/w83977af_ir.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Paul VanderSpek * Created at: Thu Nov 19 13:55:34 1998 - * Modified at: Thu Dec 10 14:06:18 1998 + * Modified at: Mon May 3 12:07:25 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli, All Rights Reserved. + * 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 @@ -150,6 +150,29 @@ #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 irda_device idev; +}; + static inline void switch_bank( int iobase, int set) { outb( set, iobase+SSR); diff --git a/include/net/irda/wrapper.h b/include/net/irda/wrapper.h index ca21ebec5..fa7ceb25c 100644 --- a/include/net/irda/wrapper.h +++ b/include/net/irda/wrapper.h @@ -1,15 +1,16 @@ /********************************************************************* * * Filename: wrapper.h - * Version: 1.0 - * Description: IrDA Wrapper layer + * 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: Fri Jan 29 10:15:46 1999 + * Modified at: Mon May 3 09:02:36 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. + * 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 @@ -38,17 +39,18 @@ #define STA BOF /* Start flag */ #define STO EOF /* End flag */ -#define IR_TRANS 0x20 /* Asynchronous transparency modifier */ +#define IRDA_TRANS 0x20 /* Asynchronous transparency modifier */ +/* States for receving a frame in async mode */ enum { - OUTSIDE_FRAME = 1, + 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_unwrap_char( struct irda_device *, __u8 byte); +int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize); +inline void async_unwrap_char(struct irda_device *idev, __u8 byte); #endif diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 5c5d90bb0..95803be46 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -96,7 +96,8 @@ struct neighbour __u8 flags; __u8 nud_state; __u8 type; - __u8 probes; + atomic_t probes; + rwlock_t lock; unsigned char ha[MAX_ADDR_LEN]; struct hh_cache *hh; atomic_t refcnt; @@ -155,7 +156,7 @@ struct neigh_table struct timer_list proxy_timer; struct sk_buff_head proxy_queue; int entries; - atomic_t lock; + rwlock_t lock; unsigned long last_rand; struct neigh_parms *parms_list; struct neigh_statistics stats; @@ -165,9 +166,12 @@ struct neigh_table 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 device *dev, - int creat); +extern struct neighbour * neigh_lookup(struct neigh_table *tbl, + const void *pkey, + struct device *dev); +extern struct neighbour * neigh_create(struct neigh_table *tbl, + const void *pkey, + struct 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, u8 *lladdr, u8 new, int override, int arp); @@ -226,16 +230,6 @@ extern __inline__ void neigh_confirm(struct neighbour *neigh) neigh->confirmed = jiffies; } -extern __inline__ struct neighbour * -neigh_lookup(struct neigh_table *tbl, const void *pkey, struct device *dev) -{ - struct neighbour *neigh; - start_bh_atomic(); - neigh = __neigh_lookup(tbl, pkey, dev, 0); - end_bh_atomic(); - return neigh; -} - extern __inline__ int neigh_is_connected(struct neighbour *neigh) { return neigh->nud_state&NUD_CONNECTED; @@ -254,17 +248,16 @@ extern __inline__ int neigh_event_send(struct neighbour *neigh, struct sk_buff * return 0; } -extern __inline__ void neigh_table_lock(struct neigh_table *tbl) +extern __inline__ struct neighbour * +__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct device *dev, int creat) { - atomic_inc(&tbl->lock); - synchronize_bh(); -} + struct neighbour *n = neigh_lookup(tbl, pkey, dev); -extern __inline__ void neigh_table_unlock(struct neigh_table *tbl) -{ - atomic_dec(&tbl->lock); -} + if (n || !creat) + return n; + return neigh_create(tbl, pkey, dev); +} #endif #endif diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 4c37d11ed..f9c80dd0f 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -77,14 +77,11 @@ extern __inline__ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, str return -1; } -extern __inline__ unsigned long cls_set_class(unsigned long *clp, unsigned long cl) -{ - cl = xchg(clp, cl); - synchronize_bh(); - return cl; -} + 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/include/net/pkt_sched.h b/include/net/pkt_sched.h index 9911464fc..46262159d 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -66,9 +66,12 @@ struct Qdisc_ops struct Qdisc_head { struct Qdisc_head *forw; + struct Qdisc_head *back; }; extern struct Qdisc_head qdisc_head; +extern spinlock_t qdisc_runqueue_lock; +extern rwlock_t qdisc_tree_lock; struct Qdisc { @@ -106,6 +109,46 @@ struct qdisc_rate_table int refcnt; }; +extern __inline__ void sch_tree_lock(struct Qdisc *q) +{ + write_lock(&qdisc_tree_lock); + spin_lock_bh(&q->dev->queue_lock); +} + +extern __inline__ void sch_tree_unlock(struct Qdisc *q) +{ + spin_unlock_bh(&q->dev->queue_lock); + write_unlock(&qdisc_tree_lock); +} + +extern __inline__ void tcf_tree_lock(struct tcf_proto *tp) +{ + write_lock(&qdisc_tree_lock); + spin_lock_bh(&tp->q->dev->queue_lock); +} + +extern __inline__ void tcf_tree_unlock(struct tcf_proto *tp) +{ + spin_unlock_bh(&tp->q->dev->queue_lock); + write_unlock(&qdisc_tree_lock); +} + + +extern __inline__ unsigned long +cls_set_class(struct tcf_proto *tp, unsigned long *clp, unsigned long cl) +{ + tcf_tree_lock(tp); + cl = xchg(clp, cl); + tcf_tree_unlock(tp); + return cl; +} + +extern __inline__ unsigned long +__cls_set_class(unsigned long *clp, unsigned long cl) +{ + return xchg(clp, cl); +} + /* Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth @@ -343,12 +386,14 @@ struct tcf_police 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); @@ -384,20 +429,56 @@ int teql_init(void); int tc_filter_init(void); int pktsched_init(void); -void qdisc_run_queues(void); -int qdisc_restart(struct device *dev); +extern void qdisc_run_queues(void); +extern int qdisc_restart(struct device *dev); + +extern spinlock_t qdisc_runqueue_lock; + +/* Is it on run list? Reliable only under qdisc_runqueue_lock. */ + +extern __inline__ int qdisc_on_runqueue(struct Qdisc *q) +{ + return q->h.forw != NULL; +} + +/* Is run list not empty? Reliable only under qdisc_runqueue_lock. */ + +extern __inline__ int qdisc_pending(void) +{ + return qdisc_head.forw != &qdisc_head; +} + +/* Add qdisc to tail of run list. Called with BH, disabled on this CPU */ + +extern __inline__ void qdisc_run(struct Qdisc *q) +{ + spin_lock(&qdisc_runqueue_lock); + if (!qdisc_on_runqueue(q)) { + q->h.forw = &qdisc_head; + q->h.back = qdisc_head.back; + qdisc_head.back->forw = &q->h; + qdisc_head.back = &q->h; + } + spin_unlock(&qdisc_runqueue_lock); +} + +/* If the device is not throttled, restart it and add to run list. + * BH must be disabled on this CPU. + */ extern __inline__ void qdisc_wakeup(struct device *dev) { if (!dev->tbusy) { - struct Qdisc *q = dev->qdisc; - if (qdisc_restart(dev) && q->h.forw == NULL) { - q->h.forw = qdisc_head.forw; - qdisc_head.forw = &q->h; - } + spin_lock(&dev->queue_lock); + if (qdisc_restart(dev)) + qdisc_run(dev->qdisc); + spin_unlock(&dev->queue_lock); } } +/* Calculate maximal size of packet seen by hard_start_xmit + routine of this device. + */ extern __inline__ unsigned psched_mtu(struct device *dev) { unsigned mtu = dev->mtu; diff --git a/include/net/route.h b/include/net/route.h index 66df47122..e230f45fc 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -35,13 +35,6 @@ #define RT_HASH_DIVISOR 256 -/* - * Prevents LRU trashing, entries considered equivalent, - * if the difference between last use times is less then this number. - */ -#define RT_CACHE_BUBBLE_THRESHOLD (5*HZ) - - #define RTO_ONLINK 0x01 #define RTO_TPROXY 0x80000000 @@ -94,8 +87,6 @@ struct rtable #endif }; -extern struct rtable *rt_hash_table[RT_HASH_DIVISOR]; - struct ip_rt_acct { __u32 o_bytes; @@ -105,6 +96,7 @@ struct ip_rt_acct }; extern struct ip_rt_acct ip_rt_acct[256]; +extern rwlock_t ip_rt_acct_lock; extern void ip_rt_init(void); extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw, diff --git a/include/net/sock.h b/include/net/sock.h index e11c1be22..73ef988a7 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -105,6 +105,7 @@ struct unix_opt { struct sock ** list; struct sock * gc_tree; int inflight; + atomic_t user_count; }; #ifdef CONFIG_NETLINK @@ -353,6 +354,22 @@ struct tcp_opt { #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 { /* This must be first. */ struct sock *sklist_next; @@ -381,10 +398,10 @@ struct sock { unsigned char reuse, /* SO_REUSEADDR setting */ nonagle; /* Disable Nagle algorithm? */ - atomic_t sock_readers; /* User count */ + socket_lock_t lock; /* Synchronizer... */ int rcvbuf; /* Size of receive buffer in bytes */ - struct wait_queue **sleep; /* Sock wait queue */ + wait_queue_head_t *sleep; /* Sock wait queue */ struct dst_entry *dst_cache; /* Destination cache */ atomic_t rmem_alloc; /* Receive queue bytes committed */ struct sk_buff_head receive_queue; /* Incoming packets */ @@ -415,9 +432,17 @@ struct sock { int hashent; struct sock *pair; - /* Error and backlog packet queues, rarely used. */ - struct sk_buff_head back_log, - error_queue; + /* 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; + + /* Error queue, rarely used. */ + struct sk_buff_head error_queue; struct proto *prot; @@ -537,6 +562,18 @@ struct sock { 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 @@ -616,15 +653,26 @@ struct proto { /* Per-protocol hash table implementations use this to make sure * nothing changes. */ -#define SOCKHASH_LOCK() start_bh_atomic() -#define SOCKHASH_UNLOCK() end_bh_atomic() +extern rwlock_t sockhash_lock; +#define SOCKHASH_LOCK_READ() read_lock_bh(&sockhash_lock) +#define SOCKHASH_UNLOCK_READ() read_unlock_bh(&sockhash_lock) +#define SOCKHASH_LOCK_WRITE() write_lock_bh(&sockhash_lock) +#define SOCKHASH_UNLOCK_WRITE() write_unlock_bh(&sockhash_lock) + +/* The following variants must _only_ be used when you know you + * can only be executing in a BH context. + */ +#define SOCKHASH_LOCK_READ_BH() read_lock(&sockhash_lock) +#define SOCKHASH_UNLOCK_READ_BH() read_unlock(&sockhash_lock) +#define SOCKHASH_LOCK_WRITE_BH() write_lock(&sockhash_lock) +#define SOCKHASH_UNLOCK_WRITE_BH() write_unlock(&sockhash_lock) /* Some things in the kernel just want to get at a protocols * entire socket list commensurate, thus... */ static __inline__ void add_to_prot_sklist(struct sock *sk) { - SOCKHASH_LOCK(); + SOCKHASH_LOCK_WRITE(); if(!sk->sklist_next) { struct proto *p = sk->prot; @@ -638,54 +686,37 @@ static __inline__ void add_to_prot_sklist(struct sock *sk) if(sk->prot->highestinuse < sk->prot->inuse) sk->prot->highestinuse = sk->prot->inuse; } - SOCKHASH_UNLOCK(); + SOCKHASH_UNLOCK_WRITE(); } static __inline__ void del_from_prot_sklist(struct sock *sk) { - SOCKHASH_LOCK(); + SOCKHASH_LOCK_WRITE(); if(sk->sklist_next) { sk->sklist_next->sklist_prev = sk->sklist_prev; sk->sklist_prev->sklist_next = sk->sklist_next; sk->sklist_next = NULL; sk->prot->inuse--; } - SOCKHASH_UNLOCK(); + SOCKHASH_UNLOCK_WRITE(); } -/* - * Used by processes to "lock" a socket state, so that +/* 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. * - * Note the 'barrier()' calls: gcc may not move a lock - * "downwards" or a unlock "upwards" when optimizing. + * 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. */ -extern void __release_sock(struct sock *sk); - -static inline void lock_sock(struct sock *sk) -{ -#if 0 -/* debugging code: the test isn't even 100% correct, but it can catch bugs */ -/* Note that a double lock is ok in theory - it's just _usually_ a bug */ - if (atomic_read(&sk->sock_readers)) { - __label__ here; - printk("double lock on socket at %p\n", &&here); -here: - } -#endif - atomic_inc(&sk->sock_readers); - synchronize_bh(); -} +extern void lock_sock(struct sock *sk); +extern void release_sock(struct sock *sk); -static inline void release_sock(struct sock *sk) -{ - barrier(); - if (atomic_dec_and_test(&sk->sock_readers)) - __release_sock(sk); -} +/* 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)) /* * This might not be the most appropriate place for this two @@ -944,4 +975,26 @@ extern __inline__ int gfp_any(void) #define NETDEBUG(x) do { x; } while (0) #endif +/* + * 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); \ + } + + #endif /* _SOCK_H */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 2d91a8d43..28fc52125 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -27,19 +27,16 @@ * New scheme, half the table is for TIME_WAIT, the other half is * for the rest. I'll experiment with dynamic table growth later. */ -#define TCP_HTABLE_SIZE 512 +extern int tcp_ehash_size; +extern struct sock **tcp_ehash; /* This is for listening sockets, thus all sockets which possess wildcards. */ #define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ -/* This is for all sockets, to keep track of the local port allocations. */ -#define TCP_BHTABLE_SIZE 512 - /* tcp_ipv4.c: These need 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 *tcp_established_hash[TCP_HTABLE_SIZE]; extern struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE]; /* There are a few simple rules, which allow for local port reuse by @@ -85,7 +82,9 @@ struct tcp_bind_bucket { struct tcp_bind_bucket **pprev; }; -extern struct tcp_bind_bucket *tcp_bound_hash[TCP_BHTABLE_SIZE]; +extern struct tcp_bind_bucket **tcp_bhash; +extern int tcp_bhash_size; + extern kmem_cache_t *tcp_bucket_cachep; extern struct tcp_bind_bucket *tcp_bucket_create(unsigned short snum); extern void tcp_bucket_unlock(struct sock *sk); @@ -113,7 +112,7 @@ static __inline__ void tcp_reg_zap(struct sock *sk) /* These are AF independent. */ static __inline__ int tcp_bhashfn(__u16 lport) { - return (lport & (TCP_BHTABLE_SIZE - 1)); + return (lport & (tcp_bhash_size - 1)); } static __inline__ void tcp_sk_bindify(struct sock *sk) @@ -121,7 +120,7 @@ static __inline__ void tcp_sk_bindify(struct sock *sk) struct tcp_bind_bucket *tb; unsigned short snum = sk->num; - for(tb = tcp_bound_hash[tcp_bhashfn(snum)]; tb->port != snum; tb = tb->next) + for(tb = tcp_bhash[tcp_bhashfn(snum)]; tb->port != snum; tb = tb->next) ; /* Update bucket flags. */ if(tb->owners == NULL) { @@ -290,7 +289,7 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) #define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when * I've got something to write and * there is no window */ -#define TCP_KEEPALIVE_TIME (180*60*HZ) /* two hours */ +#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ #define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ #define TCP_KEEPALIVE_PERIOD ((75*HZ)>>2) /* period of keepalive check */ @@ -728,7 +727,7 @@ extern __inline__ int tcp_raise_window(struct sock *sk) */ extern __inline__ __u32 tcp_recalc_ssthresh(struct tcp_opt *tp) { - __u32 snd_wnd_packets = tp->snd_wnd / tp->mss_cache; + __u32 snd_wnd_packets = tp->snd_wnd / max(tp->mss_cache, 1); return max(min(snd_wnd_packets, tp->snd_cwnd) >> 1, 2); } diff --git a/include/net/udp.h b/include/net/udp.h index 5af3c18b7..30a59b3f0 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -34,8 +34,14 @@ extern struct sock *udp_hash[UDP_HTABLE_SIZE]; extern unsigned short udp_good_socknum(void); -#define UDP_NO_CHECK 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; |