From fcf4a4369976cb355092c049e30916d9706fbae0 Mon Sep 17 00:00:00 2001 From: Catalin Boie Date: Wed, 17 Nov 2004 00:08:01 -0800 Subject: [PKT_SCHED]: Allow using nfmark as key in U32 classifier. Signed-off-by: Catalin(ux aka Dino) BOIE Signed-off-by: David S. Miller --- include/linux/pkt_cls.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 45ac289f1bbf..45ed903d247c 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -192,6 +192,7 @@ enum TCA_U32_ACT, TCA_U32_INDEV, TCA_U32_PCNT, + TCA_U32_MARK, __TCA_U32_MAX }; -- cgit v1.2.3 From 8f78d753284f7bee7cf7bcd27e230eb0a68aa751 Mon Sep 17 00:00:00 2001 From: Ian Pratt Date: Wed, 17 Nov 2004 22:03:59 -0800 Subject: [NET]: Add alloc_skb_from_cache. This serves two purposes: firstly, we like to allocate page-sized skbs as this means we zero-copy transfer of network buffers between guest operating systems. Secondly, it enables us to have a cache of pages that have been used for network buffers that we can be more lax about scrubbing when they change VM ownership (since they could be sniffed on the wire). Signed-off-by: David S. Miller --- include/linux/skbuff.h | 6 ++++++ net/core/skbuff.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 71fc2bdc0cd6..57a2843faa21 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -292,6 +292,8 @@ struct sk_buff { extern void __kfree_skb(struct sk_buff *skb); extern struct sk_buff *alloc_skb(unsigned int size, int priority); +extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, + unsigned int size, int priority); extern void kfree_skbmem(struct sk_buff *skb); extern struct sk_buff *skb_clone(struct sk_buff *skb, int priority); extern struct sk_buff *skb_copy(const struct sk_buff *skb, int priority); @@ -935,6 +937,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) * * %NULL is returned in there is no free memory. */ +#ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB static inline struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask) { @@ -943,6 +946,9 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length, skb_reserve(skb, 16); return skb; } +#else +extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask); +#endif /** * dev_alloc_skb - allocate an skbuff for sending diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0bc35a015555..a6d1d698230e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -163,6 +163,59 @@ nodata: goto out; } +/** + * alloc_skb_from_cache - allocate a network buffer + * @cp: kmem_cache from which to allocate the data area + * (object size must be big enough for @size bytes + skb overheads) + * @size: size to allocate + * @gfp_mask: allocation mask + * + * Allocate a new &sk_buff. The returned buffer has no headroom and + * tail room of size bytes. The object has a reference count of one. + * The return is the buffer. On a failure the return is %NULL. + * + * Buffers may only be allocated from interrupts using a @gfp_mask of + * %GFP_ATOMIC. + */ +struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, + unsigned int size, int gfp_mask) +{ + struct sk_buff *skb; + u8 *data; + + /* Get the HEAD */ + skb = kmem_cache_alloc(skbuff_head_cache, + gfp_mask & ~__GFP_DMA); + if (!skb) + goto out; + + /* Get the DATA. */ + size = SKB_DATA_ALIGN(size); + data = kmem_cache_alloc(cp, gfp_mask); + if (!data) + goto nodata; + + memset(skb, 0, offsetof(struct sk_buff, truesize)); + skb->truesize = size + sizeof(struct sk_buff); + atomic_set(&skb->users, 1); + skb->head = data; + skb->data = data; + skb->tail = data; + skb->end = data + size; + + atomic_set(&(skb_shinfo(skb)->dataref), 1); + skb_shinfo(skb)->nr_frags = 0; + skb_shinfo(skb)->tso_size = 0; + skb_shinfo(skb)->tso_segs = 0; + skb_shinfo(skb)->frag_list = NULL; +out: + return skb; +nodata: + kmem_cache_free(skbuff_head_cache, skb); + skb = NULL; + goto out; +} + static void skb_drop_fraglist(struct sk_buff *skb) { -- cgit v1.2.3 From 8fb8f6c69cca3e4dad3da202c120b328b803f19b Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Tue, 23 Nov 2004 07:47:34 -0800 Subject: [EBTABLES]: Add userspace logging via netlink socket. The patch below adds the ebtables ulog watcher, that sends packets to userspace. It is based on ipt_ULOG.c. The complete packet, including Ethernet header, is sent to userspace. The in and out bridge ports are also sent to userspace. Logging is of course not restricted to IP packets. An example of a userspace program that receives and parses packets sent by the ulog watcher is in the ebtables CVS tree under examples/ulog/ Signed-off-by: Bart De Schuymer Signed-off-by: David S. Miller --- include/linux/netfilter_bridge/ebt_ulog.h | 36 ++++ include/linux/netfilter_bridge/ebtables.h | 6 +- net/bridge/netfilter/Kconfig | 18 +- net/bridge/netfilter/Makefile | 1 + net/bridge/netfilter/ebt_log.c | 5 +- net/bridge/netfilter/ebt_ulog.c | 295 ++++++++++++++++++++++++++++++ net/bridge/netfilter/ebtables.c | 6 +- 7 files changed, 357 insertions(+), 10 deletions(-) create mode 100644 include/linux/netfilter_bridge/ebt_ulog.h create mode 100644 net/bridge/netfilter/ebt_ulog.c (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebt_ulog.h b/include/linux/netfilter_bridge/ebt_ulog.h new file mode 100644 index 000000000000..b677e2671541 --- /dev/null +++ b/include/linux/netfilter_bridge/ebt_ulog.h @@ -0,0 +1,36 @@ +#ifndef _EBT_ULOG_H +#define _EBT_ULOG_H + +#define EBT_ULOG_DEFAULT_NLGROUP 0 +#define EBT_ULOG_DEFAULT_QTHRESHOLD 1 +#define EBT_ULOG_MAXNLGROUPS 32 /* hardcoded netlink max */ +#define EBT_ULOG_PREFIX_LEN 32 +#define EBT_ULOG_MAX_QLEN 50 +#define EBT_ULOG_WATCHER "ulog" +#define EBT_ULOG_VERSION 1 + +struct ebt_ulog_info { + uint32_t nlgroup; + unsigned int cprange; + unsigned int qthreshold; + char prefix[EBT_ULOG_PREFIX_LEN]; +}; + +typedef struct ebt_ulog_packet_msg { + int version; + char indev[IFNAMSIZ]; + char outdev[IFNAMSIZ]; + char physindev[IFNAMSIZ]; + char physoutdev[IFNAMSIZ]; + char prefix[EBT_ULOG_PREFIX_LEN]; + struct timeval stamp; + unsigned long mark; + unsigned int hook; + size_t data_len; + /* The complete packet, including Ethernet header and perhaps + * the VLAN header is appended */ + unsigned char data[0] __attribute__ + ((aligned (__alignof__(struct ebt_ulog_info)))); +} ebt_ulog_packet_msg_t; + +#endif /* _EBT_ULOG_H */ diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index b9fcbf85f047..b1a7cc90877b 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -201,9 +201,9 @@ struct ebt_watcher { struct list_head list; const char name[EBT_FUNCTION_MAXNAMELEN]; - void (*watcher)(const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const void *watcherdata, - unsigned int datalen); + void (*watcher)(const struct sk_buff *skb, unsigned int hooknr, + const struct net_device *in, const struct net_device *out, + const void *watcherdata, unsigned int datalen); /* 0 == let it in */ int (*check)(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *watcherdata, unsigned int datalen); diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index b0e9f66269ee..68ccef507b49 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig @@ -189,8 +189,22 @@ config BRIDGE_EBT_LOG tristate "ebt: log support" depends on BRIDGE_NF_EBTABLES help - This option adds the log target, that you can use in any rule in - any ebtables table. It records the frame header to the syslog. + This option adds the log watcher, that you can use in any rule + in any ebtables table. It records info about the frame header + to the syslog. + + To compile it as a module, choose M here. If unsure, say N. + +config BRIDGE_EBT_ULOG + tristate "ebt: ulog support" + depends on BRIDGE_NF_EBTABLES + help + This option adds the ulog watcher, that you can use in any rule + in any ebtables table. The packet is passed to a userspace + logging daemon using netlink multicast sockets. This differs + from the log watcher in the sense that the complete packet is + sent to userspace instead of a descriptive text and that + netlink multicast sockets are used instead of the syslog. To compile it as a module, choose M here. If unsure, say N. diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index 6b7d017fcd18..8bf6d9f6e9d3 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o # watchers obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o +obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_ulog.o diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 6c022efaab80..5071e5327241 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -55,8 +55,9 @@ static void print_MAC(unsigned char *p) } #define myNIPQUAD(a) a[0], a[1], a[2], a[3] -static void ebt_log(const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const void *data, unsigned int datalen) +static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, + const struct net_device *in, const struct net_device *out, + const void *data, unsigned int datalen) { struct ebt_log_info *info = (struct ebt_log_info *)data; char level_string[4] = "< >"; diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c new file mode 100644 index 000000000000..ea6c24f6ff26 --- /dev/null +++ b/net/bridge/netfilter/ebt_ulog.c @@ -0,0 +1,295 @@ +/* + * netfilter module for userspace bridged Ethernet frames logging daemons + * + * Authors: + * Bart De Schuymer + * + * November, 2004 + * + * Based on ipt_ULOG.c, which is + * (C) 2000-2002 by Harald Welte + * + * This module accepts two parameters: + * + * nlbufsiz: + * The parameter specifies how big the buffer for each netlink multicast + * group is. e.g. If you say nlbufsiz=8192, up to eight kb of packets will + * get accumulated in the kernel until they are sent to userspace. It is + * NOT possible to allocate more than 128kB, and it is strongly discouraged, + * because atomically allocating 128kB inside the network rx softirq is not + * reliable. Please also keep in mind that this buffer size is allocated for + * each nlgroup you are using, so the total kernel memory usage increases + * by that factor. + * + * flushtimeout: + * Specify, after how many hundredths of a second the queue should be + * flushed even if it is not full yet. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../br_private.h" + +#define PRINTR(format, args...) do { if (net_ratelimit()) \ + printk(format , ## args); } while (0) + +static unsigned int nlbufsiz = 4096; +module_param(nlbufsiz, uint, 0600); +MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) " + "(defaults to 4096)"); + +static unsigned int flushtimeout = 10; +module_param(flushtimeout, uint, 0600); +MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths ofa second) " + "(defaults to 10)"); + +typedef struct { + unsigned int qlen; /* number of nlmsgs' in the skb */ + struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */ + struct sk_buff *skb; /* the pre-allocated skb */ + struct timer_list timer; /* the timer function */ + spinlock_t lock; /* the per-queue lock */ +} ebt_ulog_buff_t; + +static ebt_ulog_buff_t ulog_buffers[EBT_ULOG_MAXNLGROUPS]; +static struct sock *ebtulognl; + +/* send one ulog_buff_t to userspace */ +static void ulog_send(unsigned int nlgroup) +{ + ebt_ulog_buff_t *ub = &ulog_buffers[nlgroup]; + + if (timer_pending(&ub->timer)) + del_timer(&ub->timer); + + /* last nlmsg needs NLMSG_DONE */ + if (ub->qlen > 1) + ub->lastnlh->nlmsg_type = NLMSG_DONE; + + NETLINK_CB(ub->skb).dst_groups = 1 << nlgroup; + netlink_broadcast(ebtulognl, ub->skb, 0, 1 << nlgroup, GFP_ATOMIC); + + ub->qlen = 0; + ub->skb = NULL; +} + +/* timer function to flush queue in flushtimeout time */ +static void ulog_timer(unsigned long data) +{ + spin_lock_bh(&ulog_buffers[data].lock); + if (ulog_buffers[data].skb) + ulog_send(data); + spin_unlock_bh(&ulog_buffers[data].lock); +} + +static struct sk_buff *ulog_alloc_skb(unsigned int size) +{ + struct sk_buff *skb; + + skb = alloc_skb(nlbufsiz, GFP_ATOMIC); + if (!skb) { + PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer " + "of size %ub!\n", nlbufsiz); + if (size < nlbufsiz) { + /* try to allocate only as much as we need for + * current packet */ + skb = alloc_skb(size, GFP_ATOMIC); + if (!skb) + PRINTR(KERN_ERR "ebt_ulog: can't even allocate " + "buffer of size %ub\n", size); + } + } + + return skb; +} + +static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, + const struct net_device *in, const struct net_device *out, + const void *data, unsigned int datalen) +{ + ebt_ulog_packet_msg_t *pm; + size_t size, copy_len; + struct nlmsghdr *nlh; + struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data; + unsigned int group = uloginfo->nlgroup; + ebt_ulog_buff_t *ub = &ulog_buffers[group]; + spinlock_t *lock = &ub->lock; + + if ((uloginfo->cprange == 0) || + (uloginfo->cprange > skb->len + ETH_HLEN)) + copy_len = skb->len + ETH_HLEN; + else + copy_len = uloginfo->cprange; + + size = NLMSG_SPACE(sizeof(*pm) + copy_len); + if (size > nlbufsiz) { + PRINTR("ebt_ulog: Size %d needed, but nlbufsiz=%d\n", + size, nlbufsiz); + return; + } + + spin_lock_bh(lock); + + if (!ub->skb) { + if (!(ub->skb = ulog_alloc_skb(size))) + goto alloc_failure; + } else if (size > skb_tailroom(ub->skb)) { + ulog_send(group); + + if (!(ub->skb = ulog_alloc_skb(size))) + goto alloc_failure; + } + + nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, 0, + size - NLMSG_ALIGN(sizeof(*nlh))); + ub->qlen++; + + pm = NLMSG_DATA(nlh); + + /* Fill in the ulog data */ + pm->version = EBT_ULOG_VERSION; + do_gettimeofday(&pm->stamp); + if (ub->qlen == 1) + ub->skb->stamp = pm->stamp; + pm->data_len = copy_len; + pm->mark = skb->nfmark; + pm->hook = hooknr; + if (uloginfo->prefix != NULL) + strcpy(pm->prefix, uloginfo->prefix); + else + *(pm->prefix) = '\0'; + + if (in) { + strcpy(pm->physindev, in->name); + /* If in isn't a bridge, then physindev==indev */ + if (in->br_port) + strcpy(pm->indev, in->br_port->br->dev->name); + else + strcpy(pm->indev, in->name); + } else + pm->indev[0] = pm->physindev[0] = '\0'; + + if (out) { + /* If out exists, then out is a bridge port */ + strcpy(pm->physoutdev, out->name); + strcpy(pm->outdev, out->br_port->br->dev->name); + } else + pm->outdev[0] = pm->physoutdev[0] = '\0'; + + if (skb_copy_bits(skb, -ETH_HLEN, pm->data, copy_len) < 0) + BUG(); + + if (ub->qlen > 1) + ub->lastnlh->nlmsg_flags |= NLM_F_MULTI; + + ub->lastnlh = nlh; + + if (ub->qlen >= uloginfo->qthreshold) + ulog_send(group); + else if (!timer_pending(&ub->timer)) { + ub->timer.expires = jiffies + flushtimeout * HZ / 100; + add_timer(&ub->timer); + } + +unlock: + spin_unlock_bh(lock); + + return; + +nlmsg_failure: + printk(KERN_CRIT "ebt_ulog: error during NLMSG_PUT. This should " + "not happen, please report to author.\n"); + goto unlock; +alloc_failure: + goto unlock; +} + +static int ebt_ulog_check(const char *tablename, unsigned int hookmask, + const struct ebt_entry *e, void *data, unsigned int datalen) +{ + struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data; + + if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) || + uloginfo->nlgroup > 31) + return -EINVAL; + + uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0'; + + if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN) + uloginfo->qthreshold = EBT_ULOG_MAX_QLEN; + + return 0; +} + +static struct ebt_watcher ulog = { + .name = EBT_ULOG_WATCHER, + .watcher = ebt_ulog, + .check = ebt_ulog_check, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + int i, ret = 0; + + if (nlbufsiz >= 128*1024) { + printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB," + " please try a smaller nlbufsiz parameter.\n"); + return -EINVAL; + } + + /* initialize ulog_buffers */ + for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { + init_timer(&ulog_buffers[i].timer); + ulog_buffers[i].timer.function = ulog_timer; + ulog_buffers[i].timer.data = i; + ulog_buffers[i].lock = SPIN_LOCK_UNLOCKED; + } + + ebtulognl = netlink_kernel_create(NETLINK_NFLOG, NULL); + if (!ebtulognl) + ret = -ENOMEM; + else if ((ret = ebt_register_watcher(&ulog))) + sock_release(ebtulognl->sk_socket); + + return ret; +} + +static void __exit fini(void) +{ + ebt_ulog_buff_t *ub; + int i; + + ebt_unregister_watcher(&ulog); + for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { + ub = &ulog_buffers[i]; + if (timer_pending(&ub->timer)) + del_timer(&ub->timer); + spin_lock_bh(&ub->lock); + if (ub->skb) { + kfree_skb(ub->skb); + ub->skb = NULL; + } + spin_unlock_bh(&ub->lock); + } + sock_release(ebtulognl->sk_socket); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Bart De Schuymer "); +MODULE_DESCRIPTION("ebtables userspace logging module for bridged Ethernet" + " frames"); diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 00926f0bb3a9..33dde2be31ba 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -90,10 +90,10 @@ static struct ebt_target ebt_standard_target = { {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; static inline int ebt_do_watcher (struct ebt_entry_watcher *w, - const struct sk_buff *skb, const struct net_device *in, + const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, const struct net_device *out) { - w->u.watcher->watcher(skb, in, out, w->data, + w->u.watcher->watcher(skb, hooknr, in, out, w->data, w->watcher_size); /* watchers don't give a verdict */ return 0; @@ -208,7 +208,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb, /* these should only watch: not modify, nor tell us what to do with the packet */ - EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, in, + EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, hook, in, out); t = (struct ebt_entry_target *) -- cgit v1.2.3 From 4db3af5c739b99ec1edf38f074a4b6e6717b02b1 Mon Sep 17 00:00:00 2001 From: Esben Nielsen Date: Tue, 23 Nov 2004 07:54:43 -0800 Subject: [ARCNET]: Fixes. As previously reported the ArcNet driver didn't work with Preempt and SMB on. They do now. I have changed the locking system from being a global arcnet lock to being a lock per device. I used the lock in dev->hard_start_xmit = arcnet_send_packet. Furthermore I added the 'CAP mode' encapsulation. As far as I see it it is the only encapsulation which actually makes ArcNet usefull over ethernet. Previously, the driver just ignored the hardware transmit status, now you can get hardware acknowledge and excessive nacks back to userspace via a raw socket. The capmode.c is nearly just a copy of arc-rawmode.c. The difference is that it inserts a ack_tx() handle into the general driver framework. Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/arcnet/Kconfig | 19 +++ drivers/net/arcnet/Makefile | 1 + drivers/net/arcnet/arc-rawmode.c | 9 +- drivers/net/arcnet/arcnet.c | 253 ++++++++++++++++++++++---------- drivers/net/arcnet/capmode.c | 296 ++++++++++++++++++++++++++++++++++++++ drivers/net/arcnet/com20020-isa.c | 1 - drivers/net/arcnet/com20020.c | 28 ++-- drivers/net/arcnet/rfc1051.c | 3 + drivers/net/arcnet/rfc1201.c | 2 + include/linux/arcdevice.h | 21 ++- include/linux/com20020.h | 30 ++-- include/linux/if_arcnet.h | 14 ++ include/linux/if_ether.h | 1 + 13 files changed, 574 insertions(+), 104 deletions(-) create mode 100644 drivers/net/arcnet/capmode.c (limited to 'include/linux') diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig index 528691c8df8b..b258fe614e82 100644 --- a/drivers/net/arcnet/Kconfig +++ b/drivers/net/arcnet/Kconfig @@ -59,6 +59,25 @@ config ARCNET_RAW to work unless talking to a copy of the same Linux arcnet driver, but perhaps marginally faster in that case. +config ARCNET_CAP + tristate "Enable CAP mode packet interface" + depends on ARCNET + help + ARCnet "cap mode" packet encapsulation. Used to get the hardware + acknowledge back to userspace. After the initial protocol byte every + packet is stuffed with an extra 4 byte "cookie" which doesn't + actually appear on the network. After transmit the driver will send + back a packet with protocol byte 0 containing the status of the + transmition: + 0=no hardware acknowledge + 1=excessive nak + 2=transmition accepted by the reciever hardware + + Received packets are also stuffed with the extra 4 bytes but it will + be random data. + + Cap only listens to protocol 1-8. + config ARCNET_COM90xx tristate "ARCnet COM90xx (normal) chipset driver" depends on ARCNET diff --git a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile index e4dae223a344..5861af543d42 100644 --- a/drivers/net/arcnet/Makefile +++ b/drivers/net/arcnet/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_ARCNET) += arcnet.o obj-$(CONFIG_ARCNET_1201) += rfc1201.o obj-$(CONFIG_ARCNET_1051) += rfc1051.o obj-$(CONFIG_ARCNET_RAW) += arc-rawmode.o +obj-$(CONFIG_ARCNET_CAP) += capmode.o obj-$(CONFIG_ARCNET_COM90xx) += com90xx.o obj-$(CONFIG_ARCNET_COM90xxIO) += com90io.o obj-$(CONFIG_ARCNET_RIM_I) += arc-rimi.o diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c index 222caa4a243d..925574cc6b32 100644 --- a/drivers/net/arcnet/arc-rawmode.c +++ b/drivers/net/arcnet/arc-rawmode.c @@ -42,7 +42,6 @@ static int build_header(struct sk_buff *skb, struct net_device *dev, static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); - struct ArcProto rawmode_proto = { .suffix = 'r', @@ -50,6 +49,8 @@ struct ArcProto rawmode_proto = .rx = rx, .build_header = build_header, .prepare_tx = prepare_tx, + .continue_tx = NULL, + .ack_tx = NULL }; @@ -121,7 +122,8 @@ static void rx(struct net_device *dev, int bufnum, BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); - skb->protocol = 0; + skb->protocol = __constant_htons(ETH_P_ARCNET); +; netif_rx(skb); dev->last_rx = jiffies; } @@ -190,6 +192,9 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, } else hard->offset[0] = ofs = 256 - length; + BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n", + length,ofs); + lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE); lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length); diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 5d304676f3df..6b4051df2d6f 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -53,7 +53,6 @@ #include #include - /* "do nothing" functions for protocol drivers */ static void null_rx(struct net_device *dev, int bufnum, struct archdr *pkthdr, int length); @@ -69,25 +68,28 @@ static int null_prepare_tx(struct net_device *dev, struct archdr *pkt, * arc_proto_default instead. It also must not be NULL; if you would like * to set it to NULL, set it to &arc_proto_null instead. */ -struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto; + struct ArcProto *arc_proto_map[256], *arc_proto_default, + *arc_bcast_proto, *arc_raw_proto; struct ArcProto arc_proto_null = { .suffix = '?', .mtu = XMTU, + .is_ip = 0, .rx = null_rx, .build_header = null_build_header, .prepare_tx = null_prepare_tx, + .continue_tx = NULL, + .ack_tx = NULL }; -static spinlock_t arcnet_lock = SPIN_LOCK_UNLOCKED; - /* Exported function prototypes */ int arcnet_debug = ARCNET_DEBUG; EXPORT_SYMBOL(arc_proto_map); EXPORT_SYMBOL(arc_proto_default); EXPORT_SYMBOL(arc_bcast_proto); +EXPORT_SYMBOL(arc_raw_proto); EXPORT_SYMBOL(arc_proto_null); EXPORT_SYMBOL(arcnet_unregister_proto); EXPORT_SYMBOL(arcnet_debug); @@ -131,7 +133,7 @@ static int __init arcnet_init(void) #endif /* initialize the protocol map */ - arc_proto_default = arc_bcast_proto = &arc_proto_null; + arc_raw_proto = arc_proto_default = arc_bcast_proto = &arc_proto_null; for (count = 0; count < 256; count++) arc_proto_map[count] = arc_proto_default; @@ -155,7 +157,8 @@ module_exit(arcnet_exit); * Dump the contents of an sk_buff */ #if ARCNET_DEBUG_MAX & D_SKB -void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc) +void arcnet_dump_skb(struct net_device *dev, + struct sk_buff *skb, char *desc) { int i; @@ -176,18 +179,22 @@ EXPORT_SYMBOL(arcnet_dump_skb); * Dump the contents of an ARCnet buffer */ #if (ARCNET_DEBUG_MAX & (D_RX | D_TX)) -void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc) +void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc, + int take_arcnet_lock) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int i, length; - unsigned long flags; + unsigned long flags = 0; static uint8_t buf[512]; /* hw.copy_from_card expects IRQ context so take the IRQ lock to keep it single threaded */ - spin_lock_irqsave(&arcnet_lock, flags); + if(take_arcnet_lock) + spin_lock_irqsave(&lp->lock, flags); + lp->hw.copy_from_card(dev, bufnum, 0, buf, 512); - spin_unlock_irqrestore(&arcnet_lock, flags); + if(take_arcnet_lock) + spin_unlock_irqrestore(&lp->lock, flags); /* if the offset[0] byte is nonzero, this is a 256-byte packet */ length = (buf[2] ? 256 : 512); @@ -219,6 +226,8 @@ void arcnet_unregister_proto(struct ArcProto *proto) arc_proto_default = &arc_proto_null; if (arc_bcast_proto == proto) arc_bcast_proto = arc_proto_default; + if (arc_raw_proto == proto) + arc_raw_proto = arc_proto_default; for (count = 0; count < 256; count++) { if (arc_proto_map[count] == proto) @@ -261,8 +270,11 @@ static int get_arcbuf(struct net_device *dev) struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int buf = -1, i; - if (!atomic_dec_and_test(&lp->buf_lock)) /* already in this function */ - BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n", lp->buf_lock.counter); + if (!atomic_dec_and_test(&lp->buf_lock)) { + /* already in this function */ + BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n", + lp->buf_lock.counter); + } else { /* we can continue */ if (lp->next_buf >= 5) lp->next_buf -= 5; @@ -312,7 +324,7 @@ void arcdev_setup(struct net_device *dev) dev->mtu = choose_mtu(); dev->addr_len = ARCNET_ALEN; - dev->tx_queue_len = 30; + dev->tx_queue_len = 100; dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */ dev->watchdog_timeo = TX_TIMEOUT; @@ -334,8 +346,16 @@ void arcdev_setup(struct net_device *dev) struct net_device *alloc_arcdev(char *name) { - return alloc_netdev(sizeof(struct arcnet_local), - name && *name ? name : "arc%d", arcdev_setup); + struct net_device *dev; + + dev = alloc_netdev(sizeof(struct arcnet_local), + name && *name ? name : "arc%d", arcdev_setup); + if(dev) { + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + lp->lock = SPIN_LOCK_UNLOCKED; + } + + return dev; } /* @@ -351,6 +371,8 @@ static int arcnet_open(struct net_device *dev) struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int count, newmtu, error; + BUGMSG(D_INIT,"opened."); + if (!try_module_get(lp->hw.owner)) return -ENODEV; @@ -377,6 +399,8 @@ static int arcnet_open(struct net_device *dev) if (newmtu < dev->mtu) dev->mtu = newmtu; + BUGMSG(D_INIT, "arcnet_open: mtu: %d.\n", dev->mtu); + /* autodetect the encapsulation for each host. */ memset(lp->default_proto, 0, sizeof(lp->default_proto)); @@ -390,6 +414,7 @@ static int arcnet_open(struct net_device *dev) /* initialize buffers */ atomic_set(&lp->buf_lock, 1); + lp->next_buf = lp->first_free_buf = 0; release_arcbuf(dev, 0); release_arcbuf(dev, 1); @@ -411,17 +436,24 @@ static int arcnet_open(struct net_device *dev) BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse " "DOS networking programs!\n"); - if (ASTATUS() & RESETflag) + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + if (ASTATUS() & RESETflag) { + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); ACOMMAND(CFLAGScmd | RESETclear); + } + + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); /* make sure we're ready to receive IRQ's. */ AINTMASK(0); udelay(1); /* give it time to set the mask before * we reset it again. (may not even be * necessary) */ + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); lp->intmask = NORXflag | RECONflag; AINTMASK(lp->intmask); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); netif_start_queue(dev); @@ -467,32 +499,41 @@ static int arcnet_header(struct sk_buff *skb, struct net_device *dev, daddr ? *(uint8_t *) daddr : -1, type, type, len); - if (len != skb->len) + if (skb->len!=0 && len != skb->len) BUGMSG(D_NORMAL, "arcnet_header: Yikes! skb->len(%d) != len(%d)!\n", skb->len, len); - /* - * if the dest addr isn't provided, we can't choose an encapsulation! - * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a - * real header when we do rebuild_header. - */ - if (!daddr) { + + /* Type is host order - ? */ + if(type == ETH_P_ARCNET) { + proto = arc_raw_proto; + BUGMSG(D_DEBUG, "arc_raw_proto used. proto='%c'\n",proto->suffix); + _daddr = daddr ? *(uint8_t *) daddr : 0; + } + else if (!daddr) { + /* + * if the dest addr isn't provided, we can't choose an encapsulation! + * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a + * real header when we do rebuild_header. + */ *(uint16_t *) skb_push(skb, 2) = type; if (skb->nh.raw - skb->mac.raw != 2) BUGMSG(D_NORMAL, "arcnet_header: Yikes! diff (%d) is not 2!\n", (int)(skb->nh.raw - skb->mac.raw)); return -2; /* return error -- can't transmit yet! */ } - /* otherwise, we can just add the header as usual. */ - _daddr = *(uint8_t *) daddr; - proto_num = lp->default_proto[_daddr]; - proto = arc_proto_map[proto_num]; - BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n", - proto_num, proto->suffix); - if (proto == &arc_proto_null && arc_bcast_proto != proto) { - BUGMSG(D_DURING, "actually, let's use '%c' instead.\n", - arc_bcast_proto->suffix); - proto = arc_bcast_proto; + else { + /* otherwise, we can just add the header as usual. */ + _daddr = *(uint8_t *) daddr; + proto_num = lp->default_proto[_daddr]; + proto = arc_proto_map[proto_num]; + BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n", + proto_num, proto->suffix); + if (proto == &arc_proto_null && arc_bcast_proto != proto) { + BUGMSG(D_DURING, "actually, let's use '%c' instead.\n", + arc_bcast_proto->suffix); + proto = arc_bcast_proto; + } } return proto->build_header(skb, dev, type, _daddr); } @@ -519,6 +560,7 @@ static int arcnet_rebuild_header(struct sk_buff *skb) return 0; } type = *(uint16_t *) skb_pull(skb, 2); + BUGMSG(D_DURING, "rebuild header for protocol %Xh\n", type); if (type == ETH_P_IP) { #ifdef CONFIG_INET @@ -555,10 +597,12 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) struct arc_rfc1201 *soft; struct ArcProto *proto; int txbuf; + unsigned long flags; + int freeskb = 0; BUGMSG(D_DURING, - "transmit requested (status=%Xh, txbufs=%d/%d, len=%d)\n", - ASTATUS(), lp->cur_tx, lp->next_tx, skb->len); + "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n", + ASTATUS(), lp->cur_tx, lp->next_tx, skb->len,skb->protocol); pkt = (struct archdr *) skb->data; soft = &pkt->soft.rfc1201; @@ -578,38 +622,49 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) /* We're busy transmitting a packet... */ netif_stop_queue(dev); + spin_lock_irqsave(&lp->lock, flags); AINTMASK(0); txbuf = get_arcbuf(dev); if (txbuf != -1) { - if (proto->prepare_tx(dev, pkt, skb->len, txbuf)) { - /* done right away */ + if (proto->prepare_tx(dev, pkt, skb->len, txbuf) && + !proto->ack_tx) { + /* done right away and we don't want to acknowledge + the package later - forget about it now */ lp->stats.tx_bytes += skb->len; - dev_kfree_skb(skb); + freeskb = 1; } else { /* do it the 'split' way */ lp->outgoing.proto = proto; lp->outgoing.skb = skb; lp->outgoing.pkt = pkt; - if (!proto->continue_tx) - BUGMSG(D_NORMAL, "bug! prep_tx==0, but no continue_tx!\n"); - else if (proto->continue_tx(dev, txbuf)) { - BUGMSG(D_NORMAL, - "bug! continue_tx finished the first time! " - "(proto='%c')\n", proto->suffix); + if (proto->continue_tx && + proto->continue_tx(dev, txbuf)) { + BUGMSG(D_NORMAL, + "bug! continue_tx finished the first time! " + "(proto='%c')\n", proto->suffix); } } lp->next_tx = txbuf; - } else - dev_kfree_skb(skb); + } else { + freeskb = 1; + } + BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS()); /* make sure we didn't ignore a TX IRQ while we were in here */ AINTMASK(0); - lp->intmask |= TXFREEflag; + + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + lp->intmask |= TXFREEflag|EXCNAKflag; AINTMASK(lp->intmask); + BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS()); + spin_unlock_irqrestore(&lp->lock, flags); + if (freeskb) { + dev_kfree_skb(skb); + } return 0; /* no need to try again */ } @@ -628,7 +683,7 @@ static int go_tx(struct net_device *dev) if (lp->cur_tx != -1 || lp->next_tx == -1) return 0; - BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx"); + BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx", 0); lp->cur_tx = lp->next_tx; lp->next_tx = -1; @@ -640,7 +695,8 @@ static int go_tx(struct net_device *dev) lp->stats.tx_packets++; lp->lasttrans_dest = lp->lastload_dest; lp->lastload_dest = 0; - lp->intmask |= TXFREEflag; + lp->excnak_pending = 0; + lp->intmask |= TXFREEflag|EXCNAKflag; return 1; } @@ -654,7 +710,7 @@ static void arcnet_timeout(struct net_device *dev) int status = ASTATUS(); char *msg; - spin_lock_irqsave(&arcnet_lock, flags); + spin_lock_irqsave(&lp->lock, flags); if (status & TXFREEflag) { /* transmit _DID_ finish */ msg = " - missed IRQ?"; } else { @@ -665,12 +721,12 @@ static void arcnet_timeout(struct net_device *dev) } lp->stats.tx_errors++; - /* make sure we didn't miss a TX IRQ */ + /* make sure we didn't miss a TX or a EXC NAK IRQ */ AINTMASK(0); - lp->intmask |= TXFREEflag; + lp->intmask |= TXFREEflag|EXCNAKflag; AINTMASK(lp->intmask); - spin_unlock_irqrestore(&arcnet_lock, flags); + spin_unlock_irqrestore(&lp->lock, flags); if (jiffies - lp->last_timeout > 10*HZ) { BUGMSG(D_EXTRA, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n", @@ -692,18 +748,19 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct arcnet_local *lp; - int recbuf, status, didsomething, boguscount; + int recbuf, status, diagstatus, didsomething, boguscount; + int retval = IRQ_NONE; BUGMSG(D_DURING, "\n"); BUGMSG(D_DURING, "in arcnet_interrupt\n"); - - spin_lock(&arcnet_lock); lp = (struct arcnet_local *) dev->priv; if (!lp) BUG(); + spin_lock(&lp->lock); + /* * RESET flag was enabled - if device is not running, we must clear it right * away (but nothing else). @@ -712,7 +769,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (ASTATUS() & RESETflag) ACOMMAND(CFLAGScmd | RESETclear); AINTMASK(0); - spin_unlock(&arcnet_lock); + spin_unlock(&lp->lock); return IRQ_HANDLED; } @@ -722,6 +779,10 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) boguscount = 5; do { status = ASTATUS(); + diagstatus = (status >> 8) & 0xFF; + + BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n", + __FILE__,__LINE__,__FUNCTION__,status); didsomething = 0; /* @@ -761,24 +822,55 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) } didsomething++; } + + if((diagstatus & EXCNAKflag)) { + BUGMSG(D_DURING, "EXCNAK IRQ (diagstat=%Xh)\n", + diagstatus); + + ACOMMAND(NOTXcmd); /* disable transmit */ + lp->excnak_pending = 1; + + ACOMMAND(EXCNAKclear); + lp->intmask &= ~(EXCNAKflag); + didsomething++; + } + + /* a transmit finished, and we're interested in it. */ if ((status & lp->intmask & TXFREEflag) || lp->timed_out) { - lp->intmask &= ~TXFREEflag; + lp->intmask &= ~(TXFREEflag|EXCNAKflag); BUGMSG(D_DURING, "TX IRQ (stat=%Xh)\n", status); - if (lp->cur_tx != -1 && !(status & TXACKflag) && !lp->timed_out) { - if (lp->lasttrans_dest != 0) { - BUGMSG(D_EXTRA, "transmit was not acknowledged! " - "(status=%Xh, dest=%02Xh)\n", - status, lp->lasttrans_dest); - lp->stats.tx_errors++; - lp->stats.tx_carrier_errors++; - } else { - BUGMSG(D_DURING, - "broadcast was not acknowledged; that's normal " - "(status=%Xh, dest=%02Xh)\n", - status, lp->lasttrans_dest); + if (lp->cur_tx != -1 && !lp->timed_out) { + if(!(status & TXACKflag)) { + if (lp->lasttrans_dest != 0) { + BUGMSG(D_EXTRA, + "transmit was not acknowledged! " + "(status=%Xh, dest=%02Xh)\n", + status, lp->lasttrans_dest); + lp->stats.tx_errors++; + lp->stats.tx_carrier_errors++; + } else { + BUGMSG(D_DURING, + "broadcast was not acknowledged; that's normal " + "(status=%Xh, dest=%02Xh)\n", + status, lp->lasttrans_dest); + } + } + + if (lp->outgoing.proto && + lp->outgoing.proto->ack_tx) { + int ackstatus; + if(status & TXACKflag) + ackstatus=2; + else if(lp->excnak_pending) + ackstatus=1; + else + ackstatus=0; + + lp->outgoing.proto + ->ack_tx(dev, ackstatus); } } if (lp->cur_tx != -1) @@ -798,8 +890,11 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (lp->outgoing.proto->continue_tx(dev, txbuf)) { /* that was the last segment */ lp->stats.tx_bytes += lp->outgoing.skb->len; - dev_kfree_skb_irq(lp->outgoing.skb); - lp->outgoing.proto = NULL; + if(!lp->outgoing.proto->ack_tx) + { + dev_kfree_skb_irq(lp->outgoing.skb); + lp->outgoing.proto = NULL; + } } lp->next_tx = txbuf; } @@ -810,7 +905,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) } /* now process the received packet, if any */ if (recbuf != -1) { - BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq"); + BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq", 0); arcnet_rx(dev, recbuf); release_arcbuf(dev, recbuf); @@ -868,6 +963,10 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) BUGMSG(D_DURING, "not recon: clearing counters anyway.\n"); } + + if(didsomething) { + retval |= IRQ_HANDLED; + } } while (--boguscount && didsomething); @@ -880,8 +979,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) udelay(1); AINTMASK(lp->intmask); - spin_unlock(&arcnet_lock); - return IRQ_RETVAL(didsomething); + spin_unlock(&lp->lock); + return retval; } @@ -908,7 +1007,7 @@ void arcnet_rx(struct net_device *dev, int bufnum) } /* get the full header, if possible */ - if (sizeof(pkt.soft) < length) + if (sizeof(pkt.soft) <= length) lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft)); else { memset(&pkt.soft, 0, sizeof(pkt.soft)); @@ -923,7 +1022,7 @@ void arcnet_rx(struct net_device *dev, int bufnum) lp->stats.rx_bytes += length + ARC_HDR_SIZE; /* call the right receiver for the protocol */ - if (arc_proto_map[soft->proto] != &arc_proto_null) { + if (arc_proto_map[soft->proto]->is_ip) { BUGLVL(D_PROTO) { struct ArcProto *oldp = arc_proto_map[lp->default_proto[pkt.hard.source]], diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c new file mode 100644 index 000000000000..16e155b04129 --- /dev/null +++ b/drivers/net/arcnet/capmode.c @@ -0,0 +1,296 @@ +/* + * Linux ARCnet driver - "cap mode" packet encapsulation. + * It adds sequence numbers to packets for communicating between a user space + * application and the driver. After a transmit it sends a packet with protocol + * byte 0 back up to the userspace containing the sequence number of the packet + * plus the transmit-status on the ArcNet. + * + * Written 2002-4 by Esben Nielsen, Vestas Wind Systems A/S + * Derived from arc-rawmode.c by Avery Pennarun. + * arc-rawmode was in turned based on skeleton.c, see below. + * + * ********************** + * + * The original copyright of skeleton.c was as follows: + * + * skeleton.c Written 1993 by Donald Becker. + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. This software may only be used + * and distributed according to the terms of the GNU General Public License as + * modified by SRC, incorporated herein by reference. + * + * ********************** + * + * For more details, see drivers/net/arcnet.c + * + * ********************** + */ + +#include +#include +#include +#include +#include +#include +#include + +#define VERSION "arcnet: cap mode (`c') encapsulation support loaded.\n" + + +static void rx(struct net_device *dev, int bufnum, + struct archdr *pkthdr, int length); +static int build_header(struct sk_buff *skb, + struct net_device *dev, + unsigned short type, + uint8_t daddr); +static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, + int bufnum); +static int ack_tx(struct net_device *dev, int acked); + + +struct ArcProto capmode_proto = +{ + 'r', + XMTU, + 0, + rx, + build_header, + prepare_tx, + NULL, + ack_tx +}; + + +void arcnet_cap_init(void) +{ + int count; + + for (count = 1; count <= 8; count++) + if (arc_proto_map[count] == arc_proto_default) + arc_proto_map[count] = &capmode_proto; + + /* for cap mode, we only set the bcast proto if there's no better one */ + if (arc_bcast_proto == arc_proto_default) + arc_bcast_proto = &capmode_proto; + + arc_proto_default = &capmode_proto; + arc_raw_proto = &capmode_proto; +} + + +#ifdef MODULE + +int __init init_module(void) +{ + printk(VERSION); + arcnet_cap_init(); + return 0; +} + +void cleanup_module(void) +{ + arcnet_unregister_proto(&capmode_proto); +} + +MODULE_LICENSE("GPL"); +#endif /* MODULE */ + + + +/* packet receiver */ +static void rx(struct net_device *dev, int bufnum, + struct archdr *pkthdr, int length) +{ + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + struct sk_buff *skb; + struct archdr *pkt = pkthdr; + char *pktbuf, *pkthdrbuf; + int ofs; + + BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length); + + if (length >= MinTU) + ofs = 512 - length; + else + ofs = 256 - length; + + skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; + } + skb_put(skb, length + ARC_HDR_SIZE + sizeof(int)); + skb->dev = dev; + + pkt = (struct archdr *) skb->data; + + skb->mac.raw = skb->data; + skb_pull(skb, ARC_HDR_SIZE); + + /* up to sizeof(pkt->soft) has already been copied from the card */ + /* squeeze in an int for the cap encapsulation */ + + /* use these variables to be sure we count in bytes, not in + sizeof(struct archdr) */ + pktbuf=(char*)pkt; + pkthdrbuf=(char*)pkthdr; + memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)); + memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int), + pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto), + sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto)); + + if (length > sizeof(pkt->soft)) + lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft), + pkt->soft.raw + sizeof(pkt->soft) + + sizeof(int), + length - sizeof(pkt->soft)); + + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); + + skb->protocol = __constant_htons(ETH_P_ARCNET); +; + netif_rx(skb); + dev->last_rx = jiffies; +} + + +/* + * Create the ARCnet hard/soft headers for cap mode. + * There aren't any soft headers in cap mode - not even the protocol id. + */ +static int build_header(struct sk_buff *skb, + struct net_device *dev, + unsigned short type, + uint8_t daddr) +{ + int hdr_size = ARC_HDR_SIZE; + struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size); + + BUGMSG(D_PROTO, "Preparing header for cap packet %x.\n", + *((int*)&pkt->soft.cap.cookie[0])); + /* + * Set the source hardware address. + * + * This is pretty pointless for most purposes, but it can help in + * debugging. ARCnet does not allow us to change the source address in + * the actual packet sent) + */ + pkt->hard.source = *dev->dev_addr; + + /* see linux/net/ethernet/eth.c to see where I got the following */ + + if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { + /* + * FIXME: fill in the last byte of the dest ipaddr here to better + * comply with RFC1051 in "noarp" mode. + */ + pkt->hard.dest = 0; + return hdr_size; + } + /* otherwise, just fill it in and go! */ + pkt->hard.dest = daddr; + + return hdr_size; /* success */ +} + + +static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, + int bufnum) +{ + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + struct arc_hardware *hard = &pkt->hard; + int ofs; + + + /* hard header is not included in packet length */ + length -= ARC_HDR_SIZE; + /* And neither is the cookie field */ + length -= sizeof(int); + + BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n", + lp->next_tx, lp->cur_tx, bufnum); + + BUGMSG(D_PROTO, "Sending for cap packet %x.\n", + *((int*)&pkt->soft.cap.cookie[0])); + + if (length > XMTU) { + /* should never happen! other people already check for this. */ + BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n", + length, XMTU); + length = XMTU; + } + if (length > MinTU) { + hard->offset[0] = 0; + hard->offset[1] = ofs = 512 - length; + } else if (length > MTU) { + hard->offset[0] = 0; + hard->offset[1] = ofs = 512 - length - 3; + } else + hard->offset[0] = ofs = 256 - length; + + BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n", + length,ofs); + + // Copy the arcnet-header + the protocol byte down: + lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE); + lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto, + sizeof(pkt->soft.cap.proto)); + + // Skip the extra integer we have written into it as a cookie + // but write the rest of the message: + lp->hw.copy_to_card(dev, bufnum, ofs+1, + ((unsigned char*)&pkt->soft.cap.mes),length-1); + + lp->lastload_dest = hard->dest; + + return 1; /* done */ +} + + +static int ack_tx(struct net_device *dev, int acked) +{ + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + struct sk_buff *ackskb; + struct archdr *ackpkt; + int length=sizeof(struct arc_cap); + + BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n", + lp->outgoing.skb->protocol, acked); + + BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx"); + + /* Now alloc a skb to send back up through the layers: */ + ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC); + if (ackskb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n"); + goto free_outskb; + } + + skb_put(ackskb, length + ARC_HDR_SIZE ); + ackskb->dev = dev; + + ackpkt = (struct archdr *) ackskb->data; + + ackskb->mac.raw = ackskb->data; + /* skb_pull(ackskb, ARC_HDR_SIZE); */ + + + memcpy(ackpkt, lp->outgoing.skb->data, ARC_HDR_SIZE+sizeof(struct arc_cap)); + ackpkt->soft.cap.proto=0; /* using protocol 0 for acknowledge */ + ackpkt->soft.cap.mes.ack=acked; + + BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n", + *((int*)&ackpkt->soft.cap.cookie[0])); + + ackskb->protocol = __constant_htons(ETH_P_ARCNET); + + BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv"); + netif_rx(ackskb); + + free_outskb: + dev_kfree_skb_irq(lp->outgoing.skb); + lp->outgoing.proto = NULL; /* We are always finished when in this protocol */ + + return 0; +} diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c index 09af99a724b2..9289e6103de5 100644 --- a/drivers/net/arcnet/com20020-isa.c +++ b/drivers/net/arcnet/com20020-isa.c @@ -41,7 +41,6 @@ #include - #define VERSION "arcnet: COM20020 ISA support (by David Woodhouse et al.)\n" diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 7fa829eef427..b40ee3ff7fb4 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -117,7 +117,7 @@ int com20020_check(struct net_device *dev) lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2); /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */ SETCONF; - outb(0x42, ioaddr + 7); + outb(0x42, ioaddr + BUS_ALIGN*7); status = ASTATUS(); @@ -129,7 +129,7 @@ int com20020_check(struct net_device *dev) /* Enable TX */ outb(0x39, _CONFIG); - outb(inb(ioaddr + 8), ioaddr + 7); + outb(inb(ioaddr + BUS_ALIGN*8), ioaddr + BUS_ALIGN*7); ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear); @@ -173,7 +173,7 @@ int com20020_found(struct net_device *dev, int shared) dev->set_multicast_list = com20020_set_mc_list; if (!dev->dev_addr[0]) - dev->dev_addr[0] = inb(ioaddr + 8); /* FIXME: do this some other way! */ + dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this some other way! */ SET_SUBADR(SUB_SETUP1); outb(lp->setup, _XREG); @@ -188,7 +188,6 @@ int com20020_found(struct net_device *dev, int shared) outb(0x18, _COMMAND); } - lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1; /* Default 0x38 + register: Node ID */ SETCONF; @@ -235,15 +234,19 @@ int com20020_found(struct net_device *dev, int shared) static int com20020_reset(struct net_device *dev, int really_reset) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - short ioaddr = dev->base_addr; + u_int ioaddr = dev->base_addr; u_char inbyte; + BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n", + __FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name); BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS()); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2); /* power-up defaults */ SETCONF; + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); if (really_reset) { /* reset the card */ @@ -251,17 +254,22 @@ static int com20020_reset(struct net_device *dev, int really_reset) mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */ } /* clear flags & end reset */ + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear); /* verify that the ARCnet signature byte is present */ + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); com20020_copy_from_card(dev, 0, 0, &inbyte, 1); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); if (inbyte != TESTvalue) { + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n"); return 1; } /* enable extended (512-byte) packets */ ACOMMAND(CONFIGcmd | EXTconf); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); /* done! return success. */ return 0; @@ -270,22 +278,24 @@ static int com20020_reset(struct net_device *dev, int really_reset) static void com20020_setmask(struct net_device *dev, int mask) { - short ioaddr = dev->base_addr; + u_int ioaddr = dev->base_addr; + BUGMSG(D_DURING, "Setting mask to %x at %x\n",mask,ioaddr); AINTMASK(mask); } static void com20020_command(struct net_device *dev, int cmd) { - short ioaddr = dev->base_addr; + u_int ioaddr = dev->base_addr; ACOMMAND(cmd); } static int com20020_status(struct net_device *dev) { - short ioaddr = dev->base_addr; - return ASTATUS(); + u_int ioaddr = dev->base_addr; + + return ASTATUS() + (ADIAGSTATUS()<<8); } static void com20020_close(struct net_device *dev) diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c index 3fd23f97bd46..fd959cb3ef7d 100644 --- a/drivers/net/arcnet/rfc1051.c +++ b/drivers/net/arcnet/rfc1051.c @@ -47,9 +47,12 @@ struct ArcProto rfc1051_proto = { .suffix = 's', .mtu = XMTU - RFC1051_HDR_SIZE, + .is_ip = 1, .rx = rx, .build_header = build_header, .prepare_tx = prepare_tx, + .continue_tx = NULL, + .ack_tx = NULL }; diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c index ff1d434c7c51..ed793b15f0ee 100644 --- a/drivers/net/arcnet/rfc1201.c +++ b/drivers/net/arcnet/rfc1201.c @@ -47,10 +47,12 @@ struct ArcProto rfc1201_proto = { .suffix = 'a', .mtu = 1500, /* could be more, but some receivers can't handle it... */ + .is_ip = 1, /* This is for sending IP and ARP packages */ .rx = rx, .build_header = build_header, .prepare_tx = prepare_tx, .continue_tx = continue_tx, + .ack_tx = NULL }; diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h index 9d2429f07a64..bd4364daf948 100644 --- a/include/linux/arcdevice.h +++ b/include/linux/arcdevice.h @@ -25,7 +25,6 @@ #define bool int #endif - /* * RECON_THRESHOLD is the maximum number of RECON messages to receive * within one minute before printing a "cabling problem" warning. The @@ -74,6 +73,7 @@ #define D_SKB 1024 /* show skb's */ #define D_SKB_SIZE 2048 /* show skb sizes */ #define D_TIMING 4096 /* show time needed to copy buffers to card */ +#define D_DEBUG 8192 /* Very detailed debug line for line */ #ifndef ARCNET_DEBUG_MAX #define ARCNET_DEBUG_MAX (127) /* change to ~0 if you want detailed debugging */ @@ -135,6 +135,7 @@ extern int arcnet_debug; #define TXACKflag 0x02 /* transmitted msg. ackd */ #define RECONflag 0x04 /* network reconfigured */ #define TESTflag 0x08 /* test flag */ +#define EXCNAKflag 0x08 /* excesive nak flag */ #define RESETflag 0x10 /* power-on-reset */ #define RES1flag 0x20 /* reserved - usually set by jumper */ #define RES2flag 0x40 /* reserved - usually set by jumper */ @@ -162,6 +163,8 @@ extern int arcnet_debug; #define RESETclear 0x08 /* power-on-reset */ #define CONFIGclear 0x10 /* system reconfigured */ +#define EXCNAKclear 0x0E /* Clear and acknowledge the excive nak bit */ + /* flags for "load test flags" command */ #define TESTload 0x08 /* test flag (diagnostic) */ @@ -187,6 +190,7 @@ extern int arcnet_debug; struct ArcProto { char suffix; /* a for RFC1201, e for ether-encap, etc. */ int mtu; /* largest possible packet */ + int is_ip; /* This is a ip plugin - not a raw thing */ void (*rx) (struct net_device * dev, int bufnum, struct archdr * pkthdr, int length); @@ -197,9 +201,11 @@ struct ArcProto { int (*prepare_tx) (struct net_device * dev, struct archdr * pkt, int length, int bufnum); int (*continue_tx) (struct net_device * dev, int bufnum); + int (*ack_tx) (struct net_device * dev, int acked); }; -extern struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto; +extern struct ArcProto *arc_proto_map[256], *arc_proto_default, + *arc_bcast_proto, *arc_raw_proto; extern struct ArcProto arc_proto_null; @@ -251,6 +257,10 @@ struct arcnet_local { char *card_name; /* card ident string */ int card_flags; /* special card features */ + + /* On preemtive and SMB a lock is needed */ + spinlock_t lock; + /* * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of * which can be used for either sending or receiving. The new dynamic @@ -279,6 +289,8 @@ struct arcnet_local { int num_recons; /* number of RECONs between first and last. */ bool network_down; /* do we think the network is down? */ + bool excnak_pending; /* We just got an excesive nak interrupt */ + struct { uint16_t sequence; /* sequence number (incs with each packet) */ uint16_t aborted_seq; @@ -323,9 +335,10 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc); #endif #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc); +void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc, + int take_arcnet_lock); #else -#define arcnet_dump_packet(dev, bufnum, desc) ; +#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) ; #endif void arcnet_unregister_proto(struct ArcProto *proto); diff --git a/include/linux/com20020.h b/include/linux/com20020.h index c88d530bf637..ac6d9a43e085 100644 --- a/include/linux/com20020.h +++ b/include/linux/com20020.h @@ -34,17 +34,24 @@ int com20020_found(struct net_device *dev, int shared); #define ARCNET_TOTAL_SIZE 8 /* various register addresses */ -#define _INTMASK (ioaddr+0) /* writable */ -#define _STATUS (ioaddr+0) /* readable */ -#define _COMMAND (ioaddr+1) /* standard arcnet commands */ -#define _DIAGSTAT (ioaddr+1) /* diagnostic status register */ -#define _ADDR_HI (ioaddr+2) /* control registers for IO-mapped memory */ -#define _ADDR_LO (ioaddr+3) -#define _MEMDATA (ioaddr+4) /* data port for IO-mapped memory */ -#define _SUBADR (ioaddr+5) /* the extended port _XREG refers to */ -#define _CONFIG (ioaddr+6) /* configuration register */ -#define _XREG (ioaddr+7) /* extra registers (indexed by _CONFIG - or _SUBADR) */ +#ifdef CONFIG_SA1100_CT6001 +#define BUS_ALIGN 2 /* 8 bit device on a 16 bit bus - needs padding */ +#else +#define BUS_ALIGN 1 +#endif + + +#define _INTMASK (ioaddr+BUS_ALIGN*0) /* writable */ +#define _STATUS (ioaddr+BUS_ALIGN*0) /* readable */ +#define _COMMAND (ioaddr+BUS_ALIGN*1) /* standard arcnet commands */ +#define _DIAGSTAT (ioaddr+BUS_ALIGN*1) /* diagnostic status register */ +#define _ADDR_HI (ioaddr+BUS_ALIGN*2) /* control registers for IO-mapped memory */ +#define _ADDR_LO (ioaddr+BUS_ALIGN*3) +#define _MEMDATA (ioaddr+BUS_ALIGN*4) /* data port for IO-mapped memory */ +#define _SUBADR (ioaddr+BUS_ALIGN*5) /* the extended port _XREG refers to */ +#define _CONFIG (ioaddr+BUS_ALIGN*6) /* configuration register */ +#define _XREG (ioaddr+BUS_ALIGN*7) /* extra registers (indexed by _CONFIG + or _SUBADR) */ /* in the ADDR_HI register */ #define RDDATAflag 0x80 /* next access is a read (not a write) */ @@ -99,6 +106,7 @@ int com20020_found(struct net_device *dev, int shared); } #define ASTATUS() inb(_STATUS) +#define ADIAGSTATUS() inb(_DIAGSTAT) #define ACOMMAND(cmd) outb((cmd),_COMMAND) #define AINTMASK(msk) outb((msk),_INTMASK) diff --git a/include/linux/if_arcnet.h b/include/linux/if_arcnet.h index 08f413b0fceb..af380cb876a0 100644 --- a/include/linux/if_arcnet.h +++ b/include/linux/if_arcnet.h @@ -23,6 +23,9 @@ * These are the defined ARCnet Protocol ID's. */ +/* CAP mode */ +/* No macro but uses 1-8 */ + /* RFC1201 Protocol ID's */ #define ARC_P_IP 212 /* 0xD4 */ #define ARC_P_IPV6 196 /* 0xC4: RFC2497 */ @@ -86,6 +89,16 @@ struct arc_eth_encap #define ETH_ENCAP_HDR_SIZE 14 +struct arc_cap +{ + uint8_t proto; + uint8_t cookie[sizeof(int)]; /* Actually NOT sent over the network */ + union { + uint8_t ack; + uint8_t raw[0]; /* 507 bytes */ + } mes; +}; + /* * The data needed by the actual arcnet hardware. * @@ -116,6 +129,7 @@ struct archdr struct arc_rfc1201 rfc1201; struct arc_rfc1051 rfc1051; struct arc_eth_encap eth_encap; + struct arc_cap cap; uint8_t raw[0]; /* 508 bytes */ } soft; }; diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 4037aaab7aa9..75c1a290c8c2 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -91,6 +91,7 @@ #define ETH_P_IRDA 0x0017 /* Linux-IrDA */ #define ETH_P_ECONET 0x0018 /* Acorn Econet */ #define ETH_P_HDLC 0x0019 /* HDLC frames */ +#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */ /* * This is an Ethernet frame header. -- cgit v1.2.3 From 81b80feebe38f695816ddc92e69890e69d199729 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 25 Nov 2004 23:45:27 -0600 Subject: LSI Logic - SAS and FC PCI ID's From: Moore, Eric Dean Here are new PCI ID's for SAS and Fibre Channel LSI Logic controllers. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- include/linux/pci_ids.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5cfcf8941445..d274c4b96365 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -176,10 +176,20 @@ #define PCI_DEVICE_ID_LSI_FC919 0x0624 #define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625 #define PCI_DEVICE_ID_LSI_FC929X 0x0626 +#define PCI_DEVICE_ID_LSI_FC939X 0x0642 +#define PCI_DEVICE_ID_LSI_FC949X 0x0640 #define PCI_DEVICE_ID_LSI_FC919X 0x0628 #define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701 #define PCI_DEVICE_ID_LSI_61C102 0x0901 #define PCI_DEVICE_ID_LSI_63C815 0x1000 +#define PCI_DEVICE_ID_LSI_SAS1064 0x0050 +#define PCI_DEVICE_ID_LSI_SAS1066 0x005E +#define PCI_DEVICE_ID_LSI_SAS1068 0x0054 +#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C +#define PCI_DEVICE_ID_LSI_SAS1064E 0x0056 +#define PCI_DEVICE_ID_LSI_SAS1066E 0x005A +#define PCI_DEVICE_ID_LSI_SAS1068E 0x0058 +#define PCI_DEVICE_ID_LSI_SAS1078 0x0060 #define PCI_VENDOR_ID_ATI 0x1002 /* Mach64 */ -- cgit v1.2.3 From 9a8ce58ac0161da625aeae2ef3ca91c681ca526e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 27 Nov 2004 14:20:20 +0100 Subject: [NETFILTER]: Remove CONFIG_IP_NF_NAT_LOCAL config option Signed-off-by: Patrick McHardy --- arch/alpha/defconfig | 1 - arch/arm/configs/ebsa110_defconfig | 1 - arch/arm/configs/ixp4xx_defconfig | 1 - arch/i386/defconfig | 1 - arch/m68k/configs/amiga_defconfig | 1 - arch/m68k/configs/apollo_defconfig | 1 - arch/m68k/configs/atari_defconfig | 1 - arch/m68k/configs/bvme6000_defconfig | 1 - arch/m68k/configs/hp300_defconfig | 1 - arch/m68k/configs/mac_defconfig | 1 - arch/m68k/configs/mvme147_defconfig | 1 - arch/m68k/configs/mvme16x_defconfig | 1 - arch/m68k/configs/q40_defconfig | 1 - arch/m68k/configs/sun3_defconfig | 1 - arch/m68k/configs/sun3x_defconfig | 1 - arch/mips/configs/ip22_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/defconfig | 1 - arch/parisc/configs/a500_defconfig | 1 - arch/parisc/configs/c3000_defconfig | 1 - arch/parisc/configs/n4000_defconfig | 1 - arch/ppc/configs/adir_defconfig | 1 - arch/ppc/configs/apus_defconfig | 1 - arch/ppc/configs/common_defconfig | 1 - arch/ppc/configs/ibmchrp_defconfig | 1 - arch/ppc/configs/k2_defconfig | 1 - arch/ppc/configs/menf1_defconfig | 1 - arch/ppc/configs/pcore_defconfig | 1 - arch/ppc/configs/pmac_defconfig | 1 - arch/ppc/configs/pplus_defconfig | 1 - arch/ppc/defconfig | 1 - arch/ppc64/configs/g5_defconfig | 1 - arch/ppc64/configs/iSeries_defconfig | 1 - arch/ppc64/configs/pSeries_defconfig | 1 - arch/ppc64/defconfig | 1 - arch/sparc64/defconfig | 1 - include/linux/netfilter_ipv4/ip_nat.h | 5 ----- net/ipv4/netfilter/Kconfig | 14 -------------- net/ipv4/netfilter/ip_nat_core.c | 8 -------- net/ipv4/netfilter/ip_nat_rule.c | 11 ----------- net/ipv4/netfilter/ip_nat_standalone.c | 26 ++++---------------------- 41 files changed, 4 insertions(+), 96 deletions(-) (limited to 'include/linux') diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 6ac8d4a7d634..5e39b7a7c8f4 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -411,7 +411,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m # CONFIG_IP_NF_TARGET_REDIRECT is not set # CONFIG_IP_NF_TARGET_NETMAP is not set # CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/arm/configs/ebsa110_defconfig b/arch/arm/configs/ebsa110_defconfig index 68f4047fc309..5296812f87d8 100644 --- a/arch/arm/configs/ebsa110_defconfig +++ b/arch/arm/configs/ebsa110_defconfig @@ -239,7 +239,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_REDIRECT=y CONFIG_IP_NF_TARGET_NETMAP=y CONFIG_IP_NF_TARGET_SAME=y -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=y CONFIG_IP_NF_NAT_FTP=y diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index 7b821f811a86..3a068df0e6d7 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -399,7 +399,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m # CONFIG_IP_NF_TARGET_NETMAP is not set # CONFIG_IP_NF_TARGET_SAME is not set -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 1a0ba2c4d88b..8b91f12fdbc5 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -534,7 +534,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_REDIRECT=y CONFIG_IP_NF_TARGET_NETMAP=y CONFIG_IP_NF_TARGET_SAME=y -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_MANGLE=y CONFIG_IP_NF_TARGET_TOS=y diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index d9c4a1a1e2ee..736015226cda 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -356,7 +356,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index e6a0881c65e6..8b26f5562158 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -281,7 +281,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 9c39729f8f06..64b235758c10 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -311,7 +311,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 971d96965675..3300ee17c8b6 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -281,7 +281,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 06db209c14c3..e3dd814a8334 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -282,7 +282,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 45065e68ceda..00584b78ccc0 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -318,7 +318,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 7232b0cfbbda..07c0b063582f 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -282,7 +282,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 8f87aebaa8f8..792d016e548c 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -281,7 +281,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index eb4dba248aab..44ec065ff0fa 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -336,7 +336,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 640ab0ad12a7..e905b02b7356 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -270,7 +270,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 315dd4d7eccf..5df8adaa3a43 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -281,7 +281,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 8bc7792d6cf6..26b2ef143873 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -342,7 +342,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 2ec3932802cd..790f94c542dd 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -437,7 +437,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 8bc7792d6cf6..26b2ef143873 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -342,7 +342,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index e5c57399e67c..6cbb2118673f 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig @@ -338,7 +338,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index 087dfcd1d4c9..902775106de4 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -396,7 +396,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/parisc/configs/n4000_defconfig b/arch/parisc/configs/n4000_defconfig index 8df4bb1cc7b1..605718cfe99f 100644 --- a/arch/parisc/configs/n4000_defconfig +++ b/arch/parisc/configs/n4000_defconfig @@ -331,7 +331,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/adir_defconfig b/arch/ppc/configs/adir_defconfig index 3c40aaaecb98..f20e6533dc79 100644 --- a/arch/ppc/configs/adir_defconfig +++ b/arch/ppc/configs/adir_defconfig @@ -302,7 +302,6 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig index 53fb29358a67..e2245252d31f 100644 --- a/arch/ppc/configs/apus_defconfig +++ b/arch/ppc/configs/apus_defconfig @@ -354,7 +354,6 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index 1e331f73523d..ac453e160070 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -457,7 +457,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/ibmchrp_defconfig b/arch/ppc/configs/ibmchrp_defconfig index a3b6ec0d5592..27f3e69c1f96 100644 --- a/arch/ppc/configs/ibmchrp_defconfig +++ b/arch/ppc/configs/ibmchrp_defconfig @@ -367,7 +367,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/k2_defconfig b/arch/ppc/configs/k2_defconfig index edf52030f95b..f10f5a6d2dae 100644 --- a/arch/ppc/configs/k2_defconfig +++ b/arch/ppc/configs/k2_defconfig @@ -319,7 +319,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m # CONFIG_IP_NF_TARGET_NETMAP is not set # CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_FTP=m # CONFIG_IP_NF_MANGLE is not set diff --git a/arch/ppc/configs/menf1_defconfig b/arch/ppc/configs/menf1_defconfig index e84d06af2b29..321659b5505f 100644 --- a/arch/ppc/configs/menf1_defconfig +++ b/arch/ppc/configs/menf1_defconfig @@ -249,7 +249,6 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/pcore_defconfig b/arch/ppc/configs/pcore_defconfig index ba09d840d03f..ed34405a7574 100644 --- a/arch/ppc/configs/pcore_defconfig +++ b/arch/ppc/configs/pcore_defconfig @@ -332,7 +332,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m # CONFIG_IP_NF_TARGET_NETMAP is not set # CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig index ce480563bd7b..c8e1d5d0c70d 100644 --- a/arch/ppc/configs/pmac_defconfig +++ b/arch/ppc/configs/pmac_defconfig @@ -479,7 +479,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc/configs/pplus_defconfig b/arch/ppc/configs/pplus_defconfig index f1153f58a3e3..5e459bcbf591 100644 --- a/arch/ppc/configs/pplus_defconfig +++ b/arch/ppc/configs/pplus_defconfig @@ -343,7 +343,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m # CONFIG_IP_NF_TARGET_NETMAP is not set # CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_FTP=m # CONFIG_IP_NF_MANGLE is not set diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 86b2164302e0..729c32efe62d 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -464,7 +464,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig index 9cc01b5ba633..39c0eb00ddd3 100644 --- a/arch/ppc64/configs/g5_defconfig +++ b/arch/ppc64/configs/g5_defconfig @@ -440,7 +440,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_REDIRECT=y CONFIG_IP_NF_TARGET_NETMAP=y CONFIG_IP_NF_TARGET_SAME=y -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_MANGLE=y CONFIG_IP_NF_TARGET_TOS=y diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig index 84ae55bcc4c5..0ee69246bab8 100644 --- a/arch/ppc64/configs/iSeries_defconfig +++ b/arch/ppc64/configs/iSeries_defconfig @@ -316,7 +316,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig index 73981148d88f..5d242e1530a4 100644 --- a/arch/ppc64/configs/pSeries_defconfig +++ b/arch/ppc64/configs/pSeries_defconfig @@ -408,7 +408,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig index f5503873a953..cdee0276b87e 100644 --- a/arch/ppc64/defconfig +++ b/arch/ppc64/defconfig @@ -374,7 +374,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_LOCAL is not set CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index d6cce39f27b3..9152a1c011bb 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -601,7 +601,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y CONFIG_IP_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h index c4a3622604b7..16fc49298174 100644 --- a/include/linux/netfilter_ipv4/ip_nat.h +++ b/include/linux/netfilter_ipv4/ip_nat.h @@ -11,13 +11,8 @@ enum ip_nat_manip_type IP_NAT_MANIP_DST }; -#ifndef CONFIG_IP_NF_NAT_LOCAL -/* SRC manip occurs only on POST_ROUTING */ -#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING) -#else /* SRC manip occurs POST_ROUTING or LOCAL_IN */ #define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN) -#endif #define IP_NAT_RANGE_MAP_IPS 1 #define IP_NAT_RANGE_PROTO_SPECIFIED 2 diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index eb8cf140ef51..2d59090cbf6f 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -504,20 +504,6 @@ config IP_NF_TARGET_SAME To compile it as a module, choose M here. If unsure, say N. -config IP_NF_NAT_LOCAL - bool "NAT of local connections (READ HELP)" - depends on IP_NF_NAT - help - This option enables support for NAT of locally originated connections. - Enable this if you need to use destination NAT on connections - originating from local processes on the nat box itself. - - Please note that you will need a recent version (>= 1.2.6a) - of the iptables userspace program in order to use this feature. - See for download instructions. - - If unsure, say 'N'. - config IP_NF_NAT_SNMP_BASIC tristate "Basic SNMP-ALG support (EXPERIMENTAL)" depends on EXPERIMENTAL && IP_NF_NAT diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index 4ff337eb1e81..4b00d4886e6f 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -182,7 +182,6 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple, return 0; } -#ifdef CONFIG_IP_NF_NAT_LOCAL /* If it's really a local destination manip, it may need to do a source manip too. */ static int @@ -202,7 +201,6 @@ do_extra_mangle(u_int32_t var_ip, u_int32_t *other_ipp) ip_rt_put(rt); return 1; } -#endif /* Simple way to iterate through all. */ static inline int fake_cmp(const struct ip_conntrack *ct, @@ -301,7 +299,6 @@ find_best_ips_proto(struct ip_conntrack_tuple *tuple, * do_extra_mangle last time. */ *other_ipp = saved_ip; -#ifdef CONFIG_IP_NF_NAT_LOCAL if (hooknum == NF_IP_LOCAL_OUT && *var_ipp != orig_dstip && !do_extra_mangle(*var_ipp, other_ipp)) { @@ -312,7 +309,6 @@ find_best_ips_proto(struct ip_conntrack_tuple *tuple, * anyway. */ continue; } -#endif /* Count how many others map onto this. */ score = count_maps(tuple->src.ip, tuple->dst.ip, @@ -356,13 +352,11 @@ find_best_ips_proto_fast(struct ip_conntrack_tuple *tuple, else { /* Only do extra mangle when required (breaks socket binding) */ -#ifdef CONFIG_IP_NF_NAT_LOCAL if (tuple->dst.ip != mr->range[0].min_ip && hooknum == NF_IP_LOCAL_OUT && !do_extra_mangle(mr->range[0].min_ip, &tuple->src.ip)) return NULL; -#endif tuple->dst.ip = mr->range[0].min_ip; } } @@ -473,10 +467,8 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple, static unsigned int opposite_hook[NF_IP_NUMHOOKS] = { [NF_IP_PRE_ROUTING] = NF_IP_POST_ROUTING, [NF_IP_POST_ROUTING] = NF_IP_PRE_ROUTING, -#ifdef CONFIG_IP_NF_NAT_LOCAL [NF_IP_LOCAL_OUT] = NF_IP_LOCAL_IN, [NF_IP_LOCAL_IN] = NF_IP_LOCAL_OUT, -#endif }; unsigned int diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index 9f727b630923..db0bf47bacff 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c @@ -149,12 +149,8 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb, struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; -#ifdef CONFIG_IP_NF_NAT_LOCAL IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_LOCAL_OUT); -#else - IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING); -#endif ct = ip_conntrack_get(*pskb, &ctinfo); @@ -232,13 +228,6 @@ static int ipt_dnat_checkentry(const char *tablename, return 0; } -#ifndef CONFIG_IP_NF_NAT_LOCAL - if (hook_mask & (1 << NF_IP_LOCAL_OUT)) { - DEBUGP("DNAT: CONFIG_IP_NF_NAT_LOCAL not enabled\n"); - return 0; - } -#endif - return 1; } diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index c37d35879168..0ef8efffb91b 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -128,16 +128,7 @@ ip_nat_fn(unsigned int hooknum, WRITE_LOCK(&ip_nat_lock); /* Seen it before? This can happen for loopback, retrans, or local packets.. */ - if (!(info->initialized & (1 << maniptype)) -#ifndef CONFIG_IP_NF_NAT_LOCAL - /* If this session has already been confirmed we must not - * touch it again even if there is no mapping set up. - * Can only happen on local->local traffic with - * CONFIG_IP_NF_NAT_LOCAL disabled. - */ - && !(ct->status & IPS_CONFIRMED) -#endif - ) { + if (!(info->initialized & (1 << maniptype))) { unsigned int ret; if (ct->master @@ -146,15 +137,14 @@ ip_nat_fn(unsigned int hooknum, ret = call_expect(master_ct(ct), pskb, hooknum, ct, info); } else { -#ifdef CONFIG_IP_NF_NAT_LOCAL /* LOCAL_IN hook doesn't have a chain! */ if (hooknum == NF_IP_LOCAL_IN) ret = alloc_null_binding(ct, info, hooknum); else -#endif - ret = ip_nat_rule_find(pskb, hooknum, in, out, - ct, info); + ret = ip_nat_rule_find(pskb, hooknum, + in, out, ct, + info); } if (ret != NF_ACCEPT) { @@ -234,7 +224,6 @@ ip_nat_out(unsigned int hooknum, return ip_nat_fn(hooknum, pskb, in, out, okfn); } -#ifdef CONFIG_IP_NF_NAT_LOCAL static unsigned int ip_nat_local_fn(unsigned int hooknum, struct sk_buff **pskb, @@ -260,7 +249,6 @@ ip_nat_local_fn(unsigned int hooknum, return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; return ret; } -#endif /* We must be after connection tracking and before packet filtering. */ @@ -282,7 +270,6 @@ static struct nf_hook_ops ip_nat_out_ops = { .priority = NF_IP_PRI_NAT_SRC, }; -#ifdef CONFIG_IP_NF_NAT_LOCAL /* Before packet filtering, change destination */ static struct nf_hook_ops ip_nat_local_out_ops = { .hook = ip_nat_local_fn, @@ -300,7 +287,6 @@ static struct nf_hook_ops ip_nat_local_in_ops = { .hooknum = NF_IP_LOCAL_IN, .priority = NF_IP_PRI_NAT_SRC, }; -#endif /* Protocol registration. */ int ip_nat_protocol_register(struct ip_nat_protocol *proto) @@ -357,7 +343,6 @@ static int init_or_cleanup(int init) printk("ip_nat_init: can't register out hook.\n"); goto cleanup_inops; } -#ifdef CONFIG_IP_NF_NAT_LOCAL ret = nf_register_hook(&ip_nat_local_out_ops); if (ret < 0) { printk("ip_nat_init: can't register local out hook.\n"); @@ -368,16 +353,13 @@ static int init_or_cleanup(int init) printk("ip_nat_init: can't register local in hook.\n"); goto cleanup_localoutops; } -#endif return ret; cleanup: -#ifdef CONFIG_IP_NF_NAT_LOCAL nf_unregister_hook(&ip_nat_local_in_ops); cleanup_localoutops: nf_unregister_hook(&ip_nat_local_out_ops); cleanup_outops: -#endif nf_unregister_hook(&ip_nat_out_ops); cleanup_inops: nf_unregister_hook(&ip_nat_in_ops); -- cgit v1.2.3 From ce9b008ad480cc3f01c39d292c9532d148a0018f Mon Sep 17 00:00:00 2001 From: Michal Ludvig Date: Tue, 30 Nov 2004 06:01:06 -0800 Subject: [CRYPTO]: Standalone VIA PadLock driver. Signed-off-by: David S. Miller --- crypto/Kconfig | 1 + drivers/Makefile | 1 + drivers/crypto/Kconfig | 23 ++ drivers/crypto/Makefile | 7 + drivers/crypto/padlock-aes.c | 470 +++++++++++++++++++++++++++++++++++++++ drivers/crypto/padlock-generic.c | 63 ++++++ drivers/crypto/padlock.h | 36 +++ include/linux/crypto.h | 3 + 8 files changed, 604 insertions(+) create mode 100644 drivers/crypto/Kconfig create mode 100644 drivers/crypto/Makefile create mode 100644 drivers/crypto/padlock-aes.c create mode 100644 drivers/crypto/padlock-generic.c create mode 100644 drivers/crypto/padlock.h (limited to 'include/linux') diff --git a/crypto/Kconfig b/crypto/Kconfig index 3f0f54a2190c..06d45679dbb8 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -274,5 +274,6 @@ config CRYPTO_TEST help Quick & dirty crypto test module. +source "drivers/crypto/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 46b313027b8d..fe3956d17e17 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_MMC) += mmc/ obj-y += firmware/ +obj-$(CONFIG_CRYPTO) += crypto/ diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig new file mode 100644 index 000000000000..094835cce321 --- /dev/null +++ b/drivers/crypto/Kconfig @@ -0,0 +1,23 @@ +menu "Hardware crypto devices" + +config CRYPTO_DEV_PADLOCK + tristate "Support for VIA PadLock ACE" + depends on CRYPTO && X86 && !X86_64 + help + Some VIA processors come with an integrated crypto engine + (so called VIA PadLock ACE, Advanced Cryptography Engine) + that provides instructions for very fast {en,de}cryption + with some algorithms. + + The instructions are used only when the CPU supports them. + Otherwise software encryption is used. If you are unsure, + say Y. + +config CRYPTO_DEV_PADLOCK_AES + bool "Support for AES in VIA PadLock" + depends on CRYPTO_DEV_PADLOCK + default y + help + Use VIA PadLock for AES algorithm. + +endmenu diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile new file mode 100644 index 000000000000..45426ca19a23 --- /dev/null +++ b/drivers/crypto/Makefile @@ -0,0 +1,7 @@ + +obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o + +padlock-objs-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o + +padlock-objs := padlock-generic.o $(padlock-objs-y) + diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c new file mode 100644 index 000000000000..dd148de5eef8 --- /dev/null +++ b/drivers/crypto/padlock-aes.c @@ -0,0 +1,470 @@ +/* + * Cryptographic API. + * + * Support for VIA PadLock hardware crypto engine. + * + * Copyright (c) 2004 Michal Ludvig + * + * Key expansion routine taken from crypto/aes.c + * + * 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. + * + * --------------------------------------------------------------------------- + * Copyright (c) 2002, Dr Brian Gladman , Worcester, UK. + * All rights reserved. + * + * LICENSE TERMS + * + * The free distribution and use of this software in both source and binary + * form is allowed (with or without changes) provided that: + * + * 1. distributions of this source code include the above copyright + * notice, this list of conditions and the following disclaimer; + * + * 2. distributions in binary form include the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other associated materials; + * + * 3. the copyright holder's name is not used to endorse products + * built using this software without specific written permission. + * + * ALTERNATIVELY, provided that this notice is retained in full, this product + * may be distributed under the terms of the GNU General Public License (GPL), + * in which case the provisions of the GPL apply INSTEAD OF those given above. + * + * DISCLAIMER + * + * This software is provided 'as is' with no explicit or implied warranties + * in respect of its properties, including, but not limited to, correctness + * and/or fitness for purpose. + * --------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include "padlock.h" + +#define AES_MIN_KEY_SIZE 16 /* in uint8_t units */ +#define AES_MAX_KEY_SIZE 32 /* ditto */ +#define AES_BLOCK_SIZE 16 /* ditto */ +#define AES_EXTENDED_KEY_SIZE 64 /* in uint32_t units */ +#define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t)) + +static inline int aes_hw_extkey_available (uint8_t key_len); + +struct aes_ctx { + uint32_t e_data[AES_EXTENDED_KEY_SIZE+4]; + uint32_t d_data[AES_EXTENDED_KEY_SIZE+4]; + uint32_t *E; + uint32_t *D; + int key_length; +}; + +/* ====== Key management routines ====== */ + +static inline uint32_t +generic_rotr32 (const uint32_t x, const unsigned bits) +{ + const unsigned n = bits % 32; + return (x >> n) | (x << (32 - n)); +} + +static inline uint32_t +generic_rotl32 (const uint32_t x, const unsigned bits) +{ + const unsigned n = bits % 32; + return (x << n) | (x >> (32 - n)); +} + +#define rotl generic_rotl32 +#define rotr generic_rotr32 + +/* + * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) + */ +static inline uint8_t +byte(const uint32_t x, const unsigned n) +{ + return x >> (n << 3); +} + +#define uint32_t_in(x) le32_to_cpu(*(const uint32_t *)(x)) +#define uint32_t_out(to, from) (*(uint32_t *)(to) = cpu_to_le32(from)) + +#define E_KEY ctx->E +#define D_KEY ctx->D + +static uint8_t pow_tab[256]; +static uint8_t log_tab[256]; +static uint8_t sbx_tab[256]; +static uint8_t isb_tab[256]; +static uint32_t rco_tab[10]; +static uint32_t ft_tab[4][256]; +static uint32_t it_tab[4][256]; + +static uint32_t fl_tab[4][256]; +static uint32_t il_tab[4][256]; + +static inline uint8_t +f_mult (uint8_t a, uint8_t b) +{ + uint8_t aa = log_tab[a], cc = aa + log_tab[b]; + + return pow_tab[cc + (cc < aa ? 1 : 0)]; +} + +#define ff_mult(a,b) (a && b ? f_mult(a, b) : 0) + +#define f_rn(bo, bi, n, k) \ + bo[n] = ft_tab[0][byte(bi[n],0)] ^ \ + ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rn(bo, bi, n, k) \ + bo[n] = it_tab[0][byte(bi[n],0)] ^ \ + it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +#define ls_box(x) \ + ( fl_tab[0][byte(x, 0)] ^ \ + fl_tab[1][byte(x, 1)] ^ \ + fl_tab[2][byte(x, 2)] ^ \ + fl_tab[3][byte(x, 3)] ) + +#define f_rl(bo, bi, n, k) \ + bo[n] = fl_tab[0][byte(bi[n],0)] ^ \ + fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rl(bo, bi, n, k) \ + bo[n] = il_tab[0][byte(bi[n],0)] ^ \ + il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +static void +gen_tabs (void) +{ + uint32_t i, t; + uint8_t p, q; + + /* log and power tables for GF(2**8) finite field with + 0x011b as modular polynomial - the simplest prmitive + root is 0x03, used here to generate the tables */ + + for (i = 0, p = 1; i < 256; ++i) { + pow_tab[i] = (uint8_t) p; + log_tab[p] = (uint8_t) i; + + p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; + + for (i = 0, p = 1; i < 10; ++i) { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + for (i = 0; i < 256; ++i) { + p = (i ? pow_tab[255 - log_tab[i]] : 0); + q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); + p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); + sbx_tab[i] = p; + isb_tab[p] = (uint8_t) i; + } + + for (i = 0; i < 256; ++i) { + p = sbx_tab[i]; + + t = p; + fl_tab[0][i] = t; + fl_tab[1][i] = rotl (t, 8); + fl_tab[2][i] = rotl (t, 16); + fl_tab[3][i] = rotl (t, 24); + + t = ((uint32_t) ff_mult (2, p)) | + ((uint32_t) p << 8) | + ((uint32_t) p << 16) | ((uint32_t) ff_mult (3, p) << 24); + + ft_tab[0][i] = t; + ft_tab[1][i] = rotl (t, 8); + ft_tab[2][i] = rotl (t, 16); + ft_tab[3][i] = rotl (t, 24); + + p = isb_tab[i]; + + t = p; + il_tab[0][i] = t; + il_tab[1][i] = rotl (t, 8); + il_tab[2][i] = rotl (t, 16); + il_tab[3][i] = rotl (t, 24); + + t = ((uint32_t) ff_mult (14, p)) | + ((uint32_t) ff_mult (9, p) << 8) | + ((uint32_t) ff_mult (13, p) << 16) | + ((uint32_t) ff_mult (11, p) << 24); + + it_tab[0][i] = t; + it_tab[1][i] = rotl (t, 8); + it_tab[2][i] = rotl (t, 16); + it_tab[3][i] = rotl (t, 24); + } +} + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y,x) \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= rotr(u ^ t, 8) ^ \ + rotr(v ^ t, 16) ^ \ + rotr(t,24) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \ + t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \ + t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \ + t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \ +} + +#define loop6(i) \ +{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \ + t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \ + t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \ + t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \ + t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \ + t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \ +} + +#define loop8(i) \ +{ t = rotr(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \ + t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \ + t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \ + t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \ + t = E_KEY[8 * i + 4] ^ ls_box(t); \ + E_KEY[8 * i + 12] = t; \ + t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \ + t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \ + t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ +} + +static int +aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags) +{ + struct aes_ctx *ctx = ctx_arg; + uint32_t i, t, u, v, w; + uint32_t P[AES_EXTENDED_KEY_SIZE]; + uint32_t rounds; + + if (key_len != 16 && key_len != 24 && key_len != 32) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + ctx->key_length = key_len; + + ctx->E = ctx->e_data; + ctx->D = ctx->d_data; + + /* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */ + if ((int)(ctx->e_data) & 0x0F) + ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0])); + + if ((int)(ctx->d_data) & 0x0F) + ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0])); + + E_KEY[0] = uint32_t_in (in_key); + E_KEY[1] = uint32_t_in (in_key + 4); + E_KEY[2] = uint32_t_in (in_key + 8); + E_KEY[3] = uint32_t_in (in_key + 12); + + /* Don't generate extended keys if the hardware can do it. */ + if (aes_hw_extkey_available(key_len)) + return 0; + + switch (key_len) { + case 16: + t = E_KEY[3]; + for (i = 0; i < 10; ++i) + loop4 (i); + break; + + case 24: + E_KEY[4] = uint32_t_in (in_key + 16); + t = E_KEY[5] = uint32_t_in (in_key + 20); + for (i = 0; i < 8; ++i) + loop6 (i); + break; + + case 32: + E_KEY[4] = uint32_t_in (in_key + 16); + E_KEY[5] = uint32_t_in (in_key + 20); + E_KEY[6] = uint32_t_in (in_key + 24); + t = E_KEY[7] = uint32_t_in (in_key + 28); + for (i = 0; i < 7; ++i) + loop8 (i); + break; + } + + D_KEY[0] = E_KEY[0]; + D_KEY[1] = E_KEY[1]; + D_KEY[2] = E_KEY[2]; + D_KEY[3] = E_KEY[3]; + + for (i = 4; i < key_len + 24; ++i) { + imix_col (D_KEY[i], E_KEY[i]); + } + + /* PadLock needs a different format of the decryption key. */ + rounds = 10 + (key_len - 16) / 4; + + for (i = 0; i < rounds; i++) { + P[((i + 1) * 4) + 0] = D_KEY[((rounds - i - 1) * 4) + 0]; + P[((i + 1) * 4) + 1] = D_KEY[((rounds - i - 1) * 4) + 1]; + P[((i + 1) * 4) + 2] = D_KEY[((rounds - i - 1) * 4) + 2]; + P[((i + 1) * 4) + 3] = D_KEY[((rounds - i - 1) * 4) + 3]; + } + + P[0] = E_KEY[(rounds * 4) + 0]; + P[1] = E_KEY[(rounds * 4) + 1]; + P[2] = E_KEY[(rounds * 4) + 2]; + P[3] = E_KEY[(rounds * 4) + 3]; + + memcpy(D_KEY, P, AES_EXTENDED_KEY_SIZE_B); + + return 0; +} + +/* Tells whether the ACE is capable to generate + the extended key for a given key_len. */ +static inline int +aes_hw_extkey_available(uint8_t key_len) +{ + /* TODO: We should check the actual CPU model/stepping + as it's possible that the capability will be + added in the next CPU revisions. */ + if (key_len == 16) + return 1; + return 0; +} + +/* ====== Encryption/decryption routines ====== */ + +/* This is the real call to PadLock. */ +static inline void +padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key, + void *control_word, uint32_t count) +{ + asm volatile ("pushfl; popfl"); /* enforce key reload. */ + asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ + : "=m"(*output), "+S"(input), "+D"(output) + : "d"(control_word), "b"(key), "c"(count)); +} + +static void +aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec) +{ + /* Don't blindly modify this structure - the items must + fit on 16-Bytes boundaries! */ + struct padlock_xcrypt_data { + uint8_t buf[AES_BLOCK_SIZE]; + union cword cword; + }; + + struct aes_ctx *ctx = ctx_arg; + char bigbuf[sizeof(struct padlock_xcrypt_data) + 16]; + struct padlock_xcrypt_data *data; + void *key; + + /* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */ + if (((long)bigbuf) & 0x0F) + data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F)); + else + data = (void*)bigbuf; + + /* Prepare Control word. */ + memset (data, 0, sizeof(struct padlock_xcrypt_data)); + data->cword.b.encdec = !encdec; /* in the rest of cryptoapi ENC=1/DEC=0 */ + data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4; + data->cword.b.ksize = (ctx->key_length - 16) / 8; + + /* Is the hardware capable to generate the extended key? */ + if (!aes_hw_extkey_available(ctx->key_length)) + data->cword.b.keygen = 1; + + /* ctx->E starts with a plain key - if the hardware is capable + to generate the extended key itself we must supply + the plain key for both Encryption and Decryption. */ + if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0) + key = ctx->E; + else + key = ctx->D; + + memcpy(data->buf, in_arg, AES_BLOCK_SIZE); + padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1); + memcpy(out_arg, data->buf, AES_BLOCK_SIZE); +} + +static void +aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) +{ + aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT); +} + +static void +aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) +{ + aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT); +} + +static struct crypto_alg aes_alg = { + .cra_name = "aes", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aes_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_setkey = aes_set_key, + .cia_encrypt = aes_encrypt, + .cia_decrypt = aes_decrypt + } + } +}; + +int __init padlock_init_aes(void) +{ + printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n"); + + gen_tabs(); + return crypto_register_alg(&aes_alg); +} + +void __exit padlock_fini_aes(void) +{ + crypto_unregister_alg(&aes_alg); +} diff --git a/drivers/crypto/padlock-generic.c b/drivers/crypto/padlock-generic.c new file mode 100644 index 000000000000..18cf0e8274a7 --- /dev/null +++ b/drivers/crypto/padlock-generic.c @@ -0,0 +1,63 @@ +/* + * Cryptographic API. + * + * Support for VIA PadLock hardware crypto engine. + * + * Copyright (c) 2004 Michal Ludvig + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "padlock.h" + +static int __init +padlock_init(void) +{ + int ret = -ENOSYS; + + if (!cpu_has_xcrypt) { + printk(KERN_ERR PFX "VIA PadLock not detected.\n"); + return -ENODEV; + } + + if (!cpu_has_xcrypt_enabled) { + printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); + return -ENODEV; + } + +#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES + if ((ret = padlock_init_aes())) { + printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n"); + return ret; + } +#endif + + if (ret == -ENOSYS) + printk(KERN_ERR PFX "Hmm, VIA PadLock was compiled without any algorithm.\n"); + + return ret; +} + +static void __exit +padlock_fini(void) +{ +#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES + padlock_fini_aes(); +#endif +} + +module_init(padlock_init); +module_exit(padlock_fini); + +MODULE_DESCRIPTION("VIA PadLock crypto engine support."); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Michal Ludvig"); diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h new file mode 100644 index 000000000000..7a500605e449 --- /dev/null +++ b/drivers/crypto/padlock.h @@ -0,0 +1,36 @@ +/* + * Driver for VIA PadLock + * + * Copyright (c) 2004 Michal Ludvig + * + * 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 _CRYPTO_PADLOCK_H +#define _CRYPTO_PADLOCK_H + +/* Control word. */ +union cword { + uint32_t cword[4]; + struct { + int rounds:4; + int algo:3; + int keygen:1; + int interm:1; + int encdec:1; + int ksize:2; + } b; +}; + +#define PFX "padlock: " + +#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES +int padlock_init_aes(void); +void padlock_fini_aes(void); +#endif + +#endif /* _CRYPTO_PADLOCK_H */ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 0f0d8a9f5b53..4626d40e8c6e 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -56,6 +56,9 @@ #define CRYPTO_UNSPEC 0 #define CRYPTO_MAX_ALG_NAME 64 +#define CRYPTO_DIR_ENCRYPT 1 +#define CRYPTO_DIR_DECRYPT 0 + struct scatterlist; /* -- cgit v1.2.3 From 97f014fbbe267480e4a0ce2115407c0a777c5f4c Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 6 Dec 2004 02:23:20 -0600 Subject: [PATCH] Move MCA_bus to linux/mca.h - Move MCA_bus declaration from to - Define it in mca.c, not setup.c - EXPORT_SYMBOL it at the site of its definition. - Fix up random files to include for the use of the MCA_bus symbol - Delete some unnecessary ifdefs. - Delete some unneeded comments. Signed-off-by: James Bottomley --- arch/i386/kernel/i386_ksyms.c | 1 - arch/i386/kernel/mca.c | 3 +++ arch/i386/kernel/setup.c | 13 +++++++++++-- arch/i386/kernel/time.c | 5 ++--- drivers/serial/8250.c | 3 +-- include/asm-alpha/processor.h | 6 ------ include/asm-arm/processor.h | 3 --- include/asm-arm26/processor.h | 3 --- include/asm-h8300/processor.h | 5 ----- include/asm-i386/processor.h | 5 ----- include/asm-m68knommu/processor.h | 5 ----- include/asm-mips/processor.h | 6 ------ include/asm-parisc/processor.h | 3 --- include/asm-ppc/processor.h | 6 ------ include/asm-ppc64/processor.h | 6 ------ include/asm-sh/processor.h | 6 ------ include/asm-sh64/processor.h | 6 ------ include/asm-sparc/processor.h | 6 ------ include/asm-sparc64/processor.h | 4 ---- include/asm-v850/processor.h | 7 ------- include/asm-x86_64/processor.h | 6 ------ include/linux/mca.h | 14 +++----------- 22 files changed, 20 insertions(+), 102 deletions(-) (limited to 'include/linux') diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 5e6f450d0beb..13720d480f21 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -61,7 +61,6 @@ extern unsigned long get_cmos_time(void); /* platform dependent support */ EXPORT_SYMBOL(boot_cpu_data); -EXPORT_SYMBOL(MCA_bus); #ifdef CONFIG_DISCONTIGMEM EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(physnode_map); diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c index 720365e464ae..e4d3d5f27f45 100644 --- a/arch/i386/kernel/mca.c +++ b/arch/i386/kernel/mca.c @@ -56,6 +56,9 @@ static unsigned char which_scsi = 0; +int MCA_bus = 0; +EXPORT_SYMBOL(MCA_bus); + /* * Motherboard register spinlock. Untested on SMP at the moment, but * are there any MCA SMP boxes? diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 19827c0c5728..6802e027a8e7 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,6 @@ int __initdata acpi_force = 0; extern acpi_interrupt_flags acpi_sci_flags; #endif -int MCA_bus; /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; unsigned int machine_submodel_id; @@ -1288,6 +1288,15 @@ __setup("noreplacement", noreplacement_setup); static char * __init machine_specific_memory_setup(void); +#ifdef CONFIG_MCA +static void set_mca_bus(int x) +{ + MCA_bus = x; +} +#else +static void set_mca_bus(int x) { } +#endif + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -1323,7 +1332,7 @@ void __init setup_arch(char **cmdline_p) ist_info = IST_INFO; saved_videomode = VIDEO_MODE; if( SYS_DESC_TABLE.length != 0 ) { - MCA_bus = SYS_DESC_TABLE.table[3] &0x2; + set_mca_bus(SYS_DESC_TABLE.table[3] & 0x2); machine_id = SYS_DESC_TABLE.table[0]; machine_submodel_id = SYS_DESC_TABLE.table[1]; BIOS_revision = SYS_DESC_TABLE.table[2]; diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 2c5312b24b1f..5b7e4e11659b 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -261,8 +262,7 @@ static inline void do_timer_interrupt(int irq, void *dev_id, last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } -#ifdef CONFIG_MCA - if( MCA_bus ) { + if (MCA_bus) { /* The PS/2 uses level-triggered interrupts. You can't turn them off, nor would you want to (any attempt to enable edge-triggered interrupts usually gets intercepted by a @@ -275,7 +275,6 @@ static inline void do_timer_interrupt(int irq, void *dev_id, irq = inb_p( 0x61 ); /* read the current state */ outb_p( irq|0x80, 0x61 ); /* reset the IRQ */ } -#endif } /* diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 31dd922e28ef..d4e7733dbeb8 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1861,13 +1862,11 @@ static void serial8250_config_port(struct uart_port *port, int flags) int probeflags = PROBE_ANY; int ret; -#ifdef CONFIG_MCA /* * Don't probe for MCA ports on non-MCA machines. */ if (up->port.flags & UPF_BOOT_ONLYMCA && !MCA_bus) return; -#endif /* * Find the region that we can probe for. This in turn diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h index 3c750a362c44..059780a7d3d7 100644 --- a/include/asm-alpha/processor.h +++ b/include/asm-alpha/processor.h @@ -26,12 +26,6 @@ #define TASK_UNMAPPED_BASE \ ((current->personality & ADDR_LIMIT_32BIT) ? 0x40000000 : TASK_SIZE / 2) -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - typedef struct { unsigned long seg; } mm_segment_t; diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h index e2de28eec30a..06ab5f106a0f 100644 --- a/include/asm-arm/processor.h +++ b/include/asm-arm/processor.h @@ -19,9 +19,6 @@ #ifdef __KERNEL__ -#define MCA_bus 0 -#define MCA_bus__is_a_macro - #include #include #include diff --git a/include/asm-arm26/processor.h b/include/asm-arm26/processor.h index 9e0d90433795..1d2d5f7b467b 100644 --- a/include/asm-arm26/processor.h +++ b/include/asm-arm26/processor.h @@ -20,9 +20,6 @@ #ifdef __KERNEL__ -#define MCA_bus 0 -#define MCA_bus__is_a_macro - #include #include #include diff --git a/include/asm-h8300/processor.h b/include/asm-h8300/processor.h index 59900733c714..c6f0a7108ef3 100644 --- a/include/asm-h8300/processor.h +++ b/include/asm-h8300/processor.h @@ -45,11 +45,6 @@ static inline void wrusp(unsigned long usp) { */ #define TASK_UNMAPPED_BASE 0 -/* - * Bus types - */ -#define MCA_bus 0 - struct thread_struct { unsigned long ksp; /* kernel stack pointer */ unsigned long usp; /* user stack pointer */ diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 147da2f7414b..c9d9c664b557 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -259,11 +259,6 @@ static inline void clear_in_cr4 (unsigned long mask) outb((data), 0x23); \ } while (0) -/* - * Bus types (default is ISA, but people can check others with these..) - */ -extern int MCA_bus; - static inline void __monitor(const void *eax, unsigned long ecx, unsigned long edx) { diff --git a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h index 736e3192f464..ee236dd23d97 100644 --- a/include/asm-m68knommu/processor.h +++ b/include/asm-m68knommu/processor.h @@ -55,11 +55,6 @@ extern inline void wrusp(unsigned long usp) */ #define TASK_UNMAPPED_BASE 0 -/* - * Bus types - */ -#define MCA_bus 0 - /* * if you change this structure, you must change the code and offsets * in m68k/machasm.S diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index b461fd0c9831..c815890dde94 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -33,12 +33,6 @@ extern void (*cpu_wait)(void); extern unsigned int vced_count, vcei_count; -/* - * Bus types (default is ISA, but people can check others with these..) - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - #ifdef CONFIG_MIPS32 /* * User space process size: 2GB. This is hardcoded into a few places, diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index 1a886a0f61ff..0b61f51d8467 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h @@ -107,9 +107,6 @@ extern struct cpuinfo_parisc cpu_data[NR_CPUS]; #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF) -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - typedef struct { int seg; } mm_segment_t; diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 63fc68e784c5..c8f84c3a56cd 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -78,12 +78,6 @@ extern void prepare_to_copy(struct task_struct *tsk); */ extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro - /* Lazy FPU handling on uni-processor */ extern struct task_struct *last_task_used_math; extern struct task_struct *last_task_used_altivec; diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 518f551dba6a..774ca333df35 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -494,12 +494,6 @@ extern void prepare_to_copy(struct task_struct *tsk); /* Create a new kernel thread. */ extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - /* Lazy FPU handling on uni-processor */ extern struct task_struct *last_task_used_math; extern struct task_struct *last_task_used_altivec; diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 5ae342e6b52d..c4904797d6df 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -191,12 +191,6 @@ extern void release_thread(struct task_struct *); */ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) diff --git a/include/asm-sh64/processor.h b/include/asm-sh64/processor.h index 0f45ae686110..a51bd41e6fbc 100644 --- a/include/asm-sh64/processor.h +++ b/include/asm-sh64/processor.h @@ -218,12 +218,6 @@ extern void release_thread(struct task_struct *); */ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while (0) diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h index 371a105056f3..307915adb43d 100644 --- a/include/asm-sparc/processor.h +++ b/include/asm-sparc/processor.h @@ -23,12 +23,6 @@ #include #include -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - /* * The sparc has no problems with write protection */ diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index 416fad2ef1b1..bc1445b904ef 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -21,10 +21,6 @@ #include #include -/* Bus types */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - /* The sparc has no problems with write protection */ #define wp_works_ok 1 #define wp_works_ok__is_a_macro /* for versions in ksyms.c */ diff --git a/include/asm-v850/processor.h b/include/asm-v850/processor.h index b28582ecce02..d41f925f5182 100644 --- a/include/asm-v850/processor.h +++ b/include/asm-v850/processor.h @@ -48,13 +48,6 @@ */ #define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - /* If you change this, you must change the associated assembly-languages constants defined below, THREAD_*. */ struct thread_struct { diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index 0fc76da585f5..36c04fb3c0d0 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -157,12 +157,6 @@ static inline void clear_in_cr4 (unsigned long mask) :"ax"); } -/* - * Bus types - */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro - /* * User space process size: 512GB - 1GB (default). diff --git a/include/linux/mca.h b/include/linux/mca.h index a80124c4a05d..5cff2923092b 100644 --- a/include/linux/mca.h +++ b/include/linux/mca.h @@ -6,22 +6,14 @@ #ifndef _LINUX_MCA_H #define _LINUX_MCA_H -/* FIXME: This shouldn't happen, but we need everything that previously - * included mca.h to compile. Take it out later when the MCA #includes - * are sorted out */ #include -/* get the platform specific defines */ #ifdef CONFIG_MCA #include -#endif -/* The detection of MCA bus is done in the real mode (using BIOS). - * The information is exported to the protected code, where this - * variable is set to one in case MCA bus was detected. - */ -#ifndef MCA_bus__is_a_macro -extern int MCA_bus; +extern int MCA_bus; +#else +#define MCA_bus 0 #endif /* This sets up an information callback for /proc/mca/slot?. The -- cgit v1.2.3 From 54fced5487b42121ffbca00d025a517bde5008d6 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 15 Dec 2004 03:41:06 -0500 Subject: [AGPGART] Add support for ALI M1681/M1683 Signed-off-by: Dave Jones --- drivers/char/agp/ali-agp.c | 9 +++++++++ include/linux/pci_ids.h | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 005b82019f38..4f3b310d5764 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -277,6 +277,15 @@ static struct agp_device_ids ali_agp_device_ids[] __devinitdata = .device_id = PCI_DEVICE_ID_AL_M1671, .chipset_name = "M1671", }, + { + .device_id = PCI_DEVICE_ID_AL_M1681, + .chipset_name = "M1681", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1683, + .chipset_name = "M1683", + }, + { }, /* dummy final entry, always present */ }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index affb193a43e6..bfa1246e58bf 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1017,6 +1017,7 @@ #define PCI_DEVICE_ID_AL_M1531 0x1531 #define PCI_DEVICE_ID_AL_M1533 0x1533 #define PCI_DEVICE_ID_AL_M1541 0x1541 +#define PCI_DEVICE_ID_AL_M1543 0x1543 #define PCI_DEVICE_ID_AL_M1563 0x1563 #define PCI_DEVICE_ID_AL_M1621 0x1621 #define PCI_DEVICE_ID_AL_M1631 0x1631 @@ -1026,7 +1027,8 @@ #define PCI_DEVICE_ID_AL_M1647 0x1647 #define PCI_DEVICE_ID_AL_M1651 0x1651 #define PCI_DEVICE_ID_AL_M1671 0x1671 -#define PCI_DEVICE_ID_AL_M1543 0x1543 +#define PCI_DEVICE_ID_AL_M1681 0x1681 +#define PCI_DEVICE_ID_AL_M1683 0x1683 #define PCI_DEVICE_ID_AL_M3307 0x3307 #define PCI_DEVICE_ID_AL_M4803 0x5215 #define PCI_DEVICE_ID_AL_M5219 0x5219 -- cgit v1.2.3 From cceae0d365b18b685cc564071aae22599ebf52a9 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 19 Dec 2004 23:17:24 -0800 Subject: [TCP]: Efficient port randomization (rev 3) okay, here is the revised version. Testing shows that it is more consistent, and just as fast as existing code, probably because of the getting rid of portalloc_lock and better distribution. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/char/random.c | 18 +++++++++++++++ include/linux/random.h | 1 + net/ipv4/tcp_ipv4.c | 62 ++++++++++++++++++++------------------------------ 3 files changed, 44 insertions(+), 37 deletions(-) (limited to 'include/linux') diff --git a/drivers/char/random.c b/drivers/char/random.c index cfd25286c1d2..2c8612c39605 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -2369,6 +2369,24 @@ __u32 secure_ip_id(__u32 daddr) return halfMD4Transform(hash, keyptr->secret); } +/* Generate secure starting point for ephemeral TCP port search */ +u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport) +{ + struct keydata *keyptr = get_keyptr(); + u32 hash[4]; + + /* + * Pick a unique starting offset for each ephemeral port search + * (saddr, daddr, dport) and 48bits of random data. + */ + hash[0] = saddr; + hash[1] = daddr; + hash[2] = dport ^ keyptr->secret[10]; + hash[3] = keyptr->secret[11]; + + return halfMD4Transform(hash, keyptr->secret); +} + #ifdef CONFIG_SYN_COOKIES /* * Secure SYN cookie computation. This is the algorithm worked out by diff --git a/include/linux/random.h b/include/linux/random.h index 4aaffb57349d..bb7c6e64e3eb 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -52,6 +52,7 @@ extern void get_random_bytes(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); extern __u32 secure_ip_id(__u32 daddr); +extern u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport); extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport); extern __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 844b9fa6fe91..3062579ef720 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -636,10 +636,18 @@ not_unique: return -EADDRNOTAVAIL; } +static inline u32 connect_port_offset(const struct sock *sk) +{ + const struct inet_opt *inet = inet_sk(sk); + + return secure_tcp_port_ephemeral(inet->rcv_saddr, inet->daddr, + inet->dport); +} + /* * Bind a port for a connect operation and hash it. */ -static int tcp_v4_hash_connect(struct sock *sk) +static inline int tcp_v4_hash_connect(struct sock *sk) { unsigned short snum = inet_sk(sk)->num; struct tcp_bind_hashbucket *head; @@ -647,36 +655,20 @@ static int tcp_v4_hash_connect(struct sock *sk) int ret; if (!snum) { - int rover; int low = sysctl_local_port_range[0]; int high = sysctl_local_port_range[1]; - int remaining = (high - low) + 1; + int range = high - low; + int i; + int port; + static u32 hint; + u32 offset = hint + connect_port_offset(sk); struct hlist_node *node; struct tcp_tw_bucket *tw = NULL; local_bh_disable(); - - /* TODO. Actually it is not so bad idea to remove - * tcp_portalloc_lock before next submission to Linus. - * As soon as we touch this place at all it is time to think. - * - * Now it protects single _advisory_ variable tcp_port_rover, - * hence it is mostly useless. - * Code will work nicely if we just delete it, but - * I am afraid in contented case it will work not better or - * even worse: another cpu just will hit the same bucket - * and spin there. - * So some cpu salt could remove both contention and - * memory pingpong. Any ideas how to do this in a nice way? - */ - spin_lock(&tcp_portalloc_lock); - rover = tcp_port_rover; - - do { - rover++; - if ((rover < low) || (rover > high)) - rover = low; - head = &tcp_bhash[tcp_bhashfn(rover)]; + for (i = 1; i <= range; i++) { + port = low + (i + offset) % range; + head = &tcp_bhash[tcp_bhashfn(port)]; spin_lock(&head->lock); /* Does not bother with rcv_saddr checks, @@ -684,19 +676,19 @@ static int tcp_v4_hash_connect(struct sock *sk) * unique enough. */ tb_for_each(tb, node, &head->chain) { - if (tb->port == rover) { + if (tb->port == port) { BUG_TRAP(!hlist_empty(&tb->owners)); if (tb->fastreuse >= 0) goto next_port; if (!__tcp_v4_check_established(sk, - rover, + port, &tw)) goto ok; goto next_port; } } - tb = tcp_bucket_create(head, rover); + tb = tcp_bucket_create(head, port); if (!tb) { spin_unlock(&head->lock); break; @@ -706,22 +698,18 @@ static int tcp_v4_hash_connect(struct sock *sk) next_port: spin_unlock(&head->lock); - } while (--remaining > 0); - tcp_port_rover = rover; - spin_unlock(&tcp_portalloc_lock); - + } local_bh_enable(); return -EADDRNOTAVAIL; ok: - /* All locks still held and bhs disabled */ - tcp_port_rover = rover; - spin_unlock(&tcp_portalloc_lock); + hint += i; - tcp_bind_hash(sk, tb, rover); + /* Head lock still held and bh's disabled */ + tcp_bind_hash(sk, tb, port); if (sk_unhashed(sk)) { - inet_sk(sk)->sport = htons(rover); + inet_sk(sk)->sport = htons(port); __tcp_v4_hash(sk, 0); } spin_unlock(&head->lock); -- cgit v1.2.3 From 33deca1103bcbd3360a86bb5b6a1d454bee8c16c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 22 Dec 2004 07:10:35 -0500 Subject: [AGPGART] ULI M1689 support. From: Peer.Chen@uli.com.tw Signed-off-by: Dave Jones --- drivers/char/agp/amd64-agp.c | 78 +++++++++++++++++++++++++++++++++++++++++++- include/linux/pci_ids.h | 1 + 2 files changed, 78 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 1b3ee516ab54..057b13dba453 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -46,6 +46,11 @@ #define NVIDIA_X86_64_1_APBASE2 0xd8 #define NVIDIA_X86_64_1_APLIMIT2 0xdc +/* ULi K8 registers */ +#define ULI_X86_64_BASE_ADDR 0x10 +#define ULI_X86_64_HTT_FEA_REG 0x50 +#define ULI_X86_64_ENU_SCR_REG 0x54 + static int nr_garts; static struct pci_dev * hammers[MAX_HAMMER_GARTS]; @@ -406,6 +411,61 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data } } + +static struct aper_size_info_32 uli_sizes[7] = +{ + {256, 65536, 6, 10}, + {128, 32768, 5, 9}, + {64, 16384, 4, 8}, + {32, 8192, 3, 7}, + {16, 4096, 2, 6}, + {8, 2048, 1, 4}, + {4, 1024, 0, 3} +}; +static int __devinit uli_agp_init(struct pci_dev *pdev) +{ + u32 httfea,baseaddr,enuscr; + struct pci_dev *dev1; + int i; + unsigned size = amd64_fetch_size(); + printk(KERN_INFO "Setting up ULi AGP. \n"); + dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0)); + if (dev1 == NULL) { + printk(KERN_INFO PFX "Detected a ULi chipset, " + "but could not fine the secondary device.\n"); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(uli_sizes); i++) + if (uli_sizes[i].size == size) + break; + + if (i == ARRAY_SIZE(uli_sizes)) { + printk(KERN_INFO PFX "No ULi size found for %d\n", size); + return -ENODEV; + } + + /* shadow x86-64 registers into ULi registers */ + pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &httfea); + + /* if x86-64 aperture base is beyond 4G, exit here */ + if ((httfea & 0x7fff) >> (32 - 25)) + return -ENODEV; + + httfea = (httfea& 0x7fff) << 25; + + pci_read_config_dword(pdev, ULI_X86_64_BASE_ADDR, &baseaddr); + baseaddr&= ~PCI_BASE_ADDRESS_MEM_MASK; + baseaddr|= httfea; + pci_write_config_dword(pdev, ULI_X86_64_BASE_ADDR, baseaddr); + + enuscr= httfea+ (size * 1024 * 1024) - 1; + pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea); + pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr); + return 0; +} + + static struct aper_size_info_32 nforce3_sizes[5] = { {512, 131072, 7, 0x00000000 }, @@ -514,6 +574,14 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, } } + if (pdev->vendor == PCI_VENDOR_ID_AL) { + int ret = uli_agp_init(pdev); + if (ret) { + agp_put_bridge(bridge); + return ret; + } + } + pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); } @@ -537,6 +605,15 @@ static struct pci_device_id agp_amd64_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, + /* ULi M1689 */ + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_AL, + .device = PCI_DEVICE_ID_AL_M1689, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, /* VIA K8T800Pro */ { .class = (PCI_CLASS_BRIDGE_HOST << 8), @@ -582,7 +659,6 @@ static struct pci_device_id agp_amd64_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, - /* NForce3 */ { .class = (PCI_CLASS_BRIDGE_HOST << 8), diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index bfa1246e58bf..4ec82dce2f1c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1029,6 +1029,7 @@ #define PCI_DEVICE_ID_AL_M1671 0x1671 #define PCI_DEVICE_ID_AL_M1681 0x1681 #define PCI_DEVICE_ID_AL_M1683 0x1683 +#define PCI_DEVICE_ID_AL_M1689 0x1689 #define PCI_DEVICE_ID_AL_M3307 0x3307 #define PCI_DEVICE_ID_AL_M4803 0x5215 #define PCI_DEVICE_ID_AL_M5219 0x5219 -- cgit v1.2.3 From 8747044437bac3e884eb8554a8c7940d86dddbec Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 23 Dec 2004 18:15:26 -0800 Subject: [PATCH] fix CONFIG_SWAP=n build mm/rmap.c contains an open-coded reference to swap_token_default_timeout Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/swap.h b/include/linux/swap.h index b0f07148e0eb..10eb41367104 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -269,6 +269,7 @@ static inline void put_swap_token(struct mm_struct *mm) #define move_from_swap_cache(p, i, m) 1 #define __delete_from_swap_cache(p) /*NOTHING*/ #define delete_from_swap_cache(p) /*NOTHING*/ +#define swap_token_default_timeout 0 static inline int remove_exclusive_swap_page(struct page *p) { -- cgit v1.2.3