summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2002-10-11 04:22:34 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2002-10-11 04:22:34 -0700
commit2da2a587ff702fc975ad0607fdbb606af7c8e56a (patch)
tree447e836adecfd49d248bbc07c1450f0afbdb7745 /include/net
parent5d344d1ac9069dde4b815364c43f7184ea810789 (diff)
parentac27bdc817c512a48237d7b6d9764d85ebedcc1d (diff)
Merge master.kernel.org:/home/bcrl/net-2.5
into nuts.ninka.net:/home/davem/src/BK/aio-2.5
Diffstat (limited to 'include/net')
-rw-r--r--include/net/flow.h70
-rw-r--r--include/net/ip6_fib.h8
-rw-r--r--include/net/ip6_fw.h54
-rw-r--r--include/net/ip_fib.h23
-rw-r--r--include/net/irda/crc.h2
-rw-r--r--include/net/irda/ircomm_tty.h5
-rw-r--r--include/net/irda/vlsi_ir.h324
-rw-r--r--include/net/route.h41
-rw-r--r--include/net/tcp.h14
9 files changed, 306 insertions, 235 deletions
diff --git a/include/net/flow.h b/include/net/flow.h
index e1ce1b2aea31..58fbf0e8314a 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -1,6 +1,6 @@
/*
*
- * Flow based forwarding rules (usage: firewalling, etc)
+ * Generic internet FLOW.
*
*/
@@ -8,12 +8,16 @@
#define _NET_FLOW_H
struct flowi {
- int proto; /* {TCP, UDP, ICMP} */
+ int oif;
+ int iif;
union {
struct {
__u32 daddr;
__u32 saddr;
+ __u32 fwmark;
+ __u8 tos;
+ __u8 scope;
} ip4_u;
struct {
@@ -27,9 +31,12 @@ struct flowi {
#define fl6_flowlabel nl_u.ip6_u.flowlabel
#define fl4_dst nl_u.ip4_u.daddr
#define fl4_src nl_u.ip4_u.saddr
+#define fl4_fwmark nl_u.ip4_u.fwmark
+#define fl4_tos nl_u.ip4_u.tos
+#define fl4_scope nl_u.ip4_u.scope
- int oif;
-
+ __u8 proto;
+ __u8 flags;
union {
struct {
__u16 sport;
@@ -41,61 +48,8 @@ struct flowi {
__u8 code;
} icmpt;
- unsigned long data;
+ __u32 spi;
} 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/include/net/ip6_fib.h b/include/net/ip6_fib.h
index f8d382f4e7d8..4fb406133dbb 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -70,14 +70,6 @@ struct rt6_info
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;
};
diff --git a/include/net/ip6_fw.h b/include/net/ip6_fw.h
deleted file mode 100644
index 7866273d3d56..000000000000
--- a/include/net/ip6_fw.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#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/include/net/ip_fib.h b/include/net/ip_fib.h
index 3b84c5bff809..236641e5bc51 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -17,6 +17,7 @@
#define _NET_IP_FIB_H
#include <linux/config.h>
+#include <net/flow.h>
struct kern_rta
{
@@ -117,7 +118,7 @@ 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_lookup)(struct fib_table *tb, const struct flowi *flp, 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);
@@ -130,7 +131,7 @@ struct fib_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);
+ const struct flowi *flp, struct fib_result *res);
unsigned char tb_data[0];
};
@@ -152,18 +153,18 @@ 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)
+static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
{
- if (local_table->tb_lookup(local_table, key, res) &&
- main_table->tb_lookup(main_table, key, res))
+ if (local_table->tb_lookup(local_table, flp, res) &&
+ main_table->tb_lookup(main_table, flp, res))
return -ENETUNREACH;
return 0;
}
-static inline void fib_select_default(const struct rt_key *key, struct fib_result *res)
+static inline void fib_select_default(const struct flowi *flp, 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);
+ main_table->tb_select_default(main_table, flp, res);
}
#else /* CONFIG_IP_MULTIPLE_TABLES */
@@ -171,7 +172,7 @@ static inline void fib_select_default(const struct rt_key *key, struct fib_resul
#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 int fib_lookup(const struct flowi *flp, struct fib_result *res);
extern struct fib_table *__fib_new_table(int id);
extern void fib_rule_put(struct fib_rule *r);
@@ -191,7 +192,7 @@ static inline struct fib_table *fib_new_table(int id)
return fib_tables[id] ? : __fib_new_table(id);
}
-extern void fib_select_default(const struct rt_key *key, struct fib_result *res);
+extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
#endif /* CONFIG_IP_MULTIPLE_TABLES */
@@ -204,13 +205,13 @@ extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *ar
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);
+extern void fib_select_multipath(const struct flowi *flp, 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*);
+ const struct flowi *, 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);
diff --git a/include/net/irda/crc.h b/include/net/irda/crc.h
index 61a5a648864d..a419a992f15f 100644
--- a/include/net/irda/crc.h
+++ b/include/net/irda/crc.h
@@ -28,6 +28,6 @@ static inline __u16 irda_fcs(__u16 fcs, __u8 c)
}
/* Recompute the FCS with len bytes appended. */
-unsigned short crc_calc( __u16 fcs, __u8 const *buf, size_t len);
+unsigned short irda_calc_crc16( __u16 fcs, __u8 const *buf, size_t len);
#endif
diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index 7f9659cc4239..7ff56638b9d6 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -48,7 +48,9 @@
/* 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
+#define IRCOMM_TTY_HDR_UNINITIALISED 16
+/* Same for payload size. See qos.c for the smallest max data size */
+#define IRCOMM_TTY_DATA_UNINITIALISED (64 - IRCOMM_TTY_HDR_UNINITIALISED)
/*
* IrCOMM TTY driver state
@@ -83,6 +85,7 @@ struct ircomm_tty_cb {
__u32 max_data_size; /* Max data we can transmit in one packet */
__u32 max_header_size; /* The amount of header space we must reserve */
+ __u32 tx_data_size; /* Max data size of current tx_skb */
struct iriap_cb *iriap; /* Instance used for querying remote IAS */
struct ias_object* obj;
diff --git a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h
index fab3ebb726c3..32d30cbc0920 100644
--- a/include/net/irda/vlsi_ir.h
+++ b/include/net/irda/vlsi_ir.h
@@ -3,9 +3,9 @@
*
* vlsi_ir.h: VLSI82C147 PCI IrDA controller driver for Linux
*
- * Version: 0.3, Sep 30, 2001
+ * Version: 0.4
*
- * Copyright (c) 2001 Martin Diehl
+ * Copyright (c) 2001-2002 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
@@ -27,6 +27,26 @@
#ifndef IRDA_VLSI_FIR_H
#define IRDA_VLSI_FIR_H
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,4)
+#ifdef CONFIG_PROC_FS
+/* PDE() introduced in 2.5.4 */
+#define PDE(inode) ((inode)->u.generic_ip)
+#endif
+#endif
+
+/*
+ * #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,xx)
+ *
+ * missing pci-dma api call to give streaming dma buffer back to hw
+ * patch floating on lkml - probably present in 2.5.26 or later
+ * otherwise defining it as noop is ok, since the vlsi-ir is only
+ * used on two oldish x86-based notebooks which are cache-coherent
+ */
+#define pci_dma_prep_single(dev, addr, size, direction) /* nothing */
+/*
+ * #endif
+ */
+
/* ================================================================ */
/* non-standard PCI registers */
@@ -58,20 +78,20 @@ 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_PD_INV = 0x04, /* PD#: inverted power down signal,
+ * i.e. PLL is powered, if PD_INV 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 */
+ CLKCTL_EXTCLK = 0x20, /* set to select external clock input, not PLL */
+ CLKCTL_XCKSEL = 0x10, /* set to indicate EXTCLK is 40MHz, 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 */
+ * is detected, PD_INV gets set(?) and CLKSTP cleared */
};
/* ------------------------------------------ */
@@ -82,10 +102,9 @@ enum vlsi_pci_clkctl {
#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
+ * We select to operate using fixed MSTRPAGE=0, use ISA DMA
* address restrictions to make the PCI BM api aware of this,
* but ensure the hardware is dealing with real 32bit access.
*
@@ -151,7 +170,6 @@ enum vlsi_pci_irmisc {
IRMISC_UARTSEL_2e8 = 0x03
};
-
/* ================================================================ */
/* registers mapped to 32 byte PCI IO space */
@@ -350,22 +368,17 @@ enum vlsi_pio_irenable {
#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
@@ -382,10 +395,10 @@ enum vlsi_pio_irenable {
* 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)
+ * Using the expression PLSWID = 12/(BAUD+1)-1 (multiplied by two 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
+ * for 2.4kbaud getting 6usec). This is fine with 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!
*
@@ -399,7 +412,21 @@ enum vlsi_pio_irenable {
* PREAMB = 15
*/
-#define BWP_TO_PHYCTL(B,W,P) ((((B)&0x3f)<<10) | (((W)&0x1f)<<5) | (((P)&0x1f)<<0))
+#define PHYCTL_BAUD_SHIFT 10
+#define PHYCTL_BAUD_MASK 0xfc00
+#define PHYCTL_PLSWID_SHIFT 5
+#define PHYCTL_PLSWID_MASK 0x03e0
+#define PHYCTL_PREAMB_SHIFT 0
+#define PHYCTL_PREAMB_MASK 0x001f
+
+#define PHYCTL_TO_BAUD(bwp) (((bwp)&PHYCTL_BAUD_MASK)>>PHYCTL_BAUD_SHIFT)
+#define PHYCTL_TO_PLSWID(bwp) (((bwp)&PHYCTL_PLSWID_MASK)>>PHYCTL_PLSWID_SHIFT)
+#define PHYCTL_TO_PREAMB(bwp) (((bwp)&PHYCTL_PREAMB_MASK)>>PHYCTL_PREAMB_SHIFT)
+
+#define BWP_TO_PHYCTL(b,w,p) ((((b)<<PHYCTL_BAUD_SHIFT)&PHYCTL_BAUD_MASK) \
+ | (((w)<<PHYCTL_PLSWID_SHIFT)&PHYCTL_PLSWID_MASK) \
+ | (((p)<<PHYCTL_PREAMB_SHIFT)&PHYCTL_PREAMB_MASK))
+
#define BAUD_BITS(br) ((115200/(br))-1)
static inline unsigned
@@ -417,7 +444,6 @@ calc_width_bits(unsigned baudrate, unsigned widthselect, unsigned clockselect)
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)
@@ -445,42 +471,61 @@ calc_width_bits(unsigned baudrate, unsigned widthselect, unsigned clockselect)
/* 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...
+/* maximum acceptable length for received packets */
+
+/* hw imposed limitation - register uses only [11:0] */
+#define MAX_PACKET_LENGTH 0x0fff
+
+/* IrLAP I-field (apparently not defined elsewhere) */
+#define IRDA_MTU 2048
+
+/* complete packet consists of A(1)+C(1)+I(<=IRDA_MTU) */
+#define IRLAP_SKB_ALLOCSIZE (1+1+IRDA_MTU)
+
+/* the buffers we use to exchange frames with the hardware need to be
+ * larger than IRLAP_SKB_ALLOCSIZE because we may have up to 4 bytes FCS
+ * appended and, in SIR mode, a lot of frame wrapping bytes. The worst
+ * case appears to be a SIR packet with I-size==IRDA_MTU and all bytes
+ * requiring to be escaped to provide transparency. Furthermore, the peer
+ * might ask for quite a number of additional XBOFs:
+ * up to 115+48 XBOFS 163
+ * regular BOF 1
+ * A-field 1
+ * C-field 1
+ * I-field, IRDA_MTU, all escaped 4096
+ * FCS (16 bit at SIR, escaped) 4
+ * EOF 1
+ * AFAICS nothing in IrLAP guarantees A/C field not to need escaping
+ * (f.e. 0xc0/0xc1 - i.e. BOF/EOF - are legal values there) so in the
+ * worst case we have 4269 bytes total frame size.
+ * However, the VLSI uses 12 bits only for all buffer length values,
+ * which limits the maximum useable buffer size <= 4095.
+ * Note this is not a limitation in the receive case because we use
+ * the SIR filtering mode where the hw unwraps the frame and only the
+ * bare packet+fcs is stored into the buffer - in contrast to the SIR
+ * tx case where we have to pass frame-wrapped packets to the hw.
+ * If this would ever become an issue in real life, the only workaround
+ * I see would be using the legacy UART emulation in SIR mode.
*/
-
-#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] */
+#define XFER_BUF_SIZE MAX_PACKET_LENGTH
/* ------------------------------------------ */
-
/* VLSI_PIO_RCVBCNT: Receive Byte Count Register (u16, ro) */
-/* recive packet counter gets incremented on every non-filtered
+/* receive 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
*/
+/* better apply the [11:0] mask when reading, as some docs say the
+ * reserved [15:12] would return 1 when reading - which is wrong AFAICS
+ */
#define RCVBCNT_MASK 0x0fff
-/* ================================================================ */
-
+/******************************************************************/
/* descriptors for rx/tx ring
*
@@ -494,10 +539,10 @@ calc_width_bits(unsigned baudrate, unsigned widthselect, unsigned clockselect)
*
* Attention: Writing addr overwrites status!
*
- * ### FIXME: we depend on endianess here
+ * ### FIXME: depends on endianess (but there ain't no non-i586 ob800 ;-)
*/
-struct ring_descr {
+struct ring_descr_hw {
volatile u16 rd_count; /* tx/rx count [11:0] */
u16 reserved;
union {
@@ -505,60 +550,168 @@ struct ring_descr {
struct {
u8 addr_res[3];
volatile u8 status; /* descriptor status */
- } rd_s;
- } rd_u;
-};
+ } rd_s __attribute__((packed));
+ } rd_u __attribute((packed));
+} __attribute__ ((packed));
#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) */
+#define RD_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) */
+#define RD_TX_DISCRC 0x40 /* do not send CRC (for SIR) */
+#define RD_TX_BADCRC 0x20 /* force a bad CRC */
+#define RD_TX_PULSE 0x10 /* send indication pulse after this frame (MIR/FIR) */
+#define RD_TX_FRCEUND 0x08 /* force underrun */
+#define RD_TX_CLRENTX 0x04 /* clear ENTX after this frame */
+#define RD_TX_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 RD_RX_PHYERR 0x40 /* physical encoding error */
+#define RD_RX_CRCERR 0x20 /* CRC error (MIR/FIR) */
+#define RD_RX_LENGTH 0x10 /* frame exceeds buffer length */
+#define RD_RX_OVER 0x08 /* RX fifo overrun (probably PCI problem) */
+#define RD_RX_SIRBAD 0x04 /* EOF missing: BOF follows BOF (SIR, filtered) */
-#define RX_STAT_ERROR 0x7c /* any error in frame */
+#define RD_RX_ERROR 0x7c /* any error in received frame */
+/* the memory required to hold the 2 descriptor rings */
+#define HW_RING_AREA_SIZE (2 * MAX_RING_DESCR * sizeof(struct ring_descr_hw))
-/* ------------------------------------------ */
+/******************************************************************/
-/* contains the objects we've put into the ring descriptors
- * static buffers for now - probably skb's later
+/* sw-ring descriptors consists of a bus-mapped transfer buffer with
+ * associated skb and a pointer to the hw entry descriptor
*/
-struct ring_entry {
- struct sk_buff *skb;
- void *data;
+struct ring_descr {
+ struct ring_descr_hw *hw;
+ struct sk_buff *skb;
+ void *buf;
};
+/* wrappers for operations on hw-exposed ring descriptors
+ * access to the hw-part of the descriptors must use these.
+ */
+
+static inline int rd_is_active(struct ring_descr *rd)
+{
+ return ((rd->hw->rd_status & RD_ACTIVE) != 0);
+}
+
+static inline void rd_activate(struct ring_descr *rd)
+{
+ rd->hw->rd_status |= RD_ACTIVE;
+}
+
+static inline void rd_set_status(struct ring_descr *rd, u8 s)
+{
+ rd->hw->rd_status = s; /* may pass ownership to the hardware */
+}
+
+static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s)
+{
+ /* order is important for two reasons:
+ * - overlayed: writing addr overwrites status
+ * - we want to write status last so we have valid address in
+ * case status has RD_ACTIVE set
+ */
+
+ if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) {
+ BUG();
+ return;
+ }
+
+ a &= DMA_MASK_MSTRPAGE; /* clear highbyte to make sure we won't write
+ * to status - just in case MSTRPAGE_VALUE!=0
+ */
+ rd->hw->rd_addr = a;
+ wmb();
+ rd_set_status(rd, s); /* may pass ownership to the hardware */
+}
+
+static inline void rd_set_count(struct ring_descr *rd, u16 c)
+{
+ rd->hw->rd_count = c;
+}
+
+static inline u8 rd_get_status(struct ring_descr *rd)
+{
+ return rd->hw->rd_status;
+}
+
+static inline dma_addr_t rd_get_addr(struct ring_descr *rd)
+{
+ dma_addr_t a;
+
+ a = (rd->hw->rd_addr & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24);
+ return a;
+}
+
+static inline u16 rd_get_count(struct ring_descr *rd)
+{
+ return rd->hw->rd_count;
+}
+
+/******************************************************************/
+
+/* sw descriptor rings for rx, tx:
+ *
+ * operations follow producer-consumer paradigm, with the hw
+ * in the middle doing the processing.
+ * ring size must be power of two.
+ *
+ * producer advances r->tail after inserting for processing
+ * consumer advances r->head after removing processed rd
+ * ring is empty if head==tail / full if (tail+1)==head
+ */
struct vlsi_ring {
+ struct pci_dev *pdev;
+ int dir;
+ unsigned len;
unsigned size;
unsigned mask;
- unsigned head, tail;
- struct ring_descr *hw;
- struct ring_entry buf[MAX_RING_DESCR];
+ atomic_t head, tail;
+ struct ring_descr *rd;
};
-/* ------------------------------------------ */
+/* ring processing helpers */
+
+static inline struct ring_descr *ring_last(struct vlsi_ring *r)
+{
+ int t;
+
+ t = atomic_read(&r->tail) & r->mask;
+ return (((t+1) & r->mask) == (atomic_read(&r->head) & r->mask)) ? NULL : &r->rd[t];
+}
+
+static inline struct ring_descr *ring_put(struct vlsi_ring *r)
+{
+ atomic_inc(&r->tail);
+ return ring_last(r);
+}
+
+static inline struct ring_descr *ring_first(struct vlsi_ring *r)
+{
+ int h;
+
+ h = atomic_read(&r->head) & r->mask;
+ return (h == (atomic_read(&r->tail) & r->mask)) ? NULL : &r->rd[h];
+}
+
+static inline struct ring_descr *ring_get(struct vlsi_ring *r)
+{
+ atomic_inc(&r->head);
+ return ring_first(r);
+}
+
+/******************************************************************/
/* our private compound VLSI-PCI-IRDA device information */
@@ -575,15 +728,40 @@ typedef struct vlsi_irda_dev {
dma_addr_t busaddr;
void *virtaddr;
- struct vlsi_ring tx_ring, rx_ring;
+ struct vlsi_ring *tx_ring, *rx_ring;
struct timeval last_rx;
spinlock_t lock;
-
+ struct semaphore sem;
+
+ u32 cfg_space[64/sizeof(u32)];
+ u8 resume_ok;
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *proc_entry;
+#endif
+
} vlsi_irda_dev_t;
/********************************************************/
+/* the remapped error flags we use for returning from frame
+ * post-processing in vlsi_process_tx/rx() after it was completed
+ * by the hardware. These functions either return the >=0 number
+ * of transfered bytes in case of success or the negative (-)
+ * of the or'ed error flags.
+ */
+
+#define VLSI_TX_DROP 0x0001
+#define VLSI_TX_FIFO 0x0002
+
+#define VLSI_RX_DROP 0x0100
+#define VLSI_RX_OVER 0x0200
+#define VLSI_RX_LENGTH 0x0400
+#define VLSI_RX_FRAME 0x0800
+#define VLSI_RX_CRC 0x1000
+
+/********************************************************/
+
#endif /* IRDA_VLSI_FIR_H */
diff --git a/include/net/route.h b/include/net/route.h
index 7ddc79e4d07e..621b0c44b250 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -27,6 +27,7 @@
#include <linux/config.h>
#include <net/dst.h>
#include <net/inetpeer.h>
+#include <net/flow.h>
#include <linux/in_route.h>
#include <linux/rtnetlink.h>
#include <linux/route.h>
@@ -45,19 +46,6 @@
#define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->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
{
@@ -78,7 +66,7 @@ struct rtable
__u32 rt_gateway;
/* Cache lookup keys */
- struct rt_key key;
+ struct flowi fl;
/* Miscellaneous cached information */
__u32 rt_spec_dst; /* RFC1122 specific destination */
@@ -124,7 +112,7 @@ 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_output_key(struct rtable **, const struct flowi *flp);
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);
@@ -136,16 +124,6 @@ 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)
@@ -163,15 +141,20 @@ static inline char rt_tos2priority(u8 tos)
static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif)
{
+ struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dst,
+ .saddr = src,
+ .tos = tos } },
+ .oif = oif };
+
int err;
- err = ip_route_output(rp, dst, src, tos, oif);
+ err = ip_route_output_key(rp, &fl);
if (err || (dst && src))
return err;
- dst = (*rp)->rt_dst;
- src = (*rp)->rt_src;
+ fl.fl4_dst = (*rp)->rt_dst;
+ fl.fl4_src = (*rp)->rt_src;
ip_rt_put(*rp);
*rp = NULL;
- return ip_route_output(rp, dst, src, tos, oif);
+ return ip_route_output_key(rp, &fl);
}
extern void rt_bind_peer(struct rtable *rt, int create);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 7183f85e9999..de3c44d714b0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -472,6 +472,7 @@ 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 int sysctl_tcp_frto;
extern atomic_t tcp_memory_allocated;
extern atomic_t tcp_sockets_allocated;
@@ -1856,4 +1857,17 @@ static inline void tcp_v4_setup_caps(struct sock *sk, struct dst_entry *dst)
#define TCP_CHECK_TIMER(sk) do { } while (0)
+static inline int tcp_use_frto(const struct sock *sk)
+{
+ const struct tcp_opt *tp = tcp_sk(sk);
+
+ /* F-RTO must be activated in sysctl and there must be some
+ * unsent new data, and the advertised window should allow
+ * sending it.
+ */
+ return (sysctl_tcp_frto && tp->send_head &&
+ !after(TCP_SKB_CB(tp->send_head)->end_seq,
+ tp->snd_una + tp->snd_wnd));
+}
+
#endif /* _TCP_H */